diff --git a/ChangeLog b/ChangeLog index 082523b..a6acd91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,20 @@ TODO (known issues): CHANGELOG +- Added util::create_directories() wrapper to account for new behavior of + boost::filesystem::create_directories(). +- Fixed an obscure problem when preprocessing directives wouldn't be recognized + if the previous line contained nothing but an empty macro invocation + (see new test case t_9_023.cpp) +- Added a new command line option --license= to the Wave driver tool + which allows to pre-pend the content of a (license) file to every newly + created file. This option simplifies the implementation of partial + preprocessing as done on Phoenix, Fusion, etc. +- Changed the effect of the -N command line option to simply not expand + the macro by pretending it was not defined. Earlier the whole invocation + sequence was skipped, now we skip only the macro itself, which still expands + the arguments for the macro invocation. + Boost V1.51.0 - Fixed #7050: Invalid memory write bug in lexing_exception - Fixed #7159: Text-lines are processed as if they were preprocessing directives diff --git a/include/boost/wave/util/cpp_iterator.hpp b/include/boost/wave/util/cpp_iterator.hpp index e6271ac..8b378d6 100644 --- a/include/boost/wave/util/cpp_iterator.hpp +++ b/include/boost/wave/util/cpp_iterator.hpp @@ -515,6 +515,9 @@ pp_iterator_functor::operator()() act_token.set_value("\n"); } + if (IS_CATEGORY(id, EOLTokenType)) + seen_newline = true; + } while (ctx.get_hooks().may_skip_whitespace(ctx.derived(), act_token, skipped_newline)); } catch (boost::wave::cpplexer::lexing_exception const& e) { diff --git a/include/boost/wave/util/cpp_macromap.hpp b/include/boost/wave/util/cpp_macromap.hpp index 182567e..fb251ea 100644 --- a/include/boost/wave/util/cpp_macromap.hpp +++ b/include/boost/wave/util/cpp_macromap.hpp @@ -2,7 +2,7 @@ Boost.Wave: A Standard compliant C++ preprocessor library Macro expansion engine - + http://www.boost.org/ Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost @@ -58,9 +58,9 @@ namespace boost { namespace wave { namespace util { /////////////////////////////////////////////////////////////////////////////// // // macromap -// -// This class holds all currently defined macros and on demand expands -// those macro definitions +// +// This class holds all currently defined macros and on demand expands +// those macro definitions // /////////////////////////////////////////////////////////////////////////////// template @@ -74,16 +74,16 @@ class macromap { typedef typename ContextT::token_sequence_type definition_container_type; typedef std::vector parameter_container_type; - typedef macro_definition + typedef macro_definition macro_definition_type; - typedef symbol_table + typedef symbol_table defined_macros_type; - typedef typename defined_macros_type::value_type::second_type + typedef typename defined_macros_type::value_type::second_type macro_ref_type; public: - macromap(ContextT &ctx_) - : current_macros(0), defined_macros(new defined_macros_type(1)), + macromap(ContextT &ctx_) + : current_macros(0), defined_macros(new defined_macros_type(1)), main_pos("", 0), ctx(ctx_), macro_uid(1) { current_macros = defined_macros.get(); @@ -91,14 +91,14 @@ public: ~macromap() {} // Add a new macro to the given macro scope - bool add_macro(token_type const &name, bool has_parameters, - parameter_container_type ¶meters, - definition_container_type &definition, bool is_predefined = false, + bool add_macro(token_type const &name, bool has_parameters, + parameter_container_type ¶meters, + definition_container_type &definition, bool is_predefined = false, defined_macros_type *scope = 0); // Tests, whether the given macro name is defined in the given macro scope - bool is_defined(string_type const &name, - typename defined_macros_type::iterator &it, + bool is_defined(string_type const &name, + typename defined_macros_type::iterator &it, defined_macros_type *scope = 0) const; // expects a token sequence as its parameters @@ -109,31 +109,31 @@ public: bool is_defined(string_type const &str) const; // Get the macro definition for the given macro scope - bool get_macro(string_type const &name, bool &has_parameters, - bool &is_predefined, position_type &pos, - parameter_container_type ¶meters, - definition_container_type &definition, + bool get_macro(string_type const &name, bool &has_parameters, + bool &is_predefined, position_type &pos, + parameter_container_type ¶meters, + definition_container_type &definition, defined_macros_type *scope = 0) const; // Remove a macro name from the given macro scope - bool remove_macro(string_type const &name, position_type const& pos, + bool remove_macro(string_type const &name, position_type const& pos, bool even_predefined = false); template - token_type const &expand_tokensequence(IteratorT &first, - IteratorT const &last, ContainerT &pending, ContainerT &expanded, + token_type const &expand_tokensequence(IteratorT &first, + IteratorT const &last, ContainerT &pending, ContainerT &expanded, bool& seen_newline, bool expand_operator_defined); // Expand all macros inside the given token sequence template - void expand_whole_tokensequence(ContainerT &expanded, - IteratorT &first, IteratorT const &last, + void expand_whole_tokensequence(ContainerT &expanded, + IteratorT &first, IteratorT const &last, bool expand_operator_defined); // Init the predefined macros (add them to the given scope) - void init_predefined_macros(char const *fname = "", + void init_predefined_macros(char const *fname = "", defined_macros_type *scope = 0, bool at_global_scope = true); - void predefine_macro(defined_macros_type *scope, string_type const &name, + void predefine_macro(defined_macros_type *scope, string_type const &name, token_type const &t); // Init the internal macro symbol namespace @@ -146,9 +146,9 @@ public: typedef typename defined_macros_type::name_iterator name_iterator; typedef typename defined_macros_type::const_name_iterator const_name_iterator; - name_iterator begin() + name_iterator begin() { return defined_macros_type::make_iterator(current_macros->begin()); } - name_iterator end() + name_iterator end() { return defined_macros_type::make_iterator(current_macros->end()); } const_name_iterator begin() const { return defined_macros_type::make_iterator(current_macros->begin()); } @@ -158,43 +158,43 @@ public: protected: // Helper functions for expanding all macros in token sequences template - token_type const &expand_tokensequence_worker(ContainerT &pending, - unput_queue_iterator &first, - unput_queue_iterator const &last, + token_type const &expand_tokensequence_worker(ContainerT &pending, + unput_queue_iterator &first, + unput_queue_iterator const &last, bool& seen_newline, bool expand_operator_defined); // Collect all arguments supplied to a macro invocation #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 template typename std::vector::size_type collect_arguments ( - token_type const curr_token, std::vector &arguments, + token_type const curr_token, std::vector &arguments, IteratorT &next, IteratorT const &end, SizeT const ¶meter_count, bool& seen_newline); #else template typename std::vector::size_type collect_arguments ( - token_type const curr_token, std::vector &arguments, - IteratorT &next, IteratorT &endparen, IteratorT const &end, + token_type const curr_token, std::vector &arguments, + IteratorT &next, IteratorT &endparen, IteratorT const &end, SizeT const ¶meter_count, bool& seen_newline); #endif // Expand a single macro name template - bool expand_macro(ContainerT &pending, token_type const &name, - typename defined_macros_type::iterator it, - IteratorT &first, IteratorT const &last, + bool expand_macro(ContainerT &pending, token_type const &name, + typename defined_macros_type::iterator it, + IteratorT &first, IteratorT const &last, bool& seen_newline, bool expand_operator_defined, defined_macros_type *scope = 0, ContainerT *queue_symbol = 0); // Expand a predefined macro (__LINE__, __FILE__ and __INCLUDE_LEVEL__) template - bool expand_predefined_macro(token_type const &curr_token, + bool expand_predefined_macro(token_type const &curr_token, ContainerT &expanded); // Expand a single macro argument template void expand_argument (typename std::vector::size_type arg, - std::vector &arguments, + std::vector &arguments, std::vector &expanded_args, bool expand_operator_defined, std::vector &has_expanded_args); @@ -202,13 +202,13 @@ protected: template void expand_replacement_list( macro_definition_type const ¯odefinition, - std::vector &arguments, + std::vector &arguments, bool expand_operator_defined, ContainerT &expanded); // Rescans the replacement list for macro expansion template - void rescan_replacement_list(token_type const &curr_token, - macro_definition_type ¯odef, ContainerT &replacement_list, + void rescan_replacement_list(token_type const &curr_token, + macro_definition_type ¯odef, ContainerT &replacement_list, ContainerT &expanded, bool expand_operator_defined, IteratorT &nfirst, IteratorT const &nlast); @@ -219,15 +219,15 @@ protected: // Resolve operator _Pragma or the #pragma directive template - bool resolve_operator_pragma(IteratorT &first, + bool resolve_operator_pragma(IteratorT &first, IteratorT const &last, ContainerT &expanded, bool& seen_newline); -// Handle the concatenation operator '##' +// Handle the concatenation operator '##' template bool concat_tokensequence(ContainerT &expanded); template - bool is_valid_concat(string_type new_value, + bool is_valid_concat(string_type new_value, position_type const &pos, ContainerT &rescanned); #if BOOST_WAVE_SERIALIZATION != 0 @@ -248,7 +248,7 @@ private: { using namespace boost::serialization; if (version != (loaded_version & ~version_mask)) { - BOOST_WAVE_THROW(preprocess_exception, incompatible_config, + BOOST_WAVE_THROW(preprocess_exception, incompatible_config, "cpp_context state version", get_main_pos()); } ar & make_nvp("defined_macros", defined_macros); @@ -271,35 +271,35 @@ private: /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -// +// // add_macro(): adds a new macro to the macromap // /////////////////////////////////////////////////////////////////////////////// template -inline bool -macromap::add_macro(token_type const &name, bool has_parameters, - parameter_container_type ¶meters, definition_container_type &definition, +inline bool +macromap::add_macro(token_type const &name, bool has_parameters, + parameter_container_type ¶meters, definition_container_type &definition, bool is_predefined, defined_macros_type *scope) { if (!is_predefined && impl::is_special_macroname (name.get_value())) { // exclude special macro names - BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, - illegal_redefinition, name.get_value().c_str(), main_pos, + BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, + illegal_redefinition, name.get_value().c_str(), main_pos, name.get_value().c_str()); return false; } - if (boost::wave::need_variadics(ctx.get_language()) && - "__VA_ARGS__" == name.get_value()) + if (boost::wave::need_variadics(ctx.get_language()) && + "__VA_ARGS__" == name.get_value()) { // can't use __VA_ARGS__ as a macro name - BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, - bad_define_statement_va_args, name.get_value().c_str(), main_pos, + BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, + bad_define_statement_va_args, name.get_value().c_str(), main_pos, name.get_value().c_str()); return false; } if (AltExtTokenType == (token_id(name) & ExtTokenOnlyMask)) { // exclude special operator names - BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, + BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, illegal_operator_redefinition, name.get_value().c_str(), main_pos, name.get_value().c_str()); return false; @@ -316,8 +316,8 @@ typename defined_macros_type::iterator it = current_scope->find(name.get_value() !impl::parameters_equal(macrodef->macroparameters, parameters) || !impl::definition_equals(macrodef->macrodefinition, definition)) { - BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, - macro_redefinition, name.get_value().c_str(), main_pos, + BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, + macro_redefinition, name.get_value().c_str(), main_pos, name.get_value().c_str()); } return false; @@ -327,20 +327,20 @@ typename defined_macros_type::iterator it = current_scope->find(name.get_value() if (has_parameters) { std::set names; - typedef typename parameter_container_type::iterator + typedef typename parameter_container_type::iterator parameter_iterator_type; - typedef typename std::set::iterator + typedef typename std::set::iterator name_iterator_type; parameter_iterator_type end = parameters.end(); - for (parameter_iterator_type itp = parameters.begin(); itp != end; ++itp) + for (parameter_iterator_type itp = parameters.begin(); itp != end; ++itp) { name_iterator_type pit = names.find((*itp).get_value()); if (pit != names.end()) { // duplicate parameter name - BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, - duplicate_parameter_name, (*pit).c_str(), main_pos, + BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, + duplicate_parameter_name, (*pit).c_str(), main_pos, name.get_value().c_str()); return false; } @@ -349,19 +349,19 @@ typename defined_macros_type::iterator it = current_scope->find(name.get_value() } // insert a new macro node - std::pair p = + std::pair p = current_scope->insert( typename defined_macros_type::value_type( - name.get_value(), - macro_ref_type(new macro_definition_type(name, + name.get_value(), + macro_ref_type(new macro_definition_type(name, has_parameters, is_predefined, ++macro_uid) ) ) ); if (!p.second) { - BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, - macro_insertion_error, name.get_value().c_str(), main_pos, + BOOST_WAVE_THROW_NAME_CTX(ctx, macro_handling_exception, + macro_insertion_error, name.get_value().c_str(), main_pos, name.get_value().c_str()); return false; } @@ -372,26 +372,26 @@ typename defined_macros_type::iterator it = current_scope->find(name.get_value() // call the context supplied preprocessing hook #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 - ctx.get_hooks().defined_macro(name, has_parameters, - (*p.first).second->macroparameters, + ctx.get_hooks().defined_macro(name, has_parameters, + (*p.first).second->macroparameters, (*p.first).second->macrodefinition, is_predefined); #else - ctx.get_hooks().defined_macro(ctx.derived(), name, has_parameters, - (*p.first).second->macroparameters, + ctx.get_hooks().defined_macro(ctx.derived(), name, has_parameters, + (*p.first).second->macroparameters, (*p.first).second->macrodefinition, is_predefined); #endif return true; } /////////////////////////////////////////////////////////////////////////////// -// +// // is_defined(): returns, whether a given macro is already defined // /////////////////////////////////////////////////////////////////////////////// template -inline bool +inline bool macromap::is_defined(typename token_type::string_type const &name, - typename defined_macros_type::iterator &it, + typename defined_macros_type::iterator &it, defined_macros_type *scope) const { if (0 == scope) scope = current_macros; @@ -403,27 +403,27 @@ macromap::is_defined(typename token_type::string_type const &name, if (name.size() < 8 || '_' != name[0] || '_' != name[1]) return false; // quick check failed - return name == "__LINE__" || name == "__FILE__" || + return name == "__LINE__" || name == "__FILE__" || name == "__INCLUDE_LEVEL__"; } template template -inline bool -macromap::is_defined(IteratorT const &begin, +inline bool +macromap::is_defined(IteratorT const &begin, IteratorT const &end) const { // in normal mode the name under inspection should consist of an identifier // only token_id id = token_id(*begin); - if (T_IDENTIFIER != id && + if (T_IDENTIFIER != id && !IS_CATEGORY(id, KeywordTokenType) && !IS_EXTCATEGORY(id, OperatorTokenType|AltExtTokenType) && - !IS_CATEGORY(id, BoolLiteralTokenType)) + !IS_CATEGORY(id, BoolLiteralTokenType)) { std::string msg(impl::get_full_name(begin, end)); - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, invalid_macroname, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, invalid_macroname, msg.c_str(), main_pos); return false; } @@ -435,7 +435,7 @@ typename defined_macros_type::iterator cit; if (++it != end) { // there should be only one token as the inspected name std::string msg(impl::get_full_name(begin, end)); - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, invalid_macroname, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, invalid_macroname, msg.c_str(), main_pos); return false; } @@ -445,24 +445,24 @@ typename defined_macros_type::iterator cit; /////////////////////////////////////////////////////////////////////////////// // same as above, only takes an arbitrary string type as its parameter template -inline bool +inline bool macromap::is_defined(string_type const &str) const { typename defined_macros_type::iterator cit; - return is_defined(str, cit, 0); + return is_defined(str, cit, 0); } /////////////////////////////////////////////////////////////////////////////// -// +// // Get the macro definition for the given macro scope // /////////////////////////////////////////////////////////////////////////////// template -inline bool -macromap::get_macro(string_type const &name, bool &has_parameters, - bool &is_predefined, position_type &pos, - parameter_container_type ¶meters, - definition_container_type &definition, +inline bool +macromap::get_macro(string_type const &name, bool &has_parameters, + bool &is_predefined, position_type &pos, + parameter_container_type ¶meters, + definition_container_type &definition, defined_macros_type *scope) const { typename defined_macros_type::iterator it; @@ -480,21 +480,21 @@ macro_definition_type ¯o_def = *(*it).second.get(); } /////////////////////////////////////////////////////////////////////////////// -// +// // remove_macro(): remove a macro from the macromap // /////////////////////////////////////////////////////////////////////////////// template -inline bool -macromap::remove_macro(string_type const &name, +inline bool +macromap::remove_macro(string_type const &name, position_type const& pos, bool even_predefined) { typename defined_macros_type::iterator it = current_macros->find(name); - + if (it != current_macros->end()) { if ((*it).second->is_predefined) { if (!even_predefined || impl::is_special_macroname(name)) { - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, bad_undefine_statement, name.c_str(), main_pos); return false; } @@ -512,32 +512,32 @@ macromap::remove_macro(string_type const &name, return true; } else if (impl::is_special_macroname(name)) { - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, bad_undefine_statement, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, bad_undefine_statement, name.c_str(), pos); } return false; // macro was not defined } /////////////////////////////////////////////////////////////////////////////// -// +// // expand_tokensequence // -// This function is a helper function which wraps the given iterator +// This function is a helper function which wraps the given iterator // range into corresponding unput_iterator's and calls the main workhorse // of the macro expansion engine (the function expand_tokensequence_worker) // -// This is the top level macro expansion function called from the +// This is the top level macro expansion function called from the // preprocessing iterator component only. // /////////////////////////////////////////////////////////////////////////////// template template inline typename ContextT::token_type const & -macromap::expand_tokensequence(IteratorT &first, - IteratorT const &last, ContainerT &pending, ContainerT &expanded, +macromap::expand_tokensequence(IteratorT &first, + IteratorT const &last, ContainerT &pending, ContainerT &expanded, bool& seen_newline, bool expand_operator_defined) { - typedef impl::gen_unput_queue_iterator + typedef impl::gen_unput_queue_iterator gen_type; typedef typename gen_type::return_type iterator_type; @@ -546,7 +546,7 @@ macromap::expand_tokensequence(IteratorT &first, on_exit::assign on_exit(first, first_it); - return expand_tokensequence_worker(pending, first_it, last_it, + return expand_tokensequence_worker(pending, first_it, last_it, seen_newline, expand_operator_defined); } @@ -555,8 +555,8 @@ on_exit::assign on_exit(first, first_it); // expand_tokensequence_worker // // This function is the main workhorse of the macro expansion engine. It -// expands as much tokens as needed to identify the next preprocessed -// token to return to the caller. +// expands as much tokens as needed to identify the next preprocessed +// token to return to the caller. // It returns the next preprocessed token. // // The iterator 'first' is adjusted accordingly. @@ -566,9 +566,9 @@ template template inline typename ContextT::token_type const & macromap::expand_tokensequence_worker( - ContainerT &pending, - unput_queue_iterator &first, - unput_queue_iterator const &last, + ContainerT &pending, + unput_queue_iterator &first, + unput_queue_iterator const &last, bool& seen_newline, bool expand_operator_defined) { // if there exist pending tokens (tokens, which are already preprocessed), then @@ -579,7 +579,7 @@ macromap::expand_tokensequence_worker( return act_token = pending.front(); } -// analyze the next element of the given sequence, if it is an +// analyze the next element of the given sequence, if it is an // T_IDENTIFIER token, try to replace this as a macro etc. using namespace boost::wave; typedef unput_queue_iterator iterator_type; @@ -599,23 +599,23 @@ macromap::expand_tokensequence_worker( if (T_IDENTIFIER == id || IS_CATEGORY(id, KeywordTokenType) || IS_EXTCATEGORY(id, OperatorTokenType|AltExtTokenType) || - IS_CATEGORY(id, BoolLiteralTokenType)) + IS_CATEGORY(id, BoolLiteralTokenType)) { // try to replace this identifier as a macro if (expand_operator_defined && (*first).get_value() == "defined") { // resolve operator defined() return resolve_defined(first, last, pending); } - else if (boost::wave::need_variadics(ctx.get_language()) && - (*first).get_value() == "_Pragma") + else if (boost::wave::need_variadics(ctx.get_language()) && + (*first).get_value() == "_Pragma") { // in C99 mode only: resolve the operator _Pragma token_type curr_token = *first; if (!resolve_operator_pragma(first, last, pending, seen_newline) || - pending.size() > 0) + pending.size() > 0) { - // unknown to us pragma or supplied replacement, return the + // unknown to us pragma or supplied replacement, return the // next token on_exit::pop_front pop_token(pending); @@ -623,7 +623,7 @@ macromap::expand_tokensequence_worker( } // the operator _Pragma() was eaten completely, continue - return act_token = token_type(T_PLACEHOLDER, "_", + return act_token = token_type(T_PLACEHOLDER, "_", curr_token.get_position()); } @@ -631,10 +631,10 @@ macromap::expand_tokensequence_worker( typename defined_macros_type::iterator it; if (is_defined(name_token.get_value(), it)) { - // the current token contains an identifier, which is currently + // the current token contains an identifier, which is currently // defined as a macro - if (expand_macro(pending, name_token, it, first, last, - seen_newline, expand_operator_defined)) + if (expand_macro(pending, name_token, it, first, last, + seen_newline, expand_operator_defined)) { // the tokens returned by expand_macro should be rescanned // beginning at the last token of the returned replacement list @@ -652,7 +652,7 @@ macromap::expand_tokensequence_worker( else if (!pending.empty()) { // return the first token from the pending queue on_exit::pop_front pop_queue (pending); - + return act_token = pending.front(); } else { @@ -661,13 +661,13 @@ macromap::expand_tokensequence_worker( } // return the next preprocessed token - return expand_tokensequence_worker(pending, first, last, + return expand_tokensequence_worker(pending, first, last, seen_newline, expand_operator_defined); } // else if (expand_operator_defined) { -// // in preprocessing conditionals undefined identifiers and keywords +// // in preprocessing conditionals undefined identifiers and keywords // // are to be replaced with '0' (see. C++ standard 16.1.4, [cpp.cond]) -// return act_token = +// return act_token = // token_type(T_INTLIT, "0", (*first++).get_position()); // } else { @@ -678,11 +678,11 @@ macromap::expand_tokensequence_worker( } else if (expand_operator_defined && IS_CATEGORY(*first, BoolLiteralTokenType)) { // expanding a constant expression inside #if/#elif, special handling - // of 'true' and 'false' + // of 'true' and 'false' - // all remaining identifiers and keywords, except for true and false, + // all remaining identifiers and keywords, except for true and false, // are replaced with the pp-number 0 (C++ standard 16.1.4, [cpp.cond]) - return act_token = token_type(T_INTLIT, T_TRUE != id ? "0" : "1", + return act_token = token_type(T_INTLIT, T_TRUE != id ? "0" : "1", (*first++).get_position()); } else { @@ -695,7 +695,7 @@ macromap::expand_tokensequence_worker( } /////////////////////////////////////////////////////////////////////////////// -// +// // collect_arguments(): collect the actual arguments of a macro invocation // // return the number of successfully detected non-empty arguments @@ -704,15 +704,15 @@ macromap::expand_tokensequence_worker( #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 template template -inline typename std::vector::size_type -macromap::collect_arguments (token_type const curr_token, - std::vector &arguments, IteratorT &next, +inline typename std::vector::size_type +macromap::collect_arguments (token_type const curr_token, + std::vector &arguments, IteratorT &next, IteratorT const &end, SizeT const ¶meter_count, bool& seen_newline) #else template template -inline typename std::vector::size_type -macromap::collect_arguments (token_type const curr_token, +inline typename std::vector::size_type +macromap::collect_arguments (token_type const curr_token, std::vector &arguments, IteratorT &next, IteratorT &endparen, IteratorT const &end, SizeT const ¶meter_count, bool& seen_newline) #endif @@ -731,13 +731,13 @@ token_type startof_argument_list = *next; while (++next != end && nested_parenthesis_level) { token_id id = token_id(*next); - if (0 == parameter_count && + if (0 == parameter_count && !IS_CATEGORY((*next), WhiteSpaceTokenType) && id != T_NEWLINE && - id != T_RIGHTPAREN && id != T_LEFTPAREN) + id != T_RIGHTPAREN && id != T_LEFTPAREN) { // there shouldn't be any arguments - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, - too_many_macroarguments, curr_token.get_value().c_str(), + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + too_many_macroarguments, curr_token.get_value().c_str(), main_pos); return 0; } @@ -760,13 +760,13 @@ token_type startof_argument_list = *next; endparen = next; #endif if (parameter_count > 0) { - if (argument->empty() || - impl::is_whitespace_only(*argument)) + if (argument->empty() || + impl::is_whitespace_only(*argument)) { #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (boost::wave::need_variadics(ctx.get_language())) { // store a placemarker as the argument - argument->push_back(token_type(T_PLACEMARKER, "\xA7", + argument->push_back(token_type(T_PLACEMARKER, "\xA7", (*next).get_position())); ++count_arguments; } @@ -785,13 +785,13 @@ token_type startof_argument_list = *next; if (1 == nested_parenthesis_level) { // next parameter // trim_sequence(argument); - if (argument->empty() || - impl::is_whitespace_only(*argument)) + if (argument->empty() || + impl::is_whitespace_only(*argument)) { #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (boost::wave::need_variadics(ctx.get_language())) { // store a placemarker as the argument - argument->push_back(token_type(T_PLACEMARKER, "\xA7", + argument->push_back(token_type(T_PLACEMARKER, "\xA7", (*next).get_position())); ++count_arguments; } @@ -816,7 +816,7 @@ token_type startof_argument_list = *next; case T_SPACE: case T_SPACE2: case T_CCOMMENT: - if (!was_whitespace) + if (!was_whitespace) argument->push_back(token_type(T_SPACE, " ", (*next).get_position())); was_whitespace = true; break; // skip whitespace @@ -833,12 +833,12 @@ token_type startof_argument_list = *next; if (nested_parenthesis_level >= 1) { // missing ')': improperly terminated macro invocation - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, improperly_terminated_macro, "missing ')'", main_pos); return 0; } -// if no argument was expected and we didn't find any, than remove the empty +// if no argument was expected and we didn't find any, than remove the empty // element if (0 == parameter_count && 0 == count_arguments) { BOOST_ASSERT(1 == arguments.size()); @@ -848,20 +848,20 @@ token_type startof_argument_list = *next; } /////////////////////////////////////////////////////////////////////////////// -// +// // expand_whole_tokensequence // -// fully expands a given token sequence +// fully expands a given token sequence // /////////////////////////////////////////////////////////////////////////////// template template inline void -macromap::expand_whole_tokensequence(ContainerT &expanded, - IteratorT &first, IteratorT const &last, +macromap::expand_whole_tokensequence(ContainerT &expanded, + IteratorT &first, IteratorT const &last, bool expand_operator_defined) { - typedef impl::gen_unput_queue_iterator + typedef impl::gen_unput_queue_iterator gen_type; typedef typename gen_type::return_type iterator_type; @@ -875,7 +875,7 @@ macromap::expand_whole_tokensequence(ContainerT &expanded, while (!pending_queue.empty() || first_it != last_it) { expanded.push_back( - expand_tokensequence_worker(pending_queue, first_it, + expand_tokensequence_worker(pending_queue, first_it, last_it, seen_newline, expand_operator_defined) ); } @@ -885,23 +885,23 @@ macromap::expand_whole_tokensequence(ContainerT &expanded, } /////////////////////////////////////////////////////////////////////////////// -// +// // expand_argument // -// fully expands the given argument of a macro call +// fully expands the given argument of a macro call // /////////////////////////////////////////////////////////////////////////////// template template -inline void +inline void macromap::expand_argument ( - typename std::vector::size_type arg, - std::vector &arguments, std::vector &expanded_args, + typename std::vector::size_type arg, + std::vector &arguments, std::vector &expanded_args, bool expand_operator_defined, std::vector &has_expanded_args) { if (!has_expanded_args[arg]) { // expand the argument only once - typedef typename std::vector::value_type::iterator + typedef typename std::vector::value_type::iterator argument_iterator_type; argument_iterator_type begin_it = arguments[arg].begin(); @@ -915,10 +915,10 @@ macromap::expand_argument ( } /////////////////////////////////////////////////////////////////////////////// -// +// // expand_replacement_list // -// fully expands the replacement list of a given macro with the +// fully expands the replacement list of a given macro with the // actual arguments/expanded arguments // handles the '#' [cpp.stringize] and the '##' [cpp.concat] operator // @@ -928,11 +928,11 @@ template inline void macromap::expand_replacement_list( macro_definition_type const ¯odef, - std::vector &arguments, bool expand_operator_defined, + std::vector &arguments, bool expand_operator_defined, ContainerT &expanded) { using namespace boost::wave; - typedef typename macro_definition_type::const_definition_iterator_t + typedef typename macro_definition_type::const_definition_iterator_t macro_definition_iter_t; std::vector expanded_args(arguments.size()); @@ -947,7 +947,7 @@ bool adjacent_stringize = false; { bool use_replaced_arg = true; token_id base_id = BASE_TOKEN(token_id(*cit)); - + if (T_POUND_POUND == base_id) { // concatenation operator adjacent_concat = true; @@ -958,7 +958,7 @@ bool adjacent_stringize = false; adjacent_stringize = true; } else { - if (adjacent_stringize || adjacent_concat || + if (adjacent_stringize || adjacent_concat || T_POUND_POUND == impl::next_token ::peek(cit, cend)) { @@ -978,8 +978,8 @@ bool adjacent_stringize = false; BOOST_ASSERT(boost::wave::need_variadics(ctx.get_language())); i = token_id(*cit) - T_EXTPARAMETERBASE; is_ellipsis = true; - } - else + } + else #endif { i = token_id(*cit) - T_PARAMETERBASE; @@ -995,30 +995,30 @@ bool adjacent_stringize = false; BOOST_ASSERT(boost::wave::need_variadics(ctx.get_language())); // ensure all variadic arguments to be expanded - for (typename vector::size_type arg = i; + for (typename vector::size_type arg = i; arg < expanded_args.size(); ++arg) { - expand_argument(arg, arguments, expanded_args, + expand_argument(arg, arguments, expanded_args, expand_operator_defined, has_expanded_args); } impl::replace_ellipsis(expanded_args, i, expanded, pos); } - else + else #endif { // ensure argument i to be expanded - expand_argument(i, arguments, expanded_args, + expand_argument(i, arguments, expanded_args, expand_operator_defined, has_expanded_args); // replace argument ContainerT const &arg = expanded_args[i]; - - std::copy(arg.begin(), arg.end(), + + std::copy(arg.begin(), arg.end(), std::inserter(expanded, expanded.end())); } } - else if (adjacent_stringize && - !IS_CATEGORY(*cit, WhiteSpaceTokenType)) + else if (adjacent_stringize && + !IS_CATEGORY(*cit, WhiteSpaceTokenType)) { // stringize the current argument BOOST_ASSERT(!arguments[i].empty()); @@ -1030,14 +1030,14 @@ bool adjacent_stringize = false; if (is_ellipsis && boost::wave::need_variadics(ctx.get_language())) { impl::trim_sequence_left(arguments[i]); impl::trim_sequence_right(arguments.back()); - expanded.push_back(token_type(T_STRINGLIT, + expanded.push_back(token_type(T_STRINGLIT, impl::as_stringlit(arguments, i, pos), pos)); } - else -#endif + else +#endif { impl::trim_sequence(arguments[i]); - expanded.push_back(token_type(T_STRINGLIT, + expanded.push_back(token_type(T_STRINGLIT, impl::as_stringlit(arguments[i], pos), pos)); } adjacent_stringize = false; @@ -1057,9 +1057,9 @@ bool adjacent_stringize = false; #endif { ContainerT &arg = arguments[i]; - + impl::trim_sequence(arg); - std::copy(arg.begin(), arg.end(), + std::copy(arg.begin(), arg.end(), std::inserter(expanded, expanded.end())); } } @@ -1086,15 +1086,15 @@ bool adjacent_stringize = false; // // rescan_replacement_list // -// As the name implies, this function is used to rescan the replacement list +// As the name implies, this function is used to rescan the replacement list // after the first macro substitution phase. // /////////////////////////////////////////////////////////////////////////////// template template -inline void -macromap::rescan_replacement_list(token_type const &curr_token, - macro_definition_type ¯o_def, ContainerT &replacement_list, +inline void +macromap::rescan_replacement_list(token_type const &curr_token, + macro_definition_type ¯o_def, ContainerT &replacement_list, ContainerT &expanded, bool expand_operator_defined, IteratorT &nfirst, IteratorT const &nlast) { @@ -1126,8 +1126,8 @@ macromap::rescan_replacement_list(token_type const &curr_token, typename ContainerT::iterator begin_it = replacement_list.begin(); typename ContainerT::iterator end_it = replacement_list.end(); - expand_whole_tokensequence(expanded, begin_it, end_it, - expand_operator_defined); + expand_whole_tokensequence(expanded, begin_it, end_it, + expand_operator_defined); // trim replacement list, leave placeholder tokens untouched impl::trim_replacement_list(expanded); @@ -1141,7 +1141,7 @@ macromap::rescan_replacement_list(token_type const &curr_token, } /////////////////////////////////////////////////////////////////////////////// -// +// // expand_macro(): expands a defined macro // // This functions tries to expand the macro, to which points the 'first' @@ -1151,12 +1151,12 @@ macromap::rescan_replacement_list(token_type const &curr_token, /////////////////////////////////////////////////////////////////////////////// template template -inline bool -macromap::expand_macro(ContainerT &expanded, - token_type const &curr_token, typename defined_macros_type::iterator it, - IteratorT &first, IteratorT const &last, - bool& seen_newline, bool expand_operator_defined, - defined_macros_type *scope, ContainerT *queue_symbol) +inline bool +macromap::expand_macro(ContainerT &expanded, + token_type const &curr_token, typename defined_macros_type::iterator it, + IteratorT &first, IteratorT const &last, + bool& seen_newline, bool expand_operator_defined, + defined_macros_type *scope, ContainerT *queue_symbol) { using namespace boost::wave; @@ -1166,7 +1166,7 @@ macromap::expand_macro(ContainerT &expanded, IS_CATEGORY(token_id(curr_token), KeywordTokenType) || IS_EXTCATEGORY(token_id(curr_token), OperatorTokenType|AltExtTokenType) || IS_CATEGORY(token_id(curr_token), BoolLiteralTokenType)); - + if (it == scope->end()) { ++first; // advance @@ -1210,7 +1210,7 @@ macro_definition_type ¯o_def = *(*it).second.get(); ContainerT replacement_list; if (T_LEFTPAREN == impl::next_token::peek(first, last)) { - // called as a function-like macro + // called as a function-like macro impl::skip_to_token(ctx, first, last, T_LEFTPAREN, seen_newline); #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS == 0 @@ -1224,44 +1224,44 @@ ContainerT replacement_list; // collect the arguments std::vector arguments; #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 - typename std::vector::size_type count_args = - collect_arguments (curr_token, arguments, first, last, + typename std::vector::size_type count_args = + collect_arguments (curr_token, arguments, first, last, macro_def.macroparameters.size(), seen_newline); #else - typename std::vector::size_type count_args = - collect_arguments (curr_token, arguments, first, seqend, last, + typename std::vector::size_type count_args = + collect_arguments (curr_token, arguments, first, seqend, last, macro_def.macroparameters.size(), seen_newline); #endif // verify the parameter count if (count_args < macro_def.macroparameters.size() || - arguments.size() < macro_def.macroparameters.size()) + arguments.size() < macro_def.macroparameters.size()) { if (count_args != arguments.size()) { // must been at least one empty argument in C++ mode - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, - empty_macroarguments, curr_token.get_value().c_str(), + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + empty_macroarguments, curr_token.get_value().c_str(), main_pos); } else { // too few macro arguments - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, - too_few_macroarguments, curr_token.get_value().c_str(), + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + too_few_macroarguments, curr_token.get_value().c_str(), main_pos); } return false; } if (count_args > macro_def.macroparameters.size() || - arguments.size() > macro_def.macroparameters.size()) + arguments.size() > macro_def.macroparameters.size()) { #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 - if (!macro_def.has_ellipsis) -#endif + if (!macro_def.has_ellipsis) +#endif { // too many macro arguments - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, - too_many_macroarguments, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + too_many_macroarguments, curr_token.get_value().c_str(), main_pos); return false; } @@ -1270,18 +1270,22 @@ ContainerT replacement_list; // inject tracing support #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 ctx.get_hooks().expanding_function_like_macro( - macro_def.macroname, macro_def.macroparameters, + macro_def.macroname, macro_def.macroparameters, macro_def.macrodefinition, curr_token, arguments); #else - if (ctx.get_hooks().expanding_function_like_macro(ctx.derived(), - macro_def.macroname, macro_def.macroparameters, + if (ctx.get_hooks().expanding_function_like_macro(ctx.derived(), + macro_def.macroname, macro_def.macroparameters, macro_def.macrodefinition, curr_token, arguments, seqstart, seqend)) { - // do not expand this macro, just copy the whole sequence +// // do not expand this macro, just copy the whole sequence +// expanded.push_back(curr_token); +// std::copy(seqstart, first, +// std::inserter(expanded, expanded.end())); + // do not expand macro, just copy macro name and parenthesis expanded.push_back(curr_token); - std::copy(seqstart, first, - std::inserter(expanded, expanded.end())); + expanded.push_back(*seqstart); + first = ++seqstart; return false; // no further preprocessing required } #endif @@ -1296,10 +1300,10 @@ ContainerT replacement_list; ctx.get_hooks().expanding_object_like_macro( macro_def.macroname, macro_def.macrodefinition, curr_token); #else - if (ctx.get_hooks().expanding_object_like_macro(ctx.derived(), + if (ctx.get_hooks().expanding_object_like_macro(ctx.derived(), macro_def.macroname, macro_def.macrodefinition, curr_token)) { - // do not expand this macro, just copy the whole sequence + // do not expand this macro, just copy the whole sequence expanded.push_back(curr_token); return false; // no further preprocessing required } @@ -1308,8 +1312,8 @@ ContainerT replacement_list; bool found = false; impl::find_concat_operator concat_tag(found); - std::remove_copy_if(macro_def.macrodefinition.begin(), - macro_def.macrodefinition.end(), + std::remove_copy_if(macro_def.macrodefinition.begin(), + macro_def.macrodefinition.end(), std::inserter(replacement_list, replacement_list.end()), concat_tag); @@ -1338,10 +1342,10 @@ ContainerT replacement_list; ctx.get_hooks().expanding_object_like_macro( macro_def.macroname, macro_def.macrodefinition, curr_token); #else - if (ctx.get_hooks().expanding_object_like_macro(ctx.derived(), + if (ctx.get_hooks().expanding_object_like_macro(ctx.derived(), macro_def.macroname, macro_def.macrodefinition, curr_token)) { - // do not expand this macro, just copy the whole sequence + // do not expand this macro, just copy the whole sequence expanded.push_back(curr_token); ++first; // skip macro name return false; // no further preprocessing required @@ -1351,15 +1355,15 @@ ContainerT replacement_list; bool found = false; impl::find_concat_operator concat_tag(found); - std::remove_copy_if(macro_def.macrodefinition.begin(), - macro_def.macrodefinition.end(), + std::remove_copy_if(macro_def.macrodefinition.begin(), + macro_def.macrodefinition.end(), std::inserter(replacement_list, replacement_list.end()), concat_tag); // handle concatenation operators if (found && !concat_tokensequence(replacement_list)) return false; - + ++first; // skip macro name } } @@ -1373,13 +1377,13 @@ ContainerT expanded_list; ctx.get_hooks().expanded_macro(ctx.derived(), replacement_list); #endif - rescan_replacement_list(curr_token, macro_def, replacement_list, + rescan_replacement_list(curr_token, macro_def, replacement_list, expanded_list, expand_operator_defined, first, last); #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 - ctx.get_hooks().rescanned_macro(expanded_list); + ctx.get_hooks().rescanned_macro(expanded_list); #else - ctx.get_hooks().rescanned_macro(ctx.derived(), expanded_list); + ctx.get_hooks().rescanned_macro(ctx.derived(), expanded_list); #endif expanded.splice(expanded.end(), expanded_list); return true; // rescan is required @@ -1387,25 +1391,25 @@ ContainerT expanded_list; /////////////////////////////////////////////////////////////////////////////// // -// If the token under inspection points to a certain predefined macro it will +// If the token under inspection points to a certain predefined macro it will // be expanded, otherwise false is returned. // (only __FILE__, __LINE__ and __INCLUDE_LEVEL__ macros are expanded here) // /////////////////////////////////////////////////////////////////////////////// template template -inline bool -macromap::expand_predefined_macro(token_type const &curr_token, +inline bool +macromap::expand_predefined_macro(token_type const &curr_token, ContainerT &expanded) { using namespace boost::wave; - + string_type const &value = curr_token.get_value(); if (value.size() < 8 || '_' != value[0] || '_' != value[1]) return false; // quick check failed - - if (value == "__LINE__") { + + if (value == "__LINE__") { // expand the __LINE__ macro char buffer[22]; // 21 bytes holds all NUL-terminated unsigned 64-bit numbers @@ -1417,13 +1421,13 @@ string_type const &value = curr_token.get_value(); else if (value == "__FILE__") { // expand the __FILE__ macro namespace fs = boost::filesystem; - + std::string file("\""); fs::path filename(wave::util::create_path(main_pos.get_file().c_str())); - + using boost::wave::util::impl::escape_lit; file += escape_lit(wave::util::native_file_string(filename)) + "\""; - expanded.push_back(token_type(T_STRINGLIT, file.c_str(), + expanded.push_back(token_type(T_STRINGLIT, file.c_str(), curr_token.get_position())); return true; } @@ -1441,29 +1445,29 @@ string_type const &value = curr_token.get_value(); /////////////////////////////////////////////////////////////////////////////// // -// resolve_defined(): resolve the operator defined() and replace it with the +// resolve_defined(): resolve the operator defined() and replace it with the // correct T_INTLIT token // /////////////////////////////////////////////////////////////////////////////// template template inline typename ContextT::token_type const & -macromap::resolve_defined(IteratorT &first, - IteratorT const &last, ContainerT &pending) +macromap::resolve_defined(IteratorT &first, + IteratorT const &last, ContainerT &pending) { using namespace boost::wave; using namespace boost::wave::grammars; ContainerT result; IteratorT start = first; -boost::spirit::classic::parse_info hit = +boost::spirit::classic::parse_info hit = defined_grammar_gen:: parse_operator_defined(start, last, result); - + if (!hit.hit) { string_type msg ("defined(): "); msg = msg + util::impl::as_string(first, last); - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, ill_formed_expression, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, ill_formed_expression, msg.c_str(), main_pos); // insert a dummy token @@ -1473,11 +1477,11 @@ boost::spirit::classic::parse_info hit = impl::assign_iterator::do_(first, hit.stop); // insert a token, which reflects the outcome - pending.push_back(token_type(T_INTLIT, - is_defined(result.begin(), result.end()) ? "1" : "0", + pending.push_back(token_type(T_INTLIT, + is_defined(result.begin(), result.end()) ? "1" : "0", main_pos)); } - + on_exit::pop_front pop_front_token(pending); return act_token = pending.front(); @@ -1488,52 +1492,52 @@ on_exit::pop_front pop_front_token(pending); // resolve_operator_pragma(): resolve the operator _Pragma() and dispatch to // the associated action // -// This function returns true, if the pragma was correctly interpreted. +// This function returns true, if the pragma was correctly interpreted. // The iterator 'first' is positioned behind the closing ')'. -// This function returns false, if the _Pragma was not known, the +// This function returns false, if the _Pragma was not known, the // preprocessed token sequence is pushed back to the 'pending' sequence. // /////////////////////////////////////////////////////////////////////////////// template template inline bool -macromap::resolve_operator_pragma(IteratorT &first, - IteratorT const &last, ContainerT &pending, bool& seen_newline) +macromap::resolve_operator_pragma(IteratorT &first, + IteratorT const &last, ContainerT &pending, bool& seen_newline) { // isolate the parameter of the operator _Pragma token_type pragma_token = *first; - + if (!impl::skip_to_token(ctx, first, last, T_LEFTPAREN, seen_newline)) { // illformed operator _Pragma - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, ill_formed_expression, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, ill_formed_expression, "operator _Pragma()", pragma_token.get_position()); return false; } - + std::vector arguments; #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 - typename std::vector::size_type count_args = + typename std::vector::size_type count_args = collect_arguments (pragma_token, arguments, first, last, 1, seen_newline); #else IteratorT endparen = first; - typename std::vector::size_type count_args = - collect_arguments (pragma_token, arguments, first, endparen, last, 1, + typename std::vector::size_type count_args = + collect_arguments (pragma_token, arguments, first, endparen, last, 1, seen_newline); #endif // verify the parameter count if (pragma_token.get_position().get_file().empty()) pragma_token.set_position(act_token.get_position()); - + if (count_args < 1 || arguments.size() < 1) { // too few macro arguments - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, too_few_macroarguments, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, too_few_macroarguments, pragma_token.get_value().c_str(), pragma_token.get_position()); return false; } if (count_args > 1 || arguments.size() > 1) { // too many macro arguments - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, too_many_macroarguments, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, too_many_macroarguments, pragma_token.get_value().c_str(), pragma_token.get_position()); return false; } @@ -1541,7 +1545,7 @@ macromap::resolve_operator_pragma(IteratorT &first, // preprocess the pragma token body typedef typename std::vector::value_type::iterator argument_iterator_type; - + ContainerT expanded; argument_iterator_type begin_it = arguments[0].begin(); argument_iterator_type end_it = arguments[0].end(); @@ -1549,7 +1553,7 @@ macromap::resolve_operator_pragma(IteratorT &first, // un-escape the parameter of the operator _Pragma typedef typename token_type::string_type string_type; - + string_type pragma_cmd; typename ContainerT::const_iterator end_exp = expanded.end(); for (typename ContainerT::const_iterator it_exp = expanded.begin(); @@ -1559,24 +1563,24 @@ macromap::resolve_operator_pragma(IteratorT &first, break; if (IS_CATEGORY(*it_exp, WhiteSpaceTokenType)) continue; - + if (T_STRINGLIT != token_id(*it_exp)) { // ill formed operator _Pragma - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, - ill_formed_pragma_option, "_Pragma", + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + ill_formed_pragma_option, "_Pragma", pragma_token.get_position()); return false; } if (pragma_cmd.size() > 0) { - // there should be exactly one string literal (string literals are to - // be concatenated at translation phase 6, but _Pragma operators are + // there should be exactly one string literal (string literals are to + // be concatenated at translation phase 6, but _Pragma operators are // to be executed at translation phase 4) - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, - ill_formed_pragma_option, "_Pragma", + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + ill_formed_pragma_option, "_Pragma", pragma_token.get_position()); return false; } - + // remove the '\"' and concat all given string literal-values string_type token_str = (*it_exp).get_value(); pragma_cmd += token_str.substr(1, token_str.size() - 2); @@ -1585,23 +1589,23 @@ macromap::resolve_operator_pragma(IteratorT &first, // tokenize the pragma body typedef typename ContextT::lexer_type lexer_type; - + ContainerT pragma; std::string pragma_cmd_str(pragma_cmd_unesc.c_str()); - lexer_type it = lexer_type(pragma_cmd_str.begin(), pragma_cmd_str.end(), + lexer_type it = lexer_type(pragma_cmd_str.begin(), pragma_cmd_str.end(), pragma_token.get_position(), ctx.get_language()); lexer_type end = lexer_type(); - for (/**/; it != end; ++it) + for (/**/; it != end; ++it) pragma.push_back(*it); -// analyze the preprocessed token sequence and eventually dispatch to the +// analyze the preprocessed token sequence and eventually dispatch to the // associated action - if (interpret_pragma(ctx, pragma_token, pragma.begin(), pragma.end(), + if (interpret_pragma(ctx, pragma_token, pragma.begin(), pragma.end(), pending)) { return true; // successfully recognized a wave specific pragma } - + // unknown pragma token sequence, push it back and return to the caller pending.push_front(token_type(T_SPACE, " ", pragma_token.get_position())); pending.push_front(token_type(T_RIGHTPAREN, ")", pragma_token.get_position())); @@ -1614,16 +1618,16 @@ macromap::resolve_operator_pragma(IteratorT &first, /////////////////////////////////////////////////////////////////////////////// // -// Test, whether the result of a concat operator is well formed or not. +// Test, whether the result of a concat operator is well formed or not. // -// This is done by re-scanning (re-tokenizing) the resulting token sequence, +// This is done by re-scanning (re-tokenizing) the resulting token sequence, // which should give back exactly one token. // /////////////////////////////////////////////////////////////////////////////// template template inline bool -macromap::is_valid_concat(string_type new_value, +macromap::is_valid_concat(string_type new_value, position_type const &pos, ContainerT &rescanned) { // re-tokenize the newly generated string @@ -1631,14 +1635,14 @@ macromap::is_valid_concat(string_type new_value, std::string value_to_test(new_value.c_str()); - boost::wave::language_support lang = + boost::wave::language_support lang = boost::wave::enable_prefer_pp_numbers(ctx.get_language()); lang = boost::wave::enable_single_line(lang); - lexer_type it = lexer_type(value_to_test.begin(), value_to_test.end(), pos, + lexer_type it = lexer_type(value_to_test.begin(), value_to_test.end(), pos, lang); lexer_type end = lexer_type(); - for (/**/; it != end && T_EOF != token_id(*it); ++it) + for (/**/; it != end && T_EOF != token_id(*it); ++it) { // as of Wave V2.0.7 pasting of tokens is valid only if the resulting // tokens are pp_tokens (as mandated by C++11) @@ -1650,7 +1654,7 @@ macromap::is_valid_concat(string_type new_value, #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (boost::wave::need_variadics(ctx.get_language())) return true; // in variadics mode token pasting is well defined -#endif +#endif // test if the newly generated token sequence contains more than 1 token return 1 == rescanned.size(); @@ -1663,8 +1667,8 @@ macromap::is_valid_concat(string_type new_value, // /////////////////////////////////////////////////////////////////////////////// template -inline void report_invalid_concatenation(Context& ctx, - typename Context::token_type const& prev, +inline void report_invalid_concatenation(Context& ctx, + typename Context::token_type const& prev, typename Context::token_type const& next, typename Context::position_type const& main_pos) { @@ -1680,7 +1684,7 @@ typename Context::string_type error_string("\""); template template -inline bool +inline bool macromap::concat_tokensequence(ContainerT &expanded) { using namespace boost::wave; @@ -1688,7 +1692,7 @@ macromap::concat_tokensequence(ContainerT &expanded) iterator_type end = expanded.end(); iterator_type prev = end; - for (iterator_type it = expanded.begin(); it != end; /**/) + for (iterator_type it = expanded.begin(); it != end; /**/) { if (T_POUND_POUND == BASE_TOKEN(token_id(*it))) { iterator_type next = it; @@ -1696,7 +1700,7 @@ macromap::concat_tokensequence(ContainerT &expanded) ++next; if (prev == end || next == end) { // error, '##' should be in between two tokens - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, ill_formed_operator, "concat ('##')", main_pos); return false; } @@ -1707,12 +1711,12 @@ macromap::concat_tokensequence(ContainerT &expanded) ++next; if (next == end) { // error, '##' should be in between two tokens - BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, + BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, ill_formed_operator, "concat ('##')", main_pos); return false; } } - + #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (boost::wave::need_variadics(ctx.get_language())) { if (T_PLACEMARKER == token_id(*next)) { @@ -1728,14 +1732,14 @@ macromap::concat_tokensequence(ContainerT &expanded) iterator_type first_to_delete = prev; *prev = *next; - expanded.erase(++first_to_delete, ++next); + expanded.erase(++first_to_delete, ++next); it = next; continue; } } #endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 - // test if the concat operator has to concatenate two unrelated + // test if the concat operator has to concatenate two unrelated // tokens i.e. the result yields more then one token string_type concat_result; ContainerT rescanned; @@ -1743,10 +1747,10 @@ macromap::concat_tokensequence(ContainerT &expanded) concat_result = ((*prev).get_value() + (*next).get_value()); // analyze the validity of the concatenation result - if (!is_valid_concat(concat_result, (*prev).get_position(), + if (!is_valid_concat(concat_result, (*prev).get_position(), rescanned) && - !IS_CATEGORY(*prev, WhiteSpaceTokenType) && - !IS_CATEGORY(*next, WhiteSpaceTokenType)) + !IS_CATEGORY(*prev, WhiteSpaceTokenType) && + !IS_CATEGORY(*next, WhiteSpaceTokenType)) { report_invalid_concatenation(ctx, *prev, *next, main_pos); return false; @@ -1755,12 +1759,12 @@ macromap::concat_tokensequence(ContainerT &expanded) #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (boost::wave::need_variadics(ctx.get_language())) { // remove the prev, '##' and the next tokens from the sequence - expanded.erase(prev, ++next); // remove not needed tokens + expanded.erase(prev, ++next); // remove not needed tokens // some stl implementations clear() the container if we erased all - // the elements, which orphans all iterators. we re-initialize these + // the elements, which orphans all iterators. we re-initialize these // here - if (expanded.empty()) + if (expanded.empty()) end = next = expanded.end(); // replace the old token (pointed to by *prev) with the re-tokenized @@ -1775,7 +1779,7 @@ macromap::concat_tokensequence(ContainerT &expanded) else #endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 { - // we leave the token_id unchanged, but unmark the token as + // we leave the token_id unchanged, but unmark the token as // disabled, if appropriate (*prev).set_value(concat_result); if (T_NONREPLACABLE_IDENTIFIER == token_id(*prev)) @@ -1784,7 +1788,7 @@ macromap::concat_tokensequence(ContainerT &expanded) // remove the '##' and the next tokens from the sequence iterator_type first_to_delete = prev; - expanded.erase(++first_to_delete, ++next); + expanded.erase(++first_to_delete, ++next); } it = next; continue; @@ -1806,14 +1810,14 @@ macromap::concat_tokensequence(ContainerT &expanded) /////////////////////////////////////////////////////////////////////////////// template inline void -macromap::predefine_macro(defined_macros_type *scope, +macromap::predefine_macro(defined_macros_type *scope, string_type const &name, token_type const &t) { definition_container_type macrodefinition; std::vector param; macrodefinition.push_back(t); - add_macro(token_type(T_IDENTIFIER, name, t.get_position()), + add_macro(token_type(T_IDENTIFIER, name, t.get_position()), false, param, macrodefinition, true, scope); } @@ -1823,8 +1827,8 @@ std::vector param; // /////////////////////////////////////////////////////////////////////////////// template -inline void -macromap::init_predefined_macros(char const *fname, +inline void +macromap::init_predefined_macros(char const *fname, defined_macros_type *scope, bool at_global_scope) { // if no scope is given, use the current one @@ -1842,25 +1846,25 @@ position_type pos(""); token_type(m.token_id, m.value, pos)); } } - else -#endif + else +#endif { #if BOOST_WAVE_SUPPORT_CPP0X != 0 if (boost::wave::need_cpp0x(ctx.get_language())) { // define C++11 specifics for (int i = 0; 0 != predef.static_data_cpp0x(i).name; ++i) { predefined_macros::static_macros const& m = predef.static_data_cpp0x(i); - predefine_macro(current_scope, m.name, + predefine_macro(current_scope, m.name, token_type(m.token_id, m.value, pos)); } } - else -#endif + else +#endif { // define C++ specifics for (int i = 0; 0 != predef.static_data_cpp(i).name; ++i) { predefined_macros::static_macros const& m = predef.static_data_cpp(i); - predefine_macro(current_scope, m.name, + predefine_macro(current_scope, m.name, token_type(m.token_id, m.value, pos)); } @@ -1870,18 +1874,18 @@ position_type pos(""); predefine_macro(current_scope, "__WAVE_HAS_VARIADICS__", token_type(T_INTLIT, "1", pos)); } -#endif +#endif } } -// predefine the __BASE_FILE__ macro which contains the main file name - namespace fs = boost::filesystem; +// predefine the __BASE_FILE__ macro which contains the main file name + namespace fs = boost::filesystem; if (string_type(fname) != "") { fs::path filename(create_path(fname)); using boost::wave::util::impl::escape_lit; predefine_macro(current_scope, "__BASE_FILE__", - token_type(T_STRINGLIT, string_type("\"") + + token_type(T_STRINGLIT, string_type("\"") + escape_lit(native_file_string(filename)).c_str() + "\"", pos)); base_name = fname; } @@ -1890,7 +1894,7 @@ position_type pos(""); using boost::wave::util::impl::escape_lit; predefine_macro(current_scope, "__BASE_FILE__", - token_type(T_STRINGLIT, string_type("\"") + + token_type(T_STRINGLIT, string_type("\"") + escape_lit(native_file_string(filename)).c_str() + "\"", pos)); } @@ -1908,7 +1912,7 @@ position_type pos(""); // /////////////////////////////////////////////////////////////////////////////// template -inline void +inline void macromap::reset_macromap() { current_macros->clear(); diff --git a/include/boost/wave/util/filesystem_compatibility.hpp b/include/boost/wave/util/filesystem_compatibility.hpp index 4ed90b5..157c641 100644 --- a/include/boost/wave/util/filesystem_compatibility.hpp +++ b/include/boost/wave/util/filesystem_compatibility.hpp @@ -182,6 +182,14 @@ namespace boost { namespace wave { namespace util #endif } #endif + + // starting withBoost V1.50 create_directories throws if given an empty path + inline bool create_directories(boost::filesystem::path const& p) + { + if (p.string().empty()) + return true; + return boost::filesystem::create_directories(p); + } }}} #endif diff --git a/test/testwave/testfiles/t_9_023.cpp b/test/testwave/testfiles/t_9_023.cpp new file mode 100644 index 0000000..de6c456 --- /dev/null +++ b/test/testwave/testfiles/t_9_023.cpp @@ -0,0 +1,31 @@ +/*============================================================================= + Boost.Wave: A Standard compliant C++ preprocessor library + http://www.boost.org/ + + Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost + Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +// Verifies that preprocessing directives are properly recognized only if +// the '#' is really the first character on a line before macro expansion. +// See http://www.open-std.org/jtc1/sc22/wg14/docs/rr/dr_144.html. + +#define _C_STD_BEGIN + +_C_STD_BEGIN +#ifndef _M_CEE_PURE +_C_LIB_DECL +#endif + +//R #line 18 "t_9_023.cpp" +//R _C_LIB_DECL + +//H 10: t_9_023.cpp(14): #define +//H 08: t_9_023.cpp(14): _C_STD_BEGIN= +//H 01: t_9_023.cpp(14): _C_STD_BEGIN +//H 02: +//H 03: _ +//H 10: t_9_023.cpp(17): #ifndef +//H 11: t_9_023.cpp(17): #ifndef _M_CEE_PURE: 0 +//H 10: t_9_023.cpp(19): #endif diff --git a/test/testwave/testfiles/test.cfg b/test/testwave/testfiles/test.cfg index 77129fb..0f76468 100644 --- a/test/testwave/testfiles/test.cfg +++ b/test/testwave/testfiles/test.cfg @@ -238,3 +238,4 @@ t_9_019.cpp t_9_020.cpp t_9_021.cpp t_9_022.cpp +t_9_023.cpp diff --git a/tool/cpp.cpp b/tool/cpp.cpp index 023d8fd..32bdd62 100644 --- a/tool/cpp.cpp +++ b/tool/cpp.cpp @@ -81,7 +81,6 @@ using namespace boost::spirit::classic; using std::pair; using std::vector; using std::getline; -using std::ifstream; using std::ofstream; using std::cout; using std::cerr; @@ -226,7 +225,7 @@ namespace cmd_line_utils { po::options_description const &desc, po::variables_map &vm, bool may_fail = false) { - ifstream ifs(filename.c_str()); + std::ifstream ifs(filename.c_str()); if (!ifs.is_open()) { if (!may_fail) { @@ -463,7 +462,7 @@ namespace { #if BOOST_WAVE_BINARY_SERIALIZATION != 0 mode = (std::ios::openmode)(mode | std::ios::binary); #endif - ifstream ifs (state_file.string().c_str(), mode); + std::ifstream ifs (state_file.string().c_str(), mode); if (ifs.is_open()) { using namespace boost::serialization; iarchive ia(ifs); @@ -540,7 +539,8 @@ namespace { if (macronames_file != "-") { macronames_file = boost::wave::util::complete_path(macronames_file); - fs::create_directories(boost::wave::util::branch_path(macronames_file)); + boost::wave::util::create_directories( + boost::wave::util::branch_path(macronames_file)); macronames_out.open(macronames_file.string().c_str()); if (!macronames_out.is_open()) { cerr << "wave: could not open file for macro name listing: " @@ -609,7 +609,8 @@ namespace { if (macrocounts_file != "-") { macrocounts_file = boost::wave::util::complete_path(macrocounts_file); - fs::create_directories(boost::wave::util::branch_path(macrocounts_file)); + boost::wave::util::create_directories( + boost::wave::util::branch_path(macrocounts_file)); macrocounts_out.open(macrocounts_file.string().c_str()); if (!macrocounts_out.is_open()) { cerr << "wave: could not open file for macro invocation count listing: " @@ -635,7 +636,25 @@ namespace { return true; } -/////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // read all of a file into a string + std::string read_entire_file(std::istream& instream) + { + std::string content; + + instream.unsetf(std::ios::skipws); + +#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + // this is known to be very slow for large files on some systems + copy (std::istream_iterator(instream), + std::istream_iterator(), + std::inserter(content, content.end())); +#else + content = std::string(std::istreambuf_iterator(instream.rdbuf()), + std::istreambuf_iterator()); +#endif + return content; + } } // anonymous namespace /////////////////////////////////////////////////////////////////////////////// @@ -654,18 +673,8 @@ int error_count = 0; std::string instring; instream.unsetf(std::ios::skipws); - - if (!input_is_stdin) { -#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) - // this is known to be very slow for large files on some systems - copy (std::istream_iterator(instream), - std::istream_iterator(), - std::inserter(instring, instring.end())); -#else - instring = std::string(std::istreambuf_iterator(instream.rdbuf()), - std::istreambuf_iterator()); -#endif - } + if (!input_is_stdin) + instring = read_entire_file(instream); // The preprocessing of the input stream is done on the fly behind the // scenes during iteration over the context_type::iterator_type stream. @@ -682,7 +691,8 @@ int error_count = 0; vm["traceto"].as())); if (trace_file != "-") { - fs::create_directories(boost::wave::util::branch_path(trace_file)); + boost::wave::util::create_directories( + boost::wave::util::branch_path(trace_file)); traceout.open(trace_file.string().c_str()); if (!traceout.is_open()) { cerr << "wave: could not open trace file: " << trace_file @@ -706,7 +716,8 @@ int error_count = 0; vm["listincludes"].as())); if (includes_file != "-") { - fs::create_directories(boost::wave::util::branch_path(includes_file)); + boost::wave::util::create_directories( + boost::wave::util::branch_path(includes_file)); includelistout.open(includes_file.string().c_str()); if (!includelistout.is_open()) { cerr << "wave: could not open include list file: " @@ -731,7 +742,8 @@ int error_count = 0; vm["listguards"].as())); if (listguards_file != "-") { - fs::create_directories(boost::wave::util::branch_path(listguards_file)); + boost::wave::util::create_directories( + boost::wave::util::branch_path(listguards_file)); listguardsout.open(listguards_file.string().c_str()); if (!listguardsout.is_open()) { cerr << "wave: could not open include guard list file: " @@ -802,6 +814,23 @@ int error_count = 0; if (vm.count("macrocounts")) hooks.enable_macro_counting(); + // check, if we have a license file to prepend + std::string license; + + if (vm.count ("license")) { + // try to open the file, where to put the preprocessed output + std::string license_file(vm["license"].as()); + std::ifstream license_stream(license_file.c_str()); + + if (!license_stream.is_open()) { + cerr << "wave: could not open specified license file: " + << license_file << endl; + return -1; + } + license = read_entire_file(license_stream); + hooks.set_license_info(license); + } + context_type ctx (instring.begin(), instring.end(), file_name.c_str(), hooks); #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 @@ -1016,13 +1045,16 @@ int error_count = 0; } else { out_file = boost::wave::util::complete_path(out_file); - fs::create_directories(boost::wave::util::branch_path(out_file)); + boost::wave::util::create_directories( + boost::wave::util::branch_path(out_file)); output.open(out_file.string().c_str()); if (!output.is_open()) { cerr << "wave: could not open output file: " << out_file.string() << endl; return -1; } + if (!license.empty()) + output << license; default_outfile = out_file.string(); } } @@ -1036,13 +1068,16 @@ int error_count = 0; basename = basename.substr(0, pos); out_file = boost::wave::util::branch_path(out_file) / (basename + ".i"); - fs::create_directories(boost::wave::util::branch_path(out_file)); + boost::wave::util::create_directories( + boost::wave::util::branch_path(out_file)); output.open(out_file.string().c_str()); if (!output.is_open()) { cerr << "wave: could not open output file: " << out_file.string() << endl; return -1; } + if (!license.empty()) + output << license; default_outfile = out_file.string(); } @@ -1238,6 +1273,8 @@ main (int argc, char *argv[]) "disable output [-]") ("autooutput,E", "output goes into a file named .i") + ("license", po::value(), + "prepend the content of the specified file to each created file") ("include,I", po::value()->composing(), "specify an additional include directory") ("sysinclude,S", po::value >()->composing(), @@ -1414,7 +1451,7 @@ main (int argc, char *argv[]) } std::string file_name(arguments[0].value[0]); - ifstream instream(file_name.c_str()); + std::ifstream instream(file_name.c_str()); // preprocess the given input file if (!instream.is_open()) { diff --git a/tool/trace_macro_expansion.hpp b/tool/trace_macro_expansion.hpp index 9296d09..a6e7c31 100644 --- a/tool/trace_macro_expansion.hpp +++ b/tool/trace_macro_expansion.hpp @@ -62,7 +62,7 @@ enum trace_flags { /////////////////////////////////////////////////////////////////////////////// // -// Special error thrown whenever the #pragma wave system() directive is +// Special error thrown whenever the #pragma wave system() directive is // disabled // /////////////////////////////////////////////////////////////////////////////// @@ -71,15 +71,15 @@ class bad_pragma_exception : { public: enum error_code { - pragma_system_not_enabled = + pragma_system_not_enabled = boost::wave::preprocess_exception::last_error_number + 1, pragma_mismatched_push_pop, }; - bad_pragma_exception(char const *what_, error_code code, int line_, - int column_, char const *filename_) throw() - : boost::wave::preprocess_exception(what_, - (boost::wave::preprocess_exception::error_code)code, line_, + bad_pragma_exception(char const *what_, error_code code, int line_, + int column_, char const *filename_) throw() + : boost::wave::preprocess_exception(what_, + (boost::wave::preprocess_exception::error_code)code, line_, column_, filename_) { } @@ -128,10 +128,10 @@ public: }; /////////////////////////////////////////////////////////////////////////////// -// +// // The trace_macro_expansion policy is used to trace the macro expansion of // macros whenever it is requested from inside the input stream to preprocess -// through the '#pragma wave_option(trace: enable)' directive. The macro +// through the '#pragma wave_option(trace: enable)' directive. The macro // tracing is disabled with the help of a '#pragma wave_option(trace: disable)' // directive. // @@ -148,13 +148,13 @@ class trace_macro_expansion public: trace_macro_expansion( bool preserve_whitespace_, bool preserve_bol_whitespace_, - std::ofstream &output_, std::ostream &tracestrm_, - std::ostream &includestrm_, std::ostream &guardstrm_, - trace_flags flags_, bool enable_system_command_, + std::ofstream &output_, std::ostream &tracestrm_, + std::ostream &includestrm_, std::ostream &guardstrm_, + trace_flags flags_, bool enable_system_command_, bool& generate_output_, std::string const& default_outfile_) - : outputstrm(output_), tracestrm(tracestrm_), - includestrm(includestrm_), guardstrm(guardstrm_), - level(0), flags(flags_), logging_flags(trace_nothing), + : outputstrm(output_), tracestrm(tracestrm_), + includestrm(includestrm_), guardstrm(guardstrm_), + level(0), flags(flags_), logging_flags(trace_nothing), enable_system_command(enable_system_command_), preserve_whitespace(preserve_whitespace_), preserve_bol_whitespace(preserve_bol_whitespace_), @@ -167,9 +167,9 @@ public: { } - void enable_macro_counting() - { - logging_flags = trace_flags(logging_flags | trace_macro_counts); + void enable_macro_counting() + { + logging_flags = trace_flags(logging_flags | trace_macro_counts); } std::map const& get_macro_counts() const { @@ -191,34 +191,39 @@ public: noexpandmacros.insert(name); } + void set_license_info(std::string const& info) + { + license_info = info; + } + /////////////////////////////////////////////////////////////////////////// - // - // The function 'expanding_function_like_macro' is called whenever a + // + // The function 'expanding_function_like_macro' is called whenever a // function-like macro is to be expanded. // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'macrodef' marks the position, where the macro to expand + // The parameter 'macrodef' marks the position, where the macro to expand // is defined. // // The parameter 'formal_args' holds the formal arguments used during the // definition of the macro. // - // The parameter 'definition' holds the macro definition for the macro to + // The parameter 'definition' holds the macro definition for the macro to // trace. // // The parameter 'macro_call' marks the position, where this macro invoked. // - // The parameter 'arguments' holds the macro arguments used during the + // The parameter 'arguments' holds the macro arguments used during the // invocation of the macro // - // The parameters 'seqstart' and 'seqend' point into the input token + // The parameters 'seqstart' and 'seqend' point into the input token // stream allowing to access the whole token sequence comprising the macro // invocation (starting with the opening parenthesis and ending after the // closing one). // - // The return value defines whether the corresponding macro will be + // The return value defines whether the corresponding macro will be // expanded (return false) or will be copied to the output (return true). // Note: the whole argument list is copied unchanged to the output as well // without any further processing. @@ -228,24 +233,24 @@ public: // old signature template void expanding_function_like_macro( - TokenT const ¯odef, std::vector const &formal_args, + TokenT const ¯odef, std::vector const &formal_args, ContainerT const &definition, - TokenT const ¯ocall, std::vector const &arguments) + TokenT const ¯ocall, std::vector const &arguments) { if (enabled_macro_counting()) count_invocation(macrodef.get_value().c_str()); - if (!enabled_macro_tracing()) + if (!enabled_macro_tracing()) return; #else // new signature template - bool + bool expanding_function_like_macro(ContextT const& ctx, - TokenT const ¯odef, std::vector const &formal_args, + TokenT const ¯odef, std::vector const &formal_args, ContainerT const &definition, TokenT const ¯ocall, std::vector const &arguments, - IteratorT const& seqstart, IteratorT const& seqend) + IteratorT const& seqstart, IteratorT const& seqend) { if (enabled_macro_counting() || !noexpandmacros.empty()) { std::string name (macrodef.get_value().c_str()); @@ -257,14 +262,14 @@ public: count_invocation(name.c_str()); } - if (!enabled_macro_tracing()) + if (!enabled_macro_tracing()) return false; #endif if (0 == get_level()) { // output header line BOOST_WAVE_OSSTREAM stream; - stream + stream << macrocall.get_position() << ": " << macrocall.get_value() << "("; @@ -274,7 +279,7 @@ public: if (i < arguments.size()-1) stream << ", "; } - stream << ")" << std::endl; + stream << ")" << std::endl; output(BOOST_WAVE_GETSTRING(stream)); increment_level(); } @@ -283,27 +288,27 @@ public: { BOOST_WAVE_OSSTREAM stream; - stream + stream << macrodef.get_position() << ": see macro definition: " << macrodef.get_value() << "("; // formal argument list - for (typename std::vector::size_type i = 0; - i < formal_args.size(); ++i) + for (typename std::vector::size_type i = 0; + i < formal_args.size(); ++i) { stream << formal_args[i].get_value(); if (i < formal_args.size()-1) stream << ", "; } - stream << ")" << std::endl; + stream << ")" << std::endl; output(BOOST_WAVE_GETSTRING(stream)); } if (formal_args.size() > 0) { // map formal and real arguments open_trace_body("invoked with\n"); - for (typename std::vector::size_type j = 0; - j < formal_args.size(); ++j) + for (typename std::vector::size_type j = 0; + j < formal_args.size(); ++j) { using namespace boost::wave; @@ -312,15 +317,15 @@ public: #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (T_ELLIPSIS == token_id(formal_args[j])) { // ellipsis - for (typename ContainerT::size_type k = j; - k < arguments.size(); ++k) + for (typename ContainerT::size_type k = j; + k < arguments.size(); ++k) { stream << boost::wave::util::impl::as_string(arguments[k]); if (k < arguments.size()-1) stream << ", "; } - } - else + } + else #endif { stream << boost::wave::util::impl::as_string(arguments[j]); @@ -338,17 +343,17 @@ public: } /////////////////////////////////////////////////////////////////////////// - // - // The function 'expanding_object_like_macro' is called whenever a + // + // The function 'expanding_object_like_macro' is called whenever a // object-like macro is to be expanded . // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'macrodef' marks the position, where the macro to expand + // The parameter 'macrodef' marks the position, where the macro to expand // is defined. // - // The definition 'definition' holds the macro definition for the macro to + // The definition 'definition' holds the macro definition for the macro to // trace. // // The parameter 'macrocall' marks the position, where this macro invoked. @@ -357,20 +362,20 @@ public: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 // old signature template - void expanding_object_like_macro(TokenT const ¯odef, + void expanding_object_like_macro(TokenT const ¯odef, ContainerT const &definition, TokenT const ¯ocall) { if (enabled_macro_counting()) count_invocation(macrodef.get_value().c_str()); - if (!enabled_macro_tracing()) + if (!enabled_macro_tracing()) return; #else // new signature template - bool + bool expanding_object_like_macro(ContextT const& ctx, - TokenT const ¯odef, ContainerT const &definition, + TokenT const ¯odef, ContainerT const &definition, TokenT const ¯ocall) { if (enabled_macro_counting() || !noexpandmacros.empty()) { @@ -383,14 +388,14 @@ public: count_invocation(name.c_str()); } - if (!enabled_macro_tracing()) + if (!enabled_macro_tracing()) return false; #endif if (0 == get_level()) { // output header line BOOST_WAVE_OSSTREAM stream; - stream + stream << macrocall.get_position() << ": " << macrocall.get_value() << std::endl; output(BOOST_WAVE_GETSTRING(stream)); @@ -401,7 +406,7 @@ public: { BOOST_WAVE_OSSTREAM stream; - stream + stream << macrodef.get_position() << ": see macro definition: " << macrodef.get_value() << std::endl; output(BOOST_WAVE_GETSTRING(stream)); @@ -414,14 +419,14 @@ public: } /////////////////////////////////////////////////////////////////////////// - // - // The function 'expanded_macro' is called whenever the expansion of a + // + // The function 'expanded_macro' is called whenever the expansion of a // macro is finished but before the rescanning process starts. // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'result' contains the token sequence generated as the + // The parameter 'result' contains the token sequence generated as the // result of the macro expansion. // /////////////////////////////////////////////////////////////////////////// @@ -445,14 +450,14 @@ public: } /////////////////////////////////////////////////////////////////////////// - // - // The function 'rescanned_macro' is called whenever the rescanning of a + // + // The function 'rescanned_macro' is called whenever the rescanning of a // macro is finished. // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'result' contains the token sequence generated as the + // The parameter 'result' contains the token sequence generated as the // result of the rescanning. // /////////////////////////////////////////////////////////////////////////// @@ -466,7 +471,7 @@ public: void rescanned_macro(ContextT const& ctx,ContainerT const &result) #endif { - if (!enabled_macro_tracing() || get_level() == 0) + if (!enabled_macro_tracing() || get_level() == 0) return; BOOST_WAVE_OSSTREAM stream; @@ -480,37 +485,37 @@ public: } /////////////////////////////////////////////////////////////////////////// - // - // The function 'interpret_pragma' is called whenever a #pragma command + // + // The function 'interpret_pragma' is called whenever a #pragma command // directive is found which isn't known to the core Wave library, where // command is the value defined as the BOOST_WAVE_PRAGMA_KEYWORD constant // which defaults to "wave". // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'pending' may be used to push tokens back into the input - // stream, which are to be used as the replacement text for the whole + // The parameter 'pending' may be used to push tokens back into the input + // stream, which are to be used as the replacement text for the whole // #pragma directive. // // The parameter 'option' contains the name of the interpreted pragma. // - // The parameter 'values' holds the values of the parameter provided to + // The parameter 'values' holds the values of the parameter provided to // the pragma operator. // - // The parameter 'act_token' contains the actual #pragma token, which may + // The parameter 'act_token' contains the actual #pragma token, which may // be used for error output. // - // If the return value is 'false', the whole #pragma directive is + // If the return value is 'false', the whole #pragma directive is // interpreted as unknown and a corresponding error message is issued. A - // return value of 'true' signs a successful interpretation of the given + // return value of 'true' signs a successful interpretation of the given // #pragma. // /////////////////////////////////////////////////////////////////////////// template - bool - interpret_pragma(ContextT &ctx, ContainerT &pending, - typename ContextT::token_type const &option, ContainerT const &valuetokens, + bool + interpret_pragma(ContextT &ctx, ContainerT &pending, + typename ContextT::token_type const &option, ContainerT const &valuetokens, typename ContextT::token_type const &act_token) { typedef typename ContextT::token_type token_type; @@ -540,7 +545,7 @@ public: // a corresponding error (actually its a remark), typename ContextT::string_type msg( boost::wave::util::impl::as_string(values)); - BOOST_WAVE_THROW_CTX(ctx, bad_pragma_exception, + BOOST_WAVE_THROW_CTX(ctx, bad_pragma_exception, pragma_system_not_enabled, msg.c_str(), act_token.get_position()); return false; @@ -554,12 +559,12 @@ public: // stop the execution and output the argument typename ContextT::string_type msg( boost::wave::util::impl::as_string(values)); - BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, + BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, error_directive, msg.c_str(), act_token.get_position()); return false; } if (option.get_value() == "option") { - // handle different options + // handle different options return interpret_pragma_option(ctx, values, act_token); } return false; @@ -570,26 +575,26 @@ public: // The function 'emit_line_directive' is called whenever a #line directive // has to be emitted into the generated output. // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'pending' may be used to push tokens back into the input + // The parameter 'pending' may be used to push tokens back into the input // stream, which are to be used instead of the default output generated // for the #line directive. // - // The parameter 'act_token' contains the actual #pragma token, which may + // The parameter 'act_token' contains the actual #pragma token, which may // be used for error output. The line number stored in this token can be // used as the line number emitted as part of the #line directive. // // If the return value is 'false', a default #line directive is emitted - // by the library. A return value of 'true' will inhibit any further - // actions, the tokens contained in 'pending' will be copied verbatim + // by the library. A return value of 'true' will inhibit any further + // actions, the tokens contained in 'pending' will be copied verbatim // to the output. // /////////////////////////////////////////////////////////////////////////// template - bool - emit_line_directive(ContextT const& ctx, ContainerT &pending, + bool + emit_line_directive(ContextT const& ctx, ContainerT &pending, typename ContextT::token_type const& act_token) { if (!need_emit_line_directives(ctx.get_language()) || @@ -611,7 +616,7 @@ public: pos.set_column(column); // account for '#line' pending.push_back(result_type(T_SPACE, " ", pos)); - // 21 is the max required size for a 64 bit integer represented as a + // 21 is the max required size for a 64 bit integer represented as a // string char buffer[22]; @@ -639,36 +644,36 @@ public: } /////////////////////////////////////////////////////////////////////////// - // - // The function 'opened_include_file' is called whenever a file referred + // + // The function 'opened_include_file' is called whenever a file referred // by an #include directive was successfully located and opened. // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'filename' contains the file system path of the - // opened file (this is relative to the directory of the currently + // The parameter 'filename' contains the file system path of the + // opened file (this is relative to the directory of the currently // processed file or a absolute path depending on the paths given as the // include search paths). // // The include_depth parameter contains the current include file depth. // - // The is_system_include parameter denotes, whether the given file was + // The is_system_include parameter denotes, whether the given file was // found as a result of a #include <...> directive. - // + // /////////////////////////////////////////////////////////////////////////// #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 // old signature - void - opened_include_file(std::string const &relname, std::string const &absname, - std::size_t include_depth, bool is_system_include) + void + opened_include_file(std::string const &relname, std::string const &absname, + std::size_t include_depth, bool is_system_include) { #else // new signature template - void - opened_include_file(ContextT const& ctx, std::string const &relname, - std::string const &absname, bool is_system_include) + void + opened_include_file(ContextT const& ctx, std::string const &relname, + std::string const &absname, bool is_system_include) { std::size_t include_depth = ctx.get_iteration_depth(); #endif @@ -688,38 +693,38 @@ public: #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 /////////////////////////////////////////////////////////////////////////// - // - // The function 'detected_include_guard' is called whenever either a - // include file is about to be added to the list of #pragma once headers. - // That means this header file will not be opened and parsed again even - // if it is specified in a later #include directive. - // This function is called as the result of a detected include guard - // scheme. // - // The implemented heuristics for include guards detects two forms of + // The function 'detected_include_guard' is called whenever either a + // include file is about to be added to the list of #pragma once headers. + // That means this header file will not be opened and parsed again even + // if it is specified in a later #include directive. + // This function is called as the result of a detected include guard + // scheme. + // + // The implemented heuristics for include guards detects two forms of // include guards: - // + // // #ifndef INCLUDE_GUARD_MACRO // #define INCLUDE_GUARD_MACRO // ... // #endif - // + // // or - // + // // if !defined(INCLUDE_GUARD_MACRO) // #define INCLUDE_GUARD_MACRO // ... // #endif - // + // // note, that the parenthesis are optional (i.e. !defined INCLUDE_GUARD_MACRO - // will work as well). The code allows for any whitespace, newline and single + // will work as well). The code allows for any whitespace, newline and single // '#' tokens before the #if/#ifndef and after the final #endif. // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'filename' contains the file system path of the - // opened file (this is relative to the directory of the currently + // The parameter 'filename' contains the file system path of the + // opened file (this is relative to the directory of the currently // processed file or a absolute path depending on the paths given as the // include search paths). // @@ -729,46 +734,46 @@ public: template void detected_include_guard(ContextT const& ctx, std::string const& filename, - std::string const& include_guard) + std::string const& include_guard) { if (enabled_guard_tracing()) { guardstrm << include_guard << ":" << std::endl << " " << filename << std::endl; } } -#endif +#endif /////////////////////////////////////////////////////////////////////////// // - // The function 'may_skip_whitespace' will be called by the - // library whenever a token is about to be returned to the calling - // application. + // The function 'may_skip_whitespace' will be called by the + // library whenever a token is about to be returned to the calling + // application. // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The 'token' parameter holds a reference to the current token. The policy + // The 'token' parameter holds a reference to the current token. The policy // is free to change this token if needed. // - // The 'skipped_newline' parameter holds a reference to a boolean value - // which should be set to true by the policy function whenever a newline - // is going to be skipped. + // The 'skipped_newline' parameter holds a reference to a boolean value + // which should be set to true by the policy function whenever a newline + // is going to be skipped. // - // If the return value is true, the given token is skipped and the - // preprocessing continues to the next token. If the return value is - // false, the given token is returned to the calling application. + // If the return value is true, the given token is skipped and the + // preprocessing continues to the next token. If the return value is + // false, the given token is returned to the calling application. // // ATTENTION! - // Caution has to be used, because by returning true the policy function - // is able to force skipping even significant tokens, not only whitespace. + // Caution has to be used, because by returning true the policy function + // is able to force skipping even significant tokens, not only whitespace. // /////////////////////////////////////////////////////////////////////////// template - bool may_skip_whitespace(ContextT const &ctx, TokenT &token, + bool may_skip_whitespace(ContextT const &ctx, TokenT &token, bool &skipped_newline) { return this->base_type::may_skip_whitespace( - ctx, token, need_preserve_comments(ctx.get_language()), + ctx, token, need_preserve_comments(ctx.get_language()), preserve_bol_whitespace, skipped_newline) ? !preserve_whitespace : false; } @@ -778,14 +783,14 @@ public: // The function 'throw_exception' will be called by the library whenever a // preprocessing exception occurs. // - // The parameter 'ctx' is a reference to the context object used for + // The parameter 'ctx' is a reference to the context object used for // instantiating the preprocessing iterators by the user. // - // The parameter 'e' is the exception object containing detailed error + // The parameter 'e' is the exception object containing detailed error // information. // // The default behavior is to call the function boost::throw_exception. - // + // /////////////////////////////////////////////////////////////////////////// template void @@ -798,7 +803,7 @@ public: boost::throw_exception(e); #endif } - using base_type::throw_exception; + using base_type::throw_exception; protected: #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0 @@ -820,8 +825,8 @@ protected: /////////////////////////////////////////////////////////////////////////// // Interpret the different Wave specific pragma directives/operators template - bool - interpret_pragma_trace(ContextT& ctx, ContainerT const &values, + bool + interpret_pragma_trace(ContextT& ctx, ContainerT const &values, typename ContextT::token_type const &act_token) { typedef typename ContextT::token_type token_type; @@ -833,8 +838,8 @@ protected: token_type const &value = values.front(); if (value.get_value() == "enable" || - value.get_value() == "on" || - value.get_value() == "1") + value.get_value() == "on" || + value.get_value() == "1") { // #pragma wave trace(enable) enable_tracing(static_cast( @@ -842,8 +847,8 @@ protected: valid_option = true; } else if (value.get_value() == "disable" || - value.get_value() == "off" || - value.get_value() == "0") + value.get_value() == "off" || + value.get_value() == "0") { // #pragma wave trace(disable) enable_tracing(static_cast( @@ -860,8 +865,8 @@ protected: option_str += boost::wave::util::impl::as_string(values); option_str += ")"; } - BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, - ill_formed_pragma_option, option_str.c_str(), + BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, + ill_formed_pragma_option, option_str.c_str(), act_token.get_position()); return false; } @@ -871,8 +876,8 @@ protected: /////////////////////////////////////////////////////////////////////////// // interpret the pragma wave option(preserve: [0|1|2|3|push|pop]) directive template - static bool - interpret_pragma_option_preserve_set(int mode, bool &preserve_whitespace, + static bool + interpret_pragma_option_preserve_set(int mode, bool &preserve_whitespace, bool& preserve_bol_whitespace, ContextT &ctx) { switch(mode) { @@ -919,7 +924,7 @@ protected: } template - bool + bool interpret_pragma_option_preserve(ContextT &ctx, IteratorT &it, IteratorT end, typename ContextT::token_type const &act_token) { @@ -950,14 +955,14 @@ protected: else if ((*it).get_value() == "pop") { // test for mismatched push/pop #pragmas if (preserve_options.empty()) { - BOOST_WAVE_THROW_CTX(ctx, bad_pragma_exception, - pragma_mismatched_push_pop, "preserve", + BOOST_WAVE_THROW_CTX(ctx, bad_pragma_exception, + pragma_mismatched_push_pop, "preserve", act_token.get_position()); } // pop output preserve from the internal option stack bool result = interpret_pragma_option_preserve_set( - preserve_options.top(), preserve_whitespace, + preserve_options.top(), preserve_whitespace, preserve_bol_whitespace, ctx); preserve_options.pop(); return result; @@ -965,18 +970,18 @@ protected: return false; } - if (T_PP_NUMBER != id) + if (T_PP_NUMBER != id) return false; using namespace std; // some platforms have atoi in namespace std return interpret_pragma_option_preserve_set( - atoi((*it).get_value().c_str()), preserve_whitespace, + atoi((*it).get_value().c_str()), preserve_whitespace, preserve_bol_whitespace, ctx); } // interpret the pragma wave option(line: [0|1|2|push|pop]) directive template - bool + bool interpret_pragma_option_line(ContextT &ctx, IteratorT &it, IteratorT end, typename ContextT::token_type const &act_token) { @@ -985,7 +990,7 @@ protected: token_id id = util::impl::skip_whitespace(it, end); if (T_COLON == id) id = util::impl::skip_whitespace(it, end); - + // implement push/pop if (T_IDENTIFIER == id) { if ((*it).get_value() == "push") { @@ -1002,8 +1007,8 @@ protected: else if ((*it).get_value() == "pop") { // test for mismatched push/pop #pragmas if (line_options.empty()) { - BOOST_WAVE_THROW_CTX(ctx, bad_pragma_exception, - pragma_mismatched_push_pop, "line", + BOOST_WAVE_THROW_CTX(ctx, bad_pragma_exception, + pragma_mismatched_push_pop, "line", act_token.get_position()); } @@ -1018,7 +1023,7 @@ protected: return false; } - if (T_PP_NUMBER != id) + if (T_PP_NUMBER != id) return false; using namespace std; // some platforms have atoi in namespace std @@ -1033,17 +1038,18 @@ protected: return false; } - // interpret the pragma wave option(output: ["filename"|null|default|push|pop]) + // interpret the pragma wave option(output: ["filename"|null|default|push|pop]) // directive template - bool - interpret_pragma_option_output_open(boost::filesystem::path &fpath, + bool + interpret_pragma_option_output_open(boost::filesystem::path &fpath, ContextT& ctx, typename ContextT::token_type const &act_token) { namespace fs = boost::filesystem; // ensure all directories for this file do exist - fs::create_directories(boost::wave::util::branch_path(fpath)); + boost::wave::util::create_directories( + boost::wave::util::branch_path(fpath)); // figure out, whether the file has been written to by us, if yes, we // append any output to this file, otherwise we overwrite it @@ -1059,17 +1065,22 @@ protected: // open the new file outputstrm.open(fpath.string().c_str(), mode); - if (!outputstrm.is_open()) { - BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, + if (!outputstrm.is_open()) { + BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, could_not_open_output_file, fpath.string().c_str(), act_token.get_position()); return false; } + + // write license text, if file was created and if requested + if (mode == std::ios::out && !license_info.empty()) + outputstrm << license_info; + generate_output = true; current_outfile = fpath; - return true; + return true; } - + bool interpret_pragma_option_output_close(bool generate) { if (outputstrm.is_open()) @@ -1080,7 +1091,7 @@ protected: } template - bool + bool interpret_pragma_option_output(ContextT &ctx, IteratorT &it, IteratorT end, typename ContextT::token_type const &act_token) { @@ -1097,7 +1108,7 @@ protected: bool result = false; if (T_STRINGLIT == id) { namespace fs = boost::filesystem; - + string_type fname ((*it).get_value()); fs::path fpath (boost::wave::util::create_path( util::impl::unescape_lit(fname.substr(1, fname.size()-2)).c_str())); @@ -1108,7 +1119,7 @@ protected: if ((*it).get_value() == "null") { // suppress all output from this point on result = interpret_pragma_option_output_close(false); - } + } else if ((*it).get_value() == "push") { // initialize the current_outfile, if appropriate if (output_options.empty() && current_outfile.empty() && @@ -1126,8 +1137,8 @@ protected: else if ((*it).get_value() == "pop") { // test for mismatched push/pop #pragmas if (output_options.empty()) { - BOOST_WAVE_THROW_CTX(ctx, bad_pragma_exception, - pragma_mismatched_push_pop, "output", + BOOST_WAVE_THROW_CTX(ctx, bad_pragma_exception, + pragma_mismatched_push_pop, "output", act_token.get_position()); return false; } @@ -1138,7 +1149,7 @@ protected: current_outfile = opts.second; if (!current_outfile.empty()) { // re-open the last file - result = interpret_pragma_option_output_open(current_outfile, + result = interpret_pragma_option_output_open(current_outfile, ctx, act_token); } else { @@ -1158,7 +1169,7 @@ protected: else { // there was a file name on the command line fs::path fpath(boost::wave::util::create_path(default_outfile)); - result = interpret_pragma_option_output_open(fpath, ctx, + result = interpret_pragma_option_output_open(fpath, ctx, act_token); } } @@ -1234,8 +1245,8 @@ protected: /////////////////////////////////////////////////////////////////////////// // interpret the pragma wave option() directives template - bool - interpret_pragma_option(ContextT &ctx, ContainerT const &cvalues, + bool + interpret_pragma_option(ContextT &ctx, ContainerT const &cvalues, typename ContextT::token_type const &act_token) { using namespace boost::wave; @@ -1254,17 +1265,17 @@ protected: token_type const &value = *it; if (value.get_value() == "preserve") { // #pragma wave option(preserve: [0|1|2|3|push|pop]) - valid_option = interpret_pragma_option_preserve(ctx, it, end, + valid_option = interpret_pragma_option_preserve(ctx, it, end, act_token); } else if (value.get_value() == "line") { // #pragma wave option(line: [0|1|2|push|pop]) - valid_option = interpret_pragma_option_line(ctx, it, end, + valid_option = interpret_pragma_option_line(ctx, it, end, act_token); } else if (value.get_value() == "output") { // #pragma wave option(output: ["filename"|null|default|push|pop]) - valid_option = interpret_pragma_option_output(ctx, it, end, + valid_option = interpret_pragma_option_output(ctx, it, end, act_token); } @@ -1277,12 +1288,12 @@ protected: option_str += util::impl::as_string(values); option_str += ")"; } - BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, + BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, ill_formed_pragma_option, option_str.c_str(), act_token.get_position()); return false; } - + token_id id = util::impl::skip_whitespace(it, end); if (id == T_COMMA) util::impl::skip_whitespace(it, end); @@ -1294,8 +1305,8 @@ protected: // interpret the #pragma wave system() directive template bool - interpret_pragma_system(ContextT& ctx, ContainerT &pending, - ContainerT const &values, + interpret_pragma_system(ContextT& ctx, ContainerT &pending, + ContainerT const &values, typename ContextT::token_type const &act_token) { typedef typename ContextT::token_type token_type; @@ -1314,25 +1325,25 @@ protected: string_type error_str("unable to spawn command: "); error_str += native_cmd; - BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, + BOOST_WAVE_THROW_CTX(ctx, boost::wave::preprocess_exception, ill_formed_pragma_option, error_str.c_str(), act_token.get_position()); return false; } - // rescan the content of the stdout_file and insert it as the + // rescan the content of the stdout_file and insert it as the // _Pragma replacement typedef typename ContextT::lexer_type lexer_type; typedef typename ContextT::input_policy_type input_policy_type; typedef boost::wave::iteration_context< - ContextT, lexer_type, input_policy_type> + ContextT, lexer_type, input_policy_type> iteration_context_type; - iteration_context_type iter_ctx(ctx, stdout_file.c_str(), + iteration_context_type iter_ctx(ctx, stdout_file.c_str(), act_token.get_position(), ctx.get_language()); ContainerT pragma; - for (/**/; iter_ctx.first != iter_ctx.last; ++iter_ctx.first) + for (/**/; iter_ctx.first != iter_ctx.last; ++iter_ctx.first) pragma.push_back(*iter_ctx.first); // prepend the newly generated token sequence to the 'pending' container @@ -1345,14 +1356,14 @@ protected: } /////////////////////////////////////////////////////////////////////////// - // The function enable_tracing is called, whenever the status of the + // The function enable_tracing is called, whenever the status of the // tracing was changed. // The parameter 'enable' is to be used as the new tracing status. - void enable_tracing(trace_flags flags) + void enable_tracing(trace_flags flags) { logging_flags = flags; } // The function tracing_enabled should return the current tracing status. - trace_flags tracing_enabled() + trace_flags tracing_enabled() { return logging_flags; } // Helper functions for generating the trace output @@ -1389,21 +1400,21 @@ protected: int decrement_level() { BOOST_ASSERT(level > 0); return --level; } int get_level() const { return level; } - bool enabled_macro_tracing() const - { - return (flags & trace_macros) && (logging_flags & trace_macros); + bool enabled_macro_tracing() const + { + return (flags & trace_macros) && (logging_flags & trace_macros); } - bool enabled_include_tracing() const - { - return (flags & trace_includes); + bool enabled_include_tracing() const + { + return (flags & trace_includes); } - bool enabled_guard_tracing() const - { - return (flags & trace_guards); + bool enabled_guard_tracing() const + { + return (flags & trace_guards); } - bool enabled_macro_counting() const - { - return logging_flags & trace_macro_counts; + bool enabled_macro_counting() const + { + return logging_flags & trace_macro_counts; } void count_invocation(std::string const& name) @@ -1431,8 +1442,8 @@ protected: } else if (value.get_value() == "1") { // print out the current elapsed time - std::cerr - << value.get_position() << ": " + std::cerr + << value.get_position() << ": " << elapsed_time.format_elapsed_time() << std::endl; } @@ -1459,7 +1470,7 @@ private: bool preserve_bol_whitespace; // enable begin of line whitespace preservation bool& generate_output; // allow generated tokens to be streamed to output std::string const& default_outfile; // name of the output file given on command line - boost::filesystem::path current_outfile; // name of the current output file + boost::filesystem::path current_outfile; // name of the current output file stop_watch elapsed_time; // trace timings std::set written_by_us; // all files we have written to @@ -1473,6 +1484,8 @@ private: bool emit_relative_filenames; // emit relative names in #line directives std::set noexpandmacros; // list of macros not to expand + + std::string license_info; // text to pre-pend to all generated output files }; #undef BOOST_WAVE_GETSTRING