summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/header.cxx22
-rw-r--r--cli/options.cli7
-rw-r--r--cli/options.cxx11
-rw-r--r--cli/options.hxx8
-rw-r--r--cli/options.ixx6
-rw-r--r--cli/source.cxx26
6 files changed, 60 insertions, 20 deletions
diff --git a/cli/header.cxx b/cli/header.cxx
index ddf0895..6ff1f6b 100644
--- a/cli/header.cxx
+++ b/cli/header.cxx
@@ -129,14 +129,23 @@ namespace
//
if (!abst)
{
- os << name << " (int& argc," << endl
+ os << name << " ();"
+ << endl;
+
+ // Are we generating parsing constructors or parse() functions?
+ //
+ string n (options.generate_parse ()
+ ? string ("void\n") + (name != "parse" ? "parse" : "parse_")
+ : name);
+
+ os << n << " (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
+ os << n << " (int start," << endl
<< "int& argc," << endl
<< "char** argv," << endl
<< "bool erase = false," << endl
@@ -144,7 +153,7 @@ namespace
<< um << " argument = " << um << "::stop);"
<< endl;
- os << name << " (int& argc," << endl
+ os << n << " (int& argc," << endl
<< "char** argv," << endl
<< "int& end," << endl
<< "bool erase = false," << endl
@@ -152,7 +161,7 @@ namespace
<< um << " argument = " << um << "::stop);"
<< endl;
- os << name << " (int start," << endl
+ os << n << " (int start," << endl
<< "int& argc," << endl
<< "char** argv," << endl
<< "int& end," << endl
@@ -161,13 +170,10 @@ namespace
<< um << " argument = " << um << "::stop);"
<< endl;
- os << name << " (" << cli << "::scanner&," << endl
+ os << n << " (" << cli << "::scanner&," << endl
<< um << " option = " << um << "::fail," << endl
<< um << " argument = " << um << "::stop);"
<< endl;
-
- os << name << " ();"
- << endl;
}
//
diff --git a/cli/options.cli b/cli/options.cli
index 28a4ee4..7f8e2dc 100644
--- a/cli/options.cli
+++ b/cli/options.cli
@@ -40,6 +40,13 @@ class options
on the command line."
};
+ bool --generate-parse
+ {
+ "Generate \cb{parse()} functions instead of parsing constructors. This
+ is primarily useful for being able to parse into an already initialized
+ options class instance, for example, to implement merging/overriding."
+ };
+
bool --generate-description
{
"Generate the option description list that can be examined at runtime."
diff --git a/cli/options.cxx b/cli/options.cxx
index dcb408a..dd9d075 100644
--- a/cli/options.cxx
+++ b/cli/options.cxx
@@ -562,6 +562,7 @@ options ()
output_dir_ (),
generate_modifier_ (),
generate_specifier_ (),
+ generate_parse_ (),
generate_description_ (),
generate_file_scanner_ (),
suppress_inline_ (),
@@ -625,6 +626,7 @@ options (int& argc,
output_dir_ (),
generate_modifier_ (),
generate_specifier_ (),
+ generate_parse_ (),
generate_description_ (),
generate_file_scanner_ (),
suppress_inline_ (),
@@ -691,6 +693,7 @@ options (int start,
output_dir_ (),
generate_modifier_ (),
generate_specifier_ (),
+ generate_parse_ (),
generate_description_ (),
generate_file_scanner_ (),
suppress_inline_ (),
@@ -757,6 +760,7 @@ options (int& argc,
output_dir_ (),
generate_modifier_ (),
generate_specifier_ (),
+ generate_parse_ (),
generate_description_ (),
generate_file_scanner_ (),
suppress_inline_ (),
@@ -825,6 +829,7 @@ options (int start,
output_dir_ (),
generate_modifier_ (),
generate_specifier_ (),
+ generate_parse_ (),
generate_description_ (),
generate_file_scanner_ (),
suppress_inline_ (),
@@ -889,6 +894,7 @@ options (::cli::scanner& s,
output_dir_ (),
generate_modifier_ (),
generate_specifier_ (),
+ generate_parse_ (),
generate_description_ (),
generate_file_scanner_ (),
suppress_inline_ (),
@@ -960,6 +966,9 @@ print_usage (::std::ostream& os)
os << "--generate-specifier Generate functions for determining whether the" << ::std::endl
<< " option was specified on the command line." << ::std::endl;
+ os << "--generate-parse Generate 'parse()' functions instead of parsing" << ::std::endl
+ << " constructors." << ::std::endl;
+
os << "--generate-description Generate the option description list that can be" << ::std::endl
<< " examined at runtime." << ::std::endl;
@@ -1128,6 +1137,8 @@ struct _cli_options_map_init
&::cli::thunk< options, bool, &options::generate_modifier_ >;
_cli_options_map_["--generate-specifier"] =
&::cli::thunk< options, bool, &options::generate_specifier_ >;
+ _cli_options_map_["--generate-parse"] =
+ &::cli::thunk< options, bool, &options::generate_parse_ >;
_cli_options_map_["--generate-description"] =
&::cli::thunk< options, bool, &options::generate_description_ >;
_cli_options_map_["--generate-file-scanner"] =
diff --git a/cli/options.hxx b/cli/options.hxx
index 22495e4..0328661 100644
--- a/cli/options.hxx
+++ b/cli/options.hxx
@@ -326,6 +326,8 @@ namespace cli
class options
{
public:
+ options ();
+
options (int& argc,
char** argv,
bool erase = false,
@@ -358,8 +360,6 @@ class options
::cli::unknown_mode option = ::cli::unknown_mode::fail,
::cli::unknown_mode argument = ::cli::unknown_mode::stop);
- options ();
-
// Option accessors.
//
const bool&
@@ -381,6 +381,9 @@ class options
generate_specifier () const;
const bool&
+ generate_parse () const;
+
+ const bool&
generate_description () const;
const bool&
@@ -548,6 +551,7 @@ class options
std::string output_dir_;
bool generate_modifier_;
bool generate_specifier_;
+ bool generate_parse_;
bool generate_description_;
bool generate_file_scanner_;
bool suppress_inline_;
diff --git a/cli/options.ixx b/cli/options.ixx
index a66312d..c2b9a80 100644
--- a/cli/options.ixx
+++ b/cli/options.ixx
@@ -240,6 +240,12 @@ generate_specifier () const
}
inline const bool& options::
+generate_parse () const
+{
+ return this->generate_parse_;
+}
+
+inline const bool& options::
generate_description () const
{
return this->generate_description_;
diff --git a/cli/source.cxx b/cli/source.cxx
index 6a8ea76..1e0be15 100644
--- a/cli/source.cxx
+++ b/cli/source.cxx
@@ -535,12 +535,18 @@ namespace
if (!abst)
{
- os << name << "::" << endl
- << name << " (int& argc," << endl
+ bool p (options.generate_parse ());
+ string n (
+ p
+ ? "void " + name + "::\n" + (name != "parse" ? "parse" : "parse_")
+ : name + "::\n" + name);
+
+ os << n << " (int& argc," << endl
<< "char** argv," << endl
<< "bool erase," << endl
<< um << " opt," << endl
<< um << " arg)";
+ if (!p)
{
option_init init (*this);
traversal::names names_init (init);
@@ -551,13 +557,13 @@ namespace
<< "_parse (s, opt, arg);"
<< "}";
- os << name << "::" << endl
- << name << " (int start," << endl
+ os << n << " (int start," << endl
<< "int& argc," << endl
<< "char** argv," << endl
<< "bool erase," << endl
<< um << " opt," << endl
<< um << " arg)";
+ if (!p)
{
option_init init (*this);
traversal::names names_init (init);
@@ -568,13 +574,13 @@ namespace
<< "_parse (s, opt, arg);"
<< "}";
- os << name << "::" << endl
- << name << " (int& argc," << endl
+ os << n << " (int& argc," << endl
<< "char** argv," << endl
<< "int& end," << endl
<< "bool erase," << endl
<< um << " opt," << endl
<< um << " arg)";
+ if (!p)
{
option_init init (*this);
traversal::names names_init (init);
@@ -586,14 +592,14 @@ namespace
<< "end = s.end ();"
<< "}";
- os << name << "::" << endl
- << name << " (int start," << endl
+ os << n << " (int start," << endl
<< "int& argc," << endl
<< "char** argv," << endl
<< "int& end," << endl
<< "bool erase," << endl
<< um << " opt," << endl
<< um << " arg)";
+ if (!p)
{
option_init init (*this);
traversal::names names_init (init);
@@ -605,10 +611,10 @@ namespace
<< "end = s.end ();"
<< "}";
- os << name << "::" << endl
- << name << " (" << cli << "::scanner& s," << endl
+ os << n << " (" << cli << "::scanner& s," << endl
<< um << " opt," << endl
<< um << " arg)";
+ if (!p)
{
option_init init (*this);
traversal::names names_init (init);