summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-06-03 11:46:04 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-06-03 11:46:04 +0200
commit31f5102fa8694980891274006eb15b5bebdb28d6 (patch)
treec689b5a57f5bb505ce82aeda0796ca5d63d836ce
parent4c776f3cb590bf031d6288043c530679a207a0c0 (diff)
Generate certain template runtime code in every source file
This is needed if the cli runtime is included from another file instead of being generated. The alternative would be to move that code to the header file. However, that would also require including a lot of standard headers in the generated header file.
-rw-r--r--cli/generator.cxx13
-rw-r--r--cli/runtime-source.cxx755
-rw-r--r--cli/runtime-source.hxx2
3 files changed, 389 insertions, 381 deletions
diff --git a/cli/generator.cxx b/cli/generator.cxx
index 8b4b244..1ebde25 100644
--- a/cli/generator.cxx
+++ b/cli/generator.cxx
@@ -160,7 +160,9 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p)
// Check if we need to generate the runtime code. If we include
// another options file, then we assume the runtime is generated
- // there.
+ // there. However, to reduce the number of standard headers we
+ // have to include in the generated header file, we will still
+ // need to generate some template code in the source file.
//
bool runtime (true);
for (semantics::cli_unit::includes_iterator i (unit.includes_begin ());
@@ -288,13 +290,10 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p)
(br ? '>' : '"') << endl
<< endl;
- if (runtime)
- {
- if (!inl)
- generate_runtime_inline (ctx);
+ if (runtime && !inl)
+ generate_runtime_inline (ctx);
- generate_runtime_source (ctx);
- }
+ generate_runtime_source (ctx, runtime);
if (!inl)
generate_inline (ctx);
diff --git a/cli/runtime-source.cxx b/cli/runtime-source.cxx
index 37dc1ac..5964fdd 100644
--- a/cli/runtime-source.cxx
+++ b/cli/runtime-source.cxx
@@ -8,7 +8,7 @@
using namespace std;
void
-generate_runtime_source (context& ctx)
+generate_runtime_source (context& ctx, bool complete)
{
ostream& os (ctx.os);
@@ -19,7 +19,7 @@ generate_runtime_source (context& ctx)
<< "#include <ostream>" << endl
<< "#include <sstream>" << endl;
- if (ctx.options.generate_file_scanner ())
+ if (complete && ctx.options.generate_file_scanner ())
os << "#include <cstring>" << endl
<< "#include <fstream>" << endl;
@@ -27,443 +27,452 @@ generate_runtime_source (context& ctx)
ctx.cli_open ();
- // unknown_option
- //
- os << "// unknown_option" << endl
- << "//" << endl
- << "unknown_option::" << endl
- << "~unknown_option () throw ()"
- << "{"
- << "}"
-
- << "void unknown_option::" << endl
- << "print (std::ostream& os) const"
- << "{"
- << "os << \"unknown option '\" << option () << \"'\";"
- << "}"
-
- << "const char* unknown_option::" << endl
- << "what () const throw ()"
- << "{"
- << "return \"unknown option\";"
- << "}";
-
- // unknown_argument
- //
- os << "// unknown_argument" << endl
- << "//" << endl
- << "unknown_argument::" << endl
- << "~unknown_argument () throw ()"
- << "{"
- << "}"
-
- << "void unknown_argument::" << endl
- << "print (std::ostream& os) const"
- << "{"
- << "os << \"unknown argument '\" << argument () << \"'\";"
- << "}"
-
- << "const char* unknown_argument::" << endl
- << "what () const throw ()"
- << "{"
- << "return \"unknown argument\";"
- << "}";
-
- // missing_value
- //
- os << "// missing_value" << endl
- << "//" << endl
- << "missing_value::" << endl
- << "~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 ()"
- << "{"
- << "return \"missing option value\";"
- << "}";
-
- // invalid_value
- //
- os << "// invalid_value" << endl
- << "//" << endl
- << "invalid_value::" << endl
- << "~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 ()"
- << "{"
- << "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\";"
- << "}";
-
- if (ctx.options.generate_file_scanner ())
+ if (complete)
{
- // file_io_failure
+ // unknown_option
//
- os << "// file_io_failure" << endl
+ os << "// unknown_option" << endl
<< "//" << endl
- << "file_io_failure::" << endl
- << "~file_io_failure () throw ()"
+ << "unknown_option::" << endl
+ << "~unknown_option () throw ()"
<< "{"
<< "}"
- << "void file_io_failure::" << endl
+ << "void unknown_option::" << endl
<< "print (std::ostream& os) const"
<< "{"
- << "os << \"unable to open file '\" << file () << \"' or read failure\";"
+ << "os << \"unknown option '\" << option () << \"'\";"
<< "}"
- << "const char* file_io_failure::" << endl
+ << "const char* unknown_option::" << endl
<< "what () const throw ()"
<< "{"
- << "return \"unable to open file or read failure\";"
+ << "return \"unknown option\";"
<< "}";
- // unmatched_argument
+ // unknown_argument
//
- os << "// unmatched_quote" << endl
+ os << "// unknown_argument" << endl
<< "//" << endl
- << "unmatched_quote::" << endl
- << "~unmatched_quote () throw ()"
+ << "unknown_argument::" << endl
+ << "~unknown_argument () throw ()"
<< "{"
<< "}"
- << "void unmatched_quote::" << endl
+ << "void unknown_argument::" << endl
<< "print (std::ostream& os) const"
<< "{"
- << "os << \"unmatched quote in argument '\" << argument () << \"'\";"
+ << "os << \"unknown argument '\" << argument () << \"'\";"
<< "}"
- << "const char* unmatched_quote::" << endl
+ << "const char* unknown_argument::" << endl
<< "what () const throw ()"
<< "{"
- << "return \"unmatched quote\";"
+ << "return \"unknown argument\";"
<< "}";
- }
-
- // 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_)"
- << "{"
- << "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 ();"
- << "}"
-
- << "void argv_scanner::" << endl
- << "skip ()"
- << "{"
- << "if (i_ < argc_)" << endl
- << "++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
+ // missing_value
+ //
+ os << "// missing_value" << endl
<< "//" << endl
- << "const char* a (base::peek ());"
- << "const option_info* oi;"
- << endl
- << "if (" << (sep ? "!skip_ && " : "") << "(oi = find (a)))"
- << "{"
- << "base::next ();"
- << endl
- << "if (!base::more ())" << endl
- << "throw missing_value (oi->option);"
- << endl
- << "if (oi->search_func != 0)"
+ << "missing_value::" << endl
+ << "~missing_value () throw ()"
<< "{"
- << "std::string f (oi->search_func (base::next (), oi->arg));"
- << endl
- << "if (!f.empty ())" << endl
- << "load (f);"
- << "}"
- << "else" << 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 ()"
+ << "void missing_value::" << endl
+ << "print (std::ostream& os) const"
<< "{"
- << "if (!more ())" << endl
- << "throw eos_reached ();"
- << endl
- << "return args_.empty () ? base::peek () : args_.front ().c_str ();"
+ << "os << \"missing value for option '\" << option () << \"'\";"
<< "}"
- << "const char* argv_file_scanner::" << endl
- << "next ()"
- << "{"
- << "if (!more ())" << endl
- << "throw eos_reached ();"
- << endl
- << "if (args_.empty ())" << endl
- << "return base::next ();"
- << "else"
+ << "const char* missing_value::" << endl
+ << "what () const throw ()"
<< "{"
- << "hold_.swap (args_.front ());"
- << "args_.pop_front ();"
- << "return hold_.c_str ();"
- << "}"
- << "}"
+ << "return \"missing option value\";"
+ << "}";
- << "void argv_file_scanner::" << endl
- << "skip ()"
+ // invalid_value
+ //
+ os << "// invalid_value" << endl
+ << "//" << endl
+ << "invalid_value::" << endl
+ << "~invalid_value () throw ()"
<< "{"
- << "if (!more ())" << endl
- << "throw eos_reached ();"
- << endl
- << "if (args_.empty ())" << endl
- << "return base::skip ();"
- << "else" << endl
- << "args_.pop_front ();"
<< "}"
- << "const argv_file_scanner::option_info* argv_file_scanner::" << endl
- << "find (const char* a) const"
+ << "void invalid_value::" << endl
+ << "print (std::ostream& os) const"
<< "{"
- << "for (std::size_t i (0); i < options_count_; ++i)" << endl
- << "if (std::strcmp (a, options_[i].option) == 0)" << endl
- << "return &options_[i];"
- << endl
- << "return 0;"
+ << "os << \"invalid value '\" << value () << \"' for option '\"" << endl
+ << " << option () << \"'\";"
<< "}"
- << "void argv_file_scanner::" << endl
- << "load (const std::string& file)"
- << "{"
- << "using namespace std;"
- << endl
- << "ifstream is (file.c_str ());"
- << endl
- << "if (!is.is_open ())" << endl
- << "throw file_io_failure (file);"
- << endl
- << "while (!is.eof ())"
+ << "const char* invalid_value::" << endl
+ << "what () const throw ()"
<< "{"
- << "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
+ << "return \"invalid option value\";"
+ << "}";
+
+ // eos_reached
+ //
+ os << "// eos_reached" << endl
<< "//" << endl
- << "if (n != 0)"
+ << "void eos_reached::" << endl
+ << "print (std::ostream& os) const"
<< "{"
- << "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 ();"
+ << "os << what ();"
<< "}"
- << "// Ignore empty lines, those that start with #." << endl
+
+ << "const char* eos_reached::" << endl
+ << "what () const throw ()"
+ << "{"
+ << "return \"end of argument stream reached\";"
+ << "}";
+
+ if (ctx.options.generate_file_scanner ())
+ {
+ // file_io_failure
+ //
+ 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\";"
+ << "}";
+
+ // unmatched_argument
+ //
+ os << "// unmatched_quote" << endl
+ << "//" << endl
+ << "unmatched_quote::" << endl
+ << "~unmatched_quote () throw ()"
+ << "{"
+ << "}"
+
+ << "void unmatched_quote::" << endl
+ << "print (std::ostream& os) const"
+ << "{"
+ << "os << \"unmatched quote in argument '\" << argument () << \"'\";"
+ << "}"
+
+ << "const char* unmatched_quote::" << endl
+ << "what () const throw ()"
+ << "{"
+ << "return \"unmatched quote\";"
+ << "}";
+ }
+
+ // scanner
+ //
+ os << "// scanner" << 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"
+ << "scanner::" << endl
+ << "~scanner ()"
<< "{"
- << "string s1 (line, 0, p);"
- << endl
- << "// Skip leading whitespaces in the argument." << endl
+ << "}";
+
+ // argv_scanner
+ //
+ os << "// argv_scanner" << endl
<< "//" << endl
- << "n = line.size ();"
- << "for (++p; p < n; ++p)"
+
+ << "bool argv_scanner::" << endl
+ << "more ()"
<< "{"
- << "char c (line[p]);"
- << endl
- << "if (c != ' ' && c != '\\t' && c != '\\r')" << endl
- << "break;"
+ << "return i_ < argc_;"
<< "}"
- << "string s2 (line, p);"
- << endl
- << "// If the string is wrapped in quotes, remove them." << endl
- << "//" << endl
- << "n = s2.size ();"
- << "char cf (s2[0]), cl (s2[n - 1]);"
- << endl
- << "if (cf == '\"' || cf == '\\'' || cl == '\"' || cl == '\\'')"
+
+ << "const char* argv_scanner::" << endl
+ << "peek ()"
<< "{"
- << "if (n == 1 || cf != cl)" << endl
- << "throw unmatched_quote (s2);"
- << endl
- << "s2 = string (s2, 1, n - 2);"
+ << "if (i_ < argc_)" << endl
+ << "return argv_[i_];"
+ << "else" << endl
+ << "throw eos_reached ();"
<< "}"
- << "const option_info* oi;"
- << "if (" << (sep ? "!skip_ && " : "") << "(oi = find (s1.c_str ())))" << endl
+
+ << "const char* argv_scanner::" << endl
+ << "next ()"
<< "{"
- << "if (s2.empty ())" << endl
- << "throw missing_value (oi->option);"
+ << "if (i_ < argc_)"
+ << "{"
+ << "const char* r (argv_[i_]);"
<< endl
- << "if (oi->search_func != 0)"
+ << "if (erase_)"
<< "{"
- << "std::string f (oi->search_func (s2.c_str (), oi->arg));"
+ << "for (int i (i_ + 1); i < argc_; ++i)" << endl
+ << "argv_[i - 1] = argv_[i];"
<< endl
- << "if (!f.empty ())" << endl
- << "load (f);"
+ << "--argc_;"
+ << "argv_[argc_] = 0;"
<< "}"
<< "else" << endl
- << "load (s2);"
- << "}"
- << "else"
- << "{"
- << "args_.push_back (s1);"
- << "args_.push_back (s2);"
+ << "++i_;"
+ << endl
+ << "return r;"
<< "}"
+ << "else" << endl
+ << "throw eos_reached ();"
<< "}"
- << "}" // while
- << "}";
- }
- // Option description.
- //
- if (ctx.options.generate_description ())
- {
- // options
- //
- os << "void options::" << endl
- << "push_back (const option& o)"
+ << "void argv_scanner::" << endl
+ << "skip ()"
<< "{"
- << "container_type::size_type n (size ());"
- << "container_type::push_back (o);"
- << "map_[o.name ()] = n;"
- << endl
- << "for (option_names::const_iterator i (o.aliases ().begin ());" << endl
- << "i != o.aliases ().end (); ++i)" << endl
- << "map_[*i] = n;"
+ << "if (i_ < argc_)" << endl
+ << "++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 ());"
+ << "const option_info* oi;"
+ << endl
+ << "if (" << (sep ? "!skip_ && " : "") << "(oi = find (a)))"
+ << "{"
+ << "base::next ();"
+ << endl
+ << "if (!base::more ())" << endl
+ << "throw missing_value (oi->option);"
+ << endl
+ << "if (oi->search_func != 0)"
+ << "{"
+ << "std::string f (oi->search_func (base::next (), oi->arg));"
+ << endl
+ << "if (!f.empty ())" << endl
+ << "load (f);"
+ << "}"
+ << "else" << 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 ();"
+ << "}"
+
+ << "const argv_file_scanner::option_info* argv_file_scanner::" << endl
+ << "find (const char* a) const"
+ << "{"
+ << "for (std::size_t i (0); i < options_count_; ++i)" << endl
+ << "if (std::strcmp (a, options_[i].option) == 0)" << endl
+ << "return &options_[i];"
+ << endl
+ << "return 0;"
+ << "}"
+
+ << "void argv_file_scanner::" << endl
+ << "load (const std::string& file)"
+ << "{"
+ << "using namespace std;"
+ << endl
+ << "ifstream is (file.c_str ());"
+ << 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 the string is wrapped in quotes, remove them." << endl
+ << "//" << endl
+ << "n = s2.size ();"
+ << "char cf (s2[0]), cl (s2[n - 1]);"
+ << endl
+ << "if (cf == '\"' || cf == '\\'' || cl == '\"' || cl == '\\'')"
+ << "{"
+ << "if (n == 1 || cf != cl)" << endl
+ << "throw unmatched_quote (s2);"
+ << endl
+ << "s2 = string (s2, 1, n - 2);"
+ << "}"
+ << "const option_info* oi;"
+ << "if (" << (sep ? "!skip_ && " : "") <<
+ "(oi = find (s1.c_str ())))" << endl
+ << "{"
+ << "if (s2.empty ())" << endl
+ << "throw missing_value (oi->option);"
+ << endl
+ << "if (oi->search_func != 0)"
+ << "{"
+ << "std::string f (oi->search_func (s2.c_str (), oi->arg));"
+ << endl
+ << "if (!f.empty ())" << endl
+ << "load (f);"
+ << "}"
+ << "else" << endl
+ << "load (s2);"
+ << "}"
+ << "else"
+ << "{"
+ << "args_.push_back (s1);"
+ << "args_.push_back (s2);"
+ << "}"
+ << "}"
+ << "}" // while
+ << "}";
+ }
+
+ // Option description.
+ //
+ if (ctx.options.generate_description ())
+ {
+ // options
+ //
+ os << "void options::" << endl
+ << "push_back (const option& o)"
+ << "{"
+ << "container_type::size_type n (size ());"
+ << "container_type::push_back (o);"
+ << "map_[o.name ()] = n;"
+ << endl
+ << "for (option_names::const_iterator i (o.aliases ().begin ());" << endl
+ << "i != o.aliases ().end (); ++i)" << endl
+ << "map_[*i] = n;"
+ << "}";
+ }
}
+ // To reduce the number of standard headers we have to include in the
+ // generated header file, we always generate the following templates
+ // in the source file.
+ //
bool sp (ctx.specifier);
// parser class template & its specializations
diff --git a/cli/runtime-source.hxx b/cli/runtime-source.hxx
index 79e0cef..8300c9a 100644
--- a/cli/runtime-source.hxx
+++ b/cli/runtime-source.hxx
@@ -9,6 +9,6 @@
#include "context.hxx"
void
-generate_runtime_source (context&);
+generate_runtime_source (context&, bool complete);
#endif // CLI_RUNTIME_SOURCE_HXX