summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli-examples/build/root.build3
-rw-r--r--cli-examples/features/driver.cxx2
-rw-r--r--cli-examples/features/options.cli6
-rw-r--r--cli-examples/manifest6
-rw-r--r--cli-tests/build/root.build3
-rw-r--r--cli-tests/group/driver.cxx2
-rw-r--r--cli-tests/manifest6
-rw-r--r--cli/build/root.build7
-rw-r--r--cli/cli/bootstrap/cli/options.cxx117
-rw-r--r--cli/cli/bootstrap/cli/options.hxx17
-rw-r--r--cli/cli/bootstrap/cli/options.ixx30
-rw-r--r--cli/cli/context.cxx14
-rw-r--r--cli/cli/context.hxx4
-rw-r--r--cli/cli/header.cxx6
-rw-r--r--cli/cli/options.cli7
-rw-r--r--cli/cli/runtime-header.cxx43
-rw-r--r--cli/cli/runtime-source.cxx44
-rw-r--r--cli/cli/source.cxx9
-rw-r--r--cli/doc/bootstrap/cli.13
-rw-r--r--cli/doc/bootstrap/cli.xhtml5
-rw-r--r--cli/doc/cli-guide.xhtml6
-rw-r--r--cli/manifest6
22 files changed, 256 insertions, 90 deletions
diff --git a/cli-examples/build/root.build b/cli-examples/build/root.build
index 5f4b348..90a319a 100644
--- a/cli-examples/build/root.build
+++ b/cli-examples/build/root.build
@@ -16,7 +16,8 @@ if ($cxx.target.system == 'win32-msvc')
if ($cxx.class == 'msvc')
cxx.coptions += /wd4251 /wd4275 /wd4800
-using cli
+if ($build.mode != 'skeleton')
+ using cli
# Every exe{} in this project is by default a test.
#
diff --git a/cli-examples/features/driver.cxx b/cli-examples/features/driver.cxx
index c14b5c7..a6299b9 100644
--- a/cli-examples/features/driver.cxx
+++ b/cli-examples/features/driver.cxx
@@ -45,7 +45,7 @@ main (int argc, char* argv[])
// --map | -m
//
- typedef map<std::string, std::string> str_map;
+ typedef map<std::string, bool> str_map;
const str_map& m = o.map ();
str_map::const_iterator i (m.find ("a"));
diff --git a/cli-examples/features/options.cli b/cli-examples/features/options.cli
index ea055b3..4065830 100644
--- a/cli-examples/features/options.cli
+++ b/cli-examples/features/options.cli
@@ -31,9 +31,9 @@ namespace features
std::set<int> --set | -s;
// We can also use maps. In this case the option value is expected to have
- // two parts: the key and the value, separated by '='. For example: -m a=A
- // -m =B -m c= -m d (same as -m d=).
+ // two parts: the key and the value, separated by '='. For example: -m a=1
+ // -m =true -m c= -m d (same as -m d=).
//
- std::map<std::string, std::string> --map | -m;
+ std::map<std::string, bool> --map | -m;
};
}
diff --git a/cli-examples/manifest b/cli-examples/manifest
index a3d7683..2b84f64 100644
--- a/cli-examples/manifest
+++ b/cli-examples/manifest
@@ -1,6 +1,6 @@
: 1
name: cli-examples
-version: 1.2.0-b.8.z
+version: 1.2.0-b.9
project: cli
summary: Examples of using the CLI language and compiler for C++
license: MIT
@@ -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.14.0-
-depends: * bpkg >= 0.14.0-
+depends: * build2 >= 0.15.0-
+depends: * bpkg >= 0.15.0-
diff --git a/cli-tests/build/root.build b/cli-tests/build/root.build
index 5f4b348..90a319a 100644
--- a/cli-tests/build/root.build
+++ b/cli-tests/build/root.build
@@ -16,7 +16,8 @@ if ($cxx.target.system == 'win32-msvc')
if ($cxx.class == 'msvc')
cxx.coptions += /wd4251 /wd4275 /wd4800
-using cli
+if ($build.mode != 'skeleton')
+ using cli
# Every exe{} in this project is by default a test.
#
diff --git a/cli-tests/group/driver.cxx b/cli-tests/group/driver.cxx
index 357b9a9..9a3c710 100644
--- a/cli-tests/group/driver.cxx
+++ b/cli-tests/group/driver.cxx
@@ -52,7 +52,7 @@ main (int argc, char* argv[])
s.peek ();
assert (pos == s.position ());
- const char* a;
+ const char* a (0);
if (!sa)
{
a = s.next ();
diff --git a/cli-tests/manifest b/cli-tests/manifest
index cd8475a..f7a7fe0 100644
--- a/cli-tests/manifest
+++ b/cli-tests/manifest
@@ -1,6 +1,6 @@
: 1
name: cli-tests
-version: 1.2.0-b.8.z
+version: 1.2.0-b.9
project: cli
summary: Tests for the CLI compiler for C++
license: MIT
@@ -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.14.0-
-depends: * bpkg >= 0.14.0-
+depends: * build2 >= 0.15.0-
+depends: * bpkg >= 0.15.0-
diff --git a/cli/build/root.build b/cli/build/root.build
index 6132356..0753a9e 100644
--- a/cli/build/root.build
+++ b/cli/build/root.build
@@ -34,6 +34,7 @@ test.target = $cxx.target
#
# 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')
+if ($build.mode != 'skeleton')
+ copyright = $process.run_regex(cat $src_root/LICENSE, \
+ 'Copyright \(c\) (.+)\.', \
+ '\1')
diff --git a/cli/cli/bootstrap/cli/options.cxx b/cli/cli/bootstrap/cli/options.cxx
index e66ae63..2cb2f75 100644
--- a/cli/cli/bootstrap/cli/options.cxx
+++ b/cli/cli/bootstrap/cli/options.cxx
@@ -542,10 +542,31 @@ namespace cli
struct parser<bool>
{
static void
- parse (bool& x, scanner& s)
+ parse (bool& x, bool& xs, scanner& s)
{
- s.next ();
- x = true;
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ const char* v (s.next ());
+
+ if (std::strcmp (v, "1") == 0 ||
+ std::strcmp (v, "true") == 0 ||
+ std::strcmp (v, "TRUE") == 0 ||
+ std::strcmp (v, "True") == 0)
+ x = true;
+ else if (std::strcmp (v, "0") == 0 ||
+ std::strcmp (v, "false") == 0 ||
+ std::strcmp (v, "FALSE") == 0 ||
+ std::strcmp (v, "False") == 0)
+ x = false;
+ else
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
}
};
@@ -662,6 +683,14 @@ namespace cli
parser<T>::parse (x.*M, s);
}
+ template <typename X, bool X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ s.next ();
+ x.*M = true;
+ }
+
template <typename X, typename T, T X::*M, bool X::*S>
void
thunk (X& x, scanner& s)
@@ -671,7 +700,6 @@ namespace cli
}
#include <map>
-#include <cstring>
// options
//
@@ -702,6 +730,8 @@ options ()
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -844,6 +874,8 @@ options (int& argc,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -989,6 +1021,8 @@ options (int start,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -1134,6 +1168,8 @@ options (int& argc,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -1281,6 +1317,8 @@ options (int start,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -1424,6 +1462,8 @@ options (::cli::scanner& s,
cli_namespace_specified_ (false),
ostream_type_ ("::std::ostream"),
ostream_type_specified_ (false),
+ export_symbol_ (),
+ export_symbol_specified_ (false),
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
@@ -1590,6 +1630,10 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
<< " std::ostream that should be used to print usage" << ::std::endl
<< " and exception information." << ::std::endl;
+ os << "--export-symbol <symbol> Insert <symbol> in places where DLL export/import" << ::std::endl
+ << " control statements" << ::std::endl
+ << " (__declspec(dllexport/dllimport)) are necessary." << ::std::endl;
+
os << "--generate-cxx Generate C++ code." << ::std::endl;
os << "--generate-man Generate documentation in the man page format." << ::std::endl;
@@ -1799,9 +1843,9 @@ struct _cli_options_map_init
&::cli::thunk< options, std::uint64_t, &options::build2_metadata_,
&options::build2_metadata_specified_ >;
_cli_options_map_["--help"] =
- &::cli::thunk< options, bool, &options::help_ >;
+ &::cli::thunk< options, &options::help_ >;
_cli_options_map_["--version"] =
- &::cli::thunk< options, bool, &options::version_ >;
+ &::cli::thunk< options, &options::version_ >;
_cli_options_map_["--include-path"] =
&::cli::thunk< options, std::vector<std::string>, &options::include_path_,
&options::include_path_specified_ >;
@@ -1818,49 +1862,52 @@ struct _cli_options_map_init
&::cli::thunk< options, cxx_version, &options::std_,
&options::std_specified_ >;
_cli_options_map_["--generate-modifier"] =
- &::cli::thunk< options, bool, &options::generate_modifier_ >;
+ &::cli::thunk< options, &options::generate_modifier_ >;
_cli_options_map_["--generate-specifier"] =
- &::cli::thunk< options, bool, &options::generate_specifier_ >;
+ &::cli::thunk< options, &options::generate_specifier_ >;
_cli_options_map_["--generate-parse"] =
- &::cli::thunk< options, bool, &options::generate_parse_ >;
+ &::cli::thunk< options, &options::generate_parse_ >;
_cli_options_map_["--generate-merge"] =
- &::cli::thunk< options, bool, &options::generate_merge_ >;
+ &::cli::thunk< options, &options::generate_merge_ >;
_cli_options_map_["--generate-description"] =
- &::cli::thunk< options, bool, &options::generate_description_ >;
+ &::cli::thunk< options, &options::generate_description_ >;
_cli_options_map_["--generate-file-scanner"] =
- &::cli::thunk< options, bool, &options::generate_file_scanner_ >;
+ &::cli::thunk< options, &options::generate_file_scanner_ >;
_cli_options_map_["--generate-vector-scanner"] =
- &::cli::thunk< options, bool, &options::generate_vector_scanner_ >;
+ &::cli::thunk< options, &options::generate_vector_scanner_ >;
_cli_options_map_["--generate-group-scanner"] =
- &::cli::thunk< options, bool, &options::generate_group_scanner_ >;
+ &::cli::thunk< options, &options::generate_group_scanner_ >;
_cli_options_map_["--suppress-inline"] =
- &::cli::thunk< options, bool, &options::suppress_inline_ >;
+ &::cli::thunk< options, &options::suppress_inline_ >;
_cli_options_map_["--suppress-cli"] =
- &::cli::thunk< options, bool, &options::suppress_cli_ >;
+ &::cli::thunk< options, &options::suppress_cli_ >;
_cli_options_map_["--cli-namespace"] =
&::cli::thunk< options, std::string, &options::cli_namespace_,
&options::cli_namespace_specified_ >;
_cli_options_map_["--ostream-type"] =
&::cli::thunk< options, std::string, &options::ostream_type_,
&options::ostream_type_specified_ >;
+ _cli_options_map_["--export-symbol"] =
+ &::cli::thunk< options, std::string, &options::export_symbol_,
+ &options::export_symbol_specified_ >;
_cli_options_map_["--generate-cxx"] =
- &::cli::thunk< options, bool, &options::generate_cxx_ >;
+ &::cli::thunk< options, &options::generate_cxx_ >;
_cli_options_map_["--generate-man"] =
- &::cli::thunk< options, bool, &options::generate_man_ >;
+ &::cli::thunk< options, &options::generate_man_ >;
_cli_options_map_["--generate-html"] =
- &::cli::thunk< options, bool, &options::generate_html_ >;
+ &::cli::thunk< options, &options::generate_html_ >;
_cli_options_map_["--generate-txt"] =
- &::cli::thunk< options, bool, &options::generate_txt_ >;
+ &::cli::thunk< options, &options::generate_txt_ >;
_cli_options_map_["--stdout"] =
- &::cli::thunk< options, bool, &options::stdout__ >;
+ &::cli::thunk< options, &options::stdout__ >;
_cli_options_map_["--suppress-undocumented"] =
- &::cli::thunk< options, bool, &options::suppress_undocumented_ >;
+ &::cli::thunk< options, &options::suppress_undocumented_ >;
_cli_options_map_["--suppress-usage"] =
- &::cli::thunk< options, bool, &options::suppress_usage_ >;
+ &::cli::thunk< options, &options::suppress_usage_ >;
_cli_options_map_["--long-usage"] =
- &::cli::thunk< options, bool, &options::long_usage_ >;
+ &::cli::thunk< options, &options::long_usage_ >;
_cli_options_map_["--short-usage"] =
- &::cli::thunk< options, bool, &options::short_usage_ >;
+ &::cli::thunk< options, &options::short_usage_ >;
_cli_options_map_["--page-usage"] =
&::cli::thunk< options, std::string, &options::page_usage_,
&options::page_usage_specified_ >;
@@ -1868,13 +1915,13 @@ struct _cli_options_map_init
&::cli::thunk< options, std::size_t, &options::option_length_,
&options::option_length_specified_ >;
_cli_options_map_["--ascii-tree"] =
- &::cli::thunk< options, bool, &options::ascii_tree_ >;
+ &::cli::thunk< options, &options::ascii_tree_ >;
_cli_options_map_["--ansi-color"] =
- &::cli::thunk< options, bool, &options::ansi_color_ >;
+ &::cli::thunk< options, &options::ansi_color_ >;
_cli_options_map_["--exclude-base"] =
- &::cli::thunk< options, bool, &options::exclude_base_ >;
+ &::cli::thunk< options, &options::exclude_base_ >;
_cli_options_map_["--include-base-last"] =
- &::cli::thunk< options, bool, &options::include_base_last_ >;
+ &::cli::thunk< options, &options::include_base_last_ >;
_cli_options_map_["--class-doc"] =
&::cli::thunk< options, std::map<std::string, std::string>, &options::class_doc_,
&options::class_doc_specified_ >;
@@ -1891,12 +1938,12 @@ struct _cli_options_map_init
&::cli::thunk< options, std::vector<std::string>, &options::link_regex_,
&options::link_regex_specified_ >;
_cli_options_map_["--link-regex-trace"] =
- &::cli::thunk< options, bool, &options::link_regex_trace_ >;
+ &::cli::thunk< options, &options::link_regex_trace_ >;
_cli_options_map_["--html-heading-map"] =
&::cli::thunk< options, std::map<char, std::string>, &options::html_heading_map_,
&options::html_heading_map_specified_ >;
_cli_options_map_["--omit-link-check"] =
- &::cli::thunk< options, bool, &options::omit_link_check_ >;
+ &::cli::thunk< options, &options::omit_link_check_ >;
_cli_options_map_["--hxx-prologue"] =
&::cli::thunk< options, std::vector<std::string>, &options::hxx_prologue_,
&options::hxx_prologue_specified_ >;
@@ -2000,13 +2047,13 @@ struct _cli_options_map_init
&::cli::thunk< options, std::string, &options::option_separator_,
&options::option_separator_specified_ >;
_cli_options_map_["--keep-separator"] =
- &::cli::thunk< options, bool, &options::keep_separator_ >;
+ &::cli::thunk< options, &options::keep_separator_ >;
_cli_options_map_["--no-combined-flags"] =
- &::cli::thunk< options, bool, &options::no_combined_flags_ >;
+ &::cli::thunk< options, &options::no_combined_flags_ >;
_cli_options_map_["--no-combined-values"] =
- &::cli::thunk< options, bool, &options::no_combined_values_ >;
+ &::cli::thunk< options, &options::no_combined_values_ >;
_cli_options_map_["--include-with-brackets"] =
- &::cli::thunk< options, bool, &options::include_with_brackets_ >;
+ &::cli::thunk< options, &options::include_with_brackets_ >;
_cli_options_map_["--include-prefix"] =
&::cli::thunk< options, std::string, &options::include_prefix_,
&options::include_prefix_specified_ >;
diff --git a/cli/cli/bootstrap/cli/options.hxx b/cli/cli/bootstrap/cli/options.hxx
index 3ae86c6..08180f3 100644
--- a/cli/cli/bootstrap/cli/options.hxx
+++ b/cli/cli/bootstrap/cli/options.hxx
@@ -673,6 +673,21 @@ class options
void
ostream_type_specified (bool);
+ const std::string&
+ export_symbol () const;
+
+ std::string&
+ export_symbol ();
+
+ void
+ export_symbol (const std::string&);
+
+ bool
+ export_symbol_specified () const;
+
+ void
+ export_symbol_specified (bool);
+
const bool&
generate_cxx () const;
@@ -1562,6 +1577,8 @@ class options
bool cli_namespace_specified_;
std::string ostream_type_;
bool ostream_type_specified_;
+ std::string export_symbol_;
+ bool export_symbol_specified_;
bool generate_cxx_;
bool generate_man_;
bool generate_html_;
diff --git a/cli/cli/bootstrap/cli/options.ixx b/cli/cli/bootstrap/cli/options.ixx
index 8c22d51..e3fd397 100644
--- a/cli/cli/bootstrap/cli/options.ixx
+++ b/cli/cli/bootstrap/cli/options.ixx
@@ -672,6 +672,36 @@ ostream_type_specified (bool x)
this->ostream_type_specified_ = x;
}
+inline const std::string& options::
+export_symbol () const
+{
+ return this->export_symbol_;
+}
+
+inline std::string& options::
+export_symbol ()
+{
+ return this->export_symbol_;
+}
+
+inline void options::
+export_symbol (const std::string& x)
+{
+ this->export_symbol_ = x;
+}
+
+inline bool options::
+export_symbol_specified () const
+{
+ return this->export_symbol_specified_;
+}
+
+inline void options::
+export_symbol_specified (bool x)
+{
+ this->export_symbol_specified_ = x;
+}
+
inline const bool& options::
generate_cxx () const
{
diff --git a/cli/cli/context.cxx b/cli/cli/context.cxx
index 2833861..0c3254d 100644
--- a/cli/cli/context.cxx
+++ b/cli/cli/context.cxx
@@ -114,6 +114,8 @@ context (ostream& os_,
opt_prefix (options.option_prefix ()),
opt_sep (options.option_separator ()),
cli (data_->cli_),
+ exp (data_->exp_),
+ exp_inl (data_->exp_inl_),
reserved_name_map (options.reserved_name ()),
keyword_set (data_->keyword_set_),
link_regex (data_->link_regex_),
@@ -141,6 +143,16 @@ context (ostream& os_,
if (!cli.empty () && cli[0] != ':')
data_->cli_ = "::" + data_->cli_;
+ data_->exp_ = options.export_symbol ();
+
+ if (!exp.empty ())
+ {
+ data_->exp_ += ' ';
+
+ if (options.suppress_inline ())
+ data_->exp_inl_ = data_->exp_;
+ }
+
for (size_t i (0); i < sizeof (keywords) / sizeof (char*); ++i)
data_->keyword_set_.insert (keywords[i]);
@@ -179,6 +191,8 @@ context (context& c)
opt_prefix (c.opt_prefix),
opt_sep (c.opt_sep),
cli (c.cli),
+ exp (c.exp),
+ exp_inl (c.exp_inl),
reserved_name_map (c.reserved_name_map),
keyword_set (c.keyword_set),
link_regex (c.link_regex),
diff --git a/cli/cli/context.hxx b/cli/cli/context.hxx
index 19bfa51..c5802ed 100644
--- a/cli/cli/context.hxx
+++ b/cli/cli/context.hxx
@@ -92,6 +92,8 @@ public:
string const& opt_prefix;
string const& opt_sep;
string const& cli;
+ string const& exp;
+ string const& exp_inl; // Export symbol if inline is suppressed.
typedef std::map<string, string> reserved_name_map_type;
reserved_name_map_type const& reserved_name_map;
@@ -135,6 +137,8 @@ private:
{
string inl_;
string cli_;
+ string exp_;
+ string exp_inl_;
keyword_set_type keyword_set_;
regex_mapping link_regex_;
id_set_type id_set_;
diff --git a/cli/cli/header.cxx b/cli/cli/header.cxx
index a2a3ccd..87ff259 100644
--- a/cli/cli/header.cxx
+++ b/cli/cli/header.cxx
@@ -115,7 +115,7 @@ namespace
string name (escape (c.name ()));
string um (cli + "::unknown_mode");
- os << "class " << name;
+ os << "class " << exp << name;
{
base b (*this);
@@ -367,13 +367,13 @@ generate_header (context& ctx)
string up (ctx.cli + "::usage_para");
string const& ost (ctx.options.ostream_type ());
- os << up << endl
+ os << ctx.exp << up << endl
<< n << "usage (" << ost << "&," << endl
<< up << " = " << up << "::none);"
<< endl;
if (ctx.gen_usage == ut_both)
- os << up << endl
+ os << ctx.exp << up << endl
<< n << "long_usage (" << ost << "&," << endl
<< up << " = " << up << "::none);"
<< endl;
diff --git a/cli/cli/options.cli b/cli/cli/options.cli
index 3a3089b..03a0053 100644
--- a/cli/cli/options.cli
+++ b/cli/cli/options.cli
@@ -171,6 +171,13 @@ class options
should be used to print usage and exception information."
};
+ std::string --export-symbol
+ {
+ "<symbol>",
+ "Insert <symbol> in places where DLL export/import control statements
+ (\cb{__declspec(dllexport/dllimport)}) are necessary."
+ };
+
bool --generate-cxx
{
"Generate C++ code. If neither \cb{--generate-man}, \cb{--generate-html},
diff --git a/cli/cli/runtime-header.cxx b/cli/cli/runtime-header.cxx
index 2148941..c6e06dc 100644
--- a/cli/cli/runtime-header.cxx
+++ b/cli/cli/runtime-header.cxx
@@ -43,10 +43,13 @@ generate_runtime_header (context& ctx)
ctx.ns_open (ctx.cli);
+ string const& exp (ctx.exp);
+ string const& exp_inl (ctx.exp_inl);
+
// usage_para
//
if (!ctx.options.suppress_usage ())
- os << "class usage_para"
+ os << "class " << exp_inl << "usage_para"
<< "{"
<< "public:" << endl
<< "enum value"
@@ -64,7 +67,7 @@ generate_runtime_header (context& ctx)
// unknown_mode
//
- os << "class unknown_mode"
+ os << "class " << exp_inl << "unknown_mode"
<< "{"
<< "public:" << endl
<< "enum value"
@@ -89,18 +92,18 @@ generate_runtime_header (context& ctx)
<< "//" << endl
<< endl;
- os << "class exception: public std::exception"
+ os << "class " << exp << "exception: public std::exception"
<< "{"
<< "public:" << endl
<< "virtual void" << endl
<< "print (" << os_type << "&) const = 0;"
<< "};";
- os << os_type << "&" << endl
+ os << exp_inl << os_type << "&" << endl
<< "operator<< (" << os_type << "&, const exception&);"
<< endl;
- os << "class unknown_option: public exception"
+ os << "class " << exp << "unknown_option: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -121,7 +124,7 @@ generate_runtime_header (context& ctx)
<< "std::string option_;"
<< "};";
- os << "class unknown_argument: public exception"
+ os << "class " << exp << "unknown_argument: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -142,7 +145,7 @@ generate_runtime_header (context& ctx)
<< "std::string argument_;"
<< "};";
- os << "class missing_value: public exception"
+ os << "class " << exp << "missing_value: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -163,7 +166,7 @@ generate_runtime_header (context& ctx)
<< "std::string option_;"
<< "};";
- os << "class invalid_value: public exception"
+ os << "class " << exp << "invalid_value: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -194,7 +197,7 @@ generate_runtime_header (context& ctx)
<< "std::string message_;"
<< "};";
- os << "class eos_reached: public exception"
+ os << "class " << exp << "eos_reached: public exception"
<< "{"
<< "public:" << endl
<< "virtual void" << endl
@@ -206,7 +209,7 @@ generate_runtime_header (context& ctx)
if (ctx.options.generate_file_scanner ())
{
- os << "class file_io_failure: public exception"
+ os << "class " << exp << "file_io_failure: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -227,7 +230,7 @@ generate_runtime_header (context& ctx)
<< "std::string file_;"
<< "};";
- os << "class unmatched_quote: public exception"
+ os << "class " << exp << "unmatched_quote: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -251,7 +254,7 @@ generate_runtime_header (context& ctx)
if (ctx.options.generate_group_scanner ())
{
- os << "class unexpected_group: public exception"
+ os << "class " << exp << "unexpected_group: public exception"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -277,7 +280,7 @@ generate_runtime_header (context& ctx)
<< "std::string group_;"
<< "};";
- os << "class group_separator: public exception" << endl
+ os << "class " << exp << "group_separator: public exception" << endl
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -322,7 +325,7 @@ generate_runtime_header (context& ctx)
<< "// position of the previous scanner should be used as the" << endl
<< "// start position of the next." << endl
<< "//" << endl
- << "class scanner"
+ << "class " << exp << "scanner"
<< "{"
<< "public:" << endl
<< "virtual" << endl
@@ -346,7 +349,7 @@ generate_runtime_header (context& ctx)
// argv_scanner
//
- os << "class argv_scanner: public scanner"
+ os << "class " << exp << "argv_scanner: public scanner"
<< "{"
<< "public:" << endl
<< "argv_scanner (int& argc," << endl
@@ -390,7 +393,7 @@ generate_runtime_header (context& ctx)
//
if (ctx.options.generate_vector_scanner ())
{
- os << "class vector_scanner: public scanner"
+ os << "class " << exp << "vector_scanner: public scanner"
<< "{"
<< "public:" << endl
<< "vector_scanner (const std::vector<std::string>&," << endl
@@ -429,7 +432,7 @@ generate_runtime_header (context& ctx)
//
if (ctx.options.generate_file_scanner ())
{
- os << "class argv_file_scanner: public argv_scanner"
+ os << "class " << exp << "argv_file_scanner: public argv_scanner"
<< "{"
<< "public:" << endl
<< "argv_file_scanner (int& argc," << endl
@@ -549,7 +552,7 @@ generate_runtime_header (context& ctx)
//
if (ctx.options.generate_group_scanner ())
{
- os << "class group_scanner: public scanner"
+ os << "class " << exp << "group_scanner: public scanner"
<< "{"
<< "public:" << endl
<< "group_scanner (scanner&);"
@@ -632,7 +635,7 @@ generate_runtime_header (context& ctx)
os << "typedef std::vector<std::string> option_names;"
<< endl;
- os << "class option"
+ os << "class " << exp_inl << "option"
<< "{"
<< "public:" << endl
<< endl
@@ -662,7 +665,7 @@ generate_runtime_header (context& ctx)
<< "std::string default_value_;"
<< "};";
- os << "class options: public std::vector<option>"
+ os << "class " << exp << "options: public std::vector<option>"
<< "{"
<< "public:" << endl
<< "typedef std::vector<option> container_type;"
diff --git a/cli/cli/runtime-source.cxx b/cli/cli/runtime-source.cxx
index d5334a0..9620648 100644
--- a/cli/cli/runtime-source.cxx
+++ b/cli/cli/runtime-source.cxx
@@ -17,11 +17,11 @@ generate_runtime_source (context& ctx, bool complete)
<< "#include <vector>" << endl
<< "#include <utility>" << endl // pair
<< "#include <ostream>" << endl
- << "#include <sstream>" << endl;
+ << "#include <sstream>" << endl
+ << "#include <cstring>" << endl;
if (complete && ctx.options.generate_file_scanner ())
- os << "#include <cstring>" << endl
- << "#include <fstream>" << endl;
+ os << "#include <fstream>" << endl;
os << endl;
@@ -1011,11 +1011,33 @@ generate_runtime_source (context& ctx, bool complete)
<< "{";
os << "static void" << endl
- << "parse (bool& x, scanner& s)"
+ << "parse (bool& x, " << (sp ? "bool& xs, " : "") << "scanner& s)"
<< "{"
- << "s.next ();"
- << "x = true;"
- << "}";
+ << "const char* o (s.next ());"
+ << endl
+ << "if (s.more ())"
+ << "{"
+ << "const char* v (s.next ());"
+ << endl
+ << "if (std::strcmp (v, \"1\") == 0 ||" << endl
+ << "std::strcmp (v, \"true\") == 0 ||" << endl
+ << "std::strcmp (v, \"TRUE\") == 0 ||" << endl
+ << "std::strcmp (v, \"True\") == 0)" << endl
+ << "x = true;"
+ << "else if (std::strcmp (v, \"0\") == 0 ||" << endl
+ << "std::strcmp (v, \"false\") == 0 ||" << endl
+ << "std::strcmp (v, \"FALSE\") == 0 ||" << endl
+ << "std::strcmp (v, \"False\") == 0)" << endl
+ << "x = false;"
+ << "else" << endl
+ << "throw invalid_value (o, v);"
+ << "}"
+ << "else" << endl
+ << "throw missing_value (o);";
+ if (sp)
+ os << endl
+ << "xs = true;";
+ os << "}";
if (gen_merge)
os << "static void" << endl
@@ -1203,6 +1225,14 @@ generate_runtime_source (context& ctx, bool complete)
<< "parser<T>::parse (x.*M, s);"
<< "}";
+ os << "template <typename X, bool X::*M>" << endl
+ << "void" << endl
+ << "thunk (X& x, scanner& s)"
+ << "{"
+ << "s.next ();"
+ << "x.*M = true;"
+ << "}";
+
if (ctx.gen_specifier)
os << "template <typename X, typename T, T X::*M, bool X::*S>" << endl
<< "void" << endl
diff --git a/cli/cli/source.cxx b/cli/cli/source.cxx
index 1b9e832..3c04d1a 100644
--- a/cli/cli/source.cxx
+++ b/cli/cli/source.cxx
@@ -110,8 +110,12 @@ namespace
for (names::name_iterator i (n.name_begin ()); i != n.name_end (); ++i)
{
os << "_cli_" << scope << "_map_[\"" << *i << "\"] =" << endl
- << "&" << cli << "::thunk< " << scope << ", " << type << ", " <<
- "&" << scope << "::" << member;
+ << "&" << cli << "::thunk< " << scope;
+
+ if (type != "bool")
+ os << ", " << type;
+
+ os << ", " << "&" << scope << "::" << member;
if (gen_specifier && type != "bool")
os << "," << endl
@@ -1272,7 +1276,6 @@ generate_source (context& ctx)
ostream& os (ctx.os);
os << "#include <map>" << endl
- << "#include <cstring>" << endl
<< endl;
traversal::cli_unit unit;
diff --git a/cli/doc/bootstrap/cli.1 b/cli/doc/bootstrap/cli.1
index 8231848..2c9645e 100644
--- a/cli/doc/bootstrap/cli.1
+++ b/cli/doc/bootstrap/cli.1
@@ -157,6 +157,9 @@ 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--export-symbol\fR \fIsymbol\fR"
+Insert \fIsymbol\fR in places where DLL export/import control statements
+(\fB__declspec(dllexport/dllimport)\fR) are necessary\.
.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\.
diff --git a/cli/doc/bootstrap/cli.xhtml b/cli/doc/bootstrap/cli.xhtml
index 56273ef..96dc913 100644
--- a/cli/doc/bootstrap/cli.xhtml
+++ b/cli/doc/bootstrap/cli.xhtml
@@ -192,6 +192,11 @@ arg+{ --foo } # 'arg+{' ...</pre>
<code><b>std::ostream</b></code> that should be used to print usage and
exception information.</dd>
+ <dt><code><b>--export-symbol</b></code> <code><i>symbol</i></code></dt>
+ <dd>Insert <code><i>symbol</i></code> in places where DLL export/import
+ control statements (<code><b>__declspec(dllexport/dllimport)</b></code>)
+ are necessary.</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
diff --git a/cli/doc/cli-guide.xhtml b/cli/doc/cli-guide.xhtml
index 675db03..94c006c 100644
--- a/cli/doc/cli-guide.xhtml
+++ b/cli/doc/cli-guide.xhtml
@@ -1084,12 +1084,12 @@ include &lt;string>;
class options
{
- std::map&lt;std::string, std::string> --map | -m;
+ std::map&lt;std::string, bool> --map | -m;
};
</pre>
- <p>The possible option values for this interface are: <code>-m a=A</code>,
- <code>-m =B</code> (key is an empty string), <code>-m c=</code> (value
+ <p>The possible option values for this interface are: <code>-m a=1</code>,
+ <code>-m =true</code> (key is an empty string), <code>-m c=</code> (value
is an empty string), or <code>-m d</code> (same as <code>-m d=</code>).</p>
<p>The last component in the option definition is optional documentation.
diff --git a/cli/manifest b/cli/manifest
index 268c618..d86b889 100644
--- a/cli/manifest
+++ b/cli/manifest
@@ -1,6 +1,6 @@
: 1
name: cli
-version: 1.2.0-b.8.z
+version: 1.2.0-b.9
summary: Command line interface (CLI) compiler for C++
license: MIT
topics: C++, command line interface, source code generation, \
@@ -14,8 +14,8 @@ email: cli-users@codesynthesis.com ; Mailing list
build-warning-email: builds@codesynthesis.com
requires: c++14
requires: host
-depends: * build2 >= 0.14.0-
-depends: * bpkg >= 0.14.0-
+depends: * build2 >= 0.15.0-
+depends: * bpkg >= 0.15.0-
depends: libcutl ^1.11.0-
tests: * cli-tests == $
examples: * cli-examples == $