Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:10:23

0001 /*=============================================================================
0002     Boost.Wave: A Standard compliant C++ preprocessor library
0003 
0004     Detect the need to insert a whitespace token into the output stream
0005 
0006     http://www.boost.org/
0007 
0008     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0009     Software License, Version 1.0. (See accompanying file
0010     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // this must occur after all of the includes and before any code appears
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 // T_IDENTIFIER
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;        // would form an universal char
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          // avoid constructing universal characters (\u1234)
0080         case T_UNKNOWN_UNIVERSALCHAR:
0081             return would_form_universal_char(value);
0082 
0083         default:
0084             break;
0085         }
0086         return false;
0087     }
0088 // T_INTLIT
0089     inline bool
0090     handle_intlit(boost::wave::token_id prev, boost::wave::token_id /*before*/)
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 // T_FLOATLIT
0108     inline bool
0109     handle_floatlit(boost::wave::token_id prev,
0110         boost::wave::token_id /*before*/)
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 // <% T_LEFTBRACE
0128     inline bool
0129     handle_alt_leftbrace(boost::wave::token_id prev,
0130         boost::wave::token_id /*before*/)
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 // <: T_LEFTBRACKET
0144     inline bool
0145     handle_alt_leftbracket(boost::wave::token_id prev,
0146         boost::wave::token_id /*before*/)
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 // T_FIXEDPOINTLIT
0160     inline bool
0161     handle_fixedpointlit(boost::wave::token_id prev,
0162         boost::wave::token_id /*before*/)
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 // T_DOT
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 // T_QUESTION_MARK
0196     inline bool
0197     handle_questionmark(boost::wave::token_id prev,
0198         boost::wave::token_id /*before*/)
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 // T_NEWLINE
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): // \ \n
0219         case T_DIVIDE:
0220             if (T_QUESTION_MARK == before)
0221                 return true;    // ?/\n     // may be \\n
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             // no insertion between parens/brackets/braces and operators
0244             return false;
0245 
0246         default:
0247             break;
0248         }
0249         return true;
0250     }
0251 
0252 }   // namespace impl
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;       // skip whitespace insertion alltogether
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)       // 'L'
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;   // no insertion between parens/brackets/braces
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;   // no insertion between parens/brackets/braces
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;    // prevent -> or >>
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;    // prevent <<
0429             // fall through
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                 // no insertion between parens/brackets/braces and operators
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;     // '*****' do not need to be separated
0499             if (T_GREATER== prev &&
0500                 (T_MINUS == beforeprev || T_MINUSMINUS == beforeprev)
0501                )
0502             {
0503                 return true;    // prevent ->*
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     // FIXME: else, handle operators separately (will catch to many cases)
0517 //         if (IS_CATEGORY(current, OperatorTokenType) &&
0518 //             IS_CATEGORY(prev, OperatorTokenType))
0519 //         {
0520 //             return true;    // operators must be delimited always
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;            // enable this component
0534     boost::wave::token_id prev;        // the previous analyzed token
0535     boost::wave::token_id beforeprev;  // the token before the previous
0536 };
0537 
0538 ///////////////////////////////////////////////////////////////////////////////
0539 }   //  namespace util
0540 }   //  namespace wave
0541 }   //  namespace boost
0542 
0543 // the suffix header occurs after all of the code
0544 #ifdef BOOST_HAS_ABI_HEADERS
0545 #include BOOST_ABI_SUFFIX
0546 #endif
0547 
0548 #endif // !defined(BOOST_INSERT_WHITESPACE_DETECTION_HPP_765EF77B_0513_4967_BDD6_6A38148C4C96_INCLUDED)