summaryrefslogtreecommitdiff
path: root/cli/runtime-source.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-04-01 18:37:30 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-04-01 18:37:30 +0200
commitbffe74e67f69fb4ad928230e86ca776bd39ae432 (patch)
tree93cddb51d4ffc27177ee36d17bb086434de5452e /cli/runtime-source.cxx
parentfc98bf23c16baf836d2c841792d4e0b35dd82727 (diff)
Implement combined flags (-xyz vs -x -y -z) and values (--foo=bar) support
Both are enabled by default but can be disable with --no-combined-flags and --no-combined-values options.
Diffstat (limited to 'cli/runtime-source.cxx')
-rw-r--r--cli/runtime-source.cxx51
1 files changed, 45 insertions, 6 deletions
diff --git a/cli/runtime-source.cxx b/cli/runtime-source.cxx
index 7d50f24..b87f933 100644
--- a/cli/runtime-source.cxx
+++ b/cli/runtime-source.cxx
@@ -355,6 +355,9 @@ generate_runtime_source (context& ctx, bool complete)
{
bool sep (!ctx.opt_sep.empty ());
+ const string& pfx (ctx.opt_prefix);
+ bool comb_values (!pfx.empty () && !ctx.options.no_combined_values ());
+
os << "// argv_file_scanner" << endl
<< "//" << endl
@@ -369,24 +372,60 @@ generate_runtime_source (context& ctx, bool complete)
<< "// 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)))"
+ << "const option_info* oi = 0;"
+ << "const char* ov = 0;"
+ << endl;
+
+ if (sep)
+ os << "if (!skip_)"
+ << "{";
+
+ os << "if ((oi = find (a)) != 0)"
<< "{"
<< "base::next ();"
<< endl
<< "if (!base::more ())" << endl
- << "throw missing_value (oi->option);"
+ << "throw missing_value (a);"
<< endl
+ << "ov = base::next ();"
+ << "}";
+
+ // Handle the combined option/value (--foo=bar). See the option parsing
+ // implementation for details.
+ //
+ if (comb_values)
+ {
+ size_t n (pfx.size ());
+
+ os << "else if (std::strncmp (a, \"" << pfx << "\", " <<
+ n << ") == 0)" // It looks like an option.
+ << "{"
+ << "if ((ov = std::strchr (a, '=')) != 0)" // Has '='.
+ << "{"
+ << "std::string o (a, 0, ov - a);"
+ << "if ((oi = find (o.c_str ())) != 0)"
+ << "{"
+ << "base::next ();"
+ << "++ov;" // That's the value.
+ << "}"
+ << "}"
+ << "}";
+ }
+
+ if (sep)
+ os << "}";
+
+ os << "if (oi != 0)"
+ << "{"
<< "if (oi->search_func != 0)"
<< "{"
- << "std::string f (oi->search_func (base::next (), oi->arg));"
+ << "std::string f (oi->search_func (ov, oi->arg));"
<< endl
<< "if (!f.empty ())" << endl
<< "load (f);"
<< "}"
<< "else" << endl
- << "load (base::next ());"
+ << "load (ov);"
<< endl
<< "if (!args_.empty ())" << endl
<< "return true;"