From f8edfd22cb45b554a573d2722900196758e9e958 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 10 Dec 2009 09:47:29 +0200 Subject: Scanner-based parsing with support for element erasing Also implement argv_file_scanner which provides support for reading command line arguments from the argv array as well as files specified with command line options. New examples: file. New tests: ctor, erase, file. --- cli/header.cxx | 17 +++- cli/options.cli | 11 ++- cli/options.cxx | 84 +++++++++++++++--- cli/options.hxx | 30 +++++-- cli/options.ixx | 14 ++- cli/runtime-header.cxx | 82 +++++++++++++++++- cli/runtime-inline.cxx | 63 +++++++++++++- cli/runtime-source.cxx | 228 +++++++++++++++++++++++++++++++++++++++++++++++-- cli/source.cxx | 49 +++++++---- 9 files changed, 521 insertions(+), 57 deletions(-) (limited to 'cli') diff --git a/cli/header.cxx b/cli/header.cxx index 0cc9ede..012933d 100644 --- a/cli/header.cxx +++ b/cli/header.cxx @@ -73,30 +73,39 @@ namespace // string um ("::cli::unknown_mode"); - os << name << " (int argc," << endl + os << name << " (int& argc," << endl << "char** argv," << endl + << "bool erase = false," << endl << um << " option = " << um << "::fail," << endl << um << " argument = " << um << "::stop);" << endl; os << name << " (int start," << endl - << "int argc," << endl + << "int& argc," << endl << "char** argv," << endl + << "bool erase = false," << endl << um << " option = " << um << "::fail," << endl << um << " argument = " << um << "::stop);" << endl; - os << name << " (int argc," << endl + os << name << " (int& argc," << endl << "char** argv," << endl << "int& end," << endl + << "bool erase = false," << endl << um << " option = " << um << "::fail," << endl << um << " argument = " << um << "::stop);" << endl; os << name << " (int start," << endl - << "int argc," << endl + << "int& argc," << endl << "char** argv," << endl << "int& end," << endl + << "bool erase = false," << endl + << um << " option = " << um << "::fail," << endl + << um << " argument = " << um << "::stop);" + << endl; + + os << name << " (::cli::scanner&," << endl << um << " option = " << um << "::fail," << endl << um << " argument = " << um << "::stop);" << endl; diff --git a/cli/options.cli b/cli/options.cli index b9df64f..afd0f98 100644 --- a/cli/options.cli +++ b/cli/options.cli @@ -3,8 +3,8 @@ // copyright : Copyright (c) 2009 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file -// NOTE: Make sure you have a working CLI compiler around -// before modifying this file. +// NOTE: Make sure you have a working CLI compiler around before +// modifying this file. // include ; @@ -28,6 +28,13 @@ class options "Generate option value modifiers in addition to accessors." }; + bool --generate-file-scanner + { + "Generate the \c{argv_file_scanner} implementation. This scanner is + capable of reading command line arguments from the \c{argv} array as + well as files specified with command line options." + }; + bool --suppress-inline { "Generate all functions non-inline. By default simple functions are diff --git a/cli/options.cxx b/cli/options.cxx index 399069e..6d4ee87 100644 --- a/cli/options.cxx +++ b/cli/options.cxx @@ -132,7 +132,22 @@ namespace cli next () { if (i_ < argc_) - return argv_[i_++]; + { + const char* r (argv_[i_]); + + if (erase_) + { + for (int i (i_ + 1); i < argc_; ++i) + argv_[i - 1] = argv_[i]; + + --argc_; + argv_[argc_] = 0; + } + else + ++i_; + + return r; + } else throw eos_reached (); } @@ -141,7 +156,7 @@ namespace cli skip () { if (i_ < argc_) - i_++; + ++i_; else throw eos_reached (); } @@ -289,14 +304,16 @@ namespace cli // options:: -options (int argc, +options (int& argc, char** argv, + bool erase, ::cli::unknown_mode opt, ::cli::unknown_mode arg) : help_ (), version_ (), output_dir_ (), generate_modifier_ (), + generate_file_scanner_ (), suppress_inline_ (), suppress_usage_ (), long_usage_ (), @@ -322,20 +339,22 @@ options (int argc, guard_prefix_ (), reserved_name_ () { - ::cli::argv_scanner s (argc, argv); + ::cli::argv_scanner s (argc, argv, erase); _parse (s, opt, arg); } options:: options (int start, - int argc, + int& argc, char** argv, + bool erase, ::cli::unknown_mode opt, ::cli::unknown_mode arg) : help_ (), version_ (), output_dir_ (), generate_modifier_ (), + generate_file_scanner_ (), suppress_inline_ (), suppress_usage_ (), long_usage_ (), @@ -361,20 +380,22 @@ options (int start, guard_prefix_ (), reserved_name_ () { - ::cli::argv_scanner s (start, argc, argv); + ::cli::argv_scanner s (start, argc, argv, erase); _parse (s, opt, arg); } options:: -options (int argc, +options (int& argc, char** argv, int& end, + bool erase, ::cli::unknown_mode opt, ::cli::unknown_mode arg) : help_ (), version_ (), output_dir_ (), generate_modifier_ (), + generate_file_scanner_ (), suppress_inline_ (), suppress_usage_ (), long_usage_ (), @@ -400,22 +421,24 @@ options (int argc, guard_prefix_ (), reserved_name_ () { - ::cli::argv_scanner s (argc, argv); + ::cli::argv_scanner s (argc, argv, erase); _parse (s, opt, arg); end = s.end (); } options:: options (int start, - int argc, + int& argc, char** argv, int& end, + bool erase, ::cli::unknown_mode opt, ::cli::unknown_mode arg) : help_ (), version_ (), output_dir_ (), generate_modifier_ (), + generate_file_scanner_ (), suppress_inline_ (), suppress_usage_ (), long_usage_ (), @@ -441,11 +464,48 @@ options (int start, guard_prefix_ (), reserved_name_ () { - ::cli::argv_scanner s (start, argc, argv); + ::cli::argv_scanner s (start, argc, argv, erase); _parse (s, opt, arg); end = s.end (); } +options:: +options (::cli::scanner& s, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: help_ (), + version_ (), + output_dir_ (), + generate_modifier_ (), + generate_file_scanner_ (), + suppress_inline_ (), + suppress_usage_ (), + long_usage_ (), + option_length_ (0), + generate_cxx_ (), + generate_man_ (), + generate_html_ (), + man_prologue_ (), + man_epilogue_ (), + html_prologue_ (), + html_epilogue_ (), + class__ (), + stdout_ (), + hxx_suffix_ (".hxx"), + ixx_suffix_ (".ixx"), + cxx_suffix_ (".cxx"), + man_suffix_ (".1"), + html_suffix_ (".html"), + option_prefix_ ("-"), + option_separator_ ("--"), + include_with_brackets_ (), + include_prefix_ (), + guard_prefix_ (), + reserved_name_ () +{ + _parse (s, opt, arg); +} + void options:: print_usage (::std::ostream& os) { @@ -459,6 +519,8 @@ print_usage (::std::ostream& os) os << "--generate-modifier Generate option value modifiers in addition to" << ::std::endl << " accessors." << ::std::endl; + os << "--generate-file-scanner Generate the 'argv_file_scanner' implementation." << ::std::endl; + os << "--suppress-inline Generate all functions non-inline." << ::std::endl; os << "--suppress-usage Suppress the generation of the usage printing code." << ::std::endl; @@ -547,6 +609,8 @@ struct _cli_options_map_init &::cli::thunk< options, std::string, &options::output_dir_ >; _cli_options_map_["--generate-modifier"] = &::cli::thunk< options, bool, &options::generate_modifier_ >; + _cli_options_map_["--generate-file-scanner"] = + &::cli::thunk< options, bool, &options::generate_file_scanner_ >; _cli_options_map_["--suppress-inline"] = &::cli::thunk< options, bool, &options::suppress_inline_ >; _cli_options_map_["--suppress-usage"] = diff --git a/cli/options.hxx b/cli/options.hxx index 2be8e91..54143b9 100644 --- a/cli/options.hxx +++ b/cli/options.hxx @@ -166,8 +166,8 @@ namespace cli class argv_scanner: public scanner { public: - argv_scanner (int argc, char** argv); - argv_scanner (int start, int argc, char** argv); + argv_scanner (int& argc, char** argv, bool erase = false); + argv_scanner (int start, int& argc, char** argv, bool erase = false); int end () const; @@ -184,9 +184,11 @@ namespace cli virtual void skip (); - private:int i_; - int argc_; + private: + int i_; + int& argc_; char** argv_; + bool erase_; }; } @@ -202,27 +204,35 @@ class options { public: - options (int argc, + options (int& argc, char** argv, + bool erase = false, ::cli::unknown_mode option = ::cli::unknown_mode::fail, ::cli::unknown_mode argument = ::cli::unknown_mode::stop); options (int start, - int argc, + int& argc, char** argv, + bool erase = false, ::cli::unknown_mode option = ::cli::unknown_mode::fail, ::cli::unknown_mode argument = ::cli::unknown_mode::stop); - options (int argc, + options (int& argc, char** argv, int& end, + bool erase = false, ::cli::unknown_mode option = ::cli::unknown_mode::fail, ::cli::unknown_mode argument = ::cli::unknown_mode::stop); options (int start, - int argc, + int& argc, char** argv, int& end, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (::cli::scanner&, ::cli::unknown_mode option = ::cli::unknown_mode::fail, ::cli::unknown_mode argument = ::cli::unknown_mode::stop); @@ -242,6 +252,9 @@ class options generate_modifier () const; const bool& + generate_file_scanner () const; + + const bool& suppress_inline () const; const bool& @@ -329,6 +342,7 @@ class options bool version_; std::string output_dir_; bool generate_modifier_; + bool generate_file_scanner_; bool suppress_inline_; bool suppress_usage_; bool long_usage_; diff --git a/cli/options.ixx b/cli/options.ixx index 6fcc80f..74d7b15 100644 --- a/cli/options.ixx +++ b/cli/options.ixx @@ -87,14 +87,14 @@ namespace cli // argv_scanner // inline argv_scanner:: - argv_scanner (int argc, char** argv) - : i_ (1), argc_ (argc), argv_ (argv) + argv_scanner (int& argc, char** argv, bool erase) + : i_ (1), argc_ (argc), argv_ (argv), erase_ (erase) { } inline argv_scanner:: - argv_scanner (int start, int argc, char** argv) - : i_ (start), argc_ (argc), argv_ (argv) + argv_scanner (int start, int& argc, char** argv, bool erase) + : i_ (start), argc_ (argc), argv_ (argv), erase_ (erase) { } @@ -133,6 +133,12 @@ generate_modifier () const } inline const bool& options:: +generate_file_scanner () const +{ + return this->generate_file_scanner_; +} + +inline const bool& options:: suppress_inline () const { return this->suppress_inline_; diff --git a/cli/runtime-header.cxx b/cli/runtime-header.cxx index cf3ebd3..5da33c0 100644 --- a/cli/runtime-header.cxx +++ b/cli/runtime-header.cxx @@ -12,6 +12,9 @@ generate_runtime_header (context& ctx) { ostream& os (ctx.os); + if (ctx.options.generate_file_scanner ()) + os << "#include " << endl; + os << "#include " << endl << "#include " << endl << "#include " << endl @@ -155,6 +158,30 @@ generate_runtime_header (context& ctx) << "what () const throw ();" << "};"; + if (ctx.options.generate_file_scanner ()) + { + os << "class file_io_failure: public exception" + << "{" + << "public:" << endl + << "virtual" << endl + << "~file_io_failure () throw ();" + << endl + << "file_io_failure (const std::string& file);" + << endl + << "const std::string&" << endl + << "file () const;" + << endl + << "virtual void" << endl + << "print (std::ostream&) const;" + << endl + << "virtual const char*" << endl + << "what () const throw ();" + << endl + << "private:" << endl + << "std::string file_;" + << "};"; + } + // scanner // os << "class scanner" @@ -181,8 +208,8 @@ generate_runtime_header (context& ctx) os << "class argv_scanner: public scanner" << "{" << "public:" << endl - << "argv_scanner (int argc, char** argv);" - << "argv_scanner (int start, int argc, char** argv);" + << "argv_scanner (int& argc, char** argv, bool erase = false);" + << "argv_scanner (int start, int& argc, char** argv, bool erase = false);" << endl << "int" << endl << "end () const;" @@ -199,11 +226,58 @@ generate_runtime_header (context& ctx) << "virtual void" << endl << "skip ();" << endl - << "private:" + << "private:" << endl << "int i_;" - << "int argc_;" + << "int& argc_;" << "char** argv_;" + << "bool erase_;" << "};"; + // argv_file_scanner + // + if (ctx.options.generate_file_scanner ()) + { + os << "class argv_file_scanner: public argv_scanner" + << "{" + << "public:" << endl + << "argv_file_scanner (int& argc," << endl + << "char** argv," << endl + << "const std::string& file_option," << endl + << "bool erase = false);" + << endl + << "argv_file_scanner (int start," << endl + << "int& argc," << endl + << "char** argv," << endl + << "const std::string& file_option," << endl + << "bool erase = false);" + << endl + << "virtual bool" << endl + << "more ();" + << endl + << "virtual const char*" << endl + << "peek ();" + << endl + << "virtual const char*" << endl + << "next ();" + << endl + << "virtual void" << endl + << "skip ();" + << endl + << "private:" << endl + << "void" << endl + << "load (const char* file);" + << endl + << "typedef argv_scanner base;" + << endl + << "const std::string option_;" + << "std::string hold_;" + << "std::deque args_;"; + + if (!ctx.opt_sep.empty ()) + os << "bool skip_;"; + + os << "};"; + } + os << "}"; // namespace cli } diff --git a/cli/runtime-inline.cxx b/cli/runtime-inline.cxx index d4ce3ec..c99739c 100644 --- a/cli/runtime-inline.cxx +++ b/cli/runtime-inline.cxx @@ -103,18 +103,36 @@ generate_runtime_inline (context& ctx) << "return value_;" << "}"; + if (ctx.options.generate_file_scanner ()) + { + os << "// file_io_failure" << endl + << "//" << endl + + << inl << "file_io_failure::" << endl + << "file_io_failure (const std::string& file)" << endl + << ": file_ (file)" + << "{" + << "}" + + << inl << "const std::string& file_io_failure::" << endl + << "file () const" + << "{" + << "return file_;" + << "}"; + } + os << "// argv_scanner" << endl << "//" << endl; os << inl << "argv_scanner::" << endl - << "argv_scanner (int argc, char** argv)" << endl - << ": i_ (1), argc_ (argc), argv_ (argv)" + << "argv_scanner (int& argc, char** argv, bool erase)" << endl + << ": i_ (1), argc_ (argc), argv_ (argv), erase_ (erase)" << "{" << "}"; os << inl << "argv_scanner::" << endl - << "argv_scanner (int start, int argc, char** argv)" << endl - << ": i_ (start), argc_ (argc), argv_ (argv)" + << "argv_scanner (int start, int& argc, char** argv, bool erase)" << endl + << ": i_ (start), argc_ (argc), argv_ (argv), erase_ (erase)" << "{" << "}"; @@ -124,5 +142,42 @@ generate_runtime_inline (context& ctx) << "return i_;" << "}"; + // argv_file_scanner + // + if (ctx.options.generate_file_scanner ()) + { + bool sep (!ctx.opt_sep.empty ()); + + os << "// argv_file_scanner" << endl + << "//" << endl; + + os << inl << "argv_file_scanner::" << endl + << "argv_file_scanner (int& argc," << endl + << "char** argv," << endl + << "const std::string& option," << endl + << "bool erase)" << endl + << ": argv_scanner (argc, argv, erase)," << endl + << " option_ (option)"; + if (sep) + os << "," << endl + << " skip_ (false)"; + os << "{" + << "}"; + + os << inl << "argv_file_scanner::" << endl + << "argv_file_scanner (int start," << endl + << "int& argc," << endl + << "char** argv," << endl + << "const std::string& option," << endl + << "bool erase)" << endl + << ": argv_scanner (start, argc, argv, erase)," << endl + << " option_ (option)"; + if (sep) + os << "," << endl + << " skip_ (false)"; + os << "{" + << "}"; + } + os << "}"; // namespace cli } diff --git a/cli/runtime-source.cxx b/cli/runtime-source.cxx index 3003b6b..323b604 100644 --- a/cli/runtime-source.cxx +++ b/cli/runtime-source.cxx @@ -17,8 +17,13 @@ generate_runtime_source (context& ctx) << "#include " << endl << "#include " << endl << "#include " << endl - << "#include " << endl - << endl; + << "#include " << endl; + + if (ctx.options.generate_file_scanner ()) + os << "#include " << endl + << "#include " << endl; + + os << endl; os << "namespace cli" << "{"; @@ -31,11 +36,13 @@ generate_runtime_source (context& ctx) << "~unknown_option () throw ()" << "{" << "}" + << "void unknown_option::" << endl << "print (std::ostream& os) const" << "{" << "os << \"unknown option '\" << option () << \"'\";" << "}" + << "const char* unknown_option::" << endl << "what () const throw ()" << "{" @@ -50,11 +57,13 @@ generate_runtime_source (context& ctx) << "~unknown_argument () throw ()" << "{" << "}" + << "void unknown_argument::" << endl << "print (std::ostream& os) const" << "{" << "os << \"unknown argument '\" << argument () << \"'\";" << "}" + << "const char* unknown_argument::" << endl << "what () const throw ()" << "{" @@ -69,11 +78,13 @@ generate_runtime_source (context& ctx) << "~missing_value () throw ()" << "{" << "}" + << "void missing_value::" << endl << "print (std::ostream& os) const" << "{" << "os << \"missing value for option '\" << option () << \"'\";" << "}" + << "const char* missing_value::" << endl << "what () const throw ()" << "{" @@ -88,12 +99,14 @@ generate_runtime_source (context& ctx) << "~invalid_value () throw ()" << "{" << "}" + << "void invalid_value::" << endl << "print (std::ostream& os) const" << "{" << "os << \"invalid value '\" << value () << \"' for option '\"" << endl << " << option () << \"'\";" << "}" + << "const char* invalid_value::" << endl << "what () const throw ()" << "{" @@ -109,12 +122,37 @@ generate_runtime_source (context& ctx) << "{" << "os << what ();" << "}" + << "const char* eos_reached::" << endl << "what () const throw ()" << "{" << "return \"end of argument stream reached\";" << "}"; + // file_io_failure + // + if (ctx.options.generate_file_scanner ()) + { + os << "// file_io_failure" << endl + << "//" << endl + << "file_io_failure::" << endl + << "~file_io_failure () throw ()" + << "{" + << "}" + + << "void file_io_failure::" << endl + << "print (std::ostream& os) const" + << "{" + << "os << \"unable to open file '\" << file () << \"' or read failure\";" + << "}" + + << "const char* file_io_failure::" << endl + << "what () const throw ()" + << "{" + << "return \"unable to open file or read failure\";" + << "}"; + } + // scanner // os << "// scanner" << endl @@ -147,8 +185,23 @@ generate_runtime_source (context& ctx) << "const char* argv_scanner::" << endl << "next ()" << "{" - << "if (i_ < argc_)" << endl - << "return argv_[i_++];" + << "if (i_ < argc_)" + << "{" + << "const char* r (argv_[i_]);" + << endl + << "if (erase_)" + << "{" + << "for (int i (i_ + 1); i < argc_; ++i)" << endl + << "argv_[i - 1] = argv_[i];" + << endl + << "--argc_;" + << "argv_[argc_] = 0;" + << "}" + << "else" << endl + << "++i_;" + << endl + << "return r;" + << "}" << "else" << endl << "throw eos_reached ();" << "}" @@ -157,11 +210,176 @@ generate_runtime_source (context& ctx) << "skip ()" << "{" << "if (i_ < argc_)" << endl - << "i_++;" + << "++i_;" << "else" << endl << "throw eos_reached ();" << "}"; + // argv_file_scanner + // + if (ctx.options.generate_file_scanner ()) + { + bool sep (!ctx.opt_sep.empty ()); + + os << "// argv_file_scanner" << endl + << "//" << endl + + << "bool argv_file_scanner::" << endl + << "more ()" + << "{" + << "if (!args_.empty ())" << endl + << "return true;" + << endl + << "while (base::more ())" + << "{" + << "// See if the next argument is the file option." << endl + << "//" << endl + << "const char* a (base::peek ());" + << endl + << "if (" << (sep ? "!skip_ && " : "") << "a == option_)" + << "{" + << "base::next ();" + << endl + << "if (!base::more ())" << endl + << "throw missing_value (option_);" + << endl + << "load (base::next ());" + << endl + << "if (!args_.empty ())" << endl + << "return true;" + << "}" + << "else" + << "{"; + if (sep) + os << "if (!skip_)" << endl + << "skip_ = (std::strcmp (a, \"" << ctx.opt_sep << "\") == 0);" + << endl; + os << "return true;" + << "}" + << "}" // while + << "return false;" + << "}" + + << "const char* argv_file_scanner::" << endl + << "peek ()" + << "{" + << "if (!more ())" << endl + << "throw eos_reached ();" + << endl + << "return args_.empty () ? base::peek () : args_.front ().c_str ();" + << "}" + + << "const char* argv_file_scanner::" << endl + << "next ()" + << "{" + << "if (!more ())" << endl + << "throw eos_reached ();" + << endl + << "if (args_.empty ())" << endl + << "return base::next ();" + << "else" + << "{" + << "hold_.swap (args_.front ());" + << "args_.pop_front ();" + << "return hold_.c_str ();" + << "}" + << "}" + + << "void argv_file_scanner::" << endl + << "skip ()" + << "{" + << "if (!more ())" << endl + << "throw eos_reached ();" + << endl + << "if (args_.empty ())" << endl + << "return base::skip ();" + << "else" << endl + << "args_.pop_front ();" + << "}" + + << "void argv_file_scanner::" << endl + << "load (const char* file)" + << "{" + << "using namespace std;" + << endl + << "ifstream is (file);" + << endl + << "if (!is.is_open ())" << endl + << "throw file_io_failure (file);" + << endl + << "while (!is.eof ())" + << "{" + << "string line;" + << "getline (is, line);" + << endl + << "if (is.fail () && !is.eof ())" << endl + << "throw file_io_failure (file);" + << endl + << "string::size_type n (line.size ());" + << endl + << "// Trim the line from leading and trailing whitespaces." << endl + << "//" << endl + << "if (n != 0)" + << "{" + << "const char* f (line.c_str ());" + << "const char* l (f + n);" + << endl + << "const char* of (f);" + << "while (f < l && (*f == ' ' || *f == '\\t' || *f == '\\r'))" << endl + << "++f;" + << endl + << "--l;" + << endl + << "const char* ol (l);" + << "while (l > f && (*l == ' ' || *l == '\\t' || *l == '\\r'))" << endl + << "--l;" + << endl + << "if (f != of || l != ol)" << endl + << "line = f <= l ? string (f, l - f + 1) : string ();" + << "}" + << "// Ignore empty lines, those that start with #." << endl + << "//" << endl + << "if (line.empty () || line[0] == '#')" << endl + << "continue;" + << endl + << "string::size_type p (line.find (' '));" + << endl + << "if (p == string::npos)" + << "{"; + if (sep) + os << "if (!skip_)" << endl + << "skip_ = (line == \"" << ctx.opt_sep << "\");" + << endl; + os << "args_.push_back (line);" + << "}" + << "else" + << "{" + << "string s1 (line, 0, p);" + << endl + << "// Skip leading whitespaces in the argument." << endl + << "//" << endl + << "n = line.size ();" + << "for (++p; p < n; ++p)" + << "{" + << "char c (line[p]);" + << endl + << "if (c != ' ' && c != '\\t' && c != '\\r')" << endl + << "break;" + << "}" + << "string s2 (line, p);" + << endl + << "if (" << (sep ? "!skip_ && " : "") << "s1 == option_)" << endl + << "load (s2.c_str ());" + << "else" + << "{" + << "args_.push_back (s1);" + << "args_.push_back (s2);" + << "}" + << "}" + << "}" // while + << "}"; + } + // parser class template & its specializations // os << "template " << endl diff --git a/cli/source.cxx b/cli/source.cxx index 5f0b199..1c0b890 100644 --- a/cli/source.cxx +++ b/cli/source.cxx @@ -24,7 +24,11 @@ namespace os << "," << endl << " "; else + { + os << endl + << ": "; comma_ = true; + } os << emember (o); @@ -356,75 +360,88 @@ namespace string um ("::cli::unknown_mode"); os << name << "::" << endl - << name << " (int argc," << endl + << name << " (int& argc," << endl << "char** argv," << endl + << "bool erase," << endl << um << " opt," << endl - << um << " arg)" << endl - << ": "; + << um << " arg)"; { option_init init (*this); traversal::names names_init (init); names (c, names_init); } os << "{" - << "::cli::argv_scanner s (argc, argv);" + << "::cli::argv_scanner s (argc, argv, erase);" << "_parse (s, opt, arg);" << "}"; os << name << "::" << endl << name << " (int start," << endl - << "int argc," << endl + << "int& argc," << endl << "char** argv," << endl + << "bool erase," << endl << um << " opt," << endl - << um << " arg)" << endl - << ": "; + << um << " arg)"; { option_init init (*this); traversal::names names_init (init); names (c, names_init); } os << "{" - << "::cli::argv_scanner s (start, argc, argv);" + << "::cli::argv_scanner s (start, argc, argv, erase);" << "_parse (s, opt, arg);" << "}"; os << name << "::" << endl - << name << " (int argc," << endl + << name << " (int& argc," << endl << "char** argv," << endl << "int& end," << endl + << "bool erase," << endl << um << " opt," << endl - << um << " arg)" << endl - << ": "; + << um << " arg)"; { option_init init (*this); traversal::names names_init (init); names (c, names_init); } os << "{" - << "::cli::argv_scanner s (argc, argv);" + << "::cli::argv_scanner s (argc, argv, erase);" << "_parse (s, opt, arg);" << "end = s.end ();" << "}"; os << name << "::" << endl << name << " (int start," << endl - << "int argc," << endl + << "int& argc," << endl << "char** argv," << endl << "int& end," << endl + << "bool erase," << endl << um << " opt," << endl - << um << " arg)" << endl - << ": "; + << um << " arg)"; { option_init init (*this); traversal::names names_init (init); names (c, names_init); } os << "{" - << "::cli::argv_scanner s (start, argc, argv);" + << "::cli::argv_scanner s (start, argc, argv, erase);" << "_parse (s, opt, arg);" << "end = s.end ();" << "}"; + os << name << "::" << endl + << name << " (::cli::scanner& s," << endl + << um << " opt," << endl + << um << " arg)"; + { + option_init init (*this); + traversal::names names_init (init); + names (c, names_init); + } + os << "{" + << "_parse (s, opt, arg);" + << "}"; + // usage // if (usage) -- cgit v1.1