|
1 /*============================================================================= |
|
2 Boost.Wave: A Standard compliant C++ preprocessor library |
|
3 Definition of the preprocessor context |
|
4 |
|
5 http://www.boost.org/ |
|
6 |
|
7 Copyright (c) 2001-2007 Hartmut Kaiser. Distributed under the Boost |
|
8 Software License, Version 1.0. (See accompanying file |
|
9 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
|
10 =============================================================================*/ |
|
11 |
|
12 #if !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED) |
|
13 #define CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED |
|
14 |
|
15 #include <iterator> |
|
16 #include <fstream> |
|
17 #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) |
|
18 #include <sstream> |
|
19 #endif |
|
20 |
|
21 #include <boost/wave/wave_config.hpp> |
|
22 #include <boost/wave/cpp_exceptions.hpp> |
|
23 #include <boost/wave/language_support.hpp> |
|
24 #include <boost/wave/util/file_position.hpp> |
|
25 |
|
26 // this must occur after all of the includes and before any code appears |
|
27 #ifdef BOOST_HAS_ABI_HEADERS |
|
28 #include BOOST_ABI_PREFIX |
|
29 #endif |
|
30 |
|
31 /////////////////////////////////////////////////////////////////////////////// |
|
32 namespace boost { |
|
33 namespace wave { |
|
34 namespace iteration_context_policies { |
|
35 |
|
36 /////////////////////////////////////////////////////////////////////////////// |
|
37 // |
|
38 // The iteration_context_policies templates are policies for the |
|
39 // boost::wave::iteration_context which allows to control, how a given input file |
|
40 // is to be represented by a pair of iterators pointing to the begin and |
|
41 // the end of the resulting input sequence. |
|
42 // |
|
43 /////////////////////////////////////////////////////////////////////////////// |
|
44 |
|
45 /////////////////////////////////////////////////////////////////////////// |
|
46 // |
|
47 // load_file_to_string |
|
48 // |
|
49 // Loads a file into a string and returns the iterators pointing to |
|
50 // the beginning and the end of the loaded string. |
|
51 // |
|
52 /////////////////////////////////////////////////////////////////////////// |
|
53 struct load_file_to_string |
|
54 { |
|
55 template <typename IterContextT> |
|
56 class inner |
|
57 { |
|
58 public: |
|
59 template <typename PositionT> |
|
60 static |
|
61 void init_iterators(IterContextT &iter_ctx, |
|
62 PositionT const &act_pos) |
|
63 { |
|
64 typedef typename IterContextT::iterator_type iterator_type; |
|
65 |
|
66 std::ifstream instream(iter_ctx.filename.c_str()); |
|
67 if (!instream.is_open()) { |
|
68 BOOST_WAVE_THROW(preprocess_exception, bad_include_file, |
|
69 iter_ctx.filename.c_str(), act_pos); |
|
70 } |
|
71 instream.unsetf(std::ios::skipws); |
|
72 |
|
73 #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) |
|
74 // this is known to be very slow for large files on some systems |
|
75 std::copy (istream_iterator<char>(instream), |
|
76 istream_iterator<char>(), |
|
77 std::inserter(iter_ctx.instring, iter_ctx.instring.end())); |
|
78 #else |
|
79 iter_ctx.instring = std::string( |
|
80 std::istreambuf_iterator<char>(instream.rdbuf()), |
|
81 std::istreambuf_iterator<char>()); |
|
82 #endif // defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) |
|
83 |
|
84 iter_ctx.first = iterator_type(iter_ctx.instring.begin(), |
|
85 iter_ctx.instring.end(), PositionT(iter_ctx.filename), |
|
86 iter_ctx.language); |
|
87 iter_ctx.last = iterator_type(); |
|
88 } |
|
89 |
|
90 private: |
|
91 std::string instring; |
|
92 }; |
|
93 }; |
|
94 |
|
95 /////////////////////////////////////////////////////////////////////////////// |
|
96 // |
|
97 // load_file |
|
98 // |
|
99 // The load_file policy opens a given file and returns the wrapped |
|
100 // istreambuf_iterators. |
|
101 // |
|
102 /////////////////////////////////////////////////////////////////////////////// |
|
103 struct load_file |
|
104 { |
|
105 template <typename IterContextT> |
|
106 class inner { |
|
107 |
|
108 public: |
|
109 ~inner() { if (instream.is_open()) instream.close(); } |
|
110 |
|
111 template <typename PositionT> |
|
112 static |
|
113 void init_iterators(IterContextT &iter_ctx, |
|
114 PositionT const &act_pos) |
|
115 { |
|
116 typedef typename IterContextT::iterator_type iterator_type; |
|
117 |
|
118 iter_ctx.instream.open(iter_ctx.filename.c_str()); |
|
119 if (!iter_ctx.instream.is_open()) { |
|
120 BOOST_WAVE_THROW(preprocess_exception, bad_include_file, |
|
121 iter_ctx.filename.c_str(), act_pos); |
|
122 } |
|
123 iter_ctx.instream.unsetf(std::ios::skipws); |
|
124 |
|
125 using boost::spirit::make_multi_pass; |
|
126 iter_ctx.first = iterator_type( |
|
127 make_multi_pass(std::istreambuf_iterator<char>( |
|
128 iter_ctx.instream.rdbuf())), |
|
129 make_multi_pass(std::istreambuf_iterator<char>()), |
|
130 PositionT(iter_ctx.filename), iter_ctx.language); |
|
131 iter_ctx.last = iterator_type(); |
|
132 } |
|
133 |
|
134 private: |
|
135 std::ifstream instream; |
|
136 }; |
|
137 }; |
|
138 |
|
139 } // namespace iteration_context_policies |
|
140 |
|
141 /////////////////////////////////////////////////////////////////////////////// |
|
142 // |
|
143 template <typename IteratorT> |
|
144 struct base_iteration_context |
|
145 { |
|
146 public: |
|
147 base_iteration_context( |
|
148 BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0) |
|
149 : real_filename(fname), filename(fname), line(1), emitted_lines(1), |
|
150 if_block_depth(if_block_depth) |
|
151 {} |
|
152 base_iteration_context(IteratorT const &first_, IteratorT const &last_, |
|
153 BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0) |
|
154 : first(first_), last(last_), real_filename(fname), filename(fname), |
|
155 line(1), emitted_lines(1), if_block_depth(if_block_depth) |
|
156 {} |
|
157 |
|
158 // the actual input stream |
|
159 IteratorT first; // actual input stream position |
|
160 IteratorT last; // end of input stream |
|
161 BOOST_WAVE_STRINGTYPE real_filename; // real name of the current file |
|
162 BOOST_WAVE_STRINGTYPE filename; // actual processed file |
|
163 unsigned int line; // line counter of underlying stream |
|
164 unsigned int emitted_lines; // count of emitted newlines |
|
165 std::size_t if_block_depth; // depth of #if block recursion |
|
166 }; |
|
167 |
|
168 /////////////////////////////////////////////////////////////////////////////// |
|
169 // |
|
170 template < |
|
171 typename IteratorT, |
|
172 typename InputPolicyT = iteration_context_policies::load_file_to_string |
|
173 > |
|
174 struct iteration_context |
|
175 : public base_iteration_context<IteratorT>, |
|
176 public InputPolicyT::template |
|
177 inner<iteration_context<IteratorT, InputPolicyT> > |
|
178 { |
|
179 typedef IteratorT iterator_type; |
|
180 typedef typename IteratorT::token_type::position_type position_type; |
|
181 |
|
182 typedef iteration_context<IteratorT, InputPolicyT> self_type; |
|
183 |
|
184 iteration_context(BOOST_WAVE_STRINGTYPE const &fname, |
|
185 position_type const &act_pos, |
|
186 boost::wave::language_support language_) |
|
187 : base_iteration_context<IteratorT>(fname), |
|
188 language(language_) |
|
189 { |
|
190 InputPolicyT::template inner<self_type>::init_iterators(*this, act_pos); |
|
191 } |
|
192 |
|
193 boost::wave::language_support language; |
|
194 }; |
|
195 |
|
196 /////////////////////////////////////////////////////////////////////////////// |
|
197 } // namespace wave |
|
198 } // namespace boost |
|
199 |
|
200 // the suffix header occurs after all of the code |
|
201 #ifdef BOOST_HAS_ABI_HEADERS |
|
202 #include BOOST_ABI_SUFFIX |
|
203 #endif |
|
204 |
|
205 #endif // !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED) |