summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL30
-rw-r--r--README.md35
-rw-r--r--buildfile9
-rw-r--r--cli-examples/manifest4
-rw-r--r--cli-tests/manifest4
-rw-r--r--cli/build/root.build47
-rw-r--r--cli/cli/.gitignore6
-rw-r--r--cli/cli/bootstrap/cli/options.cxx (renamed from cli/cli/options.cxx)37
-rw-r--r--cli/cli/bootstrap/cli/options.hxx (renamed from cli/cli/options.hxx)50
-rw-r--r--cli/cli/bootstrap/cli/options.ixx (renamed from cli/cli/options.ixx)53
-rw-r--r--cli/cli/buildfile136
-rw-r--r--cli/cli/cli.cxx8
-rw-r--r--cli/doc/.gitignore7
-rw-r--r--cli/doc/bootstrap/cli.1416
-rw-r--r--cli/doc/bootstrap/cli.xhtml573
-rw-r--r--cli/doc/buildfile117
-rw-r--r--cli/doc/cli-guide.xhtml (renamed from cli/doc/guide/index.xhtml)0
-rw-r--r--cli/doc/cli-prologue.12
-rw-r--r--cli/doc/cli-prologue.xhtml2
-rwxr-xr-xcli/doc/doc.sh78
-rw-r--r--cli/doc/guide.html2ps (renamed from cli/doc/guide/guide.html2ps)0
-rw-r--r--cli/doc/guide/.gitignore2
-rw-r--r--cli/manifest10
23 files changed, 1389 insertions, 237 deletions
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 19bc883..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,30 +0,0 @@
-CLI uses itself for command line options parsing which makes it a bit tricky
-to develop. Below is one way to setup the development environment:
-
-$ git clone .../cli.git
-$ cd cli
-$ bdep init -C ../builds/main @main cc # Main build.
-$ bdep update # Using pre-geneared code.
-$ bdep init -d cli/ -C ../builds/save @save cc # "Saved" build.
-$ bdep update @save
-
-# @@ This does not currently work because bdep (bpkg) will drop it on next
-# sync (reconfigure).
-#
-#$ b configure: ../builds/main/cli/ \
-# config.cli="$(realpath ../builds/save/cli/cli/cli)"
-
-$ echo >>../builds/main/build/config.build \
- "cli/ config.cli=$(realpath ../builds/save/cli/cli/cli)"
-
-$ bdep update # Regenerate code.
-
-Then, when making changes that affect the generated code, perform the
-following sequence of steps (the key thing to keep in mind is that the saved
-configuration will use generated code from source directory that is
-backlinked during the main build):
-
-$ b cli/ # Regenerate using old saved.
-$ bdep update @save # Update saved.
-$ b cli/ # Regenerate using new saved.
-$ bdep update @save # Update saved.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c2dd3ea
--- /dev/null
+++ b/README.md
@@ -0,0 +1,35 @@
+# CLI
+
+CLI is a command line interface compiler for C++.
+
+The development setup for CLI uses two configurations, for example:
+
+```
+git clone .../cli.git
+cd cli
+
+bdep init --empty
+
+bdep config create @host ../cli-host --type host cc config.cxx=g++
+bdep config create @target ../cli-target cc config.cxx=g++
+
+bdep init @host -d cli
+bdep init @target -d cli-tests -d cli-examples
+
+```
+
+To generate the documentation in the `.ps` and `.pdf` formats, `html2ps` and
+`ps2pdf14` programs are required (the latter is from `ghostscript`). A warning
+is issued in the development mode if these programs are not available.
+
+Note that the development build cannot be installed (due to the bootstrap
+process; see `cli/build/root.build` for details). To test installation, a
+seperate, non-development build can be created:
+
+```
+bdep config create @install ../cli-install --type host cc config.cxx=g++ \
+ config.install.root=/tmp/install
+
+bdep init @install -d cli config.cli.develop=false
+b install: ../cli-install/cli/
+```
diff --git a/buildfile b/buildfile
index 6d9e95d..c3c8909 100644
--- a/buildfile
+++ b/buildfile
@@ -1,7 +1,6 @@
-# file : buildfile
-# license : MIT; see accompanying LICENSE file
+# Glue buildfile that "pulls" all the packages in the project.
+#
+import pkgs = [dir_paths] $process.run_regex(\
+ cat $src_root/packages.manifest, '\s*location\s*:\s*(\S+)\s*', '\1')
-# Glue buildfile that "pulls" all the packages.
-
-import pkgs = */
./: $pkgs
diff --git a/cli-examples/manifest b/cli-examples/manifest
index da9cc56..9f016b5 100644
--- a/cli-examples/manifest
+++ b/cli-examples/manifest
@@ -10,5 +10,5 @@ doc-url: https://www.codesynthesis.com/projects/cli/doc/guide/
src-url: https://git.codesynthesis.com/cgit/cli/cli/tree/cli-examples/
email: cli-users@codesynthesis.com ; Mailing list
requires: c++14
-depends: * build2 >= 0.13.0
-depends: * bpkg >= 0.13.0
+depends: * build2 >= 0.14.0-
+depends: * bpkg >= 0.14.0-
diff --git a/cli-tests/manifest b/cli-tests/manifest
index 0ff0825..8cd78eb 100644
--- a/cli-tests/manifest
+++ b/cli-tests/manifest
@@ -10,5 +10,5 @@ doc-url: https://www.codesynthesis.com/projects/cli/doc/guide/
src-url: https://git.codesynthesis.com/cgit/cli/cli/tree/cli-tests/
email: cli-users@codesynthesis.com ; Mailing list
requires: c++14
-depends: * build2 >= 0.13.0
-depends: * bpkg >= 0.13.0
+depends: * build2 >= 0.14.0-
+depends: * bpkg >= 0.14.0-
diff --git a/cli/build/root.build b/cli/build/root.build
index 476b192..6132356 100644
--- a/cli/build/root.build
+++ b/cli/build/root.build
@@ -1,24 +1,15 @@
# file : build/root.build
# license : MIT; see accompanying LICENSE file
-# Regenerate the options parsing code (included into the repository).
+# Note that we cannot install the development build. This is due to both the
+# bootstrap cli (which we need to run) and the final cli (which we need to
+# install) depending on libcutl (so we need it to be both "for-install" and
+# "for-run"). Nor can we run the final cli to generate the man pages.
#
-# Note that this is the same variable as what's used by the import machinery
-# when we import cli%exe{cli}. Here, however, we require it to be explicitly
-# specified (i.e., no default search in PATH) in order for the regeneration
-# to be enabled.
-#
-# Normally, in the development build, this variable will be set only in the
-# cli package configuration to point to its own binary (or a binary in another
-# build configuration if you want to play it safe).
-#
-# Note, though, that currently referring to the cli target in the project
-# itself ends up with the 'dependency cycle detected' error. In the future we
-# will fix that by using an ad hoc recipe instead of the cli module. But for
-# now you can workaround this issue by pointing to a binary in another
-# configuration.
-#
-config [path] config.cli
+config [bool] config.cli.develop ?= false
+
+define cli: file
+cli{*}: extension = cli
cxx.std = latest
@@ -35,20 +26,14 @@ if ($cxx.target.system == 'win32-msvc')
if ($cxx.class == 'msvc')
cxx.coptions += /wd4251 /wd4275 /wd4800
-cxx.poptions =+ "-I$out_root" "-I$src_root"
-
-# Load the cli module only if explicitly requested. This way a distribution
-# that includes pre-generated files can be built without installing cli. This
-# is also the reason why we need to explicitly spell out individual source
-# file prerequisites instead of using the cli.cxx{} group (it won't be there
-# unless the module is configured).
-#
-# @@ Replace with import when the parsing code regenerating is implemented
-# via an ad hoc recipe.
-#
-if ($config.cli != [null] && $config.cli != false)
- using cli
-
# Specify the test target for cross-testing.
#
test.target = $cxx.target
+
+# Extract the copyright notice from the LICENSE file.
+#
+# Note that cat is a builtin which means this is both portable and fast.
+#
+copyright = $process.run_regex(cat $src_root/LICENSE, \
+ 'Copyright \(c\) (.+)\.', \
+ '\1')
diff --git a/cli/cli/.gitignore b/cli/cli/.gitignore
index 903d015..79562f1 100644
--- a/cli/cli/.gitignore
+++ b/cli/cli/.gitignore
@@ -1,5 +1,7 @@
-cli
-version.hxx
+/cli
+/bootstrap/cli/cli
+/version.hxx
+/options.?xx
# Unit test executables and Testscript output directories (can be symlinks).
#
diff --git a/cli/cli/options.cxx b/cli/cli/bootstrap/cli/options.cxx
index 0f0604a..56dd24f 100644
--- a/cli/cli/options.cxx
+++ b/cli/cli/bootstrap/cli/options.cxx
@@ -15,6 +15,7 @@
#include <set>
#include <string>
#include <vector>
+#include <utility>
#include <ostream>
#include <sstream>
#include <cstring>
@@ -196,6 +197,7 @@ namespace cli
else
++i_;
+ ++start_position_;
return r;
}
else
@@ -206,11 +208,20 @@ namespace cli
skip ()
{
if (i_ < argc_)
+ {
++i_;
+ ++start_position_;
+ }
else
throw eos_reached ();
}
+ std::size_t argv_scanner::
+ position ()
+ {
+ return start_position_;
+ }
+
// argv_file_scanner
//
int argv_file_scanner::zero_argc_ = 0;
@@ -321,6 +332,7 @@ namespace cli
{
hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value);
args_.pop_front ();
+ ++start_position_;
return hold_[i_].c_str ();
}
}
@@ -334,7 +346,10 @@ namespace cli
if (args_.empty ())
return base::skip ();
else
+ {
args_.pop_front ();
+ ++start_position_;
+ }
}
const argv_file_scanner::option_info* argv_file_scanner::
@@ -347,6 +362,12 @@ namespace cli
return 0;
}
+ std::size_t argv_file_scanner::
+ position ()
+ {
+ return start_position_;
+ }
+
void argv_file_scanner::
load (const std::string& file)
{
@@ -546,6 +567,17 @@ namespace cli
};
template <typename X>
+ struct parser<std::pair<X, std::size_t> >
+ {
+ static void
+ parse (std::pair<X, std::size_t>& x, bool& xs, scanner& s)
+ {
+ x.second = s.position ();
+ parser<X>::parse (x.first, xs, s);
+ }
+ };
+
+ template <typename X>
struct parser<std::vector<X> >
{
static void
@@ -583,6 +615,7 @@ namespace cli
if (s.more ())
{
+ std::size_t pos (s.position ());
std::string ov (s.next ());
std::string::size_type p = ov.find ('=');
@@ -602,14 +635,14 @@ namespace cli
if (!kstr.empty ())
{
av[1] = const_cast<char*> (kstr.c_str ());
- argv_scanner s (0, ac, av);
+ argv_scanner s (0, ac, av, false, pos);
parser<K>::parse (k, dummy, s);
}
if (!vstr.empty ())
{
av[1] = const_cast<char*> (vstr.c_str ());
- argv_scanner s (0, ac, av);
+ argv_scanner s (0, ac, av, false, pos);
parser<V>::parse (v, dummy, s);
}
diff --git a/cli/cli/options.hxx b/cli/cli/bootstrap/cli/options.hxx
index b54d81f..35108fa 100644
--- a/cli/cli/options.hxx
+++ b/cli/cli/bootstrap/cli/options.hxx
@@ -236,6 +236,14 @@ namespace cli
// for the two previous arguments up until a call to a third
// peek() or next().
//
+ // The position() function returns a monotonically-increasing
+ // number which, if stored, can later be used to determine the
+ // relative position of the argument returned by the following
+ // call to next(). Note that if multiple scanners are used to
+ // extract arguments from multiple sources, then the end
+ // position of the previous scanner should be used as the
+ // start position of the next.
+ //
class scanner
{
public:
@@ -253,13 +261,24 @@ namespace cli
virtual void
skip () = 0;
+
+ virtual std::size_t
+ position () = 0;
};
class argv_scanner: public scanner
{
public:
- argv_scanner (int& argc, char** argv, bool erase = false);
- argv_scanner (int start, int& argc, char** argv, bool erase = false);
+ argv_scanner (int& argc,
+ char** argv,
+ bool erase = false,
+ std::size_t start_position = 0);
+
+ argv_scanner (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ std::size_t start_position = 0);
int
end () const;
@@ -276,7 +295,11 @@ namespace cli
virtual void
skip ();
- private:
+ virtual std::size_t
+ position ();
+
+ protected:
+ std::size_t start_position_;
int i_;
int& argc_;
char** argv_;
@@ -289,16 +312,19 @@ namespace cli
argv_file_scanner (int& argc,
char** argv,
const std::string& option,
- bool erase = false);
+ bool erase = false,
+ std::size_t start_position = 0);
argv_file_scanner (int start,
int& argc,
char** argv,
const std::string& option,
- bool erase = false);
+ bool erase = false,
+ std::size_t start_position = 0);
argv_file_scanner (const std::string& file,
- const std::string& option);
+ const std::string& option,
+ std::size_t start_position = 0);
struct option_info
{
@@ -315,18 +341,21 @@ namespace cli
char** argv,
const option_info* options,
std::size_t options_count,
- bool erase = false);
+ bool erase = false,
+ std::size_t start_position = 0);
argv_file_scanner (int start,
int& argc,
char** argv,
const option_info* options,
std::size_t options_count,
- bool erase = false);
+ bool erase = false,
+ std::size_t start_position = 0);
argv_file_scanner (const std::string& file,
const option_info* options = 0,
- std::size_t options_count = 0);
+ std::size_t options_count = 0,
+ std::size_t start_position = 0);
virtual bool
more ();
@@ -340,6 +369,9 @@ namespace cli
virtual void
skip ();
+ virtual std::size_t
+ position ();
+
// Return the file path if the peeked at argument came from a file and
// the empty string otherwise. The reference is guaranteed to be valid
// till the end of the scanner lifetime.
diff --git a/cli/cli/options.ixx b/cli/cli/bootstrap/cli/options.ixx
index 4461340..ee4cbdb 100644
--- a/cli/cli/options.ixx
+++ b/cli/cli/bootstrap/cli/options.ixx
@@ -141,14 +141,29 @@ namespace cli
// argv_scanner
//
inline argv_scanner::
- argv_scanner (int& argc, char** argv, bool erase)
- : i_ (1), argc_ (argc), argv_ (argv), erase_ (erase)
+ argv_scanner (int& argc,
+ char** argv,
+ bool erase,
+ std::size_t sp)
+ : start_position_ (sp + 1),
+ i_ (1),
+ argc_ (argc),
+ argv_ (argv),
+ erase_ (erase)
{
}
inline argv_scanner::
- argv_scanner (int start, int& argc, char** argv, bool erase)
- : i_ (start), argc_ (argc), argv_ (argv), erase_ (erase)
+ argv_scanner (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ std::size_t sp)
+ : start_position_ (sp + static_cast<std::size_t> (start)),
+ i_ (start),
+ argc_ (argc),
+ argv_ (argv),
+ erase_ (erase)
{
}
@@ -164,8 +179,9 @@ namespace cli
argv_file_scanner (int& argc,
char** argv,
const std::string& option,
- bool erase)
- : argv_scanner (argc, argv, erase),
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (argc, argv, erase, sp),
option_ (option),
options_ (&option_info_),
options_count_ (1),
@@ -181,8 +197,9 @@ namespace cli
int& argc,
char** argv,
const std::string& option,
- bool erase)
- : argv_scanner (start, argc, argv, erase),
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (start, argc, argv, erase, sp),
option_ (option),
options_ (&option_info_),
options_count_ (1),
@@ -195,8 +212,9 @@ namespace cli
inline argv_file_scanner::
argv_file_scanner (const std::string& file,
- const std::string& option)
- : argv_scanner (0, zero_argc_, 0),
+ const std::string& option,
+ std::size_t sp)
+ : argv_scanner (0, zero_argc_, 0, sp),
option_ (option),
options_ (&option_info_),
options_count_ (1),
@@ -214,8 +232,9 @@ namespace cli
char** argv,
const option_info* options,
std::size_t options_count,
- bool erase)
- : argv_scanner (argc, argv, erase),
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (argc, argv, erase, sp),
options_ (options),
options_count_ (options_count),
i_ (1),
@@ -229,8 +248,9 @@ namespace cli
char** argv,
const option_info* options,
std::size_t options_count,
- bool erase)
- : argv_scanner (start, argc, argv, erase),
+ bool erase,
+ std::size_t sp)
+ : argv_scanner (start, argc, argv, erase, sp),
options_ (options),
options_count_ (options_count),
i_ (1),
@@ -241,8 +261,9 @@ namespace cli
inline argv_file_scanner::
argv_file_scanner (const std::string& file,
const option_info* options,
- std::size_t options_count)
- : argv_scanner (0, zero_argc_, 0),
+ std::size_t options_count,
+ std::size_t sp)
+ : argv_scanner (0, zero_argc_, 0, sp),
options_ (options),
options_count_ (options_count),
i_ (1),
diff --git a/cli/cli/buildfile b/cli/cli/buildfile
index 2385a7d..dc5d75b 100644
--- a/cli/cli/buildfile
+++ b/cli/cli/buildfile
@@ -15,63 +15,119 @@ exe{cli}:
cli.checksum = $version
}
-libue{cli}: {hxx ixx txx cxx}{** -cli -version -options -**.test...} \
- {hxx}{version} {hxx ixx cxx}{options} \
- $libs
+hdr = {hxx ixx txx}{* -cli -version -options -*.test...}
+src = cxx{* -cli -version -options -*.test...}
+
+all_s = semantics/{hxx ixx txx cxx}{*}
+all_t = traversal/{hxx ixx txx cxx}{*}
+
+libue{cli}: $hdr $src $all_s $all_t {hxx}{version} $libs
hxx{version}: in{version} $src_root/manifest
-# Unit tests.
+# Build options (both bootstrap and final version).
#
-exe{*.test}:
+cxx.poptions =+ "-I$out_root" "-I$src_root"
+
+# Bootstrap.
+#
+# The plan is as follows:
+#
+# 1. Build the bootstrap version of cli using a copy of options.?xx saved in
+# bootstrap/cli/.
+#
+# 2. Use that to re-generate options.?xx. If the result differs from the
+# saved version, copy it over and fail the build, asking for a restart.
+#
+# 3. Otherwise, proceed to build the final version of cli.
+#
+if $config.cli.develop
{
- test = true
- install = false
-}
+ libue{cli}: {hxx ixx cxx}{options}
-for t: cxx{**.test...}
+ bootstrap/
+ {
+ # This should only apply to the bootstrap build.
+ #
+ cxx.poptions =+ "-I$src_base" # Note: must come first.
+
+ cli/
+ {
+ # Note: semantics/ and traversal/ do not include options.hxx so we can
+ # share their object files.
+ #
+ exe{cli}: obj{cli $name($src) options} ../../{$all_s $all_t} $libs
+
+ for s: cli $name($src)
+ obj{$s}: ../../cxx{$s} $libs
+
+ obj{options}: {hxx ixx cxx}{options}
+
+ obj{cli}: cxx.poptions += -DCLI_BOOTSTRAP
+ }
+ }
+
+ <{hxx ixx cxx}{options}>: cli{options} bootstrap/cli/exe{cli}
+ {
+ options = --include-with-brackets --include-prefix cli \
+ --guard-prefix CLI --generate-file-scanner \
+ --generate-specifier --generate-modifier \
+ --suppress-undocumented --reserved-name stdout
+
+ # Symlink the generated code in src for convenience of development.
+ #
+ backlink = true
+ }
+ {{
+ diag cli ($<[0])
+ ($<[1]) $options -o $out_base $path($<[0])
+
+ # If the result differs from the bootstrap version, copy it over and
+ # request the build restart.
+ #
+ if diff $src_base/bootstrap/cli/options.hxx $path($>[0]) >- && \
+ diff $src_base/bootstrap/cli/options.ixx $path($>[1]) >- && \
+ diff $src_base/bootstrap/cli/options.cxx $path($>[2]) >-
+ exit
+ end
+
+ cp $path($>[0]) $src_base/bootstrap/cli/options.hxx
+ cp $path($>[1]) $src_base/bootstrap/cli/options.ixx
+ cp $path($>[2]) $src_base/bootstrap/cli/options.cxx
+
+ exit "bootstrap options.?xx have changed, restart the build"
+ }}
+}
+else
{
- d = $directory($t)
- n = $name($t)...
+ # Use bootstrap options.?xx to build the final version of cli.
+ #
+ libue{cli}: bootstrap/cli/{hxx ixx cxx}{options}
+ cxx.poptions =+ "-I($src_base/bootstrap)" # Note: must come first.
- ./: $d/exe{$n}: $t $d/{hxx ixx txx}{+$n} $d/testscript{+$n}
- $d/exe{$n}: libue{cli}: bin.whole = false
+ ./: cli{options} # Keep in distribution.
}
-# Build options.
+# Build options (final version only).
#
+
# Pass the copyright notice extracted from the LICENSE file.
#
-copyright = $process.run_regex(cat $src_root/LICENSE, \
- 'Copyright \(c\) (.+)\.', \
- '\1')
-
obj{cli}: cxx.poptions += -DCLI_COPYRIGHT=\"$copyright\"
-# Generated options parsing code.
-#
-# @@ This will eventually be replaced with an ah hoc recipe.
+# Unit tests.
#
-if ($config.cli != [null] && $config.cli != false)
+exe{*.test}:
{
- cli.cxx{options}: cli{options}
-
- cli.options += --include-with-brackets --include-prefix cli \
---guard-prefix CLI --generate-file-scanner --generate-specifier \
---generate-modifier --suppress-undocumented --reserved-name stdout
+ test = true
+ install = false
+}
- cli.cxx{*}:
- {
- # Include the generated cli files into the distribution and don't remove
- # them when cleaning in src (so that clean results in a state identical to
- # distributed).
- #
- dist = true
- clean = ($src_root != $out_root)
+for t: cxx{**.test...}
+{
+ d = $directory($t)
+ n = $name($t)...
- # We keep the generated code in the repository so copy it back to src
- # in case of a forwarded configuration.
- #
- backlink = overwrite
- }
+ ./: $d/exe{$n}: $t $d/{hxx ixx txx}{+$n} $d/testscript{+$n}
+ $d/exe{$n}: libue{cli}: bin.whole = false
}
diff --git a/cli/cli/cli.cxx b/cli/cli/cli.cxx
index 11cf6c0..f1196de 100644
--- a/cli/cli/cli.cxx
+++ b/cli/cli/cli.cxx
@@ -16,7 +16,13 @@
#include <cli/parser.hxx>
#include <cli/generator.hxx>
-#include <cli/version.hxx>
+#ifndef CLI_BOOTSTRAP
+# include <cli/version.hxx>
+#else
+# define CLI_VERSION_ID 0
+# define CLI_VERSION_FULL 0
+# define CLI_COPYRIGHT ""
+#endif
using namespace std;
using namespace cutl;
diff --git a/cli/doc/.gitignore b/cli/doc/.gitignore
index 562ecbd..93bbd2d 100644
--- a/cli/doc/.gitignore
+++ b/cli/doc/.gitignore
@@ -1,2 +1,5 @@
-cli.xhtml
-cli.1
+*.ps
+*.pdf
+
+/cli.xhtml
+/cli.1
diff --git a/cli/doc/bootstrap/cli.1 b/cli/doc/bootstrap/cli.1
new file mode 100644
index 0000000..dae4474
--- /dev/null
+++ b/cli/doc/bootstrap/cli.1
@@ -0,0 +1,416 @@
+.\" Process this file with
+.\" groff -man -Tascii cli.1
+.\"
+.TH CLI 1 "January 2021" "CLI 1.2.0-b.7"
+.SH NAME
+cli \- command line interface compiler for C++
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH SYNOPSIS
+.\"--------------------------------------------------------------------
+.B cli
+.B [
+.I options
+.B ]
+.I file
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH DESCRIPTION
+.\"--------------------------------------------------------------------
+.B cli
+generates C++ implementation and documentation in various formats for a
+command line interface defined in the CLI language. For an input file in
+the form
+.B name.cli
+the following is generated. By default or if the
+.B --generate-cxx
+option is specified, the following C++ files are generated:
+.B name.hxx
+(header file),
+.B name.ixx
+(inline file, generated unless the
+.B --suppress-inline
+option is specified), and
+.B name.cxx (source file).
+If the
+.B --generate-html
+option is specified, then the
+.B name.html
+HTML documentation file is generated. If the
+.B --generate-man
+option is specified, then the
+.B name.1
+man page file is generated. When
+.B --generate-html
+or
+.B --generate-man
+is specified, the
+.B --stdout
+option can be used to redirect the output to STDOUT instead of a file.
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH OPTIONS
+.\"--------------------------------------------------------------------
+.IP "\fB--help\fR"
+Print usage information and exit\.
+.IP "\fB--version\fR"
+Print version and exit\.
+.IP "\fB--include-path\fR|\fB-I\fR \fIdir\fR"
+Search \fIdir\fR for bracket-included (\fB<>\fR) options files\.
+.IP "\fB--output-dir\fR|\fB-o\fR \fIdir\fR"
+Write the generated files to \fIdir\fR instead of the current directory\.
+.IP "\fB--std\fR \fIversion\fR"
+Specify the C++ standard that should be used during compilation\. Valid values
+are \fBc++98\fR (default), \fBc++11\fR, and \fBc++14\fR\.
+.IP "\fB--generate-modifier\fR"
+Generate option value modifiers in addition to accessors\.
+.IP "\fB--generate-specifier\fR"
+Generate functions for determining whether the option was specified on the
+command line\.
+.IP "\fB--generate-parse\fR"
+Generate \fBparse()\fR functions instead of parsing constructors\. This is
+primarily useful for being able to parse into an already initialized options
+class instance, for example, to implement option appending/overriding\.
+.IP "\fB--generate-merge\fR"
+Generate \fBmerge()\fR functions\. This is primarily useful for being able to
+merge several already parsed options class instances, for example, to
+implement option appending/overriding\. Note that this option forces
+\fB--generate-specifier\fR\.
+.IP "\fB--generate-description\fR"
+Generate the option description list that can be examined at runtime\.
+.IP "\fB--generate-file-scanner\fR"
+Generate the \fBargv_file_scanner\fR implementation\. This scanner is capable
+of reading command line arguments from the \fBargv\fR array as well as files
+specified with command line options\.
+.IP "\fB--generate-vector-scanner\fR"
+Generate the \fBvector_scanner\fR implementation\. This scanner is capable of
+reading command line arguments from \fBvector<string>\fR\.
+.IP "\fB--generate-group-scanner\fR"
+Generate the \fBgroup_scanner\fR implementation\. This scanner supports
+grouping of arguments (usually options) to apply only to a certain argument\.
+
+Groups can be specified before (leading) and/or after (trailing) the argument
+they apply to\. A leading group starts with '\fB{\fR' and ends with '\fB}+\fR'
+while a trailing group starts with '\fB+{\fR' and ends with '\fB}\fR'\. For
+example:
+
+.nf
+{ --foo --bar }+ arg # 'arg' with '--foo' '--bar'
+arg +{ fox=1 baz=2 } # 'arg' with 'fox=1' 'baz=2'
+.fi
+
+Multiple leading and/or trailing groups can be specified for the same
+argument\. For example:
+
+.nf
+{ -f }+ { -b }+ arg +{ f=1 } +{ b=2 } # 'arg' with '-f' 'b' 'f=1' 'b=2'
+.fi
+
+The group applies to a single argument only unless multiple arguments are
+themselves grouped with '\fB{\fR' and '\fB}\fR'\. For example:
+
+.nf
+{ --foo }+ arg1 arg2 +{ --bar } # 'arg1' with '--foo'
+ # 'arg2' with '--bar'
+
+{ --foo }+ { arg1 arg2 } +{ --bar } # 'arg1' with '--foo' '--bar'
+ # 'arg2' with '--foo' '--bar'
+.fi
+
+The group separators ('\fB{\fR', '\fB}+'\fR, etc) must be separate command
+line arguments\. In particular, they must not be adjacent either to the
+arguments inside the group nor to the argument they apply to\. All such cases
+will be treated as ordinary arguments\. For example:
+
+.nf
+{--foo}+ arg # '{--foo}+' \.\.\.
+arg+{ --foo } # 'arg+{' \.\.\.
+.fi
+
+If one of the group separators needs to be specified as an argument verbatim,
+then it must be escaped with '\fB\e\fR'\. For example:
+
+.nf
+} # error: unexpected group separator
+}x # '}x'
+\\} # '}'
+{ \\}+ }+ arg # 'arg' with '}+'
+.fi
+.IP "\fB--suppress-inline\fR"
+Generate all functions non-inline\. By default simple functions are made
+inline\. This option suppresses creation of the inline file\.
+.IP "\fB--suppress-cli\fR"
+Do not generate the CLI support types (scanners, parser, etc)\. Normally, the
+support types are generated unless another \fB\.cli\fR was included, in which
+case the support types are expected to be provided by its generated code\.
+.IP "\fB--cli-namespace\fR \fIns\fR"
+Generate the CLI support types in the \fIns\fR namespace (\fBcli\fR by
+default)\. The namespace can be nested, for example \fBdetails::cli\fR\. If
+the namespace is empty, then the support types are generated in the global
+namespace\.
+.IP "\fB--ostream-type\fR \fItype\fR"
+Output stream type instead of the default \fBstd::ostream\fR that should be
+used to print usage and exception information\.
+.IP "\fB--generate-cxx\fR"
+Generate C++ code\. If neither \fB--generate-man\fR, \fB--generate-html\fR,
+nor \fB--generate-txt\fR is specified, this mode is assumed by default\.
+.IP "\fB--generate-man\fR"
+Generate documentation in the man page format\.
+.IP "\fB--generate-html\fR"
+Generate documentation in the HTML format\.
+.IP "\fB--generate-txt\fR"
+Generate documentation in the plain text format, similar to usage\.
+.IP "\fB--stdout\fR"
+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\.
+.IP "\fB--suppress-undocumented\fR"
+Suppress the generation of documentation entries for undocumented options\.
+.IP "\fB--suppress-usage\fR"
+Suppress the generation of the usage printing code\.
+.IP "\fB--long-usage\fR"
+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\.
+.IP "\fB--short-usage\fR"
+If specified together with \fB--long-usage\fR, generate both short and long
+usage versions\. In this mode, the long usage printing function is called
+\fBprint_long_usage()\fR and in its implementation 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
+the long usage function has the \fB*long_usage()\fR suffix\.
+.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,
+and would like their usage to have the same indentation level\.
+.IP "\fB--ansi-color\fR"
+Use ANSI color escape sequences when printing usage\. By "color" we really
+only mean the bold and underline modifiers\. Note that Windows console does
+not recognize ANSI escape sequences and will display them as garbage\.
+However, if you pipe such output through \fBless(1)\fR, it will display them
+correctly\.
+.IP "\fB--exclude-base\fR"
+Exclude base class information from usage and documentation\.
+.IP "\fB--include-base-last\fR"
+Include base class information after derived for usage and documentation\. By
+default, base classes are included first\.
+.IP "\fB--class-doc\fR \fIname\fR=\fIkind\fR"
+Specify the documentation \fIkind\fR that should be used for the options class
+\fIname\fR\. The \fIname\fR value should be a fully-qualified class name, for
+example, \fBapp::options\fR\. The \fIkind\fR value can be \fBshort\fR,
+\fBlong\fR, \fBexclude\fR, or \fBexclude-base\fR\. If the value is
+\fBexclude\fR, then the class documentation is excluded from usage and
+man/HTML/text output\. If it is \fBexclude-base\fR, then it is only excluded
+when used as a base\. For usage, the \fBshort\fR and \fBlong\fR values
+determine which usage function will be called when the class is used as base
+or as part of the page usage (see \fB--page-usage\fR)\. For man/HTML/text,
+these values determine which documentation strings are used in the output\.
+.IP "\fB--class\fR \fIname\fR"
+Generate the man page, HTML, or text documentation only for the options class
+\fIname\fR\. The \fIname\fR value should be a fully-qualified options class
+name, for example, \fBapp::options\fR\. To generate documentation for multiple
+classes, repeat this option and the documentation will be produced in the
+order specified\. This functionality is useful if you need to assemble
+documentation from multiple classes in a specific order or to insert custom
+documentation between options belonging to different classes\.
+.IP "\fB--docvar\fR|\fB-v\fR \fIname\fR=\fIval\fR"
+Set documentation variable \fIname\fR to the value \fIval\fR\. Documentation
+variables can be substituted in prologues and epilogues (see
+\fB--*-prologue*\fR and \fB--*-epilogue*\fR options) using the
+\fB$\fR\fIname\fR\fB$\fR expansion syntax (use \fB$$\fR to escape expansion)\.
+They can also be defined in \fB\.cli\fR files using the
+\&"\e\fIname\fR=\fIval\fR"\fR syntax\.
+.IP "\fB--link-regex\fR \fIregex\fR"
+Add \fIregex\fR to the list of regular expressions used to transform link
+targets in the generated documentation\. The argument to this option is a
+Perl-like regular expression in the form
+\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any character can be
+used as a delimiter instead of '\fB/\fR' and the delimiter can be escaped
+inside \fIpattern\fR and \fIreplacement\fR with a backslash (\fB\e\fR)\. You
+can specify multiple regular expressions by repeating this option\. All the
+regular expressions are tried in the order specified and the first expression
+that matches is used\. Use the \fB--link-regex-trace\fR option to debug link
+transformation\.
+.IP "\fB--link-regex-trace\fR"
+Trace the process of applying regular expressions specified with the
+\fB--link-regex\fR option\. Use this option to find out why your regular
+expressions don't do what you expected them to do\.
+.IP "\fB--html-heading-map\fR \fIc\fR=\fIh\fR"
+Map CLI heading \fIc\fR (valid values: '\fBH\fR', '\fB0\fR', '\fB1\fR',
+\&'\fBh\fR', and '\fB2\fR') to HTML heading \fIh\fR (for example, '\fBh1\fR',
+\&'\fBh2\fR', etc)\.
+.IP "\fB--omit-link-check\fR"
+Don't check that local fragment link references (\el{#ref \.\.\.}) resolve to
+ids\.
+.IP "\fB--hxx-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated C++ header file\.
+.IP "\fB--ixx-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated C++ inline file\.
+.IP "\fB--cxx-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated C++ source file\.
+.IP "\fB--man-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated man page file\.
+.IP "\fB--html-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated HTML file\.
+.IP "\fB--txt-prologue\fR \fItext\fR"
+Insert \fItext\fR at the beginning of the generated text file\.
+.IP "\fB--hxx-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated C++ header file\.
+.IP "\fB--ixx-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated C++ inline file\.
+.IP "\fB--cxx-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated C++ source file\.
+.IP "\fB--man-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated man page file\.
+.IP "\fB--html-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated HTML file\.
+.IP "\fB--txt-epilogue\fR \fItext\fR"
+Insert \fItext\fR at the end of the generated text file\.
+.IP "\fB--hxx-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated C++ header
+file\.
+.IP "\fB--ixx-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated C++ inline
+file\.
+.IP "\fB--cxx-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated C++ source
+file\.
+.IP "\fB--man-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated man page
+file\.
+.IP "\fB--html-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated HTML file\.
+.IP "\fB--txt-prologue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the beginning of the generated text file\.
+.IP "\fB--hxx-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated C++ header file\.
+.IP "\fB--ixx-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated C++ inline file\.
+.IP "\fB--cxx-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated C++ source file\.
+.IP "\fB--man-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated man page file\.
+.IP "\fB--html-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated HTML file\.
+.IP "\fB--txt-epilogue-file\fR \fIfile\fR"
+Insert the content of \fIfile\fR at the end of the generated text file\.
+.IP "\fB--output-prefix\fR \fIprefix\fR"
+Add \fIprefix\fR at the beginning of the generated output file name(s)\.
+.IP "\fB--output-suffix\fR \fIsuffix\fR"
+Add \fIsuffix\fR at the end of the generated output file name(s)\. Note that
+it is added before any file type-specific suffixes; see \fB--*-suffix\fR
+below\.
+.IP "\fB--hxx-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.hxx\fR to construct the name of
+the generated header file\.
+.IP "\fB--ixx-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.ixx\fR to construct the name of
+the generated inline file\.
+.IP "\fB--cxx-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.cxx\fR to construct the name of
+the generated source file\.
+.IP "\fB--man-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.1\fR to construct the name of the
+generated man page file\.
+.IP "\fB--html-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.html\fR to construct the name of
+the generated HTML file\.
+.IP "\fB--txt-suffix\fR \fIsuffix\fR"
+Use \fIsuffix\fR instead of the default \fB\.txt\fR to construct the name of
+the generated text file\.
+.IP "\fB--option-prefix\fR \fIprefix\fR"
+Use \fIprefix\fR instead of the default '\fB-\fR' 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\.
+.IP "\fB--option-separator\fR \fIsep\fR"
+Use \fIsep\fR instead of the default '\fB--\fR' 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\.
+.IP "\fB--keep-separator\fR"
+Leave the option separator in the scanner\. This is primarily useful for
+incremental option parsing\.
+.IP "\fB--no-combined-flags\fR"
+Disable support for combining multiple single-character flags into a single
+argument (the \fB-xyz\fR form that is equivalent to \fB-x\fR \fB-y\fR
+\fB-z\fR)\. An argument is considered a combination of flags if it starts with
+a single option prefix (\fB--option-prefix\fR) and only contains letters and
+digits\. Note that an option with a value may not be part of such a
+combination, not even if it is specified last\.
+.IP "\fB--no-combined-values\fR"
+Disable support for combining an option and its value into a single argument
+with the assignment sign (the \fIoption\fR\fB=\fR\fIvalue\fR\fR form)\. This
+functionality requires a non-empty option prefix (\fB--option-prefix\fR)\.
+.IP "\fB--include-with-brackets\fR"
+Use angle brackets (\fB<>\fR) instead of quotes (\fB""\fR) in the generated
+\fB#include\fR directives\.
+.IP "\fB--include-prefix\fR \fIprefix\fR"
+Add \fIprefix\fR to the generated \fB#include\fR directive paths\.
+.IP "\fB--guard-prefix\fR \fIprefix\fR"
+Add \fIprefix\fR 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\.
+.IP "\fB--reserved-name\fR \fIname\fR=\fIrep\fR"
+Add \fIname\fR with an optional \fIrep\fR 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\.
+.IP "\fB--options-file\fR \fIfile\fR"
+Read additional options from \fIfile\fR\. Each option should appear on a
+separate line optionally followed by space or equal sign (\fB=\fR) and an
+option value\. Empty lines and lines starting with \fB#\fR are ignored\.
+Option values can be enclosed in double (\fB"\fR) or single (\fB'\fR) quotes
+to preserve leading and trailing whitespaces as well as to specify empty
+values\. If the value itself contains trailing or leading quotes, enclose it
+with an extra pair of quotes, for example \fB'"x"'\fR\. Non-leading and
+non-trailing quotes are interpreted as being part of the option value\.
+
+The semantics of providing options in a file is equivalent to providing the
+same set of options in the same order on the command line at the point where
+the \fB--options-file\fR option is specified except that the shell escaping
+and quoting is not required\. Repeat this option to specify more than one
+options file\.
+.\"
+.\" DIAGNOSTICS
+.\"
+.SH DIAGNOSTICS
+If the input file is not a valid CLI definition,
+.B cli
+will issue diagnostic messages to STDERR and exit with non-zero exit code.
+.\"
+.\" BUGS
+.\"
+.SH BUGS
+Send bug reports to the cli-users@codesynthesis.com mailing list.
+.\"
+.\" COPYRIGHT
+.\"
+.SH COPYRIGHT
+Copyright (c) 2009-2021 Code Synthesis Tools CC.
+
+Permission is granted to copy, distribute and/or modify this document under
+the terms of the MIT License. Copy of this license can be obtained from
+http://www.codesynthesis.com/licenses/mit.txt
diff --git a/cli/doc/bootstrap/cli.xhtml b/cli/doc/bootstrap/cli.xhtml
new file mode 100644
index 0000000..38b1bc8
--- /dev/null
+++ b/cli/doc/bootstrap/cli.xhtml
@@ -0,0 +1,573 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>CLI 1.2.0-b.7 Compiler Command Line Manual</title>
+
+ <meta name="copyright" content="&#169; 2009-2021 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="cli,command,line,interface,compiler,c++"/>
+ <meta name="description" content="CLI Compiler Command Line Manual"/>
+
+ <link rel="stylesheet" type="text/css" href="default.css" />
+
+<style type="text/css">
+
+ #synopsis {
+ list-style-type: none;
+ }
+
+ #synopsis li {
+ padding-top : 0.0em;
+ padding-bottom : 0.0em;
+ }
+
+ .options {
+ margin: 1em 0 1em 0;
+ }
+
+ .options dt {
+ margin: 1em 0 0 0;
+ }
+
+ .options dd {
+ margin: .1em 0 0 4.5em;
+ }
+
+</style>
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <h1>NAME</h1>
+
+ <p>cli - command line interface compiler for C++</p>
+
+ <h1>SYNOPSIS</h1>
+
+ <dl id="synopsis">
+ <dt><code><b>cli</b> [<i>options</i>] <i>file</i></code></dt>
+ </dl>
+
+ <h1>DESCRIPTION</h1>
+
+ <p><code><b>cli</b></code> generates C++ implementation and
+ documentation in various formats for a command line interface
+ defined in the CLI language. For an input file in the form
+ <code><b>name.cli</b></code> the following is generated. By
+ default or if the <code><b>--generate-cxx</b></code> option is
+ specified, the following C++ files are generated:
+ <code><b>name.hxx</b></code> (header file), <code><b>name.ixx</b></code>
+ (inline file, generated unless the <code><b>--suppress-inline</b></code>
+ option is specified), and <code><b>name.cxx</b></code> (source file).
+ If the <code><b>--generate-html</b></code> option is specified, then
+ the <code><b>name.html</b></code> HTML documentation file is generated.
+ If the <code><b>--generate-man</b></code> option is specified, then
+ the <code><b>name.1</b></code> man page file is generated. When
+ <code><b>--generate-html</b></code> or <code><b>--generate-man</b></code>
+ is specified, the <code><b>--stdout</b></code> option can be used to
+ redirect the output to STDOUT instead of a file.</p>
+
+ <h1>OPTIONS</h1>
+ <dl class="options">
+ <dt><code><b>--help</b></code></dt>
+ <dd>Print usage information and exit.</dd>
+
+ <dt><code><b>--version</b></code></dt>
+ <dd>Print version and exit.</dd>
+
+ <dt><code><b>--include-path</b></code>|<code><b>-I</b></code> <code><i>dir</i></code></dt>
+ <dd>Search <code><i>dir</i></code> for bracket-included
+ (<code><b>&lt;></b></code>) options files.</dd>
+
+ <dt><code><b>--output-dir</b></code>|<code><b>-o</b></code> <code><i>dir</i></code></dt>
+ <dd>Write the generated files to <code><i>dir</i></code> instead of the
+ current directory.</dd>
+
+ <dt><code><b>--std</b></code> <code><i>version</i></code></dt>
+ <dd>Specify the C++ standard that should be used during compilation. Valid
+ values are <code><b>c++98</b></code> (default), <code><b>c++11</b></code>,
+ and <code><b>c++14</b></code>.</dd>
+
+ <dt><code><b>--generate-modifier</b></code></dt>
+ <dd>Generate option value modifiers in addition to accessors.</dd>
+
+ <dt><code><b>--generate-specifier</b></code></dt>
+ <dd>Generate functions for determining whether the option was specified on
+ the command line.</dd>
+
+ <dt><code><b>--generate-parse</b></code></dt>
+ <dd>Generate <code><b>parse()</b></code> functions instead of parsing
+ constructors. This is primarily useful for being able to parse into an
+ already initialized options class instance, for example, to implement
+ option appending/overriding.</dd>
+
+ <dt><code><b>--generate-merge</b></code></dt>
+ <dd>Generate <code><b>merge()</b></code> functions. This is primarily
+ useful for being able to merge several already parsed options class
+ instances, for example, to implement option appending/overriding. Note
+ that this option forces <code><b>--generate-specifier</b></code>.</dd>
+
+ <dt><code><b>--generate-description</b></code></dt>
+ <dd>Generate the option description list that can be examined at
+ runtime.</dd>
+
+ <dt><code><b>--generate-file-scanner</b></code></dt>
+ <dd>Generate the <code><b>argv_file_scanner</b></code> implementation.
+ This scanner is capable of reading command line arguments from the
+ <code><b>argv</b></code> array as well as files specified with command
+ line options.</dd>
+
+ <dt><code><b>--generate-vector-scanner</b></code></dt>
+ <dd>Generate the <code><b>vector_scanner</b></code> implementation. This
+ scanner is capable of reading command line arguments from
+ <code><b>vector&lt;string></b></code>.</dd>
+
+ <dt><code><b>--generate-group-scanner</b></code></dt>
+ <dd>Generate the <code><b>group_scanner</b></code> implementation. This
+ scanner supports grouping of arguments (usually options) to apply only to
+ a certain argument.
+
+ <p>Groups can be specified before (leading) and/or after (trailing) the
+ argument they apply to. A leading group starts with
+ '<code><b>{</b></code>' and ends with '<code><b>}+</b></code>' while a
+ trailing group starts with '<code><b>+{</b></code>' and ends with
+ '<code><b>}</b></code>'. For example:</p>
+
+ <pre>{ --foo --bar }+ arg # 'arg' with '--foo' '--bar'
+arg +{ fox=1 baz=2 } # 'arg' with 'fox=1' 'baz=2'</pre>
+
+ <p>Multiple leading and/or trailing groups can be specified for the same
+ argument. For example:</p>
+
+ <pre>{ -f }+ { -b }+ arg +{ f=1 } +{ b=2 } # 'arg' with '-f' 'b' 'f=1' 'b=2'</pre>
+
+ <p>The group applies to a single argument only unless multiple arguments
+ are themselves grouped with '<code><b>{</b></code>' and
+ '<code><b>}</b></code>'. For example:</p>
+
+ <pre>{ --foo }+ arg1 arg2 +{ --bar } # 'arg1' with '--foo'
+ # 'arg2' with '--bar'
+
+{ --foo }+ { arg1 arg2 } +{ --bar } # 'arg1' with '--foo' '--bar'
+ # 'arg2' with '--foo' '--bar'</pre>
+
+ <p>The group separators ('<code><b>{</b></code>',
+ '<code><b>}+'</b></code>, etc) must be separate command line arguments. In
+ particular, they must not be adjacent either to the arguments inside the
+ group nor to the argument they apply to. All such cases will be treated as
+ ordinary arguments. For example:</p>
+
+ <pre>{--foo}+ arg # '{--foo}+' ...
+arg+{ --foo } # 'arg+{' ...</pre>
+
+ <p>If one of the group separators needs to be specified as an argument
+ verbatim, then it must be escaped with '<code><b>\</b></code>'. For
+ example:</p>
+
+ <pre>} # error: unexpected group separator
+}x # '}x'
+\} # '}'
+{ \}+ }+ arg # 'arg' with '}+'</pre></dd>
+
+ <dt><code><b>--suppress-inline</b></code></dt>
+ <dd>Generate all functions non-inline. By default simple functions are
+ made inline. This option suppresses creation of the inline file.</dd>
+
+ <dt><code><b>--suppress-cli</b></code></dt>
+ <dd>Do not generate the CLI support types (scanners, parser, etc).
+ Normally, the support types are generated unless another
+ <code><b>.cli</b></code> was included, in which case the support types are
+ expected to be provided by its generated code.</dd>
+
+ <dt><code><b>--cli-namespace</b></code> <code><i>ns</i></code></dt>
+ <dd>Generate the CLI support types in the <code><i>ns</i></code> namespace
+ (<code><b>cli</b></code> by default). The namespace can be nested, for
+ example <code><b>details::cli</b></code>. If the namespace is empty, then
+ the support types are generated in the global namespace.</dd>
+
+ <dt><code><b>--ostream-type</b></code> <code><i>type</i></code></dt>
+ <dd>Output stream type instead of the default
+ <code><b>std::ostream</b></code> that should be used to print usage and
+ exception information.</dd>
+
+ <dt><code><b>--generate-cxx</b></code></dt>
+ <dd>Generate C++ code. If neither <code><b>--generate-man</b></code>,
+ <code><b>--generate-html</b></code>, nor
+ <code><b>--generate-txt</b></code> is specified, this mode is assumed by
+ default.</dd>
+
+ <dt><code><b>--generate-man</b></code></dt>
+ <dd>Generate documentation in the man page format.</dd>
+
+ <dt><code><b>--generate-html</b></code></dt>
+ <dd>Generate documentation in the HTML format.</dd>
+
+ <dt><code><b>--generate-txt</b></code></dt>
+ <dd>Generate documentation in the plain text format, similar to
+ usage.</dd>
+
+ <dt><code><b>--stdout</b></code></dt>
+ <dd>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.</dd>
+
+ <dt><code><b>--suppress-undocumented</b></code></dt>
+ <dd>Suppress the generation of documentation entries for undocumented
+ options.</dd>
+
+ <dt><code><b>--suppress-usage</b></code></dt>
+ <dd>Suppress the generation of the usage printing code.</dd>
+
+ <dt><code><b>--long-usage</b></code></dt>
+ <dd>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.</dd>
+
+ <dt><code><b>--short-usage</b></code></dt>
+ <dd>If specified together with <code><b>--long-usage</b></code>, generate
+ both short and long usage versions. In this mode, the long usage printing
+ function is called <code><b>print_long_usage()</b></code> and in its
+ implementation the long documentation string is always used, even if the
+ short version is provided.</dd>
+
+ <dt><code><b>--page-usage</b></code> <code><i>name</i></code></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 <code><i>name</i></code> 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 the long
+ usage function has the <code><b>*long_usage()</b></code> suffix.</p></dd>
+
+ <dt><code><b>--option-length</b></code> <code><i>len</i></code></dt>
+ <dd>Indent option descriptions <code><i>len</i></code> 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.</dd>
+
+ <dt><code><b>--ansi-color</b></code></dt>
+ <dd>Use ANSI color escape sequences when printing usage. By "color" we
+ really only mean the bold and underline modifiers. Note that Windows
+ console does not recognize ANSI escape sequences and will display them as
+ garbage. However, if you pipe such output through
+ <code><b>less(1)</b></code>, it will display them correctly.</dd>
+
+ <dt><code><b>--exclude-base</b></code></dt>
+ <dd>Exclude base class information from usage and documentation.</dd>
+
+ <dt><code><b>--include-base-last</b></code></dt>
+ <dd>Include base class information after derived for usage and
+ documentation. By default, base classes are included first.</dd>
+
+ <dt><code><b>--class-doc</b></code> <code><i>name</i></code>=<code><i>kind</i></code></dt>
+ <dd>Specify the documentation <code><i>kind</i></code> that should be used
+ for the options class <code><i>name</i></code>. The
+ <code><i>name</i></code> value should be a fully-qualified class name, for
+ example, <code><b>app::options</b></code>. The <code><i>kind</i></code>
+ value can be <code><b>short</b></code>, <code><b>long</b></code>,
+ <code><b>exclude</b></code>, or <code><b>exclude-base</b></code>. If the
+ value is <code><b>exclude</b></code>, then the class documentation is
+ excluded from usage and man/HTML/text output. If it is
+ <code><b>exclude-base</b></code>, then it is only excluded when used as a
+ base. For usage, the <code><b>short</b></code> and
+ <code><b>long</b></code> values determine which usage function will be
+ called when the class is used as base or as part of the page usage (see
+ <code><b>--page-usage</b></code>). For man/HTML/text, these values
+ determine which documentation strings are used in the output.</dd>
+
+ <dt><code><b>--class</b></code> <code><i>name</i></code></dt>
+ <dd>Generate the man page, HTML, or text documentation only for the
+ options class <code><i>name</i></code>. The <code><i>name</i></code> value
+ should be a fully-qualified options class name, for example,
+ <code><b>app::options</b></code>. To generate documentation for multiple
+ classes, repeat this option and the documentation will be produced in the
+ order specified. This functionality is useful if you need to assemble
+ documentation from multiple classes in a specific order or to insert
+ custom documentation between options belonging to different classes.</dd>
+
+ <dt><code><b>--docvar</b></code>|<code><b>-v</b></code> <code><i>name</i></code>=<code><i>val</i></code></dt>
+ <dd>Set documentation variable <code><i>name</i></code> to the value
+ <code><i>val</i></code>. Documentation variables can be substituted in
+ prologues and epilogues (see <code><b>--*-prologue*</b></code> and
+ <code><b>--*-epilogue*</b></code> options) using the
+ <code><b>$</b></code><code><i>name</i></code><code><b>$</b></code>
+ expansion syntax (use <code><b>$$</b></code> to escape expansion). They
+ can also be defined in <code><b>.cli</b></code> files using the
+ <code>"\<code><i>name</i></code>=<code><i>val</i></code>"</code>
+ syntax.</dd>
+
+ <dt><code><b>--link-regex</b></code> <code><i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions used
+ to transform link targets in the generated documentation. The argument to
+ this option is a Perl-like regular expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any
+ character can be used as a delimiter instead of '<code><b>/</b></code>'
+ and the delimiter can be escaped inside <code><i>pattern</i></code> and
+ <code><i>replacement</i></code> with a backslash (<code><b>\</b></code>).
+ You can specify multiple regular expressions by repeating this option. All
+ the regular expressions are tried in the order specified and the first
+ expression that matches is used. Use the
+ <code><b>--link-regex-trace</b></code> option to debug link
+ transformation.</dd>
+
+ <dt><code><b>--link-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with the
+ <code><b>--link-regex</b></code> option. Use this option to find out why
+ your regular expressions don't do what you expected them to do.</dd>
+
+ <dt><code><b>--html-heading-map</b></code> <code><i>c</i></code>=<code><i>h</i></code></dt>
+ <dd>Map CLI heading <code><i>c</i></code> (valid values:
+ '<code><b>H</b></code>', '<code><b>0</b></code>', '<code><b>1</b></code>',
+ '<code><b>h</b></code>', and '<code><b>2</b></code>') to HTML heading
+ <code><i>h</i></code> (for example, '<code><b>h1</b></code>',
+ '<code><b>h2</b></code>', etc).</dd>
+
+ <dt><code><b>--omit-link-check</b></code></dt>
+ <dd>Don't check that local fragment link references (\l{#ref ...}) resolve
+ to ids.</dd>
+
+ <dt><code><b>--hxx-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated C++
+ header file.</dd>
+
+ <dt><code><b>--ixx-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated C++
+ inline file.</dd>
+
+ <dt><code><b>--cxx-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated C++
+ source file.</dd>
+
+ <dt><code><b>--man-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated man
+ page file.</dd>
+
+ <dt><code><b>--html-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated HTML
+ file.</dd>
+
+ <dt><code><b>--txt-prologue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the generated text
+ file.</dd>
+
+ <dt><code><b>--hxx-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated C++ header
+ file.</dd>
+
+ <dt><code><b>--ixx-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated C++ inline
+ file.</dd>
+
+ <dt><code><b>--cxx-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated C++ source
+ file.</dd>
+
+ <dt><code><b>--man-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated man page
+ file.</dd>
+
+ <dt><code><b>--html-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated HTML
+ file.</dd>
+
+ <dt><code><b>--txt-epilogue</b></code> <code><i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the generated text
+ file.</dd>
+
+ <dt><code><b>--hxx-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated C++ header file.</dd>
+
+ <dt><code><b>--ixx-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated C++ inline file.</dd>
+
+ <dt><code><b>--cxx-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated C++ source file.</dd>
+
+ <dt><code><b>--man-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated man page file.</dd>
+
+ <dt><code><b>--html-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated HTML file.</dd>
+
+ <dt><code><b>--txt-prologue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the beginning of the
+ generated text file.</dd>
+
+ <dt><code><b>--hxx-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated C++ header file.</dd>
+
+ <dt><code><b>--ixx-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated C++ inline file.</dd>
+
+ <dt><code><b>--cxx-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated C++ source file.</dd>
+
+ <dt><code><b>--man-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated man page file.</dd>
+
+ <dt><code><b>--html-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated HTML file.</dd>
+
+ <dt><code><b>--txt-epilogue-file</b></code> <code><i>file</i></code></dt>
+ <dd>Insert the content of <code><i>file</i></code> at the end of the
+ generated text file.</dd>
+
+ <dt><code><b>--output-prefix</b></code> <code><i>prefix</i></code></dt>
+ <dd>Add <code><i>prefix</i></code> at the beginning of the generated
+ output file name(s).</dd>
+
+ <dt><code><b>--output-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Add <code><i>suffix</i></code> at the end of the generated output file
+ name(s). Note that it is added before any file type-specific suffixes; see
+ <code><b>--*-suffix</b></code> below.</dd>
+
+ <dt><code><b>--hxx-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.hxx</b></code> to construct the name of the generated header
+ file.</dd>
+
+ <dt><code><b>--ixx-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.ixx</b></code> to construct the name of the generated inline
+ file.</dd>
+
+ <dt><code><b>--cxx-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.cxx</b></code> to construct the name of the generated source
+ file.</dd>
+
+ <dt><code><b>--man-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.1</b></code> to construct the name of the generated man page
+ file.</dd>
+
+ <dt><code><b>--html-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.html</b></code> to construct the name of the generated HTML
+ file.</dd>
+
+ <dt><code><b>--txt-suffix</b></code> <code><i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ <code><b>.txt</b></code> to construct the name of the generated text
+ file.</dd>
+
+ <dt><code><b>--option-prefix</b></code> <code><i>prefix</i></code></dt>
+ <dd>Use <code><i>prefix</i></code> instead of the default
+ '<code><b>-</b></code>' 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.</dd>
+
+ <dt><code><b>--option-separator</b></code> <code><i>sep</i></code></dt>
+ <dd>Use <code><i>sep</i></code> instead of the default
+ '<code><b>--</b></code>' 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.</dd>
+
+ <dt><code><b>--keep-separator</b></code></dt>
+ <dd>Leave the option separator in the scanner. This is primarily useful
+ for incremental option parsing.</dd>
+
+ <dt><code><b>--no-combined-flags</b></code></dt>
+ <dd>Disable support for combining multiple single-character flags into a
+ single argument (the <code><b>-xyz</b></code> form that is equivalent to
+ <code><b>-x</b></code> <code><b>-y</b></code> <code><b>-z</b></code>). An
+ argument is considered a combination of flags if it starts with a single
+ option prefix (<code><b>--option-prefix</b></code>) and only contains
+ letters and digits. Note that an option with a value may not be part of
+ such a combination, not even if it is specified last.</dd>
+
+ <dt><code><b>--no-combined-values</b></code></dt>
+ <dd>Disable support for combining an option and its value into a single
+ argument with the assignment sign (the
+ <code><i>option</i><b>=</b><i>value</i></code> form). This functionality
+ requires a non-empty option prefix
+ (<code><b>--option-prefix</b></code>).</dd>
+
+ <dt><code><b>--include-with-brackets</b></code></dt>
+ <dd>Use angle brackets (<code><b>&lt;></b></code>) instead of quotes
+ (<code><b>""</b></code>) in the generated <code><b>#include</b></code>
+ directives.</dd>
+
+ <dt><code><b>--include-prefix</b></code> <code><i>prefix</i></code></dt>
+ <dd>Add <code><i>prefix</i></code> to the generated
+ <code><b>#include</b></code> directive paths.</dd>
+
+ <dt><code><b>--guard-prefix</b></code> <code><i>prefix</i></code></dt>
+ <dd>Add <code><i>prefix</i></code> 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.</dd>
+
+ <dt><code><b>--reserved-name</b></code> <code><i>name</i></code>=<code><i>rep</i></code></dt>
+ <dd>Add <code><i>name</i></code> with an optional <code><i>rep</i></code>
+ 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.</dd>
+
+ <dt><code><b>--options-file</b></code> <code><i>file</i></code></dt>
+ <dd>Read additional options from <code><i>file</i></code>. Each option
+ should appear on a separate line optionally followed by space or equal
+ sign (<code><b>=</b></code>) and an option value. Empty lines and lines
+ starting with <code><b>#</b></code> are ignored. Option values can be
+ enclosed in double (<code><b>"</b></code>) or single
+ (<code><b>'</b></code>) quotes to preserve leading and trailing
+ whitespaces as well as to specify empty values. If the value itself
+ contains trailing or leading quotes, enclose it with an extra pair of
+ quotes, for example <code><b>'"x"'</b></code>. Non-leading and
+ non-trailing quotes are interpreted as being part of the option value.
+
+ <p>The semantics of providing options in a file is equivalent to providing
+ the same set of options in the same order on the command line at the point
+ where the <code><b>--options-file</b></code> option is specified except
+ that the shell escaping and quoting is not required. Repeat this option to
+ specify more than one options file.</p></dd>
+ </dl>
+
+ <h1>DIAGNOSTICS</h1>
+
+ <p>If the input file is not a valid CLI definition, <code><b>cli</b></code>
+ will issue diagnostic messages to STDERR and exit with non-zero exit
+ code.</p>
+
+ <h1>BUGS</h1>
+
+ <p>Send bug reports to the
+ <a href="mailto:cli-users@codesynthesis.com">cli-users@codesynthesis.com</a> mailing list.</p>
+
+ </div>
+ <div id="footer">
+ Copyright &#169; 2009-2021 Code Synthesis Tools CC.
+
+ <div id="terms">
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://www.codesynthesis.com/licenses/mit.txt">MIT License</a>.
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/cli/doc/buildfile b/cli/doc/buildfile
index f47adad..d56c7f5 100644
--- a/cli/doc/buildfile
+++ b/cli/doc/buildfile
@@ -7,14 +7,115 @@ css{*}: extension = css
define xhtml: doc
xhtml{*}: extension = xhtml
-./: {man1 xhtml}{cli} \
- css{default} \
- file{cli-*}
+define ps: doc
+ps{*}: extension = ps
-./: guide/doc{cli-guide*} \
- guide/xhtml{index} \
- guide/file{*.html2ps}
+define pdf: doc
+pdf{*}: extension = pdf
-doc{*}: install.subdirs = true
+define html2ps: file
+html2ps{*}: extension = html2ps
-./: file{doc.sh}
+./: css{default} xhtml{cli-guide} bootstrap/{man1 xhtml}{cli}
+
+if $config.cli.develop
+{
+ doc_version = [string] "$version.major\.$version.minor\.$version.patch"
+ if $version.pre_release
+ doc_version += "-$version.pre_release_string"
+
+ # Let's take the last for-digit number to cover 2000-2021,2022.
+ #
+ doc_year = $regex.replace($copyright, '.+[-, ]([0-9][0-9][0-9][0-9]) .+', '\1')
+
+ man_options = -v project="CLI" -v version="$doc_version" \
+ -v copyright="$copyright" --suppress-undocumented
+
+ # We use the cli version we've built to generate the documentation.
+ #
+ # Note: avoid cleaning it through this dependency.
+ #
+ include ../cli/
+
+ {xhtml man1}{cli}: ../cli/exe{cli}: clean = false
+
+ ./: man1{cli}: ../cli/cli{options} file{cli-prologue.1 cli-epilogue.1}
+ {{
+ diag cli --man ($<[1])
+
+ # Use the copyright year to approximate the last authoring date.
+ #
+ date +"%B %Y" | set date
+
+ ($<[0]) --generate-man $man_options \
+ -v date="January $doc_year" \
+ --man-prologue-file $path($<[2]) \
+ --man-epilogue-file $path($<[3]) \
+ --stdout $path($<[1]) >$path($>)
+
+ # If the result differs from the bootstrap version, copy it over. Unlike
+ # the bootstrap cli case, here we don't need to cause a build restart.
+ #
+ if! diff $src_base/bootstrap/cli.1 $path($>) >-
+ cp $path($>) $src_base/bootstrap/cli.1
+ end
+ }}
+
+ ./: xhtml{cli}: $src_root/cli/cli{options} \
+ file{cli-prologue.xhtml cli-epilogue.xhtml}
+ {{
+ diag cli --html ($<[1])
+
+ ($<[0]) --generate-html $man_options \
+ --html-prologue-file $path($<[2]) \
+ --html-epilogue-file $path($<[3]) \
+ --stdout $path($<[1]) >$path($>)
+
+ if! diff $src_base/bootstrap/cli.xhtml $path($>) >-
+ cp $path($>) $src_base/bootstrap/cli.xhtml
+ end
+ }}
+
+ # Import the html2ps and ps2pdf programs from the system, if available.
+ #
+ import? html2ps = html2ps%exe{html2ps}
+ import? ps2pdf = ps2pdf14%exe{ps2pdf14}
+
+ if ($html2ps != [null] && $ps2pdf != [null])
+ {
+ # Note that we include these generated files into the distribution and
+ # don't remove them when cleaning in src (so that clean results in a state
+ # identical to distributed).
+ #
+ ./: ps{cli-guide}: xhtml{cli-guide} html2ps{guide} $html2ps
+ {
+ options =
+
+ dist = true
+ clean = ($src_root != $out_root)
+ }
+ {{
+ diag html2ps ($<[0])
+ $html2ps $options -f $path($<[1]) -o $path($>) $path($<[0])
+ }}
+
+ ./: pdf{cli-guide}: ps{cli-guide} $ps2pdf
+ {
+ options = -dOptimize=true -dEmbedAllFonts=true
+
+ dist = true
+ clean = ($src_root != $out_root)
+ }
+ {{
+ diag ps2pdf ($<[0])
+ $ps2pdf $options $path($<[0]) $path($>)
+ }}
+ }
+ else
+ {
+ warn "html2ps and/or ps2pdf14 are not available, not generating .ps and .pdf documentation"
+ ./: html2ps{guide} # Note: not keeping ps/pdf (could be outdated).
+ }
+}
+else
+ ./: file{cli-prologue* cli-epilogue*} html2ps{guide} {ps pdf}{+cli-guide}
diff --git a/cli/doc/guide/index.xhtml b/cli/doc/cli-guide.xhtml
index 675db03..675db03 100644
--- a/cli/doc/guide/index.xhtml
+++ b/cli/doc/cli-guide.xhtml
diff --git a/cli/doc/cli-prologue.1 b/cli/doc/cli-prologue.1
index 165cd1a..2b34fee 100644
--- a/cli/doc/cli-prologue.1
+++ b/cli/doc/cli-prologue.1
@@ -1,7 +1,7 @@
.\" Process this file with
.\" groff -man -Tascii cli.1
.\"
-.TH CLI 1 "December 2009" "CLI 1.2.0"
+.TH CLI 1 "$date$" "$project$ $version$"
.SH NAME
cli \- command line interface compiler for C++
.\"
diff --git a/cli/doc/cli-prologue.xhtml b/cli/doc/cli-prologue.xhtml
index 9a57f0e..386c4f0 100644
--- a/cli/doc/cli-prologue.xhtml
+++ b/cli/doc/cli-prologue.xhtml
@@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
- <title>CLI 1.2.0 Compiler Command Line Manual</title>
+ <title>$project$ $version$ Compiler Command Line Manual</title>
<meta name="copyright" content="&#169; $copyright$"/>
<meta name="keywords" content="cli,command,line,interface,compiler,c++"/>
diff --git a/cli/doc/doc.sh b/cli/doc/doc.sh
deleted file mode 100755
index dde9aca..0000000
--- a/cli/doc/doc.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#! /usr/bin/env bash
-
-version=1.2.0-b.6
-
-trap 'exit 1' ERR
-set -o errtrace # Trap in functions.
-
-function info () { echo "$*" 1>&2; }
-function error () { info "$*"; exit 1; }
-
-date="$(date +"%B %Y")"
-copyright="$(sed -n -re 's%^Copyright \(c\) (.+)\.$%\1%p' ../LICENSE)"
-
-while [ $# -gt 0 ]; do
- case $1 in
- --clean)
- rm -f cli.xhtml cli.1
- rm -f guide/cli-guide.ps guide/cli-guide.pdf
- exit 0
- ;;
- *)
- error "unexpected $1"
- ;;
- esac
-done
-
-function compile () # <input-name> <output-name>
-{
- local i=$1; shift
- local o=$1; shift
-
- # Use a bash array to handle empty arguments.
- #
- local ops=()
- while [ $# -gt 0 ]; do
- ops=("${ops[@]}" "$1")
- shift
- done
-
- # --html-suffix .xhtml
- ../cli/cli -I .. \
--v project="cli" \
--v version="$version" \
--v date="$date" \
--v copyright="$copyright" \
-"${ops[@]}" --generate-html --stdout \
---html-prologue-file cli-prologue.xhtml \
---html-epilogue-file cli-epilogue.xhtml \
-"../cli/$i.cli" >"$o.xhtml"
-
- # --man-suffix .1
- ../cli/cli -I .. \
--v project="cli" \
--v version="$version" \
--v date="$date" \
--v copyright="$copyright" \
-"${ops[@]}" --generate-man --stdout \
---man-prologue-file cli-prologue.1 \
---man-epilogue-file cli-epilogue.1 \
-"../cli/$i.cli" >"$o.1"
-}
-
-compile options cli --suppress-undocumented
-
-# Manual.
-#
-
-#function compile_doc ()
-#{
-# html2ps -f doc.html2ps:a4.html2ps -o "$n-a4.ps" "$n.xhtml"
-# ps2pdf14 -sPAPERSIZE=a4 -dOptimize=true -dEmbedAllFonts=true "$n-a4.ps" "$n-a4.pdf"
-#
-# html2ps -f doc.html2ps:letter.html2ps -o "$n-letter.ps" "$n.xhtml"
-# ps2pdf14 -sPAPERSIZE=letter -dOptimize=true -dEmbedAllFonts=true "$n-letter.ps" "$n-letter.pdf"
-#}
-
-html2ps -f guide/guide.html2ps -o guide/cli-guide.ps guide/index.xhtml
-ps2pdf14 -dOptimize=true -dEmbedAllFonts=true guide/cli-guide.ps guide/cli-guide.pdf
diff --git a/cli/doc/guide/guide.html2ps b/cli/doc/guide.html2ps
index a691002..a691002 100644
--- a/cli/doc/guide/guide.html2ps
+++ b/cli/doc/guide.html2ps
diff --git a/cli/doc/guide/.gitignore b/cli/doc/guide/.gitignore
deleted file mode 100644
index 239cc7f..0000000
--- a/cli/doc/guide/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.ps
-*.pdf
diff --git a/cli/manifest b/cli/manifest
index 69896fb..2f0c3ff 100644
--- a/cli/manifest
+++ b/cli/manifest
@@ -12,10 +12,10 @@ doc-url: https://www.codesynthesis.com/projects/cli/doc/guide/
src-url: https://git.codesynthesis.com/cgit/cli/cli/tree/cli/
email: cli-users@codesynthesis.com ; Mailing list
build-warning-email: builds@codesynthesis.com
-builds: host
requires: c++14
-depends: * build2 >= 0.13.0
-depends: * bpkg >= 0.13.0
+requires: host
+depends: * build2 >= 0.14.0-
+depends: * bpkg >= 0.14.0-
depends: libcutl ^1.11.0-
-tests: cli-tests == $
-examples: cli-examples == $
+tests: * cli-tests == $
+examples: * cli-examples == $