Chris@16: /*============================================================================= Chris@16: Boost.Wave: A Standard compliant C++ preprocessor library Chris@16: Chris@16: http://www.boost.org/ Chris@16: Chris@16: Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost Chris@16: Software License, Version 1.0. (See accompanying file Chris@16: LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: =============================================================================*/ Chris@16: Chris@16: #if !defined(DEFAULT_PREPROCESSING_HOOKS_HPP_INCLUDED) Chris@16: #define DEFAULT_PREPROCESSING_HOOKS_HPP_INCLUDED Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: // this must occur after all of the includes and before any code appears Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_PREFIX Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { Chris@16: namespace wave { Chris@16: namespace context_policies { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The default_preprocessing_hooks class is a placeholder for all Chris@16: // preprocessing hooks called from inside the preprocessing engine Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct default_preprocessing_hooks Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'expanding_function_like_macro' is called, whenever a Chris@16: // function-like macro is to be expanded. Chris@16: // Chris@16: // The parameter 'macrodef' marks the position, where the macro to expand Chris@16: // is defined. Chris@16: // Chris@16: // The parameter 'formal_args' holds the formal arguments used during the Chris@16: // definition of the macro. Chris@16: // Chris@16: // The parameter 'definition' holds the macro definition for the macro to Chris@16: // trace. Chris@16: // Chris@16: // The parameter 'macro_call' marks the position, where this macro invoked. Chris@16: // Chris@16: // The parameter 'arguments' holds the macro arguments used during the Chris@16: // invocation of the macro Chris@16: // Chris@16: // The parameters 'seqstart' and 'seqend' point into the input token Chris@16: // stream allowing to access the whole token sequence comprising the macro Chris@16: // invocation (starting with the opening parenthesis and ending after the Chris@16: // closing one). Chris@16: // Chris@16: // The return value defines whether the corresponding macro will be Chris@16: // expanded (return false) or will be copied to the output (return true). Chris@16: // Note: the whole argument list is copied unchanged to the output as well Chris@16: // without any further processing. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void expanding_function_like_macro( Chris@16: TokenT const& macrodef, std::vector const& formal_args, Chris@16: ContainerT const& definition, Chris@16: TokenT const& macrocall, std::vector const& arguments) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: bool Chris@16: expanding_function_like_macro(ContextT const& ctx, Chris@16: TokenT const& macrodef, std::vector const& formal_args, Chris@16: ContainerT const& definition, Chris@16: TokenT const& macrocall, std::vector const& arguments, Chris@16: IteratorT const& seqstart, IteratorT const& seqend) Chris@16: { return false; } // default is to normally expand the macro Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'expanding_object_like_macro' is called, whenever a Chris@16: // object-like macro is to be expanded . Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'macro' marks the position, where the macro to expand Chris@16: // is defined. Chris@16: // Chris@16: // The definition 'definition' holds the macro definition for the macro to Chris@16: // trace. Chris@16: // Chris@16: // The parameter 'macrocall' marks the position, where this macro invoked. Chris@16: // Chris@16: // The return value defines whether the corresponding macro will be Chris@16: // expanded (return false) or will be copied to the output (return true). Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void expanding_object_like_macro(TokenT const& macro, Chris@16: ContainerT const& definition, TokenT const& macrocall) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: bool Chris@16: expanding_object_like_macro(ContextT const& ctx, TokenT const& macro, Chris@16: ContainerT const& definition, TokenT const& macrocall) Chris@16: { return false; } // default is to normally expand the macro Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'expanded_macro' is called, whenever the expansion of a Chris@16: // macro is finished but before the rescanning process starts. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'result' contains the token sequence generated as the Chris@16: // result of the macro expansion. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void expanded_macro(ContainerT const& result) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: void expanded_macro(ContextT const& ctx, ContainerT const& result) Chris@16: {} Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'rescanned_macro' is called, whenever the rescanning of a Chris@16: // macro is finished. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'result' contains the token sequence generated as the Chris@16: // result of the rescanning. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void rescanned_macro(ContainerT const& result) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: void rescanned_macro(ContextT const& ctx, ContainerT const& result) Chris@16: {} Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'locate_include_file' is called, whenever a #include Chris@16: // directive was encountered. It is supposed to locate the given file and Chris@16: // should return the full file name of the located file. This file name Chris@16: // is expected to uniquely identify the referenced file. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'file_path' contains the (expanded) file name found after Chris@16: // the #include directive. This parameter holds the string as it is Chris@16: // specified in the #include directive, i.e. or "file" will result Chris@16: // in a parameter value 'file'. Chris@16: // Chris@16: // The parameter 'is_system' is set to 'true' if this call happens as a Chris@16: // result of a #include '' directive, it is 'false' otherwise, i.e. Chris@16: // for #include "file" directives. Chris@16: // Chris@16: // The parameter 'current_name' is only used if a #include_next directive Chris@16: // was encountered (and BOOST_WAVE_SUPPORT_INCLUDE_NEXT was defined to be Chris@16: // non-zero). In this case it points to unique full name of the current Chris@16: // include file (if any). Otherwise this parameter is set to NULL. Chris@16: // Chris@16: // The parameter 'dir_path' on return is expected to hold the directory Chris@16: // part of the located file. Chris@16: // Chris@16: // The parameter 'native_name' on return is expected to hold the unique Chris@16: // full file name of the located file. Chris@16: // Chris@16: // The return value defines whether the file was located successfully. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: bool Chris@16: locate_include_file(ContextT& ctx, std::string &file_path, Chris@16: bool is_system, char const *current_name, std::string &dir_path, Chris@16: std::string &native_name) Chris@16: { Chris@16: if (!ctx.find_include_file (file_path, dir_path, is_system, current_name)) Chris@16: return false; // could not locate file Chris@16: Chris@16: namespace fs = boost::filesystem; Chris@16: Chris@16: fs::path native_path(wave::util::create_path(file_path)); Chris@16: if (!fs::exists(native_path)) { Chris@16: BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, bad_include_file, Chris@16: file_path.c_str(), ctx.get_main_pos()); Chris@16: return false; Chris@16: } Chris@16: Chris@16: // return the unique full file system path of the located file Chris@16: native_name = wave::util::native_file_string(native_path); Chris@16: Chris@16: return true; // include file has been located successfully Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'found_include_directive' is called, whenever a #include Chris@16: // directive was located. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'filename' contains the (expanded) file name found after Chris@16: // the #include directive. This has the format '', '"file"' or Chris@16: // 'file'. Chris@16: // The formats '' or '"file"' are used for #include directives found Chris@16: // in the preprocessed token stream, the format 'file' is used for files Chris@16: // specified through the --force_include command line argument. Chris@16: // Chris@16: // The parameter 'include_next' is set to true if the found directive was Chris@16: // a #include_next directive and the BOOST_WAVE_SUPPORT_INCLUDE_NEXT Chris@16: // preprocessing constant was defined to something != 0. Chris@16: // Chris@16: // The return value defines whether the found file will be included Chris@16: // (return false) or will be skipped (return true). Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: void Chris@16: found_include_directive(std::string const& filename, bool include_next) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: bool Chris@16: found_include_directive(ContextT const& ctx, std::string const& filename, Chris@16: bool include_next) Chris@16: { Chris@16: return false; // ok to include this file Chris@16: } Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'opened_include_file' is called, whenever a file referred Chris@16: // by an #include directive was successfully located and opened. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'filename' contains the file system path of the Chris@16: // opened file (this is relative to the directory of the currently Chris@16: // processed file or a absolute path depending on the paths given as the Chris@16: // include search paths). Chris@16: // Chris@16: // The include_depth parameter contains the current include file depth. Chris@16: // Chris@16: // The is_system_include parameter denotes whether the given file was Chris@16: // found as a result of a #include <...> directive. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: void Chris@16: opened_include_file(std::string const& relname, std::string const& absname, Chris@16: std::size_t include_depth, bool is_system_include) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: void Chris@16: opened_include_file(ContextT const& ctx, std::string const& relname, Chris@16: std::string const& absname, bool is_system_include) Chris@16: {} Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'returning_from_include_file' is called, whenever an Chris@16: // included file is about to be closed after it's processing is complete. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: void Chris@16: returning_from_include_file() Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: void Chris@16: returning_from_include_file(ContextT const& ctx) Chris@16: {} Chris@16: #endif Chris@16: Chris@16: #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'detected_include_guard' is called whenever either a Chris@16: // include file is about to be added to the list of #pragma once headers. Chris@16: // That means this header file will not be opened and parsed again even Chris@16: // if it is specified in a later #include directive. Chris@16: // This function is called as the result of a detected include guard Chris@16: // scheme. Chris@16: // Chris@16: // The implemented heuristics for include guards detects two forms of Chris@16: // include guards: Chris@16: // Chris@16: // #ifndef INCLUDE_GUARD_MACRO Chris@16: // #define INCLUDE_GUARD_MACRO Chris@16: // ... Chris@16: // #endif Chris@16: // Chris@16: // or Chris@16: // Chris@16: // if !defined(INCLUDE_GUARD_MACRO) Chris@16: // #define INCLUDE_GUARD_MACRO Chris@16: // ... Chris@16: // #endif Chris@16: // Chris@16: // note, that the parenthesis are optional (i.e. !defined INCLUDE_GUARD_MACRO Chris@16: // will work as well). The code allows for any whitespace, newline and single Chris@16: // '#' tokens before the #if/#ifndef and after the final #endif. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'filename' contains the file system path of the Chris@16: // opened file (this is relative to the directory of the currently Chris@16: // processed file or a absolute path depending on the paths given as the Chris@16: // include search paths). Chris@16: // Chris@16: // The parameter contains the name of the detected include guard. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: void Chris@16: detected_include_guard(ContextT const& ctx, std::string const& filename, Chris@16: std::string const& include_guard) Chris@16: {} Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'detected_pragma_once' is called whenever either a Chris@16: // include file is about to be added to the list of #pragma once headers. Chris@16: // That means this header file will not be opened and parsed again even Chris@16: // if it is specified in a later #include directive. Chris@16: // This function is called as the result of a detected directive Chris@16: // #pragma once. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter pragma_token refers to the token "#pragma" triggering Chris@16: // this preprocessing hook. Chris@16: // Chris@16: // The parameter 'filename' contains the file system path of the Chris@16: // opened file (this is relative to the directory of the currently Chris@16: // processed file or a absolute path depending on the paths given as the Chris@16: // include search paths). Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: void Chris@16: detected_pragma_once(ContextT const& ctx, TokenT const& pragma_token, Chris@16: std::string const& filename) Chris@16: {} Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'interpret_pragma' is called, whenever a '#pragma command' Chris@16: // directive is found which isn't known to the core Wave library, where Chris@16: // 'command' is the value defined as the BOOST_WAVE_PRAGMA_KEYWORD constant Chris@16: // which defaults to "wave". Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'pending' may be used to push tokens back into the input Chris@16: // stream, which are to be used as the replacement text for the whole Chris@16: // #pragma directive. Chris@16: // Chris@16: // The parameter 'option' contains the name of the interpreted pragma. Chris@16: // Chris@16: // The parameter 'values' holds the values of the parameter provided to Chris@16: // the pragma operator. Chris@16: // Chris@16: // The parameter 'act_token' contains the actual #pragma token, which may Chris@16: // be used for error output. Chris@16: // Chris@16: // If the return value is 'false', the whole #pragma directive is Chris@16: // interpreted as unknown and a corresponding error message is issued. A Chris@16: // return value of 'true' signs a successful interpretation of the given Chris@16: // #pragma. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: bool Chris@16: interpret_pragma(ContextT const& ctx, ContainerT &pending, Chris@16: typename ContextT::token_type const& option, ContainerT const& values, Chris@16: typename ContextT::token_type const& act_token) Chris@16: { Chris@16: return false; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'emit_line_directive' is called whenever a #line directive Chris@16: // has to be emitted into the generated output. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'pending' may be used to push tokens back into the input Chris@16: // stream, which are to be used instead of the default output generated Chris@16: // for the #line directive. Chris@16: // Chris@16: // The parameter 'act_token' contains the actual #pragma token, which may Chris@16: // be used for error output. The line number stored in this token can be Chris@16: // used as the line number emitted as part of the #line directive. Chris@16: // Chris@16: // If the return value is 'false', a default #line directive is emitted Chris@16: // by the library. A return value of 'true' will inhibit any further Chris@16: // actions, the tokens contained in 'pending' will be copied verbatim Chris@16: // to the output. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: bool Chris@16: emit_line_directive(ContextT const& ctx, ContainerT &pending, Chris@16: typename ContextT::token_type const& act_token) Chris@16: { Chris@16: return false; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'defined_macro' is called, whenever a macro was defined Chris@16: // successfully. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'name' is a reference to the token holding the macro name. Chris@16: // Chris@16: // The parameter 'is_functionlike' is set to true, whenever the newly Chris@16: // defined macro is defined as a function like macro. Chris@16: // Chris@16: // The parameter 'parameters' holds the parameter tokens for the macro Chris@16: // definition. If the macro has no parameters or if it is a object like Chris@16: // macro, then this container is empty. Chris@16: // Chris@16: // The parameter 'definition' contains the token sequence given as the Chris@16: // replacement sequence (definition part) of the newly defined macro. Chris@16: // Chris@16: // The parameter 'is_predefined' is set to true for all macros predefined Chris@16: // during the initialization phase of the library. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void Chris@16: defined_macro(TokenT const& macro_name, bool is_functionlike, Chris@16: ParametersT const& parameters, DefinitionT const& definition, Chris@16: bool is_predefined) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template < Chris@16: typename ContextT, typename TokenT, typename ParametersT, Chris@16: typename DefinitionT Chris@16: > Chris@16: void Chris@16: defined_macro(ContextT const& ctx, TokenT const& macro_name, Chris@16: bool is_functionlike, ParametersT const& parameters, Chris@16: DefinitionT const& definition, bool is_predefined) Chris@16: {} Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'undefined_macro' is called, whenever a macro definition Chris@16: // was removed successfully. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'name' holds the name of the macro, which definition was Chris@16: // removed. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void Chris@16: undefined_macro(TokenT const& macro_name) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: void Chris@16: undefined_macro(ContextT const& ctx, TokenT const& macro_name) Chris@16: {} Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'found_directive' is called, whenever a preprocessor Chris@16: // directive was encountered, but before the corresponding action is Chris@16: // executed. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'directive' is a reference to the token holding the Chris@16: // preprocessing directive. Chris@16: // Chris@16: // The return value defines whether the given expression has to be Chris@16: // to be executed in a normal way (return 'false'), or if it has to be Chris@16: // skipped altogether (return 'true'), which means it gets replaced in the Chris@16: // output by a single newline. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void Chris@16: found_directive(TokenT const& directive) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: bool Chris@16: found_directive(ContextT const& ctx, TokenT const& directive) Chris@16: { return false; } // by default we never skip any directives Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'found_unknown_directive' is called, whenever an unknown Chris@16: // preprocessor directive was encountered. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'line' holds the tokens of the entire source line Chris@16: // containing the unknown directive. Chris@16: // Chris@16: // The parameter 'pending' may be used to push tokens back into the input Chris@16: // stream, which are to be used as the replacement text for the whole Chris@16: // line containing the unknown directive. Chris@16: // Chris@16: // The return value defines whether the given expression has been Chris@16: // properly interpreted by the hook function or not. If this function Chris@16: // returns 'false', the library will raise an 'ill_formed_directive' Chris@16: // preprocess_exception. Otherwise the tokens pushed back into 'pending' Chris@16: // are passed on to the user program. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: bool Chris@16: found_unknown_directive(ContextT const& ctx, ContainerT const& line, Chris@16: ContainerT& pending) Chris@16: { return false; } // by default we never interpret unknown directives Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'evaluated_conditional_expression' is called, whenever a Chris@16: // conditional preprocessing expression was evaluated (the expression Chris@16: // given to a #if, #elif, #ifdef or #ifndef directive) Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'directive' is a reference to the token holding the Chris@16: // corresponding preprocessing directive. Chris@16: // Chris@16: // The parameter 'expression' holds the non-expanded token sequence Chris@16: // comprising the evaluated expression. Chris@16: // Chris@16: // The parameter expression_value contains the result of the evaluation of Chris@16: // the expression in the current preprocessing context. Chris@16: // Chris@16: // The return value defines whether the given expression has to be Chris@16: // evaluated again, allowing to decide which of the conditional branches Chris@16: // should be expanded. You need to return 'true' from this hook function Chris@16: // to force the expression to be re-evaluated. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void Chris@16: evaluated_conditional_expression(ContainerT const& expression, Chris@16: bool expression_value) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: bool Chris@16: evaluated_conditional_expression(ContextT const& ctx, Chris@16: TokenT const& directive, ContainerT const& expression, Chris@16: bool expression_value) Chris@16: { return false; } // ok to continue, do not re-evaluate expression Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'skipped_token' is called, whenever a token is about to be Chris@16: // skipped due to a false preprocessor condition (code fragments to be Chris@16: // skipped inside the not evaluated conditional #if/#else/#endif branches). Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'token' refers to the token to be skipped. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 Chris@16: // old signature Chris@16: template Chris@16: void Chris@16: skipped_token(TokenT const& token) Chris@16: {} Chris@16: #else Chris@16: // new signature Chris@16: template Chris@16: void Chris@16: skipped_token(ContextT const& ctx, TokenT const& token) Chris@16: {} Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'generated_token' will be called by the library whenever a Chris@16: // token is about to be returned from the library. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 't' is the token about to be returned from the library. Chris@16: // This function may alter the token, but in this case it must be Chris@16: // implemented with a corresponding signature: Chris@16: // Chris@16: // TokenT const& Chris@16: // generated_token(ContextT const& ctx, TokenT& t); Chris@16: // Chris@16: // which makes it possible to modify the token in place. Chris@16: // Chris@16: // The default behavior is to return the token passed as the parameter Chris@16: // without modification. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: TokenT const& Chris@16: generated_token(ContextT const& ctx, TokenT const& t) Chris@16: { return t; } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'may_skip_whitespace' will be called by the Chris@16: // library, whenever it must be tested whether a specific token refers to Chris@16: // whitespace and this whitespace has to be skipped. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The 'token' parameter holds a reference to the current token. The policy Chris@16: // is free to change this token if needed. Chris@16: // Chris@16: // The 'skipped_newline' parameter holds a reference to a boolean value Chris@16: // which should be set to true by the policy function whenever a newline Chris@16: // is going to be skipped. Chris@16: // Chris@16: // If the return value is true, the given token is skipped and the Chris@16: // preprocessing continues to the next token. If the return value is Chris@16: // false, the given token is returned to the calling application. Chris@16: // Chris@16: // ATTENTION! Chris@16: // Caution has to be used, because by returning true the policy function Chris@16: // is able to force skipping even significant tokens, not only whitespace. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: bool Chris@16: may_skip_whitespace(ContextT const& ctx, TokenT& token, bool& skipped_newline) Chris@16: { return false; } Chris@16: Chris@16: #if BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE != 0 Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'found_warning_directive' will be called by the library Chris@16: // whenever a #warning directive is found. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'message' references the argument token sequence of the Chris@16: // encountered #warning directive. Chris@16: // Chris@16: // If the return value is false, the library throws a preprocessor Chris@16: // exception of the type 'warning_directive', if the return value is true Chris@16: // the execution continues as if no #warning directive has been found. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: bool Chris@16: found_warning_directive(ContextT const& ctx, ContainerT const& message) Chris@16: { return false; } Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'found_error_directive' will be called by the library Chris@16: // whenever a #error directive is found. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'message' references the argument token sequence of the Chris@16: // encountered #error directive. Chris@16: // Chris@16: // If the return value is false, the library throws a preprocessor Chris@16: // exception of the type 'error_directive', if the return value is true Chris@16: // the execution continues as if no #error directive has been found. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: bool Chris@16: found_error_directive(ContextT const& ctx, ContainerT const& message) Chris@16: { return false; } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'found_line_directive' will be called by the library Chris@16: // whenever a #line directive is found. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'arguments' references the argument token sequence of the Chris@16: // encountered #line directive. Chris@16: // Chris@16: // The parameter 'line' contains the recognized line number from the #line Chris@16: // directive. Chris@16: // Chris@16: // The parameter 'filename' references the recognized file name from the Chris@16: // #line directive (if there was one given). Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: void Chris@16: found_line_directive(ContextT const& ctx, ContainerT const& arguments, Chris@16: unsigned int line, std::string const& filename) Chris@16: {} Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The function 'throw_exception' will be called by the library whenever a Chris@16: // preprocessing exception occurs. Chris@16: // Chris@16: // The parameter 'ctx' is a reference to the context object used for Chris@16: // instantiating the preprocessing iterators by the user. Chris@16: // Chris@16: // The parameter 'e' is the exception object containing detailed error Chris@16: // information. Chris@16: // Chris@16: // The default behavior is to call the function boost::throw_exception. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: void Chris@16: throw_exception(ContextT const& ctx, ExceptionT const& e) Chris@16: { Chris@16: boost::throw_exception(e); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: } // namespace context_policies Chris@16: } // namespace wave Chris@16: } // namespace boost Chris@16: Chris@16: // the suffix header occurs after all of the code Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_SUFFIX Chris@16: #endif Chris@16: Chris@16: #endif // !defined(DEFAULT_PREPROCESSING_HOOKS_HPP_INCLUDED)