From 0e56fe29a9afeee00e02e722496678df89d37d50 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 17 Nov 2009 13:59:39 +0200 Subject: Complete the implementation of the option documentation Add the man page generator. Port CLI usage, HTML documentation and the man page to the auto-generated version. Update examples and documentation. --- cli/context.cxx | 79 ++++++++++++++++++++++++-- cli/context.hxx | 9 ++- cli/generator.cxx | 129 +++++++++++++++++++++++++++++++++++++++--- cli/html.cxx | 12 ++++ cli/makefile | 1 + cli/man.cxx | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ cli/man.hxx | 14 +++++ cli/options.cli | 114 +++++++++++++++++++++++++++++--------- cli/options.cxx | 107 ++++++++++++++++++++++++++++------- cli/options.hxx | 36 ++++++++++-- cli/options.ixx | 54 ++++++++++++++++-- cli/source.cxx | 8 +-- 12 files changed, 650 insertions(+), 76 deletions(-) create mode 100644 cli/man.cxx create mode 100644 cli/man.hxx (limited to 'cli') diff --git a/cli/context.cxx b/cli/context.cxx index ccd3c8b..05e15cc 100644 --- a/cli/context.cxx +++ b/cli/context.cxx @@ -309,7 +309,19 @@ format (string const& s, output_type ot) { case '\\': { - r += '\\'; + switch (ot) + { + case ot_man: + { + r += "\\e"; + break; + } + default: + { + r += '\\'; + break; + } + } break; } case '"': @@ -461,6 +473,12 @@ format (string const& s, output_type ot) switch (ot) { + case ot_plain: + { + if (b & 1) + r += "'"; + break; + } case ot_html: { if (b & 1) @@ -474,6 +492,17 @@ format (string const& s, output_type ot) break; } + case ot_man: + { + if ((b & 6) == 6) + r += "\\f(BI"; + else if (b & 2) + r += "\\fI"; + else if (b & 4) + r += "\\fB"; + + break; + } default: break; } @@ -490,6 +519,7 @@ format (string const& s, output_type ot) switch (ot) { case ot_plain: + case ot_man: { r += '\n'; break; @@ -506,25 +536,43 @@ format (string const& s, output_type ot) } } } + else if (s[i] == '.') + { + if (ot == ot_man) + r += "\\."; + else + r += '.'; + } else if (!blocks.empty () && s[i] == '}') { unsigned char b (blocks.top ()); switch (ot) { - case ot_html: + case ot_plain: { if (b & 1) - r += ""; + r += "'"; + break; + } + case ot_html: + { + if (b & 4) + r += ""; if (b & 2) r += ""; - if (b & 4) - r += ""; + if (b & 1) + r += ""; break; } + case ot_man: + { + if (b & 6) + r += "\\fP"; + } default: break; } @@ -541,6 +589,27 @@ format (string const& s, output_type ot) return r; } +string context:: +fq_name (semantics::nameable& n, bool cxx_name) +{ + using namespace semantics; + + string r; + + if (dynamic_cast (&n)) + { + return ""; // Map to global namespace. + } + else + { + r = fq_name (n.scope ()); + r += "::"; + r += cxx_name ? escape (n.name ()) : n.name (); + } + + return r; +} + // namespace // diff --git a/cli/context.hxx b/cli/context.hxx index f6d53c3..30539af 100644 --- a/cli/context.hxx +++ b/cli/context.hxx @@ -70,7 +70,8 @@ public: enum output_type { ot_plain, - ot_html + ot_html, + ot_man }; static string @@ -96,6 +97,12 @@ public: } public: + // Return fully-qualified C++ or CLI name. + // + string + fq_name (semantics::nameable& n, bool cxx_name = true); + +public: context (std::ostream&, semantics::cli_unit&, options_type const&); context (context&); diff --git a/cli/generator.cxx b/cli/generator.cxx index 6043825..7531ffe 100644 --- a/cli/generator.cxx +++ b/cli/generator.cxx @@ -21,6 +21,7 @@ #include "runtime-inline.hxx" #include "runtime-source.hxx" +#include "man.hxx" #include "html.hxx" #include "context.hxx" @@ -35,10 +36,23 @@ using semantics::path; namespace { - static char const header[] = - "// This code was generated by CLI, a command line interface\n" - "// compiler for C++.\n" - "//\n\n"; + static char const cxx_header[] = + "// This code was generated by CLI, a command line interface\n" + "// compiler for C++.\n" + "//\n\n"; + + static char const man_header[] = + ".\\\"\n" + ".\\\" The following documentation was generated by CLI, a command\n" + ".\\\" line interface compiler for C++.\n" + ".\\\"\n"; + + static char const html_header[] = + "\n" + "\n\n"; string make_guard (string const& file, context& ctx) @@ -63,6 +77,18 @@ namespace return ctx.escape (r); } + + void + open (ifstream& ifs, string const& path) + { + ifs.open (path.c_str (), ios_base::in | ios_base::binary); + + if (!ifs.is_open ()) + { + cerr << path << ": error: unable to open in read mode" << endl; + throw generator::failed (); + } + } } generator:: @@ -103,6 +129,8 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p) fs::auto_removes auto_rm; + // C++ output. + // if (gen_cxx) { bool inl (!ops.suppress_inline ()); @@ -177,10 +205,10 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p) // Print headers. // - hxx << header; + hxx << cxx_header; if (inl) - ixx << header; - cxx << header; + ixx << cxx_header; + cxx << cxx_header; typedef compiler::ostream_filter @@ -255,8 +283,83 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p) } } + // man output + // + if (gen_man) + { + // Prologue & epilogue. + // + ifstream prologue, epilogue; + { + string file (ops.man_prologue ()); + + if (!file.empty ()) + open (prologue, file); + } + + { + string file (ops.man_epilogue ()); + + if (!file.empty ()) + open (epilogue, file); + } + + ofstream man; + + if (!ops.stdout ()) + { + path man_path (base + ops.man_suffix ()); + + if (!ops.output_dir ().empty ()) + man_path = path (ops.output_dir ()) / man_path; + + man.open (man_path.string ().c_str ()); + + if (!man.is_open ()) + { + cerr << "error: unable to open '" << man_path << "' in write mode" + << endl; + throw failed (); + } + + auto_rm.add (man_path); + } + + ostream& os (ops.stdout () ? cout : man); + + if (prologue.is_open ()) + os << prologue.rdbuf (); + + os << man_header; + + context ctx (os, unit, ops); + generate_man (ctx); + + if (epilogue.is_open ()) + os << epilogue.rdbuf (); + } + + // HTML output + // if (gen_html) { + // Prologue & epilogue. + // + ifstream prologue, epilogue; + { + string file (ops.html_prologue ()); + + if (!file.empty ()) + open (prologue, file); + } + + { + string file (ops.html_epilogue ()); + + if (!file.empty ()) + open (epilogue, file); + } + ofstream html; if (!ops.stdout ()) @@ -278,8 +381,18 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p) auto_rm.add (html_path); } - context ctx (ops.stdout () ? cout : html, unit, ops); + ostream& os (ops.stdout () ? cout : html); + + if (prologue.is_open ()) + os << prologue.rdbuf (); + + os << html_header; + + context ctx (os, unit, ops); generate_html (ctx); + + if (epilogue.is_open ()) + os << epilogue.rdbuf (); } auto_rm.cancel (); diff --git a/cli/html.cxx b/cli/html.cxx index b147703..be675c7 100644 --- a/cli/html.cxx +++ b/cli/html.cxx @@ -162,6 +162,17 @@ namespace virtual void traverse (type& c) { + string const& n (options.class_ ()); + + if (!n.empty ()) + { + string fqn (fq_name (c, false)); + fqn = string (fqn, 2, fqn.size () - 2); // Get rid of leading ::. + + if (n != fqn) + return; + } + os << "
" << endl; names (c, names_option_); @@ -170,6 +181,7 @@ namespace } private: + bool generated_; option option_; traversal::names names_option_; }; diff --git a/cli/makefile b/cli/makefile index 7edd27e..0ebba36 100644 --- a/cli/makefile +++ b/cli/makefile @@ -16,6 +16,7 @@ source.cxx \ runtime-header.cxx \ runtime-inline.cxx \ runtime-source.cxx \ +man.cxx \ html.cxx \ generator.cxx \ name-processor.cxx diff --git a/cli/man.cxx b/cli/man.cxx new file mode 100644 index 0000000..cb7822c --- /dev/null +++ b/cli/man.cxx @@ -0,0 +1,163 @@ +// file : cli/man.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include "man.hxx" + +namespace +{ + struct option: traversal::option, context + { + option (context& c) : context (c) {} + + virtual void + traverse (type& o) + { + using semantics::names; + + names& n (o.named ()); + + os << ".IP \"\\fB"; + + for (names::name_iterator i (n.name_begin ()); i != n.name_end (); ++i) + { + if (i != n.name_begin ()) + os << "\\fP|\\fB"; + + os << *i; + } + + os << "\\fP"; + + type::doc_list const& doc (o.doc ()); + string type (o.type ().name ()); + + std::set arg_set; + + if (type != "bool") + { + string s ( + translate_arg ( + doc.size () > 0 ? doc[0] : string (""), arg_set)); + + os << ' ' << format (s, ot_man); + } + + os << "\"" << endl; + + string d; + + // If we have both the long and the short descriptions, use + // the long one. + // + if (type == "bool") + { + if (doc.size () > 1) + d = doc[1]; + else if (doc.size () > 0) + d = doc[0]; + } + else + { + if (doc.size () > 2) + d = doc[2]; + else if (doc.size () > 1) + d = doc[1]; + } + + // Format the documentation string. + // + d = format (translate (d, arg_set), ot_man); + + if (!d.empty ()) + { + 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' || (i - b >= 76 && e != b)) + { + if (b != 0) + os << endl; + + os << string (d, b, e - b); + + if (d[i] == '\n') + os << endl; + + b = e = e + 1; + } + } + + // Flush the last line. + // + if (b != i) + { + if (b != 0) + os << endl; + + os << string (d, b, i - b); + } + } + + os << endl + << endl; + } + }; + + // + // + struct class_: traversal::class_, context + { + class_ (context& c) + : context (c), option_ (c) + { + names_option_ >> option_; + } + + virtual void + traverse (type& c) + { + string const& n (options.class_ ()); + + if (!n.empty ()) + { + string fqn (fq_name (c, false)); + fqn = string (fqn, 2, fqn.size () - 2); // Get rid of leading ::. + + if (n != fqn) + return; + } + + names (c, names_option_); + } + + private: + bool generated_; + option option_; + traversal::names names_option_; + }; +} + +void +generate_man (context& ctx) +{ + traversal::cli_unit unit; + traversal::names unit_names; + traversal::namespace_ ns; + class_ cl (ctx); + + unit >> unit_names >> ns; + unit_names >> cl; + + traversal::names ns_names; + + ns >> ns_names >> ns; + ns_names >> cl; + + unit.dispatch (ctx.unit); +} diff --git a/cli/man.hxx b/cli/man.hxx new file mode 100644 index 0000000..7a4100a --- /dev/null +++ b/cli/man.hxx @@ -0,0 +1,14 @@ +// file : cli/man.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef CLI_MAN_HXX +#define CLI_MAN_HXX + +#include "context.hxx" + +void +generate_man (context&); + +#endif // CLI_MAN_HXX diff --git a/cli/options.cli b/cli/options.cli index 1127553..085a26a 100644 --- a/cli/options.cli +++ b/cli/options.cli @@ -20,110 +20,170 @@ class options std::string --output-dir | -o { "", - "Write generated files to ." + "Write the generated files to instead of the current directory." }; bool --suppress-inline { - "Generate all functions non-inline." + "Generate all functions non-inline. By default simple functions are + made inline. This option suppresses creation of the inline file." }; bool --suppress-usage { - "Suppress generation of usage printing code." + "Suppress the generation of the usage printing code." + }; + + bool --long-usage + { + "If no short documentation string is provided, use the complete + long documentation string in usage. By default, in this situation + only the first sentence from the long string is used." + }; + + std::size_t --option-length = 0 + { + "", + "Indent option descriptions characters when printing usage. This is + useful when you have multiple options classes, potentially in separate + files, and would like their usage to have the same indentation level." }; bool --generate-cxx { - "" + "Generate C++ code. If neither \cb{--generate-man} nor \cb{--generate-html} + is specified, this mode is assumed by default." }; bool --generate-man { - "" + "Generate documentation in the man page format." }; bool --generate-html { - "" + "Generate documentation in the HTML format." }; - bool --stdout + std::string --man-prologue { - "" + "", + "Insert the content of at the beginning of the man page file." }; - std::size_t --option-length = 0 + std::string --man-epilogue { - "", - "Indent option description characters when printing usage." + "", + "Insert the content of at the end of the man page file." + }; + + std::string --html-prologue + { + "", + "Insert the content of at the beginning of the HTML file." + }; + + std::string --html-epilogue + { + "", + "Insert the content of at the end of the HTML file." + }; + + std::string --class + { + "", + "Generate the man page or HTML documentation only for the options + class. The name should be a fully-qualified options class name, + for example, \cb{app::options}. This functionality is useful if you need + to insert custom documentation between options belonging to different + classes." + }; + + bool --stdout + { + "Write output to STDOUT instead of a file. This option is not valid + when generating C++ code and is normally used to combine generated + documentation for several option classes in a single file." }; std::string --hxx-suffix = ".hxx" { "", - "Use instead of the default '.hxx' to construct the name of + "Use instead of the default \cb{.hxx} to construct the name of the generated header file." }; std::string --ixx-suffix = ".ixx" { "", - "Use instead of the default '.ixx' to construct the name of + "Use instead of the default \cb{.ixx} to construct the name of the generated inline file." }; std::string --cxx-suffix = ".cxx" { "", - "Use instead of the default '.cxx' to construct the name of + "Use instead of the default \cb{.cxx} to construct the name of the generated source file." }; + std::string --man-suffix = ".1" + { + "", + "Use instead of the default \cb{.1} to construct the name of + the generated man page file." + }; + std::string --html-suffix = ".html" { "", - "Use instead of the default '.html' to construct the name of - the generated HTML file." + "Use instead of the default \cb{.html} to construct the name + of the generated HTML file." }; std::string --option-prefix = "-" { "", - "Use instead of the default '-' as an option prefix." + "Use instead of the default \cb{-} as an option prefix. Unknown + command line arguments that start with this prefix are treated as unknown + options. If you set the option prefix to the empty value, then all the + unknown command line arguments will be treated as program arguments." }; std::string --option-separator = "--" { "", - "Use instead of the default '--' as an optional separator between - options and arguments." + "Use instead of the default \cb{--} as an optional separator between + options and arguments. All the command line arguments that are parsed + after this separator are treated as program arguments. Set the option + separator to the empty value if you don't want this functionality." }; bool --include-with-brackets { - "Use angle brackets (<>) instead of quotes (\"\") in generated #include - directives." + "Use angle brackets (<>) instead of quotes (\"\") in the generated + \cb{#include} directives." }; std::string --include-prefix { "", - "Add to generated #include directive paths." + "Add to the generated \cb{#include} directive paths." }; std::string --guard-prefix { "", - "Add to generated header inclusion guards." + "Add to the generated header inclusion guards. The prefix is + transformed to upper case and characters that are illegal in a + preprocessor macro name are replaced with underscores." }; std::map --reserved-name { "=", - "Add to the list of names that should not be used as identifiers. - The name can optionally be followed by '=' and the replacement - name that should be used instead.", - "" + "Add with an optional replacement to the list of names + that should not be used as identifiers. If provided, the replacement + name is used instead. All C++ keywords are already in this list." }; }; diff --git a/cli/options.cxx b/cli/options.cxx index 1f495b9..38ed14d 100644 --- a/cli/options.cxx +++ b/cli/options.cxx @@ -243,14 +243,21 @@ options (int argc, output_dir_ (), suppress_inline_ (), suppress_usage_ (), + long_usage_ (), + option_length_ (0), generate_cxx_ (), generate_man_ (), generate_html_ (), + man_prologue_ (), + man_epilogue_ (), + html_prologue_ (), + html_epilogue_ (), + class__ (), stdout_ (), - option_length_ (0), hxx_suffix_ (".hxx"), ixx_suffix_ (".ixx"), cxx_suffix_ (".cxx"), + man_suffix_ (".1"), html_suffix_ (".html"), option_prefix_ ("-"), option_separator_ ("--"), @@ -273,14 +280,21 @@ options (int start, output_dir_ (), suppress_inline_ (), suppress_usage_ (), + long_usage_ (), + option_length_ (0), generate_cxx_ (), generate_man_ (), generate_html_ (), + man_prologue_ (), + man_epilogue_ (), + html_prologue_ (), + html_epilogue_ (), + class__ (), stdout_ (), - option_length_ (0), hxx_suffix_ (".hxx"), ixx_suffix_ (".ixx"), cxx_suffix_ (".cxx"), + man_suffix_ (".1"), html_suffix_ (".html"), option_prefix_ ("-"), option_separator_ ("--"), @@ -303,14 +317,21 @@ options (int argc, output_dir_ (), suppress_inline_ (), suppress_usage_ (), + long_usage_ (), + option_length_ (0), generate_cxx_ (), generate_man_ (), generate_html_ (), + man_prologue_ (), + man_epilogue_ (), + html_prologue_ (), + html_epilogue_ (), + class__ (), stdout_ (), - option_length_ (0), hxx_suffix_ (".hxx"), ixx_suffix_ (".ixx"), cxx_suffix_ (".cxx"), + man_suffix_ (".1"), html_suffix_ (".html"), option_prefix_ ("-"), option_separator_ ("--"), @@ -334,14 +355,21 @@ options (int start, output_dir_ (), suppress_inline_ (), suppress_usage_ (), + long_usage_ (), + option_length_ (0), generate_cxx_ (), generate_man_ (), generate_html_ (), + man_prologue_ (), + man_epilogue_ (), + html_prologue_ (), + html_epilogue_ (), + class__ (), stdout_ (), - option_length_ (0), hxx_suffix_ (".hxx"), ixx_suffix_ (".ixx"), cxx_suffix_ (".cxx"), + man_suffix_ (".1"), html_suffix_ (".html"), option_prefix_ ("-"), option_separator_ ("--"), @@ -360,22 +388,41 @@ print_usage (::std::ostream& os) os << "--version Print version and exit." << ::std::endl; - os << "--output-dir|-o Write generated files to ." << ::std::endl; + os << "--output-dir|-o Write the generated files to instead of the" << ::std::endl + << " current directory." << ::std::endl; os << "--suppress-inline Generate all functions non-inline." << ::std::endl; - os << "--suppress-usage Suppress generation of usage printing code." << ::std::endl; + os << "--suppress-usage Suppress the generation of the usage printing code." << ::std::endl; - os << "--generate-cxx" << std::endl; + os << "--long-usage If no short documentation string is provided, use" << ::std::endl + << " the complete long documentation string in usage." << ::std::endl; - os << "--generate-man" << std::endl; + os << "--option-length Indent option descriptions characters when" << ::std::endl + << " printing usage." << ::std::endl; - os << "--generate-html" << std::endl; + os << "--generate-cxx Generate C++ code." << ::std::endl; - os << "--stdout" << std::endl; + os << "--generate-man Generate documentation in the man page format." << ::std::endl; - os << "--option-length Indent option description characters when" << ::std::endl - << " printing usage." << ::std::endl; + os << "--generate-html Generate documentation in the HTML format." << ::std::endl; + + os << "--man-prologue Insert the content of at the beginning of" << ::std::endl + << " the man page file." << ::std::endl; + + os << "--man-epilogue Insert the content of at the end of the man" << ::std::endl + << " page file." << ::std::endl; + + os << "--html-prologue Insert the content of at the beginning of" << ::std::endl + << " the HTML file." << ::std::endl; + + os << "--html-epilogue Insert the content of at the end of the HTML" << ::std::endl + << " file." << ::std::endl; + + os << "--class Generate the man page or HTML documentation only" << ::std::endl + << " for the options class." << ::std::endl; + + os << "--stdout Write output to STDOUT instead of a file." << ::std::endl; os << "--hxx-suffix Use instead of the default '.hxx' to" << ::std::endl << " construct the name of the generated header file." << ::std::endl; @@ -386,6 +433,9 @@ print_usage (::std::ostream& os) os << "--cxx-suffix Use instead of the default '.cxx' to" << ::std::endl << " construct the name of the generated source file." << ::std::endl; + os << "--man-suffix Use instead of the default '.1' to" << ::std::endl + << " construct the name of the generated man page file." << ::std::endl; + os << "--html-suffix Use instead of the default '.html' to" << ::std::endl << " construct the name of the generated HTML file." << ::std::endl; @@ -396,16 +446,17 @@ print_usage (::std::ostream& os) << " optional separator between options and arguments." << ::std::endl; os << "--include-with-brackets Use angle brackets (<>) instead of quotes (\"\") in" << ::std::endl - << " generated #include directives." << ::std::endl; + << " the generated '#include' directives." << ::std::endl; - os << "--include-prefix Add to generated #include directive paths." << ::std::endl; + os << "--include-prefix Add to the generated '#include' directive" << ::std::endl + << " paths." << ::std::endl; - os << "--guard-prefix Add to generated header inclusion guards." << ::std::endl; + os << "--guard-prefix Add to the generated header inclusion" << ::std::endl + << " guards." << ::std::endl; - os << "--reserved-name = Add to the list of names that should not be" << ::std::endl - << " used as identifiers. The name can optionally be" << ::std::endl - << " followed by '=' and the replacement name that" << ::std::endl - << " should be used instead." << ::std::endl; + os << "--reserved-name = Add with an optional replacement to" << ::std::endl + << " the list of names that should not be used as" << ::std::endl + << " identifiers." << ::std::endl; } typedef @@ -430,22 +481,36 @@ struct _cli_options_map_init &::cli::thunk< options, bool, &options::suppress_inline_ >; _cli_options_map_["--suppress-usage"] = &::cli::thunk< options, bool, &options::suppress_usage_ >; + _cli_options_map_["--long-usage"] = + &::cli::thunk< options, bool, &options::long_usage_ >; + _cli_options_map_["--option-length"] = + &::cli::thunk< options, std::size_t, &options::option_length_ >; _cli_options_map_["--generate-cxx"] = &::cli::thunk< options, bool, &options::generate_cxx_ >; _cli_options_map_["--generate-man"] = &::cli::thunk< options, bool, &options::generate_man_ >; _cli_options_map_["--generate-html"] = &::cli::thunk< options, bool, &options::generate_html_ >; + _cli_options_map_["--man-prologue"] = + &::cli::thunk< options, std::string, &options::man_prologue_ >; + _cli_options_map_["--man-epilogue"] = + &::cli::thunk< options, std::string, &options::man_epilogue_ >; + _cli_options_map_["--html-prologue"] = + &::cli::thunk< options, std::string, &options::html_prologue_ >; + _cli_options_map_["--html-epilogue"] = + &::cli::thunk< options, std::string, &options::html_epilogue_ >; + _cli_options_map_["--class"] = + &::cli::thunk< options, std::string, &options::class__ >; _cli_options_map_["--stdout"] = &::cli::thunk< options, bool, &options::stdout_ >; - _cli_options_map_["--option-length"] = - &::cli::thunk< options, std::size_t, &options::option_length_ >; _cli_options_map_["--hxx-suffix"] = &::cli::thunk< options, std::string, &options::hxx_suffix_ >; _cli_options_map_["--ixx-suffix"] = &::cli::thunk< options, std::string, &options::ixx_suffix_ >; _cli_options_map_["--cxx-suffix"] = &::cli::thunk< options, std::string, &options::cxx_suffix_ >; + _cli_options_map_["--man-suffix"] = + &::cli::thunk< options, std::string, &options::man_suffix_ >; _cli_options_map_["--html-suffix"] = &::cli::thunk< options, std::string, &options::html_suffix_ >; _cli_options_map_["--option-prefix"] = diff --git a/cli/options.hxx b/cli/options.hxx index 96f50e6..fdf7627 100644 --- a/cli/options.hxx +++ b/cli/options.hxx @@ -190,6 +190,12 @@ class options suppress_usage () const; const bool& + long_usage () const; + + const std::size_t& + option_length () const; + + const bool& generate_cxx () const; const bool& @@ -198,12 +204,24 @@ class options const bool& generate_html () const; + const std::string& + man_prologue () const; + + const std::string& + man_epilogue () const; + + const std::string& + html_prologue () const; + + const std::string& + html_epilogue () const; + + const std::string& + class_ () const; + const bool& stdout () const; - const std::size_t& - option_length () const; - const std::string& hxx_suffix () const; @@ -214,6 +232,9 @@ class options cxx_suffix () const; const std::string& + man_suffix () const; + + const std::string& html_suffix () const; const std::string& @@ -253,14 +274,21 @@ class options std::string output_dir_; bool suppress_inline_; bool suppress_usage_; + bool long_usage_; + std::size_t option_length_; bool generate_cxx_; bool generate_man_; bool generate_html_; + std::string man_prologue_; + std::string man_epilogue_; + std::string html_prologue_; + std::string html_epilogue_; + std::string class__; bool stdout_; - std::size_t option_length_; std::string hxx_suffix_; std::string ixx_suffix_; std::string cxx_suffix_; + std::string man_suffix_; std::string html_suffix_; std::string option_prefix_; std::string option_separator_; diff --git a/cli/options.ixx b/cli/options.ixx index 6cf5899..1745d4a 100644 --- a/cli/options.ixx +++ b/cli/options.ixx @@ -119,6 +119,18 @@ suppress_usage () const } inline const bool& options:: +long_usage () const +{ + return long_usage_; +} + +inline const std::size_t& options:: +option_length () const +{ + return option_length_; +} + +inline const bool& options:: generate_cxx () const { return generate_cxx_; @@ -136,16 +148,40 @@ generate_html () const return generate_html_; } -inline const bool& options:: -stdout () const +inline const std::string& options:: +man_prologue () const { - return stdout_; + return man_prologue_; } -inline const std::size_t& options:: -option_length () const +inline const std::string& options:: +man_epilogue () const { - return option_length_; + return man_epilogue_; +} + +inline const std::string& options:: +html_prologue () const +{ + return html_prologue_; +} + +inline const std::string& options:: +html_epilogue () const +{ + return html_epilogue_; +} + +inline const std::string& options:: +class_ () const +{ + return class__; +} + +inline const bool& options:: +stdout () const +{ + return stdout_; } inline const std::string& options:: @@ -167,6 +203,12 @@ cxx_suffix () const } inline const std::string& options:: +man_suffix () const +{ + return man_suffix_; +} + +inline const std::string& options:: html_suffix () const { return html_suffix_; diff --git a/cli/source.cxx b/cli/source.cxx index 4cfd425..f473665 100644 --- a/cli/source.cxx +++ b/cli/source.cxx @@ -188,7 +188,7 @@ namespace // If we have both the long and the short descriptions, use // the short one. Otherwise, use the first sentence from the - // long one. + // long one ubless --long-usage was specified. // string d; @@ -197,14 +197,14 @@ namespace if (doc.size () > 1) d = doc[0]; else if (doc.size () > 0) - d = frist_sentence (doc[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 = frist_sentence (doc[1]); + d = options.long_usage () ? doc[1] : first_sentence (doc[1]); } // Format the documentation string. @@ -281,7 +281,7 @@ namespace } string - frist_sentence (string const& s) + first_sentence (string const& s) { size_t p (s.find ('.')); -- cgit v1.1