From 9bf40e4a91f6a792c3279d9184b67451cf58bf49 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 9 Dec 2015 18:02:40 +0200 Subject: Add --std option with c++{98,11,14} values; use function-static in C++11 This way we can use option descriptions during static initialization (e.g., of an Apache module). --- cli/buildfile | 2 +- cli/header.cxx | 2 +- cli/makefile | 1 + cli/option-types.cxx | 44 ++++++++++++++++++++++++++++++++++++++++++++ cli/option-types.hxx | 34 ++++++++++++++++++++++++++++++++++ cli/options.cli | 9 +++++++++ cli/options.cxx | 18 ++++++++++++++++++ cli/options.hxx | 10 ++++++++++ cli/options.ixx | 12 ++++++++++++ cli/source.cxx | 25 +++++++++++++------------ 10 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 cli/option-types.cxx create mode 100644 cli/option-types.hxx (limited to 'cli') diff --git a/cli/buildfile b/cli/buildfile index 88b31f3..d221237 100644 --- a/cli/buildfile +++ b/cli/buildfile @@ -5,6 +5,6 @@ trav = traversal/{class elements namespace option unit} exe{cli}: cxx{cli generator html lexer name-processor parser runtime-inline \ source context header inline man options runtime-header runtime-source \ -$sema $trav} $libs +option-types $sema $trav} $libs cxx.poptions += -I$out_base -I$src_base diff --git a/cli/header.cxx b/cli/header.cxx index d5ab674..e2aebd4 100644 --- a/cli/header.cxx +++ b/cli/header.cxx @@ -231,7 +231,7 @@ namespace // fill () // if (options.generate_description ()) - os << "friend struct _cli_" + name + "_desc_init;" + os << "friend struct _cli_" + name + "_desc_type;" << endl << "static void" << endl << "fill (" << cli << "::options&);" diff --git a/cli/makefile b/cli/makefile index 71ddd9c..3b29fdc 100644 --- a/cli/makefile +++ b/cli/makefile @@ -8,6 +8,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make cxx_tun := cli.cxx lexer.cxx parser.cxx cxx_tun += \ +option-types.cxx \ options.cxx \ context.cxx \ header.cxx \ diff --git a/cli/option-types.cxx b/cli/option-types.cxx new file mode 100644 index 0000000..b3bc6ad --- /dev/null +++ b/cli/option-types.cxx @@ -0,0 +1,44 @@ +// file : cli/option-types.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include + +#include "option-types.hxx" + +using namespace std; + +static const char* cxx_version_[] = +{ + "c++98", + "c++11" + "c++14" +}; + +string cxx_version:: +string () const +{ + return cxx_version_[v_]; +} + +istream& +operator>> (istream& is, cxx_version& v) +{ + string s; + is >> s; + + if (!is.fail ()) + { + if (s == "c++98") + v = cxx_version::cxx98; + else if (s == "c++11") + v = cxx_version::cxx11; + else if (s == "c++14") + v = cxx_version::cxx14; + else + is.setstate (istream::failbit); + } + + return is; +} diff --git a/cli/option-types.hxx b/cli/option-types.hxx new file mode 100644 index 0000000..03cfbaa --- /dev/null +++ b/cli/option-types.hxx @@ -0,0 +1,34 @@ +// file : cli/option-types.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef CLI_OPTION_TYPES_HXX +#define CLI_OPTION_TYPES_HXX + +#include +#include + +struct cxx_version +{ + enum value + { + cxx98, + cxx11, + cxx14 + }; + + cxx_version (value v = value (0)) : v_ (v) {} + operator value () const {return v_;} + + std::string + string () const; + +private: + value v_; +}; + +std::istream& +operator>> (std::istream&, cxx_version&); + +#endif // CLI_OPTION_TYPES_HXX diff --git a/cli/options.cli b/cli/options.cli index 9554d10..0f0d1a9 100644 --- a/cli/options.cli +++ b/cli/options.cli @@ -12,6 +12,8 @@ include ; include ; include ; +include "option-types.hxx"; + class options { bool --help {"Print usage information and exit."}; @@ -29,6 +31,13 @@ class options "Write the generated files to instead of the current directory." }; + cxx_version --std = cxx_version::cxx98 + { + "", + "Specify the C++ standard that should be used during compilation. + Valid values are \cb{c++98} (default), \cb{c++11}, and \cb{c++14}." + }; + bool --generate-modifier { "Generate option value modifiers in addition to accessors." diff --git a/cli/options.cxx b/cli/options.cxx index 95f2a6c..3e7dbcc 100644 --- a/cli/options.cxx +++ b/cli/options.cxx @@ -567,6 +567,8 @@ options () include_path_specified_ (false), output_dir_ (), output_dir_specified_ (false), + std_ (cxx_version::cxx98), + std_specified_ (false), generate_modifier_ (), generate_specifier_ (), generate_parse_ (), @@ -676,6 +678,8 @@ options (int& argc, include_path_specified_ (false), output_dir_ (), output_dir_specified_ (false), + std_ (cxx_version::cxx98), + std_specified_ (false), generate_modifier_ (), generate_specifier_ (), generate_parse_ (), @@ -788,6 +792,8 @@ options (int start, include_path_specified_ (false), output_dir_ (), output_dir_specified_ (false), + std_ (cxx_version::cxx98), + std_specified_ (false), generate_modifier_ (), generate_specifier_ (), generate_parse_ (), @@ -900,6 +906,8 @@ options (int& argc, include_path_specified_ (false), output_dir_ (), output_dir_specified_ (false), + std_ (cxx_version::cxx98), + std_specified_ (false), generate_modifier_ (), generate_specifier_ (), generate_parse_ (), @@ -1014,6 +1022,8 @@ options (int start, include_path_specified_ (false), output_dir_ (), output_dir_specified_ (false), + std_ (cxx_version::cxx98), + std_specified_ (false), generate_modifier_ (), generate_specifier_ (), generate_parse_ (), @@ -1124,6 +1134,8 @@ options (::cli::scanner& s, include_path_specified_ (false), output_dir_ (), output_dir_specified_ (false), + std_ (cxx_version::cxx98), + std_specified_ (false), generate_modifier_ (), generate_specifier_ (), generate_parse_ (), @@ -1240,6 +1252,9 @@ print_usage (::std::ostream& os, ::cli::usage_para p) os << "--output-dir|-o Write the generated files to instead of the" << ::std::endl << " current directory." << ::std::endl; + os << "--std Specify the C++ standard that should be used" << ::std::endl + << " during compilation." << ::std::endl; + os << "--generate-modifier Generate option value modifiers in addition to" << ::std::endl << " accessors." << ::std::endl; @@ -1436,6 +1451,9 @@ struct _cli_options_map_init _cli_options_map_["-o"] = &::cli::thunk< options, std::string, &options::output_dir_, &options::output_dir_specified_ >; + _cli_options_map_["--std"] = + &::cli::thunk< options, cxx_version, &options::std_, + &options::std_specified_ >; _cli_options_map_["--generate-modifier"] = &::cli::thunk< options, bool, &options::generate_modifier_ >; _cli_options_map_["--generate-specifier"] = diff --git a/cli/options.hxx b/cli/options.hxx index 268e0fd..6171cc0 100644 --- a/cli/options.hxx +++ b/cli/options.hxx @@ -352,6 +352,8 @@ namespace cli #include +#include "option-types.hxx" + class options { public: @@ -409,6 +411,12 @@ class options bool output_dir_specified () const; + const cxx_version& + std () const; + + bool + std_specified () const; + const bool& generate_modifier () const; @@ -716,6 +724,8 @@ class options bool include_path_specified_; std::string output_dir_; bool output_dir_specified_; + cxx_version std_; + bool std_specified_; bool generate_modifier_; bool generate_specifier_; bool generate_parse_; diff --git a/cli/options.ixx b/cli/options.ixx index 3adfbd0..1d61ecb 100644 --- a/cli/options.ixx +++ b/cli/options.ixx @@ -247,6 +247,18 @@ output_dir_specified () const return this->output_dir_specified_; } +inline const cxx_version& options:: +std () const +{ + return this->std_; +} + +inline bool options:: +std_specified () const +{ + return this->std_specified_; +} + inline const bool& options:: generate_modifier () const { diff --git a/cli/source.cxx b/cli/source.cxx index 38df449..eae40dc 100644 --- a/cli/source.cxx +++ b/cli/source.cxx @@ -924,23 +924,20 @@ namespace { string desc ("_cli_" + name + "_desc"); - os << "static " << cli << "::options " << desc << "_;" - << endl; - - os << "struct " << desc << "_init" + os << "struct " << desc << "_type: " << cli << "::options" << "{" - << desc << "_init (" << cli << "::options& os)" + << desc << "_type ()" << "{" - << name << "::fill (os);" + << fq_name (c) << "::fill (*this);" << "}" << "};"; - os << "static " << desc << "_init " << desc << "_init_ (" << - desc << "_);" - << endl; + if (options.std () < cxx_version::cxx11) + os << "static " << desc << "_type " << desc << "_;" + << endl; os << "void " << name << "::" << endl - << "fill (" << cli << "::options& " << (ho || hb ? " os)" : ")") + << "fill (" << cli << "::options&" << (ho || hb ? " os)" : ")") << "{"; // Add the entries from our bases first so that our entires @@ -953,8 +950,12 @@ namespace os << "const " << cli << "::options& " << name << "::" << endl << "description ()" - << "{" - << "return " << desc << "_;" + << "{"; + + if (options.std () >= cxx_version::cxx11) + os << "static ::" << desc << "_type " << desc << "_;"; + + os << "return " << desc << "_;" << "};"; } -- cgit v1.1