Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/wave/util/insert_whitespace_detection.hpp @ 33

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

updated boost from 1_33_1 to 1_34_1

File size: 10.4 KB
Line 
1/*=============================================================================
2    Boost.Wave: A Standard compliant C++ preprocessor library
3
4    Detect the need to insert a whitespace token into the output stream
5   
6    http://www.boost.org/
7
8    Copyright (c) 2001-2007 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#if !defined(INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)
13#define INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED
14
15#include <boost/wave/wave_config.hpp>  
16#include <boost/wave/token_ids.hpp>  
17
18// this must occur after all of the includes and before any code appears
19#ifdef BOOST_HAS_ABI_HEADERS
20#include BOOST_ABI_PREFIX
21#endif
22
23///////////////////////////////////////////////////////////////////////////////
24namespace boost {
25namespace wave {
26namespace util {
27
28namespace impl {
29
30// T_IDENTIFIER
31    template <typename StringT>
32    inline bool
33    would_form_universal_char (StringT const &value)
34    {
35        if ('u' != value[0] && 'U' != value[0])
36            return false;
37        if ('u' == value[0] && value.size() < 5)
38            return false;
39        if ('U' == value[0] && value.size() < 9)
40            return false;
41   
42    typename StringT::size_type pos = 
43        value.find_first_not_of("0123456789abcdefABCDEF", 1);
44       
45        if (StringT::npos == pos || 
46            ('u' == value[0] && pos > 5) ||
47            ('U' == value[0] && pos > 9))
48        {
49            return true;        // would form an universal char
50        }
51        return false;
52    }
53    template <typename StringT>
54    inline bool 
55    handle_identifier(boost::wave::token_id prev, 
56        boost::wave::token_id before, StringT const &value)
57    {
58        using namespace boost::wave;
59        switch (static_cast<unsigned int>(prev)) {
60        case T_IDENTIFIER:
61        case T_NONREPLACABLE_IDENTIFIER:
62        case T_COMPL_ALT:
63        case T_OR_ALT:
64        case T_AND_ALT:
65        case T_NOT_ALT:
66        case T_XOR_ALT:
67        case T_ANDASSIGN_ALT:
68        case T_ORASSIGN_ALT:
69        case T_XORASSIGN_ALT:
70        case T_NOTEQUAL_ALT:
71        case T_FIXEDPOINTLIT:
72            return true;
73
74        case T_FLOATLIT:
75        case T_INTLIT:
76        case T_PP_NUMBER:
77            return (value.size() > 1 || (value[0] != 'e' && value[0] != 'E'));
78           
79         // avoid constructing universal characters (\u1234)
80        case TOKEN_FROM_ID('\\', UnknownTokenType):
81            return would_form_universal_char(value);
82        }
83        return false;
84    }
85// T_INTLIT
86    inline bool 
87    handle_intlit(boost::wave::token_id prev, boost::wave::token_id before)
88    {
89        using namespace boost::wave;
90        switch (static_cast<unsigned int>(prev)) {
91        case T_IDENTIFIER:
92        case T_NONREPLACABLE_IDENTIFIER:
93        case T_INTLIT:
94        case T_FLOATLIT:
95        case T_FIXEDPOINTLIT:
96        case T_PP_NUMBER:
97            return true;
98        }
99        return false;
100    }
101// T_FLOATLIT
102    inline bool 
103    handle_floatlit(boost::wave::token_id prev, 
104        boost::wave::token_id before)
105    {
106        using namespace boost::wave;
107        switch (static_cast<unsigned int>(prev)) {
108        case T_IDENTIFIER:
109        case T_NONREPLACABLE_IDENTIFIER:
110        case T_INTLIT:
111        case T_FLOATLIT:
112        case T_FIXEDPOINTLIT:
113        case T_PP_NUMBER:
114            return true;
115        }
116        return false;
117    }
118// <% T_LEFTBRACE
119    inline bool 
120    handle_alt_leftbrace(boost::wave::token_id prev, 
121        boost::wave::token_id before)
122    {
123        using namespace boost::wave;
124        switch (static_cast<unsigned int>(prev)) {
125        case T_LESS:        // <<%
126        case T_SHIFTLEFT:   // <<<%
127            return true;
128        }
129        return false;
130    }
131// <: T_LEFTBRACKET
132    inline bool 
133    handle_alt_leftbracket(boost::wave::token_id prev, 
134        boost::wave::token_id before)
135    {
136        using namespace boost::wave;
137        switch (static_cast<unsigned int>(prev)) {
138        case T_LESS:        // <<:
139        case T_SHIFTLEFT:   // <<<:
140            return true;
141        }
142        return false;
143    }
144// T_FIXEDPOINTLIT
145    inline bool 
146    handle_fixedpointlit(boost::wave::token_id prev, 
147        boost::wave::token_id before)
148    {
149        using namespace boost::wave;
150        switch (static_cast<unsigned int>(prev)) {
151        case T_IDENTIFIER:
152        case T_NONREPLACABLE_IDENTIFIER:
153        case T_INTLIT:
154        case T_FLOATLIT:
155        case T_FIXEDPOINTLIT:
156        case T_PP_NUMBER:
157            return true;
158        }
159        return false;
160    }
161// T_DOT
162    inline bool 
163    handle_dot(boost::wave::token_id prev, boost::wave::token_id before)
164    {
165        using namespace boost::wave;
166        switch (static_cast<unsigned int>(prev)) {
167        case T_DOT:
168            if (T_DOT == before)
169                return true;    // ...
170            break;
171        }
172        return false;
173    }
174// T_QUESTION_MARK
175    inline bool 
176    handle_questionmark(boost::wave::token_id prev, 
177        boost::wave::token_id before)
178    {
179        using namespace boost::wave;
180        switch(static_cast<unsigned int>(prev)) {
181        case TOKEN_FROM_ID('\\', UnknownTokenType):     // \?
182        case T_QUESTION_MARK:   // ??
183            return true;
184        }
185        return false;
186    }
187// T_NEWLINE
188    inline bool
189    handle_newline(boost::wave::token_id prev, 
190        boost::wave::token_id before)
191    {
192        using namespace boost::wave;
193        switch(static_cast<unsigned int>(prev)) {
194        case TOKEN_FROM_ID('\\', UnknownTokenType): // \ \n
195        case T_DIVIDE:
196            if (T_QUESTION_MARK == before)
197                return true;    // ?/\n     // may be \\n
198            break;
199        }
200        return false;
201    }
202   
203}   // namespace impl
204
205class insert_whitespace_detection 
206{
207public:
208    insert_whitespace_detection() 
209    :   prev(boost::wave::T_EOF), beforeprev(boost::wave::T_EOF) 
210    {}
211   
212    template <typename StringT>
213    bool must_insert(boost::wave::token_id current, StringT const &value)
214    {
215        using namespace boost::wave;
216        switch (static_cast<unsigned int>(current)) {
217        case T_NONREPLACABLE_IDENTIFIER:
218        case T_IDENTIFIER: 
219            return impl::handle_identifier(prev, beforeprev, value); 
220        case T_PP_NUMBER:
221        case T_INTLIT:
222            return impl::handle_intlit(prev, beforeprev); 
223        case T_FLOATLIT:
224            return impl::handle_floatlit(prev, beforeprev); 
225        case T_STRINGLIT:
226            if (TOKEN_FROM_ID('L', IdentifierTokenType) == prev)       // 'L'
227                return true;
228            break;
229        case T_LEFTBRACE_ALT:
230            return impl::handle_alt_leftbrace(prev, beforeprev); 
231        case T_LEFTBRACKET_ALT:
232            return impl::handle_alt_leftbracket(prev, beforeprev); 
233        case T_FIXEDPOINTLIT:
234            return impl::handle_fixedpointlit(prev, beforeprev); 
235        case T_DOT:
236            return impl::handle_dot(prev, beforeprev); 
237        case T_QUESTION_MARK:
238            return impl::handle_questionmark(prev, beforeprev); 
239        case T_NEWLINE:
240            return impl::handle_newline(prev, beforeprev); 
241
242        case T_LEFTPAREN:
243        case T_RIGHTPAREN:
244        case T_LEFTBRACKET:
245        case T_RIGHTBRACKET:
246        case T_SEMICOLON:
247        case T_COMMA:
248        case T_COLON:
249            switch (static_cast<unsigned int>(prev)) {
250            case T_LEFTPAREN:
251            case T_RIGHTPAREN:
252            case T_LEFTBRACKET:
253            case T_RIGHTBRACKET:
254            case T_LEFTBRACE:
255            case T_RIGHTBRACE:
256                return false;   // no insertion between parens/brackets/braces
257
258            default:
259                break;
260            }       
261            break;
262           
263        case T_LEFTBRACE:
264        case T_RIGHTBRACE:
265            switch (static_cast<unsigned int>(prev)) {
266            case T_LEFTPAREN:
267            case T_RIGHTPAREN:
268            case T_LEFTBRACKET:
269            case T_RIGHTBRACKET:
270            case T_LEFTBRACE:
271            case T_RIGHTBRACE:
272            case T_SEMICOLON:
273            case T_COMMA:
274            case T_COLON:
275                return false;   // no insertion between parens/brackets/braces
276
277            case T_QUESTION_MARK:
278                if (T_QUESTION_MARK == beforeprev)
279                    return true;
280                break;
281               
282            default:
283                break;
284            }
285            break;
286                           
287        case T_MINUS:
288        case T_MINUSMINUS:
289        case T_LESS:
290        case T_EQUAL:
291        case T_ASSIGN:
292        case T_GREATER:
293        case T_DIVIDE:
294        case T_CHARLIT:
295        case T_NOT:
296        case T_NOTEQUAL:
297        case T_DIVIDEASSIGN:
298        case T_MINUSASSIGN:
299            if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
300                return true;    // ??{op}
301            break;
302
303        case T_COMPL_ALT:
304        case T_OR_ALT:
305        case T_AND_ALT:
306        case T_NOT_ALT:
307        case T_XOR_ALT:
308        case T_ANDASSIGN_ALT:
309        case T_ORASSIGN_ALT:
310        case T_XORASSIGN_ALT:
311        case T_NOTEQUAL_ALT:
312            if (T_IDENTIFIER == prev || T_NONREPLACABLE_IDENTIFIER == prev ||
313                IS_CATEGORY(prev, KeywordTokenType))
314                return true;
315            break;
316           
317        case T_STAR:
318            if (T_STAR == prev)
319                return false;     // '*****' do not need to be separated
320            break;
321        }
322
323    // else, handle operators separately
324        if (IS_CATEGORY(current, OperatorTokenType) && 
325            IS_CATEGORY(prev, OperatorTokenType))
326        {
327            return true;    // operators must be delimited always
328        }
329        return false;
330    }
331    void shift_tokens (boost::wave::token_id next_id)
332    {
333        beforeprev = prev;
334        prev = next_id;
335    }
336   
337private:
338    boost::wave::token_id prev;        // the previous analyzed token
339    boost::wave::token_id beforeprev;  // the token before the previous
340};
341
342///////////////////////////////////////////////////////////////////////////////
343}   //  namespace util
344}   //  namespace wave
345}   //  namespace boost
346
347// the suffix header occurs after all of the code
348#ifdef BOOST_HAS_ABI_HEADERS
349#include BOOST_ABI_SUFFIX
350#endif
351
352#endif // !defined(INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)
Note: See TracBrowser for help on using the repository browser.