From 83de480a8bab105dac641f31bf2a9e6adda02fcb Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 18 Feb 2022 11:56:41 +0300 Subject: Add --export-symbol option --- cli/cli/bootstrap/cli/options.cxx | 19 +++++++++++++++++ cli/cli/bootstrap/cli/options.hxx | 17 ++++++++++++++++ cli/cli/bootstrap/cli/options.ixx | 30 +++++++++++++++++++++++++++ cli/cli/context.cxx | 14 +++++++++++++ cli/cli/context.hxx | 4 ++++ cli/cli/header.cxx | 6 +++--- cli/cli/options.cli | 7 +++++++ cli/cli/runtime-header.cxx | 43 +++++++++++++++++++++------------------ cli/doc/bootstrap/cli.1 | 3 +++ cli/doc/bootstrap/cli.xhtml | 5 +++++ 10 files changed, 125 insertions(+), 23 deletions(-) diff --git a/cli/cli/bootstrap/cli/options.cxx b/cli/cli/bootstrap/cli/options.cxx index e66ae63..5ed58b4 100644 --- a/cli/cli/bootstrap/cli/options.cxx +++ b/cli/cli/bootstrap/cli/options.cxx @@ -702,6 +702,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 +846,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 +993,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 +1140,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 +1289,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 +1434,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 +1602,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 Insert 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; @@ -1843,6 +1859,9 @@ struct _cli_options_map_init _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_options_map_["--generate-man"] = 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 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 + { + "", + "Insert 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&," << 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 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