Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/wave/util/interpret_pragma.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /*============================================================================= | |
2 Boost.Wave: A Standard compliant C++ preprocessor library | |
3 | |
4 http://www.boost.org/ | |
5 | |
6 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost | |
7 Software License, Version 1.0. (See accompanying file | |
8 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 =============================================================================*/ | |
10 | |
11 #if !defined(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED) | |
12 #define INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED | |
13 | |
14 #include <string> | |
15 #include <list> | |
16 | |
17 #include <boost/spirit/include/classic_core.hpp> | |
18 #include <boost/spirit/include/classic_assign_actor.hpp> | |
19 #include <boost/spirit/include/classic_push_back_actor.hpp> | |
20 #include <boost/spirit/include/classic_confix.hpp> | |
21 | |
22 #include <boost/wave/wave_config.hpp> | |
23 | |
24 #include <boost/wave/util/pattern_parser.hpp> | |
25 #include <boost/wave/util/macro_helpers.hpp> | |
26 | |
27 #include <boost/wave/token_ids.hpp> | |
28 #include <boost/wave/cpp_exceptions.hpp> | |
29 #include <boost/wave/cpp_iteration_context.hpp> | |
30 #include <boost/wave/language_support.hpp> | |
31 | |
32 #if !defined(spirit_append_actor) | |
33 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor) | |
34 #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor) | |
35 #endif // !defined(spirit_append_actor) | |
36 | |
37 // this must occur after all of the includes and before any code appears | |
38 #ifdef BOOST_HAS_ABI_HEADERS | |
39 #include BOOST_ABI_PREFIX | |
40 #endif | |
41 | |
42 /////////////////////////////////////////////////////////////////////////////// | |
43 namespace boost { | |
44 namespace wave { | |
45 namespace util { | |
46 | |
47 /////////////////////////////////////////////////////////////////////////////// | |
48 // | |
49 // The function interpret_pragma interprets the given token sequence as the | |
50 // body of a #pragma directive (or parameter to the _Pragma operator) and | |
51 // executes the actions associated with recognized Wave specific options. | |
52 // | |
53 /////////////////////////////////////////////////////////////////////////////// | |
54 template <typename ContextT, typename IteratorT, typename ContainerT> | |
55 inline bool | |
56 interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token, | |
57 IteratorT it, IteratorT const &end, ContainerT &pending) | |
58 { | |
59 typedef typename ContextT::token_type token_type; | |
60 typedef typename token_type::string_type string_type; | |
61 | |
62 using namespace cpplexer; | |
63 if (T_IDENTIFIER == token_id(*it)) { | |
64 // check for pragma wave ... | |
65 if ((*it).get_value() == BOOST_WAVE_PRAGMA_KEYWORD) | |
66 { | |
67 // this is a wave specific option, it should have the form: | |
68 // | |
69 // #pragma command option(value) | |
70 // | |
71 // where | |
72 // 'command' is the value of the preprocessor constant | |
73 // BOOST_WAVE_PRAGMA_KEYWORD (defaults to "wave") and | |
74 // '(value)' is required only for some pragma directives (this is | |
75 // optional) | |
76 // | |
77 // All recognized #pragma operators are forwarded to the supplied | |
78 // preprocessing hook. | |
79 using namespace boost::spirit::classic; | |
80 token_type option; | |
81 ContainerT values; | |
82 | |
83 if (!parse (++it, end, | |
84 ( ch_p(T_IDENTIFIER) | |
85 [ | |
86 spirit_assign_actor(option) | |
87 ] | |
88 | pattern_p(KeywordTokenType, | |
89 TokenTypeMask|PPTokenFlag) | |
90 [ | |
91 spirit_assign_actor(option) | |
92 ] | |
93 | pattern_p(OperatorTokenType|AltExtTokenType, | |
94 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc. | |
95 [ | |
96 spirit_assign_actor(option) | |
97 ] | |
98 | pattern_p(BoolLiteralTokenType, | |
99 TokenTypeMask|PPTokenFlag) | |
100 [ | |
101 spirit_assign_actor(option) | |
102 ] | |
103 ) | |
104 >> !comment_nest_p( | |
105 ch_p(T_LEFTPAREN), | |
106 ch_p(T_RIGHTPAREN) | |
107 )[spirit_assign_actor(values)], | |
108 pattern_p(WhiteSpaceTokenType, TokenTypeMask|PPTokenFlag)).hit) | |
109 { | |
110 typename ContextT::string_type msg( | |
111 impl::as_string<string_type>(it, end)); | |
112 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, | |
113 ill_formed_pragma_option, | |
114 msg.c_str(), act_token.get_position()); | |
115 return false; | |
116 } | |
117 | |
118 // remove the falsely matched surrounding parenthesis's | |
119 if (values.size() >= 2) { | |
120 BOOST_ASSERT(T_LEFTPAREN == values.front() && T_RIGHTPAREN == values.back()); | |
121 values.erase(values.begin()); | |
122 typename ContainerT::reverse_iterator rit = values.rbegin(); | |
123 values.erase((++rit).base()); | |
124 } | |
125 | |
126 // decode the option (call the context_policy hook) | |
127 if (!ctx.get_hooks().interpret_pragma( | |
128 ctx.derived(), pending, option, values, act_token)) | |
129 { | |
130 // unknown #pragma option | |
131 string_type option_str ((*it).get_value()); | |
132 | |
133 option_str += option.get_value(); | |
134 if (values.size() > 0) { | |
135 option_str += "("; | |
136 option_str += impl::as_string(values); | |
137 option_str += ")"; | |
138 } | |
139 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, | |
140 ill_formed_pragma_option, | |
141 option_str.c_str(), act_token.get_position()); | |
142 return false; | |
143 } | |
144 return true; | |
145 } | |
146 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 | |
147 else if ((*it).get_value() == "once") { | |
148 // #pragma once | |
149 return ctx.add_pragma_once_header(act_token, ctx.get_current_filename()); | |
150 } | |
151 #endif | |
152 #if BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE != 0 | |
153 else if ((*it).get_value() == "message") { | |
154 // #pragma message(...) or #pragma message ... | |
155 using namespace boost::spirit::classic; | |
156 ContainerT values; | |
157 | |
158 if (!parse (++it, end, | |
159 ( ( ch_p(T_LEFTPAREN) | |
160 >> lexeme_d[ | |
161 *(anychar_p[spirit_append_actor(values)] - ch_p(T_RIGHTPAREN)) | |
162 ] | |
163 >> ch_p(T_RIGHTPAREN) | |
164 ) | |
165 | lexeme_d[ | |
166 *(anychar_p[spirit_append_actor(values)] - ch_p(T_NEWLINE)) | |
167 ] | |
168 ), | |
169 pattern_p(WhiteSpaceTokenType, TokenTypeMask|PPTokenFlag) | |
170 ).hit | |
171 ) | |
172 { | |
173 typename ContextT::string_type msg( | |
174 impl::as_string<string_type>(it, end)); | |
175 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, | |
176 ill_formed_pragma_message, | |
177 msg.c_str(), act_token.get_position()); | |
178 return false; | |
179 } | |
180 | |
181 // remove the falsely matched closing parenthesis/newline | |
182 if (values.size() > 0) { | |
183 BOOST_ASSERT(T_RIGHTPAREN == values.back() || T_NEWLINE == values.back()); | |
184 typename ContainerT::reverse_iterator rit = values.rbegin(); | |
185 values.erase((++rit).base()); | |
186 } | |
187 | |
188 // output the message itself | |
189 typename ContextT::string_type msg(impl::as_string(values)); | |
190 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception, | |
191 pragma_message_directive, | |
192 msg.c_str(), act_token.get_position()); | |
193 return false; | |
194 } | |
195 #endif | |
196 } | |
197 return false; | |
198 } | |
199 | |
200 /////////////////////////////////////////////////////////////////////////////// | |
201 } // namespace util | |
202 } // namespace wave | |
203 } // namespace boost | |
204 | |
205 // the suffix header occurs after all of the code | |
206 #ifdef BOOST_HAS_ABI_HEADERS | |
207 #include BOOST_ABI_SUFFIX | |
208 #endif | |
209 | |
210 #endif // !defined(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED) |