summaryrefslogtreecommitdiff
path: root/cli/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli/cli')
-rw-r--r--cli/cli/.gitignore6
-rw-r--r--cli/cli/buildfile161
-rw-r--r--cli/cli/cli.cxx18
-rw-r--r--cli/cli/context.cxx128
-rw-r--r--cli/cli/context.hxx19
-rw-r--r--cli/cli/generator.cxx150
-rw-r--r--cli/cli/generator.hxx7
-rw-r--r--cli/cli/header.cxx6
-rw-r--r--cli/cli/html.cxx10
-rw-r--r--cli/cli/lexer.test.cxx3
-rw-r--r--cli/cli/man.cxx10
-rw-r--r--cli/cli/options.cli50
-rw-r--r--cli/cli/parser.cxx33
-rw-r--r--cli/cli/parser.hxx21
-rw-r--r--cli/cli/parser.test.cxx5
-rw-r--r--cli/cli/pregenerated/cli/options.cxx (renamed from cli/cli/options.cxx)289
-rw-r--r--cli/cli/pregenerated/cli/options.hxx (renamed from cli/cli/options.hxx)121
-rw-r--r--cli/cli/pregenerated/cli/options.ixx (renamed from cli/cli/options.ixx)443
-rw-r--r--cli/cli/runtime-header.cxx173
-rw-r--r--cli/cli/runtime-inline.cxx65
-rw-r--r--cli/cli/runtime-source.cxx382
-rw-r--r--cli/cli/semantics/class.cxx2
-rw-r--r--cli/cli/semantics/doc.cxx2
-rw-r--r--cli/cli/semantics/elements.cxx2
-rw-r--r--cli/cli/semantics/elements.hxx8
-rw-r--r--cli/cli/semantics/expression.cxx2
-rw-r--r--cli/cli/semantics/namespace.cxx2
-rw-r--r--cli/cli/semantics/option.cxx2
-rw-r--r--cli/cli/semantics/unit.cxx2
-rw-r--r--cli/cli/source.cxx19
-rw-r--r--cli/cli/traversal/elements.hxx2
-rw-r--r--cli/cli/txt.cxx5
-rw-r--r--cli/cli/version.hxx.in2
33 files changed, 1671 insertions, 479 deletions
diff --git a/cli/cli/.gitignore b/cli/cli/.gitignore
index 903d015..614e56f 100644
--- a/cli/cli/.gitignore
+++ b/cli/cli/.gitignore
@@ -1,5 +1,7 @@
-cli
-version.hxx
+/cli
+/pregenerated/cli/cli
+/version.hxx
+/options.?xx
# Unit test executables and Testscript output directories (can be symlinks).
#
diff --git a/cli/cli/buildfile b/cli/cli/buildfile
index 2385a7d..92c3e6e 100644
--- a/cli/cli/buildfile
+++ b/cli/cli/buildfile
@@ -15,63 +15,146 @@ exe{cli}:
cli.checksum = $version
}
-libue{cli}: {hxx ixx txx cxx}{** -cli -version -options -**.test...} \
- {hxx}{version} {hxx ixx cxx}{options} \
- $libs
+hdr = {hxx ixx txx}{* -cli -version -options -*.test...}
+src = cxx{* -cli -version -options -*.test...}
+
+all_s = semantics/{hxx ixx txx cxx}{*}
+all_t = traversal/{hxx ixx txx cxx}{*}
+
+libue{cli}: $hdr $src $all_s $all_t {hxx}{version} $libs
hxx{version}: in{version} $src_root/manifest
-# Unit tests.
+# Build options (apply to both bootstrap and final version).
#
-exe{*.test}:
+cxx.poptions =+ "-I$out_root" "-I$src_root"
+
+# CLI uses its own generated code to handle the command line. To solve the
+# chicken and egg problem that this poses we keep pregenerated source code in
+# pregenerated/.
+#
+# In the consumption build ($config.cli.develop == false), we just use this
+# pregenerated source code to build the final version of the compiler. In the
+# development build ($config.cli.develop == true) we use this pregenerated
+# source code to build a bootstrap version of the compiler which we then use
+# to regenerate the source code and build that final version from that.
+
+## Consumption build ($develop == false).
+#
+
+# Use pregenerated versions to build the final version of cli.
+#
+libue{cli}: pregenerated/{hxx ixx cxx}{**}: include = (!$develop)
+
+if! $develop
+ cxx.poptions =+ "-I($src_base/pregenerated)" # Note: must come first.
+
+# Distribute pregenerated versions only in the consumption build.
+#
+pregenerated/{hxx ixx cxx}{*}: dist = (!$develop)
+
+#
+##
+
+## Development build ($develop == true).
+#
+libue{cli}: {hxx ixx cxx}{options}: include = $develop
+
+# Bootstrap.
+#
+# The plan is as follows:
+#
+# 1. Build the bootstrap version of cli using a copy of options.?xx saved in
+# pregenerated/cli/.
+#
+# 2. Use that to regenerate options.?xx. If the result differs from the saved
+# version, copy it over and fail the build, asking for a restart.
+#
+# 3. Otherwise, proceed to build the final version of cli using regenerated
+# options.?xx.
+#
+pregenerated/
{
- test = true
- install = false
+ # This should only apply to the bootstrap build.
+ #
+ cxx.poptions =+ "-I$src_base" # Note: must come first.
+
+ cli/
+ {
+ # Note: semantics/ and traversal/ do not include options.hxx so we can
+ # share their object files.
+ #
+ exe{cli}: obj{cli $name($src) options} ../../{$all_s $all_t} $libs
+
+ for s: cli $name($src)
+ obj{$s}: ../../cxx{$s} $libs
+
+ obj{options}: {hxx ixx cxx}{options}
+
+ obj{cli}: cxx.poptions += -DCLI_BOOTSTRAP
+ }
}
-for t: cxx{**.test...}
+# In the development build distribute regenerated {hxx ixx cxx}{options},
+# remapping their locations to the paths of the pregenerated versions (which
+# are only distributed in the consumption build; see above). This way we make
+# sure that the distributed files are always up-to-date.
+#
+<{hxx ixx cxx}{options}>: cli{options} pregenerated/cli/exe{cli}
{
- d = $directory($t)
- n = $name($t)...
+ dist = ($develop ? pregenerated/cli/ : false)
- ./: $d/exe{$n}: $t $d/{hxx ixx txx}{+$n} $d/testscript{+$n}
- $d/exe{$n}: libue{cli}: bin.whole = false
+ # Symlink the generated code in src for convenience of development.
+ #
+ backlink = true
}
+%
+if $develop
+{{
+ options = --include-with-brackets --include-prefix cli \
+ --guard-prefix CLI --generate-file-scanner \
+ --generate-specifier --generate-modifier \
+ --suppress-undocumented --reserved-name stdout
+
+ diag cli ($<[0]) -> $>
+ ($<[1]) $options -o $out_base $path($<[0])
+
+ # If the result differs from the bootstrap version, copy it over and
+ # request the build restart.
+ #
+ if diff $src_base/pregenerated/cli/options.hxx $path($>[0]) >- && \
+ diff $src_base/pregenerated/cli/options.ixx $path($>[1]) >- && \
+ diff $src_base/pregenerated/cli/options.cxx $path($>[2]) >-
+ exit
+ end
+
+ cp $path($>[0]) $src_base/pregenerated/cli/options.hxx
+ cp $path($>[1]) $src_base/pregenerated/cli/options.ixx
+ cp $path($>[2]) $src_base/pregenerated/cli/options.cxx
+
+ exit "bootstrap options.?xx have changed, restart the build"
+}}
-# Build options.
#
+##
+
# Pass the copyright notice extracted from the LICENSE file.
#
-copyright = $process.run_regex(cat $src_root/LICENSE, \
- 'Copyright \(c\) (.+)\.', \
- '\1')
-
obj{cli}: cxx.poptions += -DCLI_COPYRIGHT=\"$copyright\"
-# Generated options parsing code.
-#
-# @@ This will eventually be replaced with an ah hoc recipe.
+# Unit tests.
#
-if ($config.cli != [null] && $config.cli != false)
+exe{*.test}:
{
- cli.cxx{options}: cli{options}
-
- cli.options += --include-with-brackets --include-prefix cli \
---guard-prefix CLI --generate-file-scanner --generate-specifier \
---generate-modifier --suppress-undocumented --reserved-name stdout
+ test = true
+ install = false
+}
- cli.cxx{*}:
- {
- # Include the generated cli files into the distribution and don't remove
- # them when cleaning in src (so that clean results in a state identical to
- # distributed).
- #
- dist = true
- clean = ($src_root != $out_root)
+for t: cxx{**.test...}
+{
+ d = $directory($t)
+ n = $name($t)...
- # We keep the generated code in the repository so copy it back to src
- # in case of a forwarded configuration.
- #
- backlink = overwrite
- }
+ ./: $d/exe{$n}: $t $d/{hxx ixx txx}{+$n} $d/testscript{+$n}
+ $d/exe{$n}: libue{cli}: bin.whole = false
}
diff --git a/cli/cli/cli.cxx b/cli/cli/cli.cxx
index 754c5ff..d56f9e2 100644
--- a/cli/cli/cli.cxx
+++ b/cli/cli/cli.cxx
@@ -6,9 +6,10 @@
#include <string>
#include <memory> // unique_ptr
#include <fstream>
+#include <utility> // move()
#include <iostream>
-#include <cutl/compiler/code-stream.hxx>
+#include <libcutl/compiler/code-stream.hxx>
#include <cli/semantics/doc.hxx>
@@ -16,7 +17,13 @@
#include <cli/parser.hxx>
#include <cli/generator.hxx>
-#include <cli/version.hxx>
+#ifndef CLI_BOOTSTRAP
+# include <cli/version.hxx>
+#else
+# define CLI_VERSION_ID 0
+# define CLI_VERSION_FULL 0
+# define CLI_COPYRIGHT ""
+#endif
using namespace std;
using namespace cutl;
@@ -115,8 +122,9 @@ main (int argc, char* argv[])
// Parse and generate.
//
- parser p (include_paths);
- unique_ptr<semantics::cli_unit> unit (p.parse (ifs, path));
+ parser p (include_paths, ops.generate_dep ());
+ parser::parse_result r (p.parse (ifs, path));
+ unique_ptr<semantics::cli_unit>& unit (r.unit);
// Merge documentation variables from the command line.
//
@@ -137,7 +145,7 @@ main (int argc, char* argv[])
}
generator g;
- g.generate (ops, *unit, path);
+ g.generate (ops, move (*unit), move (r.dependencies), path);
}
catch (cli::exception const& ex)
{
diff --git a/cli/cli/context.cxx b/cli/cli/context.cxx
index 54bb988..2c6a733 100644
--- a/cli/cli/context.cxx
+++ b/cli/cli/context.cxx
@@ -7,6 +7,7 @@
#include <cstring> // strncmp()
#include <fstream>
#include <sstream>
+#include <utility> // move()
#include <iostream>
#include <cli/context.hxx>
@@ -114,6 +115,8 @@ context (ostream& os_,
opt_prefix (options.option_prefix ()),
opt_sep (options.option_separator ()),
cli (data_->cli_),
+ exp (data_->exp_),
+ exp_inl (data_->exp_inl_),
reserved_name_map (options.reserved_name ()),
keyword_set (data_->keyword_set_),
link_regex (data_->link_regex_),
@@ -141,6 +144,16 @@ context (ostream& os_,
if (!cli.empty () && cli[0] != ':')
data_->cli_ = "::" + data_->cli_;
+ data_->exp_ = options.export_symbol ();
+
+ if (!exp.empty ())
+ {
+ data_->exp_ += ' ';
+
+ if (options.suppress_inline ())
+ data_->exp_inl_ = data_->exp_;
+ }
+
for (size_t i (0); i < sizeof (keywords) / sizeof (char*); ++i)
data_->keyword_set_.insert (keywords[i]);
@@ -179,6 +192,8 @@ context (context& c)
opt_prefix (c.opt_prefix),
opt_sep (c.opt_sep),
cli (c.cli),
+ exp (c.exp),
+ exp_inl (c.exp_inl),
reserved_name_map (c.reserved_name_map),
keyword_set (c.keyword_set),
link_regex (c.link_regex),
@@ -296,6 +311,59 @@ process_link_target (const string& tg)
return found ? r : tg;
}
+void context::
+preprocess_ascii_tree (string& s)
+{
+ // tree --charset=UTF-8 uses the following box-drawing characters (see
+ // color.c):
+ //
+ // CHAR UTF-8 ASCII
+ //----------------------------
+ //
+ // | E29482 |
+ //
+ // -- E29480 -
+ //
+ // |- E2949C |
+ //
+ // |_ E29494 `
+ //
+ // <nbspace> C2A0 <space>
+ //
+ // Note that here we rely on the fact that neither E2 nor C2 can appear as
+ // continuation bytes.
+ //
+ for (size_t i (0); i != s.size (); ++i)
+ {
+ i = s.find_first_of ("\xE2\xC2", i);
+
+ if (i == string::npos)
+ break;
+
+ if (s[i] == '\xE2')
+ {
+ if (s[i + 1] == '\x94')
+ {
+ const char* r;
+ switch (s[i + 2])
+ {
+ case '\x80': r = "-"; break;
+ case '\x82':
+ case '\x9c': r = "|"; break;
+ case '\x94': r = "`"; break;
+ default: continue;
+ }
+
+ s.replace (i, 3, r);
+ }
+ }
+ else
+ {
+ if (s[i + 1] == '\xA0')
+ s.replace (i, 2, " ");
+ }
+ }
+}
string context::
translate_arg (string const& s, std::set<string>& set)
@@ -1270,15 +1338,32 @@ format (semantics::scope& scope, string const& s, bool para)
stack<block> blocks;
blocks.push (block (block::text, para, "")); // Top-level.
- // Number of li in ol. Since we don't support nested lists, we don't
- // need to push it into the stack.
+ // Number of li in ol. Since we don't support nested lists (except in HTML
+ // where this is unused), we don't need to push it into the stack.
//
size_t ol_count (0);
// Mapping of \h to HTML tag. By default it is <h1> until we encounter
- // \h0 or \h1 at which point we change it to <h2>.
+ // \h0 or \h1 at which point we change it to <h2>. It can also be mapped
+ // with --html-heading-map.
//
- char html_h ('1');
+ char html_h ('\0');
+
+ typedef map<char, string> html_hmap;
+ if (ot == ot_html)
+ {
+ const html_hmap& hm (options.html_heading_map ());
+ html_hmap::const_iterator mi (hm.find ('h'));
+
+ if (mi != hm.end ())
+ {
+ // Note: this mapping back is necessary for TOC to function correctly
+ // with multiple string fragments.
+ //
+ if (mi->second == "h1") html_h = '1';
+ else if (mi->second == "h2") html_h = '2';
+ }
+ }
bool last (false);
for (size_t b (0), e; !last; b = e + 1)
@@ -1532,7 +1617,10 @@ format (semantics::scope& scope, string const& s, bool para)
case block::dl: good = (k == block::li); break;
case block::li: good = (k == block::note ||
k == block::text ||
- k == block::pre ); break;
+ k == block::pre ||
+ (ot == ot_html && (k == block::ul ||
+ k == block::ol ||
+ k == block::dl))); break;
case block::note: good = (k == block::text ||
k == block::pre ||
(ot == ot_html && (k == block::ul ||
@@ -1644,7 +1732,7 @@ format (semantics::scope& scope, string const& s, bool para)
{
case block::h: blocks.push (block (k, false, id, header)); break;
case block::ul:
- case block::ol: ol_count = 0; // Fall through.
+ case block::ol: if (ot != ot_html) ol_count = 0; // Fall through.
case block::dl: blocks.push (block (k, true, id)); break;
case block::li:
{
@@ -1652,9 +1740,12 @@ format (semantics::scope& scope, string const& s, bool para)
{
case block::ol:
{
- ostringstream os;
- os << ++ol_count;
- header = os.str ();
+ if (ot != ot_html)
+ {
+ ostringstream os;
+ os << ++ol_count;
+ header = os.str ();
+ }
break;
}
case block::dl:
@@ -1919,7 +2010,7 @@ format (semantics::scope& scope, string const& s, bool para)
case '1': break; // Always unwind.
case 'h':
{
- pop = html_h == '1' || e.type == 'h' || e.type == '2';
+ pop = html_h != '2' || e.type == 'h' || e.type == '2';
break;
}
case '2': pop = e.type == '2'; break;
@@ -2016,9 +2107,10 @@ format (semantics::scope& scope, string const& s, bool para)
// Same as in non-TOC mode below.
//
- // @@ This only works for a single string fragment.
+ // This only works automatically for a single string fragment.
+ // For multiple string fragments use --html-heading-map.
//
- if (t == '0' || t == '1')
+ if (html_h == '\0' && (t == '0' || t == '1'))
html_h = '2';
break;
@@ -2136,9 +2228,8 @@ format (semantics::scope& scope, string const& s, bool para)
string h;
string c;
- typedef map<char, string> map;
- const map& hm (options.html_heading_map ());
- map::const_iterator mi (hm.find (t));
+ const html_hmap& hm (options.html_heading_map ());
+ html_hmap::const_iterator mi (hm.find (t));
if (mi == hm.end ())
{
@@ -2147,7 +2238,7 @@ format (semantics::scope& scope, string const& s, bool para)
case '0': h = "h1"; c = "preface"; break;
case 'H': h = "h1"; c = "part"; break;
case '1': h = "h1"; break;
- case 'h': h = html_h == '1' ? "h1" : "h2"; break;
+ case 'h': h = html_h != '2' ? "h1" : "h2"; break;
case '2': h = "h3"; break;
}
}
@@ -2173,9 +2264,10 @@ format (semantics::scope& scope, string const& s, bool para)
v += "</" + h + '>';
- // @@ This only works for a single string fragment.
+ // This only works automatically for a single string fragment.
+ // For multiple string fragments use --html-heading-map.
//
- if (t == '0' || t == '1')
+ if (html_h == '\0' && (t == '0' || t == '1'))
html_h = '2';
break;
diff --git a/cli/cli/context.hxx b/cli/cli/context.hxx
index 633b8ad..c5802ed 100644
--- a/cli/cli/context.hxx
+++ b/cli/cli/context.hxx
@@ -12,9 +12,9 @@
#include <ostream>
#include <cstddef> // std::size_t
-#include <cutl/re.hxx>
-#include <cutl/shared-ptr.hxx>
-#include <cutl/fs/path.hxx>
+#include <libcutl/re.hxx>
+#include <libcutl/shared-ptr.hxx>
+#include <libcutl/fs/path.hxx>
#include <cli/options.hxx>
#include <cli/semantics.hxx>
@@ -92,6 +92,8 @@ public:
string const& opt_prefix;
string const& opt_sep;
string const& cli;
+ string const& exp;
+ string const& exp_inl; // Export symbol if inline is suppressed.
typedef std::map<string, string> reserved_name_map_type;
reserved_name_map_type const& reserved_name_map;
@@ -135,6 +137,8 @@ private:
{
string inl_;
string cli_;
+ string exp_;
+ string exp_inl_;
keyword_set_type keyword_set_;
regex_mapping link_regex_;
id_set_type id_set_;
@@ -153,10 +157,13 @@ public:
string
process_link_target (const string&);
- // Translate and format the documentation string. Translate converts
- // the <arg>-style constructs to \i{arg}. Format converts the string
- // to the output format.
+ // Preprocess, translate, and format the documentation string. Translate
+ // converts the <arg>-style constructs to \i{arg}. Format converts the
+ // string to the output format.
//
+ static void
+ preprocess_ascii_tree (string&);
+
static string
translate_arg (string const&, std::set<string>&);
diff --git a/cli/cli/generator.cxx b/cli/cli/generator.cxx
index df1b99e..623ac67 100644
--- a/cli/cli/generator.cxx
+++ b/cli/cli/generator.cxx
@@ -2,15 +2,16 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
-#include <cctype> // std::toupper, std::is{alpha,upper,lower}
+#include <cctype> // toupper, is{alpha,upper,lower}
#include <string>
#include <fstream>
+#include <utility> // move()
#include <iostream>
-#include <cutl/fs/auto-remove.hxx>
+#include <libcutl/fs/auto-remove.hxx>
-#include <cutl/compiler/code-stream.hxx>
-#include <cutl/compiler/cxx-indenter.hxx>
+#include <libcutl/compiler/code-stream.hxx>
+#include <libcutl/compiler/cxx-indenter.hxx>
#include <cli/header.hxx>
#include <cli/inline.hxx>
@@ -98,7 +99,10 @@ namespace
}
void
- append (context& ctx, vector<string> const& text, string const& file)
+ append (context& ctx,
+ vector<string> const& text,
+ string const& file,
+ vector<path>* pdeps)
{
for (vector<string>::const_iterator i (text.begin ());
i != text.end (); ++i)
@@ -111,7 +115,8 @@ namespace
ifstream ifs;
open (ifs, file);
- path d (path (file).directory ());
+ path p (file);
+ path d (p.directory ());
// getline() will set the failbit if it failed to extract anything,
// not even the delimiter and eofbit if it reached eof before seeing
@@ -119,6 +124,9 @@ namespace
//
for (string s; getline (ifs, s); )
append (ctx, s, &d);
+
+ if (pdeps != nullptr)
+ pdeps->push_back (move (p.normalize ()));
}
}
}
@@ -129,7 +137,10 @@ generator ()
}
void generator::
-generate (options& ops, semantics::cli_unit& unit, path const& p)
+generate (options& ops,
+ semantics::cli_unit&& unit,
+ vector<path>&& deps,
+ path const& p)
{
if (ops.generate_group_scanner ())
ops.generate_vector_scanner (true);
@@ -168,8 +179,48 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
}
}
+ bool gen_dep (ops.generate_dep ());
+ vector<path>* pdeps (gen_dep ? &deps : nullptr);
+ vector<path> depts; // Dependents.
+
fs::auto_removes auto_rm;
+ // gen_dep
+ //
+ // Make sure that we remove the potentially outdated dependency file if we
+ // fail to generate any source/documentation file.
+ //
+ // Note that we will write the dependency file content later, when all the
+ // dependents and dependencies are determined.
+ //
+ ofstream dep;
+
+ if (gen_dep)
+ {
+ path dep_path;
+
+ if (ops.dep_file ().empty ())
+ {
+ dep_path = path (pfx + base + sfx + ops.dep_suffix ());
+
+ if (!ops.output_dir ().empty ())
+ dep_path = path (ops.output_dir ()) / dep_path;
+ }
+ else
+ dep_path = path (ops.dep_file ());
+
+ dep.open (dep_path.string ().c_str (), ios_base::out);
+
+ if (!dep.is_open ())
+ {
+ cerr << "error: unable to open '" << dep_path << "' in write mode"
+ << endl;
+ throw failed ();
+ }
+
+ auto_rm.add (dep_path);
+ }
+
// C++ output.
//
if (gen_cxx)
@@ -235,6 +286,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
auto_rm.add (hxx_path);
+ if (gen_dep)
+ depts.push_back (move (hxx_path.normalize ()));
+
//
//
ofstream ixx;
@@ -251,6 +305,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
}
auto_rm.add (ixx_path);
+
+ if (gen_dep)
+ depts.push_back (move (ixx_path.normalize ()));
}
//
@@ -266,6 +323,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
auto_rm.add (cxx_path);
+ if (gen_dep)
+ depts.push_back (move (cxx_path.normalize ()));
+
// Print headers.
//
hxx << cxx_header;
@@ -304,7 +364,7 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
//
hxx << "// Begin prologue." << endl
<< "//" << endl;
- append (ctx, ops.hxx_prologue (), ops.hxx_prologue_file ());
+ append (ctx, ops.hxx_prologue (), ops.hxx_prologue_file (), pdeps);
hxx << "//" << endl
<< "// End prologue." << endl
<< endl;
@@ -331,7 +391,7 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
//
hxx << "// Begin epilogue." << endl
<< "//" << endl;
- append (ctx, ops.hxx_epilogue (), ops.hxx_epilogue_file ());
+ append (ctx, ops.hxx_epilogue (), ops.hxx_epilogue_file (), pdeps);
hxx << "//" << endl
<< "// End epilogue." << endl
<< endl;
@@ -349,7 +409,7 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
//
ixx << "// Begin prologue." << endl
<< "//" << endl;
- append (ctx, ops.ixx_prologue (), ops.ixx_prologue_file ());
+ append (ctx, ops.ixx_prologue (), ops.ixx_prologue_file (), pdeps);
ixx << "//" << endl
<< "// End prologue." << endl
<< endl;
@@ -369,7 +429,7 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
//
ixx << "// Begin epilogue." << endl
<< "//" << endl;
- append (ctx, ops.ixx_epilogue (), ops.ixx_epilogue_file ());
+ append (ctx, ops.ixx_epilogue (), ops.ixx_epilogue_file (), pdeps);
ixx << "//" << endl
<< "// End epilogue." << endl;
}
@@ -383,7 +443,7 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
//
cxx << "// Begin prologue." << endl
<< "//" << endl;
- append (ctx, ops.cxx_prologue (), ops.cxx_prologue_file ());
+ append (ctx, ops.cxx_prologue (), ops.cxx_prologue_file (), pdeps);
cxx << "//" << endl
<< "// End prologue." << endl
<< endl;
@@ -413,7 +473,7 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
//
cxx << "// Begin epilogue." << endl
<< "//" << endl;
- append (ctx, ops.cxx_epilogue (), ops.cxx_epilogue_file ());
+ append (ctx, ops.cxx_epilogue (), ops.cxx_epilogue_file (), pdeps);
cxx << "//" << endl
<< "// End epilogue." << endl
<< endl;
@@ -443,6 +503,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
}
auto_rm.add (man_path);
+
+ if (gen_dep)
+ depts.push_back (move (man_path.normalize ()));
}
// The explicit cast helps VC++ 8.0 overcome its issues.
@@ -452,9 +515,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
for (bool first (true); first || ctx.toc; first = false)
{
- append (ctx, ops.man_prologue (), ops.man_prologue_file ());
+ append (ctx, ops.man_prologue (), ops.man_prologue_file (), pdeps);
generate_man (ctx);
- append (ctx, ops.man_epilogue (), ops.man_epilogue_file ());
+ append (ctx, ops.man_epilogue (), ops.man_epilogue_file (), pdeps);
if (ctx.toc)
{
@@ -492,6 +555,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
}
auto_rm.add (html_path);
+
+ if (gen_dep)
+ depts.push_back (move (html_path.normalize ()));
}
// The explicit cast helps VC++ 8.0 overcome its issues.
@@ -501,9 +567,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
for (bool first (true); first || ctx.toc; first = false)
{
- append (ctx, ops.html_prologue (), ops.html_prologue_file ());
+ append (ctx, ops.html_prologue (), ops.html_prologue_file (), pdeps);
generate_html (ctx);
- append (ctx, ops.html_epilogue (), ops.html_epilogue_file ());
+ append (ctx, ops.html_epilogue (), ops.html_epilogue_file (), pdeps);
if (ctx.toc)
{
@@ -538,6 +604,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
}
auto_rm.add (txt_path);
+
+ if (gen_dep)
+ depts.push_back (move (txt_path.normalize ()));
}
// The explicit cast helps VC++ 8.0 overcome its issues.
@@ -547,9 +616,9 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
for (bool first (true); first || ctx.toc; first = false)
{
- append (ctx, ops.txt_prologue (), ops.txt_prologue_file ());
+ append (ctx, ops.txt_prologue (), ops.txt_prologue_file (), pdeps);
generate_txt (ctx);
- append (ctx, ops.txt_epilogue (), ops.txt_epilogue_file ());
+ append (ctx, ops.txt_epilogue (), ops.txt_epilogue_file (), pdeps);
if (ctx.toc)
{
@@ -561,6 +630,49 @@ generate (options& ops, semantics::cli_unit& unit, path const& p)
ctx.verify_id_ref ();
}
+ // gen_dep
+ //
+ if (gen_dep)
+ {
+ // Write the specified path to the dependencies file stream, escaping
+ // colons and backslashes.
+ //
+ auto write = [&dep] (path const& p)
+ {
+ for (char c: p.string ())
+ {
+ if (c == ':' || c == '\\')
+ dep << '\\';
+
+ dep << c;
+ }
+ };
+
+ // Note that we don't add the dependency file as a dependent, but in the
+ // future may invent some option which triggers that.
+ //
+ bool first (true);
+ for (const auto& p: depts)
+ {
+ if (!first)
+ dep << " \\" << endl;
+ else
+ first = false;
+
+ write (p);
+ }
+
+ dep << ':';
+
+ for (const auto& p: deps)
+ {
+ dep << " \\" << endl
+ << " "; write (p);
+ }
+
+ dep << endl;
+ }
+
auto_rm.cancel ();
}
catch (const generation_failed&)
diff --git a/cli/cli/generator.hxx b/cli/cli/generator.hxx
index f567528..3deb3f3 100644
--- a/cli/cli/generator.hxx
+++ b/cli/cli/generator.hxx
@@ -5,6 +5,8 @@
#ifndef CLI_GENERATOR_HXX
#define CLI_GENERATOR_HXX
+#include <vector>
+
#include <cli/options.hxx>
#include <cli/semantics/unit.hxx>
@@ -16,7 +18,10 @@ public:
class failed {};
void
- generate (options&, semantics::cli_unit&, semantics::path const&);
+ generate (options&,
+ semantics::cli_unit&&,
+ std::vector<semantics::path>&& dependencies,
+ semantics::path const&);
private:
generator (generator const&);
diff --git a/cli/cli/header.cxx b/cli/cli/header.cxx
index a2a3ccd..87ff259 100644
--- a/cli/cli/header.cxx
+++ b/cli/cli/header.cxx
@@ -115,7 +115,7 @@ namespace
string name (escape (c.name ()));
string um (cli + "::unknown_mode");
- os << "class " << name;
+ os << "class " << exp << name;
{
base b (*this);
@@ -367,13 +367,13 @@ generate_header (context& ctx)
string up (ctx.cli + "::usage_para");
string const& ost (ctx.options.ostream_type ());
- os << up << endl
+ os << ctx.exp << up << endl
<< n << "usage (" << ost << "&," << endl
<< up << " = " << up << "::none);"
<< endl;
if (ctx.gen_usage == ut_both)
- os << up << endl
+ os << ctx.exp << up << endl
<< n << "long_usage (" << ost << "&," << endl
<< up << " = " << up << "::none);"
<< endl;
diff --git a/cli/cli/html.cxx b/cli/cli/html.cxx
index b374b91..48eb5e3 100644
--- a/cli/cli/html.cxx
+++ b/cli/cli/html.cxx
@@ -127,13 +127,16 @@ namespace
// n > 2 - arg string, short string, long string
//
size_t n (ds.size ());
- const string& d (
+ string d (
n == 1
? (cd_ == cd_short ? first_sentence (ds[0]) : ds[0])
: (n == 2
? (cd_ == cd_short ? first_sentence (ds[1]) : ds[1])
: ds[cd_ == cd_short ? 1 : 2]));
+ if (options.ascii_tree ())
+ preprocess_ascii_tree (d);
+
std::set<string> arg_set;
if (n > 1)
translate_arg (ds[0], arg_set);
@@ -211,6 +214,8 @@ namespace
if (type != "bool" || doc.size () >= 3)
{
+ // Note: we naturally assume this doesn't need --ascii-tree treatment.
+ //
string s (
translate_arg (
doc.size () > 0 ? doc[0] : string ("<arg>"), arg_set));
@@ -236,6 +241,9 @@ namespace
d = (cd_ == cd_short ? first_sentence (doc[1]) : doc[1]);
}
+ if (options.ascii_tree ())
+ preprocess_ascii_tree (d);
+
// Format the documentation string.
//
d = format (o.scope (), escape_html (translate (d, arg_set)), false);
diff --git a/cli/cli/lexer.test.cxx b/cli/cli/lexer.test.cxx
index 0eb4dcb..a5cc2f3 100644
--- a/cli/cli/lexer.test.cxx
+++ b/cli/cli/lexer.test.cxx
@@ -8,6 +8,9 @@
#include <cli/token.hxx>
#include <cli/lexer.hxx>
+#undef NDEBUG
+#include <cassert>
+
using namespace std;
const char* keywords[] =
diff --git a/cli/cli/man.cxx b/cli/cli/man.cxx
index df703e8..d446b2a 100644
--- a/cli/cli/man.cxx
+++ b/cli/cli/man.cxx
@@ -91,13 +91,16 @@ namespace
// n > 2 - arg string, short string, long string
//
size_t n (ds.size ());
- const string& d (
+ string d (
n == 1
? (cd_ == cd_short ? first_sentence (ds[0]) : ds[0])
: (n == 2
? (cd_ == cd_short ? first_sentence (ds[1]) : ds[1])
: ds[cd_ == cd_short ? 1 : 2]));
+ if (options.ascii_tree ())
+ preprocess_ascii_tree (d);
+
std::set<string> arg_set;
if (n > 1)
translate_arg (ds[0], arg_set);
@@ -149,6 +152,8 @@ namespace
if (type != "bool" || doc.size () >= 3)
{
+ // Note: we naturally assume this doesn't need --ascii-tree treatment.
+ //
string s (
translate_arg (
doc.size () > 0 ? doc[0] : string ("<arg>"), arg_set));
@@ -174,6 +179,9 @@ namespace
d = (cd_ == cd_short ? first_sentence (doc[1]) : doc[1]);
}
+ if (options.ascii_tree ())
+ preprocess_ascii_tree (d);
+
// Format the documentation string.
//
d = format (o.scope (), translate (d, arg_set), false);
diff --git a/cli/cli/options.cli b/cli/cli/options.cli
index ff462d3..211e01f 100644
--- a/cli/cli/options.cli
+++ b/cli/cli/options.cli
@@ -108,11 +108,15 @@ class options
{ -f }+ { -b }+ arg +{ f=1 } +{ b=2 } # 'arg' with '-f' 'b' 'f=1' 'b=2'
\
- Note that the group applies to a single argument only. For example:
+ The group applies to a single argument only unless multiple arguments
+ are themselves grouped with '\cb{{}' and '\cb{\}}'. For example:
\
- { --foo }+ arg1 arg2 +{ --bar } # 'arg1' with '--foo' and
- # 'arg2' with '--bar'
+ { --foo }+ arg1 arg2 +{ --bar } # 'arg1' with '--foo'
+ # 'arg2' with '--bar'
+
+ { --foo }+ { arg1 arg2 } +{ --bar } # 'arg1' with '--foo' '--bar'
+ # 'arg2' with '--foo' '--bar'
\
The group separators ('\cb{{}', '\cb{\}+'}, etc) must be separate command
@@ -167,6 +171,13 @@ class options
should be used to print usage and exception information."
};
+ std::string --export-symbol
+ {
+ "<symbol>",
+ "Insert <symbol> in places where DLL export/import control statements
+ (\cb{__declspec(dllexport/dllimport)}) are necessary."
+ };
+
bool --generate-cxx
{
"Generate C++ code. If neither \cb{--generate-man}, \cb{--generate-html},
@@ -188,6 +199,18 @@ class options
"Generate documentation in the plain text format, similar to usage."
};
+ bool --generate-dep
+ {
+ "Generate \cb{make} dependency information. This option triggers the
+ creation of the \cb{.d} file containing the dependencies of the generated
+ files on the main \cb{.cli} file as well as all the \cb{.cli} files that
+ it includes or sources, transitively. Paths specified with the
+ \cb{--*-prologue-file} and \cb{--*-epilogue-file} options are also
+ added as dependencies. Note, however, that paths specified with the
+ \cb{--options-file} option are not added (since they may or may not
+ contain options that affect the output)."
+ };
+
bool --stdout
{
"Write output to STDOUT instead of a file. This option is not valid
@@ -253,6 +276,13 @@ class options
files, and would like their usage to have the same indentation level."
};
+ bool --ascii-tree
+ {
+ "Convert UTF-8 \cb{tree(1)} output to ASCII. Specifically, box-drawing
+ characters used in the \cb{--charset=UTF-8} output are replaced with
+ ASCII characters used in the \cb{--charset=ASCII} output."
+ };
+
bool --ansi-color
{
"Use ANSI color escape sequences when printing usage. By \"color\" we
@@ -568,6 +598,20 @@ class options
the generated text file."
};
+ std::string --dep-suffix = ".d"
+ {
+ "<suffix>",
+ "Use <suffix> instead of the default \cb{.d} to construct the name of the
+ generated dependency file. See also \cb{--dep-file}."
+ };
+
+ std::string --dep-file
+ {
+ "<path>",
+ "Use <path> as the generated dependency file path instead of deriving it
+ from the input file name."
+ };
+
std::string --option-prefix = "-"
{
"<prefix>",
diff --git a/cli/cli/parser.cxx b/cli/cli/parser.cxx
index 4685edc..e2efca5 100644
--- a/cli/cli/parser.cxx
+++ b/cli/cli/parser.cxx
@@ -17,6 +17,7 @@
#include <fstream>
#include <sstream>
+#include <utility> // move()
#include <iostream>
#include <cli/token.hxx>
@@ -66,7 +67,7 @@ const char* punctuation[] = {
// Output the token type and value in a format suitable for diagnostics.
//
-std::ostream&
+static std::ostream&
operator<< (std::ostream& os, token const& t)
{
switch (t.type ())
@@ -184,16 +185,19 @@ recover (token& t)
}
}
-unique_ptr<cli_unit> parser::
+parser::parse_result parser::
parse (std::istream& is, path const& p)
{
unique_ptr<cli_unit> unit (new cli_unit (p, 1, 1));
{
path ap (p);
- ap.absolute ();
+ ap.complete ();
ap.normalize ();
- include_map_[ap] = unit.get ();
+ include_map_[move (ap)] = unit.get ();
+
+ if (collect_dependencies_)
+ dependencies_.push_back (path (p).normalize ());
}
root_ = cur_ = unit.get ();
@@ -211,7 +215,7 @@ parse (std::istream& is, path const& p)
if (!valid_ || !l.valid ())
throw invalid_input ();
- return unit;
+ return parse_result {move (unit), move (dependencies_)};
}
void parser::
@@ -350,6 +354,16 @@ source_decl ()
if (valid_)
{
+ if (collect_dependencies_)
+ {
+ path ap (p);
+ ap.complete ();
+ ap.normalize ();
+
+ if (include_map_.emplace (move (ap), nullptr).second)
+ dependencies_.push_back (p);
+ }
+
auto_restore<path const> new_path (path_, &p);
ifstream ifs (p.string ().c_str ());
@@ -468,15 +482,18 @@ include_decl ()
// Detect and ignore multiple inclusions.
//
path ap (p);
- ap.absolute ();
+ ap.complete ();
ap.normalize ();
include_map::iterator it (include_map_.find (ap));
- if (it == include_map_.end ())
+ if (it == include_map_.end () || it->second == nullptr)
{
+ if (collect_dependencies_ && it == include_map_.end ())
+ dependencies_.push_back (p);
+
cli_unit& n (root_->new_node<cli_unit> (p, 1, 1));
root_->new_edge<cli_includes> (*cur_, n, ik, f);
- include_map_[ap] = &n;
+ include_map_[move (ap)] = &n;
auto_restore<cli_unit> new_cur (cur_, &n);
auto_restore<path const> new_path (path_, &p);
diff --git a/cli/cli/parser.hxx b/cli/cli/parser.hxx
index 326768e..960e74b 100644
--- a/cli/cli/parser.hxx
+++ b/cli/cli/parser.hxx
@@ -23,11 +23,23 @@ class parser
public:
typedef std::vector<semantics::path> paths;
- parser (paths const& include_paths): include_paths_ (include_paths) {}
+ parser (paths const& include_paths, bool collect_dependencies)
+ : include_paths_ (include_paths),
+ collect_dependencies_ (collect_dependencies) {}
struct invalid_input {};
- std::unique_ptr<semantics::cli_unit>
+ struct parse_result
+ {
+ std::unique_ptr<semantics::cli_unit> unit;
+
+ // Normalized paths of the main CLI file and files it includes and sources
+ // recursively, with the duplicates suppressed.
+ //
+ paths dependencies;
+ };
+
+ parse_result
parse (std::istream& is, semantics::path const& path);
private:
@@ -72,6 +84,7 @@ private:
private:
paths const include_paths_;
+ bool collect_dependencies_;
bool valid_;
semantics::path const* path_;
@@ -84,8 +97,12 @@ private:
std::size_t doc_count_; // Scope doc counter, see scope_doc() for details.
+ // If the entry's value is NULL, then the key refers to a sourced file.
+ //
typedef std::map<semantics::path, semantics::cli_unit*> include_map;
include_map include_map_;
+
+ paths dependencies_;
};
#endif // CLI_PARSER_HXX
diff --git a/cli/cli/parser.test.cxx b/cli/cli/parser.test.cxx
index 6ef0d11..44109b3 100644
--- a/cli/cli/parser.test.cxx
+++ b/cli/cli/parser.test.cxx
@@ -9,6 +9,9 @@
#include <cli/semantics.hxx>
#include <cli/traversal.hxx>
+#undef NDEBUG
+#include <cassert>
+
using namespace std;
int
@@ -29,7 +32,7 @@ main (int argc, char* argv[])
ifs.open (path.string ().c_str ());
parser::paths include_paths;
- parser p (include_paths);
+ parser p (include_paths, true /* collect_dependencies */);
p.parse (ifs, path);
}
catch (semantics::invalid_path const& e)
diff --git a/cli/cli/options.cxx b/cli/cli/pregenerated/cli/options.cxx
index d64e801..9f0be5f 100644
--- a/cli/cli/options.cxx
+++ b/cli/cli/pregenerated/cli/options.cxx
@@ -15,6 +15,7 @@
#include <set>
#include <string>
#include <vector>
+#include <utility>
#include <ostream>
#include <sstream>
#include <cstring>
@@ -196,6 +197,7 @@ namespace cli
else
++i_;
+ ++start_position_;
return r;
}
else
@@ -206,11 +208,20 @@ namespace cli
skip ()
{
if (i_ < argc_)
+ {
++i_;
+ ++start_position_;
+ }
else
throw eos_reached ();
}
+ std::size_t argv_scanner::
+ position ()
+ {
+ return start_position_;
+ }
+
// argv_file_scanner
//
int argv_file_scanner::zero_argc_ = 0;
@@ -321,6 +332,7 @@ namespace cli
{
hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value);
args_.pop_front ();
+ ++start_position_;
return hold_[i_].c_str ();
}
}
@@ -334,7 +346,10 @@ namespace cli
if (args_.empty ())
return base::skip ();
else
+ {
args_.pop_front ();
+ ++start_position_;
+ }
}
const argv_file_scanner::option_info* argv_file_scanner::
@@ -347,6 +362,12 @@ namespace cli
return 0;
}
+ std::size_t argv_file_scanner::
+ position ()
+ {
+ return start_position_;
+ }
+
void argv_file_scanner::
load (const std::string& file)
{
@@ -459,12 +480,28 @@ namespace cli
if (oi->search_func != 0)
{
- std::string f (oi->search_func (s2.c_str (), oi->arg));
+ string f (oi->search_func (s2.c_str (), oi->arg));
if (!f.empty ())
load (f);
}
else
+ {
+ // If the path of the file being parsed is not simple and the
+ // path of the file that needs to be loaded is relative, then
+ // complete the latter using the former as a base.
+ //
+#ifndef _WIN32
+ string::size_type p (file.find_last_of ('/'));
+ bool c (p != string::npos && s2[0] != '/');
+#else
+ string::size_type p (file.find_last_of ("/\\"));
+ bool c (p != string::npos && s2[1] != ':');
+#endif
+ if (c)
+ s2.insert (0, file, 0, p + 1);
+
load (s2);
+ }
continue;
}
@@ -505,10 +542,31 @@ namespace cli
struct parser<bool>
{
static void
- parse (bool& x, scanner& s)
+ parse (bool& x, bool& xs, scanner& s)
{
- s.next ();
- x = true;
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ const char* v (s.next ());
+
+ if (std::strcmp (v, "1") == 0 ||
+ std::strcmp (v, "true") == 0 ||
+ std::strcmp (v, "TRUE") == 0 ||
+ std::strcmp (v, "True") == 0)
+ x = true;
+ else if (std::strcmp (v, "0") == 0 ||
+ std::strcmp (v, "false") == 0 ||
+ std::strcmp (v, "FALSE") == 0 ||
+ std::strcmp (v, "False") == 0)
+ x = false;
+ else
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
}
};
@@ -530,6 +588,17 @@ namespace cli
};
template <typename X>
+ struct parser<std::pair<X, std::size_t> >
+ {
+ static void
+ parse (std::pair<X, std::size_t>& x, bool& xs, scanner& s)
+ {
+ x.second = s.position ();
+ parser<X>::parse (x.first, xs, s);
+ }
+ };
+
+ template <typename X>
struct parser<std::vector<X> >
{
static void
@@ -543,11 +612,11 @@ namespace cli
}
};
- template <typename X>
- struct parser<std::set<X> >
+ template <typename X, typename C>
+ struct parser<std::set<X, C> >
{
static void
- parse (std::set<X>& c, bool& xs, scanner& s)
+ parse (std::set<X, C>& c, bool& xs, scanner& s)
{
X x;
bool dummy;
@@ -557,16 +626,17 @@ namespace cli
}
};
- template <typename K, typename V>
- struct parser<std::map<K, V> >
+ template <typename K, typename V, typename C>
+ struct parser<std::map<K, V, C> >
{
static void
- parse (std::map<K, V>& m, bool& xs, scanner& s)
+ parse (std::map<K, V, C>& m, bool& xs, scanner& s)
{
const char* o (s.next ());
if (s.more ())
{
+ std::size_t pos (s.position ());
std::string ov (s.next ());
std::string::size_type p = ov.find ('=');
@@ -586,14 +656,14 @@ namespace cli
if (!kstr.empty ())
{
av[1] = const_cast<char*> (kstr.c_str ());
- argv_scanner s (0, ac, av);
+ argv_scanner s (0, ac, av, false, pos);
parser<K>::parse (k, dummy, s);
}
if (!vstr.empty ())
{
av[1] = const_cast<char*> (vstr.c_str ());
- argv_scanner s (0, ac, av);
+ argv_scanner s (0, ac, av, false, pos);
parser<V>::parse (v, dummy, s);
}
@@ -606,6 +676,56 @@ namespace cli
}
};
+ template <typename K, typename V, typename C>
+ struct parser<std::multimap<K, V, C> >
+ {
+ static void
+ parse (std::multimap<K, V, C>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::size_t pos (s.position ());
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m.insert (typename std::multimap<K, V, C>::value_type (k, v));
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
template <typename X, typename T, T X::*M>
void
thunk (X& x, scanner& s)
@@ -613,6 +733,14 @@ namespace cli
parser<T>::parse (x.*M, s);
}
+ template <typename X, bool X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ s.next ();
+ x.*M = true;
+ }
+
template <typename X, typename T, T X::*M, bool X::*S>
void
thunk (X& x, scanner& s)
@@ -622,7 +750,6 @@ namespace cli
}
#include <map>
-#include <cstring>
// options
//
@@ -653,10 +780,13 @@ options ()
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
generate_txt_ (),
+ generate_dep_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -666,6 +796,7 @@ options ()
page_usage_specified_ (false),
option_length_ (0),
option_length_specified_ (false),
+ ascii_tree_ (),
ansi_color_ (),
exclude_base_ (),
include_base_last_ (),
@@ -745,6 +876,10 @@ options ()
html_suffix_specified_ (false),
txt_suffix_ (".txt"),
txt_suffix_specified_ (false),
+ dep_suffix_ (".d"),
+ dep_suffix_specified_ (false),
+ dep_file_ (),
+ dep_file_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -794,10 +929,13 @@ options (int& argc,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
generate_txt_ (),
+ generate_dep_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -807,6 +945,7 @@ options (int& argc,
page_usage_specified_ (false),
option_length_ (0),
option_length_specified_ (false),
+ ascii_tree_ (),
ansi_color_ (),
exclude_base_ (),
include_base_last_ (),
@@ -886,6 +1025,10 @@ options (int& argc,
html_suffix_specified_ (false),
txt_suffix_ (".txt"),
txt_suffix_specified_ (false),
+ dep_suffix_ (".d"),
+ dep_suffix_specified_ (false),
+ dep_file_ (),
+ dep_file_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -938,10 +1081,13 @@ options (int start,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
generate_txt_ (),
+ generate_dep_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -951,6 +1097,7 @@ options (int start,
page_usage_specified_ (false),
option_length_ (0),
option_length_specified_ (false),
+ ascii_tree_ (),
ansi_color_ (),
exclude_base_ (),
include_base_last_ (),
@@ -1030,6 +1177,10 @@ options (int start,
html_suffix_specified_ (false),
txt_suffix_ (".txt"),
txt_suffix_specified_ (false),
+ dep_suffix_ (".d"),
+ dep_suffix_specified_ (false),
+ dep_file_ (),
+ dep_file_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -1082,10 +1233,13 @@ options (int& argc,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
generate_txt_ (),
+ generate_dep_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -1095,6 +1249,7 @@ options (int& argc,
page_usage_specified_ (false),
option_length_ (0),
option_length_specified_ (false),
+ ascii_tree_ (),
ansi_color_ (),
exclude_base_ (),
include_base_last_ (),
@@ -1174,6 +1329,10 @@ options (int& argc,
html_suffix_specified_ (false),
txt_suffix_ (".txt"),
txt_suffix_specified_ (false),
+ dep_suffix_ (".d"),
+ dep_suffix_specified_ (false),
+ dep_file_ (),
+ dep_file_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -1228,10 +1387,13 @@ options (int start,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
generate_txt_ (),
+ generate_dep_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -1241,6 +1403,7 @@ options (int start,
page_usage_specified_ (false),
option_length_ (0),
option_length_specified_ (false),
+ ascii_tree_ (),
ansi_color_ (),
exclude_base_ (),
include_base_last_ (),
@@ -1320,6 +1483,10 @@ options (int start,
html_suffix_specified_ (false),
txt_suffix_ (".txt"),
txt_suffix_specified_ (false),
+ dep_suffix_ (".d"),
+ dep_suffix_specified_ (false),
+ dep_file_ (),
+ dep_file_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -1370,10 +1537,13 @@ options (::cli::scanner& s,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
generate_txt_ (),
+ generate_dep_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -1383,6 +1553,7 @@ options (::cli::scanner& s,
page_usage_specified_ (false),
option_length_ (0),
option_length_specified_ (false),
+ ascii_tree_ (),
ansi_color_ (),
exclude_base_ (),
include_base_last_ (),
@@ -1462,6 +1633,10 @@ options (::cli::scanner& s,
html_suffix_specified_ (false),
txt_suffix_ (".txt"),
txt_suffix_specified_ (false),
+ dep_suffix_ (".d"),
+ dep_suffix_specified_ (false),
+ dep_file_ (),
+ dep_file_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -1535,6 +1710,10 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
<< " std::ostream that should be used to print usage" << ::std::endl
<< " and exception information." << ::std::endl;
+ os << "--export-symbol <symbol> Insert <symbol> in places where DLL export/import" << ::std::endl
+ << " control statements" << ::std::endl
+ << " (__declspec(dllexport/dllimport)) are necessary." << ::std::endl;
+
os << "--generate-cxx Generate C++ code." << ::std::endl;
os << "--generate-man Generate documentation in the man page format." << ::std::endl;
@@ -1544,6 +1723,8 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--generate-txt Generate documentation in the plain text format," << ::std::endl
<< " similar to usage." << ::std::endl;
+ os << "--generate-dep Generate make dependency information." << ::std::endl;
+
os << "--stdout Write output to STDOUT instead of a file." << ::std::endl;
os << "--suppress-undocumented Suppress the generation of documentation entries" << ::std::endl
@@ -1564,6 +1745,8 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--option-length <len> Indent option descriptions <len> characters when" << ::std::endl
<< " printing usage." << ::std::endl;
+ os << "--ascii-tree Convert UTF-8 tree(1) output to ASCII." << ::std::endl;
+
os << "--ansi-color Use ANSI color escape sequences when printing" << ::std::endl
<< " usage." << ::std::endl;
@@ -1692,6 +1875,13 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--txt-suffix <suffix> Use <suffix> instead of the default .txt to" << ::std::endl
<< " construct the name of the generated text file." << ::std::endl;
+ os << "--dep-suffix <suffix> Use <suffix> instead of the default .d to" << ::std::endl
+ << " construct the name of the generated dependency" << ::std::endl
+ << " file." << ::std::endl;
+
+ os << "--dep-file <path> Use <path> as the generated dependency file path" << ::std::endl
+ << " instead of deriving it from the input file name." << ::std::endl;
+
os << "--option-prefix <prefix> Use <prefix> instead of the default '-' as an" << ::std::endl
<< " option prefix." << ::std::endl;
@@ -1742,9 +1932,9 @@ struct _cli_options_map_init
&::cli::thunk< options, std::uint64_t, &options::build2_metadata_,
&options::build2_metadata_specified_ >;
_cli_options_map_["--help"] =
- &::cli::thunk< options, bool, &options::help_ >;
+ &::cli::thunk< options, &options::help_ >;
_cli_options_map_["--version"] =
- &::cli::thunk< options, bool, &options::version_ >;
+ &::cli::thunk< options, &options::version_ >;
_cli_options_map_["--include-path"] =
&::cli::thunk< options, std::vector<std::string>, &options::include_path_,
&options::include_path_specified_ >;
@@ -1761,61 +1951,68 @@ struct _cli_options_map_init
&::cli::thunk< options, cxx_version, &options::std_,
&options::std_specified_ >;
_cli_options_map_["--generate-modifier"] =
- &::cli::thunk< options, bool, &options::generate_modifier_ >;
+ &::cli::thunk< options, &options::generate_modifier_ >;
_cli_options_map_["--generate-specifier"] =
- &::cli::thunk< options, bool, &options::generate_specifier_ >;
+ &::cli::thunk< options, &options::generate_specifier_ >;
_cli_options_map_["--generate-parse"] =
- &::cli::thunk< options, bool, &options::generate_parse_ >;
+ &::cli::thunk< options, &options::generate_parse_ >;
_cli_options_map_["--generate-merge"] =
- &::cli::thunk< options, bool, &options::generate_merge_ >;
+ &::cli::thunk< options, &options::generate_merge_ >;
_cli_options_map_["--generate-description"] =
- &::cli::thunk< options, bool, &options::generate_description_ >;
+ &::cli::thunk< options, &options::generate_description_ >;
_cli_options_map_["--generate-file-scanner"] =
- &::cli::thunk< options, bool, &options::generate_file_scanner_ >;
+ &::cli::thunk< options, &options::generate_file_scanner_ >;
_cli_options_map_["--generate-vector-scanner"] =
- &::cli::thunk< options, bool, &options::generate_vector_scanner_ >;
+ &::cli::thunk< options, &options::generate_vector_scanner_ >;
_cli_options_map_["--generate-group-scanner"] =
- &::cli::thunk< options, bool, &options::generate_group_scanner_ >;
+ &::cli::thunk< options, &options::generate_group_scanner_ >;
_cli_options_map_["--suppress-inline"] =
- &::cli::thunk< options, bool, &options::suppress_inline_ >;
+ &::cli::thunk< options, &options::suppress_inline_ >;
_cli_options_map_["--suppress-cli"] =
- &::cli::thunk< options, bool, &options::suppress_cli_ >;
+ &::cli::thunk< options, &options::suppress_cli_ >;
_cli_options_map_["--cli-namespace"] =
&::cli::thunk< options, std::string, &options::cli_namespace_,
&options::cli_namespace_specified_ >;
_cli_options_map_["--ostream-type"] =
&::cli::thunk< options, std::string, &options::ostream_type_,
&options::ostream_type_specified_ >;
+ _cli_options_map_["--export-symbol"] =
+ &::cli::thunk< options, std::string, &options::export_symbol_,
+ &options::export_symbol_specified_ >;
_cli_options_map_["--generate-cxx"] =
- &::cli::thunk< options, bool, &options::generate_cxx_ >;
+ &::cli::thunk< options, &options::generate_cxx_ >;
_cli_options_map_["--generate-man"] =
- &::cli::thunk< options, bool, &options::generate_man_ >;
+ &::cli::thunk< options, &options::generate_man_ >;
_cli_options_map_["--generate-html"] =
- &::cli::thunk< options, bool, &options::generate_html_ >;
+ &::cli::thunk< options, &options::generate_html_ >;
_cli_options_map_["--generate-txt"] =
- &::cli::thunk< options, bool, &options::generate_txt_ >;
+ &::cli::thunk< options, &options::generate_txt_ >;
+ _cli_options_map_["--generate-dep"] =
+ &::cli::thunk< options, &options::generate_dep_ >;
_cli_options_map_["--stdout"] =
- &::cli::thunk< options, bool, &options::stdout__ >;
+ &::cli::thunk< options, &options::stdout__ >;
_cli_options_map_["--suppress-undocumented"] =
- &::cli::thunk< options, bool, &options::suppress_undocumented_ >;
+ &::cli::thunk< options, &options::suppress_undocumented_ >;
_cli_options_map_["--suppress-usage"] =
- &::cli::thunk< options, bool, &options::suppress_usage_ >;
+ &::cli::thunk< options, &options::suppress_usage_ >;
_cli_options_map_["--long-usage"] =
- &::cli::thunk< options, bool, &options::long_usage_ >;
+ &::cli::thunk< options, &options::long_usage_ >;
_cli_options_map_["--short-usage"] =
- &::cli::thunk< options, bool, &options::short_usage_ >;
+ &::cli::thunk< options, &options::short_usage_ >;
_cli_options_map_["--page-usage"] =
&::cli::thunk< options, std::string, &options::page_usage_,
&options::page_usage_specified_ >;
_cli_options_map_["--option-length"] =
&::cli::thunk< options, std::size_t, &options::option_length_,
&options::option_length_specified_ >;
+ _cli_options_map_["--ascii-tree"] =
+ &::cli::thunk< options, &options::ascii_tree_ >;
_cli_options_map_["--ansi-color"] =
- &::cli::thunk< options, bool, &options::ansi_color_ >;
+ &::cli::thunk< options, &options::ansi_color_ >;
_cli_options_map_["--exclude-base"] =
- &::cli::thunk< options, bool, &options::exclude_base_ >;
+ &::cli::thunk< options, &options::exclude_base_ >;
_cli_options_map_["--include-base-last"] =
- &::cli::thunk< options, bool, &options::include_base_last_ >;
+ &::cli::thunk< options, &options::include_base_last_ >;
_cli_options_map_["--class-doc"] =
&::cli::thunk< options, std::map<std::string, std::string>, &options::class_doc_,
&options::class_doc_specified_ >;
@@ -1832,12 +2029,12 @@ struct _cli_options_map_init
&::cli::thunk< options, std::vector<std::string>, &options::link_regex_,
&options::link_regex_specified_ >;
_cli_options_map_["--link-regex-trace"] =
- &::cli::thunk< options, bool, &options::link_regex_trace_ >;
+ &::cli::thunk< options, &options::link_regex_trace_ >;
_cli_options_map_["--html-heading-map"] =
&::cli::thunk< options, std::map<char, std::string>, &options::html_heading_map_,
&options::html_heading_map_specified_ >;
_cli_options_map_["--omit-link-check"] =
- &::cli::thunk< options, bool, &options::omit_link_check_ >;
+ &::cli::thunk< options, &options::omit_link_check_ >;
_cli_options_map_["--hxx-prologue"] =
&::cli::thunk< options, std::vector<std::string>, &options::hxx_prologue_,
&options::hxx_prologue_specified_ >;
@@ -1934,6 +2131,12 @@ struct _cli_options_map_init
_cli_options_map_["--txt-suffix"] =
&::cli::thunk< options, std::string, &options::txt_suffix_,
&options::txt_suffix_specified_ >;
+ _cli_options_map_["--dep-suffix"] =
+ &::cli::thunk< options, std::string, &options::dep_suffix_,
+ &options::dep_suffix_specified_ >;
+ _cli_options_map_["--dep-file"] =
+ &::cli::thunk< options, std::string, &options::dep_file_,
+ &options::dep_file_specified_ >;
_cli_options_map_["--option-prefix"] =
&::cli::thunk< options, std::string, &options::option_prefix_,
&options::option_prefix_specified_ >;
@@ -1941,13 +2144,13 @@ struct _cli_options_map_init
&::cli::thunk< options, std::string, &options::option_separator_,
&options::option_separator_specified_ >;
_cli_options_map_["--keep-separator"] =
- &::cli::thunk< options, bool, &options::keep_separator_ >;
+ &::cli::thunk< options, &options::keep_separator_ >;
_cli_options_map_["--no-combined-flags"] =
- &::cli::thunk< options, bool, &options::no_combined_flags_ >;
+ &::cli::thunk< options, &options::no_combined_flags_ >;
_cli_options_map_["--no-combined-values"] =
- &::cli::thunk< options, bool, &options::no_combined_values_ >;
+ &::cli::thunk< options, &options::no_combined_values_ >;
_cli_options_map_["--include-with-brackets"] =
- &::cli::thunk< options, bool, &options::include_with_brackets_ >;
+ &::cli::thunk< options, &options::include_with_brackets_ >;
_cli_options_map_["--include-prefix"] =
&::cli::thunk< options, std::string, &options::include_prefix_,
&options::include_prefix_specified_ >;
diff --git a/cli/cli/options.hxx b/cli/cli/pregenerated/cli/options.hxx
index b54d81f..f44258f 100644
--- a/cli/cli/options.hxx
+++ b/cli/cli/pregenerated/cli/options.hxx
@@ -236,6 +236,14 @@ namespace cli
// for the two previous arguments up until a call to a third
// peek() or next().
//
+ // The position() function returns a monotonically-increasing
+ // number which, if stored, can later be used to determine the
+ // relative position of the argument returned by the following
+ // call to next(). Note that if multiple scanners are used to
+ // extract arguments from multiple sources, then the end
+ // position of the previous scanner should be used as the
+ // start position of the next.
+ //
class scanner
{
public:
@@ -253,13 +261,24 @@ namespace cli
virtual void
skip () = 0;
+
+ virtual std::size_t
+ position () = 0;
};
class argv_scanner: public scanner
{
public:
- argv_scanner (int& argc, char** argv, bool erase = false);
- argv_scanner (int start, int& argc, char** argv, bool erase = false);
+ argv_scanner (int& argc,
+ char** argv,
+ bool erase = false,
+ std::size_t start_position = 0);
+
+ argv_scanner (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ std::size_t start_position = 0);
int
end () const;
@@ -276,7 +295,11 @@ namespace cli
virtual void
skip ();
- private:
+ virtual std::size_t
+ position ();
+
+ protected:
+ std::size_t start_position_;
int i_;
int& argc_;
char** argv_;
@@ -289,16 +312,19 @@ namespace cli
argv_file_scanner (int& argc,
char** argv,
const std::string& option,
- bool erase = false);
+ bool erase = false,
+ std::size_t start_position = 0);
argv_file_scanner (int start,
int& argc,
char** argv,
const std::string& option,
- bool erase = false);
+ bool erase = false,
+ std::size_t start_position = 0);
argv_file_scanner (const std::string& file,
- const std::string& option);
+ const std::string& option,
+ std::size_t start_position = 0);
struct option_info
{
@@ -315,18 +341,21 @@ namespace cli
char** argv,
const option_info* options,
std::size_t options_count,
- bool erase = false);
+ bool erase = false,
+ std::size_t start_position = 0);
argv_file_scanner (int start,
int& argc,
char** argv,
const option_info* options,
std::size_t options_count,
- bool erase = false);
+ bool erase = false,
+ std::size_t start_position = 0);
argv_file_scanner (const std::string& file,
const option_info* options = 0,
- std::size_t options_count = 0);
+ std::size_t options_count = 0,
+ std::size_t start_position = 0);
virtual bool
more ();
@@ -340,6 +369,9 @@ namespace cli
virtual void
skip ();
+ virtual std::size_t
+ position ();
+
// Return the file path if the peeked at argument came from a file and
// the empty string otherwise. The reference is guaranteed to be valid
// till the end of the scanner lifetime.
@@ -641,6 +673,21 @@ class options
void
ostream_type_specified (bool);
+ const std::string&
+ export_symbol () const;
+
+ std::string&
+ export_symbol ();
+
+ void
+ export_symbol (const std::string&);
+
+ bool
+ export_symbol_specified () const;
+
+ void
+ export_symbol_specified (bool);
+
const bool&
generate_cxx () const;
@@ -678,6 +725,15 @@ class options
generate_txt (const bool&);
const bool&
+ generate_dep () const;
+
+ bool&
+ generate_dep ();
+
+ void
+ generate_dep (const bool&);
+
+ const bool&
stdout_ () const;
bool&
@@ -753,6 +809,15 @@ class options
option_length_specified (bool);
const bool&
+ ascii_tree () const;
+
+ bool&
+ ascii_tree ();
+
+ void
+ ascii_tree (const bool&);
+
+ const bool&
ansi_color () const;
bool&
@@ -1353,6 +1418,36 @@ class options
txt_suffix_specified (bool);
const std::string&
+ dep_suffix () const;
+
+ std::string&
+ dep_suffix ();
+
+ void
+ dep_suffix (const std::string&);
+
+ bool
+ dep_suffix_specified () const;
+
+ void
+ dep_suffix_specified (bool);
+
+ const std::string&
+ dep_file () const;
+
+ std::string&
+ dep_file ();
+
+ void
+ dep_file (const std::string&);
+
+ bool
+ dep_file_specified () const;
+
+ void
+ dep_file_specified (bool);
+
+ const std::string&
option_prefix () const;
std::string&
@@ -1521,10 +1616,13 @@ class options
bool cli_namespace_specified_;
std::string ostream_type_;
bool ostream_type_specified_;
+ std::string export_symbol_;
+ bool export_symbol_specified_;
bool generate_cxx_;
bool generate_man_;
bool generate_html_;
bool generate_txt_;
+ bool generate_dep_;
bool stdout__;
bool suppress_undocumented_;
bool suppress_usage_;
@@ -1534,6 +1632,7 @@ class options
bool page_usage_specified_;
std::size_t option_length_;
bool option_length_specified_;
+ bool ascii_tree_;
bool ansi_color_;
bool exclude_base_;
bool include_base_last_;
@@ -1613,6 +1712,10 @@ class options
bool html_suffix_specified_;
std::string txt_suffix_;
bool txt_suffix_specified_;
+ std::string dep_suffix_;
+ bool dep_suffix_specified_;
+ std::string dep_file_;
+ bool dep_file_specified_;
std::string option_prefix_;
bool option_prefix_specified_;
std::string option_separator_;
diff --git a/cli/cli/options.ixx b/cli/cli/pregenerated/cli/options.ixx
index 5916883..54fa54a 100644
--- a/cli/cli/options.ixx
+++ b/cli/cli/pregenerated/cli/options.ixx
@@ -141,14 +141,29 @@ namespace cli
// argv_scanner
//
inline argv_scanner::
- argv_scanner (int& argc, char** argv, bool erase)
- : i_ (1), argc_ (argc), argv_ (argv), erase_ (erase)
+ argv_scanner (int& argc,
+ char** argv,
+ bool erase,
+ std::size_t sp)
+ : start_position_ (sp + 1),
+ i_ (1),
+ argc_ (argc),
+ argv_ (argv),
+ erase_ (erase)
{
}
inline argv_scanner::
- argv_scanner (int start, int& argc, char** argv, bool erase)
- : i_ (start), argc_ (argc), argv_ (argv), erase_ (erase)
+ argv_scanner (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ std::size_t sp)
+ : start_position_ (sp + static_cast<std::size_t> (start)),
+ i_ (start),
+ argc_ (argc),
+ argv_ (argv),
+ erase_ (erase)
{
}
@@ -164,8 +179,9 @@ namespace cli
argv_file_scanner (int& argc,
char** argv,
const std::string& option,
- bool erase)
- : argv_scanner (argc, argv, erase),
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (argc, argv, erase, sp),
option_ (option),
options_ (&option_info_),
options_count_ (1),
@@ -181,8 +197,9 @@ namespace cli
int& argc,
char** argv,
const std::string& option,
- bool erase)
- : argv_scanner (start, argc, argv, erase),
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (start, argc, argv, erase, sp),
option_ (option),
options_ (&option_info_),
options_count_ (1),
@@ -195,8 +212,9 @@ namespace cli
inline argv_file_scanner::
argv_file_scanner (const std::string& file,
- const std::string& option)
- : argv_scanner (0, zero_argc_, 0),
+ const std::string& option,
+ std::size_t sp)
+ : argv_scanner (0, zero_argc_, 0, sp),
option_ (option),
options_ (&option_info_),
options_count_ (1),
@@ -214,8 +232,9 @@ namespace cli
char** argv,
const option_info* options,
std::size_t options_count,
- bool erase)
- : argv_scanner (argc, argv, erase),
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (argc, argv, erase, sp),
options_ (options),
options_count_ (options_count),
i_ (1),
@@ -229,8 +248,9 @@ namespace cli
char** argv,
const option_info* options,
std::size_t options_count,
- bool erase)
- : argv_scanner (start, argc, argv, erase),
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (start, argc, argv, erase, sp),
options_ (options),
options_count_ (options_count),
i_ (1),
@@ -241,8 +261,9 @@ namespace cli
inline argv_file_scanner::
argv_file_scanner (const std::string& file,
const option_info* options,
- std::size_t options_count)
- : argv_scanner (0, zero_argc_, 0),
+ std::size_t options_count,
+ std::size_t sp)
+ : argv_scanner (0, zero_argc_, 0, sp),
options_ (options),
options_count_ (options_count),
i_ (1),
@@ -268,7 +289,7 @@ build2_metadata ()
}
inline void options::
-build2_metadata(const std::uint64_t& x)
+build2_metadata (const std::uint64_t& x)
{
this->build2_metadata_ = x;
}
@@ -280,7 +301,7 @@ build2_metadata_specified () const
}
inline void options::
-build2_metadata_specified(bool x)
+build2_metadata_specified (bool x)
{
this->build2_metadata_specified_ = x;
}
@@ -298,7 +319,7 @@ help ()
}
inline void options::
-help(const bool& x)
+help (const bool& x)
{
this->help_ = x;
}
@@ -316,7 +337,7 @@ version ()
}
inline void options::
-version(const bool& x)
+version (const bool& x)
{
this->version_ = x;
}
@@ -334,7 +355,7 @@ include_path ()
}
inline void options::
-include_path(const std::vector<std::string>& x)
+include_path (const std::vector<std::string>& x)
{
this->include_path_ = x;
}
@@ -346,7 +367,7 @@ include_path_specified () const
}
inline void options::
-include_path_specified(bool x)
+include_path_specified (bool x)
{
this->include_path_specified_ = x;
}
@@ -364,7 +385,7 @@ output_dir ()
}
inline void options::
-output_dir(const std::string& x)
+output_dir (const std::string& x)
{
this->output_dir_ = x;
}
@@ -376,7 +397,7 @@ output_dir_specified () const
}
inline void options::
-output_dir_specified(bool x)
+output_dir_specified (bool x)
{
this->output_dir_specified_ = x;
}
@@ -394,7 +415,7 @@ std ()
}
inline void options::
-std(const cxx_version& x)
+std (const cxx_version& x)
{
this->std_ = x;
}
@@ -406,7 +427,7 @@ std_specified () const
}
inline void options::
-std_specified(bool x)
+std_specified (bool x)
{
this->std_specified_ = x;
}
@@ -424,7 +445,7 @@ generate_modifier ()
}
inline void options::
-generate_modifier(const bool& x)
+generate_modifier (const bool& x)
{
this->generate_modifier_ = x;
}
@@ -442,7 +463,7 @@ generate_specifier ()
}
inline void options::
-generate_specifier(const bool& x)
+generate_specifier (const bool& x)
{
this->generate_specifier_ = x;
}
@@ -460,7 +481,7 @@ generate_parse ()
}
inline void options::
-generate_parse(const bool& x)
+generate_parse (const bool& x)
{
this->generate_parse_ = x;
}
@@ -478,7 +499,7 @@ generate_merge ()
}
inline void options::
-generate_merge(const bool& x)
+generate_merge (const bool& x)
{
this->generate_merge_ = x;
}
@@ -496,7 +517,7 @@ generate_description ()
}
inline void options::
-generate_description(const bool& x)
+generate_description (const bool& x)
{
this->generate_description_ = x;
}
@@ -514,7 +535,7 @@ generate_file_scanner ()
}
inline void options::
-generate_file_scanner(const bool& x)
+generate_file_scanner (const bool& x)
{
this->generate_file_scanner_ = x;
}
@@ -532,7 +553,7 @@ generate_vector_scanner ()
}
inline void options::
-generate_vector_scanner(const bool& x)
+generate_vector_scanner (const bool& x)
{
this->generate_vector_scanner_ = x;
}
@@ -550,7 +571,7 @@ generate_group_scanner ()
}
inline void options::
-generate_group_scanner(const bool& x)
+generate_group_scanner (const bool& x)
{
this->generate_group_scanner_ = x;
}
@@ -568,7 +589,7 @@ suppress_inline ()
}
inline void options::
-suppress_inline(const bool& x)
+suppress_inline (const bool& x)
{
this->suppress_inline_ = x;
}
@@ -586,7 +607,7 @@ suppress_cli ()
}
inline void options::
-suppress_cli(const bool& x)
+suppress_cli (const bool& x)
{
this->suppress_cli_ = x;
}
@@ -604,7 +625,7 @@ cli_namespace ()
}
inline void options::
-cli_namespace(const std::string& x)
+cli_namespace (const std::string& x)
{
this->cli_namespace_ = x;
}
@@ -616,7 +637,7 @@ cli_namespace_specified () const
}
inline void options::
-cli_namespace_specified(bool x)
+cli_namespace_specified (bool x)
{
this->cli_namespace_specified_ = x;
}
@@ -634,7 +655,7 @@ ostream_type ()
}
inline void options::
-ostream_type(const std::string& x)
+ostream_type (const std::string& x)
{
this->ostream_type_ = x;
}
@@ -646,11 +667,41 @@ ostream_type_specified () const
}
inline void options::
-ostream_type_specified(bool x)
+ostream_type_specified (bool x)
{
this->ostream_type_specified_ = x;
}
+inline const std::string& options::
+export_symbol () const
+{
+ return this->export_symbol_;
+}
+
+inline std::string& options::
+export_symbol ()
+{
+ return this->export_symbol_;
+}
+
+inline void options::
+export_symbol (const std::string& x)
+{
+ this->export_symbol_ = x;
+}
+
+inline bool options::
+export_symbol_specified () const
+{
+ return this->export_symbol_specified_;
+}
+
+inline void options::
+export_symbol_specified (bool x)
+{
+ this->export_symbol_specified_ = x;
+}
+
inline const bool& options::
generate_cxx () const
{
@@ -664,7 +715,7 @@ generate_cxx ()
}
inline void options::
-generate_cxx(const bool& x)
+generate_cxx (const bool& x)
{
this->generate_cxx_ = x;
}
@@ -682,7 +733,7 @@ generate_man ()
}
inline void options::
-generate_man(const bool& x)
+generate_man (const bool& x)
{
this->generate_man_ = x;
}
@@ -700,7 +751,7 @@ generate_html ()
}
inline void options::
-generate_html(const bool& x)
+generate_html (const bool& x)
{
this->generate_html_ = x;
}
@@ -718,12 +769,30 @@ generate_txt ()
}
inline void options::
-generate_txt(const bool& x)
+generate_txt (const bool& x)
{
this->generate_txt_ = x;
}
inline const bool& options::
+generate_dep () const
+{
+ return this->generate_dep_;
+}
+
+inline bool& options::
+generate_dep ()
+{
+ return this->generate_dep_;
+}
+
+inline void options::
+generate_dep (const bool& x)
+{
+ this->generate_dep_ = x;
+}
+
+inline const bool& options::
stdout_ () const
{
return this->stdout__;
@@ -736,7 +805,7 @@ stdout_ ()
}
inline void options::
-stdout_(const bool& x)
+stdout_ (const bool& x)
{
this->stdout__ = x;
}
@@ -754,7 +823,7 @@ suppress_undocumented ()
}
inline void options::
-suppress_undocumented(const bool& x)
+suppress_undocumented (const bool& x)
{
this->suppress_undocumented_ = x;
}
@@ -772,7 +841,7 @@ suppress_usage ()
}
inline void options::
-suppress_usage(const bool& x)
+suppress_usage (const bool& x)
{
this->suppress_usage_ = x;
}
@@ -790,7 +859,7 @@ long_usage ()
}
inline void options::
-long_usage(const bool& x)
+long_usage (const bool& x)
{
this->long_usage_ = x;
}
@@ -808,7 +877,7 @@ short_usage ()
}
inline void options::
-short_usage(const bool& x)
+short_usage (const bool& x)
{
this->short_usage_ = x;
}
@@ -826,7 +895,7 @@ page_usage ()
}
inline void options::
-page_usage(const std::string& x)
+page_usage (const std::string& x)
{
this->page_usage_ = x;
}
@@ -838,7 +907,7 @@ page_usage_specified () const
}
inline void options::
-page_usage_specified(bool x)
+page_usage_specified (bool x)
{
this->page_usage_specified_ = x;
}
@@ -856,7 +925,7 @@ option_length ()
}
inline void options::
-option_length(const std::size_t& x)
+option_length (const std::size_t& x)
{
this->option_length_ = x;
}
@@ -868,12 +937,30 @@ option_length_specified () const
}
inline void options::
-option_length_specified(bool x)
+option_length_specified (bool x)
{
this->option_length_specified_ = x;
}
inline const bool& options::
+ascii_tree () const
+{
+ return this->ascii_tree_;
+}
+
+inline bool& options::
+ascii_tree ()
+{
+ return this->ascii_tree_;
+}
+
+inline void options::
+ascii_tree (const bool& x)
+{
+ this->ascii_tree_ = x;
+}
+
+inline const bool& options::
ansi_color () const
{
return this->ansi_color_;
@@ -886,7 +973,7 @@ ansi_color ()
}
inline void options::
-ansi_color(const bool& x)
+ansi_color (const bool& x)
{
this->ansi_color_ = x;
}
@@ -904,7 +991,7 @@ exclude_base ()
}
inline void options::
-exclude_base(const bool& x)
+exclude_base (const bool& x)
{
this->exclude_base_ = x;
}
@@ -922,7 +1009,7 @@ include_base_last ()
}
inline void options::
-include_base_last(const bool& x)
+include_base_last (const bool& x)
{
this->include_base_last_ = x;
}
@@ -940,7 +1027,7 @@ class_doc ()
}
inline void options::
-class_doc(const std::map<std::string, std::string>& x)
+class_doc (const std::map<std::string, std::string>& x)
{
this->class_doc_ = x;
}
@@ -952,7 +1039,7 @@ class_doc_specified () const
}
inline void options::
-class_doc_specified(bool x)
+class_doc_specified (bool x)
{
this->class_doc_specified_ = x;
}
@@ -970,7 +1057,7 @@ class_ ()
}
inline void options::
-class_(const std::vector<std::string>& x)
+class_ (const std::vector<std::string>& x)
{
this->class__ = x;
}
@@ -982,7 +1069,7 @@ class__specified () const
}
inline void options::
-class__specified(bool x)
+class__specified (bool x)
{
this->class__specified_ = x;
}
@@ -1000,7 +1087,7 @@ docvar ()
}
inline void options::
-docvar(const std::map<std::string, std::string>& x)
+docvar (const std::map<std::string, std::string>& x)
{
this->docvar_ = x;
}
@@ -1012,7 +1099,7 @@ docvar_specified () const
}
inline void options::
-docvar_specified(bool x)
+docvar_specified (bool x)
{
this->docvar_specified_ = x;
}
@@ -1030,7 +1117,7 @@ link_regex ()
}
inline void options::
-link_regex(const std::vector<std::string>& x)
+link_regex (const std::vector<std::string>& x)
{
this->link_regex_ = x;
}
@@ -1042,7 +1129,7 @@ link_regex_specified () const
}
inline void options::
-link_regex_specified(bool x)
+link_regex_specified (bool x)
{
this->link_regex_specified_ = x;
}
@@ -1060,7 +1147,7 @@ link_regex_trace ()
}
inline void options::
-link_regex_trace(const bool& x)
+link_regex_trace (const bool& x)
{
this->link_regex_trace_ = x;
}
@@ -1078,7 +1165,7 @@ html_heading_map ()
}
inline void options::
-html_heading_map(const std::map<char, std::string>& x)
+html_heading_map (const std::map<char, std::string>& x)
{
this->html_heading_map_ = x;
}
@@ -1090,7 +1177,7 @@ html_heading_map_specified () const
}
inline void options::
-html_heading_map_specified(bool x)
+html_heading_map_specified (bool x)
{
this->html_heading_map_specified_ = x;
}
@@ -1108,7 +1195,7 @@ omit_link_check ()
}
inline void options::
-omit_link_check(const bool& x)
+omit_link_check (const bool& x)
{
this->omit_link_check_ = x;
}
@@ -1126,7 +1213,7 @@ hxx_prologue ()
}
inline void options::
-hxx_prologue(const std::vector<std::string>& x)
+hxx_prologue (const std::vector<std::string>& x)
{
this->hxx_prologue_ = x;
}
@@ -1138,7 +1225,7 @@ hxx_prologue_specified () const
}
inline void options::
-hxx_prologue_specified(bool x)
+hxx_prologue_specified (bool x)
{
this->hxx_prologue_specified_ = x;
}
@@ -1156,7 +1243,7 @@ ixx_prologue ()
}
inline void options::
-ixx_prologue(const std::vector<std::string>& x)
+ixx_prologue (const std::vector<std::string>& x)
{
this->ixx_prologue_ = x;
}
@@ -1168,7 +1255,7 @@ ixx_prologue_specified () const
}
inline void options::
-ixx_prologue_specified(bool x)
+ixx_prologue_specified (bool x)
{
this->ixx_prologue_specified_ = x;
}
@@ -1186,7 +1273,7 @@ cxx_prologue ()
}
inline void options::
-cxx_prologue(const std::vector<std::string>& x)
+cxx_prologue (const std::vector<std::string>& x)
{
this->cxx_prologue_ = x;
}
@@ -1198,7 +1285,7 @@ cxx_prologue_specified () const
}
inline void options::
-cxx_prologue_specified(bool x)
+cxx_prologue_specified (bool x)
{
this->cxx_prologue_specified_ = x;
}
@@ -1216,7 +1303,7 @@ man_prologue ()
}
inline void options::
-man_prologue(const std::vector<std::string>& x)
+man_prologue (const std::vector<std::string>& x)
{
this->man_prologue_ = x;
}
@@ -1228,7 +1315,7 @@ man_prologue_specified () const
}
inline void options::
-man_prologue_specified(bool x)
+man_prologue_specified (bool x)
{
this->man_prologue_specified_ = x;
}
@@ -1246,7 +1333,7 @@ html_prologue ()
}
inline void options::
-html_prologue(const std::vector<std::string>& x)
+html_prologue (const std::vector<std::string>& x)
{
this->html_prologue_ = x;
}
@@ -1258,7 +1345,7 @@ html_prologue_specified () const
}
inline void options::
-html_prologue_specified(bool x)
+html_prologue_specified (bool x)
{
this->html_prologue_specified_ = x;
}
@@ -1276,7 +1363,7 @@ txt_prologue ()
}
inline void options::
-txt_prologue(const std::vector<std::string>& x)
+txt_prologue (const std::vector<std::string>& x)
{
this->txt_prologue_ = x;
}
@@ -1288,7 +1375,7 @@ txt_prologue_specified () const
}
inline void options::
-txt_prologue_specified(bool x)
+txt_prologue_specified (bool x)
{
this->txt_prologue_specified_ = x;
}
@@ -1306,7 +1393,7 @@ hxx_epilogue ()
}
inline void options::
-hxx_epilogue(const std::vector<std::string>& x)
+hxx_epilogue (const std::vector<std::string>& x)
{
this->hxx_epilogue_ = x;
}
@@ -1318,7 +1405,7 @@ hxx_epilogue_specified () const
}
inline void options::
-hxx_epilogue_specified(bool x)
+hxx_epilogue_specified (bool x)
{
this->hxx_epilogue_specified_ = x;
}
@@ -1336,7 +1423,7 @@ ixx_epilogue ()
}
inline void options::
-ixx_epilogue(const std::vector<std::string>& x)
+ixx_epilogue (const std::vector<std::string>& x)
{
this->ixx_epilogue_ = x;
}
@@ -1348,7 +1435,7 @@ ixx_epilogue_specified () const
}
inline void options::
-ixx_epilogue_specified(bool x)
+ixx_epilogue_specified (bool x)
{
this->ixx_epilogue_specified_ = x;
}
@@ -1366,7 +1453,7 @@ cxx_epilogue ()
}
inline void options::
-cxx_epilogue(const std::vector<std::string>& x)
+cxx_epilogue (const std::vector<std::string>& x)
{
this->cxx_epilogue_ = x;
}
@@ -1378,7 +1465,7 @@ cxx_epilogue_specified () const
}
inline void options::
-cxx_epilogue_specified(bool x)
+cxx_epilogue_specified (bool x)
{
this->cxx_epilogue_specified_ = x;
}
@@ -1396,7 +1483,7 @@ man_epilogue ()
}
inline void options::
-man_epilogue(const std::vector<std::string>& x)
+man_epilogue (const std::vector<std::string>& x)
{
this->man_epilogue_ = x;
}
@@ -1408,7 +1495,7 @@ man_epilogue_specified () const
}
inline void options::
-man_epilogue_specified(bool x)
+man_epilogue_specified (bool x)
{
this->man_epilogue_specified_ = x;
}
@@ -1426,7 +1513,7 @@ html_epilogue ()
}
inline void options::
-html_epilogue(const std::vector<std::string>& x)
+html_epilogue (const std::vector<std::string>& x)
{
this->html_epilogue_ = x;
}
@@ -1438,7 +1525,7 @@ html_epilogue_specified () const
}
inline void options::
-html_epilogue_specified(bool x)
+html_epilogue_specified (bool x)
{
this->html_epilogue_specified_ = x;
}
@@ -1456,7 +1543,7 @@ txt_epilogue ()
}
inline void options::
-txt_epilogue(const std::vector<std::string>& x)
+txt_epilogue (const std::vector<std::string>& x)
{
this->txt_epilogue_ = x;
}
@@ -1468,7 +1555,7 @@ txt_epilogue_specified () const
}
inline void options::
-txt_epilogue_specified(bool x)
+txt_epilogue_specified (bool x)
{
this->txt_epilogue_specified_ = x;
}
@@ -1486,7 +1573,7 @@ hxx_prologue_file ()
}
inline void options::
-hxx_prologue_file(const std::string& x)
+hxx_prologue_file (const std::string& x)
{
this->hxx_prologue_file_ = x;
}
@@ -1498,7 +1585,7 @@ hxx_prologue_file_specified () const
}
inline void options::
-hxx_prologue_file_specified(bool x)
+hxx_prologue_file_specified (bool x)
{
this->hxx_prologue_file_specified_ = x;
}
@@ -1516,7 +1603,7 @@ ixx_prologue_file ()
}
inline void options::
-ixx_prologue_file(const std::string& x)
+ixx_prologue_file (const std::string& x)
{
this->ixx_prologue_file_ = x;
}
@@ -1528,7 +1615,7 @@ ixx_prologue_file_specified () const
}
inline void options::
-ixx_prologue_file_specified(bool x)
+ixx_prologue_file_specified (bool x)
{
this->ixx_prologue_file_specified_ = x;
}
@@ -1546,7 +1633,7 @@ cxx_prologue_file ()
}
inline void options::
-cxx_prologue_file(const std::string& x)
+cxx_prologue_file (const std::string& x)
{
this->cxx_prologue_file_ = x;
}
@@ -1558,7 +1645,7 @@ cxx_prologue_file_specified () const
}
inline void options::
-cxx_prologue_file_specified(bool x)
+cxx_prologue_file_specified (bool x)
{
this->cxx_prologue_file_specified_ = x;
}
@@ -1576,7 +1663,7 @@ man_prologue_file ()
}
inline void options::
-man_prologue_file(const std::string& x)
+man_prologue_file (const std::string& x)
{
this->man_prologue_file_ = x;
}
@@ -1588,7 +1675,7 @@ man_prologue_file_specified () const
}
inline void options::
-man_prologue_file_specified(bool x)
+man_prologue_file_specified (bool x)
{
this->man_prologue_file_specified_ = x;
}
@@ -1606,7 +1693,7 @@ html_prologue_file ()
}
inline void options::
-html_prologue_file(const std::string& x)
+html_prologue_file (const std::string& x)
{
this->html_prologue_file_ = x;
}
@@ -1618,7 +1705,7 @@ html_prologue_file_specified () const
}
inline void options::
-html_prologue_file_specified(bool x)
+html_prologue_file_specified (bool x)
{
this->html_prologue_file_specified_ = x;
}
@@ -1636,7 +1723,7 @@ txt_prologue_file ()
}
inline void options::
-txt_prologue_file(const std::string& x)
+txt_prologue_file (const std::string& x)
{
this->txt_prologue_file_ = x;
}
@@ -1648,7 +1735,7 @@ txt_prologue_file_specified () const
}
inline void options::
-txt_prologue_file_specified(bool x)
+txt_prologue_file_specified (bool x)
{
this->txt_prologue_file_specified_ = x;
}
@@ -1666,7 +1753,7 @@ hxx_epilogue_file ()
}
inline void options::
-hxx_epilogue_file(const std::string& x)
+hxx_epilogue_file (const std::string& x)
{
this->hxx_epilogue_file_ = x;
}
@@ -1678,7 +1765,7 @@ hxx_epilogue_file_specified () const
}
inline void options::
-hxx_epilogue_file_specified(bool x)
+hxx_epilogue_file_specified (bool x)
{
this->hxx_epilogue_file_specified_ = x;
}
@@ -1696,7 +1783,7 @@ ixx_epilogue_file ()
}
inline void options::
-ixx_epilogue_file(const std::string& x)
+ixx_epilogue_file (const std::string& x)
{
this->ixx_epilogue_file_ = x;
}
@@ -1708,7 +1795,7 @@ ixx_epilogue_file_specified () const
}
inline void options::
-ixx_epilogue_file_specified(bool x)
+ixx_epilogue_file_specified (bool x)
{
this->ixx_epilogue_file_specified_ = x;
}
@@ -1726,7 +1813,7 @@ cxx_epilogue_file ()
}
inline void options::
-cxx_epilogue_file(const std::string& x)
+cxx_epilogue_file (const std::string& x)
{
this->cxx_epilogue_file_ = x;
}
@@ -1738,7 +1825,7 @@ cxx_epilogue_file_specified () const
}
inline void options::
-cxx_epilogue_file_specified(bool x)
+cxx_epilogue_file_specified (bool x)
{
this->cxx_epilogue_file_specified_ = x;
}
@@ -1756,7 +1843,7 @@ man_epilogue_file ()
}
inline void options::
-man_epilogue_file(const std::string& x)
+man_epilogue_file (const std::string& x)
{
this->man_epilogue_file_ = x;
}
@@ -1768,7 +1855,7 @@ man_epilogue_file_specified () const
}
inline void options::
-man_epilogue_file_specified(bool x)
+man_epilogue_file_specified (bool x)
{
this->man_epilogue_file_specified_ = x;
}
@@ -1786,7 +1873,7 @@ html_epilogue_file ()
}
inline void options::
-html_epilogue_file(const std::string& x)
+html_epilogue_file (const std::string& x)
{
this->html_epilogue_file_ = x;
}
@@ -1798,7 +1885,7 @@ html_epilogue_file_specified () const
}
inline void options::
-html_epilogue_file_specified(bool x)
+html_epilogue_file_specified (bool x)
{
this->html_epilogue_file_specified_ = x;
}
@@ -1816,7 +1903,7 @@ txt_epilogue_file ()
}
inline void options::
-txt_epilogue_file(const std::string& x)
+txt_epilogue_file (const std::string& x)
{
this->txt_epilogue_file_ = x;
}
@@ -1828,7 +1915,7 @@ txt_epilogue_file_specified () const
}
inline void options::
-txt_epilogue_file_specified(bool x)
+txt_epilogue_file_specified (bool x)
{
this->txt_epilogue_file_specified_ = x;
}
@@ -1846,7 +1933,7 @@ output_prefix ()
}
inline void options::
-output_prefix(const std::string& x)
+output_prefix (const std::string& x)
{
this->output_prefix_ = x;
}
@@ -1858,7 +1945,7 @@ output_prefix_specified () const
}
inline void options::
-output_prefix_specified(bool x)
+output_prefix_specified (bool x)
{
this->output_prefix_specified_ = x;
}
@@ -1876,7 +1963,7 @@ output_suffix ()
}
inline void options::
-output_suffix(const std::string& x)
+output_suffix (const std::string& x)
{
this->output_suffix_ = x;
}
@@ -1888,7 +1975,7 @@ output_suffix_specified () const
}
inline void options::
-output_suffix_specified(bool x)
+output_suffix_specified (bool x)
{
this->output_suffix_specified_ = x;
}
@@ -1906,7 +1993,7 @@ hxx_suffix ()
}
inline void options::
-hxx_suffix(const std::string& x)
+hxx_suffix (const std::string& x)
{
this->hxx_suffix_ = x;
}
@@ -1918,7 +2005,7 @@ hxx_suffix_specified () const
}
inline void options::
-hxx_suffix_specified(bool x)
+hxx_suffix_specified (bool x)
{
this->hxx_suffix_specified_ = x;
}
@@ -1936,7 +2023,7 @@ ixx_suffix ()
}
inline void options::
-ixx_suffix(const std::string& x)
+ixx_suffix (const std::string& x)
{
this->ixx_suffix_ = x;
}
@@ -1948,7 +2035,7 @@ ixx_suffix_specified () const
}
inline void options::
-ixx_suffix_specified(bool x)
+ixx_suffix_specified (bool x)
{
this->ixx_suffix_specified_ = x;
}
@@ -1966,7 +2053,7 @@ cxx_suffix ()
}
inline void options::
-cxx_suffix(const std::string& x)
+cxx_suffix (const std::string& x)
{
this->cxx_suffix_ = x;
}
@@ -1978,7 +2065,7 @@ cxx_suffix_specified () const
}
inline void options::
-cxx_suffix_specified(bool x)
+cxx_suffix_specified (bool x)
{
this->cxx_suffix_specified_ = x;
}
@@ -1996,7 +2083,7 @@ man_suffix ()
}
inline void options::
-man_suffix(const std::string& x)
+man_suffix (const std::string& x)
{
this->man_suffix_ = x;
}
@@ -2008,7 +2095,7 @@ man_suffix_specified () const
}
inline void options::
-man_suffix_specified(bool x)
+man_suffix_specified (bool x)
{
this->man_suffix_specified_ = x;
}
@@ -2026,7 +2113,7 @@ html_suffix ()
}
inline void options::
-html_suffix(const std::string& x)
+html_suffix (const std::string& x)
{
this->html_suffix_ = x;
}
@@ -2038,7 +2125,7 @@ html_suffix_specified () const
}
inline void options::
-html_suffix_specified(bool x)
+html_suffix_specified (bool x)
{
this->html_suffix_specified_ = x;
}
@@ -2056,7 +2143,7 @@ txt_suffix ()
}
inline void options::
-txt_suffix(const std::string& x)
+txt_suffix (const std::string& x)
{
this->txt_suffix_ = x;
}
@@ -2068,12 +2155,72 @@ txt_suffix_specified () const
}
inline void options::
-txt_suffix_specified(bool x)
+txt_suffix_specified (bool x)
{
this->txt_suffix_specified_ = x;
}
inline const std::string& options::
+dep_suffix () const
+{
+ return this->dep_suffix_;
+}
+
+inline std::string& options::
+dep_suffix ()
+{
+ return this->dep_suffix_;
+}
+
+inline void options::
+dep_suffix (const std::string& x)
+{
+ this->dep_suffix_ = x;
+}
+
+inline bool options::
+dep_suffix_specified () const
+{
+ return this->dep_suffix_specified_;
+}
+
+inline void options::
+dep_suffix_specified (bool x)
+{
+ this->dep_suffix_specified_ = x;
+}
+
+inline const std::string& options::
+dep_file () const
+{
+ return this->dep_file_;
+}
+
+inline std::string& options::
+dep_file ()
+{
+ return this->dep_file_;
+}
+
+inline void options::
+dep_file (const std::string& x)
+{
+ this->dep_file_ = x;
+}
+
+inline bool options::
+dep_file_specified () const
+{
+ return this->dep_file_specified_;
+}
+
+inline void options::
+dep_file_specified (bool x)
+{
+ this->dep_file_specified_ = x;
+}
+
+inline const std::string& options::
option_prefix () const
{
return this->option_prefix_;
@@ -2086,7 +2233,7 @@ option_prefix ()
}
inline void options::
-option_prefix(const std::string& x)
+option_prefix (const std::string& x)
{
this->option_prefix_ = x;
}
@@ -2098,7 +2245,7 @@ option_prefix_specified () const
}
inline void options::
-option_prefix_specified(bool x)
+option_prefix_specified (bool x)
{
this->option_prefix_specified_ = x;
}
@@ -2116,7 +2263,7 @@ option_separator ()
}
inline void options::
-option_separator(const std::string& x)
+option_separator (const std::string& x)
{
this->option_separator_ = x;
}
@@ -2128,7 +2275,7 @@ option_separator_specified () const
}
inline void options::
-option_separator_specified(bool x)
+option_separator_specified (bool x)
{
this->option_separator_specified_ = x;
}
@@ -2146,7 +2293,7 @@ keep_separator ()
}
inline void options::
-keep_separator(const bool& x)
+keep_separator (const bool& x)
{
this->keep_separator_ = x;
}
@@ -2164,7 +2311,7 @@ no_combined_flags ()
}
inline void options::
-no_combined_flags(const bool& x)
+no_combined_flags (const bool& x)
{
this->no_combined_flags_ = x;
}
@@ -2182,7 +2329,7 @@ no_combined_values ()
}
inline void options::
-no_combined_values(const bool& x)
+no_combined_values (const bool& x)
{
this->no_combined_values_ = x;
}
@@ -2200,7 +2347,7 @@ include_with_brackets ()
}
inline void options::
-include_with_brackets(const bool& x)
+include_with_brackets (const bool& x)
{
this->include_with_brackets_ = x;
}
@@ -2218,7 +2365,7 @@ include_prefix ()
}
inline void options::
-include_prefix(const std::string& x)
+include_prefix (const std::string& x)
{
this->include_prefix_ = x;
}
@@ -2230,7 +2377,7 @@ include_prefix_specified () const
}
inline void options::
-include_prefix_specified(bool x)
+include_prefix_specified (bool x)
{
this->include_prefix_specified_ = x;
}
@@ -2248,7 +2395,7 @@ guard_prefix ()
}
inline void options::
-guard_prefix(const std::string& x)
+guard_prefix (const std::string& x)
{
this->guard_prefix_ = x;
}
@@ -2260,7 +2407,7 @@ guard_prefix_specified () const
}
inline void options::
-guard_prefix_specified(bool x)
+guard_prefix_specified (bool x)
{
this->guard_prefix_specified_ = x;
}
@@ -2278,7 +2425,7 @@ reserved_name ()
}
inline void options::
-reserved_name(const std::map<std::string, std::string>& x)
+reserved_name (const std::map<std::string, std::string>& x)
{
this->reserved_name_ = x;
}
@@ -2290,7 +2437,7 @@ reserved_name_specified () const
}
inline void options::
-reserved_name_specified(bool x)
+reserved_name_specified (bool x)
{
this->reserved_name_specified_ = x;
}
@@ -2308,7 +2455,7 @@ options_file ()
}
inline void options::
-options_file(const std::string& x)
+options_file (const std::string& x)
{
this->options_file_ = x;
}
@@ -2320,7 +2467,7 @@ options_file_specified () const
}
inline void options::
-options_file_specified(bool x)
+options_file_specified (bool x)
{
this->options_file_specified_ = x;
}
diff --git a/cli/cli/runtime-header.cxx b/cli/cli/runtime-header.cxx
index adf70dd..1003e91 100644
--- a/cli/cli/runtime-header.cxx
+++ b/cli/cli/runtime-header.cxx
@@ -43,10 +43,13 @@ generate_runtime_header (context& ctx)
ctx.ns_open (ctx.cli);
+ string const& exp (ctx.exp);
+ string const& exp_inl (ctx.exp_inl);
+
// usage_para
//
if (!ctx.options.suppress_usage ())
- os << "class usage_para"
+ os << "class " << exp_inl << "usage_para"
<< "{"
<< "public:" << endl
<< "enum value"
@@ -64,7 +67,7 @@ generate_runtime_header (context& ctx)
// unknown_mode
//
- os << "class unknown_mode"
+ os << "class " << exp_inl << "unknown_mode"
<< "{"
<< "public:" << endl
<< "enum value"
@@ -85,26 +88,30 @@ generate_runtime_header (context& ctx)
string const& os_type (ctx.options.ostream_type ());
+ const char* nothrow (ctx.options.std () < cxx_version::cxx11
+ ? "throw ()"
+ : "noexcept");
+
os << "// Exceptions." << endl
<< "//" << endl
<< endl;
- os << "class exception: public std::exception"
+ os << "class " << exp << "exception: public std::exception"
<< "{"
<< "public:" << endl
<< "virtual void" << endl
<< "print (" << os_type << "&) const = 0;"
<< "};";
- os << os_type << "&" << endl
+ os << exp_inl << os_type << "&" << endl
<< "operator<< (" << os_type << "&, const exception&);"
<< endl;
- os << "class unknown_option: public exception"
+ os << "class " << exp << "unknown_option: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
- << "~unknown_option () throw ();"
+ << "~unknown_option () " << nothrow << ';'
<< endl
<< "unknown_option (const std::string& option);"
<< endl
@@ -115,17 +122,17 @@ generate_runtime_header (context& ctx)
<< "print (" << os_type << "&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< endl
<< "private:" << endl
<< "std::string option_;"
<< "};";
- os << "class unknown_argument: public exception"
+ os << "class " << exp << "unknown_argument: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
- << "~unknown_argument () throw ();"
+ << "~unknown_argument () " << nothrow << ';'
<< endl
<< "unknown_argument (const std::string& argument);"
<< endl
@@ -136,17 +143,17 @@ generate_runtime_header (context& ctx)
<< "print (" << os_type << "&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< endl
<< "private:" << endl
<< "std::string argument_;"
<< "};";
- os << "class missing_value: public exception"
+ os << "class " << exp << "missing_value: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
- << "~missing_value () throw ();"
+ << "~missing_value () " << nothrow << ';'
<< endl
<< "missing_value (const std::string& option);"
<< endl
@@ -157,17 +164,17 @@ generate_runtime_header (context& ctx)
<< "print (" << os_type << "&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< endl
<< "private:" << endl
<< "std::string option_;"
<< "};";
- os << "class invalid_value: public exception"
+ os << "class " << exp << "invalid_value: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
- << "~invalid_value () throw ();"
+ << "~invalid_value () " << nothrow << ';'
<< endl
<< "invalid_value (const std::string& option," << endl
<< "const std::string& value," << endl
@@ -186,7 +193,7 @@ generate_runtime_header (context& ctx)
<< "print (" << os_type << "&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< endl
<< "private:" << endl
<< "std::string option_;"
@@ -194,23 +201,23 @@ generate_runtime_header (context& ctx)
<< "std::string message_;"
<< "};";
- os << "class eos_reached: public exception"
+ os << "class " << exp << "eos_reached: public exception"
<< "{"
<< "public:" << endl
<< "virtual void" << endl
<< "print (" << os_type << "&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< "};";
if (ctx.options.generate_file_scanner ())
{
- os << "class file_io_failure: public exception"
+ os << "class " << exp << "file_io_failure: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
- << "~file_io_failure () throw ();"
+ << "~file_io_failure () " << nothrow << ';'
<< endl
<< "file_io_failure (const std::string& file);"
<< endl
@@ -221,17 +228,17 @@ generate_runtime_header (context& ctx)
<< "print (" << os_type << "&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< endl
<< "private:" << endl
<< "std::string file_;"
<< "};";
- os << "class unmatched_quote: public exception"
+ os << "class " << exp << "unmatched_quote: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
- << "~unmatched_quote () throw ();"
+ << "~unmatched_quote () " << nothrow << ';'
<< endl
<< "unmatched_quote (const std::string& argument);"
<< endl
@@ -242,7 +249,7 @@ generate_runtime_header (context& ctx)
<< "print (" << os_type << "&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< endl
<< "private:" << endl
<< "std::string argument_;"
@@ -251,11 +258,11 @@ generate_runtime_header (context& ctx)
if (ctx.options.generate_group_scanner ())
{
- os << "class unexpected_group: public exception"
+ os << "class " << exp << "unexpected_group: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
- << "~unexpected_group () throw ();"
+ << "~unexpected_group () " << nothrow << ';'
<< endl
<< "unexpected_group (const std::string& argument," << endl
<< "const std::string& group);"
@@ -270,18 +277,18 @@ generate_runtime_header (context& ctx)
<< "print (std::ostream&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< endl
<< "private:" << endl
<< "std::string argument_;"
<< "std::string group_;"
<< "};";
- os << "class group_separator: public exception" << endl
+ os << "class " << exp << "group_separator: public exception" << endl
<< "{"
<< "public:" << endl
<< "virtual" << endl
- << "~group_separator () throw ();"
+ << "~group_separator () " << nothrow << ';'
<< endl
<< "// Note: either (but not both) can be empty." << endl
<< "//" << endl
@@ -298,7 +305,7 @@ generate_runtime_header (context& ctx)
<< "print (std::ostream&) const;"
<< endl
<< "virtual const char*" << endl
- << "what () const throw ();"
+ << "what () const " << nothrow << ';'
<< endl
<< "private:" << endl
<< "std::string encountered_;"
@@ -308,13 +315,21 @@ generate_runtime_header (context& ctx)
// scanner
//
- os << "// Command line argument scanner interface." << endl
- << "//" << endl
- << "// The values returned by next() are guaranteed to be valid" << endl
- << "// for the two previous arguments up until a call to a third" << endl
- << "// peek() or next()." << endl
- << "//" << endl
- << "class scanner"
+ os << "// Command line argument scanner interface." << endl
+ << "//" << endl
+ << "// The values returned by next() are guaranteed to be valid" << endl
+ << "// for the two previous arguments up until a call to a third" << endl
+ << "// peek() or next()." << endl
+ << "//" << endl
+ << "// The position() function returns a monotonically-increasing" << endl
+ << "// number which, if stored, can later be used to determine the"<< endl
+ << "// relative position of the argument returned by the following"<< endl
+ << "// call to next(). Note that if multiple scanners are used to" << endl
+ << "// extract arguments from multiple sources, then the end" << endl
+ << "// position of the previous scanner should be used as the" << endl
+ << "// start position of the next." << endl
+ << "//" << endl
+ << "class " << exp << "scanner"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -331,15 +346,26 @@ generate_runtime_header (context& ctx)
<< endl
<< "virtual void" << endl
<< "skip () = 0;"
+ << endl
+ << "virtual std::size_t" << endl
+ << "position () = 0;"
<< "};";
// argv_scanner
//
- os << "class argv_scanner: public scanner"
+ os << "class " << exp << "argv_scanner: public scanner"
<< "{"
<< "public:" << endl
- << "argv_scanner (int& argc, char** argv, bool erase = false);"
- << "argv_scanner (int start, int& argc, char** argv, bool erase = false);"
+ << "argv_scanner (int& argc," << endl
+ << "char** argv," << endl
+ << "bool erase = false," << endl
+ << "std::size_t start_position = 0);"
+ << endl
+ << "argv_scanner (int start," << endl
+ << "int& argc," << endl
+ << "char** argv," << endl
+ << "bool erase = false," << endl
+ << "std::size_t start_position = 0);"
<< endl
<< "int" << endl
<< "end () const;"
@@ -356,7 +382,11 @@ generate_runtime_header (context& ctx)
<< "virtual void" << endl
<< "skip ();"
<< endl
- << "private:" << endl
+ << "virtual std::size_t" << endl
+ << "position ();"
+ << endl
+ << "protected:" << endl
+ << "std::size_t start_position_;"
<< "int i_;"
<< "int& argc_;"
<< "char** argv_;"
@@ -367,17 +397,18 @@ generate_runtime_header (context& ctx)
//
if (ctx.options.generate_vector_scanner ())
{
- os << "class vector_scanner: public scanner"
+ os << "class " << exp << "vector_scanner: public scanner"
<< "{"
<< "public:" << endl
- << "vector_scanner (const std::vector<std::string>&, " <<
- "std::size_t start = 0);"
+ << "vector_scanner (const std::vector<std::string>&," << endl
+ << "std::size_t start = 0," << endl
+ << "std::size_t start_position = 0);"
<< endl
<< "std::size_t" << endl
<< "end () const;"
<< endl
<< "void" << endl
- << "reset (std::size_t start = 0);"
+ << "reset (std::size_t start = 0, std::size_t start_position = 0);"
<< endl
<< "virtual bool" << endl
<< "more ();"
@@ -391,7 +422,11 @@ generate_runtime_header (context& ctx)
<< "virtual void" << endl
<< "skip ();"
<< endl
+ << "virtual std::size_t" << endl
+ << "position ();"
+ << endl
<< "private:" << endl
+ << "std::size_t start_position_;"
<< "const std::vector<std::string>& v_;"
<< "std::size_t i_;"
<< "};";
@@ -401,22 +436,25 @@ generate_runtime_header (context& ctx)
//
if (ctx.options.generate_file_scanner ())
{
- os << "class argv_file_scanner: public argv_scanner"
+ os << "class " << exp << "argv_file_scanner: public argv_scanner"
<< "{"
<< "public:" << endl
<< "argv_file_scanner (int& argc," << endl
<< "char** argv," << endl
<< "const std::string& option," << endl
- << "bool erase = false);"
+ << "bool erase = false," << endl
+ << "std::size_t start_position = 0);"
<< endl
<< "argv_file_scanner (int start," << endl
<< "int& argc," << endl
<< "char** argv," << endl
<< "const std::string& option," << endl
- << "bool erase = false);"
+ << "bool erase = false," << endl
+ << "std::size_t start_position = 0);"
<< endl
<< "argv_file_scanner (const std::string& file," << endl
- << "const std::string& option);"
+ << "const std::string& option," << endl
+ << "std::size_t start_position = 0);"
<< endl
<< "struct option_info"
<< "{"
@@ -432,18 +470,21 @@ generate_runtime_header (context& ctx)
<< "char** argv," << endl
<< "const option_info* options," << endl
<< "std::size_t options_count," << endl
- << "bool erase = false);"
+ << "bool erase = false," << endl
+ << "std::size_t start_position = 0);"
<< endl
<< "argv_file_scanner (int start," << endl
<< "int& argc," << endl
<< "char** argv," << endl
<< "const option_info* options," << endl
<< "std::size_t options_count," << endl
- << "bool erase = false);"
+ << "bool erase = false," << endl
+ << "std::size_t start_position = 0);"
<< endl
<< "argv_file_scanner (const std::string& file," << endl
<< "const option_info* options = 0," << endl
- << "std::size_t options_count = 0);"
+ << "std::size_t options_count = 0," << endl
+ << "std::size_t start_position = 0);"
<< endl
<< "virtual bool" << endl
<< "more ();"
@@ -457,6 +498,9 @@ generate_runtime_header (context& ctx)
<< "virtual void" << endl
<< "skip ();"
<< endl
+ << "virtual std::size_t" << endl
+ << "position ();"
+ << endl
<< "// Return the file path if the peeked at argument came from a file and" << endl
<< "// the empty string otherwise. The reference is guaranteed to be valid" << endl
<< "// till the end of the scanner lifetime." << endl
@@ -512,7 +556,7 @@ generate_runtime_header (context& ctx)
//
if (ctx.options.generate_group_scanner ())
{
- os << "class group_scanner: public scanner"
+ os << "class " << exp << "group_scanner: public scanner"
<< "{"
<< "public:" << endl
<< "group_scanner (scanner&);"
@@ -529,12 +573,18 @@ generate_runtime_header (context& ctx)
<< "virtual void" << endl
<< "skip ();"
<< endl
+ << "virtual std::size_t" << endl
+ << "position ();"
+ << endl
<< "// The group is only available after the call to next()" << endl
<< "// (and skip() -- in case one needs to make sure the group" << endl
<< "// was empty, or some such) and is only valid (and must be" << endl
<< "// handled) until the next call to any of the scanner" << endl
<< "// functions (including more())." << endl
<< "//" << endl
+ << "// Note also that argument positions within each group start"<< endl
+ << "// from 0." << endl
+ << "//" << endl
<< "scanner&" << endl
<< "group ();"
<< endl
@@ -562,21 +612,20 @@ generate_runtime_header (context& ctx)
<< "static separator" << endl
<< "sense (const char*);"
<< endl
- << "// If the state is scanned or skipped, then scan the" << endl
- << "// leading groups and save the next (unescaped) argument in" << endl
- << "// arg_. If the state is peeked, then scan the trailing" << endl
- << "// groups. In both cases set the new state." << endl
+
+ << "// Scan the leading groups, the next argument/argument pack,"<< endl
+ << "// and the trailing groups." << endl
<< "//" << endl
<< "void" << endl
- << "scan_group (state);"
+ << "scan_group ();"
<< endl
<< "scanner& scan_;"
<< "state state_;"
<< endl
<< "// Circular buffer of two arguments." << endl
<< "//" << endl
- << "std::string arg_[2];"
- << "std::size_t i_;"
+ << "std::vector<std::string> arg_[2];"
+ << "std::size_t i_, j_, pos_;"
<< endl
<< "std::vector<std::string> group_;"
<< "vector_scanner group_scan_;"
@@ -590,7 +639,7 @@ generate_runtime_header (context& ctx)
os << "typedef std::vector<std::string> option_names;"
<< endl;
- os << "class option"
+ os << "class " << exp_inl << "option"
<< "{"
<< "public:" << endl
<< endl
@@ -620,7 +669,7 @@ generate_runtime_header (context& ctx)
<< "std::string default_value_;"
<< "};";
- os << "class options: public std::vector<option>"
+ os << "class " << exp << "options: public std::vector<option>"
<< "{"
<< "public:" << endl
<< "typedef std::vector<option> container_type;"
diff --git a/cli/cli/runtime-inline.cxx b/cli/cli/runtime-inline.cxx
index 8f0e84c..ce18e92 100644
--- a/cli/cli/runtime-inline.cxx
+++ b/cli/cli/runtime-inline.cxx
@@ -232,14 +232,29 @@ generate_runtime_inline (context& ctx)
<< "//" << endl;
os << inl << "argv_scanner::" << endl
- << "argv_scanner (int& argc, char** argv, bool erase)" << endl
- << ": i_ (1), argc_ (argc), argv_ (argv), erase_ (erase)"
+ << "argv_scanner (int& argc," << endl
+ << "char** argv," << endl
+ << "bool erase," << endl
+ << "std::size_t sp)" << endl
+ << ": start_position_ (sp + 1)," << endl
+ << " i_ (1)," << endl
+ << " argc_ (argc)," << endl
+ << " argv_ (argv)," << endl
+ << " erase_ (erase)"
<< "{"
<< "}";
os << inl << "argv_scanner::" << endl
- << "argv_scanner (int start, int& argc, char** argv, bool erase)" << endl
- << ": i_ (start), argc_ (argc), argv_ (argv), erase_ (erase)"
+ << "argv_scanner (int start," << endl
+ << "int& argc," << endl
+ << "char** argv," << endl
+ << "bool erase," << endl
+ << "std::size_t sp)" << endl
+ << ": start_position_ (sp + static_cast<std::size_t> (start))," << endl
+ << " i_ (start)," << endl
+ << " argc_ (argc)," << endl
+ << " argv_ (argv)," << endl
+ << " erase_ (erase)"
<< "{"
<< "}";
@@ -257,9 +272,10 @@ generate_runtime_inline (context& ctx)
<< "//" << endl;
os << inl << "vector_scanner::" << endl
- << "vector_scanner (const std::vector<std::string>& v, " <<
- "std::size_t i)" << endl
- << ": v_ (v), i_ (i)"
+ << "vector_scanner (const std::vector<std::string>& v," << endl
+ << "std::size_t i," << endl
+ << "std::size_t sp)" << endl
+ << ": start_position_ (sp), v_ (v), i_ (i)"
<< "{"
<< "}";
@@ -270,9 +286,10 @@ generate_runtime_inline (context& ctx)
<< "}";
os << inl << "void vector_scanner::" << endl
- << "reset (std::size_t i)"
+ << "reset (std::size_t i, std::size_t sp)"
<< "{"
<< "i_ = i;"
+ << "start_position_ = sp;"
<< "}";
}
@@ -289,8 +306,9 @@ generate_runtime_inline (context& ctx)
<< "argv_file_scanner (int& argc," << endl
<< "char** argv," << endl
<< "const std::string& option," << endl
- << "bool erase)" << endl
- << ": argv_scanner (argc, argv, erase)," << endl
+ << "bool erase," << endl
+ << "std::size_t sp)" << endl
+ << ": argv_scanner (argc, argv, erase, sp)," << endl
<< " option_ (option)," << endl
<< " options_ (&option_info_)," << endl
<< " options_count_ (1)," << endl
@@ -308,8 +326,9 @@ generate_runtime_inline (context& ctx)
<< "int& argc," << endl
<< "char** argv," << endl
<< "const std::string& option," << endl
- << "bool erase)" << endl
- << ": argv_scanner (start, argc, argv, erase)," << endl
+ << "bool erase," << endl
+ << "std::size_t sp)" << endl
+ << ": argv_scanner (start, argc, argv, erase, sp)," << endl
<< " option_ (option)," << endl
<< " options_ (&option_info_)," << endl
<< " options_count_ (1)," << endl
@@ -324,8 +343,9 @@ generate_runtime_inline (context& ctx)
os << inl << "argv_file_scanner::" << endl
<< "argv_file_scanner (const std::string& file," << endl
- << "const std::string& option)" << endl
- << ": argv_scanner (0, zero_argc_, 0)," << endl
+ << "const std::string& option," << endl
+ << "std::size_t sp)" << endl
+ << ": argv_scanner (0, zero_argc_, 0, sp)," << endl
<< " option_ (option)," << endl
<< " options_ (&option_info_)," << endl
<< " options_count_ (1)," << endl
@@ -345,8 +365,9 @@ generate_runtime_inline (context& ctx)
<< "char** argv," << endl
<< "const option_info* options," << endl
<< "std::size_t options_count," << endl
- << "bool erase)" << endl
- << ": argv_scanner (argc, argv, erase)," << endl
+ << "bool erase," << endl
+ << "std::size_t sp)" << endl
+ << ": argv_scanner (argc, argv, erase, sp)," << endl
<< " options_ (options)," << endl
<< " options_count_ (options_count)," << endl
<< " i_ (1)";
@@ -362,8 +383,9 @@ generate_runtime_inline (context& ctx)
<< "char** argv," << endl
<< "const option_info* options," << endl
<< "std::size_t options_count," << endl
- << "bool erase)" << endl
- << ": argv_scanner (start, argc, argv, erase)," << endl
+ << "bool erase," << endl
+ << "std::size_t sp)" << endl
+ << ": argv_scanner (start, argc, argv, erase, sp)," << endl
<< " options_ (options)," << endl
<< " options_count_ (options_count)," << endl
<< " i_ (1)";
@@ -376,8 +398,9 @@ generate_runtime_inline (context& ctx)
os << inl << "argv_file_scanner::" << endl
<< "argv_file_scanner (const std::string& file," << endl
<< "const option_info* options," << endl
- << "std::size_t options_count)" << endl
- << ": argv_scanner (0, zero_argc_, 0)," << endl
+ << "std::size_t options_count," << endl
+ << "std::size_t sp)" << endl
+ << ": argv_scanner (0, zero_argc_, 0, sp)," << endl
<< " options_ (options)," << endl
<< " options_count_ (options_count)," << endl
<< " i_ (1)";
@@ -398,7 +421,7 @@ generate_runtime_inline (context& ctx)
<< inl << "group_scanner::" << endl
<< "group_scanner (scanner& s)" << endl
- << ": scan_ (s), state_ (skipped), i_ (1), group_scan_ (group_)"
+ << ": scan_ (s), state_ (skipped), i_ (1), j_ (0), group_scan_ (group_)"
<< "{"
<< "}"
diff --git a/cli/cli/runtime-source.cxx b/cli/cli/runtime-source.cxx
index 3864163..11cd746 100644
--- a/cli/cli/runtime-source.cxx
+++ b/cli/cli/runtime-source.cxx
@@ -15,12 +15,13 @@ generate_runtime_source (context& ctx, bool complete)
<< "#include <set>" << endl
<< "#include <string>" << endl
<< "#include <vector>" << endl
+ << "#include <utility>" << endl // pair
<< "#include <ostream>" << endl
- << "#include <sstream>" << endl;
+ << "#include <sstream>" << endl
+ << "#include <cstring>" << endl;
if (complete && ctx.options.generate_file_scanner ())
- os << "#include <cstring>" << endl
- << "#include <fstream>" << endl;
+ os << "#include <fstream>" << endl;
os << endl;
@@ -30,12 +31,16 @@ generate_runtime_source (context& ctx, bool complete)
{
string const& os_type (ctx.options.ostream_type ());
+ const char* nothrow (ctx.options.std () < cxx_version::cxx11
+ ? "throw ()"
+ : "noexcept");
+
// unknown_option
//
os << "// unknown_option" << endl
<< "//" << endl
<< "unknown_option::" << endl
- << "~unknown_option () throw ()"
+ << "~unknown_option () " << nothrow
<< "{"
<< "}"
@@ -46,7 +51,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* unknown_option::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "return \"unknown option\";"
<< "}";
@@ -56,7 +61,7 @@ generate_runtime_source (context& ctx, bool complete)
os << "// unknown_argument" << endl
<< "//" << endl
<< "unknown_argument::" << endl
- << "~unknown_argument () throw ()"
+ << "~unknown_argument () " << nothrow
<< "{"
<< "}"
@@ -67,7 +72,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* unknown_argument::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "return \"unknown argument\";"
<< "}";
@@ -77,7 +82,7 @@ generate_runtime_source (context& ctx, bool complete)
os << "// missing_value" << endl
<< "//" << endl
<< "missing_value::" << endl
- << "~missing_value () throw ()"
+ << "~missing_value () " << nothrow
<< "{"
<< "}"
@@ -88,7 +93,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* missing_value::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "return \"missing option value\";"
<< "}";
@@ -98,7 +103,7 @@ generate_runtime_source (context& ctx, bool complete)
os << "// invalid_value" << endl
<< "//" << endl
<< "invalid_value::" << endl
- << "~invalid_value () throw ()"
+ << "~invalid_value () " << nothrow
<< "{"
<< "}"
@@ -114,7 +119,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* invalid_value::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "return \"invalid option value\";"
<< "}";
@@ -130,7 +135,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* eos_reached::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "return \"end of argument stream reached\";"
<< "}";
@@ -142,7 +147,7 @@ generate_runtime_source (context& ctx, bool complete)
os << "// file_io_failure" << endl
<< "//" << endl
<< "file_io_failure::" << endl
- << "~file_io_failure () throw ()"
+ << "~file_io_failure () " << nothrow
<< "{"
<< "}"
@@ -154,7 +159,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* file_io_failure::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "return \"unable to open file or read failure\";"
<< "}";
@@ -164,7 +169,7 @@ generate_runtime_source (context& ctx, bool complete)
os << "// unmatched_quote" << endl
<< "//" << endl
<< "unmatched_quote::" << endl
- << "~unmatched_quote () throw ()"
+ << "~unmatched_quote () " << nothrow
<< "{"
<< "}"
@@ -176,7 +181,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* unmatched_quote::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "return \"unmatched quote\";"
<< "}";
@@ -190,7 +195,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "//" << endl
<< "unexpected_group::" << endl
- << "~unexpected_group () throw ()"
+ << "~unexpected_group () " << nothrow
<< "{"
<< "}"
@@ -202,7 +207,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* unexpected_group::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "return \"unexpected grouped argument\";"
<< "}";
@@ -213,7 +218,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "//" << endl
<< "group_separator::" << endl
- << "~group_separator () throw ()"
+ << "~group_separator () " << nothrow
<< "{"
<< "}"
@@ -237,7 +242,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "const char* group_separator::" << endl
- << "what () const throw ()"
+ << "what () const " << nothrow
<< "{"
<< "bool ex (!expected_.empty ());"
<< "bool en (!encountered_.empty ());"
@@ -259,6 +264,10 @@ generate_runtime_source (context& ctx, bool complete)
// argv_scanner
//
+ // Note that due to the erase logic we cannot just add i_ to
+ // start_position and so have to increment it instead. See also
+ // argv_file_scanner that continues with this logic.
+ //
os << "// argv_scanner" << endl
<< "//" << endl
@@ -295,6 +304,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "else" << endl
<< "++i_;"
<< endl
+ << "++start_position_;"
<< "return r;"
<< "}"
<< "else" << endl
@@ -304,10 +314,19 @@ generate_runtime_source (context& ctx, bool complete)
<< "void argv_scanner::" << endl
<< "skip ()"
<< "{"
- << "if (i_ < argc_)" << endl
+ << "if (i_ < argc_)"
+ << "{"
<< "++i_;"
+ << "++start_position_;"
+ << "}"
<< "else" << endl
<< "throw eos_reached ();"
+ << "}"
+
+ << "std::size_t argv_scanner::" << endl
+ << "position ()"
+ << "{"
+ << "return start_position_;"
<< "}";
// vector_scanner
@@ -348,11 +367,19 @@ generate_runtime_source (context& ctx, bool complete)
<< "++i_;"
<< "else" << endl
<< "throw eos_reached ();"
+ << "}"
+
+ << "std::size_t vector_scanner::" << endl
+ << "position ()"
+ << "{"
+ << "return start_position_ + i_;"
<< "}";
}
// argv_file_scanner
//
+ // Note that we continue incrementing start_position like argv_scanner.
+ //
if (ctx.options.generate_file_scanner ())
{
bool sep (!ctx.opt_sep.empty ());
@@ -486,6 +513,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "{"
<< "hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value);"
<< "args_.pop_front ();"
+ << "++start_position_;"
<< "return hold_[i_].c_str ();"
<< "}"
<< "}"
@@ -498,8 +526,11 @@ generate_runtime_source (context& ctx, bool complete)
<< endl
<< "if (args_.empty ())" << endl
<< "return base::skip ();"
- << "else" << endl
+ << "else"
+ << "{"
<< "args_.pop_front ();"
+ << "++start_position_;"
+ << "}"
<< "}"
<< "const argv_file_scanner::option_info* argv_file_scanner::" << endl
@@ -512,6 +543,12 @@ generate_runtime_source (context& ctx, bool complete)
<< "return 0;"
<< "}"
+ << "std::size_t argv_file_scanner::" << endl
+ << "position ()"
+ << "{"
+ << "return start_position_;"
+ << "}"
+
<< "void argv_file_scanner::" << endl
<< "load (const std::string& file)"
<< "{"
@@ -699,43 +736,50 @@ generate_runtime_source (context& ctx, bool complete)
<< "if (state_ == scanned)"
<< "{"
<< "if (group_scan_.end () != group_.size ())" << endl
- << "throw unexpected_group (arg_[i_], group_scan_.next ());"
+ << "throw unexpected_group (arg_[i_][j_], group_scan_.next ());"
<< "}"
- << "return scan_.more ();"
+ << "return j_ != 0 || scan_.more ();"
<< "}"
<< "const char* group_scanner::" << endl
<< "peek ()"
<< "{"
- << "if (state_ != peeked)" << endl
- << "scan_group (peeked);"
- << "scan_.peek ();"
+ << "if (state_ != peeked)"
+ << "{"
+ << "scan_group ();"
+ << "state_ = peeked;"
+ << "}"
<< "// Return unescaped." << endl
- << "return arg_[i_].c_str ();"
+ << "return arg_[i_][j_ - 1].c_str ();"
<< "}"
<< "const char* group_scanner::" << endl
<< "next ()"
<< "{"
<< "if (state_ != peeked)" << endl
- << "scan_group (peeked);"
- << "scan_.next ();"
- << "scan_group (scanned);"
+ << "scan_group ();"
+ << "state_ = scanned;"
<< "// Return unescaped." << endl
- << "return arg_[i_].c_str ();"
+ << "return arg_[i_][--j_].c_str ();"
<< "}"
<< "void group_scanner::" << endl
<< "skip ()"
<< "{"
<< "if (state_ != peeked)" << endl
- << "scan_group (peeked);"
- << "scan_.skip ();"
- << "scan_group (skipped);"
+ << "scan_group ();"
+ << "state_ = skipped;"
+ << "--j_;"
+ << "}"
+
+ << "std::size_t group_scanner::" << endl
+ << "position ()"
+ << "{"
+ << "return j_ == 0 ? scan_.position () : pos_ + (arg_[i_].size () - j_);"
<< "}"
<< "void group_scanner::" << endl
- << "scan_group (state st)"
+ << "scan_group ()"
<< "{"
<< "// If the previous argument has been scanned, then make" << endl
<< "// sure the group has been scanned (handled) as well." << endl
@@ -743,53 +787,66 @@ generate_runtime_source (context& ctx, bool complete)
<< "if (state_ == scanned)"
<< "{"
<< "if (group_scan_.end () != group_.size ())" << endl
- << "throw unexpected_group (arg_[i_], group_scan_.next ());"
+ << "throw unexpected_group (arg_[i_][j_], group_scan_.next ());"
<< "}"
- << "if (state_ != peeked)"
+ << "// If we still have arguments in the pack, rewind the group." << endl
+ << "//" << endl
+ << "if (j_ != 0)"
<< "{"
- << "arg_[i_ == 0 ? ++i_ : --i_].clear ();"
- << "group_.clear ();"
<< "group_scan_.reset ();"
+ << "return;"
<< "}"
- << "// We recognize all group sequences both before and " << endl
- << "// after the argument and diagnose any misuse. We may" << endl
- << "// also have multiple groups:" << endl
- << "//" << endl
- << "// { -x }+ { -y }+ arg" << endl
- << "//" << endl
+ // Position must remain the same from before the first call to peek()
+ // (comes directly from the scanner) and until next().
+ //
+ // Note that while it may seem like a good idea to pass
+ // scan_.position() to reset() below, the trailing group positions
+ // will overlap with the argument's. So it seems best to start
+ // positions of each argument in a group from 0.
+ //
+ // Note also that we try hard not to throw away allocated memory in
+ // arg_[][0].
+ //
+ << "i_ += (i_ == 0 ? 1 : -1);"
+ << "group_.clear ();"
+ << "group_scan_.reset ();"
+ << "pos_ = scan_.position ();"
<< endl
- << "// Using group_ won't cover empty groups." << endl
+
+ << "// Note: using group_ won't cover empty groups and using" << endl
+ << "// j_ won't cover single-argument packs." << endl
<< "//" << endl
- << "bool g (false);"
+ << "bool group (false), pack (false);"
<< endl
- << "while (scan_.more ())"
+ << "do"
<< "{"
- << "const char* a (scan_.peek ());"
+ << "const char* a (scan_.next ());"
<< "size_t i (*a == '\\\\' ? 1 : 0);"
<< "separator s (sense (a + i));"
<< endl
<< "if (s == none || i != 0)"
<< "{"
- << "if (state_ != peeked)" << endl
- << "arg_[i_] = a + (s != none ? i : 0);"
+ << "if (arg_[i_].size () != 1)" << endl
+ << "arg_[i_].resize (1);"
+ << endl
+ << "arg_[i_][0] = a + (s != none ? i : 0);"
+ << "j_ = 1;"
<< "break;"
<< "}"
- << "// Start of a leading group for the next argument." << endl
+ << "// Start of a leading group for the next argument or" << endl
+ << "// argument pack. We will only know which once we see" << endl
+ << "// the closing separator." << endl
<< "//" << endl
- << "if (s == open && state_ == peeked)" << endl
- << "break;"
- << endl
- << "if (s != (state_ == peeked ? open_plus : open))" << endl
+ << "if (s != open)" << endl
<< "throw group_separator (a, \"\");"
<< endl
- << "g = true;"
+ << "size_t n (group_.size ());"
<< endl
<< "// Scan the group until the closing separator." << endl
<< "//" << endl
- << "scan_.next ();"
<< "s = none;"
<< "while (s == none && scan_.more ())"
<< "{"
@@ -804,20 +861,88 @@ generate_runtime_source (context& ctx, bool complete)
<< "}"
<< "}"
- << "if (s != (state_ == peeked ? close : close_plus))"
+ << "if (s == close)"
<< "{"
- << "throw group_separator ((s != none ? a : \"\")," << endl
- << "(state_ == peeked ? \"}\" : \"}+\"));"
+ << "size_t m (group_.size ());"
+ << endl
+ << "j_ = m - n;"
+ << "if (j_ == 0)" << endl
+ << "throw group_separator (\"{\", \"\");"
+ << endl
+ << "if (arg_[i_].size () != j_)" << endl
+ << "arg_[i_].resize (j_);"
+ << endl
+ << "// Move from group_ to arg_. Add in reverse for ease " << endl
+ << "// of iteration." << endl
+ << "//" << endl
+ << "for (size_t j (0); j != j_; ++j)" << endl
+ << "arg_[i_][j] = group_[m - j - 1];"
+ << "group_.resize (n);"
+ << endl
+ << "pack = true;"
+ << "break;"
<< "}"
+ << "else if (s == close_plus)" << endl
+ << "group = true;"
+ << "else" << endl
+ << "throw group_separator ((s != none ? a : \"\"), \"}+\");"
<< "}"
+ << "while (scan_.more ());"
+ << endl
<< "// Handle the case where we have seen the leading group" << endl
<< "// but there are no more arguments." << endl
<< "//" << endl
- << "if (g && state_ != peeked && !scan_.more ())" << endl
+ << "if (group && j_ == 0)" << endl
<< "throw group_separator (\"{\", \"\");"
<< endl
- << "state_ = st;"
+ << "// Handle trailing groups, if any." << endl
+ << "//" << endl
+
+ << "while (scan_.more ())"
+ << "{"
+ << "const char* a (scan_.peek ());"
+ << "size_t i (*a == '\\\\' ? 1 : 0);"
+ << "separator s (sense (a + i));"
+ << endl
+
+ << "// Next argument, argument pack, or leading group." << endl
+ << "//" << endl
+ << "if (s == none || s == open || i != 0)" << endl
+ << "break;"
+ << endl
+ << "if (s != open_plus)" << endl
+ << "throw group_separator (a, \"\");"
+ << endl
+ << "group = true;"
+ << endl
+ << "// Scan the group until the closing separator." << endl
+ << "//" << endl
+ << "scan_.next ();"
+ << "s = none;"
+ << "while (s == none && scan_.more ())"
+ << "{"
+ << "a = scan_.next ();"
+ << "i = (*a == '\\\\' ? 1 : 0);"
+ << "s = sense (a + i);"
+ << endl
+ << "if (s == none || i != 0)"
+ << "{"
+ << "group_.push_back (a + (s != none ? i : 0));"
+ << "s = none;"
+ << "}"
+ << "}"
+
+ << "if (s != close)" << endl
+ << "throw group_separator ((s != none ? a : \"\"), \"}\");"
+ << "}"
+
+ << "// Handle the case where we have seen the argument pack" << endl
+ << "// without leading or trailing group." << endl
+ << "//" << endl
+ << "if (pack && !group)" << endl
+ << "throw group_separator (\"{\", \"\");"
+
<< "}";
}
@@ -890,11 +1015,33 @@ generate_runtime_source (context& ctx, bool complete)
<< "{";
os << "static void" << endl
- << "parse (bool& x, scanner& s)"
+ << "parse (bool& x, " << (sp ? "bool& xs, " : "") << "scanner& s)"
<< "{"
- << "s.next ();"
- << "x = true;"
- << "}";
+ << "const char* o (s.next ());"
+ << endl
+ << "if (s.more ())"
+ << "{"
+ << "const char* v (s.next ());"
+ << endl
+ << "if (std::strcmp (v, \"1\") == 0 ||" << endl
+ << "std::strcmp (v, \"true\") == 0 ||" << endl
+ << "std::strcmp (v, \"TRUE\") == 0 ||" << endl
+ << "std::strcmp (v, \"True\") == 0)" << endl
+ << "x = true;"
+ << "else if (std::strcmp (v, \"0\") == 0 ||" << endl
+ << "std::strcmp (v, \"false\") == 0 ||" << endl
+ << "std::strcmp (v, \"FALSE\") == 0 ||" << endl
+ << "std::strcmp (v, \"False\") == 0)" << endl
+ << "x = false;"
+ << "else" << endl
+ << "throw invalid_value (o, v);"
+ << "}"
+ << "else" << endl
+ << "throw missing_value (o);";
+ if (sp)
+ os << endl
+ << "xs = true;";
+ os << "}";
if (gen_merge)
os << "static void" << endl
@@ -934,6 +1081,28 @@ generate_runtime_source (context& ctx, bool complete)
os << "};";
+ // parser<std::pair<X, std::size_t>>
+ //
+ os << "template <typename X>" << endl
+ << "struct parser<std::pair<X, std::size_t> >"
+ << "{";
+
+ os << "static void" << endl
+ << "parse (std::pair<X, std::size_t>& x, " << (sp ? "bool& xs, " : "") << "scanner& s)"
+ << "{"
+ << "x.second = s.position ();"
+ << "parser<X>::parse (x.first, " << (sp ? "xs, " : "") << "s);"
+ << "}";
+
+ if (gen_merge)
+ os << "static void" << endl
+ << "merge (std::pair<X, std::size_t>& b, const std::pair<X, std::size_t>& a)"
+ << "{"
+ << "b = a;"
+ << "}";
+
+ os << "};";
+
// parser<std::vector<X>>
//
os << "template <typename X>" << endl
@@ -1001,6 +1170,7 @@ generate_runtime_source (context& ctx, bool complete)
<< endl
<< "if (s.more ())"
<< "{"
+ << "std::size_t pos (s.position ());"
<< "std::string ov (s.next ());"
<< "std::string::size_type p = ov.find ('=');"
<< endl
@@ -1020,13 +1190,13 @@ generate_runtime_source (context& ctx, bool complete)
os << "if (!kstr.empty ())"
<< "{"
<< "av[1] = const_cast<char*> (kstr.c_str ());"
- << "argv_scanner s (0, ac, av);"
+ << "argv_scanner s (0, ac, av, false, pos);"
<< "parser<K>::parse (k, " << (sp ? "dummy, " : "") << "s);"
<< "}"
<< "if (!vstr.empty ())"
<< "{"
<< "av[1] = const_cast<char*> (vstr.c_str ());"
- << "argv_scanner s (0, ac, av);"
+ << "argv_scanner s (0, ac, av, false, pos);"
<< "parser<V>::parse (v, " << (sp ? "dummy, " : "") << "s);"
<< "}"
<< "m[k] = v;"
@@ -1050,6 +1220,70 @@ generate_runtime_source (context& ctx, bool complete)
os << "};";
+ // parser<std::multimap<K,V,C>>
+ //
+ os << "template <typename K, typename V, typename C>" << endl
+ << "struct parser<std::multimap<K, V, C> >"
+ << "{";
+
+ os << "static void" << endl
+ << "parse (std::multimap<K, V, C>& m, " << (sp ? "bool& xs, " : "") << "scanner& s)"
+ << "{"
+ << "const char* o (s.next ());"
+ << endl
+ << "if (s.more ())"
+ << "{"
+ << "std::size_t pos (s.position ());"
+ << "std::string ov (s.next ());"
+ << "std::string::size_type p = ov.find ('=');"
+ << endl
+ << "K k = K ();"
+ << "V v = V ();"
+ << "std::string kstr (ov, 0, p);"
+ << "std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));"
+ << endl
+ << "int ac (2);"
+ << "char* av[] ="
+ << "{"
+ << "const_cast<char*> (o)," << endl
+ << "0"
+ << "};";
+ if (sp)
+ os << "bool dummy;";
+ os << "if (!kstr.empty ())"
+ << "{"
+ << "av[1] = const_cast<char*> (kstr.c_str ());"
+ << "argv_scanner s (0, ac, av, false, pos);"
+ << "parser<K>::parse (k, " << (sp ? "dummy, " : "") << "s);"
+ << "}"
+ << "if (!vstr.empty ())"
+ << "{"
+ << "av[1] = const_cast<char*> (vstr.c_str ());"
+ << "argv_scanner s (0, ac, av, false, pos);"
+ << "parser<V>::parse (v, " << (sp ? "dummy, " : "") << "s);"
+ << "}"
+ << "m.insert (typename std::multimap<K, V, C>::value_type (k, v));"
+ << "}"
+ << "else" << endl
+ << "throw missing_value (o);";
+ if (sp)
+ os << endl
+ << "xs = true;";
+ os << "}";
+
+ if (gen_merge)
+ os << "static void" << endl
+ << "merge (std::multimap<K, V, C>& b, const std::multimap<K, V, C>& a)"
+ << "{"
+ << "for (typename std::multimap<K, V, C>::const_iterator i (a.begin ()); " << endl
+ << "i != a.end (); " << endl
+ << "++i)" << endl
+ << "b.insert (typename std::multimap<K, V, C>::value_type (i->first," << endl
+ << "i->second));" << endl
+ << "}";
+
+ os << "};";
+
// Parser thunk.
//
os << "template <typename X, typename T, T X::*M>" << endl
@@ -1059,6 +1293,14 @@ generate_runtime_source (context& ctx, bool complete)
<< "parser<T>::parse (x.*M, s);"
<< "}";
+ os << "template <typename X, bool X::*M>" << endl
+ << "void" << endl
+ << "thunk (X& x, scanner& s)"
+ << "{"
+ << "s.next ();"
+ << "x.*M = true;"
+ << "}";
+
if (ctx.gen_specifier)
os << "template <typename X, typename T, T X::*M, bool X::*S>" << endl
<< "void" << endl
diff --git a/cli/cli/semantics/class.cxx b/cli/cli/semantics/class.cxx
index 494d5d0..cd90f8e 100644
--- a/cli/cli/semantics/class.cxx
+++ b/cli/cli/semantics/class.cxx
@@ -2,7 +2,7 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
-#include <cutl/compiler/type-info.hxx>
+#include <libcutl/compiler/type-info.hxx>
#include <cli/semantics/class.hxx>
diff --git a/cli/cli/semantics/doc.cxx b/cli/cli/semantics/doc.cxx
index c31260c..a12893d 100644
--- a/cli/cli/semantics/doc.cxx
+++ b/cli/cli/semantics/doc.cxx
@@ -2,7 +2,7 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
-#include <cutl/compiler/type-info.hxx>
+#include <libcutl/compiler/type-info.hxx>
#include <cli/semantics/doc.hxx>
diff --git a/cli/cli/semantics/elements.cxx b/cli/cli/semantics/elements.cxx
index ed8eb7d..3c43f91 100644
--- a/cli/cli/semantics/elements.cxx
+++ b/cli/cli/semantics/elements.cxx
@@ -2,7 +2,7 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
-#include <cutl/compiler/type-info.hxx>
+#include <libcutl/compiler/type-info.hxx>
#include <cli/semantics/elements.hxx>
diff --git a/cli/cli/semantics/elements.hxx b/cli/cli/semantics/elements.hxx
index 6235a06..e43f707 100644
--- a/cli/cli/semantics/elements.hxx
+++ b/cli/cli/semantics/elements.hxx
@@ -14,12 +14,12 @@
#include <utility> // std::pair
#include <cassert>
-#include <cutl/fs/path.hxx>
+#include <libcutl/fs/path.hxx>
-#include <cutl/container/graph.hxx>
-#include <cutl/container/pointer-iterator.hxx>
+#include <libcutl/container/graph.hxx>
+#include <libcutl/container/pointer-iterator.hxx>
-#include <cutl/compiler/context.hxx>
+#include <libcutl/compiler/context.hxx>
namespace semantics
{
diff --git a/cli/cli/semantics/expression.cxx b/cli/cli/semantics/expression.cxx
index 18d3312..5d1260d 100644
--- a/cli/cli/semantics/expression.cxx
+++ b/cli/cli/semantics/expression.cxx
@@ -2,7 +2,7 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
-#include <cutl/compiler/type-info.hxx>
+#include <libcutl/compiler/type-info.hxx>
#include <cli/semantics/expression.hxx>
diff --git a/cli/cli/semantics/namespace.cxx b/cli/cli/semantics/namespace.cxx
index 3c2643c..b9ed422 100644
--- a/cli/cli/semantics/namespace.cxx
+++ b/cli/cli/semantics/namespace.cxx
@@ -2,7 +2,7 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
-#include <cutl/compiler/type-info.hxx>
+#include <libcutl/compiler/type-info.hxx>
#include <cli/semantics/namespace.hxx>
diff --git a/cli/cli/semantics/option.cxx b/cli/cli/semantics/option.cxx
index 8746a5e..215a169 100644
--- a/cli/cli/semantics/option.cxx
+++ b/cli/cli/semantics/option.cxx
@@ -2,7 +2,7 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
-#include <cutl/compiler/type-info.hxx>
+#include <libcutl/compiler/type-info.hxx>
#include <cli/semantics/option.hxx>
diff --git a/cli/cli/semantics/unit.cxx b/cli/cli/semantics/unit.cxx
index 9c532ea..690011f 100644
--- a/cli/cli/semantics/unit.cxx
+++ b/cli/cli/semantics/unit.cxx
@@ -2,7 +2,7 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
-#include <cutl/compiler/type-info.hxx>
+#include <libcutl/compiler/type-info.hxx>
#include <cli/semantics/unit.hxx>
diff --git a/cli/cli/source.cxx b/cli/cli/source.cxx
index b6df839..3c04d1a 100644
--- a/cli/cli/source.cxx
+++ b/cli/cli/source.cxx
@@ -110,8 +110,12 @@ namespace
for (names::name_iterator i (n.name_begin ()); i != n.name_end (); ++i)
{
os << "_cli_" << scope << "_map_[\"" << *i << "\"] =" << endl
- << "&" << cli << "::thunk< " << scope << ", " << type << ", " <<
- "&" << scope << "::" << member;
+ << "&" << cli << "::thunk< " << scope;
+
+ if (type != "bool")
+ os << ", " << type;
+
+ os << ", " << "&" << scope << "::" << member;
if (gen_specifier && type != "bool")
os << "," << endl
@@ -278,6 +282,9 @@ namespace
: (n == 1 ? ds[0] : ds[1]); // Else, use common (no first sentence).
}
+ if (options.ascii_tree ())
+ preprocess_ascii_tree (d);
+
std::set<string> arg_set;
if (n > 1 && options.ansi_color ())
translate_arg (ds[0], arg_set);
@@ -345,6 +352,8 @@ namespace
{
l++; // ' ' seperator
+ // Note: we naturally assume this doesn't need --ascii-tree treatment.
+ //
string s (doc.size () > 0 ? doc[0] : string ("<arg>"));
if (options.ansi_color ())
@@ -439,6 +448,8 @@ namespace
os << ' ';
l++;
+ // Note: we naturally assume this doesn't need --ascii-tree treatment.
+ //
string s (doc.size () > 0 ? doc[0] : string ("<arg>"));
if (color)
@@ -475,6 +486,9 @@ namespace
}
}
+ if (options.ascii_tree ())
+ preprocess_ascii_tree (d);
+
// Format the documentation string.
//
if (color)
@@ -1262,7 +1276,6 @@ generate_source (context& ctx)
ostream& os (ctx.os);
os << "#include <map>" << endl
- << "#include <cstring>" << endl
<< endl;
traversal::cli_unit unit;
diff --git a/cli/cli/traversal/elements.hxx b/cli/cli/traversal/elements.hxx
index a2ada23..f56de49 100644
--- a/cli/cli/traversal/elements.hxx
+++ b/cli/cli/traversal/elements.hxx
@@ -5,7 +5,7 @@
#ifndef CLI_TRAVERSAL_ELEMENTS_HXX
#define CLI_TRAVERSAL_ELEMENTS_HXX
-#include <cutl/compiler/traversal.hxx>
+#include <libcutl/compiler/traversal.hxx>
#include <cli/semantics/elements.hxx>
diff --git a/cli/cli/txt.cxx b/cli/cli/txt.cxx
index 16de45a..1e9094d 100644
--- a/cli/cli/txt.cxx
+++ b/cli/cli/txt.cxx
@@ -164,13 +164,16 @@ namespace
// n > 2 - arg string, short string, long string
//
size_t n (ds.size ());
- const string& d (
+ string d (
n == 1
? (cd_ == cd_short ? first_sentence (ds[0]) : ds[0])
: (n == 2
? (cd_ == cd_short ? first_sentence (ds[1]) : ds[1])
: ds[cd_ == cd_short ? 1 : 2]));
+ if (options.ascii_tree ())
+ preprocess_ascii_tree (d);
+
std::set<string> arg_set;
if (n > 1 && options.ansi_color ())
translate_arg (ds[0], arg_set);
diff --git a/cli/cli/version.hxx.in b/cli/cli/version.hxx.in
index ceb5389..11db861 100644
--- a/cli/cli/version.hxx.in
+++ b/cli/cli/version.hxx.in
@@ -38,7 +38,7 @@
#define CLI_VERSION_FULL "$cli.version$"
-#include <cutl/version.hxx>
+#include <libcutl/version.hxx>
$libcutl.check(LIBCUTL_VERSION, LIBCUTL_SNAPSHOT)$