From 7b6259fdcdd8690c1c842eac90c60b841def6cc8 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Wed, 25 May 2011 19:27:24 +0000 Subject: [PATCH] Wave: merging from trunk [SVN r72164] --- ChangeLog | 1 + .../boost/wave/grammars/cpp_chlit_grammar.hpp | 12 +-- .../wave/grammars/cpp_expression_grammar.hpp | 22 +++++- .../wave/grammars/cpp_literal_grammar_gen.hpp | 4 +- include/boost/wave/wave_config.hpp | 16 ++++ include/boost/wave/wave_version.hpp | 4 +- .../cpp_tokens/instantiate_cpp_literalgrs.cpp | 6 +- .../instantiate_cpp_literalgrs.cpp | 6 +- .../instantiate_cpp_literalgrs.cpp | 6 +- src/instantiate_cpp_literalgrs.cpp | 6 +- tool/cpp.cpp | 76 +++++++++---------- tool/trace_macro_expansion.hpp | 12 +-- 12 files changed, 112 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e9c4de..12d80c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,7 @@ Boost V1.47.0 cause unexpected results if the suppressed macro would influence #ifdef's later on. - Fixed problem #5554: wave slex parser eof without eol skips the last line. + interactive mode. Boost V1.46.0 - V2.2.0 diff --git a/include/boost/wave/grammars/cpp_chlit_grammar.hpp b/include/boost/wave/grammars/cpp_chlit_grammar.hpp index f0af6e0..c494f9f 100644 --- a/include/boost/wave/grammars/cpp_chlit_grammar.hpp +++ b/include/boost/wave/grammars/cpp_chlit_grammar.hpp @@ -298,15 +298,15 @@ struct chlit_grammar : #define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE inline #endif -template +template BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE -unsigned int -chlit_grammar_gen::evaluate(TokenT const &token, value_error &status) +IntegralResult +chlit_grammar_gen::evaluate(TokenT const &token, value_error &status) { using namespace boost::spirit::classic; chlit_grammar g; -boost::uint32_t result = 0; +IntegralResult result = 0; typename TokenT::string_type const &token_val = token.get_value(); parse_info hit = parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]); @@ -320,7 +320,7 @@ parse_info hit = if ('L' == token_val[0]) { // recognized wide character if (g.overflow || - result > (unsigned long)(std::numeric_limits::max)()) + result > (IntegralResult)(std::numeric_limits::max)()) { // out of range status = error_character_overflow; @@ -329,7 +329,7 @@ parse_info hit = else { // recognized narrow ('normal') character if (g.overflow || - result > (unsigned long)(std::numeric_limits::max)()) + result > (IntegralResult)(std::numeric_limits::max)()) { // out of range status = error_character_overflow; diff --git a/include/boost/wave/grammars/cpp_expression_grammar.hpp b/include/boost/wave/grammars/cpp_expression_grammar.hpp index 6f69de2..a52d36a 100644 --- a/include/boost/wave/grammars/cpp_expression_grammar.hpp +++ b/include/boost/wave/grammars/cpp_expression_grammar.hpp @@ -105,7 +105,7 @@ namespace impl { /////////////////////////////////////////////////////////////////////////////// // -// convert the given token value (character literal) to a unsigned int +// Convert the given token value (character literal) to a unsigned int // /////////////////////////////////////////////////////////////////////////////// struct convert_chlit { @@ -122,7 +122,25 @@ namespace impl { { typedef boost::wave::grammars::closures::closure_value return_type; value_error status = error_noerror; - unsigned int value = chlit_grammar_gen::evaluate(token, status); + + // If the literal is a wchar_t and wchar_t is represented by a + // signed integral type, then the created value will be signed as + // well, otherwise we assume unsigned values. +#if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT + if ('L' == token.get_value()[0] && std::numeric_limits::is_signed) + { + int value = chlit_grammar_gen::evaluate(token, status); + return return_type(value, status); + } +#elif BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED + if ('L' == token.get_value()[0]) + { + int value = chlit_grammar_gen::evaluate(token, status); + return return_type(value, status); + } +#endif + + unsigned int value = chlit_grammar_gen::evaluate(token, status); return return_type(value, status); } }; diff --git a/include/boost/wave/grammars/cpp_literal_grammar_gen.hpp b/include/boost/wave/grammars/cpp_literal_grammar_gen.hpp index 9492daa..f6e2415 100644 --- a/include/boost/wave/grammars/cpp_literal_grammar_gen.hpp +++ b/include/boost/wave/grammars/cpp_literal_grammar_gen.hpp @@ -54,10 +54,10 @@ struct BOOST_WAVE_DECL intlit_grammar_gen { // to safe compilation time. // /////////////////////////////////////////////////////////////////////////////// -template +template struct BOOST_WAVE_DECL chlit_grammar_gen { - static unsigned int evaluate(TokenT const &tok, value_error& status); + static IntegralResult evaluate(TokenT const &tok, value_error& status); }; /////////////////////////////////////////////////////////////////////////////// diff --git a/include/boost/wave/wave_config.hpp b/include/boost/wave/wave_config.hpp index 13b1d1c..fa537a6 100644 --- a/include/boost/wave/wave_config.hpp +++ b/include/boost/wave/wave_config.hpp @@ -402,6 +402,22 @@ namespace boost { namespace wave #endif }} +/////////////////////////////////////////////////////////////////////////////// +// On some platforms Wave will not be able to properly detect whether wchar_t +// is representing a signed or unsigned integral data type. Use the +// configuration constants below to force wchar_t being signed or unsigned, as +// appropriate. +// +// The default is to use std::numeric_limits::is_signed. + +#define BOOST_WAVE_WCHAR_T_AUTOSELECT 1 +#define BOOST_WAVE_WCHAR_T_FORCE_SIGNED 2 +#define BOOST_WAVE_WCHAR_T_FORCE_UNSIGNED 3 + +#if !defined(BOOST_WAVE_WCHAR_T_SIGNEDNESS) +#define BOOST_WAVE_WCHAR_T_SIGNEDNESS BOOST_WAVE_WCHAR_T_AUTOSELECT +#endif + /////////////////////////////////////////////////////////////////////////////// // Wave needs at least 4 parameters for phoenix actors #if !defined(PHOENIX_LIMIT) diff --git a/include/boost/wave/wave_version.hpp b/include/boost/wave/wave_version.hpp index debe704..3512e0d 100644 --- a/include/boost/wave/wave_version.hpp +++ b/include/boost/wave/wave_version.hpp @@ -16,11 +16,11 @@ // BOOST_WAVE_VERSION & 0x0000FF is the sub-minor version // BOOST_WAVE_VERSION & 0x00FF00 is the minor version // BOOST_WAVE_VERSION & 0xFF0000 is the major version -#define BOOST_WAVE_VERSION 0x020200 +#define BOOST_WAVE_VERSION 0x020300 // The following defines contain the same information as above #define BOOST_WAVE_VERSION_MAJOR 2 -#define BOOST_WAVE_VERSION_MINOR 2 +#define BOOST_WAVE_VERSION_MINOR 3 #define BOOST_WAVE_VERSION_SUBMINOR 0 #endif // !defined(WAVE_VERSION_H_9D79ABDB_AC54_4C0A_89B1_F70A2DCFE21E_INCLUDED) diff --git a/samples/cpp_tokens/instantiate_cpp_literalgrs.cpp b/samples/cpp_tokens/instantiate_cpp_literalgrs.cpp index 8d98b02..a3fbe6d 100644 --- a/samples/cpp_tokens/instantiate_cpp_literalgrs.cpp +++ b/samples/cpp_tokens/instantiate_cpp_literalgrs.cpp @@ -37,7 +37,11 @@ typedef boost::wave::cpplexer::slex_token<> token_type; template struct boost::wave::grammars::intlit_grammar_gen; -template struct boost::wave::grammars::chlit_grammar_gen; +#if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT || \ + BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED +template struct boost::wave::grammars::chlit_grammar_gen; +#endif +template struct boost::wave::grammars::chlit_grammar_gen; #endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0 diff --git a/samples/list_includes/instantiate_cpp_literalgrs.cpp b/samples/list_includes/instantiate_cpp_literalgrs.cpp index 6cd4b0e..f87b99d 100644 --- a/samples/list_includes/instantiate_cpp_literalgrs.cpp +++ b/samples/list_includes/instantiate_cpp_literalgrs.cpp @@ -37,7 +37,11 @@ typedef boost::wave::cpplexer::lex_token<> token_type; template struct boost::wave::grammars::intlit_grammar_gen; -template struct boost::wave::grammars::chlit_grammar_gen; +#if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT || \ + BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED +template struct boost::wave::grammars::chlit_grammar_gen; +#endif +template struct boost::wave::grammars::chlit_grammar_gen; #endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0 diff --git a/samples/real_positions/instantiate_cpp_literalgrs.cpp b/samples/real_positions/instantiate_cpp_literalgrs.cpp index e34a59f..422a319 100644 --- a/samples/real_positions/instantiate_cpp_literalgrs.cpp +++ b/samples/real_positions/instantiate_cpp_literalgrs.cpp @@ -36,7 +36,11 @@ typedef lex_token<> token_type; template struct boost::wave::grammars::intlit_grammar_gen; -template struct boost::wave::grammars::chlit_grammar_gen; +#if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT || \ + BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED +template struct boost::wave::grammars::chlit_grammar_gen; +#endif +template struct boost::wave::grammars::chlit_grammar_gen; #endif // #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0 diff --git a/src/instantiate_cpp_literalgrs.cpp b/src/instantiate_cpp_literalgrs.cpp index 96ef476..4fbfb87 100644 --- a/src/instantiate_cpp_literalgrs.cpp +++ b/src/instantiate_cpp_literalgrs.cpp @@ -41,7 +41,11 @@ typedef boost::wave::cpplexer::lex_token<> token_type; // no need to change anything below template struct boost::wave::grammars::intlit_grammar_gen; -template struct boost::wave::grammars::chlit_grammar_gen; +#if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT || \ + BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED +template struct boost::wave::grammars::chlit_grammar_gen; +#endif +template struct boost::wave::grammars::chlit_grammar_gen; // the suffix header occurs after all of the code #ifdef BOOST_HAS_ABI_HEADERS diff --git a/tool/cpp.cpp b/tool/cpp.cpp index 0f9d092..91270dc 100644 --- a/tool/cpp.cpp +++ b/tool/cpp.cpp @@ -143,10 +143,10 @@ int print_copyright() "LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)", 0 }; - + for (int i = 0; 0 != copyright[i]; ++i) cout << copyright[i] << endl; - + return 0; // exit app } @@ -216,7 +216,7 @@ namespace cmd_line_utils { else { // store this path as an user path p->paths.push_back(t); - } + } } }; @@ -236,7 +236,7 @@ namespace cmd_line_utils { } return false; } - + vector options; std::string line; @@ -245,7 +245,7 @@ namespace cmd_line_utils { std::string::size_type pos = line.find_first_not_of(" \t"); if (pos == std::string::npos) continue; - + // skip comment lines if ('#' != line[pos]) { // strip leading and trailing whitespace @@ -281,7 +281,7 @@ namespace cmd_line_utils { } return file; } - + /////////////////////////////////////////////////////////////////////////////// } @@ -311,7 +311,7 @@ namespace { : print_time(false), outstrm(outstrm_) { } - + ~auto_stop_watch() { if (print_time) { @@ -320,7 +320,7 @@ namespace { << std::endl; } } - + void set_print_time(bool print_time_) { print_time = print_time_; @@ -350,7 +350,7 @@ namespace { "end-of-file while writing to the stream\n"; } return result; - } + } /////////////////////////////////////////////////////////////////////////// // Retrieve the position of a macro definition @@ -364,7 +364,7 @@ namespace { bool is_predefined = false; std::vector parameters; typename Context::token_sequence_type definition; - + return ctx.get_macro_definition(name, has_parameters, is_predefined, pos, parameters, definition); } @@ -422,7 +422,7 @@ namespace { return result; } - + /////////////////////////////////////////////////////////////////////////// // Read one logical line of text inline bool @@ -560,13 +560,13 @@ namespace { for (name_iterator it = ctx.macro_names_begin(); it != end; ++it) { typedef std::vector parameters_type; - + bool has_pars = false; bool predef = false; context_type::position_type pos; parameters_type pars; context_type::token_sequence_type def; - + if (ctx.get_macro_definition(*it, has_pars, predef, pos, pars, def)) { macronames_out << (predef ? "-P" : "-D") << *it; @@ -666,7 +666,7 @@ int error_count = 0; std::istreambuf_iterator()); #endif } - + // The preprocessing of the input stream is done on the fly behind the // scenes during iteration over the context_type::iterator_type stream. std::ofstream output; @@ -871,13 +871,13 @@ int error_count = 0; ctx.get_language(), false)); } #endif - + // enable preserving comments mode if (preserve_comments) { ctx.set_language( boost::wave::enable_preserve_comments(ctx.get_language())); } - + // control the generation of #line directives if (vm.count("line")) { int lineopt = vm["line"].as(); @@ -910,7 +910,7 @@ int error_count = 0; // add include directories to the system include search paths if (vm.count("sysinclude")) { vector syspaths = vm["sysinclude"].as >(); - + vector::const_iterator end = syspaths.end(); for (vector::const_iterator cit = syspaths.begin(); cit != end; ++cit) @@ -918,7 +918,7 @@ int error_count = 0; ctx.add_sysinclude_path(cmd_line_utils::trim_quotes(*cit).c_str()); } } - + // add include directories to the include search paths if (vm.count("include")) { cmd_line_utils::include_paths const &ip = @@ -934,7 +934,7 @@ int error_count = 0; // if -I- was given on the command line, this has to be propagated if (ip.seen_separator) ctx.set_sysinclude_delimiter(); - + // add system include directories to the include path vector::const_iterator sysend = ip.syspaths.end(); for (vector::const_iterator syscit = ip.syspaths.begin(); @@ -943,7 +943,7 @@ int error_count = 0; ctx.add_sysinclude_path(cmd_line_utils::trim_quotes(*syscit).c_str()); } } - + // add additional defined macros if (vm.count("define")) { vector const ¯os = vm["define"].as >(); @@ -980,7 +980,7 @@ int error_count = 0; } #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS == 0 - // suppress expansion of, specified macros + // suppress expansion of specified macros if (vm.count("noexpand")) { vector const &noexpandmacros = vm["noexpand"].as >(); @@ -1003,7 +1003,7 @@ int error_count = 0; } ctx.set_max_include_nesting_depth(max_depth); } - + // open the output file if (vm.count("output")) { // try to open the file, where to put the preprocessed output @@ -1049,17 +1049,17 @@ int error_count = 0; // we assume the session to be interactive if input is stdin and output is // stdout and the output is not inhibited bool is_interactive = input_is_stdin && !output.is_open() && allow_output; - + if (is_interactive) { // if interactive we don't warn for missing endif's etc. ctx.set_language( - boost::wave::enable_single_line(ctx.get_language())); + boost::wave::enable_single_line(ctx.get_language()), false); } - + // analyze the input file context_type::iterator_type first = ctx.begin(); context_type::iterator_type last = ctx.end(); - + // preprocess the required include files if (vm.count("forceinclude")) { // add the filenames to force as include files in _reverse_ order @@ -1093,7 +1093,7 @@ int error_count = 0; do { // loop over all generated tokens outputting the generated text bool finished = false; - + if (input_is_stdin) { if (is_interactive) cout << ">>> "; // prompt if is interactive @@ -1104,16 +1104,16 @@ int error_count = 0; break; // end of input reached first = ctx.begin(instring.begin(), instring.end()); } - + bool need_to_advanve = false; - + do { try { if (need_to_advanve) { ++first; need_to_advanve = false; } - + while (first != last) { // store the last known good token position current_position = (*first).get_position(); @@ -1131,7 +1131,7 @@ int error_count = 0; else cout << (*first).get_value(); } - + // advance to the next token ++first; } @@ -1215,12 +1215,12 @@ main (int argc, char *argv[]) << " using a different configuration (see wave_config.hpp)." << endl; } - + // analyze the command line options and arguments try { // declare the options allowed on the command line only po::options_description desc_cmdline ("Options allowed on the command line only"); - + desc_cmdline.add_options() ("help,h", "print out program usage (this message)") ("version,v", "print the version number") @@ -1257,7 +1257,7 @@ main (int argc, char *argv[]) ("nesting,n", po::value(), "specify a new maximal include nesting depth") ; - + po::options_description desc_ext ("Extended options (allowed everywhere)"); desc_ext.add_options() @@ -1309,21 +1309,21 @@ main (int argc, char *argv[]) "or 'wave.state' [-] (interactive mode only)") #endif ; - + // combine the options for the different usage schemes po::options_description desc_overall_cmdline; po::options_description desc_overall_cfgfile; desc_overall_cmdline.add(desc_cmdline).add(desc_generic).add(desc_ext); desc_overall_cfgfile.add(desc_generic).add(desc_ext); - + // parse command line and store results using namespace boost::program_options::command_line_style; po::parsed_options opts(po::parse_command_line(argc, argv, desc_overall_cmdline, unix_style, cmd_line_utils::at_option_parser)); po::variables_map vm; - + po::store(opts, vm); po::notify(vm); @@ -1389,7 +1389,7 @@ main (int argc, char *argv[]) cout << desc_help << endl; return 1; } - + if (vm.count("version")) { cout << get_version() << endl; return 0; diff --git a/tool/trace_macro_expansion.hpp b/tool/trace_macro_expansion.hpp index 57c56aa..7679a2e 100644 --- a/tool/trace_macro_expansion.hpp +++ b/tool/trace_macro_expansion.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -161,8 +162,6 @@ public: default_outfile(default_outfile_), emit_relative_filenames(false) { - using namespace std; // some systems have time in namespace std - time(&started_at); } ~trace_macro_expansion() { @@ -1046,11 +1045,14 @@ protected: // ensure all directories for this file do exist fs::create_directories(boost::wave::util::branch_path(fpath)); - // figure out, whether the file to open was last accessed by us + // figure out, whether the file has been written to by us, if yes, we + // append any output to this file, otherwise we overwrite it std::ios::openmode mode = std::ios::out; - if (fs::exists(fpath) && fs::last_write_time(fpath) >= started_at) + if (fs::exists(fpath) && written_by_us.find(fpath) != written_by_us.end()) mode = (std::ios::openmode)(std::ios::out | std::ios::app); + written_by_us.insert(fpath); + // close the current file if (outputstrm.is_open()) outputstrm.close(); @@ -1460,7 +1462,7 @@ private: boost::filesystem::path current_outfile; // name of the current output file stop_watch elapsed_time; // trace timings - std::time_t started_at; // time, this process was started at + std::set written_by_us; // all files we have written to typedef std::pair output_option_type; std::stack output_options; // output option stack