~ubuntu-branches/debian/sid/boost1.49/sid

« back to all changes in this revision

Viewing changes to libs/wave/samples/preprocess_pragma_output/preprocess_pragma_output.hpp

  • Committer: Package Import Robot
  • Author(s): Steve M. Robbins
  • Date: 2012-02-26 00:31:44 UTC
  • Revision ID: package-import@ubuntu.com-20120226003144-eaytp12cbf6ubpms
Tags: upstream-1.49.0
ImportĀ upstreamĀ versionĀ 1.49.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=============================================================================
 
2
    Boost.Wave: A Standard compliant C++ preprocessor library
 
3
    Example demonstrating how to preprocess the token stream generated by a
 
4
    #pragma directive
 
5
    
 
6
    http://www.boost.org/
 
7
 
 
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
=============================================================================*/
 
12
 
 
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
 
15
 
 
16
template <typename String, typename Iterator>
 
17
inline String
 
18
as_unescaped_string(Iterator it, Iterator const& end)
 
19
{
 
20
    using namespace boost::wave;
 
21
    
 
22
    String result;
 
23
    for (/**/; it != end; ++it) 
 
24
    {
 
25
        switch (token_id(*it)) {
 
26
        case T_STRINGLIT:
 
27
            {
 
28
                string val (util::impl::unescape_lit((*it).get_value()).c_str());
 
29
                val.erase(val.size()-1);
 
30
                val.erase(0, 1);
 
31
                result += val;
 
32
            }
 
33
            break;
 
34
 
 
35
        default:    // just skip everything else (hey it's a sample)
 
36
            break;
 
37
        }
 
38
    }
 
39
    return result;
 
40
}
 
41
 
 
42
// return the string representation of a token sequence
 
43
template <typename String, typename Container>
 
44
inline String
 
45
as_unescaped_string(Container const &token_sequence)
 
46
{
 
47
    return as_unescaped_string<String>(token_sequence.begin(), 
 
48
        token_sequence.end());
 
49
}
 
50
 
 
51
///////////////////////////////////////////////////////////////////////////////
 
52
//  
 
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.
 
56
//
 
57
//  This policy type is used as a template parameter to the boost::wave::context<>
 
58
//  object.
 
59
//
 
60
///////////////////////////////////////////////////////////////////////////////
 
61
class preprocess_pragma_output_hooks
 
62
:   public boost::wave::context_policies::default_preprocessing_hooks
 
63
{
 
64
public:
 
65
    preprocess_pragma_output_hooks() {}
 
66
    
 
67
    template <typename Context>
 
68
    struct reset_language_support
 
69
    {
 
70
        reset_language_support(Context& ctx)
 
71
          : ctx_(ctx), lang_(ctx.get_language())
 
72
        {
 
73
            ctx.set_language(boost::wave::enable_single_line(lang_), false);
 
74
        }
 
75
        ~reset_language_support()
 
76
        {
 
77
            ctx_.set_language(lang_, false);
 
78
        }
 
79
        
 
80
        Context& ctx_;
 
81
        boost::wave::language_support lang_;
 
82
    };
 
83
    
 
84
    ///////////////////////////////////////////////////////////////////////////
 
85
    //  
 
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".
 
90
    //
 
91
    //  The parameter 'ctx' is a reference to the context object used for 
 
92
    //  instantiating the preprocessing iterators by the user.
 
93
    //
 
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 
 
96
    //  #pragma directive.
 
97
    //
 
98
    //  The parameter 'option' contains the name of the interpreted pragma.
 
99
    //
 
100
    //  The parameter 'values' holds the values of the parameter provided to 
 
101
    //  the pragma operator.
 
102
    //
 
103
    //  The parameter 'act_token' contains the actual #pragma token, which may 
 
104
    //  be used for error output.
 
105
    //
 
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 
 
109
    //  #pragma.
 
110
    //
 
111
    ///////////////////////////////////////////////////////////////////////////
 
112
    template <typename Context, typename Container>
 
113
    bool 
 
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)
 
117
    {
 
118
        typedef typename Context::token_type token_type;
 
119
        typedef typename Context::iterator_type iterator_type;
 
120
 
 
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 
 
125
        // output stream.
 
126
         
 
127
            try {
 
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 
 
131
            //  with.
 
132
                std::string s (as_unescaped_string<std::string>(values)); 
 
133
                reset_language_support<Context> lang(ctx);
 
134
                
 
135
                using namespace boost::wave;
 
136
 
 
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.
 
140
                Container pragma;
 
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) 
 
144
                {
 
145
                    pragma.push_back(*it);
 
146
                    it++;
 
147
                }
 
148
 
 
149
            // prepend the newly generated token sequence to the 'pending' 
 
150
            // container
 
151
                pending.splice(pending.begin(), pragma);
 
152
            }
 
153
            catch (boost::wave::preprocess_exception const& /*e*/) {
 
154
            // the library will report an 'ill_formed_pragma_option' for us
 
155
                return false;
 
156
            }
 
157
            return true;
 
158
        }
 
159
 
 
160
        // we don't know anything about this #pragma wave directive
 
161
        return false;   
 
162
    }
 
163
};
 
164
 
 
165
 
 
166
#endif
 
167