Boost logo

Boost-Commit :

From: hartmut.kaiser_at_[hidden]
Date: 2008-04-03 16:09:43


Author: hkaiser
Date: 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
New Revision: 44020
URL: http://svn.boost.org/trac/boost/changeset/44020

Log:
Wave: Added new sample 'preprocess_pragma_output' and fixed a couple of problems (see ChangeLog).
Added:
   trunk/libs/wave/samples/preprocess_pragma_output/
   trunk/libs/wave/samples/preprocess_pragma_output/build/
   trunk/libs/wave/samples/preprocess_pragma_output/build/Jamfile.v2 (contents, props changed)
   trunk/libs/wave/samples/preprocess_pragma_output/example.cpp (contents, props changed)
   trunk/libs/wave/samples/preprocess_pragma_output/preprocess_pragma_output.cpp (contents, props changed)
   trunk/libs/wave/samples/preprocess_pragma_output/preprocess_pragma_output.hpp (contents, props changed)
Text files modified:
   trunk/boost/wave/cpp_context.hpp | 26 ++++++++++++---
   trunk/boost/wave/cpp_throw.hpp | 30 +++++++++---------
   trunk/boost/wave/grammars/cpp_defined_grammar.hpp | 8 ++--
   trunk/boost/wave/grammars/cpp_defined_grammar_gen.hpp | 18 +++++-----
   trunk/boost/wave/util/cpp_iterator.hpp | 63 ++++++++++++++++++++-------------------
   trunk/boost/wave/util/cpp_macromap.hpp | 32 +++++++++----------
   trunk/boost/wave/util/cpp_macromap_utils.hpp | 3 +
   trunk/boost/wave/util/interpret_pragma.hpp | 20 ++++++------
   trunk/libs/wave/ChangeLog | 12 ++++++
   trunk/libs/wave/samples/Jamfile.v2 | 1
   10 files changed, 120 insertions(+), 93 deletions(-)

Modified: trunk/boost/wave/cpp_context.hpp
==============================================================================
--- trunk/boost/wave/cpp_context.hpp (original)
+++ trunk/boost/wave/cpp_context.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -19,6 +19,8 @@
 #include <boost/concept_check.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/filesystem/path.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
 
 #include <boost/wave/wave_config.hpp>
 #if BOOST_WAVE_SERIALIZATION != 0
@@ -72,14 +74,22 @@
 //
 ///////////////////////////////////////////////////////////////////////////////
 
+struct this_type {};
+
 template <
     typename IteratorT,
     typename LexIteratorT,
     typename InputPolicyT = iteration_context_policies::load_file_to_string,
- typename HooksT = context_policies::eat_whitespace<typename LexIteratorT::token_type>
+ typename HooksT = context_policies::eat_whitespace<typename LexIteratorT::token_type>,
+ typename DerivedT = this_type
>
 class context : private boost::noncopyable
 {
+private:
+ typedef typename mpl::if_<
+ is_same<DerivedT, this_type>, context, DerivedT
+ >::type actual_context_type;
+
 public:
 
 // concept checks
@@ -88,12 +98,10 @@
     
 // public typedefs
     typedef typename LexIteratorT::token_type token_type;
- typedef context<IteratorT, LexIteratorT, InputPolicyT, HooksT>
- self_type;
     
     typedef IteratorT target_iterator_type;
     typedef LexIteratorT lexer_type;
- typedef pp_iterator<self_type> iterator_type;
+ typedef pp_iterator<context> iterator_type;
 
     typedef InputPolicyT input_policy_type;
     typedef typename token_type::position_type position_type;
@@ -217,7 +225,7 @@
     void reset_macro_definitions()
         { macros.reset_macromap(); macros.init_predefined_macros(); }
 
- typedef boost::wave::util::macromap<self_type> macromap_type;
+ typedef boost::wave::util::macromap<context> macromap_type;
     typedef typename macromap_type::name_iterator name_iterator;
     typedef typename macromap_type::const_name_iterator const_name_iterator;
     
@@ -257,6 +265,12 @@
 // access the policies
     hook_policy_type &get_hooks() { return hooks; }
 
+// return type of actually used context type (might be the derived type)
+ actual_context_type& derived()
+ { return *static_cast<actual_context_type*>(this); }
+ actual_context_type const& derived() const
+ { return *static_cast<actual_context_type const*>(this); }
+
 // return the directory of the currently preprocessed file
     boost::filesystem::path get_current_directory() const
         { return includes.get_current_directory(); }
@@ -438,7 +452,7 @@
         }
         catch (boost::wave::preprocess_exception const& e) {
         // catch version mismatch exceptions and call error handler
- get_hooks().throw_exception(*this, e);
+ get_hooks().throw_exception(derived(), e);
         }
     }
     BOOST_SERIALIZATION_SPLIT_MEMBER()

