LCOV - code coverage report
Current view: top level - usr/include/boost/wave/util - macro_helpers.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 99 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*=============================================================================
       2             :     Boost.Wave: A Standard compliant C++ preprocessor library
       3             : 
       4             :     http://www.boost.org/
       5             : 
       6             :     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
       7             :     Software License, Version 1.0. (See accompanying file
       8             :     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       9             : =============================================================================*/
      10             : 
      11             : #if !defined(MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED)
      12             : #define MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED
      13             : 
      14             : #include <vector>
      15             : 
      16             : #include <boost/assert.hpp>
      17             : #include <boost/wave/wave_config.hpp>
      18             : #include <boost/wave/token_ids.hpp>
      19             : #include <boost/wave/cpplexer/validate_universal_char.hpp>
      20             : #include <boost/wave/util/unput_queue_iterator.hpp>
      21             : 
      22             : // this must occur after all of the includes and before any code appears
      23             : #ifdef BOOST_HAS_ABI_HEADERS
      24             : #include BOOST_ABI_PREFIX
      25             : #endif
      26             : 
      27             : ///////////////////////////////////////////////////////////////////////////////
      28             : namespace boost {
      29             : namespace wave {
      30             : namespace util {
      31             : 
      32             : namespace impl {
      33             : 
      34             :     // escape a string literal (insert '\\' before every '\"', '?' and '\\')
      35             :     template <typename StringT>
      36             :     inline StringT
      37           0 :     escape_lit(StringT const &value)
      38             :     {
      39           0 :         StringT result;
      40           0 :         typename StringT::size_type pos = 0;
      41           0 :         typename StringT::size_type pos1 = value.find_first_of ("\"\\?", 0);
      42           0 :         if (StringT::npos != pos1) {
      43             :             do {
      44           0 :                 result += value.substr(pos, pos1-pos)
      45             :                             + StringT("\\")
      46           0 :                             + StringT(1, value[pos1]);
      47           0 :                 pos1 = value.find_first_of ("\"\\?", pos = pos1+1);
      48           0 :             } while (StringT::npos != pos1);
      49           0 :             result += value.substr(pos);
      50             :         }
      51             :         else {
      52           0 :             result = value;
      53             :         }
      54           0 :         return result;
      55             :     }
      56             : 
      57             :     // un-escape a string literal (remove '\\' just before '\\', '\"' or '?')
      58             :     template <typename StringT>
      59             :     inline StringT
      60           0 :     unescape_lit(StringT const &value)
      61             :     {
      62           0 :         StringT result;
      63           0 :         typename StringT::size_type pos = 0;
      64           0 :         typename StringT::size_type pos1 = value.find_first_of ("\\", 0);
      65           0 :         if (StringT::npos != pos1) {
      66             :             do {
      67           0 :                 switch (value[pos1+1]) {
      68           0 :                 case '\\':
      69             :                 case '\"':
      70             :                 case '?':
      71           0 :                     result = result + value.substr(pos, pos1-pos);
      72           0 :                     pos1 = value.find_first_of ("\\", (pos = pos1+1)+1);
      73           0 :                     break;
      74             : 
      75           0 :                 case 'n':
      76           0 :                     result = result + value.substr(pos, pos1-pos) + "\n";
      77           0 :                     pos1 = value.find_first_of ("\\", pos = pos1+1);
      78           0 :                     ++pos;
      79           0 :                     break;
      80             : 
      81           0 :                 default:
      82           0 :                     result = result + value.substr(pos, pos1-pos+1);
      83           0 :                     pos1 = value.find_first_of ("\\", pos = pos1+1);
      84             :                 }
      85             : 
      86           0 :             } while (pos1 != StringT::npos);
      87           0 :             result = result + value.substr(pos);
      88             :         }
      89             :         else {
      90             :         // the string doesn't contain any escaped character sequences
      91           0 :             result = value;
      92             :         }
      93           0 :         return result;
      94             :     }
      95             : 
      96             :     // return the string representation of a token sequence
      97             :     template <typename ContainerT, typename PositionT>
      98             :     inline typename ContainerT::value_type::string_type
      99           0 :     as_stringlit (ContainerT const &token_sequence, PositionT const &pos)
     100             :     {
     101             :         using namespace boost::wave;
     102             :         typedef typename ContainerT::value_type::string_type string_type;
     103             : 
     104           0 :         string_type result("\"");
     105           0 :         bool was_whitespace = false;
     106           0 :         typename ContainerT::const_iterator end = token_sequence.end();
     107           0 :         for (typename ContainerT::const_iterator it = token_sequence.begin();
     108           0 :              it != end; ++it)
     109             :         {
     110           0 :             token_id id = token_id(*it);
     111             : 
     112           0 :             if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
     113           0 :                 if (!was_whitespace) {
     114             :                 // C++ standard 16.3.2.2 [cpp.stringize]
     115             :                 // Each occurrence of white space between the argument's
     116             :                 // preprocessing tokens becomes a single space character in the
     117             :                 // character string literal.
     118           0 :                     result += " ";
     119             :                     was_whitespace = true;
     120             :                 }
     121             :             }
     122           0 :             else if (T_STRINGLIT == id || T_CHARLIT == id) {
     123             :             // string literals and character literals have to be escaped
     124           0 :                 result += impl::escape_lit((*it).get_value());
     125           0 :                 was_whitespace = false;
     126             :             }
     127             :             else
     128             : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
     129           0 :             if (T_PLACEMARKER != id)
     130             : #endif
     131             :             {
     132             :             // now append this token to the string
     133           0 :                 result += (*it).get_value();
     134             :                 was_whitespace = false;
     135             :             }
     136             :         }
     137           0 :         result += "\"";
     138             : 
     139             :     // validate the resulting literal to contain no invalid universal character
     140             :     // value (throws if invalid chars found)
     141           0 :         boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(),
     142             :             pos.get_column(), pos.get_file());
     143           0 :         return result;
     144             :     }
     145             : 
     146             : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
     147             :     // return the string representation of a token sequence
     148             :     template <typename ContainerT, typename PositionT>
     149             :     inline typename ContainerT::value_type::string_type
     150           0 :     as_stringlit (std::vector<ContainerT> const &arguments,
     151             :         typename std::vector<ContainerT>::size_type i, PositionT const &pos)
     152             :     {
     153             :         using namespace boost::wave;
     154             :         typedef typename ContainerT::value_type::string_type string_type;
     155             : 
     156           0 :         BOOST_ASSERT(i < arguments.size());
     157             : 
     158           0 :         string_type result("\"");
     159           0 :         bool was_whitespace = false;
     160             : 
     161           0 :         for (/**/; i < arguments.size(); ++i) {
     162             :         // stringize all remaining arguments
     163           0 :             typename ContainerT::const_iterator end = arguments[i].end();
     164           0 :             for (typename ContainerT::const_iterator it = arguments[i].begin();
     165           0 :                  it != end; ++it)
     166             :             {
     167           0 :                 token_id id = token_id(*it);
     168             : 
     169           0 :                 if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
     170           0 :                     if (!was_whitespace) {
     171             :                     // C++ standard 16.3.2.2 [cpp.stringize]
     172             :                     // Each occurrence of white space between the argument's
     173             :                     // preprocessing tokens becomes a single space character in the
     174             :                     // character string literal.
     175           0 :                         result += " ";
     176             :                         was_whitespace = true;
     177             :                     }
     178             :                 }
     179           0 :                 else if (T_STRINGLIT == id || T_CHARLIT == id) {
     180             :                 // string literals and character literals have to be escaped
     181           0 :                     result += impl::escape_lit((*it).get_value());
     182           0 :                     was_whitespace = false;
     183             :                 }
     184           0 :                 else if (T_PLACEMARKER != id) {
     185             :                 // now append this token to the string
     186           0 :                     result += (*it).get_value();
     187             :                     was_whitespace = false;
     188             :                 }
     189             :             }
     190             : 
     191             :         // append comma, if not last argument
     192           0 :             if (i < arguments.size()-1) {
     193           0 :                 result += ",";
     194             :                 was_whitespace = false;
     195             :             }
     196             :         }
     197           0 :         result += "\"";
     198             : 
     199             :     // validate the resulting literal to contain no invalid universal character
     200             :     // value (throws if invalid chars found)
     201           0 :         boost::wave::cpplexer::impl::validate_literal(result, pos.get_line(),
     202             :             pos.get_column(), pos.get_file());
     203           0 :         return result;
     204             :     }
     205             : #endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
     206             : 
     207             :     // return the string representation of a token sequence
     208             :     template <typename StringT, typename IteratorT>
     209             :     inline StringT
     210           0 :     as_string(IteratorT it, IteratorT const& end)
     211             :     {
     212           0 :         StringT result;
     213           0 :         for (/**/; it != end; ++it)
     214             :         {
     215           0 :             result += (*it).get_value();
     216             :         }
     217           0 :         return result;
     218             :     }
     219             : 
     220             :     // return the string representation of a token sequence
     221             :     template <typename ContainerT>
     222             :     inline typename ContainerT::value_type::string_type
     223           0 :     as_string (ContainerT const &token_sequence)
     224             :     {
     225             :         typedef typename ContainerT::value_type::string_type string_type;
     226           0 :         return as_string<string_type>(token_sequence.begin(),
     227           0 :             token_sequence.end());
     228             :     }
     229             : 
     230             : #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
     231             :     ///////////////////////////////////////////////////////////////////////////
     232             :     //
     233             :     //  Copies all arguments beginning with the given index to the output
     234             :     //  sequence. The arguments are separated by commas.
     235             :     //
     236             :     template <typename ContainerT, typename PositionT>
     237           0 :     void replace_ellipsis (std::vector<ContainerT> const &arguments,
     238             :         typename ContainerT::size_type index,
     239             :         ContainerT &expanded, PositionT const &pos)
     240             :     {
     241             :         using namespace cpplexer;
     242             :         typedef typename ContainerT::value_type token_type;
     243             : 
     244           0 :         token_type comma(T_COMMA, ",", pos);
     245           0 :         for (/**/; index < arguments.size(); ++index) {
     246           0 :         ContainerT const &arg = arguments[index];
     247             : 
     248           0 :             std::copy(arg.begin(), arg.end(),
     249             :                 std::inserter(expanded, expanded.end()));
     250             : 
     251           0 :             if (index < arguments.size()-1)
     252           0 :                 expanded.push_back(comma);
     253             :         }
     254           0 :     }
     255             : #endif
     256             : 
     257             :     // Skip all whitespace characters and queue the skipped characters into the
     258             :     // given container
     259             :     template <typename IteratorT>
     260             :     inline boost::wave::token_id
     261           0 :     skip_whitespace(IteratorT &first, IteratorT const &last)
     262             :     {
     263           0 :         token_id id = util::impl::next_token<IteratorT>::peek(first, last, false);
     264           0 :         if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
     265           0 :             do {
     266           0 :                 ++first;
     267           0 :                 id = util::impl::next_token<IteratorT>::peek(first, last, false);
     268           0 :             } while (IS_CATEGORY(id, WhiteSpaceTokenType));
     269             :         }
     270           0 :         ++first;
     271           0 :         return id;
     272             :     }
     273             : 
     274             :     template <typename IteratorT, typename ContainerT>
     275             :     inline boost::wave::token_id
     276             :     skip_whitespace(IteratorT &first, IteratorT const &last, ContainerT &queue)
     277             :     {
     278             :         queue.push_back (*first);       // queue up the current token
     279             : 
     280             :         token_id id = util::impl::next_token<IteratorT>::peek(first, last, false);
     281             :         if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
     282             :             do {
     283             :                 queue.push_back(*++first);  // queue up the next whitespace
     284             :                 id = util::impl::next_token<IteratorT>::peek(first, last, false);
     285             :             } while (IS_CATEGORY(id, WhiteSpaceTokenType));
     286             :         }
     287             :         ++first;
     288             :         return id;
     289             :     }
     290             : 
     291             : }   // namespace impl
     292             : 
     293             : ///////////////////////////////////////////////////////////////////////////////
     294             : }   // namespace util
     295             : }   // namespace wave
     296             : }   // namespace boost
     297             : 
     298             : // the suffix header occurs after all of the code
     299             : #ifdef BOOST_HAS_ABI_HEADERS
     300             : #include BOOST_ABI_SUFFIX
     301             : #endif
     302             : 
     303             : #endif // !defined(MACRO_HELPERS_HPP_931BBC99_EBFA_4692_8FBE_B555998C2C39_INCLUDED)

Generated by: LCOV version 1.14