229 #include <csspp/assembler.h> 230 #include <csspp/compiler.h> 231 #include <csspp/exceptions.h> 232 #include <csspp/parser.h> 236 #include <advgetopt/advgetopt.h> 237 #include <advgetopt/exception.h> 241 #include <boost/preprocessor/stringize.hpp> 269 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_REQUIRED | advgetopt::GETOPT_FLAG_MULTIPLE,
272 "define values in the $_csspp_args variable map",
277 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_FLAG,
280 "show all messages, including @debug messages",
285 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_MULTIPLE,
288 "specify a path to various user defined CSS files; \"-\" to clear the list (i.e. \"-I -\")",
293 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_FLAG,
296 "prevent the \"logo\" from appearing in the output file",
301 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_FLAG,
302 "empty-on-undefined-variable",
304 "if accessing an undefined variable, return an empty string, otherwise generate an error",
309 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_SHOW_USAGE_ON_ERROR,
312 "save the results in the specified file",
317 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_FLAG,
320 "define the number of digits to use after the decimal point, defaults to 3; note that for percent values, the precision is always 2.",
325 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_FLAG,
328 "suppress @info and @warning messages",
333 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_REQUIRED,
336 "output style: compressed, tidy, compact, expanded",
341 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_FLAG,
344 "make warnings count as errors",
349 advgetopt::GETOPT_FLAG_COMMAND_LINE | advgetopt::GETOPT_FLAG_MULTIPLE | advgetopt::GETOPT_FLAG_DEFAULT_OPTION | advgetopt::GETOPT_FLAG_SHOW_USAGE_ON_ERROR,
352 "[file.css ...]; use stdin if no filename specified",
355 advgetopt::end_options()
359 #pragma GCC diagnostic ignored "-Wpedantic" 362 .f_project_name =
"csspp",
363 .f_group_name =
nullptr,
365 .f_options_files_directory =
nullptr,
366 .f_environment_variable_name =
"CSSPPFLAGS",
367 .f_section_variables_name =
nullptr,
368 .f_configuration_files =
nullptr,
369 .f_configuration_filename =
nullptr,
370 .f_configuration_directories =
nullptr,
371 .f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_PROCESS_SYSTEM_PARAMETERS,
372 .f_help_header =
"Usage: %p [-<opt>] [file.css ...] [-o out.css]\n" 373 "where -<opt> is one or more of:",
374 .f_help_footer =
"%c",
375 .f_version = CSSPP_VERSION,
376 .f_license =
"GNU GPL v2",
377 .f_copyright =
"Copyright (c) 2015-" 378 BOOST_PP_STRINGIZE(UTC_BUILD_YEAR)
379 " by Made to Order Software Corporation -- All Rights Reserved",
389 pp(
int argc,
char * argv[]);
394 std::shared_ptr<advgetopt::getopt>
f_opt;
398 pp::pp(
int argc,
char * argv[])
399 : f_opt(new advgetopt::getopt(g_options_environment, argc, argv))
401 if(
f_opt->is_defined(
"quiet"))
403 csspp::error::instance().set_hide_all(
true);
406 if(
f_opt->is_defined(
"debug"))
408 csspp::error::instance().set_show_debug(
true);
411 if(
f_opt->is_defined(
"Werror"))
413 csspp::error::instance().set_count_warnings_as_errors(
true);
416 if(
f_opt->is_defined(
"precision"))
424 csspp::lexer::pointer_t l;
425 csspp::position::pointer_t pos;
426 std::unique_ptr<std::stringstream> ss;
428 csspp::safe_precision_t safe_precision(
f_precision);
430 if(
f_opt->is_defined(
"--"))
433 int const arg_count(
f_opt->size(
"--"));
435 &&
f_opt->get_string(
"--") ==
"-")
438 pos.reset(
new csspp::position(
"-"));
439 l.reset(
new csspp::lexer(std::cin, *pos));
443 std::unique_ptr<char, void (*)(char *)> cwd(get_current_dir_name(),
free_char);
444 ss.reset(
new std::stringstream);
445 pos.reset(
new csspp::position(
"csspp.css"));
446 for(
int idx(0); idx < arg_count; ++idx)
449 std::string filename(
f_opt->get_string(
"--", idx));
452 csspp::error::instance() << *pos
453 <<
"You cannot include a file with an empty name." 454 << csspp::error_mode_t::ERROR_WARNING;
459 csspp::error::instance() << *pos
460 <<
"You cannot currently mix files and stdin. You may use @import \"filename\"; in your stdin data though." 461 << csspp::error_mode_t::ERROR_WARNING;
464 if(filename[0] ==
'/')
467 *ss <<
"@import \"" << filename <<
"\";\n";
472 *ss <<
"@import \"" << cwd.get() <<
"/" << filename <<
"\";\n";
475 l.reset(
new csspp::lexer(*ss, *pos));
481 pos.reset(
new csspp::position(
"-"));
482 l.reset(
new csspp::lexer(std::cin, *pos));
486 csspp::error_happened_t error_tracker;
488 csspp::node::pointer_t root(p.stylesheet());
489 if(error_tracker.error_happened())
494 csspp::node::pointer_t csspp_args(
new csspp::node(csspp::node_type_t::LIST, root->get_position()));
495 csspp::node::pointer_t args_var(
new csspp::node(csspp::node_type_t::VARIABLE, root->get_position()));
496 args_var->set_string(
"_csspp_args");
497 csspp::node::pointer_t wrapper(
new csspp::node(csspp::node_type_t::LIST, root->get_position()));
498 csspp::node::pointer_t array(
new csspp::node(csspp::node_type_t::ARRAY, root->get_position()));
499 wrapper->add_child(array);
500 csspp_args->add_child(args_var);
501 csspp_args->add_child(wrapper);
502 if(
f_opt->is_defined(
"args"))
504 int const count(
f_opt->size(
"args"));
505 for(
int idx(0); idx < count; ++idx)
507 csspp::node::pointer_t arg(
new csspp::node(csspp::node_type_t::STRING, root->get_position()));
508 arg->set_string(
f_opt->get_string(
"args", idx));
509 array->add_child(arg);
512 root->set_variable(
"_csspp_args", csspp_args);
517 c.set_date_time_variables(time(
nullptr));
520 if(
f_opt->is_defined(
"I"))
522 int const count(
f_opt->size(
"I"));
523 for(
int idx(0); idx < count; ++idx)
525 std::string
const path(
f_opt->get_string(
"I", idx));
537 if(
f_opt->is_defined(
"no-logo"))
542 if(
f_opt->is_defined(
"empty-on-undefined-variable"))
544 c.set_empty_on_undefined_variable(
true);
548 if(error_tracker.error_happened())
554 csspp::output_mode_t output_mode(csspp::output_mode_t::COMPRESSED);
555 if(
f_opt->is_defined(
"style"))
557 std::string
const mode(
f_opt->get_string(
"style"));
558 if(mode ==
"compressed")
560 output_mode = csspp::output_mode_t::COMPRESSED;
562 else if(mode ==
"tidy")
564 output_mode = csspp::output_mode_t::TIDY;
566 else if(mode ==
"compact")
568 output_mode = csspp::output_mode_t::COMPACT;
570 else if(mode ==
"expanded")
572 output_mode = csspp::output_mode_t::EXPANDED;
576 csspp::error::instance() << root->get_position()
577 <<
"The output mode \"" 579 <<
"\" is not supported. Try one of: compressed, tidy, compact, expanded instead." 580 << csspp::error_mode_t::ERROR_WARNING;
586 if(
f_opt->is_defined(
"output")
587 &&
f_opt->get_string(
"output") !=
"-")
589 out =
new std::ofstream(
f_opt->get_string(
"output"));
595 csspp::assembler a(*out);
596 a.output(c.get_root(), output_mode);
597 if(
f_opt->is_defined(
"output")
598 &&
f_opt->get_string(
"output") !=
"-")
602 if(error_tracker.error_happened())
614 int main(
int argc,
char *argv[])
618 pp preprocessor(argc, argv);
619 return preprocessor.compile();
621 catch(advgetopt::getopt_exit
const & except)
623 return except.code();
625 catch(csspp::csspp_exception_exit
const & e)
628 return e.exit_code();
630 catch(csspp::csspp_exception_logic
const & e)
632 std::cerr <<
"fatal error: a logic exception, which should NEVER occur, occurred: " << e.what() << std::endl;
635 catch(csspp::csspp_exception_overflow
const & e)
637 std::cerr <<
"fatal error: an overflow exception occurred: " << e.what() << std::endl;
640 catch(csspp::csspp_exception_runtime
const & e)
642 std::cerr <<
"fatal error: a runtime exception occurred: " << e.what() << std::endl;
645 catch(advgetopt::getopt_undefined
const & e)
647 std::cerr <<
"fatal error: an undefined exception occurred because of your command line: " << e.what() << std::endl;
650 catch(advgetopt::getopt_invalid
const & e)
652 std::cerr <<
"fatal error: there is an error on your command line, an exception occurred: " << e.what() << std::endl;
655 catch(advgetopt::getopt_invalid_default
const & e)
657 std::cerr <<
"fatal error: there is an error on your command line, you used a parameter without a value and there is no default. The exception says: " << e.what() << std::endl;
constexpr advgetopt::option g_options[]
advgetopt::options_environment const g_options_environment
pp(int argc, char *argv[])
int main(int argc, char *argv[])
void free_char(char *ptr)
std::shared_ptr< advgetopt::getopt > f_opt