Modified: trunk/boost/wave/cpp_throw.hpp
==============================================================================
--- trunk/boost/wave/cpp_throw.hpp (original)
+++ trunk/boost/wave/cpp_throw.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -42,8 +42,8 @@
         if ((msg)[0] != 0) stream << ": " << (msg); \
         stream << std::ends; \
         std::string throwmsg = stream.str(); stream.freeze(false); \
- ctx.get_hooks().throw_exception(ctx, cls(throwmsg.c_str(), cls::code, \
- (act_pos).get_line(), (act_pos).get_column(), \
+ ctx.get_hooks().throw_exception(ctx.derived(), cls(throwmsg.c_str(), \
+ cls::code, (act_pos).get_line(), (act_pos).get_column(), \
             (act_pos).get_file().c_str())); \
     } \
     /**/
@@ -70,9 +70,9 @@
             << cls::error_text(cls::code); \
         if ((msg)[0] != 0) stream << ": " << (msg); \
         stream << std::ends; \
- ctx.get_hooks().throw_exception(ctx, cls(stream.str().c_str(), \
- cls::code, (act_pos).get_line(), (act_pos).get_column(), \
- (act_pos).get_file().c_str())); \
+ ctx.get_hooks().throw_exception(ctx.derived(), \
+ cls(stream.str().c_str(), cls::code, (act_pos).get_line(), \
+ (act_pos).get_column(), (act_pos).get_file().c_str())); \
     } \
     /**/
 #endif // BOOST_NO_STRINGSTREAM
@@ -92,8 +92,8 @@
         if ((msg)[0] != 0) stream << ": " << (msg); \
         stream << std::ends; \
         std::string throwmsg = stream.str(); stream.freeze(false); \
- ctx.get_hooks().throw_exception(ctx, cls(throwmsg.c_str(), cls::code, \
- (act_pos).get_line(), (act_pos).get_column(), \
+ ctx.get_hooks().throw_exception(ctx.derived(), cls(throwmsg.c_str(), \
+ cls::code, (act_pos).get_line(), (act_pos).get_column(), \
             (act_pos).get_file().c_str(), (name))); \
     } \
     /**/
@@ -107,9 +107,9 @@
             << cls::error_text(cls::code); \
         if ((msg)[0] != 0) stream << ": " << (msg); \
         stream << std::ends; \
- ctx.get_hooks().throw_exception(ctx, cls(stream.str().c_str(), \
- cls::code, (act_pos).get_line(), (act_pos).get_column(), \
- (act_pos).get_file().c_str(), (name))); \
+ ctx.get_hooks().throw_exception(ctx.derived(), \
+ cls(stream.str().c_str(), cls::code, (act_pos).get_line(), \
+ (act_pos).get_column(), (act_pos).get_file().c_str(), (name))); \
     } \
     /**/
 #endif // BOOST_NO_STRINGSTREAM
@@ -129,8 +129,8 @@
         if ((msg)[0] != 0) stream << ": " << (msg); \
         stream << std::ends; \
         std::string throwmsg = stream.str(); stream.freeze(false); \
- ctx.get_hooks().throw_exception(ctx, cls(throwmsg.c_str(), code, \
- (act_pos).get_line(), (act_pos).get_column(), \
+ ctx.get_hooks().throw_exception(ctx.derived(), cls(throwmsg.c_str(), \
+ code, (act_pos).get_line(), (act_pos).get_column(), \
             (act_pos).get_file().c_str())); \
     } \
     /**/
@@ -144,9 +144,9 @@
             << cls::error_text(code); \
         if ((msg)[0] != 0) stream << ": " << (msg); \
         stream << std::ends; \
- ctx.get_hooks().throw_exception(ctx, cls(stream.str().c_str(), code, \
- (act_pos).get_line(), (act_pos).get_column(), \
- (act_pos).get_file().c_str())); \
+ ctx.get_hooks().throw_exception(ctx.derived(), \
+ cls(stream.str().c_str(), code, (act_pos).get_line(), \
+ (act_pos).get_column(), (act_pos).get_file().c_str())); \
     } \
     /**/
 #endif // BOOST_NO_STRINGSTREAM

Modified: trunk/boost/wave/grammars/cpp_defined_grammar.hpp
==============================================================================
--- trunk/boost/wave/grammars/cpp_defined_grammar.hpp (original)
+++ trunk/boost/wave/grammars/cpp_defined_grammar.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -145,10 +145,10 @@
 template <typename LexIteratorT>
 BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
 boost::spirit::parse_info<
