summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-11-19 14:53:52 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-11-19 14:53:52 +0200
commit813e4744038ec3a1ca8095111074c1cb2a824d83 (patch)
treec4cda65a3280c09c50c0a3e227cdff5b43240247
parent3e34f8ac2ba3b719f13a8f9ef7422cbee8b02192 (diff)
Implement entire page usage generation
-rw-r--r--cli/context.cxx85
-rw-r--r--cli/context.hxx37
-rw-r--r--cli/generator.cxx65
-rw-r--r--cli/header.cxx31
-rw-r--r--cli/makefile4
-rw-r--r--cli/options.cli24
-rw-r--r--cli/options.cxx417
-rw-r--r--cli/options.hxx160
-rw-r--r--cli/options.ixx240
-rw-r--r--cli/runtime-header.cxx17
-rw-r--r--cli/runtime-inline.cxx4
-rw-r--r--cli/runtime-source.cxx4
-rw-r--r--cli/source.cxx412
-rw-r--r--doc/cli.120
-rw-r--r--doc/cli.xhtml20
15 files changed, 1273 insertions, 267 deletions
diff --git a/cli/context.cxx b/cli/context.cxx
index a014824..d13f1e5 100644
--- a/cli/context.cxx
+++ b/cli/context.cxx
@@ -1403,6 +1403,69 @@ format (output_type ot, string const& s, bool para)
}
string context::
+substitute (const string& s, semantics::cli_unit& u)
+{
+ string r;
+
+ // Scan the string looking for variables ($var$).
+ //
+ size_t b (0), e (b);
+ for (size_t n (s.size ()); e != n; ++e)
+ {
+ if (s[e] == '$' && e + 1 != n)
+ {
+ if (s[e + 1] == '$') // Escape.
+ {
+ r.append (s, b, ++e - b); // Keep one, skip the other.
+ b = e + 1;
+ continue;
+ }
+
+ // Scan for as long as it is a C identifier.
+ //
+ size_t p (e + 1); // Position of the second '$'.
+ for (; p != n; ++p)
+ {
+ char c (s[p]);
+
+ if (!(c == '_' ||
+ ('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ (p != e + 1 && '0' <= c && c <= '9')))
+ break;
+ }
+
+ // Note: check that the second '$' is not escaped.
+ //
+ if (p != n && s[p] == '$' && (p + 1 == n || s[p + 1] != '$'))
+ {
+ r.append (s, b, e - b);
+
+ // Lookup and substiute the variable.
+ //
+ ++e;
+ string v (s, e, p - e);
+
+ if (semantics::doc* d = u.lookup<semantics::doc> ("", "var: " + v))
+ r += d->front ();
+ else
+ {
+ cerr << "error: undefined variable '" << v << "' in '" << s << "'"
+ << endl;
+ throw generation_failed ();
+ }
+
+ e = p;
+ b = e + 1;
+ }
+ }
+ }
+
+ r.append (s, b, e - b); // Last chunk.
+ return r;
+}
+
+string context::
fq_name (semantics::nameable& n, bool cxx_name)
{
using namespace semantics;
@@ -1423,23 +1486,23 @@ fq_name (semantics::nameable& n, bool cxx_name)
return r;
}
-void context::
-cli_open ()
+string context::
+ns_open (const string& qn, bool last)
{
string::size_type b (0), e;
do
{
- e = cli.find ("::", b);
- string n (cli, b, e == string::npos ? e : e - b);
+ e = qn.find ("::", b);
+ string n (qn, b, e == string::npos ? e : e - b);
- if (!n.empty ())
+ if (!n.empty () && (last || e != string::npos))
os << "namespace " << n << "{";
b = e;
if (b == string::npos)
- break;
+ return n;
b += 2;
@@ -1447,22 +1510,22 @@ cli_open ()
}
void context::
-cli_close ()
+ns_close (const string& qn, bool last)
{
string::size_type b (0), e;
do
{
- e = cli.find ("::", b);
- string n (cli, b, e == string::npos ? e : e - b);
+ e = qn.find ("::", b);
+ string n (qn, b, e == string::npos ? e : e - b);
- if (!n.empty ())
+ if (!n.empty () && (last || e != string::npos))
os << "}";
b = e;
if (b == string::npos)
- break;
+ return;
b += 2;
diff --git a/cli/context.hxx b/cli/context.hxx
index 0170c7c..460287c 100644
--- a/cli/context.hxx
+++ b/cli/context.hxx
@@ -22,21 +22,22 @@ using std::endl;
class generation_failed {};
+enum usage
+{
+ ut_none,
+ ut_short,
+ ut_long,
+ ut_both
+};
+
class context
{
public:
typedef std::size_t size_t;
typedef std::string string;
- typedef ::options options_type;
-public:
- enum usage_type
- {
- ut_none,
- ut_short,
- ut_long,
- ut_both
- };
+ typedef ::options options_type;
+ typedef ::usage usage_type;
private:
struct data;
@@ -101,6 +102,14 @@ public:
void
format_line (output_type, string&, const char*, size_t);
+ // Substitute doc variable expansions ($var$).
+ //
+ static string
+ substitute (const string&, semantics::cli_unit&);
+
+ string
+ substitute (const string& s) {return substitute (s, unit);}
+
public:
static string const&
ename (semantics::nameable& n)
@@ -132,14 +141,16 @@ public:
string
fq_name (semantics::nameable& n, bool cxx_name = true);
- // Open/close cli namespace.
+ // Open/close namespace. If last is false, then the last name
+ // component is not treated as a namespace. The open function
+ // also returns the last name component.
//
public:
- void
- cli_open ();
+ string
+ ns_open (const string& name, bool last = true);
void
- cli_close ();
+ ns_close (const string& name, bool last = true);
public:
context (std::ostream&, semantics::cli_unit&, options_type const&);
diff --git a/cli/generator.cxx b/cli/generator.cxx
index b45d0ec..37092ab 100644
--- a/cli/generator.cxx
+++ b/cli/generator.cxx
@@ -79,67 +79,6 @@ namespace
}
void
- append (ostream& os, const string& s, semantics::cli_unit& u)
- {
- // Scan the string looking for variable substitutions ($var$).
- //
- size_t b (0), e (b);
- for (size_t n (s.size ()); e != n; ++e)
- {
- if (s[e] == '$' && e + 1 != n)
- {
- if (s[e + 1] == '$') // Escape.
- {
- os.write (s.c_str () + b, ++e - b); // Write one, skip the other.
- b = e + 1;
- continue;
- }
-
- // Scan for as long as it is a C identifier.
- //
- size_t p (e + 1); // Position of the second '$'.
- for (; p != n; ++p)
- {
- char c (s[p]);
-
- if (!(c == '_' ||
- ('a' <= c && c <= 'z') ||
- ('A' <= c && c <= 'Z') ||
- (p != e + 1 && '0' <= c && c <= '9')))
- break;
- }
-
- // Note: check that the second '$' is not escaped.
- //
- if (p != n && s[p] == '$' && (p + 1 == n || s[p + 1] != '$'))
- {
- os.write (s.c_str () + b, e - b);
-
- // Lookup and substiute the variable.
- //
- ++e;
- string v (s, e, p - e);
-
- if (semantics::doc* d = u.lookup<semantics::doc> ("", "var: " + v))
- os << d->front ();
- else
- {
- cerr << "error: undefined variable '" << v << "' in '" << s << "'"
- << endl;
- throw generation_failed ();
- }
-
- e = p;
- b = e + 1;
- }
- }
- }
-
- os.write (s.c_str () + b, e - b); // Last chunk.
- os << endl;
- }
-
- void
append (ostream& os,
vector<string> const& text,
string const& file,
@@ -147,7 +86,7 @@ namespace
{
for (vector<string>::const_iterator i (text.begin ());
i != text.end (); ++i)
- append (os, *i, u);
+ os << context::substitute (*i, u) << endl;
if (!file.empty ())
{
@@ -159,7 +98,7 @@ namespace
// the delimiter.
//
for (string s; getline (ifs, s); )
- append (os, s, u);
+ os << context::substitute (s, u) << endl;
}
}
}
diff --git a/cli/header.cxx b/cli/header.cxx
index 6ff1f6b..76e2626 100644
--- a/cli/header.cxx
+++ b/cli/header.cxx
@@ -5,6 +5,8 @@
#include "header.hxx"
+using namespace std;
+
namespace
{
//
@@ -308,6 +310,8 @@ namespace
void
generate_header (context& ctx)
{
+ ostream& os (ctx.os);
+
traversal::cli_unit unit;
includes includes (ctx);
traversal::names unit_names;
@@ -324,4 +328,31 @@ generate_header (context& ctx)
ns_names >> cl;
unit.dispatch (ctx.unit);
+
+ // Entire page usage.
+ //
+ if (ctx.usage != ut_none && ctx.options.page_usage_specified ())
+ {
+ os << "// Print page usage information." << endl
+ << "//" << endl;
+
+ const string& qn (ctx.options.page_usage ());
+ string n (ctx.escape (ctx.substitute (ctx.ns_open (qn, false))));
+
+ string const& ost (ctx.options.ostream_type ());
+
+ if (ctx.usage != ut_both)
+ os << "void" << endl
+ << n << "usage (" << ost << "&);"
+ << endl;
+ else
+ os << "void" << endl
+ << n << "short_usage (" << ost << "&);"
+ << endl
+ << "void" << endl
+ << n << "long_usage (" << ost << "&);"
+ << endl;
+
+ ctx.ns_close (qn, false);
+ }
}
diff --git a/cli/makefile b/cli/makefile
index 78e09b1..71ddd9c 100644
--- a/cli/makefile
+++ b/cli/makefile
@@ -65,8 +65,8 @@ genf := $(cli_tun:.cli=.hxx) $(cli_tun:.cli=.ixx) $(cli_tun:.cli=.cxx)
gen := $(addprefix $(out_base)/,$(genf))
$(gen): cli := $(out_root)/cli/cli
-$(gen): cli_options += --generate-file-scanner --guard-prefix CLI \
---reserved-name stdout
+$(gen): cli_options += --generate-file-scanner --generate-specifier \
+--guard-prefix CLI --reserved-name stdout
$(call include-dep,$(cxx_od),$(cxx_obj),$(gen))
diff --git a/cli/options.cli b/cli/options.cli
index 4972ba9..437f848 100644
--- a/cli/options.cli
+++ b/cli/options.cli
@@ -131,6 +131,30 @@ class options
even if the short version is provided."
};
+ std::string --page-usage
+ {
+ "<name>",
+ "Generate the combined usage printing code for the entire page.
+ Specifically, this will include all the namespace-level documentation as
+ well as usage for all the options classes printed in the order they are
+ defined in the main translation unit (documentation/classes from included
+ units are ignored except for base classes).
+
+ The <name> argument is used as a prefix to form the name of the usage
+ printing function. It can include the namespace qualification as well
+ as documentation variable expansion, for example:
+
+ \
+ --page-usage print_ # print_usage() in global namespace
+ --page-usage app::print_ # print_usage() in app namespace
+ --page-usage print_$name$_ # print_foo_usage() if name is foo
+ \
+
+ If both \cb{--long-usage} and \cb{--short-usage} options are specified,
+ then two functions are generated with the \cb{*short_usage()} and
+ \cb{*long_usage()} suffixes."
+ };
+
std::size_t --option-length = 0
{
"<len>",
diff --git a/cli/options.cxx b/cli/options.cxx
index d6b0e84..0ac1b4c 100644
--- a/cli/options.cxx
+++ b/cli/options.cxx
@@ -416,7 +416,7 @@ namespace cli
struct parser
{
static void
- parse (X& x, scanner& s)
+ parse (X& x, bool& xs, scanner& s)
{
std::string o (s.next ());
@@ -429,6 +429,8 @@ namespace cli
}
else
throw missing_value (o);
+
+ xs = true;
}
};
@@ -447,7 +449,7 @@ namespace cli
struct parser<std::string>
{
static void
- parse (std::string& x, scanner& s)
+ parse (std::string& x, bool& xs, scanner& s)
{
const char* o (s.next ());
@@ -455,6 +457,8 @@ namespace cli
x = s.next ();
else
throw missing_value (o);
+
+ xs = true;
}
};
@@ -462,11 +466,13 @@ namespace cli
struct parser<std::vector<X> >
{
static void
- parse (std::vector<X>& c, scanner& s)
+ parse (std::vector<X>& c, bool& xs, scanner& s)
{
X x;
- parser<X>::parse (x, s);
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
c.push_back (x);
+ xs = true;
}
};
@@ -474,11 +480,13 @@ namespace cli
struct parser<std::set<X> >
{
static void
- parse (std::set<X>& c, scanner& s)
+ parse (std::set<X>& c, bool& xs, scanner& s)
{
X x;
- parser<X>::parse (x, s);
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
c.insert (x);
+ xs = true;
}
};
@@ -486,7 +494,7 @@ namespace cli
struct parser<std::map<K, V> >
{
static void
- parse (std::map<K, V>& m, scanner& s)
+ parse (std::map<K, V>& m, bool& xs, scanner& s)
{
const char* o (s.next ());
@@ -506,24 +514,27 @@ namespace cli
const_cast<char*> (o), 0
};
+ bool dummy;
if (!kstr.empty ())
{
av[1] = const_cast<char*> (kstr.c_str ());
argv_scanner s (0, ac, av);
- parser<K>::parse (k, s);
+ parser<K>::parse (k, dummy, s);
}
if (!vstr.empty ())
{
av[1] = const_cast<char*> (vstr.c_str ());
argv_scanner s (0, ac, av);
- parser<V>::parse (v, s);
+ parser<V>::parse (v, dummy, s);
}
m[k] = v;
}
else
throw missing_value (o);
+
+ xs = true;
}
};
@@ -533,6 +544,13 @@ namespace cli
{
parser<T>::parse (x.*M, s);
}
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
+ }
}
#include <map>
@@ -546,7 +564,9 @@ options ()
: help_ (),
version_ (),
include_path_ (),
+ include_path_specified_ (false),
output_dir_ (),
+ output_dir_specified_ (false),
generate_modifier_ (),
generate_specifier_ (),
generate_parse_ (),
@@ -554,7 +574,9 @@ options ()
generate_file_scanner_ (),
suppress_inline_ (),
cli_namespace_ ("::cli"),
+ cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
+ ostream_type_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -563,43 +585,79 @@ options ()
suppress_usage_ (),
long_usage_ (),
short_usage_ (),
+ page_usage_ (),
+ page_usage_specified_ (false),
option_length_ (0),
+ option_length_specified_ (false),
ansi_color_ (),
exclude_base_ (),
class__ (),
+ class__specified_ (false),
docvar_ (),
+ docvar_specified_ (false),
hxx_prologue_ (),
+ hxx_prologue_specified_ (false),
ixx_prologue_ (),
+ ixx_prologue_specified_ (false),
cxx_prologue_ (),
+ cxx_prologue_specified_ (false),
man_prologue_ (),
+ man_prologue_specified_ (false),
html_prologue_ (),
+ html_prologue_specified_ (false),
hxx_epilogue_ (),
+ hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
+ ixx_epilogue_specified_ (false),
cxx_epilogue_ (),
+ cxx_epilogue_specified_ (false),
man_epilogue_ (),
+ man_epilogue_specified_ (false),
html_epilogue_ (),
+ html_epilogue_specified_ (false),
hxx_prologue_file_ (),
+ hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
+ ixx_prologue_file_specified_ (false),
cxx_prologue_file_ (),
+ cxx_prologue_file_specified_ (false),
man_prologue_file_ (),
+ man_prologue_file_specified_ (false),
html_prologue_file_ (),
+ html_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
+ hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
+ ixx_epilogue_file_specified_ (false),
cxx_epilogue_file_ (),
+ cxx_epilogue_file_specified_ (false),
man_epilogue_file_ (),
+ man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
+ html_epilogue_file_specified_ (false),
hxx_suffix_ (".hxx"),
+ hxx_suffix_specified_ (false),
ixx_suffix_ (".ixx"),
+ ixx_suffix_specified_ (false),
cxx_suffix_ (".cxx"),
+ cxx_suffix_specified_ (false),
man_suffix_ (".1"),
+ man_suffix_specified_ (false),
html_suffix_ (".html"),
+ html_suffix_specified_ (false),
option_prefix_ ("-"),
+ option_prefix_specified_ (false),
option_separator_ ("--"),
+ option_separator_specified_ (false),
include_with_brackets_ (),
include_prefix_ (),
+ include_prefix_specified_ (false),
guard_prefix_ (),
+ guard_prefix_specified_ (false),
reserved_name_ (),
- options_file_ ()
+ reserved_name_specified_ (false),
+ options_file_ (),
+ options_file_specified_ (false)
{
}
@@ -612,7 +670,9 @@ options (int& argc,
: help_ (),
version_ (),
include_path_ (),
+ include_path_specified_ (false),
output_dir_ (),
+ output_dir_specified_ (false),
generate_modifier_ (),
generate_specifier_ (),
generate_parse_ (),
@@ -620,7 +680,9 @@ options (int& argc,
generate_file_scanner_ (),
suppress_inline_ (),
cli_namespace_ ("::cli"),
+ cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
+ ostream_type_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -629,43 +691,79 @@ options (int& argc,
suppress_usage_ (),
long_usage_ (),
short_usage_ (),
+ page_usage_ (),
+ page_usage_specified_ (false),
option_length_ (0),
+ option_length_specified_ (false),
ansi_color_ (),
exclude_base_ (),
class__ (),
+ class__specified_ (false),
docvar_ (),
+ docvar_specified_ (false),
hxx_prologue_ (),
+ hxx_prologue_specified_ (false),
ixx_prologue_ (),
+ ixx_prologue_specified_ (false),
cxx_prologue_ (),
+ cxx_prologue_specified_ (false),
man_prologue_ (),
+ man_prologue_specified_ (false),
html_prologue_ (),
+ html_prologue_specified_ (false),
hxx_epilogue_ (),
+ hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
+ ixx_epilogue_specified_ (false),
cxx_epilogue_ (),
+ cxx_epilogue_specified_ (false),
man_epilogue_ (),
+ man_epilogue_specified_ (false),
html_epilogue_ (),
+ html_epilogue_specified_ (false),
hxx_prologue_file_ (),
+ hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
+ ixx_prologue_file_specified_ (false),
cxx_prologue_file_ (),
+ cxx_prologue_file_specified_ (false),
man_prologue_file_ (),
+ man_prologue_file_specified_ (false),
html_prologue_file_ (),
+ html_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
+ hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
+ ixx_epilogue_file_specified_ (false),
cxx_epilogue_file_ (),
+ cxx_epilogue_file_specified_ (false),
man_epilogue_file_ (),
+ man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
+ html_epilogue_file_specified_ (false),
hxx_suffix_ (".hxx"),
+ hxx_suffix_specified_ (false),
ixx_suffix_ (".ixx"),
+ ixx_suffix_specified_ (false),
cxx_suffix_ (".cxx"),
+ cxx_suffix_specified_ (false),
man_suffix_ (".1"),
+ man_suffix_specified_ (false),
html_suffix_ (".html"),
+ html_suffix_specified_ (false),
option_prefix_ ("-"),
+ option_prefix_specified_ (false),
option_separator_ ("--"),
+ option_separator_specified_ (false),
include_with_brackets_ (),
include_prefix_ (),
+ include_prefix_specified_ (false),
guard_prefix_ (),
+ guard_prefix_specified_ (false),
reserved_name_ (),
- options_file_ ()
+ reserved_name_specified_ (false),
+ options_file_ (),
+ options_file_specified_ (false)
{
::cli::argv_scanner s (argc, argv, erase);
_parse (s, opt, arg);
@@ -681,7 +779,9 @@ options (int start,
: help_ (),
version_ (),
include_path_ (),
+ include_path_specified_ (false),
output_dir_ (),
+ output_dir_specified_ (false),
generate_modifier_ (),
generate_specifier_ (),
generate_parse_ (),
@@ -689,7 +789,9 @@ options (int start,
generate_file_scanner_ (),
suppress_inline_ (),
cli_namespace_ ("::cli"),
+ cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
+ ostream_type_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -698,43 +800,79 @@ options (int start,
suppress_usage_ (),
long_usage_ (),
short_usage_ (),
+ page_usage_ (),
+ page_usage_specified_ (false),
option_length_ (0),
+ option_length_specified_ (false),
ansi_color_ (),
exclude_base_ (),
class__ (),
+ class__specified_ (false),
docvar_ (),
+ docvar_specified_ (false),
hxx_prologue_ (),
+ hxx_prologue_specified_ (false),
ixx_prologue_ (),
+ ixx_prologue_specified_ (false),
cxx_prologue_ (),
+ cxx_prologue_specified_ (false),
man_prologue_ (),
+ man_prologue_specified_ (false),
html_prologue_ (),
+ html_prologue_specified_ (false),
hxx_epilogue_ (),
+ hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
+ ixx_epilogue_specified_ (false),
cxx_epilogue_ (),
+ cxx_epilogue_specified_ (false),
man_epilogue_ (),
+ man_epilogue_specified_ (false),
html_epilogue_ (),
+ html_epilogue_specified_ (false),
hxx_prologue_file_ (),
+ hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
+ ixx_prologue_file_specified_ (false),
cxx_prologue_file_ (),
+ cxx_prologue_file_specified_ (false),
man_prologue_file_ (),
+ man_prologue_file_specified_ (false),
html_prologue_file_ (),
+ html_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
+ hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
+ ixx_epilogue_file_specified_ (false),
cxx_epilogue_file_ (),
+ cxx_epilogue_file_specified_ (false),
man_epilogue_file_ (),
+ man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
+ html_epilogue_file_specified_ (false),
hxx_suffix_ (".hxx"),
+ hxx_suffix_specified_ (false),
ixx_suffix_ (".ixx"),
+ ixx_suffix_specified_ (false),
cxx_suffix_ (".cxx"),
+ cxx_suffix_specified_ (false),
man_suffix_ (".1"),
+ man_suffix_specified_ (false),
html_suffix_ (".html"),
+ html_suffix_specified_ (false),
option_prefix_ ("-"),
+ option_prefix_specified_ (false),
option_separator_ ("--"),
+ option_separator_specified_ (false),
include_with_brackets_ (),
include_prefix_ (),
+ include_prefix_specified_ (false),
guard_prefix_ (),
+ guard_prefix_specified_ (false),
reserved_name_ (),
- options_file_ ()
+ reserved_name_specified_ (false),
+ options_file_ (),
+ options_file_specified_ (false)
{
::cli::argv_scanner s (start, argc, argv, erase);
_parse (s, opt, arg);
@@ -750,7 +888,9 @@ options (int& argc,
: help_ (),
version_ (),
include_path_ (),
+ include_path_specified_ (false),
output_dir_ (),
+ output_dir_specified_ (false),
generate_modifier_ (),
generate_specifier_ (),
generate_parse_ (),
@@ -758,7 +898,9 @@ options (int& argc,
generate_file_scanner_ (),
suppress_inline_ (),
cli_namespace_ ("::cli"),
+ cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
+ ostream_type_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -767,43 +909,79 @@ options (int& argc,
suppress_usage_ (),
long_usage_ (),
short_usage_ (),
+ page_usage_ (),
+ page_usage_specified_ (false),
option_length_ (0),
+ option_length_specified_ (false),
ansi_color_ (),
exclude_base_ (),
class__ (),
+ class__specified_ (false),
docvar_ (),
+ docvar_specified_ (false),
hxx_prologue_ (),
+ hxx_prologue_specified_ (false),
ixx_prologue_ (),
+ ixx_prologue_specified_ (false),
cxx_prologue_ (),
+ cxx_prologue_specified_ (false),
man_prologue_ (),
+ man_prologue_specified_ (false),
html_prologue_ (),
+ html_prologue_specified_ (false),
hxx_epilogue_ (),
+ hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
+ ixx_epilogue_specified_ (false),
cxx_epilogue_ (),
+ cxx_epilogue_specified_ (false),
man_epilogue_ (),
+ man_epilogue_specified_ (false),
html_epilogue_ (),
+ html_epilogue_specified_ (false),
hxx_prologue_file_ (),
+ hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
+ ixx_prologue_file_specified_ (false),
cxx_prologue_file_ (),
+ cxx_prologue_file_specified_ (false),
man_prologue_file_ (),
+ man_prologue_file_specified_ (false),
html_prologue_file_ (),
+ html_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
+ hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
+ ixx_epilogue_file_specified_ (false),
cxx_epilogue_file_ (),
+ cxx_epilogue_file_specified_ (false),
man_epilogue_file_ (),
+ man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
+ html_epilogue_file_specified_ (false),
hxx_suffix_ (".hxx"),
+ hxx_suffix_specified_ (false),
ixx_suffix_ (".ixx"),
+ ixx_suffix_specified_ (false),
cxx_suffix_ (".cxx"),
+ cxx_suffix_specified_ (false),
man_suffix_ (".1"),
+ man_suffix_specified_ (false),
html_suffix_ (".html"),
+ html_suffix_specified_ (false),
option_prefix_ ("-"),
+ option_prefix_specified_ (false),
option_separator_ ("--"),
+ option_separator_specified_ (false),
include_with_brackets_ (),
include_prefix_ (),
+ include_prefix_specified_ (false),
guard_prefix_ (),
+ guard_prefix_specified_ (false),
reserved_name_ (),
- options_file_ ()
+ reserved_name_specified_ (false),
+ options_file_ (),
+ options_file_specified_ (false)
{
::cli::argv_scanner s (argc, argv, erase);
_parse (s, opt, arg);
@@ -821,7 +999,9 @@ options (int start,
: help_ (),
version_ (),
include_path_ (),
+ include_path_specified_ (false),
output_dir_ (),
+ output_dir_specified_ (false),
generate_modifier_ (),
generate_specifier_ (),
generate_parse_ (),
@@ -829,7 +1009,9 @@ options (int start,
generate_file_scanner_ (),
suppress_inline_ (),
cli_namespace_ ("::cli"),
+ cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
+ ostream_type_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -838,43 +1020,79 @@ options (int start,
suppress_usage_ (),
long_usage_ (),
short_usage_ (),
+ page_usage_ (),
+ page_usage_specified_ (false),
option_length_ (0),
+ option_length_specified_ (false),
ansi_color_ (),
exclude_base_ (),
class__ (),
+ class__specified_ (false),
docvar_ (),
+ docvar_specified_ (false),
hxx_prologue_ (),
+ hxx_prologue_specified_ (false),
ixx_prologue_ (),
+ ixx_prologue_specified_ (false),
cxx_prologue_ (),
+ cxx_prologue_specified_ (false),
man_prologue_ (),
+ man_prologue_specified_ (false),
html_prologue_ (),
+ html_prologue_specified_ (false),
hxx_epilogue_ (),
+ hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
+ ixx_epilogue_specified_ (false),
cxx_epilogue_ (),
+ cxx_epilogue_specified_ (false),
man_epilogue_ (),
+ man_epilogue_specified_ (false),
html_epilogue_ (),
+ html_epilogue_specified_ (false),
hxx_prologue_file_ (),
+ hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
+ ixx_prologue_file_specified_ (false),
cxx_prologue_file_ (),
+ cxx_prologue_file_specified_ (false),
man_prologue_file_ (),
+ man_prologue_file_specified_ (false),
html_prologue_file_ (),
+ html_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
+ hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
+ ixx_epilogue_file_specified_ (false),
cxx_epilogue_file_ (),
+ cxx_epilogue_file_specified_ (false),
man_epilogue_file_ (),
+ man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
+ html_epilogue_file_specified_ (false),
hxx_suffix_ (".hxx"),
+ hxx_suffix_specified_ (false),
ixx_suffix_ (".ixx"),
+ ixx_suffix_specified_ (false),
cxx_suffix_ (".cxx"),
+ cxx_suffix_specified_ (false),
man_suffix_ (".1"),
+ man_suffix_specified_ (false),
html_suffix_ (".html"),
+ html_suffix_specified_ (false),
option_prefix_ ("-"),
+ option_prefix_specified_ (false),
option_separator_ ("--"),
+ option_separator_specified_ (false),
include_with_brackets_ (),
include_prefix_ (),
+ include_prefix_specified_ (false),
guard_prefix_ (),
+ guard_prefix_specified_ (false),
reserved_name_ (),
- options_file_ ()
+ reserved_name_specified_ (false),
+ options_file_ (),
+ options_file_specified_ (false)
{
::cli::argv_scanner s (start, argc, argv, erase);
_parse (s, opt, arg);
@@ -888,7 +1106,9 @@ options (::cli::scanner& s,
: help_ (),
version_ (),
include_path_ (),
+ include_path_specified_ (false),
output_dir_ (),
+ output_dir_specified_ (false),
generate_modifier_ (),
generate_specifier_ (),
generate_parse_ (),
@@ -896,7 +1116,9 @@ options (::cli::scanner& s,
generate_file_scanner_ (),
suppress_inline_ (),
cli_namespace_ ("::cli"),
+ cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
+ ostream_type_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -905,43 +1127,79 @@ options (::cli::scanner& s,
suppress_usage_ (),
long_usage_ (),
short_usage_ (),
+ page_usage_ (),
+ page_usage_specified_ (false),
option_length_ (0),
+ option_length_specified_ (false),
ansi_color_ (),
exclude_base_ (),
class__ (),
+ class__specified_ (false),
docvar_ (),
+ docvar_specified_ (false),
hxx_prologue_ (),
+ hxx_prologue_specified_ (false),
ixx_prologue_ (),
+ ixx_prologue_specified_ (false),
cxx_prologue_ (),
+ cxx_prologue_specified_ (false),
man_prologue_ (),
+ man_prologue_specified_ (false),
html_prologue_ (),
+ html_prologue_specified_ (false),
hxx_epilogue_ (),
+ hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
+ ixx_epilogue_specified_ (false),
cxx_epilogue_ (),
+ cxx_epilogue_specified_ (false),
man_epilogue_ (),
+ man_epilogue_specified_ (false),
html_epilogue_ (),
+ html_epilogue_specified_ (false),
hxx_prologue_file_ (),
+ hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
+ ixx_prologue_file_specified_ (false),
cxx_prologue_file_ (),
+ cxx_prologue_file_specified_ (false),
man_prologue_file_ (),
+ man_prologue_file_specified_ (false),
html_prologue_file_ (),
+ html_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
+ hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
+ ixx_epilogue_file_specified_ (false),
cxx_epilogue_file_ (),
+ cxx_epilogue_file_specified_ (false),
man_epilogue_file_ (),
+ man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
+ html_epilogue_file_specified_ (false),
hxx_suffix_ (".hxx"),
+ hxx_suffix_specified_ (false),
ixx_suffix_ (".ixx"),
+ ixx_suffix_specified_ (false),
cxx_suffix_ (".cxx"),
+ cxx_suffix_specified_ (false),
man_suffix_ (".1"),
+ man_suffix_specified_ (false),
html_suffix_ (".html"),
+ html_suffix_specified_ (false),
option_prefix_ ("-"),
+ option_prefix_specified_ (false),
option_separator_ ("--"),
+ option_separator_specified_ (false),
include_with_brackets_ (),
include_prefix_ (),
+ include_prefix_specified_ (false),
guard_prefix_ (),
+ guard_prefix_specified_ (false),
reserved_name_ (),
- options_file_ ()
+ reserved_name_specified_ (false),
+ options_file_ (),
+ options_file_specified_ (false)
{
_parse (s, opt, arg);
}
@@ -1002,6 +1260,9 @@ print_usage (::std::ostream& os)
os << "--short-usage If specified together with '--long-usage'," << ::std::endl
<< " generate both short and long usage versions." << ::std::endl;
+ os << "--page-usage <name> Generate the combined usage printing code for the" << ::std::endl
+ << " entire page." << ::std::endl;
+
os << "--option-length <len> Indent option descriptions <len> characters when" << ::std::endl
<< " printing usage." << ::std::endl;
@@ -1131,13 +1392,17 @@ struct _cli_options_map_init
_cli_options_map_["--version"] =
&::cli::thunk< options, bool, &options::version_ >;
_cli_options_map_["--include-path"] =
- &::cli::thunk< options, std::vector<std::string>, &options::include_path_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::include_path_,
+ &options::include_path_specified_ >;
_cli_options_map_["-I"] =
- &::cli::thunk< options, std::vector<std::string>, &options::include_path_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::include_path_,
+ &options::include_path_specified_ >;
_cli_options_map_["--output-dir"] =
- &::cli::thunk< options, std::string, &options::output_dir_ >;
+ &::cli::thunk< options, std::string, &options::output_dir_,
+ &options::output_dir_specified_ >;
_cli_options_map_["-o"] =
- &::cli::thunk< options, std::string, &options::output_dir_ >;
+ &::cli::thunk< options, std::string, &options::output_dir_,
+ &options::output_dir_specified_ >;
_cli_options_map_["--generate-modifier"] =
&::cli::thunk< options, bool, &options::generate_modifier_ >;
_cli_options_map_["--generate-specifier"] =
@@ -1151,9 +1416,11 @@ struct _cli_options_map_init
_cli_options_map_["--suppress-inline"] =
&::cli::thunk< options, bool, &options::suppress_inline_ >;
_cli_options_map_["--cli-namespace"] =
- &::cli::thunk< options, std::string, &options::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_ >;
+ &::cli::thunk< options, std::string, &options::ostream_type_,
+ &options::ostream_type_specified_ >;
_cli_options_map_["--generate-cxx"] =
&::cli::thunk< options, bool, &options::generate_cxx_ >;
_cli_options_map_["--generate-man"] =
@@ -1170,82 +1437,120 @@ struct _cli_options_map_init
&::cli::thunk< options, bool, &options::long_usage_ >;
_cli_options_map_["--short-usage"] =
&::cli::thunk< options, bool, &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_ >;
+ &::cli::thunk< options, std::size_t, &options::option_length_,
+ &options::option_length_specified_ >;
_cli_options_map_["--ansi-color"] =
&::cli::thunk< options, bool, &options::ansi_color_ >;
_cli_options_map_["--exclude-base"] =
&::cli::thunk< options, bool, &options::exclude_base_ >;
_cli_options_map_["--class"] =
- &::cli::thunk< options, std::vector<std::string>, &options::class__ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::class__,
+ &options::class__specified_ >;
_cli_options_map_["--docvar"] =
- &::cli::thunk< options, std::map<std::string, std::string>, &options::docvar_ >;
+ &::cli::thunk< options, std::map<std::string, std::string>, &options::docvar_,
+ &options::docvar_specified_ >;
_cli_options_map_["-v"] =
- &::cli::thunk< options, std::map<std::string, std::string>, &options::docvar_ >;
+ &::cli::thunk< options, std::map<std::string, std::string>, &options::docvar_,
+ &options::docvar_specified_ >;
_cli_options_map_["--hxx-prologue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::hxx_prologue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::hxx_prologue_,
+ &options::hxx_prologue_specified_ >;
_cli_options_map_["--ixx-prologue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::ixx_prologue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::ixx_prologue_,
+ &options::ixx_prologue_specified_ >;
_cli_options_map_["--cxx-prologue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::cxx_prologue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::cxx_prologue_,
+ &options::cxx_prologue_specified_ >;
_cli_options_map_["--man-prologue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::man_prologue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::man_prologue_,
+ &options::man_prologue_specified_ >;
_cli_options_map_["--html-prologue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::html_prologue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::html_prologue_,
+ &options::html_prologue_specified_ >;
_cli_options_map_["--hxx-epilogue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::hxx_epilogue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::hxx_epilogue_,
+ &options::hxx_epilogue_specified_ >;
_cli_options_map_["--ixx-epilogue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::ixx_epilogue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::ixx_epilogue_,
+ &options::ixx_epilogue_specified_ >;
_cli_options_map_["--cxx-epilogue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::cxx_epilogue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::cxx_epilogue_,
+ &options::cxx_epilogue_specified_ >;
_cli_options_map_["--man-epilogue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::man_epilogue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::man_epilogue_,
+ &options::man_epilogue_specified_ >;
_cli_options_map_["--html-epilogue"] =
- &::cli::thunk< options, std::vector<std::string>, &options::html_epilogue_ >;
+ &::cli::thunk< options, std::vector<std::string>, &options::html_epilogue_,
+ &options::html_epilogue_specified_ >;
_cli_options_map_["--hxx-prologue-file"] =
- &::cli::thunk< options, std::string, &options::hxx_prologue_file_ >;
+ &::cli::thunk< options, std::string, &options::hxx_prologue_file_,
+ &options::hxx_prologue_file_specified_ >;
_cli_options_map_["--ixx-prologue-file"] =
- &::cli::thunk< options, std::string, &options::ixx_prologue_file_ >;
+ &::cli::thunk< options, std::string, &options::ixx_prologue_file_,
+ &options::ixx_prologue_file_specified_ >;
_cli_options_map_["--cxx-prologue-file"] =
- &::cli::thunk< options, std::string, &options::cxx_prologue_file_ >;
+ &::cli::thunk< options, std::string, &options::cxx_prologue_file_,
+ &options::cxx_prologue_file_specified_ >;
_cli_options_map_["--man-prologue-file"] =
- &::cli::thunk< options, std::string, &options::man_prologue_file_ >;
+ &::cli::thunk< options, std::string, &options::man_prologue_file_,
+ &options::man_prologue_file_specified_ >;
_cli_options_map_["--html-prologue-file"] =
- &::cli::thunk< options, std::string, &options::html_prologue_file_ >;
+ &::cli::thunk< options, std::string, &options::html_prologue_file_,
+ &options::html_prologue_file_specified_ >;
_cli_options_map_["--hxx-epilogue-file"] =
- &::cli::thunk< options, std::string, &options::hxx_epilogue_file_ >;
+ &::cli::thunk< options, std::string, &options::hxx_epilogue_file_,
+ &options::hxx_epilogue_file_specified_ >;
_cli_options_map_["--ixx-epilogue-file"] =
- &::cli::thunk< options, std::string, &options::ixx_epilogue_file_ >;
+ &::cli::thunk< options, std::string, &options::ixx_epilogue_file_,
+ &options::ixx_epilogue_file_specified_ >;
_cli_options_map_["--cxx-epilogue-file"] =
- &::cli::thunk< options, std::string, &options::cxx_epilogue_file_ >;
+ &::cli::thunk< options, std::string, &options::cxx_epilogue_file_,
+ &options::cxx_epilogue_file_specified_ >;
_cli_options_map_["--man-epilogue-file"] =
- &::cli::thunk< options, std::string, &options::man_epilogue_file_ >;
+ &::cli::thunk< options, std::string, &options::man_epilogue_file_,
+ &options::man_epilogue_file_specified_ >;
_cli_options_map_["--html-epilogue-file"] =
- &::cli::thunk< options, std::string, &options::html_epilogue_file_ >;
+ &::cli::thunk< options, std::string, &options::html_epilogue_file_,
+ &options::html_epilogue_file_specified_ >;
_cli_options_map_["--hxx-suffix"] =
- &::cli::thunk< options, std::string, &options::hxx_suffix_ >;
+ &::cli::thunk< options, std::string, &options::hxx_suffix_,
+ &options::hxx_suffix_specified_ >;
_cli_options_map_["--ixx-suffix"] =
- &::cli::thunk< options, std::string, &options::ixx_suffix_ >;
+ &::cli::thunk< options, std::string, &options::ixx_suffix_,
+ &options::ixx_suffix_specified_ >;
_cli_options_map_["--cxx-suffix"] =
- &::cli::thunk< options, std::string, &options::cxx_suffix_ >;
+ &::cli::thunk< options, std::string, &options::cxx_suffix_,
+ &options::cxx_suffix_specified_ >;
_cli_options_map_["--man-suffix"] =
- &::cli::thunk< options, std::string, &options::man_suffix_ >;
+ &::cli::thunk< options, std::string, &options::man_suffix_,
+ &options::man_suffix_specified_ >;
_cli_options_map_["--html-suffix"] =
- &::cli::thunk< options, std::string, &options::html_suffix_ >;
+ &::cli::thunk< options, std::string, &options::html_suffix_,
+ &options::html_suffix_specified_ >;
_cli_options_map_["--option-prefix"] =
- &::cli::thunk< options, std::string, &options::option_prefix_ >;
+ &::cli::thunk< options, std::string, &options::option_prefix_,
+ &options::option_prefix_specified_ >;
_cli_options_map_["--option-separator"] =
- &::cli::thunk< options, std::string, &options::option_separator_ >;
+ &::cli::thunk< options, std::string, &options::option_separator_,
+ &options::option_separator_specified_ >;
_cli_options_map_["--include-with-brackets"] =
&::cli::thunk< options, bool, &options::include_with_brackets_ >;
_cli_options_map_["--include-prefix"] =
- &::cli::thunk< options, std::string, &options::include_prefix_ >;
+ &::cli::thunk< options, std::string, &options::include_prefix_,
+ &options::include_prefix_specified_ >;
_cli_options_map_["--guard-prefix"] =
- &::cli::thunk< options, std::string, &options::guard_prefix_ >;
+ &::cli::thunk< options, std::string, &options::guard_prefix_,
+ &options::guard_prefix_specified_ >;
_cli_options_map_["--reserved-name"] =
- &::cli::thunk< options, std::map<std::string, std::string>, &options::reserved_name_ >;
+ &::cli::thunk< options, std::map<std::string, std::string>, &options::reserved_name_,
+ &options::reserved_name_specified_ >;
_cli_options_map_["--options-file"] =
- &::cli::thunk< options, std::string, &options::options_file_ >;
+ &::cli::thunk< options, std::string, &options::options_file_,
+ &options::options_file_specified_ >;
}
};
diff --git a/cli/options.hxx b/cli/options.hxx
index 933a41a..020ff40 100644
--- a/cli/options.hxx
+++ b/cli/options.hxx
@@ -371,9 +371,15 @@ class options
const std::vector<std::string>&
include_path () const;
+ bool
+ include_path_specified () const;
+
const std::string&
output_dir () const;
+ bool
+ output_dir_specified () const;
+
const bool&
generate_modifier () const;
@@ -395,9 +401,15 @@ class options
const std::string&
cli_namespace () const;
+ bool
+ cli_namespace_specified () const;
+
const std::string&
ostream_type () const;
+ bool
+ ostream_type_specified () const;
+
const bool&
generate_cxx () const;
@@ -422,9 +434,18 @@ class options
const bool&
short_usage () const;
+ const std::string&
+ page_usage () const;
+
+ bool
+ page_usage_specified () const;
+
const std::size_t&
option_length () const;
+ bool
+ option_length_specified () const;
+
const bool&
ansi_color () const;
@@ -434,105 +455,204 @@ class options
const std::vector<std::string>&
class_ () const;
+ bool
+ class__specified () const;
+
const std::map<std::string, std::string>&
docvar () const;
+ bool
+ docvar_specified () const;
+
const std::vector<std::string>&
hxx_prologue () const;
+ bool
+ hxx_prologue_specified () const;
+
const std::vector<std::string>&
ixx_prologue () const;
+ bool
+ ixx_prologue_specified () const;
+
const std::vector<std::string>&
cxx_prologue () const;
+ bool
+ cxx_prologue_specified () const;
+
const std::vector<std::string>&
man_prologue () const;
+ bool
+ man_prologue_specified () const;
+
const std::vector<std::string>&
html_prologue () const;
+ bool
+ html_prologue_specified () const;
+
const std::vector<std::string>&
hxx_epilogue () const;
+ bool
+ hxx_epilogue_specified () const;
+
const std::vector<std::string>&
ixx_epilogue () const;
+ bool
+ ixx_epilogue_specified () const;
+
const std::vector<std::string>&
cxx_epilogue () const;
+ bool
+ cxx_epilogue_specified () const;
+
const std::vector<std::string>&
man_epilogue () const;
+ bool
+ man_epilogue_specified () const;
+
const std::vector<std::string>&
html_epilogue () const;
+ bool
+ html_epilogue_specified () const;
+
const std::string&
hxx_prologue_file () const;
+ bool
+ hxx_prologue_file_specified () const;
+
const std::string&
ixx_prologue_file () const;
+ bool
+ ixx_prologue_file_specified () const;
+
const std::string&
cxx_prologue_file () const;
+ bool
+ cxx_prologue_file_specified () const;
+
const std::string&
man_prologue_file () const;
+ bool
+ man_prologue_file_specified () const;
+
const std::string&
html_prologue_file () const;
+ bool
+ html_prologue_file_specified () const;
+
const std::string&
hxx_epilogue_file () const;
+ bool
+ hxx_epilogue_file_specified () const;
+
const std::string&
ixx_epilogue_file () const;
+ bool
+ ixx_epilogue_file_specified () const;
+
const std::string&
cxx_epilogue_file () const;
+ bool
+ cxx_epilogue_file_specified () const;
+
const std::string&
man_epilogue_file () const;
+ bool
+ man_epilogue_file_specified () const;
+
const std::string&
html_epilogue_file () const;
+ bool
+ html_epilogue_file_specified () const;
+
const std::string&
hxx_suffix () const;
+ bool
+ hxx_suffix_specified () const;
+
const std::string&
ixx_suffix () const;
+ bool
+ ixx_suffix_specified () const;
+
const std::string&
cxx_suffix () const;
+ bool
+ cxx_suffix_specified () const;
+
const std::string&
man_suffix () const;
+ bool
+ man_suffix_specified () const;
+
const std::string&
html_suffix () const;
+ bool
+ html_suffix_specified () const;
+
const std::string&
option_prefix () const;
+ bool
+ option_prefix_specified () const;
+
const std::string&
option_separator () const;
+ bool
+ option_separator_specified () const;
+
const bool&
include_with_brackets () const;
const std::string&
include_prefix () const;
+ bool
+ include_prefix_specified () const;
+
const std::string&
guard_prefix () const;
+ bool
+ guard_prefix_specified () const;
+
const std::map<std::string, std::string>&
reserved_name () const;
+ bool
+ reserved_name_specified () const;
+
const std::string&
options_file () const;
+ bool
+ options_file_specified () const;
+
// Print usage information.
//
static void
@@ -554,7 +674,9 @@ class options
bool help_;
bool version_;
std::vector<std::string> include_path_;
+ bool include_path_specified_;
std::string output_dir_;
+ bool output_dir_specified_;
bool generate_modifier_;
bool generate_specifier_;
bool generate_parse_;
@@ -562,7 +684,9 @@ class options
bool generate_file_scanner_;
bool suppress_inline_;
std::string cli_namespace_;
+ bool cli_namespace_specified_;
std::string ostream_type_;
+ bool ostream_type_specified_;
bool generate_cxx_;
bool generate_man_;
bool generate_html_;
@@ -571,43 +695,79 @@ class options
bool suppress_usage_;
bool long_usage_;
bool short_usage_;
+ std::string page_usage_;
+ bool page_usage_specified_;
std::size_t option_length_;
+ bool option_length_specified_;
bool ansi_color_;
bool exclude_base_;
std::vector<std::string> class__;
+ bool class__specified_;
std::map<std::string, std::string> docvar_;
+ bool docvar_specified_;
std::vector<std::string> hxx_prologue_;
+ bool hxx_prologue_specified_;
std::vector<std::string> ixx_prologue_;
+ bool ixx_prologue_specified_;
std::vector<std::string> cxx_prologue_;
+ bool cxx_prologue_specified_;
std::vector<std::string> man_prologue_;
+ bool man_prologue_specified_;
std::vector<std::string> html_prologue_;
+ bool html_prologue_specified_;
std::vector<std::string> hxx_epilogue_;
+ bool hxx_epilogue_specified_;
std::vector<std::string> ixx_epilogue_;
+ bool ixx_epilogue_specified_;
std::vector<std::string> cxx_epilogue_;
+ bool cxx_epilogue_specified_;
std::vector<std::string> man_epilogue_;
+ bool man_epilogue_specified_;
std::vector<std::string> html_epilogue_;
+ bool html_epilogue_specified_;
std::string hxx_prologue_file_;
+ bool hxx_prologue_file_specified_;
std::string ixx_prologue_file_;
+ bool ixx_prologue_file_specified_;
std::string cxx_prologue_file_;
+ bool cxx_prologue_file_specified_;
std::string man_prologue_file_;
+ bool man_prologue_file_specified_;
std::string html_prologue_file_;
+ bool html_prologue_file_specified_;
std::string hxx_epilogue_file_;
+ bool hxx_epilogue_file_specified_;
std::string ixx_epilogue_file_;
+ bool ixx_epilogue_file_specified_;
std::string cxx_epilogue_file_;
+ bool cxx_epilogue_file_specified_;
std::string man_epilogue_file_;
+ bool man_epilogue_file_specified_;
std::string html_epilogue_file_;
+ bool html_epilogue_file_specified_;
std::string hxx_suffix_;
+ bool hxx_suffix_specified_;
std::string ixx_suffix_;
+ bool ixx_suffix_specified_;
std::string cxx_suffix_;
+ bool cxx_suffix_specified_;
std::string man_suffix_;
+ bool man_suffix_specified_;
std::string html_suffix_;
+ bool html_suffix_specified_;
std::string option_prefix_;
+ bool option_prefix_specified_;
std::string option_separator_;
+ bool option_separator_specified_;
bool include_with_brackets_;
std::string include_prefix_;
+ bool include_prefix_specified_;
std::string guard_prefix_;
+ bool guard_prefix_specified_;
std::map<std::string, std::string> reserved_name_;
+ bool reserved_name_specified_;
std::string options_file_;
+ bool options_file_specified_;
};
#include "options.ixx"
diff --git a/cli/options.ixx b/cli/options.ixx
index c4a3220..447fe18 100644
--- a/cli/options.ixx
+++ b/cli/options.ixx
@@ -221,12 +221,24 @@ include_path () const
return this->include_path_;
}
+inline bool options::
+include_path_specified () const
+{
+ return this->include_path_specified_;
+}
+
inline const std::string& options::
output_dir () const
{
return this->output_dir_;
}
+inline bool options::
+output_dir_specified () const
+{
+ return this->output_dir_specified_;
+}
+
inline const bool& options::
generate_modifier () const
{
@@ -269,12 +281,24 @@ cli_namespace () const
return this->cli_namespace_;
}
+inline bool options::
+cli_namespace_specified () const
+{
+ return this->cli_namespace_specified_;
+}
+
inline const std::string& options::
ostream_type () const
{
return this->ostream_type_;
}
+inline bool options::
+ostream_type_specified () const
+{
+ return this->ostream_type_specified_;
+}
+
inline const bool& options::
generate_cxx () const
{
@@ -323,12 +347,30 @@ short_usage () const
return this->short_usage_;
}
+inline const std::string& options::
+page_usage () const
+{
+ return this->page_usage_;
+}
+
+inline bool options::
+page_usage_specified () const
+{
+ return this->page_usage_specified_;
+}
+
inline const std::size_t& options::
option_length () const
{
return this->option_length_;
}
+inline bool options::
+option_length_specified () const
+{
+ return this->option_length_specified_;
+}
+
inline const bool& options::
ansi_color () const
{
@@ -347,174 +389,348 @@ class_ () const
return this->class__;
}
+inline bool options::
+class__specified () const
+{
+ return this->class__specified_;
+}
+
inline const std::map<std::string, std::string>& options::
docvar () const
{
return this->docvar_;
}
+inline bool options::
+docvar_specified () const
+{
+ return this->docvar_specified_;
+}
+
inline const std::vector<std::string>& options::
hxx_prologue () const
{
return this->hxx_prologue_;
}
+inline bool options::
+hxx_prologue_specified () const
+{
+ return this->hxx_prologue_specified_;
+}
+
inline const std::vector<std::string>& options::
ixx_prologue () const
{
return this->ixx_prologue_;
}
+inline bool options::
+ixx_prologue_specified () const
+{
+ return this->ixx_prologue_specified_;
+}
+
inline const std::vector<std::string>& options::
cxx_prologue () const
{
return this->cxx_prologue_;
}
+inline bool options::
+cxx_prologue_specified () const
+{
+ return this->cxx_prologue_specified_;
+}
+
inline const std::vector<std::string>& options::
man_prologue () const
{
return this->man_prologue_;
}
+inline bool options::
+man_prologue_specified () const
+{
+ return this->man_prologue_specified_;
+}
+
inline const std::vector<std::string>& options::
html_prologue () const
{
return this->html_prologue_;
}
+inline bool options::
+html_prologue_specified () const
+{
+ return this->html_prologue_specified_;
+}
+
inline const std::vector<std::string>& options::
hxx_epilogue () const
{
return this->hxx_epilogue_;
}
+inline bool options::
+hxx_epilogue_specified () const
+{
+ return this->hxx_epilogue_specified_;
+}
+
inline const std::vector<std::string>& options::
ixx_epilogue () const
{
return this->ixx_epilogue_;
}
+inline bool options::
+ixx_epilogue_specified () const
+{
+ return this->ixx_epilogue_specified_;
+}
+
inline const std::vector<std::string>& options::
cxx_epilogue () const
{
return this->cxx_epilogue_;
}
+inline bool options::
+cxx_epilogue_specified () const
+{
+ return this->cxx_epilogue_specified_;
+}
+
inline const std::vector<std::string>& options::
man_epilogue () const
{
return this->man_epilogue_;
}
+inline bool options::
+man_epilogue_specified () const
+{
+ return this->man_epilogue_specified_;
+}
+
inline const std::vector<std::string>& options::
html_epilogue () const
{
return this->html_epilogue_;
}
+inline bool options::
+html_epilogue_specified () const
+{
+ return this->html_epilogue_specified_;
+}
+
inline const std::string& options::
hxx_prologue_file () const
{
return this->hxx_prologue_file_;
}
+inline bool options::
+hxx_prologue_file_specified () const
+{
+ return this->hxx_prologue_file_specified_;
+}
+
inline const std::string& options::
ixx_prologue_file () const
{
return this->ixx_prologue_file_;
}
+inline bool options::
+ixx_prologue_file_specified () const
+{
+ return this->ixx_prologue_file_specified_;
+}
+
inline const std::string& options::
cxx_prologue_file () const
{
return this->cxx_prologue_file_;
}
+inline bool options::
+cxx_prologue_file_specified () const
+{
+ return this->cxx_prologue_file_specified_;
+}
+
inline const std::string& options::
man_prologue_file () const
{
return this->man_prologue_file_;
}
+inline bool options::
+man_prologue_file_specified () const
+{
+ return this->man_prologue_file_specified_;
+}
+
inline const std::string& options::
html_prologue_file () const
{
return this->html_prologue_file_;
}
+inline bool options::
+html_prologue_file_specified () const
+{
+ return this->html_prologue_file_specified_;
+}
+
inline const std::string& options::
hxx_epilogue_file () const
{
return this->hxx_epilogue_file_;
}
+inline bool options::
+hxx_epilogue_file_specified () const
+{
+ return this->hxx_epilogue_file_specified_;
+}
+
inline const std::string& options::
ixx_epilogue_file () const
{
return this->ixx_epilogue_file_;
}
+inline bool options::
+ixx_epilogue_file_specified () const
+{
+ return this->ixx_epilogue_file_specified_;
+}
+
inline const std::string& options::
cxx_epilogue_file () const
{
return this->cxx_epilogue_file_;
}
+inline bool options::
+cxx_epilogue_file_specified () const
+{
+ return this->cxx_epilogue_file_specified_;
+}
+
inline const std::string& options::
man_epilogue_file () const
{
return this->man_epilogue_file_;
}
+inline bool options::
+man_epilogue_file_specified () const
+{
+ return this->man_epilogue_file_specified_;
+}
+
inline const std::string& options::
html_epilogue_file () const
{
return this->html_epilogue_file_;
}
+inline bool options::
+html_epilogue_file_specified () const
+{
+ return this->html_epilogue_file_specified_;
+}
+
inline const std::string& options::
hxx_suffix () const
{
return this->hxx_suffix_;
}
+inline bool options::
+hxx_suffix_specified () const
+{
+ return this->hxx_suffix_specified_;
+}
+
inline const std::string& options::
ixx_suffix () const
{
return this->ixx_suffix_;
}
+inline bool options::
+ixx_suffix_specified () const
+{
+ return this->ixx_suffix_specified_;
+}
+
inline const std::string& options::
cxx_suffix () const
{
return this->cxx_suffix_;
}
+inline bool options::
+cxx_suffix_specified () const
+{
+ return this->cxx_suffix_specified_;
+}
+
inline const std::string& options::
man_suffix () const
{
return this->man_suffix_;
}
+inline bool options::
+man_suffix_specified () const
+{
+ return this->man_suffix_specified_;
+}
+
inline const std::string& options::
html_suffix () const
{
return this->html_suffix_;
}
+inline bool options::
+html_suffix_specified () const
+{
+ return this->html_suffix_specified_;
+}
+
inline const std::string& options::
option_prefix () const
{
return this->option_prefix_;
}
+inline bool options::
+option_prefix_specified () const
+{
+ return this->option_prefix_specified_;
+}
+
inline const std::string& options::
option_separator () const
{
return this->option_separator_;
}
+inline bool options::
+option_separator_specified () const
+{
+ return this->option_separator_specified_;
+}
+
inline const bool& options::
include_with_brackets () const
{
@@ -527,24 +743,48 @@ include_prefix () const
return this->include_prefix_;
}
+inline bool options::
+include_prefix_specified () const
+{
+ return this->include_prefix_specified_;
+}
+
inline const std::string& options::
guard_prefix () const
{
return this->guard_prefix_;
}
+inline bool options::
+guard_prefix_specified () const
+{
+ return this->guard_prefix_specified_;
+}
+
inline const std::map<std::string, std::string>& options::
reserved_name () const
{
return this->reserved_name_;
}
+inline bool options::
+reserved_name_specified () const
+{
+ return this->reserved_name_specified_;
+}
+
inline const std::string& options::
options_file () const
{
return this->options_file_;
}
+inline bool options::
+options_file_specified () const
+{
+ return this->options_file_specified_;
+}
+
// Begin epilogue.
//
//
diff --git a/cli/runtime-header.cxx b/cli/runtime-header.cxx
index 21d3723..42f7063 100644
--- a/cli/runtime-header.cxx
+++ b/cli/runtime-header.cxx
@@ -25,7 +25,20 @@ generate_runtime_header (context& ctx)
<< "#include <exception>" << endl
<< endl;
- ctx.cli_open ();
+ // VC++ and xlC don't like the (void)x expression if x is a reference
+ // to an incomplete type. On the other hand, GCC warns that (void*)&x
+ // doesn't have any effect.
+ //
+ os << "#ifndef CLI_POTENTIALLY_UNUSED" << endl
+ << "# if defined(_MSC_VER) || defined(__xlC__)" << endl
+ << "# define CLI_POTENTIALLY_UNUSED(x) (void*)&x" << endl
+ << "# else" << endl
+ << "# define CLI_POTENTIALLY_UNUSED(x) (void)x" << endl
+ << "# endif" << endl
+ << "#endif" << endl
+ << endl;
+
+ ctx.ns_open (ctx.cli);
// unknown_mode
//
@@ -396,5 +409,5 @@ generate_runtime_header (context& ctx)
<< "struct parser;"
<< endl;
- ctx.cli_close ();
+ ctx.ns_close (ctx.cli);
}
diff --git a/cli/runtime-inline.cxx b/cli/runtime-inline.cxx
index cb0e0e4..15efa8d 100644
--- a/cli/runtime-inline.cxx
+++ b/cli/runtime-inline.cxx
@@ -14,7 +14,7 @@ generate_runtime_inline (context& ctx)
string const& inl (ctx.inl);
string const& os_type (ctx.options.ostream_type ());
- ctx.cli_open ();
+ ctx.ns_open (ctx.cli);
// unknown_mode
//
@@ -305,5 +305,5 @@ generate_runtime_inline (context& ctx)
<< "}";
}
- ctx.cli_close ();
+ ctx.ns_close (ctx.cli);
}
diff --git a/cli/runtime-source.cxx b/cli/runtime-source.cxx
index be29a57..cb0cde0 100644
--- a/cli/runtime-source.cxx
+++ b/cli/runtime-source.cxx
@@ -25,7 +25,7 @@ generate_runtime_source (context& ctx, bool complete)
os << endl;
- ctx.cli_open ();
+ ctx.ns_open (ctx.cli);
if (complete)
{
@@ -652,5 +652,5 @@ generate_runtime_source (context& ctx, bool complete)
<< "parser<T>::parse (x.*M, x.*S, s);"
<< "}";
- ctx.cli_close ();
+ ctx.ns_close (ctx.cli);
}
diff --git a/cli/source.cxx b/cli/source.cxx
index d58f46b..0258c84 100644
--- a/cli/source.cxx
+++ b/cli/source.cxx
@@ -201,12 +201,104 @@ namespace
return r;
}
- struct option_length: traversal::option, context
+ static string
+ escape_str (string const& s)
{
- option_length (context& c, size_t& l, type*& o)
- : context (c), length_ (l), option_ (o)
+ string r;
+
+ for (size_t i (0), n (s.size ()); i < n; ++i)
+ {
+ switch (s[i])
+ {
+ case '\\':
+ {
+ r += "\\\\";
+ break;
+ }
+ case '"':
+ {
+ r += "\\\"";
+ break;
+ }
+ case '\033':
+ {
+ r += "\\033";
+ break;
+ }
+ default:
+ {
+ r += s[i];
+ break;
+ }
+ }
+ }
+
+ return r;
+ }
+
+ // This function assumes that the string opening part has already been
+ // written. The 'first' argument is the number of characters already
+ // written in the first line (e.g., an option name).
+ //
+ static void
+ wrap_lines (ostream& os,
+ const string& d,
+ size_t indent = 0,
+ size_t first = 0)
+ {
+ assert (!d.empty ());
+
+ string ind (indent, ' ');
+ os << string (indent - first, ' ');
+
+ size_t b (0), e (0), i (0);
+ for (size_t n (d.size ()); i < n; ++i)
+ {
+ if (d[i] == ' ' || d[i] == '\n')
+ e = i;
+
+ if (d[i] == '\n' || text_size (d, b, i - b) == 79 - indent)
+ {
+ if (b != 0) // Not a first line.
+ os << endl
+ << " << \"" << ind;
+
+ string s (d, b, (e != b ? e : i) - b);
+ os << escape_str (s) << "\" << ::std::endl";
+
+ // Handle consecutive newlines (e.g., pre, paragraph separator).
+ //
+ if (d[i] == '\n')
+ {
+ for (; i + 1 < n && d[i + 1] == '\n'; e = ++i)
+ os << endl
+ << " << ::std::endl";
+ }
+
+ b = e = (e != b ? e : i) + 1;
+ }
+ }
+
+ // Flush the last line.
+ //
+ if (b != i)
{
+ if (b != 0)
+ os << endl
+ << " << \"" << ind;
+
+ string s (d, b, i - b);
+ os << escape_str (s) << "\" << ::std::endl";
}
+ }
+
+ struct option_length: traversal::option, context
+ {
+ option_length (context& c, size_t& l)
+ : context (c), length_ (l), option_ (0) {}
+
+ option_length (context& c, size_t& l, type*& o)
+ : context (c), length_ (l), option_ (&o) {}
virtual void
traverse (type& o)
@@ -218,8 +310,6 @@ namespace
if (options.suppress_undocumented () && doc.empty ())
return;
- bool color (options.ansi_color ());
-
size_t l (0);
names& n (o.named ());
@@ -239,7 +329,7 @@ namespace
string s (doc.size () > 0 ? doc[0] : string ("<arg>"));
- if (color)
+ if (options.ansi_color ())
{
std::set<string> arg_set;
s = translate_arg (s, arg_set);
@@ -251,13 +341,14 @@ namespace
if (l > length_)
{
length_ = l;
- option_ = &o;
+ if (option_ != 0)
+ *option_ = &o;
}
}
private:
size_t& length_;
- type*& option_;
+ type** option_;
};
//
@@ -355,60 +446,7 @@ namespace
d = format (ot_plain, d, false);
if (!d.empty ())
- {
- pad (length_ - l);
-
- size_t b (0), e (0), i (0);
-
- for (size_t n (d.size ()); i < n; ++i)
- {
- if (d[i] == ' ' || d[i] == '\n')
- e = i;
-
- // Assume we have 78 characters instead of 79 per line to make sure
- // we get the same output on Windows (which has two characters for
- // a newline).
- //
- if (d[i] == '\n' || text_size (d, b, i - b) == 78 - length_)
- {
- if (b != 0) // Not a first line.
- {
- os << endl
- << " << \"";
- pad ();
- }
-
- string s (d, b, (e != b ? e : i) - b);
- os << escape_str (s) << "\" << ::std::endl";
-
- // Handle consecutive newlines (e.g., pre, paragraph separator).
- //
- if (d[i] == '\n')
- {
- for (; i + 1 < n && d[i + 1] == '\n'; e = ++i)
- os << endl
- << " << ::std::endl";
- }
-
- b = e = (e != b ? e : i) + 1;
- }
- }
-
- // Flush the last line.
- //
- if (b != i)
- {
- if (b != 0)
- {
- os << endl
- << " << \"";
- pad ();
- }
-
- string s (d, b, i - b);
- os << escape_str (s) << "\" << ::std::endl";
- }
- }
+ wrap_lines (os, d, length_ + 1, l); // +1 for extra space after arg.
else
os << "\" << std::endl";
@@ -417,21 +455,6 @@ namespace
}
private:
- void
- pad (size_t n)
- {
- for (; n > 0; --n)
- os << ' ';
-
- os << ' '; // Space between arg and description.
- }
-
- void
- pad ()
- {
- pad (length_);
- }
-
string
first_sentence (string const& s)
{
@@ -449,42 +472,6 @@ namespace
return p == string::npos ? s : string (s, 0, p + 1);
}
- string
- escape_str (string const& s)
- {
- string r;
- r.reserve (s.size ());
-
- for (size_t i (0), n (s.size ()); i < n; ++i)
- {
- switch (s[i])
- {
- case '\\':
- {
- r += "\\\\";
- break;
- }
- case '"':
- {
- r += "\\\"";
- break;
- }
- case '\033':
- {
- r += "\\033";
- break;
- }
- default:
- {
- r += s[i];
- break;
- }
- }
- }
-
- return r;
- }
-
private:
size_t length_;
usage_type usage_;
@@ -1000,14 +987,127 @@ namespace
option_desc option_desc_;
traversal::names names_option_desc_;
};
+
+ // Page usage.
+ //
+ enum paragraph {para_none, para_text, para_option};
+
+ struct doc: traversal::doc, context
+ {
+ doc (context& c, usage_type u, paragraph& p)
+ : context (c), usage_ (u), para_ (p) {}
+
+ virtual void
+ traverse (type& ds)
+ {
+ if (ds.name ().compare (0, 3, "doc") != 0) // Ignore doc variables.
+ return;
+
+ // Figure out which documentation string we should use.
+ //
+ // n = 1 - common doc string
+ // n = 2 - arg string, common doc string
+ // n > 2 - arg string, short string, long string
+ //
+ size_t n (ds.size ());
+ string d;
+
+ if (usage == ut_both && usage_ == ut_long)
+ {
+ d = n > 2 // Have both short and long?
+ ? ds[2] // Then use long.
+ : (n == 1 ? ds[0] : ds[1]); // Else, use common.
+ }
+ else // Short or long.
+ {
+ d = n > 2 // Have both short and long?
+ ? ds[1] // Then use short,
+ : (n == 1 ? ds[0] : ds[1]); // Else, use common (no first sentence).
+ }
+
+ std::set<string> arg_set;
+ if (n > 1 && options.ansi_color ())
+ translate_arg (ds[0], arg_set);
+
+ d = format (ot_plain, translate (d, arg_set), true);
+
+ if (d.empty ())
+ return;
+
+ if (para_ == para_none) // First.
+ os << "os << \"";
+ else
+ os << "os << ::std::endl" << endl
+ << " << \"";
+
+ wrap_lines (os, d);
+ os << ";"
+ << endl;
+
+ para_ = para_text;
+ }
+
+ private:
+ usage_type usage_;
+ paragraph& para_;
+ };
+
+ struct class_usage: traversal::class_, context
+ {
+ class_usage (context& c, usage_type u, paragraph& p)
+ : context (c), usage_ (u), para_ (p) {}
+
+ virtual void
+ traverse (type& c)
+ {
+ // Figure out if this class has any documentation by calculating
+ // the option length. If it is 0, then we don't have any.
+ //
+ size_t len (0);
+ {
+ option_length olt (*this, len);
+ traversal::class_ ct;
+ traversal::inherits i;
+ traversal::names n;
+
+ if (!options.exclude_base ()) // Go into bases unless --exclude-base.
+ ct >> i >> ct;
+
+ ct >> n >> olt;
+ ct.traverse (c);
+ }
+
+ if (len == 0)
+ return;
+
+ if (para_ == para_text)
+ os << "os << ::std::endl;";
+
+ const char* t (
+ usage != ut_both
+ ? ""
+ : usage_ == ut_short ? "short_" : "long_");
+
+ os << fq_name (c) << "::print_" << t << "usage (os);"
+ << endl;
+
+ para_ = para_option;
+ }
+
+ private:
+ usage_type usage_;
+ paragraph& para_;
+ };
}
void
generate_source (context& ctx)
{
- ctx.os << "#include <map>" << endl
- << "#include <cstring>" << endl
- << endl;
+ ostream& os (ctx.os);
+
+ os << "#include <map>" << endl
+ << "#include <cstring>" << endl
+ << endl;
traversal::cli_unit unit;
traversal::names unit_names;
@@ -1023,4 +1123,84 @@ generate_source (context& ctx)
ns_names >> cl;
unit.dispatch (ctx.unit);
+
+ // Entire page usage.
+ //
+ if (ctx.usage != ut_none && ctx.options.page_usage_specified ())
+ {
+ const string& qn (ctx.options.page_usage ());
+ string n (ctx.escape (ctx.substitute (ctx.ns_open (qn, false))));
+
+ usage u (ctx.usage);
+ string const& ost (ctx.options.ostream_type ());
+
+ {
+ os << "void" << endl
+ << n << (u == ut_both ? "short_" : "") << "usage (" << ost << "& os)"
+ << "{"
+ << "CLI_POTENTIALLY_UNUSED (os);"
+ << endl;
+
+ paragraph para (para_none);
+
+ traversal::cli_unit unit;
+ traversal::names unit_names;
+ traversal::namespace_ ns;
+ doc dc (ctx, u == ut_both ? ut_short : u, para);
+ class_usage cl (ctx, u == ut_both ? ut_short : u, para);
+
+ unit >> unit_names;
+ unit_names >> dc;
+ unit_names >> ns;
+ unit_names >> cl;
+
+ traversal::names ns_names;
+
+ ns >> ns_names;
+ ns_names >> dc;
+ ns_names >> ns;
+ ns_names >> cl;
+
+ unit.dispatch (ctx.unit);
+
+ os << "}";
+ }
+
+ // Long version.
+ //
+ if (u == ut_both)
+ {
+ os << "void" << endl
+ << n << "long_usage (" << ost << "& os)"
+ << "{"
+ << "CLI_POTENTIALLY_UNUSED (os);"
+ << endl;
+
+ paragraph para (para_none);
+
+ traversal::cli_unit unit;
+ traversal::names unit_names;
+ traversal::namespace_ ns;
+ doc dc (ctx, ut_long, para);
+ class_usage cl (ctx, ut_long, para);
+
+ unit >> unit_names;
+ unit_names >> dc;
+ unit_names >> ns;
+ unit_names >> cl;
+
+ traversal::names ns_names;
+
+ ns >> ns_names;
+ ns_names >> dc;
+ ns_names >> ns;
+ ns_names >> cl;
+
+ unit.dispatch (ctx.unit);
+
+ os << "}";
+ }
+
+ ctx.ns_close (qn, false);
+ }
}
diff --git a/doc/cli.1 b/doc/cli.1
index 663fdaf..a50a1bc 100644
--- a/doc/cli.1
+++ b/doc/cli.1
@@ -116,6 +116,26 @@ usage versions\. In this mode, the usage printing functions are called
\fBprint_short_usage()\fR and \fBprint_long_usage()\fR and for the long usage
the long documentation string is always used, even if the short version is
provided\.
+.IP "\fB--page-usage\fR \fIname\fR"
+Generate the combined usage printing code for the entire page\. Specifically,
+this will include all the namespace-level documentation as well as usage for
+all the options classes printed in the order they are defined in the main
+translation unit (documentation/classes from included units are ignored except
+for base classes)\.
+
+The \fIname\fR argument is used as a prefix to form the name of the usage
+printing function\. It can include the namespace qualification as well as
+documentation variable expansion, for example:
+
+.nf
+--page-usage print_ # print_usage() in global namespace
+--page-usage app::print_ # print_usage() in app namespace
+--page-usage print_$name$_ # print_foo_usage() if name is foo
+.fi
+
+If both \fB--long-usage\fR and \fB--short-usage\fR options are specified, then
+two functions are generated with the \fB*short_usage()\fR and
+\fB*long_usage()\fR suffixes\.
.IP "\fB--option-length\fR \fIlen\fR"
Indent option descriptions \fIlen\fR characters when printing usage\. This is
useful when you have multiple options classes, potentially in separate files,
diff --git a/doc/cli.xhtml b/doc/cli.xhtml
index 305087c..92f237b 100644
--- a/doc/cli.xhtml
+++ b/doc/cli.xhtml
@@ -159,6 +159,26 @@
documentation string is always used, even if the short version is
provided.</dd>
+ <dt><code><b>--page-usage</b></code> <i>name</i></dt>
+ <dd>Generate the combined usage printing code for the entire page.
+ Specifically, this will include all the namespace-level documentation as
+ well as usage for all the options classes printed in the order they are
+ defined in the main translation unit (documentation/classes from included
+ units are ignored except for base classes).
+
+ <p>The <i>name</i> argument is used as a prefix to form the name of the
+ usage printing function. It can include the namespace qualification as
+ well as documentation variable expansion, for example:</p>
+
+ <pre>--page-usage print_ # print_usage() in global namespace
+--page-usage app::print_ # print_usage() in app namespace
+--page-usage print_$name$_ # print_foo_usage() if name is foo</pre>
+
+ <p>If both <code><b>--long-usage</b></code> and
+ <code><b>--short-usage</b></code> options are specified, then two
+ functions are generated with the <code><b>*short_usage()</b></code> and
+ <code><b>*long_usage()</b></code> suffixes.</p></dd>
+
<dt><code><b>--option-length</b></code> <i>len</i></dt>
<dd>Indent option descriptions <i>len</i> characters when printing usage.
This is useful when you have multiple options classes, potentially in