]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/wave/util/insert_whitespace_detection.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / wave / util / insert_whitespace_detection.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Boost.Wave: A Standard compliant C++ preprocessor library
3
4 Detect the need to insert a whitespace token into the output stream
b32b8144 5
7c673cae
FG
6 http://www.boost.org/
7
8 Copyright (c) 2001-2012 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
b32b8144
FG
15#include <boost/wave/wave_config.hpp>
16#include <boost/wave/token_ids.hpp>
7c673cae
FG
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;
b32b8144
FG
41
42 typename StringT::size_type pos =
7c673cae 43 value.find_first_not_of("0123456789abcdefABCDEF", 1);
b32b8144
FG
44
45 if (StringT::npos == pos ||
7c673cae
FG
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>
b32b8144
FG
54 inline bool
55 handle_identifier(boost::wave::token_id prev,
7c673cae
FG
56 boost::wave::token_id before, StringT const &value)
57 {
58 using namespace boost::wave;
b32b8144 59 switch (prev) {
7c673cae
FG
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'));
b32b8144 78
7c673cae 79 // avoid constructing universal characters (\u1234)
b32b8144 80 case T_UNKNOWN_UNIVERSALCHAR:
7c673cae 81 return would_form_universal_char(value);
b32b8144
FG
82
83 default:
84 break;
7c673cae
FG
85 }
86 return false;
87 }
88// T_INTLIT
b32b8144 89 inline bool
7c673cae
FG
90 handle_intlit(boost::wave::token_id prev, boost::wave::token_id /*before*/)
91 {
92 using namespace boost::wave;
b32b8144 93 switch (prev) {
7c673cae
FG
94 case T_IDENTIFIER:
95 case T_NONREPLACABLE_IDENTIFIER:
96 case T_INTLIT:
97 case T_FLOATLIT:
98 case T_FIXEDPOINTLIT:
99 case T_PP_NUMBER:
100 return true;
b32b8144
FG
101
102 default:
103 break;
7c673cae
FG
104 }
105 return false;
106 }
107// T_FLOATLIT
b32b8144
FG
108 inline bool
109 handle_floatlit(boost::wave::token_id prev,
7c673cae
FG
110 boost::wave::token_id /*before*/)
111 {
112 using namespace boost::wave;
b32b8144 113 switch (prev) {
7c673cae
FG
114 case T_IDENTIFIER:
115 case T_NONREPLACABLE_IDENTIFIER:
116 case T_INTLIT:
117 case T_FLOATLIT:
118 case T_FIXEDPOINTLIT:
119 case T_PP_NUMBER:
120 return true;
b32b8144
FG
121
122 default:
123 break;
7c673cae
FG
124 }
125 return false;
126 }
127// <% T_LEFTBRACE
b32b8144
FG
128 inline bool
129 handle_alt_leftbrace(boost::wave::token_id prev,
7c673cae
FG
130 boost::wave::token_id /*before*/)
131 {
132 using namespace boost::wave;
b32b8144 133 switch (prev) {
7c673cae
FG
134 case T_LESS: // <<%
135 case T_SHIFTLEFT: // <<<%
136 return true;
b32b8144
FG
137
138 default:
139 break;
7c673cae
FG
140 }
141 return false;
142 }
143// <: T_LEFTBRACKET
b32b8144
FG
144 inline bool
145 handle_alt_leftbracket(boost::wave::token_id prev,
7c673cae
FG
146 boost::wave::token_id /*before*/)
147 {
148 using namespace boost::wave;
b32b8144 149 switch (prev) {
7c673cae
FG
150 case T_LESS: // <<:
151 case T_SHIFTLEFT: // <<<:
152 return true;
b32b8144
FG
153
154 default:
155 break;
7c673cae
FG
156 }
157 return false;
158 }
159// T_FIXEDPOINTLIT
b32b8144
FG
160 inline bool
161 handle_fixedpointlit(boost::wave::token_id prev,
7c673cae
FG
162 boost::wave::token_id /*before*/)
163 {
164 using namespace boost::wave;
b32b8144 165 switch (prev) {
7c673cae
FG
166 case T_IDENTIFIER:
167 case T_NONREPLACABLE_IDENTIFIER:
168 case T_INTLIT:
169 case T_FLOATLIT:
170 case T_FIXEDPOINTLIT:
171 case T_PP_NUMBER:
172 return true;
b32b8144
FG
173
174 default:
175 break;
7c673cae
FG
176 }
177 return false;
178 }
179// T_DOT
b32b8144 180 inline bool
7c673cae
FG
181 handle_dot(boost::wave::token_id prev, boost::wave::token_id before)
182 {
183 using namespace boost::wave;
b32b8144 184 switch (prev) {
7c673cae
FG
185 case T_DOT:
186 if (T_DOT == before)
187 return true; // ...
188 break;
b32b8144
FG
189
190 default:
191 break;
7c673cae
FG
192 }
193 return false;
194 }
195// T_QUESTION_MARK
b32b8144
FG
196 inline bool
197 handle_questionmark(boost::wave::token_id prev,
7c673cae
FG
198 boost::wave::token_id /*before*/)
199 {
200 using namespace boost::wave;
b32b8144
FG
201 switch(prev) {
202 case T_UNKNOWN_UNIVERSALCHAR: // \?
7c673cae
FG
203 case T_QUESTION_MARK: // ??
204 return true;
b32b8144
FG
205
206 default:
207 break;
7c673cae
FG
208 }
209 return false;
210 }
211// T_NEWLINE
212 inline bool
b32b8144 213 handle_newline(boost::wave::token_id prev,
7c673cae
FG
214 boost::wave::token_id before)
215 {
216 using namespace boost::wave;
b32b8144 217 switch(prev) {
7c673cae
FG
218 case TOKEN_FROM_ID('\\', UnknownTokenType): // \ \n
219 case T_DIVIDE:
220 if (T_QUESTION_MARK == before)
221 return true; // ?/\n // may be \\n
222 break;
b32b8144
FG
223
224 default:
225 break;
7c673cae
FG
226 }
227 return false;
228 }
229
b32b8144 230 inline bool
7c673cae
FG
231 handle_parens(boost::wave::token_id prev)
232 {
b32b8144 233 switch (prev) {
7c673cae
FG
234 case T_LEFTPAREN:
235 case T_RIGHTPAREN:
236 case T_LEFTBRACKET:
237 case T_RIGHTBRACKET:
238 case T_LEFTBRACE:
239 case T_RIGHTBRACE:
240 case T_SEMICOLON:
241 case T_COMMA:
242 case T_COLON:
243 // no insertion between parens/brackets/braces and operators
b32b8144 244 return false;
7c673cae
FG
245
246 default:
247 break;
248 }
249 return true;
250 }
b32b8144 251
7c673cae
FG
252} // namespace impl
253
b32b8144 254class insert_whitespace_detection
7c673cae
FG
255{
256public:
b32b8144 257 insert_whitespace_detection(bool insert_whitespace_ = true)
7c673cae 258 : insert_whitespace(insert_whitespace_),
b32b8144 259 prev(boost::wave::T_EOF), beforeprev(boost::wave::T_EOF)
7c673cae 260 {}
b32b8144 261
7c673cae
FG
262 template <typename StringT>
263 bool must_insert(boost::wave::token_id current, StringT const &value)
264 {
265 if (!insert_whitespace)
266 return false; // skip whitespace insertion alltogether
b32b8144 267
7c673cae 268 using namespace boost::wave;
b32b8144 269 switch (current) {
7c673cae 270 case T_NONREPLACABLE_IDENTIFIER:
b32b8144
FG
271 case T_IDENTIFIER:
272 return impl::handle_identifier(prev, beforeprev, value);
7c673cae
FG
273 case T_PP_NUMBER:
274 case T_INTLIT:
b32b8144 275 return impl::handle_intlit(prev, beforeprev);
7c673cae 276 case T_FLOATLIT:
b32b8144 277 return impl::handle_floatlit(prev, beforeprev);
7c673cae
FG
278 case T_STRINGLIT:
279 if (TOKEN_FROM_ID('L', IdentifierTokenType) == prev) // 'L'
280 return true;
281 break;
282 case T_LEFTBRACE_ALT:
b32b8144 283 return impl::handle_alt_leftbrace(prev, beforeprev);
7c673cae 284 case T_LEFTBRACKET_ALT:
b32b8144 285 return impl::handle_alt_leftbracket(prev, beforeprev);
7c673cae 286 case T_FIXEDPOINTLIT:
b32b8144 287 return impl::handle_fixedpointlit(prev, beforeprev);
7c673cae 288 case T_DOT:
b32b8144 289 return impl::handle_dot(prev, beforeprev);
7c673cae 290 case T_QUESTION_MARK:
b32b8144 291 return impl::handle_questionmark(prev, beforeprev);
7c673cae 292 case T_NEWLINE:
b32b8144 293 return impl::handle_newline(prev, beforeprev);
7c673cae
FG
294
295 case T_LEFTPAREN:
296 case T_RIGHTPAREN:
297 case T_LEFTBRACKET:
298 case T_RIGHTBRACKET:
299 case T_SEMICOLON:
300 case T_COMMA:
301 case T_COLON:
b32b8144 302 switch (prev) {
7c673cae
FG
303 case T_LEFTPAREN:
304 case T_RIGHTPAREN:
305 case T_LEFTBRACKET:
306 case T_RIGHTBRACKET:
307 case T_LEFTBRACE:
308 case T_RIGHTBRACE:
309 return false; // no insertion between parens/brackets/braces
310
311 default:
312 if (IS_CATEGORY(prev, OperatorTokenType))
313 return false;
314 break;
b32b8144 315 }
7c673cae 316 break;
b32b8144 317
7c673cae
FG
318 case T_LEFTBRACE:
319 case T_RIGHTBRACE:
b32b8144 320 switch (prev) {
7c673cae
FG
321 case T_LEFTPAREN:
322 case T_RIGHTPAREN:
323 case T_LEFTBRACKET:
324 case T_RIGHTBRACKET:
325 case T_LEFTBRACE:
326 case T_RIGHTBRACE:
327 case T_SEMICOLON:
328 case T_COMMA:
329 case T_COLON:
330 return false; // no insertion between parens/brackets/braces
331
332 case T_QUESTION_MARK:
333 if (T_QUESTION_MARK == beforeprev)
334 return true;
335 if (IS_CATEGORY(prev, OperatorTokenType))
336 return false;
337 break;
b32b8144 338
7c673cae
FG
339 default:
340 break;
341 }
342 break;
b32b8144 343
7c673cae
FG
344 case T_MINUS:
345 case T_MINUSMINUS:
346 case T_MINUSASSIGN:
347 if (T_MINUS == prev || T_MINUSMINUS == prev)
348 return true;
349 if (!impl::handle_parens(prev))
350 return false;
351 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
352 return true;
353 break;
b32b8144 354
7c673cae
FG
355 case T_PLUS:
356 case T_PLUSPLUS:
357 case T_PLUSASSIGN:
358 if (T_PLUS == prev || T_PLUSPLUS == prev)
359 return true;
360 if (!impl::handle_parens(prev))
361 return false;
362 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
363 return true;
364 break;
b32b8144 365
7c673cae
FG
366 case T_DIVIDE:
367 case T_DIVIDEASSIGN:
368 if (T_DIVIDE == prev)
369 return true;
370 if (!impl::handle_parens(prev))
371 return false;
372 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
373 return true;
374 break;
b32b8144 375
7c673cae
FG
376 case T_EQUAL:
377 case T_ASSIGN:
b32b8144 378 switch (prev) {
7c673cae
FG
379 case T_PLUSASSIGN:
380 case T_MINUSASSIGN:
381 case T_DIVIDEASSIGN:
382 case T_STARASSIGN:
383 case T_SHIFTRIGHTASSIGN:
384 case T_SHIFTLEFTASSIGN:
385 case T_EQUAL:
386 case T_NOTEQUAL:
387 case T_LESSEQUAL:
388 case T_GREATEREQUAL:
389 case T_LESS:
390 case T_GREATER:
391 case T_PLUS:
392 case T_MINUS:
393 case T_STAR:
394 case T_DIVIDE:
395 case T_ORASSIGN:
396 case T_ANDASSIGN:
397 case T_XORASSIGN:
398 case T_OR:
399 case T_AND:
400 case T_XOR:
401 case T_OROR:
402 case T_ANDAND:
403 return true;
404
405 case T_QUESTION_MARK:
406 if (T_QUESTION_MARK == beforeprev)
407 return true;
408 break;
b32b8144 409
7c673cae
FG
410 default:
411 if (!impl::handle_parens(prev))
412 return false;
413 break;
414 }
415 break;
416
417 case T_GREATER:
418 if (T_MINUS == prev || T_GREATER == prev)
419 return true; // prevent -> or >>
420 if (!impl::handle_parens(prev))
421 return false;
422 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
423 return true;
424 break;
425
426 case T_LESS:
427 if (T_LESS == prev)
428 return true; // prevent <<
429 // fall through
430 case T_CHARLIT:
431 case T_NOT:
432 case T_NOTEQUAL:
433 if (!impl::handle_parens(prev))
434 return false;
435 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
436 return true;
437 break;
438
439 case T_AND:
440 case T_ANDAND:
441 if (!impl::handle_parens(prev))
442 return false;
443 if (T_AND == prev || T_ANDAND == prev)
444 return true;
445 break;
b32b8144 446
7c673cae
FG
447 case T_OR:
448 if (!impl::handle_parens(prev))
449 return false;
450 if (T_OR == prev)
451 return true;
452 break;
b32b8144 453
7c673cae
FG
454 case T_XOR:
455 if (!impl::handle_parens(prev))
456 return false;
457 if (T_XOR == prev)
458 return true;
459 break;
b32b8144 460
7c673cae
FG
461 case T_COMPL_ALT:
462 case T_OR_ALT:
463 case T_AND_ALT:
464 case T_NOT_ALT:
465 case T_XOR_ALT:
466 case T_ANDASSIGN_ALT:
467 case T_ORASSIGN_ALT:
468 case T_XORASSIGN_ALT:
469 case T_NOTEQUAL_ALT:
b32b8144 470 switch (prev) {
7c673cae
FG
471 case T_LEFTPAREN:
472 case T_RIGHTPAREN:
473 case T_LEFTBRACKET:
474 case T_RIGHTBRACKET:
475 case T_LEFTBRACE:
476 case T_RIGHTBRACE:
477 case T_SEMICOLON:
478 case T_COMMA:
479 case T_COLON:
480 // no insertion between parens/brackets/braces and operators
b32b8144 481 return false;
7c673cae
FG
482
483 case T_IDENTIFIER:
484 if (T_NONREPLACABLE_IDENTIFIER == prev ||
485 IS_CATEGORY(prev, KeywordTokenType))
486 {
487 return true;
488 }
489 break;
b32b8144 490
7c673cae
FG
491 default:
492 break;
493 }
494 break;
b32b8144 495
7c673cae
FG
496 case T_STAR:
497 if (T_STAR == prev)
498 return false; // '*****' do not need to be separated
b32b8144 499 if (T_GREATER== prev &&
7c673cae
FG
500 (T_MINUS == beforeprev || T_MINUSMINUS == beforeprev)
501 )
502 {
503 return true; // prevent ->*
504 }
505 break;
506
507 case T_POUND:
508 if (T_POUND == prev)
509 return true;
510 break;
b32b8144
FG
511
512 default:
513 break;
7c673cae
FG
514 }
515
516 // FIXME: else, handle operators separately (will catch to many cases)
b32b8144 517// if (IS_CATEGORY(current, OperatorTokenType) &&
7c673cae
FG
518// IS_CATEGORY(prev, OperatorTokenType))
519// {
520// return true; // operators must be delimited always
521// }
522 return false;
523 }
524 void shift_tokens (boost::wave::token_id next_id)
525 {
526 if (insert_whitespace) {
527 beforeprev = prev;
528 prev = next_id;
529 }
530 }
b32b8144 531
7c673cae
FG
532private:
533 bool insert_whitespace; // enable this component
534 boost::wave::token_id prev; // the previous analyzed token
535 boost::wave::token_id beforeprev; // the token before the previous
536};
537
538///////////////////////////////////////////////////////////////////////////////
539} // namespace util
b32b8144 540} // namespace wave
7c673cae
FG
541} // namespace boost
542
543// the suffix header occurs after all of the code
544#ifdef BOOST_HAS_ABI_HEADERS
545#include BOOST_ABI_SUFFIX
546#endif
547
548#endif // !defined(INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)