advanced_hooks.hpp 6.1 KB

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