123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873 |
- /*=============================================================================
- 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)
- =============================================================================*/
- #if !defined(BOOST_WAVE_LIBS_WAVE_TEST_COLLECT_HOOKS_INFORMATION_HPP)
- #define BOOST_WAVE_LIBS_WAVE_TEST_COLLECT_HOOKS_INFORMATION_HPP
- #include <boost/config.hpp>
- #include <boost/lexical_cast.hpp>
- #include <boost/filesystem/path.hpp>
- #include <boost/filesystem/operations.hpp>
- ///////////////////////////////////////////////////////////////////////////////
- // workaround for missing ostringstream
- #ifdef BOOST_NO_STRINGSTREAM
- #include <strstream>
- #define BOOST_WAVETEST_OSSTREAM std::ostrstream
- std::string BOOST_WAVETEST_GETSTRING(std::ostrstream& ss)
- {
- ss << ends;
- std::string rval = ss.str();
- ss.freeze(false);
- return rval;
- }
- #else
- #include <sstream>
- #define BOOST_WAVETEST_GETSTRING(ss) ss.str()
- #define BOOST_WAVETEST_OSSTREAM std::ostringstream
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- template <typename String>
- String handle_filepath(String const &name)
- {
- using boost::wave::util::impl::unescape_lit;
-
- String unesc_name (unescape_lit(name));
- typename String::size_type p = unesc_name.find_last_of("/\\");
- if (p != unesc_name.npos)
- unesc_name = unesc_name.substr(p+1);
- return unesc_name;
- }
- ///////////////////////////////////////////////////////////////////////////////
- template <typename String>
- inline String repr(boost::wave::util::file_position<String> const& pos)
- {
- std::string linenum = boost::lexical_cast<std::string>(pos.get_line());
- return handle_filepath(pos.get_file()) + String("(") + linenum.c_str() + ")";
- }
- template <typename String>
- inline String repr(String const& value)
- {
- String result;
- typename String::const_iterator end = value.end();
- for (typename String::const_iterator it = value.begin(); it != end; ++it)
- {
- typedef typename String::value_type char_type;
- char_type c = *it;
- if (c == static_cast<char_type>('\a'))
- result.append("\\a");
- else if (c == static_cast<char_type>('\b'))
- result.append("\\b");
- else if (c == static_cast<char_type>('\f'))
- result.append("\\f");
- else if (c == static_cast<char_type>('\n'))
- result.append("\\n");
- else if (c == static_cast<char_type>('\r'))
- result.append("\\r");
- else if (c == static_cast<char_type>('\t'))
- result.append("\\t");
- else if (c == static_cast<char_type>('\v'))
- result.append("\\v");
- else
- result += static_cast<char_type>(c);
- }
- return result;
- }
- #if defined(BOOST_WINDOWS)
- template <typename String>
- inline String replace_slashes(String value, char const* lookfor = "\\",
- char replace_with = '/')
- {
- typename String::size_type p = value.find_first_of(lookfor);
- while (p != value.npos) {
- value[p] = replace_with;
- p = value.find_first_of(lookfor, p+1);
- }
- return value;
- }
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- template <typename Token>
- class collect_hooks_information
- : public boost::wave::context_policies::eat_whitespace<Token>
- {
- typedef boost::wave::context_policies::eat_whitespace<Token> base_type;
- public:
- collect_hooks_information(std::string& trace)
- : hooks_trace(trace), skipped_token_hooks(false)
- {}
- void set_skipped_token_hooks(bool flag)
- {
- skipped_token_hooks = flag;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'expanding_function_like_macro' is called, whenever a
- // function-like macro is to be expanded.
- //
- // 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
- // trace.
- //
- // The parameter 'macro_call' marks the position, where this macro invoked.
- //
- // The parameter 'arguments' holds the macro arguments used during the
- // invocation of the macro
- //
- // 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
- // 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.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container, typename Iterator>
- bool
- expanding_function_like_macro(Context const& ctx,
- Token const& macro, std::vector<Token> const& formal_args,
- Container const& definition,
- Token const& macrocall, std::vector<Container> const& arguments,
- Iterator const& seqstart, Iterator const& seqend)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- // trace real macro call
- strm << "00: " << repr(macrocall.get_position()) << ": "
- << macrocall.get_value() << "(";
- for (typename std::vector<Token>::size_type i = 0;
- i < arguments.size(); ++i)
- {
- strm << boost::wave::util::impl::as_string(arguments[i]);
- if (i < arguments.size()-1)
- strm << ",";
- }
- strm << "), ";
-
- // trace macro definition
- strm << "[" << repr(macro.get_position()) << ": "
- << macro.get_value() << "(";
- for (typename std::vector<Token>::size_type i = 0;
- i < formal_args.size(); ++i)
- {
- strm << formal_args[i].get_value();
- if (i < formal_args.size()-1)
- strm << ", ";
- }
- strm << ")=" << boost::wave::util::impl::as_string(definition) << "]"
- << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false; // default is to normally expand the macro
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // 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
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'macro' marks the position, where the macro to expand
- // is defined.
- //
- // The definition 'definition' holds the macro definition for the macro to
- // trace.
- //
- // The parameter 'macrocall' marks the position, where this macro invoked.
- //
- // The return value defines, whether the corresponding macro will be
- // expanded (return false) or will be copied to the output (return true).
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- bool
- expanding_object_like_macro(Context const& ctx, Token const& macro,
- Container const& definition, Token const& macrocall)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "01: " << repr(macro.get_position()) << ": "
- << macro.get_value() << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false; // default is to normally expand the macro
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // 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
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'result' contains the token sequence generated as the
- // result of the macro expansion.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- void expanded_macro(Context const& ctx, Container const& result)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "02: " << boost::wave::util::impl::as_string(result) << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // 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
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'result' contains the token sequence generated as the
- // result of the rescanning.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- void rescanned_macro(Context const& ctx, Container const& result)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "03: " << boost::wave::util::impl::as_string(result) << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'found_include_directive' is called, whenever a #include
- // directive was located.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'filename' contains the (expanded) file name found after
- // the #include directive. This has the format '<file>', '"file"' or
- // 'file'.
- // The formats '<file>' or '"file"' are used for #include directives found
- // in the preprocessed token stream, the format 'file' is used for files
- // specified through the --force_include command line argument.
- //
- // The parameter 'include_next' is set to true if the found directive was
- // a #include_next directive and the BOOST_WAVE_SUPPORT_INCLUDE_NEXT
- // preprocessing constant was defined to something != 0.
- //
- // The return value defines, whether the found file will be included
- // (return false) or will be skipped (return true).
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- bool
- found_include_directive(Context const& ctx, std::string filename,
- bool include_next)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "04: " << filename;
- if (include_next)
- strm << " (include_next)";
- strm << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false; // ok to include this file
- }
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // 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
- // 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
- // 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
- // found as a result of a #include <...> directive.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- void
- opened_include_file(Context const& ctx, std::string relname,
- std::string absname, bool is_system_include)
- {
- using boost::wave::util::impl::escape_lit;
- #if defined(BOOST_WINDOWS)
- relname = replace_slashes(relname);
- absname = replace_slashes(absname);
- #endif
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "05: " << escape_lit(relname)
- << " (" << escape_lit(absname) << ")" << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'returning_from_include_file' is called, whenever an
- // included file is about to be closed after it's processing is complete.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- void
- returning_from_include_file(Context const& ctx)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "06: " << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // 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
- // 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
- // #pragma directive.
- //
- // The parameter 'option' contains the name of the interpreted pragma.
- //
- // 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
- // be used for error output.
- //
- // 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
- // #pragma.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- bool
- interpret_pragma(Context const& ctx, Container &pending,
- Token const& option, Container const& values, Token const& act_token)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "07: " << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'defined_macro' is called, whenever a macro was defined
- // successfully.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'name' is a reference to the token holding the macro name.
- //
- // The parameter 'is_functionlike' is set to true, whenever the newly
- // defined macro is defined as a function like macro.
- //
- // The parameter 'parameters' holds the parameter tokens for the macro
- // definition. If the macro has no parameters or if it is a object like
- // macro, then this container is empty.
- //
- // The parameter 'definition' contains the token sequence given as the
- // replacement sequence (definition part) of the newly defined macro.
- //
- // The parameter 'is_predefined' is set to true for all macros predefined
- // during the initialization phase of the library.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- void
- defined_macro(Context const& ctx, Token const& macro,
- bool is_functionlike, std::vector<Token> const& pars,
- Container const& definition, bool is_predefined)
- {
- // do not trace the definition of the internal helper macros
- if (!is_predefined) {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "08: " << repr(macro.get_position()) << ": "
- << macro.get_value();
- if (is_functionlike) {
- // list the parameter names for function style macros
- strm << "(";
- for (typename std::vector<Token>::size_type i = 0;
- i < pars.size(); ++i)
- {
- strm << pars[i].get_value();
- if (i < pars.size()-1)
- strm << ", ";
- }
- strm << ")";
- }
- strm << "=" << boost::wave::util::impl::as_string(definition)
- << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'undefined_macro' is called, whenever a macro definition
- // was removed successfully.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'name' holds the name of the macro, which definition was
- // removed.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- void
- undefined_macro(Context const& ctx, Token const& macro)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "09: " << repr(macro.get_position()) << ": "
- << macro.get_value() << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'found_directive' is called, whenever a preprocessor
- // directive was encountered, but before the corresponding action is
- // executed.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'directive' is a reference to the token holding the
- // preprocessing directive.
- //
- // The return value defines, whether the given expression has to be
- // to be executed in a normal way (return 'false'), or if it has to be
- // skipped altogether (return 'true'), which means it gets replaced in the
- // output by a single newline.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- bool
- found_directive(Context const& ctx, Token const& directive)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "10: " << repr(directive.get_position()) << ": "
- << directive.get_value() << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false; // by default we never skip any directives
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'evaluated_conditional_expression' is called, whenever a
- // conditional preprocessing expression was evaluated (the expression
- // given to a #if, #elif, #ifdef or #ifndef directive)
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'directive' is a reference to the token holding the
- // corresponding preprocessing directive.
- //
- // The parameter 'expression' holds the non-expanded token sequence
- // comprising the evaluated expression.
- //
- // The parameter expression_value contains the result of the evaluation of
- // the expression in the current preprocessing context.
- //
- // The return value defines, whether the given expression has to be
- // evaluated again, allowing to decide which of the conditional branches
- // should be expanded. You need to return 'true' from this hook function
- // to force the expression to be re-evaluated.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- bool
- evaluated_conditional_expression(Context const& ctx,
- Token const& directive, Container const& expression,
- bool expression_value)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "11: " << repr(directive.get_position()) << ": "
- << directive.get_value() << " "
- << boost::wave::util::impl::as_string(expression) << ": "
- << expression_value << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false; // ok to continue, do not re-evaluate expression
- }
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'skipped_token' is called, whenever a token is about to be
- // skipped due to a false preprocessor condition (code fragments to be
- // skipped inside the not evaluated conditional #if/#else/#endif branches).
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'token' refers to the token to be skipped.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- void
- skipped_token(Context const& ctx, Token const& token)
- {
- // this normally generates a lot of noise
- if (skipped_token_hooks) {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "12: " << repr(token.get_position()) << ": >"
- << repr(token.get_value()) << "<" << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'generated_token' will be called by the library whenever a
- // token is about to be returned from the library.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 't' is the token about to be returned from the library.
- // This function may alter the token, but in this case it must be
- // implemented with a corresponding signature:
- //
- // Token const&
- // generated_token(Context const& ctx, Token& t);
- //
- // which makes it possible to modify the token in place.
- //
- // The default behavior is to return the token passed as the parameter
- // without modification.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- Token const&
- generated_token(Context const& ctx, Token const& t)
- {
- // this generates a lot of noise
- // BOOST_WAVETEST_OSSTREAM strm;
- // strm << "13: " << std::endl;
- // hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return t;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'may_skip_whitespace' will be called by the
- // library, whenever it must be tested whether a specific token refers to
- // whitespace and this whitespace has to be skipped.
- //
- // 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
- // 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.
- //
- // 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.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- bool
- may_skip_whitespace(Context const& ctx, Token& token, bool& skipped_newline)
- {
- // this generates a lot of noise
- // BOOST_WAVETEST_OSSTREAM strm;
- // strm << "14: " << std::endl;
- // hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return this->base_type::may_skip_whitespace(ctx, token, skipped_newline);
- }
- #if BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE != 0
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'found_warning_directive' will be called by the library
- // whenever a #warning directive is found.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'message' references the argument token sequence of the
- // encountered #warning directive.
- //
- // If the return value is false, the library throws a preprocessor
- // exception of the type 'warning_directive', if the return value is true
- // the execution continues as if no #warning directive has been found.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- bool
- found_warning_directive(Context const& ctx, Container const& message)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "15: " << boost::wave::util::impl::as_string(message)
- << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false;
- }
- #endif
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'found_error_directive' will be called by the library
- // whenever a #error directive is found.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'message' references the argument token sequence of the
- // encountered #error directive.
- //
- // If the return value is false, the library throws a preprocessor
- // exception of the type 'error_directive', if the return value is true
- // the execution continues as if no #error directive has been found.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- bool
- found_error_directive(Context const& ctx, Container const& message)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "16: " << boost::wave::util::impl::as_string(message)
- << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'found_line_directive' will be called by the library
- // whenever a #line directive is found.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'arguments' references the argument token sequence of the
- // encountered #line directive.
- //
- // The parameter 'line' contains the recognized line number from the #line
- // directive.
- //
- // The parameter 'filename' references the recognized file name from the
- // #line directive (if there was one given).
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Container>
- void
- found_line_directive(Context const& ctx, Container const& arguments,
- unsigned int line, std::string const& filename)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "17: " << boost::wave::util::impl::as_string(arguments)
- << " (" << line << ", \"" << filename << "\")" << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // 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
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'e' is the exception object containing detailed error
- // information.
- //
- // The default behavior is to call the function boost::throw_exception.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context, typename Exception>
- void
- throw_exception(Context const& ctx, Exception const& e)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "18: " << e.what() << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return this->base_type::throw_exception(ctx, e);
- }
- #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
- // 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
- // '#' tokens before the #if/#ifndef and after the final #endif.
- //
- // 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
- // processed file or a absolute path depending on the paths given as the
- // include search paths).
- //
- // The parameter contains the name of the detected include guard.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename ContextT>
- void
- detected_include_guard(ContextT const& ctx, std::string filename,
- std::string const& include_guard)
- {
- using boost::wave::util::impl::escape_lit;
- #if defined(BOOST_WINDOWS)
- filename = replace_slashes(filename);
- #endif
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "19: " << escape_lit(filename) << ": "
- << include_guard << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'detected_pragma_once' 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 directive
- // #pragma once.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter pragma_token refers to the token "#pragma" triggering
- // this preprocessing hook.
- //
- // 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).
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename ContextT, typename TokenT>
- void
- detected_pragma_once(ContextT const& ctx, TokenT const& pragma_token,
- std::string filename)
- {
- using boost::wave::util::impl::escape_lit;
- #if defined(BOOST_WINDOWS)
- filename = replace_slashes(filename);
- #endif
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "20: " << repr(pragma_token.get_position()) << ": "
- << pragma_token.get_value() << ": "
- << escape_lit(filename) << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- }
- #endif
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'found_unknown_directive' is called, whenever an unknown
- // preprocessor directive was encountered.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 'line' holds the tokens of the entire source line
- // containing the unknown directive.
- //
- // 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
- // line containing the unknown directive.
- //
- // The return value defines, whether the given expression has been
- // properly interpreted by the hook function or not. If this function
- // returns 'false', the library will raise an 'ill_formed_directive'
- // preprocess_exception. Otherwise the tokens pushed back into 'pending'
- // are passed on to the user program.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename ContextT, typename ContainerT>
- bool
- found_unknown_directive(ContextT const& ctx, ContainerT const& line,
- ContainerT& pending)
- {
- BOOST_WAVETEST_OSSTREAM strm;
- strm << "21: " << repr((*line.begin()).get_position()) << ": "
- << boost::wave::util::impl::as_string(line) << std::endl;
- hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
- return false;
- }
- private:
- std::string& hooks_trace;
- bool skipped_token_hooks;
- };
- #endif
|