Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:43

0001 /*=============================================================================
0002     Boost.Wave: A Standard compliant C++ preprocessor library
0003 
0004     http://www.boost.org/
0005 
0006     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0007     Software License, Version 1.0. (See accompanying file
0008     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 =============================================================================*/
0010 
0011 #if !defined(BOOST_MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED)
0012 #define BOOST_MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED
0013 
0014 #include <vector>
0015 
0016 #include <boost/assert.hpp>
0017 #include <boost/wave/wave_config.hpp>
0018 #include <boost/wave/token_ids.hpp>
0019 #include <boost/wave/cpplexer/validate_universal_char.hpp>
0020 #include <boost/wave/util/unput_queue_iterator.hpp>
0021 
0022 // this must occur after all of the includes and before any code appears
0023 #ifdef BOOST_HAS_ABI_HEADERS
0024 #include BOOST_ABI_PREFIX
0025 #endif
0026 
0027 ///////////////////////////////////////////////////////////////////////////////
0028 namespace boost {
0029 namespace wave {
0030 namespace util {
0031 
0032 namespace impl {
0033 
0034     // escape a string literal (insert '\\' before every '\"', '?' and '\\')
0035     template <typename StringT>
0036     inline StringT
0037     escape_lit(StringT const &value)
0038     {
0039         StringT result;
0040         typename StringT::size_type pos = 0;
0041         typename StringT::size_type pos1 = value.find_first_of ("\"\\?", 0);
0042         if (StringT::npos != pos1) {
0043             do {
0044                 result += value.substr(pos, pos1-pos)
0045                             + StringT("\\")
0046                             + StringT(1, value[pos1]);
0047                 pos1 = value.find_first_of ("\"\\?", pos = pos1+1);
0048             } while (StringT::npos != pos1);
0049             result += value.substr(pos);
0050         }
0051         else {
0052             result = value;
0053         }
0054         return result;
0055     }
0056 
0057     // un-escape a string literal (remove '\\' just before '\\', '\"' or '?')
0058     template <typename StringT>
0059     inline StringT
0060     unescape_lit(StringT const &value)
0061     {
0062         StringT result;
0063         typename StringT::size_type pos = 0;
0064         typename StringT::size_type pos1 = value.find_first_of ("\\", 0);
0065         if (StringT::npos != pos1) {
0066             do {
0067                 switch (value[pos1+1]) {
0068                 case '\\':
0069                 case '\"':
0070                 case '?':
0071                     result = result + value.substr(pos, pos1-pos);
0072                     pos1 = value.find_first_of ("\\", (pos = pos1+1)+1);
0073                     break;
0074 
0075                 case 'n':
0076                     result = result + value.substr(pos, pos1-pos) + "\n";
0077                     pos1 = value.find_first_of ("\\", pos = pos1+1);
0078                     ++pos;
0079                     break;
0080 
0081                 default:
0082                     result = result + value.substr(pos, pos1-pos+1);
0083                     pos1 = value.find_first_of ("\\", pos = pos1+1);
0084                 }
0085 
0086             } while (pos1 != StringT::npos);
0087             result = result + value.substr(pos);
0088         }
0089         else {
0090         // the string doesn't contain any escaped character sequences
0091             result = value;
0092         }
0093         return result;
0094     }
0095 
0096     // return the string representation of a token sequence
0097     template <typename ContainerT, typename PositionT>
0098     inline typename ContainerT::value_type::string_type
0099     as_stringlit (ContainerT const &token_sequence, PositionT const &pos)
0100     {
0101         using namespace boost::wave;
0102         typedef typename ContainerT::value_type::string_type string_type;
0103 
0104         string_type result("\"");
0105         bool was_whitespace = false;
0106         typename ContainerT::const_iterator end = token_sequence.end();
0107         for (typename ContainerT::const_iterator it = token_sequence.begin();
0108              it != end; ++it)
0109         {
0110             token_id id = token_id(*it);
0111 
0112             if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
0113                 if (!was_whitespace) {
0114                 // C++ standard 16.3.2.2 [cpp.stringize]
0115                 // Each occurrence of white space between the argument's
0116                 // preprocessing tokens becomes a single space character in the
0117                 // character string literal.
0118                     result += " ";
0119                     was_whitespace = true;
0120                 }
0121             }
0122             else if (T_STRINGLIT == id || T_CHARLIT == id) {
0123             // string literals and character literals have to be escaped
0124                 result += impl::escape_lit((*it).get_value());
0125                 was_whitespace = false;
0126             }
0127             else
0128 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
0129             if (T_PLACEMARKER != id)
0130 #endif
0131             {
0132             // now append this token to the string
0133                 result += (*it).get_value();
0134                 was_whitespace = false;
0135             }
0136         }
0137         result += "\"";
0138 
0139     // validate the resulting literal to contain no invalid universal character
0140     // value (throws if invalid chars found)
0141         boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(),
0142             pos.get_column(), pos.get_file());
0143         return result;
0144     }
0145 
0146 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
0147     // return the string representation of a token sequence
0148     template <typename ContainerT, typename PositionT>
0149     inline typename ContainerT::value_type::string_type
0150     as_stringlit (std::vector<ContainerT> const &arguments,
0151         typename std::vector<ContainerT>::size_type i, PositionT const &pos)
0152     {
0153         using namespace boost::wave;
0154         typedef typename ContainerT::value_type::string_type string_type;
0155 
0156         BOOST_ASSERT(i < arguments.size());
0157 
0158         string_type result("\"");
0159         bool was_whitespace = false;
0160 
0161         for (/**/; i < arguments.size(); ++i) {
0162         // stringize all remaining arguments
0163             typename ContainerT::const_iterator end = arguments[i].end();
0164             for (typename ContainerT::const_iterator it = arguments[i].begin();
0165                  it != end; ++it)
0166             {
0167                 token_id id = token_id(*it);
0168 
0169                 if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
0170                     if (!was_whitespace) {
0171                     // C++ standard 16.3.2.2 [cpp.stringize]
0172                     // Each occurrence of white space between the argument's
0173                     // preprocessing tokens becomes a single space character in the
0174                     // character string literal.
0175                         result += " ";
0176                         was_whitespace = true;
0177                     }
0178                 }
0179                 else if (T_STRINGLIT == id || T_CHARLIT == id) {
0180                 // string literals and character literals have to be escaped
0181                     result += impl::escape_lit((*it).get_value());
0182                     was_whitespace = false;
0183                 }
0184                 else if (T_PLACEMARKER != id) {
0185                 // now append this token to the string
0186                     result += (*it).get_value();
0187                     was_whitespace = false;
0188                 }
0189             }
0190 
0191         // append comma, if not last argument
0192             if (i < arguments.size()-1) {
0193                 result += ",";
0194                 was_whitespace = false;
0195             }
0196         }
0197         result += "\"";
0198 
0199     // validate the resulting literal to contain no invalid universal character
0200     // value (throws if invalid chars found)
0201         boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(),
0202             pos.get_column(), pos.get_file());
0203         return result;
0204     }
0205 #endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
0206 
0207     // return the string representation of a token sequence
0208     template <typename StringT, typename IteratorT>
0209     inline StringT
0210     as_string(IteratorT it, IteratorT const& end)
0211     {
0212         StringT result;
0213         for (/**/; it != end; ++it)
0214         {
0215             result += (*it).get_value();
0216         }
0217         return result;
0218     }
0219 
0220     // return the string representation of a token sequence
0221     template <typename ContainerT>
0222     inline typename ContainerT::value_type::string_type
0223     as_string (ContainerT const &token_sequence)
0224     {
0225         typedef typename ContainerT::value_type::string_type string_type;
0226         return as_string<string_type>(token_sequence.begin(),
0227             token_sequence.end());
0228     }
0229 
0230 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
0231     ///////////////////////////////////////////////////////////////////////////
0232     //
0233     //  Copies all arguments beginning with the given index to the output
0234     //  sequence. The arguments are separated by commas.
0235     //
0236     template <typename ContainerT, typename PositionT>
0237     void replace_ellipsis (std::vector<ContainerT> const &arguments,
0238         typename ContainerT::size_type index,
0239         ContainerT &expanded, PositionT const &pos)
0240     {
0241         using namespace cpplexer;
0242         typedef typename ContainerT::value_type token_type;
0243 
0244         token_type comma(T_COMMA, ",", pos);
0245         for (/**/; index < arguments.size(); ++index) {
0246         ContainerT const &arg = arguments[index];
0247 
0248             std::copy(arg.begin(), arg.end(),
0249                 std::inserter(expanded, expanded.end()));
0250 
0251             if (index < arguments.size()-1)
0252                 expanded.push_back(comma);
0253         }
0254     }
0255 
0256 #if BOOST_WAVE_SUPPORT_VA_OPT != 0
0257     ///////////////////////////////////////////////////////////////////////////
0258     //
0259     //  Finds the token range inside __VA_OPT__.
0260     //  Updates mdit to the position of the final rparen.
0261     //  If the parenthesis do not match up, or there are none, returns false
0262     //  and leaves mdit unchanged.
0263     //
0264     template <typename MDefIterT>
0265     bool find_va_opt_args (
0266         MDefIterT & mdit,                     // VA_OPT
0267         MDefIterT   mdend)
0268     {
0269         if ((std::distance(mdit, mdend) < 3) ||
0270             (T_LEFTPAREN != next_token<MDefIterT>::peek(mdit, mdend))) {
0271             return false;
0272         }
0273 
0274         MDefIterT mdstart_it = mdit;
0275         ++mdit;   // skip to lparen
0276         std::size_t scope = 0;
0277         // search for final rparen, leaving iterator there
0278         for (; (mdit != mdend) && !((scope == 1) && (T_RIGHTPAREN == token_id(*mdit)));
0279              ++mdit) {
0280             // count balanced parens
0281             if (T_RIGHTPAREN == token_id(*mdit)) {
0282                 scope--;
0283             } else if (T_LEFTPAREN == token_id(*mdit)) {
0284                 scope++;
0285             }
0286         }
0287         if ((mdit == mdend) && ((scope != 1) || (T_RIGHTPAREN != token_id(*mdit)))) {
0288             // arrived at end without matching rparen
0289             mdit = mdstart_it;
0290             return false;
0291         }
0292 
0293         return true;
0294     }
0295 
0296 #endif
0297 #endif
0298 
0299     // Skip all whitespace characters and queue the skipped characters into the
0300     // given container
0301     template <typename IteratorT>
0302     inline boost::wave::token_id
0303     skip_whitespace(IteratorT &first, IteratorT const &last)
0304     {
0305         token_id id = util::impl::next_token<IteratorT>::peek(first, last, false);
0306         if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
0307             do {
0308                 ++first;
0309                 id = util::impl::next_token<IteratorT>::peek(first, last, false);
0310             } while (IS_CATEGORY(id, WhiteSpaceTokenType));
0311         }
0312         ++first;
0313         return id;
0314     }
0315 
0316     template <typename IteratorT, typename ContainerT>
0317     inline boost::wave::token_id
0318     skip_whitespace(IteratorT &first, IteratorT const &last, ContainerT &queue)
0319     {
0320         queue.push_back (*first);       // queue up the current token
0321 
0322         token_id id = util::impl::next_token<IteratorT>::peek(first, last, false);
0323         if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
0324             do {
0325                 queue.push_back(*++first);  // queue up the next whitespace
0326                 id = util::impl::next_token<IteratorT>::peek(first, last, false);
0327             } while (IS_CATEGORY(id, WhiteSpaceTokenType));
0328         }
0329         ++first;
0330         return id;
0331     }
0332 
0333     // trim all whitespace from the beginning and the end of the given string
0334     template <typename StringT>
0335     inline StringT
0336     trim_whitespace(StringT const &s)
0337     {
0338         typedef typename StringT::size_type size_type;
0339 
0340         size_type first = s.find_first_not_of(" \t\v\f");
0341         if (StringT::npos == first)
0342             return StringT();
0343         size_type last = s.find_last_not_of(" \t\v\f");
0344         return s.substr(first, last-first+1);
0345     }
0346 
0347 }   // namespace impl
0348 
0349 ///////////////////////////////////////////////////////////////////////////////
0350 }   // namespace util
0351 }   // namespace wave
0352 }   // namespace boost
0353 
0354 // the suffix header occurs after all of the code
0355 #ifdef BOOST_HAS_ABI_HEADERS
0356 #include BOOST_ABI_SUFFIX
0357 #endif
0358 
0359 #endif // !defined(BOOST_MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED)