]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/wave/util/interpret_pragma.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / wave / util / interpret_pragma.hpp
CommitLineData
7c673cae
FG
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
20effc67
TL
11#if !defined(BOOST_INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)
12#define BOOST_INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED
7c673cae
FG
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///////////////////////////////////////////////////////////////////////////////
43namespace boost {
44namespace wave {
45namespace util {
46
47///////////////////////////////////////////////////////////////////////////////
48//
49// The function interpret_pragma interprets the given token sequence as the
b32b8144 50// body of a #pragma directive (or parameter to the _Pragma operator) and
7c673cae
FG
51// executes the actions associated with recognized Wave specific options.
52//
53///////////////////////////////////////////////////////////////////////////////
54template <typename ContextT, typename IteratorT, typename ContainerT>
b32b8144 55inline bool
7c673cae
FG
56interpret_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 ...
b32b8144 65 if ((*it).get_value() == BOOST_WAVE_PRAGMA_KEYWORD)
7c673cae
FG
66 {
67 // this is a wave specific option, it should have the form:
68 //
69 // #pragma command option(value)
70 //
b32b8144 71 // where
7c673cae
FG
72 // 'command' is the value of the preprocessor constant
73 // BOOST_WAVE_PRAGMA_KEYWORD (defaults to "wave") and
b32b8144 74 // '(value)' is required only for some pragma directives (this is
7c673cae
FG
75 // optional)
76 //
b32b8144 77 // All recognized #pragma operators are forwarded to the supplied
7c673cae
FG
78 // preprocessing hook.
79 using namespace boost::spirit::classic;
80 token_type option;
81 ContainerT values;
b32b8144
FG
82
83 if (!parse (++it, end,
7c673cae
FG
84 ( ch_p(T_IDENTIFIER)
85 [
86 spirit_assign_actor(option)
b32b8144
FG
87 ]
88 | pattern_p(KeywordTokenType,
7c673cae
FG
89 TokenTypeMask|PPTokenFlag)
90 [
91 spirit_assign_actor(option)
b32b8144
FG
92 ]
93 | pattern_p(OperatorTokenType|AltExtTokenType,
7c673cae
FG
94 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
95 [
96 spirit_assign_actor(option)
b32b8144
FG
97 ]
98 | pattern_p(BoolLiteralTokenType,
7c673cae
FG
99 TokenTypeMask|PPTokenFlag)
100 [
101 spirit_assign_actor(option)
b32b8144 102 ]
7c673cae
FG
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));
b32b8144 112 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
7c673cae
FG
113 ill_formed_pragma_option,
114 msg.c_str(), act_token.get_position());
115 return false;
116 }
117
20effc67 118 // remove the falsely matched surrounding parenthesis's
7c673cae
FG
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
20effc67 126 // decode the option (call the context_policy hook)
7c673cae 127 if (!ctx.get_hooks().interpret_pragma(
b32b8144 128 ctx.derived(), pending, option, values, act_token))
7c673cae 129 {
20effc67
TL
130 // unknown #pragma option
131 string_type option_str((*it).get_value());
7c673cae
FG
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 }
b32b8144 139 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
7c673cae
FG
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") {
20effc67 148 // #pragma once
7c673cae
FG
149 return ctx.add_pragma_once_header(act_token, ctx.get_current_filename());
150 }
b32b8144 151#endif
7c673cae
FG
152#if BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE != 0
153 else if ((*it).get_value() == "message") {
20effc67 154 // #pragma message(...) or #pragma message ...
7c673cae
FG
155 using namespace boost::spirit::classic;
156 ContainerT values;
157
b32b8144
FG
158 if (!parse (++it, end,
159 ( ( ch_p(T_LEFTPAREN)
7c673cae
FG
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));
b32b8144 175 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
7c673cae
FG
176 ill_formed_pragma_message,
177 msg.c_str(), act_token.get_position());
178 return false;
179 }
180
20effc67 181 // remove the falsely matched closing parenthesis/newline
7c673cae
FG
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
20effc67 188 // output the message itself
7c673cae 189 typename ContextT::string_type msg(impl::as_string(values));
b32b8144
FG
190 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
191 pragma_message_directive,
7c673cae
FG
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
20effc67 210#endif // !defined(BOOST_INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)