summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-09-02 17:06:10 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-09-02 17:06:10 +0200
commit7c83b407648f1ef919218d8965d4c21378910755 (patch)
tree52f62723ccf07bb59a45737cb2d0fc89ae691f4f /cli
parent2eb28736a05c7083f2b30b501954a789bbd85f88 (diff)
Add --generate-parse option
When specified, CLI will generate 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.
Diffstat (limited to 'cli')
-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);