File indexing completed on 2025-12-15 10:10:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #if !defined(BOOST_INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)
0013 #define BOOST_INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED
0014
0015 #include <boost/wave/wave_config.hpp>
0016 #include <boost/wave/token_ids.hpp>
0017
0018
0019 #ifdef BOOST_HAS_ABI_HEADERS
0020 #include BOOST_ABI_PREFIX
0021 #endif
0022
0023
0024 namespace boost {
0025 namespace wave {
0026 namespace util {
0027
0028 namespace impl {
0029
0030
0031 template <typename StringT>
0032 inline bool
0033 would_form_universal_char (StringT const &value)
0034 {
0035 if ('u' != value[0] && 'U' != value[0])
0036 return false;
0037 if ('u' == value[0] && value.size() < 5)
0038 return false;
0039 if ('U' == value[0] && value.size() < 9)
0040 return false;
0041
0042 typename StringT::size_type pos =
0043 value.find_first_not_of("0123456789abcdefABCDEF", 1);
0044
0045 if (StringT::npos == pos ||
0046 ('u' == value[0] && pos > 5) ||
0047 ('U' == value[0] && pos > 9))
0048 {
0049 return true;
0050 }
0051 return false;
0052 }
0053 template <typename StringT>
0054 inline bool
0055 handle_identifier(boost::wave::token_id prev,
0056 boost::wave::token_id before, StringT const &value)
0057 {
0058 using namespace boost::wave;
0059 switch (prev) {
0060 case T_IDENTIFIER:
0061 case T_NONREPLACABLE_IDENTIFIER:
0062 case T_COMPL_ALT:
0063 case T_OR_ALT:
0064 case T_AND_ALT:
0065 case T_NOT_ALT:
0066 case T_XOR_ALT:
0067 case T_ANDASSIGN_ALT:
0068 case T_ORASSIGN_ALT:
0069 case T_XORASSIGN_ALT:
0070 case T_NOTEQUAL_ALT:
0071 case T_FIXEDPOINTLIT:
0072 return true;
0073
0074 case T_FLOATLIT:
0075 case T_INTLIT:
0076 case T_PP_NUMBER:
0077 return (value.size() > 1 || (value[0] != 'e' && value[0] != 'E'));
0078
0079
0080 case T_UNKNOWN_UNIVERSALCHAR:
0081 return would_form_universal_char(value);
0082
0083 default:
0084 break;
0085 }
0086 return false;
0087 }
0088
0089 inline bool
0090 handle_intlit(boost::wave::token_id prev, boost::wave::token_id )
0091 {
0092 using namespace boost::wave;
0093 switch (prev) {
0094 case T_IDENTIFIER:
0095 case T_NONREPLACABLE_IDENTIFIER:
0096 case T_INTLIT:
0097 case T_FLOATLIT:
0098 case T_FIXEDPOINTLIT:
0099 case T_PP_NUMBER:
0100 return true;
0101
0102 default:
0103 break;
0104 }
0105 return false;
0106 }
0107
0108 inline bool
0109 handle_floatlit(boost::wave::token_id prev,
0110 boost::wave::token_id )
0111 {
0112 using namespace boost::wave;
0113 switch (prev) {
0114 case T_IDENTIFIER:
0115 case T_NONREPLACABLE_IDENTIFIER:
0116 case T_INTLIT:
0117 case T_FLOATLIT:
0118 case T_FIXEDPOINTLIT:
0119 case T_PP_NUMBER:
0120 return true;
0121
0122 default:
0123 break;
0124 }
0125 return false;
0126 }
0127
0128 inline bool
0129 handle_alt_leftbrace(boost::wave::token_id prev,
0130 boost::wave::token_id )
0131 {
0132 using namespace boost::wave;
0133 switch (prev) {
0134 case T_LESS:
0135 case T_SHIFTLEFT:
0136 return true;
0137
0138 default:
0139 break;
0140 }
0141 return false;
0142 }
0143
0144 inline bool
0145 handle_alt_leftbracket(boost::wave::token_id prev,
0146 boost::wave::token_id )
0147 {
0148 using namespace boost::wave;
0149 switch (prev) {
0150 case T_LESS:
0151 case T_SHIFTLEFT:
0152 return true;
0153
0154 default:
0155 break;
0156 }
0157 return false;
0158 }
0159
0160 inline bool
0161 handle_fixedpointlit(boost::wave::token_id prev,
0162 boost::wave::token_id )
0163 {
0164 using namespace boost::wave;
0165 switch (prev) {
0166 case T_IDENTIFIER:
0167 case T_NONREPLACABLE_IDENTIFIER:
0168 case T_INTLIT:
0169 case T_FLOATLIT:
0170 case T_FIXEDPOINTLIT:
0171 case T_PP_NUMBER:
0172 return true;
0173
0174 default:
0175 break;
0176 }
0177 return false;
0178 }
0179
0180 inline bool
0181 handle_dot(boost::wave::token_id prev, boost::wave::token_id before)
0182 {
0183 using namespace boost::wave;
0184 switch (prev) {
0185 case T_DOT:
0186 if (T_DOT == before)
0187 return true;
0188 break;
0189
0190 default:
0191 break;
0192 }
0193 return false;
0194 }
0195
0196 inline bool
0197 handle_questionmark(boost::wave::token_id prev,
0198 boost::wave::token_id )
0199 {
0200 using namespace boost::wave;
0201 switch(prev) {
0202 case T_UNKNOWN_UNIVERSALCHAR:
0203 case T_QUESTION_MARK:
0204 return true;
0205
0206 default:
0207 break;
0208 }
0209 return false;
0210 }
0211
0212 inline bool
0213 handle_newline(boost::wave::token_id prev,
0214 boost::wave::token_id before)
0215 {
0216 using namespace boost::wave;
0217 switch(prev) {
0218 case TOKEN_FROM_ID('\\', UnknownTokenType):
0219 case T_DIVIDE:
0220 if (T_QUESTION_MARK == before)
0221 return true;
0222 break;
0223
0224 default:
0225 break;
0226 }
0227 return false;
0228 }
0229
0230 inline bool
0231 handle_parens(boost::wave::token_id prev)
0232 {
0233 switch (prev) {
0234 case T_LEFTPAREN:
0235 case T_RIGHTPAREN:
0236 case T_LEFTBRACKET:
0237 case T_RIGHTBRACKET:
0238 case T_LEFTBRACE:
0239 case T_RIGHTBRACE:
0240 case T_SEMICOLON:
0241 case T_COMMA:
0242 case T_COLON:
0243
0244 return false;
0245
0246 default:
0247 break;
0248 }
0249 return true;
0250 }
0251
0252 }
0253
0254 class insert_whitespace_detection
0255 {
0256 public:
0257 insert_whitespace_detection(bool insert_whitespace_ = true)
0258 : insert_whitespace(insert_whitespace_),
0259 prev(boost::wave::T_EOF), beforeprev(boost::wave::T_EOF)
0260 {}
0261
0262 template <typename StringT>
0263 bool must_insert(boost::wave::token_id current, StringT const &value)
0264 {
0265 if (!insert_whitespace)
0266 return false;
0267
0268 using namespace boost::wave;
0269 switch (current) {
0270 case T_NONREPLACABLE_IDENTIFIER:
0271 case T_IDENTIFIER:
0272 return impl::handle_identifier(prev, beforeprev, value);
0273 case T_PP_NUMBER:
0274 case T_INTLIT:
0275 return impl::handle_intlit(prev, beforeprev);
0276 case T_FLOATLIT:
0277 return impl::handle_floatlit(prev, beforeprev);
0278 case T_STRINGLIT:
0279 if (TOKEN_FROM_ID('L', IdentifierTokenType) == prev)
0280 return true;
0281 break;
0282 case T_LEFTBRACE_ALT:
0283 return impl::handle_alt_leftbrace(prev, beforeprev);
0284 case T_LEFTBRACKET_ALT:
0285 return impl::handle_alt_leftbracket(prev, beforeprev);
0286 case T_FIXEDPOINTLIT:
0287 return impl::handle_fixedpointlit(prev, beforeprev);
0288 case T_DOT:
0289 return impl::handle_dot(prev, beforeprev);
0290 case T_QUESTION_MARK:
0291 return impl::handle_questionmark(prev, beforeprev);
0292 case T_NEWLINE:
0293 return impl::handle_newline(prev, beforeprev);
0294
0295 case T_LEFTPAREN:
0296 case T_RIGHTPAREN:
0297 case T_LEFTBRACKET:
0298 case T_RIGHTBRACKET:
0299 case T_SEMICOLON:
0300 case T_COMMA:
0301 case T_COLON:
0302 switch (prev) {
0303 case T_LEFTPAREN:
0304 case T_RIGHTPAREN:
0305 case T_LEFTBRACKET:
0306 case T_RIGHTBRACKET:
0307 case T_LEFTBRACE:
0308 case T_RIGHTBRACE:
0309 return false;
0310
0311 default:
0312 if (IS_CATEGORY(prev, OperatorTokenType))
0313 return false;
0314 break;
0315 }
0316 break;
0317
0318 case T_LEFTBRACE:
0319 case T_RIGHTBRACE:
0320 switch (prev) {
0321 case T_LEFTPAREN:
0322 case T_RIGHTPAREN:
0323 case T_LEFTBRACKET:
0324 case T_RIGHTBRACKET:
0325 case T_LEFTBRACE:
0326 case T_RIGHTBRACE:
0327 case T_SEMICOLON:
0328 case T_COMMA:
0329 case T_COLON:
0330 return false;
0331
0332 case T_QUESTION_MARK:
0333 if (T_QUESTION_MARK == beforeprev)
0334 return true;
0335 if (IS_CATEGORY(prev, OperatorTokenType))
0336 return false;
0337 break;
0338
0339 default:
0340 break;
0341 }
0342 break;
0343
0344 case T_MINUS:
0345 case T_MINUSMINUS:
0346 case T_MINUSASSIGN:
0347 if (T_MINUS == prev || T_MINUSMINUS == prev)
0348 return true;
0349 if (!impl::handle_parens(prev))
0350 return false;
0351 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
0352 return true;
0353 break;
0354
0355 case T_PLUS:
0356 case T_PLUSPLUS:
0357 case T_PLUSASSIGN:
0358 if (T_PLUS == prev || T_PLUSPLUS == prev)
0359 return true;
0360 if (!impl::handle_parens(prev))
0361 return false;
0362 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
0363 return true;
0364 break;
0365
0366 case T_DIVIDE:
0367 case T_DIVIDEASSIGN:
0368 if (T_DIVIDE == prev)
0369 return true;
0370 if (!impl::handle_parens(prev))
0371 return false;
0372 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
0373 return true;
0374 break;
0375
0376 case T_EQUAL:
0377 case T_ASSIGN:
0378 switch (prev) {
0379 case T_PLUSASSIGN:
0380 case T_MINUSASSIGN:
0381 case T_DIVIDEASSIGN:
0382 case T_STARASSIGN:
0383 case T_SHIFTRIGHTASSIGN:
0384 case T_SHIFTLEFTASSIGN:
0385 case T_EQUAL:
0386 case T_NOTEQUAL:
0387 case T_LESSEQUAL:
0388 case T_GREATEREQUAL:
0389 case T_LESS:
0390 case T_GREATER:
0391 case T_PLUS:
0392 case T_MINUS:
0393 case T_STAR:
0394 case T_DIVIDE:
0395 case T_ORASSIGN:
0396 case T_ANDASSIGN:
0397 case T_XORASSIGN:
0398 case T_OR:
0399 case T_AND:
0400 case T_XOR:
0401 case T_OROR:
0402 case T_ANDAND:
0403 return true;
0404
0405 case T_QUESTION_MARK:
0406 if (T_QUESTION_MARK == beforeprev)
0407 return true;
0408 break;
0409
0410 default:
0411 if (!impl::handle_parens(prev))
0412 return false;
0413 break;
0414 }
0415 break;
0416
0417 case T_GREATER:
0418 if (T_MINUS == prev || T_GREATER == prev)
0419 return true;
0420 if (!impl::handle_parens(prev))
0421 return false;
0422 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
0423 return true;
0424 break;
0425
0426 case T_LESS:
0427 if (T_LESS == prev)
0428 return true;
0429
0430 case T_CHARLIT:
0431 case T_NOT:
0432 case T_NOTEQUAL:
0433 if (!impl::handle_parens(prev))
0434 return false;
0435 if (T_QUESTION_MARK == prev && T_QUESTION_MARK == beforeprev)
0436 return true;
0437 break;
0438
0439 case T_AND:
0440 case T_ANDAND:
0441 if (!impl::handle_parens(prev))
0442 return false;
0443 if (T_AND == prev || T_ANDAND == prev)
0444 return true;
0445 break;
0446
0447 case T_OR:
0448 if (!impl::handle_parens(prev))
0449 return false;
0450 if (T_OR == prev)
0451 return true;
0452 break;
0453
0454 case T_XOR:
0455 if (!impl::handle_parens(prev))
0456 return false;
0457 if (T_XOR == prev)
0458 return true;
0459 break;
0460
0461 case T_COMPL_ALT:
0462 case T_OR_ALT:
0463 case T_AND_ALT:
0464 case T_NOT_ALT:
0465 case T_XOR_ALT:
0466 case T_ANDASSIGN_ALT:
0467 case T_ORASSIGN_ALT:
0468 case T_XORASSIGN_ALT:
0469 case T_NOTEQUAL_ALT:
0470 switch (prev) {
0471 case T_LEFTPAREN:
0472 case T_RIGHTPAREN:
0473 case T_LEFTBRACKET:
0474 case T_RIGHTBRACKET:
0475 case T_LEFTBRACE:
0476 case T_RIGHTBRACE:
0477 case T_SEMICOLON:
0478 case T_COMMA:
0479 case T_COLON:
0480
0481 return false;
0482
0483 case T_IDENTIFIER:
0484 if (T_NONREPLACABLE_IDENTIFIER == prev ||
0485 IS_CATEGORY(prev, KeywordTokenType))
0486 {
0487 return true;
0488 }
0489 break;
0490
0491 default:
0492 break;
0493 }
0494 break;
0495
0496 case T_STAR:
0497 if (T_STAR == prev)
0498 return false;
0499 if (T_GREATER== prev &&
0500 (T_MINUS == beforeprev || T_MINUSMINUS == beforeprev)
0501 )
0502 {
0503 return true;
0504 }
0505 break;
0506
0507 case T_POUND:
0508 if (T_POUND == prev)
0509 return true;
0510 break;
0511
0512 default:
0513 break;
0514 }
0515
0516
0517
0518
0519
0520
0521
0522 return false;
0523 }
0524 void shift_tokens (boost::wave::token_id next_id)
0525 {
0526 if (insert_whitespace) {
0527 beforeprev = prev;
0528 prev = next_id;
0529 }
0530 }
0531
0532 private:
0533 bool insert_whitespace;
0534 boost::wave::token_id prev;
0535 boost::wave::token_id beforeprev;
0536 };
0537
0538
0539 }
0540 }
0541 }
0542
0543
0544 #ifdef BOOST_HAS_ABI_HEADERS
0545 #include BOOST_ABI_SUFFIX
0546 #endif
0547
0548 #endif