Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r68146 - in trunk: boost/wave/util libs/wave libs/wave/samples/quick_start libs/wave/samples/quick_start/build tools/wave
From: hartmut.kaiser_at_[hidden]
Date: 2011-01-13 22:35:27


Author: hkaiser
Date: 2011-01-13 22:35:24 EST (Thu, 13 Jan 2011)
New Revision: 68146
URL: http://svn.boost.org/trac/boost/changeset/68146

Log:
Wave: After preprocessing the body of any #pragma wave option() the wave tool now concatenates all adjacent string literals into a single string literal.
Text files modified:
   trunk/boost/wave/util/macro_helpers.hpp | 30 +++++++++---------
   trunk/boost/wave/util/unput_queue_iterator.hpp | 2
   trunk/libs/wave/ChangeLog | 5 +++
   trunk/libs/wave/samples/quick_start/build/Jamfile.v2 | 2
   trunk/libs/wave/samples/quick_start/quick_start.cpp | 52 ++++++++++++++++---------------
   trunk/tools/wave/trace_macro_expansion.hpp | 66 +++++++++++++++++++++++++++++++++++++++
   6 files changed, 114 insertions(+), 43 deletions(-)

Modified: trunk/boost/wave/util/macro_helpers.hpp
==============================================================================
--- trunk/boost/wave/util/macro_helpers.hpp (original)
+++ trunk/boost/wave/util/macro_helpers.hpp 2011-01-13 22:35:24 EST (Thu, 13 Jan 2011)
@@ -71,18 +71,18 @@
                     result = result + value.substr(pos, pos1-pos);
                     pos1 = value.find_first_of ("\\", (pos = pos1+1)+1);
                     break;
-
+
                 case 'n':
                     result = result + value.substr(pos, pos1-pos) + "\n";
                     pos1 = value.find_first_of ("\\", pos = pos1+1);
                     ++pos;
                     break;
-
+
                 default:
                     result = result + value.substr(pos, pos1-pos+1);
                     pos1 = value.find_first_of ("\\", pos = pos1+1);
                 }
-
+
             } while (pos1 != StringT::npos);
             result = result + value.substr(pos);
         }
@@ -92,7 +92,7 @@
         }
         return result;
     }
-
+
     // return the string representation of a token sequence
     template <typename ContainerT, typename PositionT>
     inline typename ContainerT::value_type::string_type
