Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:43

0001 /*=============================================================================
0002     Boost.Wave: A Standard compliant C++ preprocessor library
0003 
0004     http://www.boost.org/
0005 
0006     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0007     Software License, Version 1.0. (See accompanying file
0008     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 =============================================================================*/
0010 
0011 #if !defined(BOOST_INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)
0012 #define BOOST_INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED
0013 
0014 #include <string>
0015 #include <list>
0016 
0017 #include <boost/spirit/include/classic_core.hpp>
0018 #include <boost/spirit/include/classic_assign_actor.hpp>
0019 #include <boost/spirit/include/classic_push_back_actor.hpp>
0020 #include <boost/spirit/include/classic_confix.hpp>
0021 
0022 #include <boost/wave/wave_config.hpp>
0023 
0024 #include <boost/wave/util/pattern_parser.hpp>
0025 #include <boost/wave/util/macro_helpers.hpp>
0026 
0027 #include <boost/wave/token_ids.hpp>
0028 #include <boost/wave/cpp_exceptions.hpp>
0029 #include <boost/wave/cpp_iteration_context.hpp>
0030 #include <boost/wave/language_support.hpp>
0031 
0032 #if !defined(spirit_append_actor)
0033 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
0034 #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
0035 #endif // !defined(spirit_append_actor)
0036 
0037 // this must occur after all of the includes and before any code appears
0038 #ifdef BOOST_HAS_ABI_HEADERS
0039 #include BOOST_ABI_PREFIX
0040 #endif
0041 
0042 ///////////////////////////////////////////////////////////////////////////////
0043 namespace boost {
0044 namespace wave {
0045 namespace util {
0046 
0047 ///////////////////////////////////////////////////////////////////////////////
0048 //
0049 //  The function interpret_pragma interprets the given token sequence as the
0050 //  body of a #pragma directive (or parameter to the _Pragma operator) and
0051 //  executes the actions associated with recognized Wave specific options.
0052 //
0053 ///////////////////////////////////////////////////////////////////////////////
0054 template <typename ContextT, typename IteratorT, typename ContainerT>
0055 inline bool
0056 interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token,
0057     IteratorT it, IteratorT const &end, ContainerT &pending)
0058 {
0059     typedef typename ContextT::token_type token_type;
0060     typedef typename token_type::string_type string_type;
0061 
0062     using namespace cpplexer;
0063     if (T_IDENTIFIER == token_id(*it)) {
0064     // check for pragma wave ...
0065         if ((*it).get_value() == BOOST_WAVE_PRAGMA_KEYWORD)
0066         {
0067         //  this is a wave specific option, it should have the form:
0068         //
0069         //      #pragma command option(value)
0070         //
0071         //  where
0072         //      'command' is the value of the preprocessor constant
0073         //                BOOST_WAVE_PRAGMA_KEYWORD (defaults to "wave") and
0074         //      '(value)' is required only for some pragma directives (this is
0075         //                optional)
0076         //
0077         //  All recognized #pragma operators are forwarded to the supplied
0078         //  preprocessing hook.
0079             using namespace boost::spirit::classic;
0080             token_type option;
0081             ContainerT values;
0082 
0083             if (!parse (++it, end,
0084                             (   ch_p(T_IDENTIFIER)
0085                                 [
0086                                     spirit_assign_actor(option)
0087                                 ]
0088                             |   pattern_p(KeywordTokenType,
0089                                     TokenTypeMask|PPTokenFlag)
0090                                 [
0091                                     spirit_assign_actor(option)
0092                                 ]
0093                             |   pattern_p(OperatorTokenType|AltExtTokenType,
0094                                     ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
0095                                 [
0096                                     spirit_assign_actor(option)
0097                                 ]
0098                             |   pattern_p(BoolLiteralTokenType,
0099                                     TokenTypeMask|PPTokenFlag)
0100                                 [
0101                                     spirit_assign_actor(option)
0102                                 ]
0103                             )
0104                         >> !comment_nest_p(
0105                                 ch_p(T_LEFTPAREN),
0106                                 ch_p(T_RIGHTPAREN)
0107                             )[spirit_assign_actor(values)],
0108                     pattern_p(WhiteSpaceTokenType, TokenTypeMask|PPTokenFlag)).hit)
0109             {
0110                 typename ContextT::string_type msg(
0111                     impl::as_string<string_type>(it, end));
0112                 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
0113                     ill_formed_pragma_option,
0114                     msg.c_str(), act_token.get_position());
0115                 return false;
0116             }
0117 
0118             // remove the falsely matched surrounding parenthesis's
0119             if (values.size() >= 2) {
0120                 BOOST_ASSERT(T_LEFTPAREN == values.front() && T_RIGHTPAREN == values.back());
0121                 values.erase(values.begin());
0122                 typename ContainerT::reverse_iterator rit = values.rbegin();
0123                 values.erase((++rit).base());
0124             }
0125 
0126             // decode the option (call the context_policy hook)
0127             if (!ctx.get_hooks().interpret_pragma(
0128                   ctx.derived(), pending, option, values, act_token))
0129             {
0130                 // unknown #pragma option
0131                 string_type option_str((*it).get_value());
0132 
0133                 option_str += option.get_value();
0134                 if (values.size() > 0) {
0135                     option_str += "(";
0136                     option_str += impl::as_string(values);
0137                     option_str += ")";
0138                 }
0139                 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
0140                     ill_formed_pragma_option,
0141                     option_str.c_str(), act_token.get_position());
0142                 return false;
0143             }
0144             return true;
0145         }
0146 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
0147         else if ((*it).get_value() == "once") {
0148             // #pragma once
0149             return ctx.add_pragma_once_header(act_token, ctx.get_current_filename());
0150         }
0151 #endif
0152 #if BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE != 0
0153         else if ((*it).get_value() == "message") {
0154             // #pragma message(...) or #pragma message ...
0155             using namespace boost::spirit::classic;
0156             ContainerT values;
0157 
0158             if (!parse (++it, end,
0159                             (   (   ch_p(T_LEFTPAREN)
0160                                 >>  lexeme_d[
0161                                         *(anychar_p[spirit_append_actor(values)] - ch_p(T_RIGHTPAREN))
0162                                     ]
0163                                 >>  ch_p(T_RIGHTPAREN)
0164                                 )
0165                             |   lexeme_d[
0166                                     *(anychar_p[spirit_append_actor(values)] - ch_p(T_NEWLINE))
0167                                 ]
0168                             ),
0169                             pattern_p(WhiteSpaceTokenType, TokenTypeMask|PPTokenFlag)
0170                        ).hit
0171                )
0172             {
0173                 typename ContextT::string_type msg(
0174                     impl::as_string<string_type>(it, end));
0175                 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
0176                     ill_formed_pragma_message,
0177                     msg.c_str(), act_token.get_position());
0178                 return false;
0179             }
0180 
0181             // remove the falsely matched closing parenthesis/newline
0182             if (values.size() > 0) {
0183                 BOOST_ASSERT(T_RIGHTPAREN == values.back() || T_NEWLINE == values.back());
0184                 typename ContainerT::reverse_iterator rit = values.rbegin();
0185                 values.erase((++rit).base());
0186             }
0187 
0188             // output the message itself
0189             typename ContextT::string_type msg(impl::as_string(values));
0190             BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
0191                 pragma_message_directive,
0192                 msg.c_str(), act_token.get_position());
0193             return false;
0194         }
0195 #endif
0196     }
0197     return false;
0198 }
0199 
0200 ///////////////////////////////////////////////////////////////////////////////
0201 }   // namespace util
0202 }   // namespace wave
0203 }   // namespace boost
0204 
0205 // the suffix header occurs after all of the code
0206 #ifdef BOOST_HAS_ABI_HEADERS
0207 #include BOOST_ABI_SUFFIX
0208 #endif
0209 
0210 #endif // !defined(BOOST_INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)