Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/wave/whitespace_handling.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 6.4 KB
Line 
1/*=============================================================================
2    Boost.Wave: A Standard compliant C++ preprocessor library
3    Whitespace eater
4   
5    http://www.boost.org/
6
7    Copyright (c) 2003 Paul Mensonides
8    Copyright (c) 2001-2007 Hartmut Kaiser.
9    Distributed under the Boost Software License, Version 1.0. (See accompanying
10    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11=============================================================================*/
12
13#if !defined(WHITESPACE_HANDLING_HPP_INCLUDED)
14#define WHITESPACE_HANDLING_HPP_INCLUDED
15
16#include <boost/wave/wave_config.hpp>  
17#include <boost/wave/token_ids.hpp>  
18#include <boost/wave/preprocessing_hooks.hpp>
19
20// this must occur after all of the includes and before any code appears
21#ifdef BOOST_HAS_ABI_HEADERS
22#include BOOST_ABI_PREFIX
23#endif
24
25///////////////////////////////////////////////////////////////////////////////
26namespace boost {
27namespace wave {
28namespace context_policies {
29
30namespace util {
31    ///////////////////////////////////////////////////////////////////////////
32    //  This function returns true if the given C style comment contains at
33    //  least one newline
34    template <typename TokenT>
35    bool ccomment_has_newline(TokenT const& token)
36    {
37        using namespace boost::wave;
38
39        if (T_CCOMMENT == token_id(token) &&
40            TokenT::string_type::npos != token.get_value().find_first_of("\n"))
41        {
42            return true;
43        }
44        return false;
45    }
46
47    ///////////////////////////////////////////////////////////////////////////
48    //  This function returns the number of newlines in the given C style
49    //  comment
50    template <typename TokenT>
51    int ccomment_count_newlines(TokenT const& token)
52    {
53        using namespace boost::wave;
54        int newlines = 0;
55        if (T_CCOMMENT == token_id(token)) {
56        typename TokenT::string_type const& value = token.get_value();
57        typename TokenT::string_type::size_type p = value.find_first_of("\n");
58
59            while (TokenT::string_type::npos != p) {
60                ++newlines;
61                p = value.find_first_of("\n", p+1);
62            } 
63        }
64        return newlines;
65    }
66}
67
68///////////////////////////////////////////////////////////////////////////////
69template <typename TokenT>
70class eat_whitespace 
71:   public default_preprocessing_hooks
72{
73public:
74    eat_whitespace();
75   
76    template <typename ContextT>
77    bool may_skip_whitespace(ContextT const& ctx, TokenT &token, 
78        bool &skipped_newline);
79
80protected:
81    bool skip_cppcomment(boost::wave::token_id id)
82    {
83        return !preserve_comments && T_CPPCOMMENT == id;
84    }
85   
86private:
87    typedef bool state_t(TokenT &token, bool &skipped_newline);
88    state_t eat_whitespace::* state;
89    state_t general, newline, newline_2nd, whitespace;
90    bool preserve_comments;
91};
92
93template <typename TokenT>
94inline 
95eat_whitespace<TokenT>::eat_whitespace()
96:   state(&eat_whitespace::newline), preserve_comments(false)
97{
98}
99
100template <typename TokenT>
101template <typename ContextT>
102inline bool 
103eat_whitespace<TokenT>::may_skip_whitespace(ContextT const& ctx, TokenT &token, 
104    bool &skipped_newline) 
105{
106    // re-initialize the preserve comments state
107    preserve_comments = boost::wave::need_preserve_comments(ctx.get_language());
108    return (this->*state)(token, skipped_newline);
109}
110
111template <typename TokenT>
112inline bool 
113eat_whitespace<TokenT>::general(TokenT &token, bool &skipped_newline) 
114{
115    using namespace boost::wave;
116
117    token_id id = token_id(token);
118    if (T_NEWLINE == id || T_CPPCOMMENT == id) {
119        state = &eat_whitespace::newline;
120    }
121    else if (T_SPACE == id || T_SPACE2 == id || T_CCOMMENT == id) {
122        state = &eat_whitespace::whitespace;
123
124        if (util::ccomment_has_newline(token)) 
125            skipped_newline = true;
126
127        if ((!preserve_comments || T_CCOMMENT != id) && 
128            token.get_value().size() > 1)
129        {
130            token.set_value(" ");   // replace with a single space
131        }
132    }
133    else {
134        state = &eat_whitespace::general;
135    }
136    return false;
137}
138
139template <typename TokenT>
140inline bool 
141eat_whitespace<TokenT>::newline(TokenT &token, bool &skipped_newline) 
142{
143    using namespace boost::wave;
144   
145    token_id id = token_id(token);
146    if (T_NEWLINE == id || T_CPPCOMMENT == id) {
147        skipped_newline = true;
148        state = &eat_whitespace::newline_2nd;
149        return T_NEWLINE == id || skip_cppcomment(id);
150    }
151    else if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id) {
152        return general(token, skipped_newline);
153    }
154
155    if (T_CCOMMENT == id) {
156        if (util::ccomment_has_newline(token)) {
157            skipped_newline = true;
158            state = &eat_whitespace::newline_2nd;
159        }
160        if (preserve_comments) {
161            state = &eat_whitespace::general;
162            return false;
163        }
164        // fall through...
165    }
166    return true;
167}
168
169template <typename TokenT>
170inline bool 
171eat_whitespace<TokenT>::newline_2nd(TokenT &token, bool &skipped_newline) 
172{
173    using namespace boost::wave;
174   
175    token_id id = token_id(token);
176    if (T_SPACE == id || T_SPACE2 == id)
177        return true;
178    if (T_CCOMMENT == id) {
179        if (util::ccomment_has_newline(token))
180            skipped_newline = true;
181
182        if (preserve_comments) {
183            state = &eat_whitespace::general;
184            return false;
185        }
186        return  true;
187    }
188    if (T_NEWLINE != id && T_CPPCOMMENT != id) 
189        return general(token, skipped_newline);
190
191    skipped_newline = true;
192    return T_NEWLINE == id || skip_cppcomment(id);
193}
194
195template <typename TokenT>
196inline bool 
197eat_whitespace<TokenT>::whitespace(TokenT &token, bool &skipped_newline) 
198{
199    using namespace boost::wave;
200   
201    token_id id = token_id(token);
202    if (T_SPACE != id && T_SPACE2 != id && 
203        T_CCOMMENT != id && T_CPPCOMMENT != id) 
204    {
205        return general(token, skipped_newline);
206    }
207   
208    if (T_CCOMMENT == id) {
209        if (util::ccomment_has_newline(token))
210            skipped_newline = true;
211        return !preserve_comments;
212    }
213
214    return T_SPACE == id || T_SPACE2 == id || skip_cppcomment(id);
215}
216
217///////////////////////////////////////////////////////////////////////////////
218}   // namespace context_policies
219}   // namespace wave
220}   // namespace boost
221
222// the suffix header occurs after all of the code
223#ifdef BOOST_HAS_ABI_HEADERS
224#include BOOST_ABI_SUFFIX
225#endif
226
227#endif // !defined(WHITESPACE_HANDLING_HPP_INCLUDED)
228
Note: See TracBrowser for help on using the repository browser.