1
/*=============================================================================
2
Boost.Wave: A Standard compliant C++ preprocessor library
3
Example demonstrating how to preprocess the token stream generated by a
8
Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost
9
Software License, Version 1.0. (See accompanying file
10
LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11
=============================================================================*/
13
#if !defined(BOOST_WAVE_SAMPLE_PREPROCESS_PRAGMA_OUTPUT_APR_03_2008_0813AM)
14
#define BOOST_WAVE_SAMPLE_PREPROCESS_PRAGMA_OUTPUT_APR_03_2008_0813AM
16
template <typename String, typename Iterator>
18
as_unescaped_string(Iterator it, Iterator const& end)
20
using namespace boost::wave;
23
for (/**/; it != end; ++it)
25
switch (token_id(*it)) {
28
string val (util::impl::unescape_lit((*it).get_value()).c_str());
29
val.erase(val.size()-1);
35
default: // just skip everything else (hey it's a sample)
42
// return the string representation of a token sequence
43
template <typename String, typename Container>
45
as_unescaped_string(Container const &token_sequence)
47
return as_unescaped_string<String>(token_sequence.begin(),
48
token_sequence.end());
51
///////////////////////////////////////////////////////////////////////////////
53
// The preprocess_pragma_output_hooks policy class is used implement a special
54
// #pragma wave pp("some C++ code") directive allowing to insert preprocessed
55
// code into the output sequence generated by the tool.
57
// This policy type is used as a template parameter to the boost::wave::context<>
60
///////////////////////////////////////////////////////////////////////////////
61
class preprocess_pragma_output_hooks
62
: public boost::wave::context_policies::default_preprocessing_hooks
65
preprocess_pragma_output_hooks() {}
67
template <typename Context>
68
struct reset_language_support
70
reset_language_support(Context& ctx)
71
: ctx_(ctx), lang_(ctx.get_language())
73
ctx.set_language(boost::wave::enable_single_line(lang_), false);
75
~reset_language_support()
77
ctx_.set_language(lang_, false);
81
boost::wave::language_support lang_;
84
///////////////////////////////////////////////////////////////////////////
86
// The function 'interpret_pragma' is called, whenever a #pragma command
87
// directive is found which isn't known to the core Wave library, where
88
// command is the value defined as the BOOST_WAVE_PRAGMA_KEYWORD constant
89
// which defaults to "wave".
91
// The parameter 'ctx' is a reference to the context object used for
92
// instantiating the preprocessing iterators by the user.
94
// The parameter 'pending' may be used to push tokens back into the input
95
// stream, which are to be used as the replacement text for the whole
98
// The parameter 'option' contains the name of the interpreted pragma.
100
// The parameter 'values' holds the values of the parameter provided to
101
// the pragma operator.
103
// The parameter 'act_token' contains the actual #pragma token, which may
104
// be used for error output.
106
// If the return value is 'false', the whole #pragma directive is
107
// interpreted as unknown and a corresponding error message is issued. A
108
// return value of 'true' signs a successful interpretation of the given
111
///////////////////////////////////////////////////////////////////////////
112
template <typename Context, typename Container>
114
interpret_pragma(Context& ctx, Container &pending,
115
typename Context::token_type const& option,
116
Container const& values, typename Context::token_type const& act_token)
118
typedef typename Context::token_type token_type;
119
typedef typename Context::iterator_type iterator_type;
121
if (option.get_value() == "pp") {
122
// Concatenate the string(s) passed as the options to this pragma,
123
// preprocess the result using the current context and insert the
124
// generated token sequence in place of the pragma directive into the
128
// We're explicitly using a std::string here since the type of the
129
// iterators passed to the ctx.begin() below must match the types
130
// of the iterator the original context instance has been created
132
std::string s (as_unescaped_string<std::string>(values));
133
reset_language_support<Context> lang(ctx);
135
using namespace boost::wave;
137
// The expanded token sequence is stored in the 'pragma' container
138
// to ensure consistency in the output in the case of an error
139
// while preprocessing the pragma option strings.
141
iterator_type end = ctx.end();
142
for (iterator_type it = ctx.begin(s.begin(), s.end());
143
it != end && token_id(*it) != T_EOF; ++it)
145
pragma.push_back(*it);
149
// prepend the newly generated token sequence to the 'pending'
151
pending.splice(pending.begin(), pragma);
153
catch (boost::wave::preprocess_exception const& /*e*/) {
154
// the library will report an 'ill_formed_pragma_option' for us
160
// we don't know anything about this #pragma wave directive