From 6a9a911f05bbd0d2a63a06512733a4a6ff5b3e65 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 4 Oct 2009 13:58:20 +0200 Subject: Add --option-{prefix,separator} options --- cli/context.cxx | 6 +++- cli/context.hxx | 4 ++- cli/options.cli | 3 ++ cli/options.cxx | 26 ++++++++++++++ cli/options.hxx | 8 +++++ cli/options.ixx | 12 +++++++ cli/source.cxx | 106 ++++++++++++++++++++++++++++++++++---------------------- 7 files changed, 121 insertions(+), 44 deletions(-) diff --git a/cli/context.cxx b/cli/context.cxx index b82a318..3f3261c 100644 --- a/cli/context.cxx +++ b/cli/context.cxx @@ -16,10 +16,12 @@ context (ostream& os_, semantics::cli_unit& unit_, options_type const& ops) unit (unit_), options (ops), inl (data_->inl_), + opt_prefix (options.option_prefix ()), + opt_sep (options.option_separator ()), reserved_name_map (options.reserved_name ()) { if (!options.suppress_inline ()) - inl = "inline "; + data_->inl_ = "inline "; } context:: @@ -29,6 +31,8 @@ context (context& c) unit (c.unit), options (c.options), inl (c.inl), + opt_prefix (c.opt_prefix), + opt_sep (c.opt_sep), reserved_name_map (c.reserved_name_map) { } diff --git a/cli/context.hxx b/cli/context.hxx index f57ac7f..37864af 100644 --- a/cli/context.hxx +++ b/cli/context.hxx @@ -35,7 +35,9 @@ public: semantics::cli_unit& unit; options_type const& options; - string& inl; + string const& inl; + string const& opt_prefix; + string const& opt_sep; typedef std::map reserved_name_map_type; reserved_name_map_type const& reserved_name_map; diff --git a/cli/options.cli b/cli/options.cli index 3fe6fa8..e2549fa 100644 --- a/cli/options.cli +++ b/cli/options.cli @@ -23,6 +23,9 @@ class options std::string --ixx-suffix = ".ixx"; std::string --cxx-suffix = ".cxx"; + std::string --option-prefix = "-"; + std::string --option-separator = "--"; + bool --include-with-brackets; std::string --include-prefix; std::string --guard-prefix; diff --git a/cli/options.cxx b/cli/options.cxx index 1cbbfb4..d92af58 100644 --- a/cli/options.cxx +++ b/cli/options.cxx @@ -5,6 +5,7 @@ #include "options.hxx" #include +#include #include #include #include @@ -147,6 +148,19 @@ namespace cli } }; + template + struct parser > + { + static int + parse (std::set& s, char** argv, int n) + { + X x; + int i (parser::parse (x, argv, n)); + s.insert (x); + return i; + } + }; + template struct parser > { @@ -231,6 +245,8 @@ options (int argc, hxx_suffix_ (".hxx"), ixx_suffix_ (".ixx"), cxx_suffix_ (".cxx"), + option_prefix_ ("-"), + option_separator_ ("--"), include_with_brackets_ (), include_prefix_ (), guard_prefix_ (), @@ -252,6 +268,8 @@ options (int start, hxx_suffix_ (".hxx"), ixx_suffix_ (".ixx"), cxx_suffix_ (".cxx"), + option_prefix_ ("-"), + option_separator_ ("--"), include_with_brackets_ (), include_prefix_ (), guard_prefix_ (), @@ -273,6 +291,8 @@ options (int argc, hxx_suffix_ (".hxx"), ixx_suffix_ (".ixx"), cxx_suffix_ (".cxx"), + option_prefix_ ("-"), + option_separator_ ("--"), include_with_brackets_ (), include_prefix_ (), guard_prefix_ (), @@ -295,6 +315,8 @@ options (int start, hxx_suffix_ (".hxx"), ixx_suffix_ (".ixx"), cxx_suffix_ (".cxx"), + option_prefix_ ("-"), + option_separator_ ("--"), include_with_brackets_ (), include_prefix_ (), guard_prefix_ (), @@ -329,6 +351,10 @@ struct _cli_options_map_init &::cli::thunk; _cli_options_map_["--cxx-suffix"] = &::cli::thunk; + _cli_options_map_["--option-prefix"] = + &::cli::thunk; + _cli_options_map_["--option-separator"] = + &::cli::thunk; _cli_options_map_["--include-with-brackets"] = &::cli::thunk; _cli_options_map_["--include-prefix"] = diff --git a/cli/options.hxx b/cli/options.hxx index 2906344..97f1246 100644 --- a/cli/options.hxx +++ b/cli/options.hxx @@ -227,6 +227,12 @@ class options std::string const& cxx_suffix () const; + std::string const& + option_prefix () const; + + std::string const& + option_separator () const; + bool const& include_with_brackets () const; @@ -255,6 +261,8 @@ class options std::string hxx_suffix_; std::string ixx_suffix_; std::string cxx_suffix_; + std::string option_prefix_; + std::string option_separator_; bool include_with_brackets_; std::string include_prefix_; std::string guard_prefix_; diff --git a/cli/options.ixx b/cli/options.ixx index 12cb277..01fbd37 100644 --- a/cli/options.ixx +++ b/cli/options.ixx @@ -47,6 +47,18 @@ cxx_suffix () const return cxx_suffix_; } +inline std::string const& options:: +option_prefix () const +{ + return option_prefix_; +} + +inline std::string const& options:: +option_separator () const +{ + return option_separator_; +} + inline bool const& options:: include_with_brackets () const { diff --git a/cli/source.cxx b/cli/source.cxx index afac17e..991968c 100644 --- a/cli/source.cxx +++ b/cli/source.cxx @@ -193,60 +193,82 @@ namespace << "} " << map << "_init_;" << endl; + bool pfx (!opt_prefix.empty ()); + bool sep (!opt_sep.empty ()); + os << "int " << name << "::" << endl << "_parse (int start," << endl << "int argc," << endl << "char** argv," << endl << um << " opt_mode," << endl << um << " arg_mode)" + << "{"; + + if (sep) + os << "bool opt (true);" // Still recognizing options. + << endl; + + os << "for (; start < argc;)" << "{" - << "bool opt (true);" // Still recognizing options. - << endl - << "for (; start < argc;)" - << "{" - << "const char* s (argv[start]);" - << endl - << "if (std::strcmp (s, \"--\") == 0)" - << "{" - << "start++;" - << "opt = false;" - << "continue;" - << "}" - << map << "::const_iterator i (" << endl - << "opt ? " << map << "_.find (s) : " << map << "_.end ());" - << endl + << "const char* s (argv[start]);"; + + if (sep) + os << endl + << "if (std::strcmp (s, \"" << opt_sep << "\") == 0)" + << "{" + << "start++;" + << "opt = false;" + << "continue;" + << "}" + << map << "::const_iterator i (" << endl + << "opt ? " << map << "_.find (s) : " << map << "_.end ());"; + else + os << map << "::const_iterator i (" << map << "_.find (s));"; + + os << endl << "if (i != " << map << "_.end ())" << "{" << "start += (*(i->second)) (*this, argv + start, argc - start);" - << "}" - << "else if (opt && s[0] == '-' && s[1] != '\\0')" - << "{" + << "}"; - // Unknown option. - // - << "switch (opt_mode)" - << "{" - << "case ::cli::unknown_mode::skip:" << endl - << "{" - << "start++;" - << "continue;" - << "}" - << "case ::cli::unknown_mode::stop:" << endl - << "{" - << "break;" - << "}" - << "case ::cli::unknown_mode::fail:" << endl - << "{" - << "throw ::cli::unknown_option (s);" - << "}" - << "}" // switch - << "break;" // The stop case. - << "}" - << "else" - << "{" + // Unknown option. + // + if (pfx) + { + size_t n (opt_prefix.size ()); + + os << "else if ("; + + if (sep) + os << "opt && "; + + os << "std::strncmp (s, \"" << opt_prefix << "\", " << + n << ") == 0 && s[" << n << "] != '\\0')" + << "{" + << "switch (opt_mode)" + << "{" + << "case ::cli::unknown_mode::skip:" << endl + << "{" + << "start++;" + << "continue;" + << "}" + << "case ::cli::unknown_mode::stop:" << endl + << "{" + << "break;" + << "}" + << "case ::cli::unknown_mode::fail:" << endl + << "{" + << "throw ::cli::unknown_option (s);" + << "}" + << "}" // switch + << "break;" // The stop case. + << "}"; + } - // Unknown argument. - // + // Unknown argument. + // + os << "else" + << "{" << "switch (arg_mode)" << "{" << "case ::cli::unknown_mode::skip:" << endl -- cgit v1.1