@@ -100,7 +100,7 @@
     {
         using namespace boost::wave;
         typedef typename ContainerT::value_type::string_type string_type;
-
+
         string_type result("\"");
         bool was_whitespace = false;
         typename ContainerT::const_iterator end = token_sequence.end();
@@ -108,7 +108,7 @@
              it != end; ++it)
         {
             token_id id = token_id(*it);
-
+
             if (IS_CATEGORY(*it, WhiteSpaceTokenType) || T_NEWLINE == id) {
                 if (!was_whitespace) {
                 // C++ standard 16.3.2.2 [cpp.stringize]
@@ -152,12 +152,12 @@
     {
         using namespace boost::wave;
         typedef typename ContainerT::value_type::string_type string_type;
-
+
         BOOST_ASSERT(i < arguments.size());
-
+
         string_type result("\"");
         bool was_whitespace = false;
-
+
         for (/**/; i < arguments.size(); ++i) {
         // stringize all remaining arguments
             typename ContainerT::const_iterator end = arguments[i].end();
@@ -187,7 +187,7 @@
                     was_whitespace = false;
                 }
             }
-
+
         // append comma, if not last argument
             if (i < arguments.size()-1) {
                 result += ",";
@@ -216,7 +216,7 @@
         }
         return result;
     }
-
+
     // return the string representation of a token sequence
     template <typename ContainerT>
     inline typename ContainerT::value_type::string_type
@@ -226,7 +226,7 @@
         return as_string<string_type>(token_sequence.begin(),
             token_sequence.end());
     }
-
+
 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
     ///////////////////////////////////////////////////////////////////////////
     //
@@ -244,7 +244,7 @@
         token_type comma(T_COMMA, ",", pos);
         for (/**/; index < arguments.size(); ++index) {
         ContainerT const &arg = arguments[index];
-
+
             std::copy(arg.begin(), arg.end(),
                 std::inserter(expanded, expanded.end()));
                 
@@ -270,13 +270,13 @@
         ++first;
         return id;
     }
-
+
     template <typename IteratorT, typename ContainerT>
     inline boost::wave::token_id
     skip_whitespace(IteratorT &first, IteratorT const &last, ContainerT &queue)
     {
         queue.push_back (*first); // queue up the current token
-
+
         token_id id = util::impl::next_token<IteratorT>::peek(first, last, false);
         if (IS_CATEGORY(id, WhiteSpaceTokenType)) {
             do {

Modified: trunk/boost/wave/util/unput_queue_iterator.hpp
==============================================================================
--- trunk/boost/wave/util/unput_queue_iterator.hpp (original)
+++ trunk/boost/wave/util/unput_queue_iterator.hpp 2011-01-13 22:35:24 EST (Thu, 13 Jan 2011)
@@ -240,7 +240,7 @@
             typename iterator_type::container_type::iterator cit = queue.begin();
             typename iterator_type::container_type::iterator cend = queue.end();
 
- if (skip_whitespace) {
+ if (skip_whitespace) {
                     for (++cit; cit != cend; ++cit) {
                         if (!IS_CATEGORY(*cit, WhiteSpaceTokenType) &&
                             T_NEWLINE != token_id(*cit))

Modified: trunk/libs/wave/ChangeLog
==============================================================================
--- trunk/libs/wave/ChangeLog (original)
+++ trunk/libs/wave/ChangeLog 2011-01-13 22:35:24 EST (Thu, 13 Jan 2011)
@@ -20,6 +20,11 @@
 
 CHANGELOG
 
+Boost V1.47.0
+- V2.3.0
+- After preprocessing the body of any #pragma wave option() the wave tool now
+ concatenates all adjacent string literals into a single string literal.
+
 Boost V1.46.0
 - V2.2.0
 - Added recognition of C++0x keywords to Re2C lexers.

Modified: trunk/libs/wave/samples/quick_start/build/Jamfile.v2
==============================================================================
--- trunk/libs/wave/samples/quick_start/build/Jamfile.v2 (original)
+++ trunk/libs/wave/samples/quick_start/build/Jamfile.v2 2011-01-13 22:35:24 EST (Thu, 13 Jan 2011)
@@ -4,7 +4,7 @@
 #
 # http://www.boost.org/
 #
-# Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost
+# Copyright (c) 2001-2011 Hartmut Kaiser. Distributed under the Boost
 # Software License, Version 1.0. (See accompanying file
 # LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 

Modified: trunk/libs/wave/samples/quick_start/quick_start.cpp
==============================================================================
--- trunk/libs/wave/samples/quick_start/quick_start.cpp (original)
+++ trunk/libs/wave/samples/quick_start/quick_start.cpp 2011-01-13 22:35:24 EST (Thu, 13 Jan 2011)
@@ -3,7 +3,7 @@
 
     http://www.boost.org/
 
- Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost
+ Copyright (c) 2001-2011 Hartmut Kaiser. Distributed under the Boost
     Software License, Version 1.0. (See accompanying file
     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
@@ -36,10 +36,10 @@
 
     try {
 //[quick_start_main
- // The following preprocesses the given input file (given by argv[1]).
+ // The following preprocesses the input file given by argv[1].
     // Open and read in the specified input file.
- std::ifstream instream(argv[1]);
- std::string instring;
+ std::ifstream instream(argv[1]);
+ std::string instring;
 
         if (!instream.is_open()) {
             std::cerr << "Could not open input file: " << argv[1] << std::endl;
@@ -48,40 +48,42 @@
         instream.unsetf(std::ios::skipws);
         instring = std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
                                 std::istreambuf_iterator<char>());
-
- // This token type is one of the central types used throughout the library,
- // because it is a template parameter to some of the public classes and
- // instances of this type are returned from the iterators.
+
+ // This token type is one of the central types used throughout the library.
+ // It is a template parameter to some of the public classes and instances
+ // of this type are returned from the iterators.
         typedef boost::wave::cpplexer::lex_token<> token_type;
-
+
     // The template boost::wave::cpplexer::lex_iterator<> is the lexer type to
     // to use as the token source for the preprocessing engine. It is
     // parametrized with the token type.
         typedef boost::wave::cpplexer::lex_iterator<token_type> lex_iterator_type;
-
- // This is the resulting context type to use. The first template parameter
- // should match the iterator type to be used during construction of the
- // corresponding context object (see below).
+
+ // This is the resulting context type. The first template parameter should
+ // match the iterator type used during construction of the context
+ // instance (see below). It is the type of the underlying input stream.
         typedef boost::wave::context<std::string::iterator, lex_iterator_type>
             context_type;
 
     // The preprocessor iterator shouldn't be constructed directly. It is
- // to be generated through a wave::context<> object. This wave:context<>
- // object is to be used additionally to initialize and define different
- // parameters of the actual preprocessing (not done here).
+ // generated through a wave::context<> object. This wave:context<> object
+ // is additionally used to initialize and define different parameters of
+ // the actual preprocessing (not done here).
     //
     // The preprocessing of the input stream is done on the fly behind the
- // scenes during iteration over the context_type::iterator_type stream.
- context_type ctx (instring.begin(), instring.end(), argv[1]);
-
- // Get the preprocessor iterators and use them to generate
- // the token sequence.
- context_type::iterator_type first = ctx.begin();
- context_type::iterator_type last = ctx.end();
-
+ // scenes during iteration over the range of context_type::iterator_type
+ // instances.
+ context_type ctx (instring.begin(), instring.end(), argv[1]);
+
+ // Get the preprocessor iterators and use them to generate the token
+ // sequence.
+ context_type::iterator_type first = ctx.begin();
+ context_type::iterator_type last = ctx.end();
 
     // The input stream is preprocessed for you while iterating over the range
- // [first, last)
+ // [first, last). The dereferenced iterator returns tokens holding
+ // information about the preprocessed input stream, such as token type,
+ // token value, and position.
         while (first != last) {
             current_position = (*first).get_position();
             std::cout << (*first).get_value();

Modified: trunk/tools/wave/trace_macro_expansion.hpp
==============================================================================
--- trunk/tools/wave/trace_macro_expansion.hpp (original)
+++ trunk/tools/wave/trace_macro_expansion.hpp 2011-01-13 22:35:24 EST (Thu, 13 Jan 2011)
@@ -1144,10 +1144,71 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
+ // join all adjacent string tokens into the first one
+ template <typename StringT>
+ StringT unlit(StringT const& str)
+ {
+ return str.substr(1, str.size()-2);
+ }
+
+ template <typename StringT>
+ StringT merge_string_lits(StringT const& lhs, StringT const& rhs)
+ {
+ StringT result ("\"");
+
+ result += unlit(lhs);
+ result += unlit(rhs);
+ result += "\"";
+ return result;
+ }
+
+ template <typename ContextT, typename ContainerT>
+ void join_adjacent_string_tokens(ContextT &ctx, ContainerT const& values,
+ ContainerT& joined_values)
+ {
+ using namespace boost::wave;
+
+ typedef typename ContextT::token_type token_type;
+ typedef typename token_type::string_type string_type;
+ typedef typename ContainerT::const_iterator const_iterator;
+ typedef typename ContainerT::iterator iterator;
+
+ token_type* current = 0;
+
+ const_iterator end = values.end();
+ for (const_iterator it = values.begin(); it != end; ++it) {
+ token_id id(*it);
+
+ if (id == T_STRINGLIT) {
+ if (!current) {
+ joined_values.push_back(*it);
+ current = &joined_values.back();
+ }
+ else {
+ current->set_value(merge_string_lits(
+ current->get_value(), (*it).get_value()));
+ }
+ }
+ else if (current) {
+ typedef util::impl::next_token<const_iterator> next_token_type;
+ token_id next_id (next_token_type::peek(it, end, true));
+
+ if (next_id != T_STRINGLIT) {
+ current = 0;
+ joined_values.push_back(*it);
+ }
+ }
+ else {
+ joined_values.push_back(*it);
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
     // interpret the pragma wave option() directives
     template <typename ContextT, typename ContainerT>
     bool
- interpret_pragma_option(ContextT &ctx, ContainerT const &values,
+ interpret_pragma_option(ContextT &ctx, ContainerT const &cvalues,
         typename ContextT::token_type const &act_token)
     {
         using namespace boost::wave;
@@ -1156,6 +1217,9 @@
         typedef typename token_type::string_type string_type;
         typedef typename ContainerT::const_iterator const_iterator;
 
+ ContainerT values;
+ join_adjacent_string_tokens(ctx, cvalues, values);
+
         const_iterator end = values.end();
         for (const_iterator it = values.begin(); it != end; /**/) {
         bool valid_option = false;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk