annotate DEPENDENCIES/generic/include/boost/wave/util/insert_whitespace_detection.hpp @ 133:4acb5d8d80b6 tip

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