summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/context.cxx11
-rw-r--r--cli/context.hxx11
-rw-r--r--cli/header.cxx19
-rw-r--r--cli/options.cli9
-rw-r--r--cli/options.cxx25
-rw-r--r--cli/options.hxx22
-rw-r--r--cli/options.ixx19
-rw-r--r--cli/source.cxx96
8 files changed, 171 insertions, 41 deletions
diff --git a/cli/context.cxx b/cli/context.cxx
index af6b58f..1324b0c 100644
--- a/cli/context.cxx
+++ b/cli/context.cxx
@@ -101,7 +101,6 @@ context (ostream& os_,
options (ops),
modifier (options.generate_modifier ()),
specifier (options.generate_specifier ()),
- usage (!options.suppress_usage ()),
inl (data_->inl_),
opt_prefix (options.option_prefix ()),
opt_sep (options.option_separator ()),
@@ -109,6 +108,16 @@ context (ostream& os_,
reserved_name_map (options.reserved_name ()),
keyword_set (data_->keyword_set_)
{
+ if (options.suppress_usage ())
+ usage = ut_none;
+ else
+ {
+ if (options.long_usage ())
+ usage = options.short_usage () ? ut_both : ut_long;
+ else
+ usage = ut_short;
+ }
+
if (!options.suppress_inline ())
data_->inl_ = "inline ";
diff --git a/cli/context.hxx b/cli/context.hxx
index afaf577..b6ce420 100644
--- a/cli/context.hxx
+++ b/cli/context.hxx
@@ -29,6 +29,15 @@ public:
typedef std::string string;
typedef ::options options_type;
+public:
+ enum usage_type
+ {
+ ut_none,
+ ut_short,
+ ut_long,
+ ut_both
+ };
+
private:
struct data;
cutl::shared_ptr<data> data_;
@@ -40,7 +49,7 @@ public:
bool modifier;
bool specifier;
- bool usage;
+ usage_type usage;
string const& inl;
string const& opt_prefix;
diff --git a/cli/header.cxx b/cli/header.cxx
index 26c23b8..ddf0895 100644
--- a/cli/header.cxx
+++ b/cli/header.cxx
@@ -179,13 +179,22 @@ namespace
// Usage.
//
- if (usage)
+ if (usage != ut_none)
{
os << "// Print usage information." << endl
- << "//" << endl
- << "static void" << endl
- << "print_usage (" << options.ostream_type () << "&);"
- << endl;
+ << "//" << endl;
+
+ if (usage != ut_both)
+ os << "static void" << endl
+ << "print_usage (" << options.ostream_type () << "&);"
+ << endl;
+ else
+ os << "static void" << endl
+ << "print_short_usage (" << options.ostream_type () << "&);"
+ << endl
+ << "static void" << endl
+ << "print_long_usage (" << options.ostream_type () << "&);"
+ << endl;
}
// Description.
diff --git a/cli/options.cli b/cli/options.cli
index ab7be1c..28a4ee4 100644
--- a/cli/options.cli
+++ b/cli/options.cli
@@ -83,6 +83,15 @@ class options
only the first sentence from the long string is used."
};
+ bool --short-usage
+ {
+ "If specified together with \cb{--long-usage}, generate both short
+ and long usage versions. In this mode, the usage printing functions
+ are called \cb{print_short_usage()} and \cb{print_long_usage()} and
+ for the long usage the long documentation string is always used,
+ even if the short version is provided."
+ };
+
std::size_t --option-length = 0
{
"<len>",
diff --git a/cli/options.cxx b/cli/options.cxx
index 1e94e17..dcb408a 100644
--- a/cli/options.cxx
+++ b/cli/options.cxx
@@ -1,7 +1,14 @@
-// This code was generated by CLI, a command line interface
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
// compiler for C++.
//
+// Begin prologue.
+//
+//
+// End prologue.
+
#include "options.hxx"
#include <map>
@@ -562,6 +569,7 @@ options ()
suppress_undocumented_ (),
suppress_usage_ (),
long_usage_ (),
+ short_usage_ (),
option_length_ (0),
exclude_base_ (),
cli_namespace_ ("::cli"),
@@ -624,6 +632,7 @@ options (int& argc,
suppress_undocumented_ (),
suppress_usage_ (),
long_usage_ (),
+ short_usage_ (),
option_length_ (0),
exclude_base_ (),
cli_namespace_ ("::cli"),
@@ -689,6 +698,7 @@ options (int start,
suppress_undocumented_ (),
suppress_usage_ (),
long_usage_ (),
+ short_usage_ (),
option_length_ (0),
exclude_base_ (),
cli_namespace_ ("::cli"),
@@ -754,6 +764,7 @@ options (int& argc,
suppress_undocumented_ (),
suppress_usage_ (),
long_usage_ (),
+ short_usage_ (),
option_length_ (0),
exclude_base_ (),
cli_namespace_ ("::cli"),
@@ -821,6 +832,7 @@ options (int start,
suppress_undocumented_ (),
suppress_usage_ (),
long_usage_ (),
+ short_usage_ (),
option_length_ (0),
exclude_base_ (),
cli_namespace_ ("::cli"),
@@ -884,6 +896,7 @@ options (::cli::scanner& s,
suppress_undocumented_ (),
suppress_usage_ (),
long_usage_ (),
+ short_usage_ (),
option_length_ (0),
exclude_base_ (),
cli_namespace_ ("::cli"),
@@ -967,6 +980,9 @@ print_usage (::std::ostream& os)
os << "--long-usage If no short documentation string is provided, use" << ::std::endl
<< " the complete long documentation string in usage." << ::std::endl;
+ os << "--short-usage If specified together with '--long-usage'," << ::std::endl
+ << " generate both short and long usage versions." << ::std::endl;
+
os << "--option-length <len> Indent option descriptions <len> characters when" << ::std::endl
<< " printing usage." << ::std::endl;
@@ -1126,6 +1142,8 @@ struct _cli_options_map_init
&::cli::thunk< options, bool, &options::suppress_usage_ >;
_cli_options_map_["--long-usage"] =
&::cli::thunk< options, bool, &options::long_usage_ >;
+ _cli_options_map_["--short-usage"] =
+ &::cli::thunk< options, bool, &options::short_usage_ >;
_cli_options_map_["--option-length"] =
&::cli::thunk< options, std::size_t, &options::option_length_ >;
_cli_options_map_["--exclude-base"] =
@@ -1289,3 +1307,8 @@ _parse (::cli::scanner& s,
}
}
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/cli/options.hxx b/cli/options.hxx
index d3a9c5c..22495e4 100644
--- a/cli/options.hxx
+++ b/cli/options.hxx
@@ -1,10 +1,17 @@
-// This code was generated by CLI, a command line interface
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
// compiler for C++.
//
#ifndef CLI_OPTIONS_HXX
#define CLI_OPTIONS_HXX
+// Begin prologue.
+//
+//
+// End prologue.
+
#include <deque>
#include <iosfwd>
#include <string>
@@ -351,6 +358,8 @@ class options
::cli::unknown_mode option = ::cli::unknown_mode::fail,
::cli::unknown_mode argument = ::cli::unknown_mode::stop);
+ options ();
+
// Option accessors.
//
const bool&
@@ -392,6 +401,9 @@ class options
const bool&
long_usage () const;
+ const bool&
+ short_usage () const;
+
const std::size_t&
option_length () const;
@@ -520,8 +532,6 @@ class options
// Implementation details.
//
protected:
- options ();
-
bool
_parse (const char*, ::cli::scanner&);
@@ -545,6 +555,7 @@ class options
bool suppress_undocumented_;
bool suppress_usage_;
bool long_usage_;
+ bool short_usage_;
std::size_t option_length_;
bool exclude_base_;
std::string cli_namespace_;
@@ -589,4 +600,9 @@ class options
#include "options.ixx"
+// Begin epilogue.
+//
+//
+// End epilogue.
+
#endif // CLI_OPTIONS_HXX
diff --git a/cli/options.ixx b/cli/options.ixx
index a361898..a66312d 100644
--- a/cli/options.ixx
+++ b/cli/options.ixx
@@ -1,7 +1,14 @@
-// This code was generated by CLI, a command line interface
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
// compiler for C++.
//
+// Begin prologue.
+//
+//
+// End prologue.
+
namespace cli
{
// unknown_mode
@@ -274,6 +281,12 @@ long_usage () const
return this->long_usage_;
}
+inline const bool& options::
+short_usage () const
+{
+ return this->short_usage_;
+}
+
inline const std::size_t& options::
option_length () const
{
@@ -514,3 +527,7 @@ options_file () const
return this->options_file_;
}
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/cli/source.cxx b/cli/source.cxx
index 2bf1c0f..6a8ea76 100644
--- a/cli/source.cxx
+++ b/cli/source.cxx
@@ -229,7 +229,8 @@ namespace
//
struct option_usage: traversal::option, context
{
- option_usage (context& c, size_t l) : context (c), length_ (l) {}
+ option_usage (context& c, size_t l, usage_type u)
+ : context (c), length_ (l), usage_ (u) {}
virtual void
traverse (type& o)
@@ -278,25 +279,29 @@ namespace
}
}
- // If we have both the long and the short descriptions, use
- // the short one. Otherwise, use the first sentence from the
- // long one unless --long-usage was specified.
+ // Figure out which documentation string we should use.
//
string d;
-
- if (type == "bool" && doc.size () < 3)
- {
- if (doc.size () > 1)
- d = doc[0];
- else if (doc.size () > 0)
- d = options.long_usage () ? doc[0] : first_sentence (doc[0]);
- }
- else
{
- if (doc.size () > 2)
- d = doc[1];
- else if (doc.size () > 1)
- d = options.long_usage () ? doc[1] : first_sentence (doc[1]);
+ size_t i (type == "bool" && doc.size () < 3 ? 0 : 1);
+
+ if (doc.size () > i) // Have at least one.
+ {
+ if (usage == ut_both && usage_ == ut_long)
+ {
+ d = doc.size () > i + 1 // Have both short and long?
+ ? doc[i + 1] // Then use long.
+ : doc[i];
+ }
+ else // Short or long.
+ {
+ d = doc.size () > i + 1 // Have both short and long?
+ ? doc[i] // Then use short,
+ : (usage == ut_long // Otherwise, if asked for long,
+ ? doc[i] // Then use long,
+ : first_sentence (doc[i])); // Else first sentence of long.
+ }
+ }
}
// Format the documentation string.
@@ -426,6 +431,7 @@ namespace
private:
size_t length_;
+ usage_type usage_;
};
//
@@ -463,16 +469,24 @@ namespace
struct base_usage: traversal::class_, context
{
- base_usage (context& c): context (c) {}
+ base_usage (context& c, usage_type u): context (c), usage_ (u) {}
virtual void
traverse (type& c)
{
+ const char* t (
+ usage != ut_both
+ ? ""
+ : usage_ == ut_short ? "short_" : "long_");
+
os << "// " << escape (c.name ()) << " base" << endl
<< "//" << endl
- << fq_name (c) << "::print_usage (os);"
+ << fq_name (c) << "::print_" << t << "usage (os);"
<< endl;
}
+
+ private:
+ usage_type usage_;
};
//
@@ -483,13 +497,11 @@ namespace
: context (c),
base_parse_ (c),
base_desc_ (c),
- base_usage_ (c),
option_map_ (c),
option_desc_ (c)
{
inherits_base_parse_ >> base_parse_;
inherits_base_desc_ >> base_desc_;
- inherits_base_usage_ >> base_usage_;
names_option_map_ >> option_map_;
names_option_desc_ >> option_desc_;
}
@@ -609,7 +621,7 @@ namespace
// Usage.
//
- if (usage)
+ if (usage != ut_none)
{
bool b (hb && !options.exclude_base ());
@@ -690,24 +702,53 @@ namespace
// If len is 0 then it means we have no options to print.
//
os << "void " << name << "::" << endl
- << "print_usage (" << options.ostream_type () << "&" <<
- (len != 0 || b ? " os)" : ")")
+ << "print_" << (usage == ut_both ? "short_" : "") << "usage (" <<
+ options.ostream_type () << "&" << (len != 0 || b ? " os)" : ")")
<< "{";
// Call our bases.
//
if (b)
- inherits (c, inherits_base_usage_);
+ {
+ base_usage t (*this, usage == ut_both ? ut_short : usage);
+ traversal::inherits i (t);
+ inherits (c, i);
+ }
// Print option usage.
//
{
- option_usage t (*this, len);
+ option_usage t (*this, len, usage == ut_both ? ut_short : usage);
traversal::names n (t);
names (c, n);
}
os << "}";
+
+ // Long version.
+ //
+ if (usage == ut_both)
+ {
+ os << "void " << name << "::" << endl
+ << "print_long_usage (" <<
+ options.ostream_type () << "&" << (len != 0 || b ? " os)" : ")")
+ << "{";
+
+ if (b)
+ {
+ base_usage t (*this, ut_long);
+ traversal::inherits i (t);
+ inherits (c, i);
+ }
+
+ {
+ option_usage t (*this, len, ut_long);
+ traversal::names n (t);
+ names (c, n);
+ }
+
+ os << "}";
+ }
}
// Description.
@@ -891,9 +932,6 @@ namespace
base_desc base_desc_;
traversal::inherits inherits_base_desc_;
- base_usage base_usage_;
- traversal::inherits inherits_base_usage_;
-
option_map option_map_;
traversal::names names_option_map_;