| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 | /*=============================================================================    Boost.Wave: A Standard compliant C++ preprocessor library    http://www.boost.org/    Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost    Software License, Version 1.0. (See accompanying file    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#if !defined(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)#define INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED#include <string>#include <list>#include <boost/spirit/include/classic_core.hpp>#include <boost/spirit/include/classic_assign_actor.hpp>#include <boost/spirit/include/classic_push_back_actor.hpp>#include <boost/spirit/include/classic_confix.hpp>#include <boost/wave/wave_config.hpp>#include <boost/wave/util/pattern_parser.hpp>#include <boost/wave/util/macro_helpers.hpp>#include <boost/wave/token_ids.hpp>#include <boost/wave/cpp_exceptions.hpp>#include <boost/wave/cpp_iteration_context.hpp>#include <boost/wave/language_support.hpp>#if !defined(spirit_append_actor)#define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)#define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)#endif // !defined(spirit_append_actor)// this must occur after all of the includes and before any code appears#ifdef BOOST_HAS_ABI_HEADERS#include BOOST_ABI_PREFIX#endif///////////////////////////////////////////////////////////////////////////////namespace boost {namespace wave {namespace util {///////////////////////////////////////////////////////////////////////////////////  The function interpret_pragma interprets the given token sequence as the//  body of a #pragma directive (or parameter to the _Pragma operator) and//  executes the actions associated with recognized Wave specific options./////////////////////////////////////////////////////////////////////////////////template <typename ContextT, typename IteratorT, typename ContainerT>inline boolinterpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token,    IteratorT it, IteratorT const &end, ContainerT &pending){    typedef typename ContextT::token_type token_type;    typedef typename token_type::string_type string_type;    using namespace cpplexer;    if (T_IDENTIFIER == token_id(*it)) {    // check for pragma wave ...        if ((*it).get_value() == BOOST_WAVE_PRAGMA_KEYWORD)        {        //  this is a wave specific option, it should have the form:        //        //      #pragma command option(value)        //        //  where        //      'command' is the value of the preprocessor constant        //                BOOST_WAVE_PRAGMA_KEYWORD (defaults to "wave") and        //      '(value)' is required only for some pragma directives (this is        //                optional)        //        //  All recognized #pragma operators are forwarded to the supplied        //  preprocessing hook.            using namespace boost::spirit::classic;            token_type option;            ContainerT values;            if (!parse (++it, end,                            (   ch_p(T_IDENTIFIER)                                [                                    spirit_assign_actor(option)                                ]                            |   pattern_p(KeywordTokenType,                                    TokenTypeMask|PPTokenFlag)                                [                                    spirit_assign_actor(option)                                ]                            |   pattern_p(OperatorTokenType|AltExtTokenType,                                    ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.                                [                                    spirit_assign_actor(option)                                ]                            |   pattern_p(BoolLiteralTokenType,                                    TokenTypeMask|PPTokenFlag)                                [                                    spirit_assign_actor(option)                                ]                            )                        >> !comment_nest_p(                                ch_p(T_LEFTPAREN),                                ch_p(T_RIGHTPAREN)                            )[spirit_assign_actor(values)],                    pattern_p(WhiteSpaceTokenType, TokenTypeMask|PPTokenFlag)).hit)            {                typename ContextT::string_type msg(                    impl::as_string<string_type>(it, end));                BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,                    ill_formed_pragma_option,                    msg.c_str(), act_token.get_position());                return false;            }        // remove the falsely matched surrounding parenthesis's            if (values.size() >= 2) {                BOOST_ASSERT(T_LEFTPAREN == values.front() && T_RIGHTPAREN == values.back());                values.erase(values.begin());                typename ContainerT::reverse_iterator rit = values.rbegin();                values.erase((++rit).base());            }        // decode the option (call the context_policy hook)            if (!ctx.get_hooks().interpret_pragma(                  ctx.derived(), pending, option, values, act_token))            {            // unknown #pragma option            string_type option_str ((*it).get_value());                option_str += option.get_value();                if (values.size() > 0) {                    option_str += "(";                    option_str += impl::as_string(values);                    option_str += ")";                }                BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,                    ill_formed_pragma_option,                    option_str.c_str(), act_token.get_position());                return false;            }            return true;        }#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0        else if ((*it).get_value() == "once") {        // #pragma once            return ctx.add_pragma_once_header(act_token, ctx.get_current_filename());        }#endif#if BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE != 0        else if ((*it).get_value() == "message") {        // #pragma message(...) or #pragma message ...            using namespace boost::spirit::classic;            ContainerT values;            if (!parse (++it, end,                            (   (   ch_p(T_LEFTPAREN)                                >>  lexeme_d[                                        *(anychar_p[spirit_append_actor(values)] - ch_p(T_RIGHTPAREN))                                    ]                                >>  ch_p(T_RIGHTPAREN)                                )                            |   lexeme_d[                                    *(anychar_p[spirit_append_actor(values)] - ch_p(T_NEWLINE))                                ]                            ),                            pattern_p(WhiteSpaceTokenType, TokenTypeMask|PPTokenFlag)                       ).hit               )            {                typename ContextT::string_type msg(                    impl::as_string<string_type>(it, end));                BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,                    ill_formed_pragma_message,                    msg.c_str(), act_token.get_position());                return false;            }        // remove the falsely matched closing parenthesis/newline            if (values.size() > 0) {                BOOST_ASSERT(T_RIGHTPAREN == values.back() || T_NEWLINE == values.back());                typename ContainerT::reverse_iterator rit = values.rbegin();                values.erase((++rit).base());            }        // output the message itself            typename ContextT::string_type msg(impl::as_string(values));            BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,                pragma_message_directive,                msg.c_str(), act_token.get_position());            return false;        }#endif    }    return false;}///////////////////////////////////////////////////////////////////////////////}   // namespace util}   // namespace wave}   // namespace boost// the suffix header occurs after all of the code#ifdef BOOST_HAS_ABI_HEADERS#include BOOST_ABI_SUFFIX#endif#endif // !defined(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED)
 |