cpp_macromap.hpp
字号:
else if (adjacent_stringize && !IS_CATEGORY(*cit, WhiteSpaceTokenType)) { // stringize the current argument BOOST_ASSERT(!arguments[i].empty()); // safe a copy of the first tokens position (not a reference!) position_type pos ((*arguments[i].begin()).get_position());#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 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, impl::as_stringlit(arguments, i, pos), pos)); } else #endif { impl::trim_sequence(arguments[i]); expanded.push_back(token_type(T_STRINGLIT, impl::as_stringlit(arguments[i], pos), pos)); } adjacent_stringize = false; } else { // simply copy the original argument (adjacent '##' or '#')#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (is_ellipsis) { position_type const &pos = (*cit).get_position(); impl::trim_sequence_left(arguments[i]); impl::trim_sequence_right(arguments.back()); BOOST_ASSERT(boost::wave::need_variadics(ctx.get_language())); impl::replace_ellipsis(arguments, i, expanded, pos); } else#endif { ContainerT &arg = arguments[i]; impl::trim_sequence(arg); std::copy(arg.begin(), arg.end(), std::inserter(expanded, expanded.end())); } } } else if (!adjacent_stringize || T_POUND != base_id) { // insert the actual replacement token (if it is not the '#' operator) expanded.push_back(*cit); } } if (adjacent_stringize) { // error, '#' should not be the last token BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, ill_formed_operator, "stringize ('#')", main_pos); return; } // handle the cpp.concat operator if (seen_concat) concat_tokensequence(expanded);}/////////////////////////////////////////////////////////////////////////////////// rescan_replacement_list//// As the name implies, this function is used to rescan the replacement list // after the first macro substitution phase./////////////////////////////////////////////////////////////////////////////////template <typename ContextT>template <typename IteratorT, typename ContainerT>inline void macromap<ContextT>::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){ if (!replacement_list.empty()) {#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 // remove the placemarkers if (boost::wave::need_variadics(ctx.get_language())) { typename ContainerT::iterator end = replacement_list.end(); typename ContainerT::iterator it = replacement_list.begin(); while (it != end) { using namespace boost::wave; if (T_PLACEMARKER == token_id(*it)) { typename ContainerT::iterator placemarker = it; ++it; replacement_list.erase(placemarker); } else { ++it; } } }#endif // rescan the replacement list, during this rescan the current macro under // expansion isn't available as an expandable macro on_exit::reset<bool> on_exit(macro_def.is_available_for_replacement, false); 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); // trim replacement list, leave placeholder tokens untouched impl::trim_replacement_list(expanded); } if (expanded.empty()) { // the resulting replacement list should contain at least a placeholder // token expanded.push_back(token_type(T_PLACEHOLDER, "_", curr_token.get_position())); }}///////////////////////////////////////////////////////////////////////////////// // expand_macro(): expands a defined macro//// This functions tries to expand the macro, to which points the 'first'// iterator. The functions eats up more tokens, if the macro to expand is// a function-like macro./////////////////////////////////////////////////////////////////////////////////template <typename ContextT>template <typename IteratorT, typename ContainerT>inline bool macromap<ContextT>::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; if (0 == scope) scope = current_macros; BOOST_ASSERT(T_IDENTIFIER == token_id(curr_token) || 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 // try to expand a predefined macro (__FILE__, __LINE__ or __INCLUDE_LEVEL__) if (expand_predefined_macro(curr_token, expanded)) return false; // not defined as a macro if (0 != queue_symbol) { expanded.splice(expanded.end(), *queue_symbol); } else { expanded.push_back(curr_token); } return false; }// ensure the parameters to be replaced with special parameter tokensmacro_definition_type ¯o_def = *(*it).second.get(); macro_def.replace_parameters();// test if this macro is currently available for replacement if (!macro_def.is_available_for_replacement) { // this macro is marked as non-replaceable // copy the macro name itself if (0 != queue_symbol) { queue_symbol->push_back(token_type(T_NONREPLACABLE_IDENTIFIER, curr_token.get_value(), curr_token.get_position())); expanded.splice(expanded.end(), *queue_symbol); } else { expanded.push_back(token_type(T_NONREPLACABLE_IDENTIFIER, curr_token.get_value(), curr_token.get_position())); } ++first; return false; }// try to replace the current identifier as a function-like macroContainerT replacement_list; if (T_LEFTPAREN == impl::next_token<IteratorT>::peek(first, last)) { // called as a function-like macro impl::skip_to_token(first, last, T_LEFTPAREN, seen_newline); #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS == 0 IteratorT seqstart = first; IteratorT seqend = first;#endif if (macro_def.is_functionlike) { // defined as a function-like macro // collect the arguments std::vector<ContainerT> arguments;#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 typename std::vector<ContainerT>::size_type count_args = collect_arguments (curr_token, arguments, first, last, macro_def.macroparameters.size(), seen_newline);#else typename std::vector<ContainerT>::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()) { 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(), main_pos); } else { // too few macro arguments 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()) {#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 if (!macro_def.has_ellipsis) #endif { // too many macro arguments BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, too_many_macroarguments, curr_token.get_value().c_str(), main_pos); return false; } } // 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.macrodefinition, curr_token, arguments);#else 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 std::copy(seqstart, first, std::inserter(replacement_list, replacement_list.end())); return false; // no further preprocessing required }#endif // expand the replacement list of this macro expand_replacement_list(macro_def, arguments, expand_operator_defined, replacement_list); } else { // defined as an object-like macro#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 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(), macro_def.macroname, macro_def.macrodefinition, curr_token)) { // do not expand this macro, just copy the whole sequence replacement_list.push_back(curr_token); ++first; // skip macro name return false; // no further preprocessing required }#endif bool found = false; impl::find_concat_operator concat_tag(found); 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; } } else { // called as an object like macro if ((*it).second->is_functionlike) { // defined as a function-like macro if (0 != queue_symbol) { queue_symbol->push_back(curr_token); expanded.splice(expanded.end(), *queue_symbol); } else { expanded.push_back(curr_token); } ++first; // skip macro name return false; // no further preprocessing required } else { // defined as an object-like macro (expand it)#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 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(), macro_def.macroname, macro_def.macrodefinition, curr_token)) { // do not expand this macro, just copy the whole sequence replacement_list.push_back(curr_token); ++first; // skip macro name return false; // no further preprocessing required }#endif bool found = false; impl::find_concat_operator concat_tag(found); std::remove_copy_if(macro_def.macrodefinition.begin(), macro_def.macrodefinition.end(), std::inserter(replacement_list, replacement_list.end()), concat_tag);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -