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