- typename defined_grammar_gen<LexIteratorT>::iterator1_t
+ typename defined_grammar_gen<LexIteratorT>::iterator1_type
>
 defined_grammar_gen<LexIteratorT>::parse_operator_defined (
- iterator1_t const &first, iterator1_t const &last,
+ iterator1_type const &first, iterator1_type const &last,
     token_sequence_type &found_qualified_name)
 {
     using namespace boost::spirit;
@@ -162,10 +162,10 @@
 template <typename LexIteratorT>
 BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
 boost::spirit::parse_info<
- typename defined_grammar_gen<LexIteratorT>::iterator2_t
+ typename defined_grammar_gen<LexIteratorT>::iterator2_type
>
 defined_grammar_gen<LexIteratorT>::parse_operator_defined (
- iterator2_t const &first, iterator2_t const &last,
+ iterator2_type const &first, iterator2_type const &last,
     token_sequence_type &found_qualified_name)
 {
     using namespace boost::spirit;

Modified: trunk/boost/wave/grammars/cpp_defined_grammar_gen.hpp
==============================================================================
--- trunk/boost/wave/grammars/cpp_defined_grammar_gen.hpp (original)
+++ trunk/boost/wave/grammars/cpp_defined_grammar_gen.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -52,20 +52,20 @@
 
     typedef boost::wave::util::unput_queue_iterator<
             typename token_sequence_type::iterator, token_type, token_sequence_type>
- iterator1_t;
+ iterator1_type;
 
     typedef boost::wave::util::unput_queue_iterator<
             LexIteratorT, token_type, token_sequence_type>
- iterator2_t;
+ iterator2_type;
         
 // parse the operator defined and return the found qualified name
- static boost::spirit::parse_info<iterator1_t>
- parse_operator_defined (iterator1_t const &first, iterator1_t const &last,
- token_sequence_type &found_qualified_name);
-
- static boost::spirit::parse_info<iterator2_t>
- parse_operator_defined (iterator2_t const &first, iterator2_t const &last,
- token_sequence_type &found_qualified_name);
+ static boost::spirit::parse_info<iterator1_type>
+ parse_operator_defined (iterator1_type const &first,
+ iterator1_type const &last, token_sequence_type &found_qualified_name);
+
+ static boost::spirit::parse_info<iterator2_type>
+ parse_operator_defined (iterator2_type const &first,
+ iterator2_type const &last, token_sequence_type &found_qualified_name);
 };
 
 ///////////////////////////////////////////////////////////////////////////////

Modified: trunk/boost/wave/util/cpp_iterator.hpp
==============================================================================
--- trunk/boost/wave/util/cpp_iterator.hpp (original)
+++ trunk/boost/wave/util/cpp_iterator.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -393,7 +393,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
         ctx.get_hooks().returning_from_include_file();
 #else
- ctx.get_hooks().returning_from_include_file(ctx);
+ ctx.get_hooks().returning_from_include_file(ctx.derived());
 #endif
 
     // restore the previous iteration context after finishing the preprocessing
@@ -498,11 +498,11 @@
                 act_token.set_value("\n");
             }
             
- } while (ctx.get_hooks().may_skip_whitespace(ctx, act_token, skipped_newline));
+ } while (ctx.get_hooks().may_skip_whitespace(ctx.derived(), act_token, skipped_newline));
     }
     catch (boost::wave::cpplexer::lexing_exception const& e) {
     // dispatch any lexer exceptions to the context hook function
- ctx.get_hooks().throw_exception(ctx, e);
+ ctx.get_hooks().throw_exception(ctx.derived(), e);
         return act_token;
     }
         
@@ -514,7 +514,7 @@
         if (need_emit_line_directives(ctx.get_language()) && emit_line_directive())
         {
             skipped_newline = false;
- ctx.get_hooks().may_skip_whitespace(ctx, act_token, skipped_newline); // feed ws eater FSM
+ ctx.get_hooks().may_skip_whitespace(ctx.derived(), act_token, skipped_newline); // feed ws eater FSM
             id = token_id(act_token);
         }
     }
@@ -582,7 +582,7 @@
             act_token.get_position());
     }
     whitespace.shift_tokens(id);
- return ctx.get_hooks().generated_token(ctx, act_token);
+ return ctx.get_hooks().generated_token(ctx.derived(), act_token);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -652,7 +652,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
                     ctx.get_hooks().skipped_token(act_token);
 #else
- ctx.get_hooks().skipped_token(ctx, act_token);
+ ctx.get_hooks().skipped_token(ctx.derived(), act_token);
 #endif
                     continue;
                 }
@@ -687,7 +687,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
                 ctx.get_hooks().skipped_token(act_token);
 #else
- ctx.get_hooks().skipped_token(ctx, act_token);
+ ctx.get_hooks().skipped_token(ctx.derived(), act_token);
 #endif
                 ++iter_ctx->first;
             }
@@ -861,7 +861,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
             ctx.get_hooks().skipped_token(*it);
 #else
- ctx.get_hooks().skipped_token(ctx, *it);
+ ctx.get_hooks().skipped_token(ctx.derived(), *it);
 #endif
         }
         BOOST_ASSERT(it == end || id != T_UNKNOWN);
@@ -876,7 +876,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
         ctx.get_hooks().skipped_token(*it);
 #else
