cpp_iteration_context.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. Definition of the preprocessor context
  4. http://www.boost.org/
  5. Copyright (c) 2001-2012 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. #if !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED)
  10. #define CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED
  11. #include <iterator>
  12. #include <boost/filesystem/fstream.hpp>
  13. #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
  14. #include <sstream>
  15. #endif
  16. #include <boost/wave/wave_config.hpp>
  17. #include <boost/wave/cpp_exceptions.hpp>
  18. #include <boost/wave/language_support.hpp>
  19. #include <boost/wave/util/file_position.hpp>
  20. // #include <boost/spirit/include/iterator/classic_multi_pass.hpp> // make_multi_pass
  21. // this must occur after all of the includes and before any code appears
  22. #ifdef BOOST_HAS_ABI_HEADERS
  23. #include BOOST_ABI_PREFIX
  24. #endif
  25. ///////////////////////////////////////////////////////////////////////////////
  26. namespace boost {
  27. namespace wave {
  28. namespace iteration_context_policies {
  29. ///////////////////////////////////////////////////////////////////////////////
  30. //
  31. // The iteration_context_policies templates are policies for the
  32. // boost::wave::iteration_context which allows to control, how a given
  33. // input file is to be represented by a pair of iterators pointing to the
  34. // begin and the end of the resulting input sequence.
  35. //
  36. ///////////////////////////////////////////////////////////////////////////////
  37. ///////////////////////////////////////////////////////////////////////////
  38. //
  39. // load_file_to_string
  40. //
  41. // Loads a file into a string and returns the iterators pointing to
  42. // the beginning and the end of the loaded string.
  43. //
  44. ///////////////////////////////////////////////////////////////////////////
  45. struct load_file_to_string
  46. {
  47. template <typename IterContextT>
  48. class inner
  49. {
  50. public:
  51. template <typename PositionT>
  52. static void init_iterators(IterContextT &iter_ctx,
  53. PositionT const &act_pos, language_support language)
  54. {
  55. typedef typename IterContextT::iterator_type iterator_type;
  56. // read in the file
  57. boost::filesystem::ifstream instream(iter_ctx.filename.c_str());
  58. if (!instream.is_open()) {
  59. BOOST_WAVE_THROW_CTX(iter_ctx.ctx, preprocess_exception,
  60. bad_include_file, iter_ctx.filename.c_str(), act_pos);
  61. return;
  62. }
  63. instream.unsetf(std::ios::skipws);
  64. iter_ctx.instring.assign(
  65. std::istreambuf_iterator<char>(instream.rdbuf()),
  66. std::istreambuf_iterator<char>());
  67. iter_ctx.first = iterator_type(
  68. iter_ctx.instring.begin(), iter_ctx.instring.end(),
  69. PositionT(iter_ctx.filename), language);
  70. iter_ctx.last = iterator_type();
  71. }
  72. private:
  73. std::string instring;
  74. };
  75. };
  76. } // namespace iteration_context_policies
  77. ///////////////////////////////////////////////////////////////////////////////
  78. // Base class for iteration contexts
  79. template <typename ContextT, typename IteratorT>
  80. struct base_iteration_context
  81. {
  82. enum file_type
  83. {
  84. // this iteration context handles ...
  85. main_file, // ... the main preprocessed file
  86. system_header, // ... a header file included used #include <>
  87. user_header // ... a header file included using #include ""
  88. };
  89. base_iteration_context(ContextT& ctx_,
  90. BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0)
  91. : real_filename(fname), real_relative_filename(fname), filename(fname),
  92. line(1), emitted_lines(0), if_block_depth(if_block_depth), ctx(ctx_),
  93. type(main_file)
  94. {}
  95. base_iteration_context(ContextT& ctx_,
  96. IteratorT const &first_, IteratorT const &last_,
  97. BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0,
  98. file_type type_ = main_file)
  99. : first(first_), last(last_), real_filename(fname),
  100. real_relative_filename(fname), filename(fname),
  101. line(1), emitted_lines(0), if_block_depth(if_block_depth), ctx(ctx_),
  102. type(type_)
  103. {}
  104. // the actual input stream
  105. IteratorT first; // actual input stream position
  106. IteratorT last; // end of input stream
  107. BOOST_WAVE_STRINGTYPE real_filename; // real name of the current file
  108. BOOST_WAVE_STRINGTYPE real_relative_filename; // real relative name of the current file
  109. BOOST_WAVE_STRINGTYPE filename; // actual processed file
  110. std::size_t line; // line counter of underlying stream
  111. std::size_t emitted_lines; // count of emitted newlines
  112. std::size_t if_block_depth; // depth of #if block recursion
  113. ContextT& ctx; // corresponding context<> object
  114. file_type type; // the type of the handled file
  115. };
  116. ///////////////////////////////////////////////////////////////////////////////
  117. //
  118. template <
  119. typename ContextT, typename IteratorT,
  120. typename InputPolicyT = typename ContextT::input_policy_type
  121. >
  122. struct iteration_context
  123. : public base_iteration_context<ContextT, IteratorT>,
  124. public InputPolicyT::template
  125. inner<iteration_context<ContextT, IteratorT, InputPolicyT> >
  126. {
  127. typedef IteratorT iterator_type;
  128. typedef typename IteratorT::token_type::position_type position_type;
  129. typedef base_iteration_context<ContextT, IteratorT> base_type;
  130. typedef iteration_context<ContextT, IteratorT, InputPolicyT> self_type;
  131. iteration_context(ContextT& ctx, BOOST_WAVE_STRINGTYPE const &fname,
  132. position_type const &act_pos,
  133. boost::wave::language_support language_,
  134. typename base_type::file_type type = base_type::main_file)
  135. : base_iteration_context<ContextT, IteratorT>(ctx, fname, type)
  136. {
  137. InputPolicyT::template inner<self_type>::init_iterators(
  138. *this, act_pos, language_);
  139. }
  140. };
  141. ///////////////////////////////////////////////////////////////////////////////
  142. } // namespace wave
  143. } // namespace boost
  144. // the suffix header occurs after all of the code
  145. #ifdef BOOST_HAS_ABI_HEADERS
  146. #include BOOST_ABI_SUFFIX
  147. #endif
  148. #endif // !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED)