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)