1 /*============================================================================= 2 Boost.Wave: A Standard compliant C++ preprocessor library 3 http://www.boost.org/ 4 5 Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost 6 Software License, Version 1.0. (See accompanying file 7 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 10 #if !defined(BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED) 11 #define BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED 12 13 #include <cstdio> 14 #include <ostream> 15 #include <string> 16 17 #include <boost/assert.hpp> 18 #include <boost/config.hpp> 19 20 #include <boost/wave/token_ids.hpp> 21 #include <boost/wave/util/macro_helpers.hpp> 22 #include <boost/wave/preprocessing_hooks.hpp> 23 24 /////////////////////////////////////////////////////////////////////////////// 25 // 26 // The advanced_preprocessing_hooks policy class is used to register some 27 // of the more advanced (and probably more rarely used hooks with the Wave 28 // library. 29 // 30 // This policy type is used as a template parameter to the boost::wave::context<> 31 // object. 32 // 33 /////////////////////////////////////////////////////////////////////////////// 34 class advanced_preprocessing_hooks 35 : public boost::wave::context_policies::default_preprocessing_hooks 36 { 37 public: advanced_preprocessing_hooks()38 advanced_preprocessing_hooks() : need_comment(true) {} 39 40 /////////////////////////////////////////////////////////////////////////// 41 // 42 // The function 'found_directive' is called, whenever a preprocessor 43 // directive was encountered, but before the corresponding action is 44 // executed. 45 // 46 // The parameter 'ctx' is a reference to the context object used for 47 // instantiating the preprocessing iterators by the user. 48 // 49 // The parameter 'directive' is a reference to the token holding the 50 // preprocessing directive. 51 // 52 /////////////////////////////////////////////////////////////////////////// 53 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 54 template <typename TokenT> 55 void found_directive(TokenT const & directive)56 found_directive(TokenT const& directive) 57 #else 58 template <typename ContextT, typename TokenT> 59 bool 60 found_directive(ContextT const& ctx, TokenT const& directive) 61 #endif 62 { 63 // print the commented conditional directives 64 using namespace boost::wave; 65 token_id id = token_id(directive); 66 switch (id) { 67 case T_PP_IFDEF: 68 case T_PP_IFNDEF: 69 case T_PP_IF: 70 case T_PP_ELIF: 71 std::cout << "// " << directive.get_value() << " "; 72 need_comment = false; 73 break; 74 75 case T_PP_ELSE: 76 case T_PP_ENDIF: 77 std::cout << "// " << directive.get_value() << std::endl; 78 need_comment = true; 79 break; 80 81 default: 82 break; 83 } 84 85 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS == 0 86 return false; 87 #endif 88 } 89 90 /////////////////////////////////////////////////////////////////////////// 91 // 92 // The function 'evaluated_conditional_expression' is called, whenever a 93 // conditional preprocessing expression was evaluated (the expression 94 // given to a #if, #elif, #ifdef or #ifndef directive) 95 // 96 // The parameter 'ctx' is a reference to the context object used for 97 // instantiating the preprocessing iterators by the user. 98 // 99 // The parameter 'expression' holds the non-expanded token sequence 100 // comprising the evaluated expression. 101 // 102 // The parameter expression_value contains the result of the evaluation of 103 // the expression in the current preprocessing context. 104 // 105 // The return value defines, whether the given expression has to be 106 // evaluated again, allowing to decide which of the conditional branches 107 // should be expanded. You need to return 'true' from this hook function 108 // to force the expression to be re-evaluated. 109 // 110 /////////////////////////////////////////////////////////////////////////// 111 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 112 template <typename ContainerT> 113 bool evaluated_conditional_expression(ContainerT const & expression,bool expression_value)114 evaluated_conditional_expression( 115 ContainerT const& expression, bool expression_value) 116 #else 117 template <typename ContextT, typename TokenT, typename ContainerT> 118 bool 119 evaluated_conditional_expression(ContextT const &ctx, 120 TokenT const& directive, ContainerT const& expression, 121 bool expression_value) 122 #endif 123 { 124 // print the conditional expressions 125 std::cout << boost::wave::util::impl::as_string(expression) << std::endl; 126 need_comment = true; 127 return false; // ok to continue, do not re-evaluate expression 128 } 129 130 /////////////////////////////////////////////////////////////////////////// 131 // 132 // The function 'skipped_token' is called, whenever a token is about to be 133 // skipped due to a false preprocessor condition (code fragments to be 134 // skipped inside the not evaluated conditional #if/#else/#endif branches). 135 // 136 // The parameter 'ctx' is a reference to the context object used for 137 // instantiating the preprocessing iterators by the user. 138 // 139 // The parameter 'token' refers to the token to be skipped. 140 // 141 /////////////////////////////////////////////////////////////////////////// 142 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 143 template <typename TokenT> 144 void skipped_token(TokenT const & token)145 skipped_token(TokenT const& token) 146 #else 147 template <typename ContextT, typename TokenT> 148 void 149 skipped_token(ContextT const& ctx, TokenT const& token) 150 #endif 151 { 152 // prepend a comment at the beginning of all skipped lines 153 using namespace boost::wave; 154 if (need_comment && token_id(token) != T_SPACE) { 155 std::cout << "// "; 156 need_comment = false; 157 } 158 std::cout << token.get_value(); 159 if (token_id(token) == T_NEWLINE || token_id(token) == T_CPPCOMMENT) 160 need_comment = true; 161 } 162 163 private: 164 bool need_comment; 165 }; 166 167 #endif // !defined(BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED) 168