• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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