- ctx.get_hooks().skipped_token(ctx, *it);
+ ctx.get_hooks().skipped_token(ctx.derived(), *it);
 #endif
 
         for (++it; it != end; ++it) {
@@ -887,7 +887,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
                 ctx.get_hooks().skipped_token(*it);
 #else
- ctx.get_hooks().skipped_token(ctx, *it);
+ ctx.get_hooks().skipped_token(ctx.derived(), *it);
 #endif
                 ++it; // skip eol/C/C++ comment
                 return true; // no more significant tokens on this line
@@ -900,7 +900,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
             ctx.get_hooks().skipped_token(*it);
 #else
- ctx.get_hooks().skipped_token(ctx, *it);
+ ctx.get_hooks().skipped_token(ctx.derived(), *it);
 #endif
         }
         return false;
@@ -917,7 +917,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
             ctx.get_hooks().skipped_token(*it);
 #else
- ctx.get_hooks().skipped_token(ctx, *it);
+ ctx.get_hooks().skipped_token(ctx.derived(), *it);
 #endif
             if (T_CPPCOMMENT == id || T_NEWLINE == id ||
                 context_policies::util::ccomment_has_newline(*it))
@@ -999,7 +999,9 @@
 // start over with the next line, if only possible
     if (can_exit) {
         string_type value ((*it).get_value());
- if (!impl::skip_to_eol(ctx, it, iter_ctx->last)) {
+ if (!impl::skip_to_eol(ctx, it, iter_ctx->last) &&
+ !need_single_line(ctx.get_language()))
+ {
         // The line doesn't end with an eol but eof token.
             seen_newline = true; // allow to resume after warning
             iter_ctx->first = it;
@@ -1077,7 +1079,7 @@
     // the found pp directive
     bool result = dispatch_directive (hit, found_directive, found_eoltokens);
     
- if (found_eof) {
+ if (found_eof && !need_single_line(ctx.get_language())) {
         // The line was terminated with an end of file token.
         // So trigger a warning, that the last line was not terminated with a
         // newline.
@@ -1133,7 +1135,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
     ctx.get_hooks().found_directive(found_directive);
 #else
- if (ctx.get_hooks().found_directive(ctx, found_directive))
+ if (ctx.get_hooks().found_directive(ctx.derived(), found_directive))
         return true; // skip this directive and return newline only
 #endif
     
@@ -1293,7 +1295,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
     ctx.get_hooks().found_include_directive(f, include_next);
 #else
- if (ctx.get_hooks().found_include_directive(ctx, f, include_next))
+ if (ctx.get_hooks().found_include_directive(ctx.derived(), f, include_next))
         return true; // client returned false: skip file to include
 #endif
 
@@ -1330,7 +1332,7 @@
         ctx.get_hooks().opened_include_file(dir_path, file_path,
             ctx.get_iteration_depth(), is_system);
 #else
- ctx.get_hooks().opened_include_file(ctx, dir_path, file_path,
+ ctx.get_hooks().opened_include_file(ctx.derived(), dir_path, file_path,
             is_system);
 #endif
 
@@ -1568,7 +1570,7 @@
 #else
     do {
         is_defined = ctx.is_defined_macro(toexpand.begin(), toexpand.end());
- } while (ctx.get_hooks().evaluated_conditional_expression(ctx,
+ } while (ctx.get_hooks().evaluated_conditional_expression(ctx.derived(),
              found_directive, toexpand, is_defined));
 #endif
     ctx.enter_if_block(is_defined);
@@ -1601,7 +1603,7 @@
 #else
     do {
         is_defined = ctx.is_defined_macro(toexpand.begin(), toexpand.end());
- } while (ctx.get_hooks().evaluated_conditional_expression(ctx,
+ } while (ctx.get_hooks().evaluated_conditional_expression(ctx.derived(),
              found_directive, toexpand, is_defined));
 #endif
     ctx.enter_if_block(!is_defined);
@@ -1711,7 +1713,7 @@
         }
         catch (boost::wave::preprocess_exception const& e) {
         // any errors occurred have to be dispatched to the context hooks
- ctx.get_hooks().throw_exception(ctx, e);
+ ctx.get_hooks().throw_exception(ctx.derived(), e);
             break;
         }
                         
@@ -1719,7 +1721,7 @@
         ctx.get_hooks().evaluated_conditional_expression(toexpand, if_status);
     } while (false);
 #else
- } while (ctx.get_hooks().evaluated_conditional_expression(ctx,
+ } while (ctx.get_hooks().evaluated_conditional_expression(ctx.derived(),
                 found_directive, toexpand, if_status)
              && status == grammars::error_noerror);
 #endif
@@ -1815,14 +1817,14 @@
         }
         catch (boost::wave::preprocess_exception const& e) {
         // any errors occurred have to be dispatched to the context hooks
- ctx.get_hooks().throw_exception(ctx, e);
+ ctx.get_hooks().throw_exception(ctx.derived(), e);
         }
                 
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
         ctx.get_hooks().evaluated_conditional_expression(toexpand, if_status);
     } while (false);
 #else
- } while (ctx.get_hooks().evaluated_conditional_expression(ctx,
+ } while (ctx.get_hooks().evaluated_conditional_expression(ctx.derived(),
                 found_directive, toexpand, if_status)
              && status == grammars::error_noerror);
 #endif
@@ -1980,12 +1982,12 @@
         }
 
     // call the corresponding pp hook function
- ctx.get_hooks().found_line_directive(ctx, expanded, line,
+ ctx.get_hooks().found_line_directive(ctx.derived(), expanded, line,
             file_name.c_str());
     }
     else {
     // call the corresponding pp hook function
- ctx.get_hooks().found_line_directive(ctx, toexpand, line,
+ ctx.get_hooks().found_line_directive(ctx.derived(), toexpand, line,
             file_name.c_str());
     }
     
@@ -2044,13 +2046,13 @@
     typename token_sequence_type::iterator begin2 = toexpand.begin();
     ctx.expand_whole_tokensequence(begin2, toexpand.end(), expanded,
         false);
- if (!ctx.get_hooks().found_error_directive(ctx, toexpand))
+ if (!ctx.get_hooks().found_error_directive(ctx.derived(), toexpand))
 #else
 // simply copy the body of this #error message to the issued diagnostic
 // message
     std::copy(first, make_ref_transform_iterator(end, get_value),
         std::inserter(expanded, expanded.end()));
- if (!ctx.get_hooks().found_error_directive(ctx, expanded))
+ if (!ctx.get_hooks().found_error_directive(ctx.derived(), expanded))
 #endif
     {
     // report the corresponding error
@@ -2092,13 +2094,13 @@
     typename token_sequence_type::iterator begin2 = toexpand.begin();
     ctx.expand_whole_tokensequence(begin2, toexpand.end(), expanded,
         false);
- if (!ctx.get_hooks().found_warning_directive(ctx, toexpand))
+ if (!ctx.get_hooks().found_warning_directive(ctx.derived(), toexpand))
 #else
 // simply copy the body of this #warning message to the issued diagnostic
 // message
     std::copy(first, make_ref_transform_iterator(end, get_value),
         std::inserter(expanded, expanded.end()));
- if (!ctx.get_hooks().found_warning_directive(ctx, expanded))
+ if (!ctx.get_hooks().found_warning_directive(ctx.derived(), expanded))
 #endif
     {
     // report the corresponding error
@@ -2208,7 +2210,8 @@
     if (it == end) // eof reached
         return false;
 
- return boost::wave::util::interpret_pragma(ctx, act_token, it, end, result);
+ return boost::wave::util::interpret_pragma(
+ ctx.derived(), act_token, it, end, result);
 }
 
 ///////////////////////////////////////////////////////////////////////////////

Modified: trunk/boost/wave/util/cpp_macromap.hpp
==============================================================================
--- trunk/boost/wave/util/cpp_macromap.hpp (original)
+++ trunk/boost/wave/util/cpp_macromap.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -373,7 +373,7 @@
         (*p.first).second->macroparameters,
         (*p.first).second->macrodefinition, is_predefined);
 #else
- ctx.get_hooks().defined_macro(ctx, name, has_parameters,
+ ctx.get_hooks().defined_macro(ctx.derived(), name, has_parameters,
         (*p.first).second->macroparameters,
         (*p.first).second->macrodefinition, is_predefined);
 #endif
@@ -504,7 +504,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
         ctx.get_hooks().undefined_macro(token);
 #else
- ctx.get_hooks().undefined_macro(ctx, token);
+ ctx.get_hooks().undefined_macro(ctx.derived(), token);
 #endif
         return true;
     }
@@ -870,10 +870,10 @@
 bool seen_newline;
     
     while (!pending_queue.empty() || first_it != last_it) {
- token_type t = expand_tokensequence_worker(pending_queue, first_it,
- last_it, seen_newline, expand_operator_defined);
-
- expanded.push_back(t);
+ expanded.push_back(
+ expand_tokensequence_worker(pending_queue, first_it,
+ last_it, seen_newline, expand_operator_defined)
+ );
     }
 
 // should have returned all expanded tokens
@@ -1269,8 +1269,8 @@
                 macro_def.macroname, macro_def.macroparameters,
                 macro_def.macrodefinition, curr_token, arguments);
 #else
- if (ctx.get_hooks().expanding_function_like_macro(
- ctx, macro_def.macroname, macro_def.macroparameters,
+ if (ctx.get_hooks().expanding_function_like_macro(ctx.derived(),
+ macro_def.macroname, macro_def.macroparameters,
                     macro_def.macrodefinition, curr_token, arguments,
                     seqstart, seqend))
             {
@@ -1291,9 +1291,8 @@
             ctx.get_hooks().expanding_object_like_macro(
                 macro_def.macroname, macro_def.macrodefinition, curr_token);
 #else
- if (ctx.get_hooks().expanding_object_like_macro(
- ctx, macro_def.macroname, macro_def.macrodefinition,
- curr_token))
+ if (ctx.get_hooks().expanding_object_like_macro(ctx.derived(),
+ macro_def.macroname, macro_def.macrodefinition, curr_token))
             {
                 // do not expand this macro, just copy the whole sequence
                 replacement_list.push_back(curr_token);
@@ -1335,9 +1334,8 @@
             ctx.get_hooks().expanding_object_like_macro(
                 macro_def.macroname, macro_def.macrodefinition, curr_token);
 #else
- if (ctx.get_hooks().expanding_object_like_macro(
- ctx, macro_def.macroname, macro_def.macrodefinition,
- curr_token))
+ if (ctx.get_hooks().expanding_object_like_macro(ctx.derived(),
+ macro_def.macroname, macro_def.macrodefinition, curr_token))
             {
                 // do not expand this macro, just copy the whole sequence
                 replacement_list.push_back(curr_token);
@@ -1368,7 +1366,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
     ctx.get_hooks().expanded_macro(replacement_list);
 #else
- ctx.get_hooks().expanded_macro(ctx, replacement_list);
+ ctx.get_hooks().expanded_macro(ctx.derived(), replacement_list);
 #endif
     
     rescan_replacement_list(curr_token, macro_def, replacement_list,
@@ -1377,7 +1375,7 @@
 #if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0
     ctx.get_hooks().rescanned_macro(expanded_list);
 #else
- ctx.get_hooks().rescanned_macro(ctx, expanded_list);
+ ctx.get_hooks().rescanned_macro(ctx.derived(), expanded_list);
 #endif
     expanded.splice(expanded.end(), expanded_list);
     return true; // rescan is required
@@ -1387,7 +1385,7 @@
 //
 // If the token under inspection points to a certain predefined macro it will
 // be expanded, otherwise false is returned.
-// (only __FILE__, __LINE__ and __INCLUDE_LEVEL__ macros are expaned here)
+// (only __FILE__, __LINE__ and __INCLUDE_LEVEL__ macros are expanded here)
 //
 ///////////////////////////////////////////////////////////////////////////////
 template <typename ContextT>

Modified: trunk/boost/wave/util/cpp_macromap_utils.hpp
==============================================================================
--- trunk/boost/wave/util/cpp_macromap_utils.hpp (original)
+++ trunk/boost/wave/util/cpp_macromap_utils.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -100,7 +100,8 @@
     //
     ///////////////////////////////////////////////////////////////////////////
     template <typename IteratorT, typename UnputIteratorT>
- class assign {
+ class assign
+ {
     public:
         assign(IteratorT &it_, UnputIteratorT const &uit_)
         : it(it_), uit(uit_) {}

Modified: trunk/boost/wave/util/interpret_pragma.hpp
==============================================================================
--- trunk/boost/wave/util/interpret_pragma.hpp (original)
+++ trunk/boost/wave/util/interpret_pragma.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -19,6 +19,7 @@
 #include <boost/spirit/actor/assign_actor.hpp>
 #include <boost/spirit/actor/push_back_actor.hpp>
 #endif // SPIRIT_VERSION >= 0x1700
+#include <boost/spirit/utility/confix.hpp>
 
 #include <boost/wave/wave_config.hpp>
 
@@ -105,12 +106,10 @@
                                     spirit_assign_actor(option)
                                 ]
                             )
- >> !( ch_p(T_LEFTPAREN)
- >> lexeme_d[
- *(anychar_p[spirit_append_actor(values)] - ch_p(T_RIGHTPAREN))
- ]
- >> ch_p(T_RIGHTPAREN)
- ),
+ >> !comment_nest_p(
+ ch_p(T_LEFTPAREN),
+ ch_p(T_RIGHTPAREN)
+ )[spirit_assign_actor(values)],
                     pattern_p(WhiteSpaceTokenType, TokenTypeMask)).hit)
             {
                 BOOST_WAVE_THROW_CTX(ctx, preprocess_exception,
@@ -120,16 +119,17 @@
                 return false;
             }
         
- // remove the falsely matched closing parenthesis
- if (values.size() > 0) {
- BOOST_ASSERT(T_RIGHTPAREN == values.back());
+ // remove the falsely matched surrounding parenthesis's
+ if (values.size() >= 2) {
+ BOOST_ASSERT(T_LEFTPAREN == values.front() && T_RIGHTPAREN == values.back());
+ values.erase(values.begin());
                 typename ContainerT::reverse_iterator rit = values.rbegin();
                 values.erase((++rit).base());
             }
             
         // decode the option (call the context_policy hook)
             if (!ctx.get_hooks().interpret_pragma(
- ctx, pending, option, values, act_token))
+ ctx.derived(), pending, option, values, act_token))
             {
             // unknown #pragma option
             string_type option_str ((*it).get_value());

Modified: trunk/libs/wave/ChangeLog
==============================================================================
--- trunk/libs/wave/ChangeLog (original)
+++ trunk/libs/wave/ChangeLog 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -24,8 +24,18 @@
 
 CHANGELOG
 
+Boost V1.36
 - Wave Version 1.4
-
+- Added an additional template parameter to the context object, allowing to
+ specify any possibly derived type. This change propagates to the preprocessing
+ hooks, which now get passed the most derived context type as its first
+ argument allowing to access protected members in the original context type.
+- Fixed a problem during parsing of #pragma wave directive, where the value
+ sequence contained a closing parenthesis. This caused a premature end of the
+ pragma value parsing.
+- Fixed handling of support_option_single_line, which was ignored under certain
+ circumstances.
+
 Boost V1.35.0
 - Wave Version 1.3
 - Changed the return value of the 'evaluated_conditional_expression()' pp hook

Modified: trunk/libs/wave/samples/Jamfile.v2
==============================================================================
--- trunk/libs/wave/samples/Jamfile.v2 (original)
+++ trunk/libs/wave/samples/Jamfile.v2 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -16,3 +16,4 @@
 build-project hannibal/build ;
 build-project real_positions/build ;
 build-project token_statistics/build ;
+build-project preprocess_pragma_output/build ;

Added: trunk/libs/wave/samples/preprocess_pragma_output/build/Jamfile.v2
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/preprocess_pragma_output/build/Jamfile.v2 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -0,0 +1,22 @@
+# Boost.Wave: A Standard compliant C++ preprocessor library
+#
+# Boost Wave Library Sample Build Jamfile (preprocess_pragma_output)
+#
+# http://www.boost.org/
+#
+# Copyright (c) 2001-2008 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)
+
+exe preprocess_pragma_output
+ : ../preprocess_pragma_output.cpp
+ /boost/wave//boost_wave
+ /boost/thread//boost_thread
+ /boost/date_time//boost_date_time
+ /boost/filesystem//boost_filesystem
+ /boost/system//boost_system
+ :
+ <toolset>msvc-8.0:<define>_SCL_SECURE_NO_DEPRECATE
+ <toolset>msvc-8.0:<define>_CRT_SECURE_NO_DEPRECATE
+ ;
+

Added: trunk/libs/wave/samples/preprocess_pragma_output/example.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/preprocess_pragma_output/example.cpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -0,0 +1,23 @@
+/*=============================================================================
+ Boost.Wave: A Standard compliant C++ preprocessor library
+ Example demonstrating how to preprocess the token stream generated by a
+ #pragma directive
+
+ http://www.boost.org/
+
+ Copyright (c) 2001-2008 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// This special pragma will be analyzed by the corresponding hook function
+// implemented in the preprocess_pragma_output_hooks policy class. This
+// #pragma preprocesses the provided arguments in the current context.
+#pragma wave pp ( \
+ #define M() "some text" \
+ ) \
+ /**/
+
+M() // this should produce: "some text"
+

Added: trunk/libs/wave/samples/preprocess_pragma_output/preprocess_pragma_output.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/preprocess_pragma_output/preprocess_pragma_output.cpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -0,0 +1,115 @@
+/*=============================================================================
+ Boost.Wave: A Standard compliant C++ preprocessor library
+ Example demonstrating how to preprocess the token stream generated by a
+ #pragma directive
+
+ http://www.boost.org/
+
+ Copyright (c) 2001-2008 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)
+=============================================================================*/
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+///////////////////////////////////////////////////////////////////////////////
+// Include Wave itself
+#include <boost/wave.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// Include the lexer stuff
+#include <boost/wave/cpplexer/cpp_lex_token.hpp> // token class
+#include <boost/wave/cpplexer/cpp_lex_iterator.hpp> // lexer class
+
+///////////////////////////////////////////////////////////////////////////////
+// Include special preprocessing hooks
+#include "preprocess_pragma_output.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// main entry point
+int main(int argc, char *argv[])
+{
+ if (2 != argc) {
+ std::cerr << "Usage: preprocess_pragma_output infile" << std::endl;
+ return -1;
+ }
+
+// current file position is saved for exception handling
+boost::wave::util::file_position_type current_position;
+
+ try {
+ // Open and read in the specified input file.
+ std::ifstream instream(argv[1]);
+ std::string instring;
+
+ if (!instream.is_open()) {
+ std::cerr << "Could not open input file: " << argv[1] << std::endl;
+ return -2;
+ }
+ instream.unsetf(std::ios::skipws);
+ instring = std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
+ std::istreambuf_iterator<char>());
+
+ // The template boost::wave::cpplexer::lex_token<> is the token type to be
+ // used by the Wave library.
+ typedef boost::wave::cpplexer::lex_token<> token_type;
+
+ // The template boost::wave::cpplexer::lex_iterator<> is the lexer type to
+ // be used by the Wave library.
+ typedef boost::wave::cpplexer::lex_iterator<token_type> lex_iterator_type;
+
+ // This is the resulting context type to use.
+ typedef boost::wave::context<
+ std::string::iterator, lex_iterator_type,
+ boost::wave::iteration_context_policies::load_file_to_string,
+ preprocess_pragma_output_hooks>
+ 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).
+ //
+ // 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]);
+
+ // analyze the input file
+ context_type::iterator_type first = ctx.begin();
+ context_type::iterator_type last = ctx.end();
+
+ while (first != last) {
+ current_position = (*first).get_position();
+ std::cout << (*first).get_value();
+ ++first;
+ }
+ }
+ catch (boost::wave::cpp_exception const& e) {
+ // some preprocessing error
+ std::cerr
+ << e.file_name() << "(" << e.line_no() << "): "
+ << e.description() << std::endl;
+ return 2;
+ }
+ catch (std::exception const& e) {
+ // use last recognized token to retrieve the error position
+ std::cerr
+ << current_position.get_file()
+ << "(" << current_position.get_line() << "): "
+ << "exception caught: " << e.what()
+ << std::endl;
+ return 3;
+ }
+ catch (...) {
+ // use last recognized token to retrieve the error position
+ std::cerr
+ << current_position.get_file()
+ << "(" << current_position.get_line() << "): "
+ << "unexpected exception caught." << std::endl;
+ return 4;
+ }
+ return 0;
+}

Added: trunk/libs/wave/samples/preprocess_pragma_output/preprocess_pragma_output.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/preprocess_pragma_output/preprocess_pragma_output.hpp 2008-04-03 16:09:41 EDT (Thu, 03 Apr 2008)
@@ -0,0 +1,126 @@
+/*=============================================================================
+ Boost.Wave: A Standard compliant C++ preprocessor library
+ Example demonstrating how to preprocess the token stream generated by a
+ #pragma directive
+
+ http://www.boost.org/
+
+ Copyright (c) 2001-2008 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)
+=============================================================================*/
+
+#if !defined(BOOST_WAVE_SAMPLE_PREPROCESS_PRAGMA_OUTPUT_APR_03_2008_0813AM)
+#define BOOST_WAVE_SAMPLE_PREPROCESS_PRAGMA_OUTPUT_APR_03_2008_0813AM
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// The preprocess_pragma_output_hooks policy class is used implement a special
+// #pragma wave pp("some C++ code") directive allowing to insert preprocessed
+// code into the output sequence generated by the tool.
+//
+// This policy type is used as a template parameter to the boost::wave::context<>
+// object.
+//
+///////////////////////////////////////////////////////////////////////////////
+class preprocess_pragma_output_hooks
+: public boost::wave::context_policies::default_preprocessing_hooks
+{
+public:
+ preprocess_pragma_output_hooks() {}
+
+ template <typename Context>
+ struct reset_language_support
+ {
+ reset_language_support(Context& ctx)
+ : ctx_(ctx), lang_(ctx.get_language())
+ {
+ ctx.set_language(boost::wave::enable_single_line(lang_), false);
+ }
+ ~reset_language_support()
+ {
+ ctx_.set_language(lang_, false);
+ }
+
+ Context& ctx_;
+ boost::wave::language_support lang_;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The function 'interpret_pragma' is called, whenever a #pragma command
+ // directive is found which isn't known to the core Wave library, where
+ // command is the value defined as the BOOST_WAVE_PRAGMA_KEYWORD constant
+ // which defaults to "wave".
+ //
+ // The parameter 'ctx' is a reference to the context object used for
+ // instantiating the preprocessing iterators by the user.
+ //
+ // The parameter 'pending' may be used to push tokens back into the input
+ // stream, which are to be used as the replacement text for the whole
+ // #pragma directive.
+ //
+ // The parameter 'option' contains the name of the interpreted pragma.
+ //
+ // The parameter 'values' holds the values of the parameter provided to
+ // the pragma operator.
+ //
+ // The parameter 'act_token' contains the actual #pragma token, which may
+ // be used for error output.
+ //
+ // If the return value is 'false', the whole #pragma directive is
+ // interpreted as unknown and a corresponding error message is issued. A
+ // return value of 'true' signs a successful interpretation of the given
+ // #pragma.
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Context, typename Container>
+ bool
+ interpret_pragma(Context& ctx, Container &pending,
+ typename Context::token_type const& option,
+ Container const& values, typename Context::token_type const& act_token)
+ {
+ typedef typename Context::token_type token_type;
+ typedef typename Context::iterator_type iterator_type;
+
+ if (option.get_value() == "pp")
+ {
+ try {
+ // We're explicitly using a std::string here since the type of the
+ // iterators passed to the ctx.begin() below must match the types
+ // of the iterator the original context instance has been created
+ // with.
+ std::string s (boost::wave::util::impl::as_string(values).c_str());
+ reset_language_support<Context> lang(ctx);
+
+ using boost::wave::token_id;
+ using boost::wave::T_EOF;
+
+ Container pragma;
+ iterator_type end = ctx.end();
+ for (iterator_type it = ctx.begin(s.begin(), s.end());
+ it != end && token_id(*it) != T_EOF; ++it)
+ {
+ pragma.push_back(*it);
+ it++;
+ }
+
+ // prepend the newly generated token sequence to the 'pending'
+ // container
+ pending.splice(pending.begin(), pragma);
+ }
+ catch (boost::wave::preprocess_exception const& e) {
+ // the library will report an 'ill_formed_pragma_option' for us
+ return false;
+ }
+ return true;
+ }
+
+ // we don't know anything about this #pragma wave directive
+ return false;
+ }
+};
+
+
+#endif
+


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