From c2b7e8a5a7bc98bcf5e03b32eefaa664442c26fe Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 27 Sep 2009 19:17:22 +0200 Subject: Add option file for the CLI compiler itself --- cli/options.cxx | 328 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 cli/options.cxx (limited to 'cli/options.cxx') diff --git a/cli/options.cxx b/cli/options.cxx new file mode 100644 index 0000000..6aba013 --- /dev/null +++ b/cli/options.cxx @@ -0,0 +1,328 @@ +// This code was generated by CLI, a command line interface +// compiler for C++. +// + +#include "options.hxx" + +// options +// + +bool const& options:: +help () const +{ + return help_; +} + +bool const& options:: +version () const +{ + return version_; +} + +std::string const& options:: +output_dir () const +{ + return output_dir_; +} + +#include +#include +#include +#include + +namespace cli +{ + // unknown_option + // + unknown_option:: + ~unknown_option () throw () + { + } + + void unknown_option:: + print (std::ostream& os) const + { + os << "unknown option '" << option () << "'"; + } + + const char* unknown_option:: + what () const throw () + { + return "unknown option"; + } + + // unknown_argument + // + unknown_argument:: + ~unknown_argument () throw () + { + } + + void unknown_argument:: + print (std::ostream& os) const + { + os << "unknown argument '" << argument () << "'"; + } + + const char* unknown_argument:: + what () const throw () + { + return "unknown argument"; + } + + // missing_value + // + missing_value:: + ~missing_value () throw () + { + } + + void missing_value:: + print (std::ostream& os) const + { + os << "missing value for option '" << option () << "'"; + } + + const char* missing_value:: + what () const throw () + { + return "missing option value"; + } + + // invalid_value + // + invalid_value:: + ~invalid_value () throw () + { + } + + void invalid_value:: + print (std::ostream& os) const + { + os << "invalid value '" << value () << "' for option '" + << option () << "'"; + } + + const char* invalid_value:: + what () const throw () + { + return "invalid option value"; + } + + template + struct parser + { + static int + parse (X& x, char** argv, int n) + { + if (n > 1) + { + std::istringstream is (argv[1]); + if (!(is >> x && is.eof ())) + throw invalid_value (argv[0], argv[1]); + return 2; + } + else + throw missing_value (argv[0]); + } + }; + + template <> + struct parser + { + static int + parse (bool& x, char**, int) + { + x = true; + return 1; + } + }; + + template <> + struct parser + { + static int + parse (std::string& x, char** argv, int n) + { + if (n > 1) + { + x = argv[1]; + return 2; + } + else + throw missing_value (argv[0]); + } + }; + + template + struct parser > + { + static int + parse (std::vector& v, char** argv, int n) + { + X x; + int i (parser::parse (x, argv, n)); + v.push_back (x); + return i; + } + }; + + template + int + thunk (X& x, char** argv, int n) + { + return parser::parse (x.*P, argv, n); + } +} + +#include +#include + +// options +// + +options:: +options (int argc, + char** argv, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: help_ (), + version_ (), + output_dir_ () +{ + _parse (1, argc, argv, opt, arg); +} + +options:: +options (int start, + int argc, + char** argv, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: help_ (), + version_ (), + output_dir_ () +{ + _parse (start, argc, argv, opt, arg); +} + +options:: +options (int argc, + char** argv, + int& end, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: help_ (), + version_ (), + output_dir_ () +{ + end = _parse (1, argc, argv, opt, arg); +} + +options:: +options (int start, + int argc, + char** argv, + int& end, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: help_ (), + version_ (), + output_dir_ () +{ + end = _parse (start, argc, argv, opt, arg); +} + +typedef +std::map +_cli_options_map; + +static _cli_options_map _cli_options_map_; + +struct _cli_options_map_init +{ + _cli_options_map_init () + { + _cli_options_map_["--help"] = + &::cli::thunk; + _cli_options_map_["--version"] = + &::cli::thunk; + _cli_options_map_["--output-dir"] = + &::cli::thunk; + } +} _cli_options_map_init_; + +int options:: +_parse (int start, + int argc, + char** argv, + ::cli::unknown_mode opt_mode, + ::cli::unknown_mode arg_mode) +{ + bool opt (true); + + for (; start < argc;) + { + const char* s (argv[start]); + + if (std::strcmp (s, "--") == 0) + { + start++; + opt = false; + continue; + } + + _cli_options_map::const_iterator i ( + opt ? _cli_options_map_.find (s) : _cli_options_map_.end ()); + + if (i != _cli_options_map_.end ()) + { + start += (*(i->second)) (*this, argv + start, argc - start); + } + else if (opt && s[0] == '-' && s[1] != '\0') + { + switch (opt_mode) + { + case ::cli::unknown_mode::skip: + { + start++; + continue; + } + case ::cli::unknown_mode::stop: + { + break; + } + case ::cli::unknown_mode::fail: + { + throw ::cli::unknown_option (s); + } + } + + break; + } + else + { + switch (arg_mode) + { + case ::cli::unknown_mode::skip: + { + start++; + continue; + } + case ::cli::unknown_mode::stop: + { + break; + } + case ::cli::unknown_mode::fail: + { + throw ::cli::unknown_argument (s); + } + } + + break; + } + } + + return start; +} + -- cgit v1.1