summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-11-28 11:41:15 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-11-28 11:41:15 +0200
commit36e3bc290d58ad29692a4d594f37a6cb761912c7 (patch)
tree3ebbc1edf910e5168fb819404ecedbf23c95b9d0
parenta376ccf37122f0768fce8e3c5a16561e01ee2351 (diff)
Use a scanner interface instead of argc/argv
This will allow supporting other sources of options, for example, an option file.
-rw-r--r--cli/header.cxx6
-rw-r--r--cli/options.cxx193
-rw-r--r--cli/options.hxx61
-rw-r--r--cli/options.ixx20
-rw-r--r--cli/runtime-header.cxx60
-rw-r--r--cli/runtime-inline.cxx21
-rw-r--r--cli/runtime-source.cxx152
-rw-r--r--cli/source.cxx51
8 files changed, 419 insertions, 145 deletions
diff --git a/cli/header.cxx b/cli/header.cxx
index 2749b6d..0cc9ede 100644
--- a/cli/header.cxx
+++ b/cli/header.cxx
@@ -123,10 +123,8 @@ namespace
// _parse()
//
os << "private:" << endl
- << "int" << endl
- << "_parse (int start," << endl
- << "int argc," << endl
- << "char** argv," << endl
+ << "void" << endl
+ << "_parse (::cli::scanner&," << endl
<< um << " option," << endl
<< um << " argument);"
<< endl;
diff --git a/cli/options.cxx b/cli/options.cxx
index 78b3f5f..399069e 100644
--- a/cli/options.cxx
+++ b/cli/options.cxx
@@ -90,98 +90,155 @@ namespace cli
return "invalid option value";
}
+ // eos_reached
+ //
+ void eos_reached::
+ print (std::ostream& os) const
+ {
+ os << what ();
+ }
+
+ const char* eos_reached::
+ what () const throw ()
+ {
+ return "end of argument stream reached";
+ }
+
+ // scanner
+ //
+ scanner::
+ ~scanner ()
+ {
+ }
+
+ // argv_scanner
+ //
+ bool argv_scanner::
+ more ()
+ {
+ return i_ < argc_;
+ }
+
+ const char* argv_scanner::
+ peek ()
+ {
+ if (i_ < argc_)
+ return argv_[i_];
+ else
+ throw eos_reached ();
+ }
+
+ const char* argv_scanner::
+ next ()
+ {
+ if (i_ < argc_)
+ return argv_[i_++];
+ else
+ throw eos_reached ();
+ }
+
+ void argv_scanner::
+ skip ()
+ {
+ if (i_ < argc_)
+ i_++;
+ else
+ throw eos_reached ();
+ }
+
template <typename X>
struct parser
{
- static int
- parse (X& x, char** argv, int n)
+ static void
+ parse (X& x, scanner& s)
{
- if (n > 1)
+ const char* o (s.next ());
+
+ if (s.more ())
{
- std::istringstream is (argv[1]);
+ const char* v (s.next ());
+ std::istringstream is (v);
if (!(is >> x && is.eof ()))
- throw invalid_value (argv[0], argv[1]);
- return 2;
+ throw invalid_value (o, v);
}
else
- throw missing_value (argv[0]);
+ throw missing_value (o);
}
};
template <>
struct parser<bool>
{
- static int
- parse (bool& x, char**, int)
+ static void
+ parse (bool& x, scanner& s)
{
+ s.next ();
x = true;
- return 1;
}
};
template <>
struct parser<std::string>
{
- static int
- parse (std::string& x, char** argv, int n)
+ static void
+ parse (std::string& x, scanner& s)
{
- if (n > 1)
- {
- x = argv[1];
- return 2;
- }
+ const char* o (s.next ());
+
+ if (s.more ())
+ x = s.next ();
else
- throw missing_value (argv[0]);
+ throw missing_value (o);
}
};
template <typename X>
struct parser<std::vector<X> >
{
- static int
- parse (std::vector<X>& v, char** argv, int n)
+ static void
+ parse (std::vector<X>& c, scanner& s)
{
X x;
- int i = parser<X>::parse (x, argv, n);
- v.push_back (x);
- return i;
+ parser<X>::parse (x, s);
+ c.push_back (x);
}
};
template <typename X>
struct parser<std::set<X> >
{
- static int
- parse (std::set<X>& s, char** argv, int n)
+ static void
+ parse (std::set<X>& c, scanner& s)
{
X x;
- int i = parser<X>::parse (x, argv, n);
- s.insert (x);
- return i;
+ parser<X>::parse (x, s);
+ c.insert (x);
}
};
template <typename K, typename V>
struct parser<std::map<K, V> >
{
- static int
- parse (std::map<K, V>& m, char** argv, int n)
+ static void
+ parse (std::map<K, V>& m, scanner& s)
{
- if (n > 1)
+ const char* o (s.next ());
+
+ if (s.more ())
{
- std::string s (argv[1]);
- std::string::size_type p = s.find ('=');
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
if (p == std::string::npos)
{
K k = K ();
- if (!s.empty ())
+ if (!ov.empty ())
{
- std::istringstream ks (s);
+ std::istringstream ks (ov);
if (!(ks >> k && ks.eof ()))
- throw invalid_value (argv[0], argv[1]);
+ throw invalid_value (o, ov);
}
m[k] = V ();
@@ -190,15 +247,15 @@ namespace cli
{
K k = K ();
V v = V ();
- std::string kstr (s, 0, p);
- std::string vstr (s, p + 1);
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, p + 1);
if (!kstr.empty ())
{
std::istringstream ks (kstr);
if (!(ks >> k && ks.eof ()))
- throw invalid_value (argv[0], argv[1]);
+ throw invalid_value (o, ov);
}
if (!vstr.empty ())
@@ -206,24 +263,22 @@ namespace cli
std::istringstream vs (vstr);
if (!(vs >> v && vs.eof ()))
- throw invalid_value (argv[0], argv[1]);
+ throw invalid_value (o, ov);
}
m[k] = v;
}
-
- return 2;
}
else
- throw missing_value (argv[0]);
+ throw missing_value (o);
}
};
template <typename X, typename T, T X::*P>
- int
- thunk (X& x, char** argv, int n)
+ void
+ thunk (X& x, scanner& s)
{
- return parser<T>::parse (x.*P, argv, n);
+ parser<T>::parse (x.*P, s);
}
}
@@ -267,7 +322,8 @@ options (int argc,
guard_prefix_ (),
reserved_name_ ()
{
- _parse (1, argc, argv, opt, arg);
+ ::cli::argv_scanner s (argc, argv);
+ _parse (s, opt, arg);
}
options::
@@ -305,7 +361,8 @@ options (int start,
guard_prefix_ (),
reserved_name_ ()
{
- _parse (start, argc, argv, opt, arg);
+ ::cli::argv_scanner s (start, argc, argv);
+ _parse (s, opt, arg);
}
options::
@@ -343,7 +400,9 @@ options (int argc,
guard_prefix_ (),
reserved_name_ ()
{
- end = _parse (1, argc, argv, opt, arg);
+ ::cli::argv_scanner s (argc, argv);
+ _parse (s, opt, arg);
+ end = s.end ();
}
options::
@@ -382,7 +441,9 @@ options (int start,
guard_prefix_ (),
reserved_name_ ()
{
- end = _parse (start, argc, argv, opt, arg);
+ ::cli::argv_scanner s (start, argc, argv);
+ _parse (s, opt, arg);
+ end = s.end ();
}
void options::
@@ -467,7 +528,7 @@ print_usage (::std::ostream& os)
}
typedef
-std::map<std::string, int (*) (options&, char**, int)>
+std::map<std::string, void (*) (options&, ::cli::scanner&)>
_cli_options_map;
static _cli_options_map _cli_options_map_;
@@ -537,40 +598,38 @@ struct _cli_options_map_init
}
} _cli_options_map_init_;
-int options::
-_parse (int start,
- int argc,
- char** argv,
+void options::
+_parse (::cli::scanner& s,
::cli::unknown_mode opt_mode,
::cli::unknown_mode arg_mode)
{
bool opt = true;
- for (; start < argc;)
+ while (s.more ())
{
- const char* s = argv[start];
+ const char* o = s.peek ();
- if (std::strcmp (s, "--") == 0)
+ if (std::strcmp (o, "--") == 0)
{
- start++;
+ s.skip ();
opt = false;
continue;
}
_cli_options_map::const_iterator i (
- opt ? _cli_options_map_.find (s) : _cli_options_map_.end ());
+ opt ? _cli_options_map_.find (o) : _cli_options_map_.end ());
if (i != _cli_options_map_.end ())
{
- start += (*(i->second)) (*this, argv + start, argc - start);
+ (*(i->second)) (*this, s);
}
- else if (opt && std::strncmp (s, "-", 1) == 0 && s[1] != '\0')
+ else if (opt && std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
{
switch (opt_mode)
{
case ::cli::unknown_mode::skip:
{
- start++;
+ s.skip ();
continue;
}
case ::cli::unknown_mode::stop:
@@ -579,7 +638,7 @@ _parse (int start,
}
case ::cli::unknown_mode::fail:
{
- throw ::cli::unknown_option (s);
+ throw ::cli::unknown_option (o);
}
}
@@ -591,7 +650,7 @@ _parse (int start,
{
case ::cli::unknown_mode::skip:
{
- start++;
+ s.skip ();
continue;
}
case ::cli::unknown_mode::stop:
@@ -600,14 +659,12 @@ _parse (int start,
}
case ::cli::unknown_mode::fail:
{
- throw ::cli::unknown_argument (s);
+ throw ::cli::unknown_argument (o);
}
}
break;
}
}
-
- return start;
}
diff --git a/cli/options.hxx b/cli/options.hxx
index d5712d1..2be8e91 100644
--- a/cli/options.hxx
+++ b/cli/options.hxx
@@ -133,6 +133,61 @@ namespace cli
std::string option_;
std::string value_;
};
+
+ class eos_reached: public exception
+ {
+ public:
+ virtual void
+ print (std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+ };
+
+ class scanner
+ {
+ public:
+ virtual
+ ~scanner ();
+
+ virtual bool
+ more () = 0;
+
+ virtual const char*
+ peek () = 0;
+
+ virtual const char*
+ next () = 0;
+
+ virtual void
+ skip () = 0;
+ };
+
+ class argv_scanner: public scanner
+ {
+ public:
+ argv_scanner (int argc, char** argv);
+ argv_scanner (int start, int argc, char** argv);
+
+ int
+ end () const;
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ virtual void
+ skip ();
+
+ private:int i_;
+ int argc_;
+ char** argv_;
+ };
}
#include <map>
@@ -264,10 +319,8 @@ class options
print_usage (::std::ostream&);
private:
- int
- _parse (int start,
- int argc,
- char** argv,
+ void
+ _parse (::cli::scanner&,
::cli::unknown_mode option,
::cli::unknown_mode argument);
diff --git a/cli/options.ixx b/cli/options.ixx
index 60afbda..6fcc80f 100644
--- a/cli/options.ixx
+++ b/cli/options.ixx
@@ -83,6 +83,26 @@ namespace cli
{
return value_;
}
+
+ // argv_scanner
+ //
+ inline argv_scanner::
+ argv_scanner (int argc, char** argv)
+ : i_ (1), argc_ (argc), argv_ (argv)
+ {
+ }
+
+ inline argv_scanner::
+ argv_scanner (int start, int argc, char** argv)
+ : i_ (start), argc_ (argc), argv_ (argv)
+ {
+ }
+
+ inline int argv_scanner::
+ end () const
+ {
+ return i_;
+ }
}
// options
diff --git a/cli/runtime-header.cxx b/cli/runtime-header.cxx
index 055754c..cf3ebd3 100644
--- a/cli/runtime-header.cxx
+++ b/cli/runtime-header.cxx
@@ -145,5 +145,65 @@ generate_runtime_header (context& ctx)
<< "std::string value_;"
<< "};";
+ os << "class eos_reached: public exception"
+ << "{"
+ << "public:" << endl
+ << "virtual void" << endl
+ << "print (std::ostream&) const;"
+ << endl
+ << "virtual const char*" << endl
+ << "what () const throw ();"
+ << "};";
+
+ // scanner
+ //
+ os << "class scanner"
+ << "{"
+ << "public:" << endl
+ << "virtual" << endl
+ << "~scanner ();"
+ << endl
+ << "virtual bool" << endl
+ << "more () = 0;"
+ << endl
+ << "virtual const char*" << endl
+ << "peek () = 0;"
+ << endl
+ << "virtual const char*" << endl
+ << "next () = 0;"
+ << endl
+ << "virtual void" << endl
+ << "skip () = 0;"
+ << "};";
+
+ // argv_scanner
+ //
+ os << "class argv_scanner: public scanner"
+ << "{"
+ << "public:" << endl
+ << "argv_scanner (int argc, char** argv);"
+ << "argv_scanner (int start, int argc, char** argv);"
+ << endl
+ << "int" << endl
+ << "end () const;"
+ << endl
+ << "virtual bool" << endl
+ << "more ();"
+ << endl
+ << "virtual const char*" << endl
+ << "peek ();"
+ << endl
+ << "virtual const char*" << endl
+ << "next ();"
+ << endl
+ << "virtual void" << endl
+ << "skip ();"
+ << endl
+ << "private:"
+ << "int i_;"
+ << "int argc_;"
+ << "char** argv_;"
+ << "};";
+
os << "}"; // namespace cli
}
diff --git a/cli/runtime-inline.cxx b/cli/runtime-inline.cxx
index 9c33c2e..d4ce3ec 100644
--- a/cli/runtime-inline.cxx
+++ b/cli/runtime-inline.cxx
@@ -103,5 +103,26 @@ generate_runtime_inline (context& ctx)
<< "return value_;"
<< "}";
+ os << "// argv_scanner" << endl
+ << "//" << endl;
+
+ os << inl << "argv_scanner::" << endl
+ << "argv_scanner (int argc, char** argv)" << endl
+ << ": i_ (1), argc_ (argc), argv_ (argv)"
+ << "{"
+ << "}";
+
+ os << inl << "argv_scanner::" << endl
+ << "argv_scanner (int start, int argc, char** argv)" << endl
+ << ": i_ (start), argc_ (argc), argv_ (argv)"
+ << "{"
+ << "}";
+
+ os << inl << "int argv_scanner::" << endl
+ << "end () const"
+ << "{"
+ << "return i_;"
+ << "}";
+
os << "}"; // namespace cli
}
diff --git a/cli/runtime-source.cxx b/cli/runtime-source.cxx
index 9f96416..3003b6b 100644
--- a/cli/runtime-source.cxx
+++ b/cli/runtime-source.cxx
@@ -100,23 +100,87 @@ generate_runtime_source (context& ctx)
<< "return \"invalid option value\";"
<< "}";
+ // eos_reached
+ //
+ os << "// eos_reached" << endl
+ << "//" << endl
+ << "void eos_reached::" << endl
+ << "print (std::ostream& os) const"
+ << "{"
+ << "os << what ();"
+ << "}"
+ << "const char* eos_reached::" << endl
+ << "what () const throw ()"
+ << "{"
+ << "return \"end of argument stream reached\";"
+ << "}";
+
+ // scanner
+ //
+ os << "// scanner" << endl
+ << "//" << endl
+ << "scanner::" << endl
+ << "~scanner ()"
+ << "{"
+ << "}";
+
+ // argv_scanner
+ //
+ os << "// argv_scanner" << endl
+ << "//" << endl
+
+ << "bool argv_scanner::" << endl
+ << "more ()"
+ << "{"
+ << "return i_ < argc_;"
+ << "}"
+
+ << "const char* argv_scanner::" << endl
+ << "peek ()"
+ << "{"
+ << "if (i_ < argc_)" << endl
+ << "return argv_[i_];"
+ << "else" << endl
+ << "throw eos_reached ();"
+ << "}"
+
+ << "const char* argv_scanner::" << endl
+ << "next ()"
+ << "{"
+ << "if (i_ < argc_)" << endl
+ << "return argv_[i_++];"
+ << "else" << endl
+ << "throw eos_reached ();"
+ << "}"
+
+ << "void argv_scanner::" << endl
+ << "skip ()"
+ << "{"
+ << "if (i_ < argc_)" << endl
+ << "i_++;"
+ << "else" << endl
+ << "throw eos_reached ();"
+ << "}";
+
// parser class template & its specializations
//
os << "template <typename X>" << endl
<< "struct parser"
<< "{"
- << "static int" << endl
- << "parse (X& x, char** argv, int n)"
+ << "static void" << endl
+ << "parse (X& x, scanner& s)"
<< "{"
- << "if (n > 1)"
+ << "const char* o (s.next ());"
+ << endl
+ << "if (s.more ())"
<< "{"
- << "std::istringstream is (argv[1]);"
+ << "const char* v (s.next ());"
+ << "std::istringstream is (v);"
<< "if (!(is >> x && is.eof ()))" << endl
- << "throw invalid_value (argv[0], argv[1]);"
- << "return 2;"
+ << "throw invalid_value (o, v);"
<< "}"
<< "else" << endl
- << "throw missing_value (argv[0]);"
+ << "throw missing_value (o);"
<< "}"
<< "};";
@@ -125,11 +189,11 @@ generate_runtime_source (context& ctx)
os << "template <>" << endl
<< "struct parser<bool>"
<< "{"
- << "static int" << endl
- << "parse (bool& x, char**, int)"
+ << "static void" << endl
+ << "parse (bool& x, scanner& s)"
<< "{"
+ << "s.next ();"
<< "x = true;"
- << "return 1;"
<< "}"
<< "};";
@@ -138,16 +202,15 @@ generate_runtime_source (context& ctx)
os << "template <>" << endl
<< "struct parser<std::string>"
<< "{"
- << "static int" << endl
- << "parse (std::string& x, char** argv, int n)"
+ << "static void" << endl
+ << "parse (std::string& x, scanner& s)"
<< "{"
- << "if (n > 1)"
- << "{"
- << "x = argv[1];"
- << "return 2;"
- << "}"
+ << "const char* o (s.next ());"
+ << endl
+ << "if (s.more ())" << endl
+ << "x = s.next ();"
<< "else" << endl
- << "throw missing_value (argv[0]);"
+ << "throw missing_value (o);"
<< "}"
<< "};";
@@ -156,13 +219,12 @@ generate_runtime_source (context& ctx)
os << "template <typename X>" << endl
<< "struct parser<std::vector<X> >"
<< "{"
- << "static int" << endl
- << "parse (std::vector<X>& v, char** argv, int n)"
+ << "static void" << endl
+ << "parse (std::vector<X>& c, scanner& s)"
<< "{"
<< "X x;"
- << "int i = parser<X>::parse (x, argv, n);"
- << "v.push_back (x);"
- << "return i;"
+ << "parser<X>::parse (x, s);"
+ << "c.push_back (x);"
<< "}"
<< "};";
@@ -171,13 +233,12 @@ generate_runtime_source (context& ctx)
os << "template <typename X>" << endl
<< "struct parser<std::set<X> >"
<< "{"
- << "static int" << endl
- << "parse (std::set<X>& s, char** argv, int n)"
+ << "static void" << endl
+ << "parse (std::set<X>& c, scanner& s)"
<< "{"
<< "X x;"
- << "int i = parser<X>::parse (x, argv, n);"
- << "s.insert (x);"
- << "return i;"
+ << "parser<X>::parse (x, s);"
+ << "c.insert (x);"
<< "}"
<< "};";
@@ -186,24 +247,26 @@ generate_runtime_source (context& ctx)
os << "template <typename K, typename V>" << endl
<< "struct parser<std::map<K, V> >"
<< "{"
- << "static int" << endl
- << "parse (std::map<K, V>& m, char** argv, int n)"
+ << "static void" << endl
+ << "parse (std::map<K, V>& m, scanner& s)"
<< "{"
- << "if (n > 1)"
+ << "const char* o (s.next ());"
+ << endl
+ << "if (s.more ())"
<< "{"
- << "std::string s (argv[1]);"
- << "std::string::size_type p = s.find ('=');"
+ << "std::string ov (s.next ());"
+ << "std::string::size_type p = ov.find ('=');"
<< endl
<< "if (p == std::string::npos)"
<< "{"
<< "K k = K ();"
<< endl
- << "if (!s.empty ())"
+ << "if (!ov.empty ())"
<< "{"
- << "std::istringstream ks (s);"
+ << "std::istringstream ks (ov);"
<< endl
<< "if (!(ks >> k && ks.eof ()))" << endl
- << "throw invalid_value (argv[0], argv[1]);"
+ << "throw invalid_value (o, ov);"
<< "}"
<< "m[k] = V ();"
<< "}"
@@ -211,39 +274,38 @@ generate_runtime_source (context& ctx)
<< "{"
<< "K k = K ();"
<< "V v = V ();"
- << "std::string kstr (s, 0, p);"
- << "std::string vstr (s, p + 1);"
+ << "std::string kstr (ov, 0, p);"
+ << "std::string vstr (ov, p + 1);"
<< endl
<< "if (!kstr.empty ())"
<< "{"
<< "std::istringstream ks (kstr);"
<< endl
<< "if (!(ks >> k && ks.eof ()))" << endl
- << "throw invalid_value (argv[0], argv[1]);"
+ << "throw invalid_value (o, ov);"
<< "}"
<< "if (!vstr.empty ())"
<< "{"
<< "std::istringstream vs (vstr);"
<< endl
<< "if (!(vs >> v && vs.eof ()))" << endl
- << "throw invalid_value (argv[0], argv[1]);"
+ << "throw invalid_value (o, ov);"
<< "}"
<< "m[k] = v;"
<< "}"
- << "return 2;"
<< "}"
<< "else" << endl
- << "throw missing_value (argv[0]);"
+ << "throw missing_value (o);"
<< "}"
<< "};";
// Parser thunk.
//
os << "template <typename X, typename T, T X::*P>" << endl
- << "int" << endl
- << "thunk (X& x, char** argv, int n)"
+ << "void" << endl
+ << "thunk (X& x, scanner& s)"
<< "{"
- << "return parser<T>::parse (x.*P, argv, n);"
+ << "parser<T>::parse (x.*P, s);"
<< "}";
os << "}"; // namespace cli
diff --git a/cli/source.cxx b/cli/source.cxx
index f473665..5f0b199 100644
--- a/cli/source.cxx
+++ b/cli/source.cxx
@@ -367,7 +367,8 @@ namespace
names (c, names_init);
}
os << "{"
- << "_parse (1, argc, argv, opt, arg);"
+ << "::cli::argv_scanner s (argc, argv);"
+ << "_parse (s, opt, arg);"
<< "}";
os << name << "::" << endl
@@ -383,7 +384,8 @@ namespace
names (c, names_init);
}
os << "{"
- << "_parse (start, argc, argv, opt, arg);"
+ << "::cli::argv_scanner s (start, argc, argv);"
+ << "_parse (s, opt, arg);"
<< "}";
os << name << "::" << endl
@@ -399,7 +401,9 @@ namespace
names (c, names_init);
}
os << "{"
- << "end = _parse (1, argc, argv, opt, arg);"
+ << "::cli::argv_scanner s (argc, argv);"
+ << "_parse (s, opt, arg);"
+ << "end = s.end ();"
<< "}";
os << name << "::" << endl
@@ -416,7 +420,9 @@ namespace
names (c, names_init);
}
os << "{"
- << "end = _parse (start, argc, argv, opt, arg);"
+ << "::cli::argv_scanner s (start, argc, argv);"
+ << "_parse (s, opt, arg);"
+ << "end = s.end ();"
<< "}";
// usage
@@ -468,8 +474,8 @@ namespace
string map ("_cli_" + name + "_map");
os << "typedef" << endl
- << "std::map<std::string, int (*) (" <<
- name << "&, char**, int)>" << endl
+ << "std::map<std::string, void (*) (" <<
+ name << "&, ::cli::scanner&)>" << endl
<< map << ";"
<< endl
<< "static " << map << " " << map << "_;"
@@ -489,10 +495,8 @@ namespace
bool pfx (!opt_prefix.empty ());
bool sep (!opt_sep.empty ());
- os << "int " << name << "::" << endl
- << "_parse (int start," << endl
- << "int argc," << endl
- << "char** argv," << endl
+ os << "void " << name << "::" << endl
+ << "_parse (::cli::scanner& s," << endl
<< um << " opt_mode," << endl
<< um << " arg_mode)"
<< "{";
@@ -501,27 +505,27 @@ namespace
os << "bool opt = true;" // Still recognizing options.
<< endl;
- os << "for (; start < argc;)"
+ os << "while (s.more ())"
<< "{"
- << "const char* s = argv[start];";
+ << "const char* o = s.peek ();";
if (sep)
os << endl
- << "if (std::strcmp (s, \"" << opt_sep << "\") == 0)"
+ << "if (std::strcmp (o, \"" << opt_sep << "\") == 0)"
<< "{"
- << "start++;"
+ << "s.skip ();" // We don't want to remove the separator.
<< "opt = false;"
<< "continue;"
<< "}"
<< map << "::const_iterator i (" << endl
- << "opt ? " << map << "_.find (s) : " << map << "_.end ());";
+ << "opt ? " << map << "_.find (o) : " << map << "_.end ());";
else
- os << map << "::const_iterator i (" << map << "_.find (s));";
+ os << map << "::const_iterator i (" << map << "_.find (o));";
os << endl
<< "if (i != " << map << "_.end ())"
<< "{"
- << "start += (*(i->second)) (*this, argv + start, argc - start);"
+ << "(*(i->second)) (*this, s);"
<< "}";
// Unknown option.
@@ -535,14 +539,14 @@ namespace
if (sep)
os << "opt && ";
- os << "std::strncmp (s, \"" << opt_prefix << "\", " <<
- n << ") == 0 && s[" << n << "] != '\\0')"
+ os << "std::strncmp (o, \"" << opt_prefix << "\", " <<
+ n << ") == 0 && o[" << n << "] != '\\0')"
<< "{"
<< "switch (opt_mode)"
<< "{"
<< "case ::cli::unknown_mode::skip:" << endl
<< "{"
- << "start++;"
+ << "s.skip ();"
<< "continue;"
<< "}"
<< "case ::cli::unknown_mode::stop:" << endl
@@ -551,7 +555,7 @@ namespace
<< "}"
<< "case ::cli::unknown_mode::fail:" << endl
<< "{"
- << "throw ::cli::unknown_option (s);"
+ << "throw ::cli::unknown_option (o);"
<< "}"
<< "}" // switch
<< "break;" // The stop case.
@@ -566,7 +570,7 @@ namespace
<< "{"
<< "case ::cli::unknown_mode::skip:" << endl
<< "{"
- << "start++;"
+ << "s.skip ();"
<< "continue;"
<< "}"
<< "case ::cli::unknown_mode::stop:" << endl
@@ -575,14 +579,13 @@ namespace
<< "}"
<< "case ::cli::unknown_mode::fail:" << endl
<< "{"
- << "throw ::cli::unknown_argument (s);"
+ << "throw ::cli::unknown_argument (o);"
<< "}"
<< "}" // switch
<< "break;" // The stop case.
<< "}"
<< "}" // for
- << "return start;"
<< "}";
}