Mercurial > hg > vamp-build-and-test
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/wave/util/interpret_pragma.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,210 @@ +/*============================================================================= + 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 bool +interpret_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)