Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56629 - in branches/release: boost/wave boost/wave/util libs/wave libs/wave/doc libs/wave/test/testwave libs/wave/test/testwave/testfiles tools/wave
From: hartmut.kaiser_at_[hidden]
Date: 2009-10-06 20:04:15


Author: hkaiser
Date: 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
New Revision: 56629
URL: http://svn.boost.org/trac/boost/changeset/56629

Log:
Wave: merging from trunk
Added:
   branches/release/libs/wave/test/testwave/testfiles/t_2_019.cpp
      - copied unchanged from r56618, /trunk/libs/wave/test/testwave/testfiles/t_2_019.cpp
   branches/release/libs/wave/test/testwave/testfiles/t_2_019_001.hpp
      - copied unchanged from r56618, /trunk/libs/wave/test/testwave/testfiles/t_2_019_001.hpp
   branches/release/libs/wave/test/testwave/testfiles/t_2_019_002.hpp
      - copied unchanged from r56618, /trunk/libs/wave/test/testwave/testfiles/t_2_019_002.hpp
   branches/release/libs/wave/test/testwave/testfiles/t_2_019_003.hpp
      - copied unchanged from r56618, /trunk/libs/wave/test/testwave/testfiles/t_2_019_003.hpp
Properties modified:
   branches/release/boost/wave/ (props changed)
   branches/release/libs/wave/ (props changed)
   branches/release/tools/wave/ (props changed)
Text files modified:
   branches/release/boost/wave/cpp_context.hpp | 14 +++++
   branches/release/boost/wave/preprocessing_hooks.hpp | 82 ++++++++++++++++++++++++++++++++-
   branches/release/boost/wave/util/cpp_include_paths.hpp | 2
   branches/release/boost/wave/util/cpp_iterator.hpp | 18 ++++--
   branches/release/boost/wave/util/file_position.hpp | 14 ++--
   branches/release/boost/wave/util/interpret_pragma.hpp | 12 ++--
   branches/release/libs/wave/ChangeLog | 9 ++
   branches/release/libs/wave/doc/class_reference_ctxpolicy.html | 96 +++++++++++++++++++++++++++++++--------
   branches/release/libs/wave/doc/class_reference_filepos.html | 18 +++---
   branches/release/libs/wave/doc/wave_driver.html | 17 ++++++
   branches/release/libs/wave/test/testwave/collect_hooks_information.hpp | 83 ++++++++++++++++++++++++++++++++++
   branches/release/libs/wave/test/testwave/testfiles/t_2_009.cpp | 1
   branches/release/libs/wave/test/testwave/testfiles/t_9_016.cpp | 1
   branches/release/libs/wave/test/testwave/testfiles/test.cfg | 1
   branches/release/tools/wave/cpp.cpp | 33 ++++++++++++
   branches/release/tools/wave/trace_macro_expansion.hpp | 69 ++++++++++++++++++++++++++--
   16 files changed, 404 insertions(+), 66 deletions(-)

Modified: branches/release/boost/wave/cpp_context.hpp
==============================================================================
--- branches/release/boost/wave/cpp_context.hpp (original)
+++ branches/release/boost/wave/cpp_context.hpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -403,8 +403,18 @@
     bool has_pragma_once(std::string const &filename_)
         { return includes.has_pragma_once(filename_); }
     bool add_pragma_once_header(std::string const &filename_,
- std::string const& guard_name = "__BOOST_WAVE_PRAGMA_ONCE__")
- { return includes.add_pragma_once_header(filename_, guard_name); }
+ std::string const& guard_name)
+ {
+ get_hooks().detected_include_guard(derived(), filename_, guard_name);
+ return includes.add_pragma_once_header(filename_, guard_name);
+ }
+ bool add_pragma_once_header(token_type const &pragma_,
+ std::string const &filename_)
+ {
+ get_hooks().detected_pragma_once(derived(), pragma_, filename_);
+ return includes.add_pragma_once_header(filename_,
+ "__BOOST_WAVE_PRAGMA_ONCE__");
+ }
 #endif
 
 #if BOOST_WAVE_SERIALIZATION != 0

Modified: branches/release/boost/wave/preprocessing_hooks.hpp
==============================================================================
--- branches/release/boost/wave/preprocessing_hooks.hpp (original)
+++ branches/release/boost/wave/preprocessing_hooks.hpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -238,7 +238,7 @@
         std::string const& absname, bool is_system_include)
     {}
 #endif
-
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // The function 'returning_from_include_file' is called, whenever an
@@ -261,6 +261,80 @@
     {}
 #endif
 
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The function 'detected_include_guard' is called whenever either a
+ // include file is about to be added to the list of #pragma once headers.
+ // That means this header file will not be opened and parsed again even
+ // if it is specified in a later #include directive.
+ // This function is called as the result of a detected include guard
+ // scheme.
+ //
+ // The implemented heuristics for include guards detects two forms of
+ // include guards:
+ //
+ // #ifndef INCLUDE_GUARD_MACRO
+ // #define INCLUDE_GUARD_MACRO
+ // ...
+ // #endif
+ //
+ // or
+ //
+ // if !defined(INCLUDE_GUARD_MACRO)
+ // #define INCLUDE_GUARD_MACRO
+ // ...
+ // #endif
+ //
+ // note, that the parenthesis are optional (i.e. !defined INCLUDE_GUARD_MACRO
+ // will work as well). The code allows for any whitespace, newline and single
+ // '#' tokens before the #if/#ifndef and after the final #endif.
+ //
+ // The parameter 'ctx' is a reference to the context object used for
+ // instantiating the preprocessing iterators by the user.
+ //
+ // The parameter 'filename' contains the file system path of the
+ // opened file (this is relative to the directory of the currently
+ // processed file or a absolute path depending on the paths given as the
+ // include search paths).
+ //
+ // The parameter contains the name of the detected include guard.
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename ContextT>
+ void
+ detected_include_guard(ContextT const& ctx, std::string const& filename,
+ std::string const& include_guard)
+ {}
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The function 'detected_pragma_once' is called whenever either a
+ // include file is about to be added to the list of #pragma once headers.
+ // That means this header file will not be opened and parsed again even
+ // if it is specified in a later #include directive.
+ // This function is called as the result of a detected directive
+ // #pragma once.
+ //
+ // The parameter 'ctx' is a reference to the context object used for
+ // instantiating the preprocessing iterators by the user.
+ //
+ // The parameter pragma_token refers to the token "#pragma" triggering
+ // this preprocessing hook.
+ //
+ // The parameter 'filename' contains the file system path of the
+ // opened file (this is relative to the directory of the currently
+ // processed file or a absolute path depending on the paths given as the
+ // include search paths).
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename ContextT, typename TokenT>
+ void
+ detected_pragma_once(ContextT const& ctx, TokenT const& pragma_token,
+ std::string const& filename)
+ {}
+#endif
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // The function 'interpret_pragma' is called, whenever a '#pragma command'
@@ -368,7 +442,7 @@
     undefined_macro(ContextT const& ctx, TokenT const& macro_name)
     {}
 #endif
-
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // The function 'found_directive' is called, whenever a preprocessor
@@ -441,7 +515,7 @@
         bool expression_value)
     { return false; } // ok to continue, do not re-evaluate expression
 #endif
-
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // The function 'skipped_token' is called, whenever a token is about to be
@@ -591,7 +665,7 @@
     found_line_directive(ContextT const& ctx, ContainerT const& arguments,
         unsigned int line, std::string const& filename)
     {}
-
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // The function 'throw_exception' will be called by the library whenever a

Modified: branches/release/boost/wave/util/cpp_include_paths.hpp
==============================================================================
--- branches/release/boost/wave/util/cpp_include_paths.hpp (original)
+++ branches/release/boost/wave/util/cpp_include_paths.hpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -440,7 +440,7 @@
     using namespace boost::serialization;
     std::string path_str;
     ar & make_nvp("filepath", path_str);
- p = boost::filesystem::path(path_str, boost::filesystem::native);
+ p = wave::util::create_path(path_str);
 }
 
 // split non-intrusive serialization function member into separate

Modified: branches/release/boost/wave/util/cpp_iterator.hpp
==============================================================================
--- branches/release/boost/wave/util/cpp_iterator.hpp (original)
+++ branches/release/boost/wave/util/cpp_iterator.hpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -427,7 +427,10 @@
 
     // restore the actual current file and directory
 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
- ctx.set_current_filename(iter_ctx->real_filename.c_str());
+ namespace fs = boost::filesystem;
+ fs::path rfp(wave::util::create_path(iter_ctx->real_filename.c_str()));
+ std::string real_filename(rfp.string());
+ ctx.set_current_filename(real_filename.c_str());
 #endif
         ctx.set_current_directory(iter_ctx->real_filename.c_str());
 
@@ -1523,18 +1526,17 @@
     }
 
 // test, if this file is known through a #pragma once directive
+ std::string native_path_str(wave::util::native_file_string(native_path));
 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
- if (!ctx.has_pragma_once(wave::util::native_file_string(native_path)))
+ if (!ctx.has_pragma_once(native_path.string()))
 #endif
     {
     // the new include file determines the actual current directory
- ctx.set_current_directory(
- wave::util::native_file_string(native_path).c_str());
+ ctx.set_current_directory(native_path_str.c_str());
 
     // preprocess the opened file
     boost::shared_ptr<base_iteration_context_type> new_iter_ctx (
- new iteration_context_type(ctx,
- wave::util::native_file_string(native_path).c_str(),
+ new iteration_context_type(ctx, native_path_str.c_str(),
             act_pos, boost::wave::enable_prefer_pp_numbers(ctx.get_language())));
 
     // call the include policy trace function
@@ -1559,7 +1561,9 @@
 
         act_pos.set_file(iter_ctx->filename); // initialize file position
 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
- ctx.set_current_filename(iter_ctx->real_filename.c_str());
+ fs::path rfp(wave::util::create_path(iter_ctx->real_filename.c_str()));
+ std::string real_filename(rfp.string());
+ ctx.set_current_filename(real_filename.c_str());
 #endif
 
         act_pos.set_line(iter_ctx->line);

Modified: branches/release/boost/wave/util/file_position.hpp
==============================================================================
--- branches/release/boost/wave/util/file_position.hpp (original)
+++ branches/release/boost/wave/util/file_position.hpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -78,12 +78,12 @@
 
 public:
     typedef StringT string_type;
-
+
     file_position()
     : file(), line(1), column(1)
     {}
- explicit file_position(string_type const& file_, int line_ = 1,
- int column_ = 1)
+ explicit file_position(string_type const& file_, unsigned int line_ = 1,
+ unsigned int column_ = 1)
     : file(file_), line(line_), column(column_)
     {
         BOOST_ASSERT(!debug::is_escaped_lit(file));
@@ -93,7 +93,7 @@
     string_type const &get_file() const { return file; }
     unsigned int get_line() const { return line; }
     unsigned int get_column() const { return column; }
-
+
     void set_file(string_type const &file_)
     {
         file = file_;
@@ -101,7 +101,7 @@
     }
     void set_line(unsigned int line_) { line = line_; }
     void set_column(unsigned int column_) { column = column_; }
-
+
 private:
 #if BOOST_WAVE_SERIALIZATION != 0
     friend class boost::serialization::access;
@@ -154,11 +154,11 @@
 : boost::spirit::classic::position_iterator<IteratorT, PositionT>
 {
     typedef boost::spirit::classic::position_iterator<IteratorT, PositionT> base_type;
-
+
     position_iterator()
     {
     }
-
+
     position_iterator(IteratorT const &begin, IteratorT const &end,
             PositionT const &pos)
     : base_type(begin, end, pos)

Modified: branches/release/boost/wave/util/interpret_pragma.hpp
==============================================================================
--- branches/release/boost/wave/util/interpret_pragma.hpp (original)
+++ branches/release/boost/wave/util/interpret_pragma.hpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -58,7 +58,7 @@
 {
     typedef typename ContextT::token_type token_type;
     typedef typename token_type::string_type string_type;
-
+
     using namespace cpplexer;
     if (T_IDENTIFIER == token_id(*it)) {
     // check for pragma wave ...
@@ -111,7 +111,7 @@
                     act_token.get_position());
                 return false;
             }
-
+
         // remove the falsely matched surrounding parenthesis's
             if (values.size() >= 2) {
                 BOOST_ASSERT(T_LEFTPAREN == values.front() && T_RIGHTPAREN == values.back());
@@ -119,7 +119,7 @@
                 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.derived(), pending, option, values, act_token))
@@ -143,7 +143,7 @@
 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
         else if ((*it).get_value() == "once") {
         // #pragma once
- return ctx.add_pragma_once_header(ctx.get_current_filename());
+ return ctx.add_pragma_once_header(act_token, ctx.get_current_filename());
         }
 #endif
 #if BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE != 0
@@ -151,7 +151,7 @@
         // #pragma message(...) or #pragma message ...
             using namespace boost::spirit::classic;
             ContainerT values;
-
+
             if (!parse (++it, end,
                             ( ( ch_p(T_LEFTPAREN)
>> lexeme_d[
@@ -173,7 +173,7 @@
                     act_token.get_position());
                 return false;
             }
-
+
         // remove the falsely matched closing parenthesis/newline
             if (values.size() > 0) {
                 BOOST_ASSERT(T_RIGHTPAREN == values.back() || T_NEWLINE == values.back());

Modified: branches/release/libs/wave/ChangeLog
==============================================================================
--- branches/release/libs/wave/ChangeLog (original)
+++ branches/release/libs/wave/ChangeLog 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -16,8 +16,6 @@
 - Fix the trigraph backslash problem in the re2c (C/C++ and IDL) scanners, if
   there is the end of the (internal) buffer just in between a '??/' and a '\n'.
 
-- Do a sourceforge release.
-
 -------------------------------------------------------------------------------
 
 CHANGELOG
@@ -37,6 +35,13 @@
   (default is cout).
 - Fixed compilation problems caused by recent changes to the multi_pass iterator
   from Spirit V2.1.
+- Added a new preprocessing hooks detected_pragma_once() and
+ detected_include_guard() which are getting called whenever either a #pragma
+ once has been detected or if the include guard heuristics detected an
+ include guard for a particular include file.
+- Added a new command line option to the wave driver tool: --listguards/-g
+ allowing to trace all include files which are either contain a #pragma once
+ or contain include guards.
 
 Boost V1.40.0
 - V2.0.2

Modified: branches/release/libs/wave/doc/class_reference_ctxpolicy.html
==============================================================================
--- branches/release/libs/wave/doc/class_reference_ctxpolicy.html (original)
+++ branches/release/libs/wave/doc/class_reference_ctxpolicy.html 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -4,6 +4,11 @@
 <title>The Context Policy</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <link href="theme/style.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+.style1 {
+ background-color: #EEEEEE;
+}
+</style>
 </head>
 <body>
 <table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
@@ -56,21 +61,33 @@
         <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ExceptionT&gt;<br> void throw_exception(ContextT <span class="keyword">const</span> &amp;ctx, <br> ExceptionT <span class="keyword">const</span>&amp; e);<br><br> <span class="comment">// test, whether a given token may be skipped</span><br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">bool</span> may_skip_whitespace (ContextT <span class="keyword">const</span>&amp; ctx,<br> TokenT &amp;token, <span class="keyword">bool</span> &amp;skipped_newline);<br>
         <span class="comment">// Conditional compilation</span><span class="keyword">
         template</span> &lt;<br> <span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <br> <span class="keyword">typename</span> ContainerT<br> &gt;<br> <span class="keyword">bool</span> evaluated_conditional_expression(<br> ContextT <span class="keyword">const</span> &amp;ctx, TokenT <span class="keyword">const</span>&amp; directive, <br> ContainerT <span class="keyword">const</span>&amp; expression, <span class="keyword">bool</span> expression_value);<br>
- <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">void</span> skipped_token(ContextT <span class="keyword">const</span> &amp;ctx, <br> TokenT <span class="keyword">const</span>&amp; token);<br><br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> TokenT <span class="keyword">const</span>&amp; generated_token(ContextT <span class="keyword">const</span> &amp;ctx, <br> TokenT <span class="keyword">const</span>&amp; token);<br><br> <span class="comment">// macro expansion tracing</span><span class="keyword">
+ <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">void</span> skipped_token(ContextT <span class="keyword">const</span> &amp;ctx, <br> TokenT <span class="keyword">const</span>&amp; token);<br><br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> TokenT <span class="keyword">const</span>&amp; generated_token(ContextT <span class="keyword">const</span> &amp;ctx, <br> TokenT <span class="keyword">const</span>&amp; token);<br><br> <span class="comment">// macro expansion tracing</span><span class="keyword">
         template</span> &lt;<span class="keyword">
- typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT,<br> <span class="keyword">typename</span> IteratorT<br> &gt;<br> <span class="keyword">bool</span> expanding_function_like_macro(<br> ContextT <span class="keyword">const</span> &amp;ctx, TokenT <span class="keyword">const</span> &amp;macrodef, <br> <span class="keyword">std::vector</span>&lt;TokenT&gt; <span class="keyword">const</span> &amp;formal_args, <br> ContainerT <span class="keyword">const</span> &amp;definition, TokenT <span class="keyword">const</span> &amp;macrocall, <br> <span class="keyword">std::vector</span>&lt;ContainerT&gt; <span class="keyword">const</span> &amp;arguments,<br> IteratorT <span class="keyword">const</span> &amp;seqstart, Iterator <span class="keyword">const</span> &amp;seqend);<br> <br>
    <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> expanding_object_like_macro(<br> ContextT <span class="keyword">const</span> &amp;ctx, TokenT <span class="keyword">const</span> &amp;macro, <br> ContainerT <span class="keyword">const</span> &amp;definition, TokenT <span class="keyword">const</span> &amp;macrocall);<br> <br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> expanded_macro(ContextT <span class="keyword">const</span> &amp;ctx, <br> ContainerT <span class="keyword">const</span> &amp;result);<br> <br>
   <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> rescanned_macro(ContextT <span class="keyword">const</span> &amp;ctx, <br> ContainerT <span class="keyword">const</span> &amp;result);<br><br> <span class="comment">// include file tracing functions</span>
- <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">bool</span> found_include_directive(ContextT <span class="keyword">const</span> &amp;ctx, <br> std::string <span class="keyword">const</span> &amp;filename, <span class="keyword">bool</span> include_next);<br><br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void </span>opened_include_file(ContextT <span class="keyword">const</span> &amp;ctx, <br> std::string <span class="keyword">const</span> &amp;relname, std::string const&amp; absname,<br> <span class="keyword">bool</span> is_system_include); <br><br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="key
word">void</span> returning_from_include_file(ContextT <span class="keyword">const</span> &amp;ctx);<br><br> <span class="comment">// interpretation of #pragma's of the form </span>
+ typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT,<br> <span class="keyword">typename</span> IteratorT<br> &gt;<br> <span class="keyword">bool</span> expanding_function_like_macro(<br> ContextT <span class="keyword">const</span> &amp;ctx, TokenT <span class="keyword">const</span> &amp;macrodef, <br> <span class="keyword">std::vector</span>&lt;TokenT&gt; <span class="keyword">const</span> &amp;formal_args, <br> ContainerT <span class="keyword">const</span> &amp;definition, TokenT <span class="keyword">const</span> &amp;macrocall, <br> <span class="keyword">std::vector</span>&lt;ContainerT&gt; <span class="keyword">const</span> &amp;arguments,<br> IteratorT <span class="keyword">const</span> &amp;seqstart, Iterator <span class="keyword">const</span> &amp;seqend);<br> <br>
    <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> expanding_object_like_macro(<br> ContextT <span class="keyword">const</span> &amp;ctx, TokenT <span class="keyword">const</span> &amp;macro, <br> ContainerT <span class="keyword">const</span> &amp;definition, TokenT <span class="keyword">const</span> &amp;macrocall);<br> <br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> expanded_macro(ContextT <span class="keyword">const</span> &amp;ctx, <br> ContainerT <span class="keyword">const</span> &amp;result);<br> <br>
   <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> rescanned_macro(ContextT <span class="keyword">const</span> &amp;ctx, <br> ContainerT <span class="keyword">const</span> &amp;result);<br><br>
+ <span class="comment">// include file tracing functions</span>
+ <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">bool</span> found_include_directive(ContextT <span class="keyword">const</span> &amp;ctx, <br> std::string <span class="keyword">const</span> &amp;filename, <span class="keyword">bool</span> include_next);<br>
+ <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void </span>opened_include_file(ContextT <span class="keyword">const</span> &amp;ctx, <br> std::string <span class="keyword">const</span> &amp;relname, std::string <span class="keyword">const</span>&amp; absname,<br> <span class="keyword">bool</span> is_system_include); <br>
+ <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void</span> returning_from_include_file(ContextT <span class="keyword">const</span> &amp;ctx);<br>
+ <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void</span> detected_include_guard(ContextT <span class="keyword">const</span> &amp;ctx,
+ std::string <span class="keyword">const</span>&amp; filename,
+ std::string <span class="keyword">const</span>&amp; include_guard);<br>
+ <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">void</span> detected_pragma_once(ContextT <span class="keyword">const</span> &amp;ctx,
+ TokenT <span class="keyword">const</span>&amp; pragma_token,
+ std::string <span class="keyword">const</span>&amp; filename);<br><br>
+ <span class="comment">// interpretation of #pragma's of the form </span>
         <span class="comment">// 'wave option[(value)]'</span>
- <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> interpret_pragma(ContextT <span class="keyword">const</span> &amp;ctx, ContainerT &amp;pending, <br> <span class="keyword">typename</span> ContextT::token_type <span class="keyword">const</span> &amp;option, <br> ContainerT <span class="keyword">const</span> &amp;values, <br> <span class="keyword">typename</span> ContextT::token_type <span class="keyword">const</span> &amp;pragma_token);<br><br> <span class="comment">// macro definition hooks</span>
+ <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> interpret_pragma(ContextT <span class="keyword">const</span> &amp;ctx, ContainerT &amp;pending, <br> <span class="keyword">typename</span> ContextT::token_type <span class="keyword">const</span> &amp;option, <br> ContainerT <span class="keyword">const</span> &amp;values, <br> <span class="keyword">typename</span> ContextT::token_type <span class="keyword">const</span> &amp;pragma_token);<br><br>
+ <span class="comment">// macro definition hooks</span>
         <span class="keyword">template</span> &lt;<br> <span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">
             typename</span> ParametersT, <span class="keyword">typename</span> DefinitionT<br> &gt;<br> <span class="keyword">void</span> defined_macro(ContextT <span class="keyword">const</span> &amp;ctx, TokenT <span class="keyword">const</span> &amp;name, <span class="keyword">
- bool</span> is_functionlike, ParametersT <span class="keyword">const</span> &amp;parameters, <br> DefinitionT <span class="keyword">const</span> &amp;definition, <span class="keyword">bool</span> is_predefined);<br><br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">void</span> undefined_macro(ContextT <span class="keyword">const</span> &amp;ctx, <br> TokenT<span class="keyword"> const</span> &amp;name);<br><br> <span class="comment">// #error and #warning directive hooks</span>
+ bool</span> is_functionlike, ParametersT <span class="keyword">const</span> &amp;parameters, <br> DefinitionT <span class="keyword">const</span> &amp;definition, <span class="keyword">bool</span> is_predefined);<br><br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">void</span> undefined_macro(ContextT <span class="keyword">const</span> &amp;ctx, <br> TokenT<span class="keyword"> const</span> &amp;name);<br><br>
+ <span class="comment">// #error and #warning directive hooks</span>
         <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> found_warning_directive(ContextT <span class="keyword">const</span> &amp;ctx, <br> ContainerT <span class="keyword">const</span> &amp;message);<br><br> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> found_error_directive(ContextT <span class="keyword">const</span> &amp;ctx, <br> ContainerT <span class="keyword">const</span> &amp;message);<br><br> <span class="comment">// #line directive hook</span>
         <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> found_line_directive(ContextT <span class="keyword">const</span> &amp;ctx, <br> ContainerT <span class="keyword">const</span> &amp;arguments, <span class="keyword">unsigned int</span> line,<br> std::string <span class="keyword">const</span>&amp; filename);<br> };<br><br>}}} <span class="comment">// namespace boost::wave::context_policies</span></pre>
 <h2><a name="member_functions"></a>Member functions</h2>
 <h3>General hook functions </h3>
 <p><a name="found_directive"></a><strong>found_directive</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">bool</span> found_directive(ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const </span>&amp;directive);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">bool</span> found_directive(ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const </span>&amp;directive);
 </pre>
 <blockquote>
   <p>The function <tt>found_directive</tt> is called, whenever the preprocessor has detected one of the preprocessing directives (<span class="preprocessor">#define</span>, <span class="preprocessor">#undef</span>, <span class="preprocessor">#if</span>, <span class="preprocessor">#idef</span>, <span class="preprocessor">#ifndef</span>, <span class="preprocessor">#elif</span>, <span class="preprocessor">#endif</span>, <span class="preprocessor">#error</span>, <span class="preprocessor">#include</span>, <span class="preprocessor">#pragma</span> or <span class="preprocessor">#warning</span>) .</p>
@@ -83,14 +100,14 @@
     value is <tt>false</tt>, the directive is processed in the normal manner. </p>
 </blockquote>
 <p><a name="throw_exception"></a><strong>throw_exception</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ExceptionT&gt;<br> void throw_exception(ContextT <span class="keyword">const</span> &amp;ctx, <br> ExceptionT <span class="keyword">const</span>&amp; e);</pre>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ExceptionT&gt;<br> void throw_exception(ContextT <span class="keyword">const</span> &amp;ctx, <br> ExceptionT <span class="keyword">const</span>&amp; e);</pre>
 <blockquote>
   <p>he function&nbsp;<tt>throw_exception</tt> is called, whenever a preprocessing exception occurs .</p>
   <p>The <tt>ctx</tt> parameter provides a reference to the <tt>context_type</tt> used during instantiation of the preprocessing iterators by the user.&nbsp; </p>
   <p>The parameter&nbsp;<tt>e</tt> is the exception object containing detailed error information. </p>
 </blockquote>
 <p><a name="may_skip_whitespace" id="may_skip"></a><strong>may_skipwhitespace</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">bool</span> may_skip_whitespace(ContextT <span class="keyword">const</span>&amp; ctx, TokenT &amp;token, <br> <span class="keyword">bool</span>&amp; skipped_newline);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">bool</span> may_skip_whitespace(ContextT <span class="keyword">const</span>&amp; ctx, TokenT &amp;token, <br> <span class="keyword">bool</span>&amp; skipped_newline);
 </pre>
 <blockquote>
   <p>The function <tt>may_skipwhitespace</tt> will be called by the library, whenever a token is about to be returned to the calling application. </p>
@@ -104,7 +121,8 @@
 </blockquote>
 <h3>Conditional compilation hook functions </h3>
 <p><a name="evaluated_conditional_expression"></a><strong>evaluated_conditional_expression</strong></p>
-<pre><span class="keyword"> template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT&gt;<br><span class="keyword"> bool</span> evaluated_conditional_expression(ContextT <span class="keyword">const</span>&amp; ctx, <br> TokenT <span class="keyword">const</span>&amp; directive, ContainerT <span class="keyword">const</span>&amp; expression, <span class="keyword"><br> bool</span> expression_value);<br>
+<pre><span class="keyword"> template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT&gt;
+<span class="keyword"> bool</span> evaluated_conditional_expression(ContextT <span class="keyword">const</span>&amp; ctx, <br> TokenT <span class="keyword">const</span>&amp; directive, ContainerT <span class="keyword">const</span>&amp; expression, <span class="keyword"><br> bool</span> expression_value);
 </pre>
 <blockquote>
   <p>The function <tt>evaluated_conditional_expression</tt> is called, whenever the preprocessor has encountered a <span class="preprocessor">#if</span>, <span class="preprocessor">#elif</span>, <span class="preprocessor">#ifdef</span> or <span class="preprocessor">#ifndef</span> directive. This hook gets passed the non-expanded conditional
@@ -124,7 +142,7 @@
   </p>
 </blockquote>
 <p><a name="skipped_token"></a><strong>skipped_token</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">void</span> skipped_token(ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const</span>&amp; token);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> <span class="keyword">void</span> skipped_token(ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const</span>&amp; token);
 </pre>
 <blockquote>
   <p>The function <tt>skipped_token</tt> is called, whenever a token is about to be skipped due to a false preprocessor condition (code fragments to be
@@ -134,7 +152,7 @@
   <p>The parameter <tt>token</tt> refers to the token to be skipped.</p>
 </blockquote>
 <p><a name="generated_token"></a><strong>generated_token</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> TokenT <span class="keyword">const</span>&amp; generated_token(ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const</span>&amp; token);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT&gt;<br> TokenT <span class="keyword">const</span>&amp; generated_token(ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const</span>&amp; token);
 </pre>
 <blockquote>
   <p>The function <tt>generated_token</tt> is called, whenever a token is about to be returned from the library.</p>
@@ -148,7 +166,7 @@
 </blockquote>
 <h3>Macro expansion tracking functions</h3>
 <p><a name="expanding_function_like_macro"></a><b>expanding_function_like_macro</b></p>
-<pre><span class="keyword"> template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> expanding_function_like_macro(<br> ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const</span> &amp;macrodef, <br> <span class="keyword">std::vector</span>&lt;TokenT&gt; <span class="keyword">const</span> &amp;formal_args, <br> ContainerT <span class="keyword">const</span> &amp;definition, TokenT <span class="keyword">const</span> &amp;macrocall, <br> <span class="keyword">std::vector</span>&lt;ContainerT&gt; <span class="keyword">const</span> &amp;arguments,<br> IteratorT <span class="keyword">const</span> &amp;seqstart, Iterator <span class="keyword">const</span> &amp;seqend);</pre>
+<pre><span class="keyword"> template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> expanding_function_like_macro(<br> ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const</span> &amp;macrodef, <br> <span class="keyword">std::vector</span>&lt;TokenT&gt; <span class="keyword">const</span> &amp;formal_args, <br> ContainerT <span class="keyword">const</span> &amp;definition, TokenT <span class="keyword">const</span> &amp;macrocall, <br> <span class="keyword">std::vector</span>&lt;ContainerT&gt; <span class="keyword">const</span> &amp;arguments,<br> IteratorT <span class="keyword">const</span> &amp;seqstart, Iterator <span class="keyword">const</span> &amp;seqend);</pre>
 <blockquote>
   <p>The function <tt>expanding_function_like_macro</tt> is called, whenever a
     function-like macro is to be expanded, i.e. <i>before</i> the actual expansion
@@ -181,7 +199,7 @@
   </p>
 </blockquote>
 <p><a name="expanding_object_like_macro"></a><b>expanding_object_like_macro</b></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> expanding_object_like_macro(<br> ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const</span> &amp;macro, <br> ContainerT <span class="keyword">const</span> &amp;definition, TokenT <span class="keyword">const</span> &amp;macrocall);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> TokenT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">bool</span> expanding_object_like_macro(<br> ContextT <span class="keyword">const</span>&amp; ctx, TokenT <span class="keyword">const</span> &amp;macro, <br> ContainerT <span class="keyword">const</span> &amp;definition, TokenT <span class="keyword">const</span> &amp;macrocall);
 </pre>
 <blockquote>
   <p>The function <tt>expanding_object_like_macro</tt> is called, whenever a object-like
@@ -201,7 +219,7 @@
   </p>
 </blockquote>
 <p><a name="expanded_macro"></a><b>expanded_macro</b></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> expanded_macro(ContextT <span class="keyword">const</span>&amp; ctx, ContainerT <span class="keyword">const</span> &amp;result);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> expanded_macro(ContextT <span class="keyword">const</span>&amp; ctx, ContainerT <span class="keyword">const</span> &amp;result);
 </pre>
 <blockquote>
   <p>The function <tt>expanded_macro</tt> is called whenever the expansion of
@@ -213,7 +231,7 @@
     so far. This is a standard STL container containing the generated token sequence.</p>
 </blockquote>
 <p><a name="rescanned_macro"></a><b>rescanned_macro</b></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> rescanned_macro(ContextT <span class="keyword">const</span>&amp; ctx, ContainerT <span class="keyword">const</span> &amp;result);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> rescanned_macro(ContextT <span class="keyword">const</span>&amp; ctx, ContainerT <span class="keyword">const</span> &amp;result);
 </pre>
 <blockquote>
   <p>The function <tt>rescanned_macro</tt> is called whenever the rescanning
@@ -226,7 +244,7 @@
 </blockquote>
 <h3>Include file tracing functions</h3>
 <p><a name="opened_include_file" id="found_include_directive"></a><strong>found_include_directive</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">bool</span> found_include_directive(ContextT <span class="keyword">const</span>&amp; ctx, <br> std::string <span class="keyword">const</span> &amp;filename, <span class="keyword">bool</span> include_next);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">bool</span> found_include_directive(ContextT <span class="keyword">const</span>&amp; ctx, <br> std::string <span class="keyword">const</span> &amp;filename, <span class="keyword">bool</span> include_next);
 </pre>
 <blockquote>
   <p>The function <tt>found_include_directive</tt> is called whenever whenever a #include directive was located..</p>
@@ -246,7 +264,7 @@
   </p>
 </blockquote>
 <p><a name="opened_include_file" id="opened_include_file"></a><strong>opened_include_file</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void</span> opened_include_file(ContextT <span class="keyword">const</span>&amp; ctx, <br> std::string <span class="keyword">const</span> &amp;rel_filename, std::string <span class="keyword">const</span> &amp;abs_filename, <br> <span class="keyword">bool</span> is_system_include);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void</span> opened_include_file(ContextT <span class="keyword">const</span>&amp; ctx, <br> std::string <span class="keyword">const</span> &amp;rel_filename, std::string <span class="keyword">const</span> &amp;abs_filename, <br> <span class="keyword">bool</span> is_system_include);
 </pre>
 <blockquote>
   <p>The function <tt>opened_include_file</tt> is called whenever a file referred
@@ -263,7 +281,7 @@
     as a result of a <tt>#include&nbsp;&lt;...&gt;</tt> directive.</p>
 </blockquote>
 <p><a name="returning_from_include_file" id="returning_from_include_file"></a><strong>returning_from_include_file</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void</span> returning_from_include_file(ContextT <span class="keyword">const</span>&amp; ctx);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void</span> returning_from_include_file(ContextT <span class="keyword">const</span>&amp; ctx);
 </pre>
 <blockquote>
   <p>The function <tt>returning_from_include_file</tt> is called whenever an
@@ -271,6 +289,43 @@
   <p>The <tt>ctx</tt> parameter provides a reference to the <tt>context_type</tt> used during instantiation of the preprocessing iterators by the user.
     Note, this parameter was added for the Boost V1.35.0 release. </p>
 </blockquote>
+<p><a name="detected_include_guard" id="detected_include_guard"></a><strong>detected_include_guard</strong></p>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT&gt;<br> <span class="keyword">void</span> detected_include_guard(ContextT <span class="keyword">const</span>&amp; ctx,
+ std::string <span class="keyword">const</span>&amp; filename,
+ std::string <span class="keyword">const</span>&amp; include_guard);
+</pre>
+<blockquote>
+ <p>The function <tt>detected_include_guard</tt> is called whenever a<span lang="de">n</span>
+ include file is about to be added to the list of #pragma once headers as the
+ result of a detected include guard scheme. That means this header file will
+ not be opened and parsed again even if it is specified in a later
+ <span class="preprocessor">#include</span> directive.&nbsp; </p>
+ <p>The <tt>ctx</tt> parameter provides a reference to the <tt>context_type</tt>
+ used during instantiation of the preprocessing iterators by the user. </p>
+ <p>The parameter <tt>filename</tt> contains the file system path of the opened file
+ (this is relative to the directory of the currently processed file or a
+ absolute path depending on the paths given as the include search paths).</p>
+ <p>The parameter <tt>include_guard</tt> contains the name of the detected include guard.<br> </p>
+</blockquote>
+<p><a name="detected_pragma_once" id="detected_pragma_once"></a><strong>detected_pragma_once</strong></p>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename </span>TokenT&gt;<br> <span class="keyword">void</span> detected_<span lang="de">p<span class="style1">ragma<span lang="en-us">_</span>once</span></span>(ContextT <span class="keyword">const</span>&amp; ctx,
+<span lang="de"> TokenT <span class="keyword">const</span>&amp; pragma_token,</span>
+ std::string <span class="keyword">const</span>&amp; filename);</pre>
+<blockquote>
+ <p>The function <tt>detected_pragma_once</tt> is called whenever either a<span lang="de">n</span>
+ include file is about to be added to the list of #pragma once headers as the
+ result of a detected <span lang="de"><span class="preprocessor">#pragma once</span>
+ directive</span>. That means this header file will not be opened and parsed
+ again even if it is specified in a later <span class="preprocessor">#include</span>
+ directive. </p>
+ <p>The <tt>ctx</tt> parameter provides a reference to the <tt>context_type</tt>
+ used during instantiation of the preprocessing iterators by the user. </p>
+ <p><span lang="de">The parameter pragma_token refers to the token &quot;#pragma&quot;
+ triggering this preprocessing hook.</span></p>
+ <p>The parameter <tt>filename</tt> contains the file system path of the opened file
+ (this is relative to the directory of the currently processed file or a
+ absolute path depending on the paths given as the include search paths).</p>
+</blockquote>
 <h3>Interpretation of #pragma's</h3>
 <p><strong><a name="interpret_pragma"></a>interpret_pragma</strong></p>
 <pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> bool interpret_pragma(ContextT <span class="keyword">const</span> &amp;ctx, ContainerT &amp;pending, <br> <span class="keyword">typename</span> ContextT::token_type <span class="keyword">const</span> &amp;option, <br> ContainerT <span class="keyword">const</span> &amp;values, <br> <span class="keyword">typename</span> ContextT::token_type<span class="keyword"> const</span> &amp;pragma_token);<br>
@@ -346,7 +401,7 @@
     exception of the type <code>error_directive</code> (normal execution continues), if the return value is <tt>true</tt> the execution continues as if no <span class="preprocessor">#error</span> directive has been found and the overall directive is replaced by a single newline. </p>
 </blockquote>
 <p><strong><a name="found_line_directive" id="found_line_directive"></a>found_line_drective</strong></p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> found_line_drective(ContextT <span class="keyword">const</span>&amp; ctx, <br> ContainerT <span class="keyword">const</span> &amp;arguments, <span class="keyword">unsigned int</span> line,<br> std::string <span class="keyword">const</span>&amp; filename);<br>
+<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContextT, <span class="keyword">typename</span> ContainerT&gt;<br> <span class="keyword">void</span> found_line_drective(ContextT <span class="keyword">const</span>&amp; ctx, <br> ContainerT <span class="keyword">const</span> &amp;arguments, <span class="keyword">unsigned int</span> line,<br> std::string <span class="keyword">const</span>&amp; filename);
 </pre>
 <blockquote>
   <p>The function <tt>found_line_directive </tt> is called whenever a <span class="preprocessor">#line </span>directive has been encountered. Note, this function was added for the Boost V1.35.0 release. </p>
@@ -373,7 +428,8 @@
   1.0. (See accompanying file LICENSE_1_0.txt or copy at
   http://www.boost.org/LICENSE_1_0.txt) </font> </p>
 <p class="copyright"><span class="updated">Last updated:
- <!-- #BeginDate format:fcAm1m -->Tuesday, October 14, 2008 18:45<!-- #EndDate -->
+ <!-- #BeginDate format:fcAm1m -->Thursday, September 1<span lang="de">8</span>, 2009
+<span lang="de">09</span>:<span lang="de">10</span><!-- #EndDate -->
   </span></p>
 </body>
 </html>

Modified: branches/release/libs/wave/doc/class_reference_filepos.html
==============================================================================
--- branches/release/libs/wave/doc/class_reference_filepos.html (original)
+++ branches/release/libs/wave/doc/class_reference_filepos.html 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -47,12 +47,12 @@
     <span class="keyword">public</span>:
         <a href="class_reference_filepos.html#constructors">file_position</a>();
         <span class="keyword">explicit</span> file_position(String const &amp;file,
- int line_ = 1, int column_ = 1);
+ <span class="keyword">unsigned int</span> line_ = 1, <span class="keyword">unsigned int </span>column_ = 1);
 
     // accessors
         String <span class="keyword">const</span> &amp;get_file() <span class="keyword">const</span>;
- <span class="keyword">int</span> get_line() <span class="keyword">const</span>;
- <span class="keyword">int</span> get_column() <span class="keyword">const</span>;
+ <span class="keyword">unsigned int</span> get_line() <span class="keyword">const</span>;
+ <span class="keyword">unsigned int</span> get_column() <span class="keyword">const</span>;
     
         <span class="keyword">void</span> set_file(String <span class="keyword">const</span> &amp;file);
         <span class="keyword">void</span> set_line(<span class="keyword">int</span> line);
@@ -73,7 +73,7 @@
 <h3><a name="constructors"></a>Constructors</h3>
 <pre> file_position();
         <span class="keyword">explicit</span> file_position(String const &amp;file,
- int line_ = 1, int column_ = 1);
+ <span class="keyword">unsigned int </span>line_ = 1, <span class="keyword">unsigned int </span>column_ = 1);
 </pre>
 <blockquote>
   <p>The constructors initialize a new instance of a <tt>file_position</tt> in
@@ -82,8 +82,8 @@
 </blockquote>
 <p><a name="get_accessors"></a><b>get_file</b>, <b>get_line</b>, <b>get_column</b></p>
 <pre> String <span class="keyword">const</span> &amp;get_file() <span class="keyword">const</span>;
- <span class="keyword">int</span> get_line() <span class="keyword">const</span>;
- <span class="keyword">int</span> get_column() <span class="keyword">const</span>;
+ <span class="keyword">unsigned int</span> get_line() <span class="keyword">const</span>;
+ <span class="keyword">unsigned int</span> get_column() <span class="keyword">const</span>;
 </pre>
 <blockquote>
   <p>The <tt>get_...</tt> functions are used to access the current values of the
@@ -92,8 +92,8 @@
 </blockquote>
 <p><a name="set_accessors"></a><b>set_file</b>, <b>set_line</b>, <b>set_column</b></p>
 <pre> <span class="keyword">void</span> set_file(String <span class="keyword">const</span> &amp;file);
- <span class="keyword">void</span> set_line(<span class="keyword">int</span> line);
- <span class="keyword">void</span> set_column(<span class="keyword">int</span> column);
+ <span class="keyword">void</span> set_line(<span class="keyword">unsigned int</span> line);
+ <span class="keyword">void</span> set_column(<span class="keyword">unsigned int</span> column);
 </pre>
 <blockquote>
   <p>The <tt>set_...</tt> functions are used to set new values to the file position
@@ -113,7 +113,7 @@
   <br>
 <font size="2">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) </font> </p>
 <p class="copyright"><span class="updated">Last updated:
- <!-- #BeginDate format:fcAm1m -->Sunday, October 12, 2008 20:14<!-- #EndDate -->
+ <!-- #BeginDate format:fcAm1m -->Saturday, September 18, 2009 15:14<!-- #EndDate -->
 </span></p>
 </body>
 </html>

Modified: branches/release/libs/wave/doc/wave_driver.html
==============================================================================
--- branches/release/libs/wave/doc/wave_driver.html (original)
+++ branches/release/libs/wave/doc/wave_driver.html 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -59,6 +59,8 @@
     -l [ --listincludes ] arg: list included file to a file [arg] or to stdout [-]
     -m [ --macronames ] arg: list names of all defined macros to a file [arg] or
                                  to stdout [-]
+ -c [ --macrocounts ] arg list macro invocation counts to a file [arg] or to
+ stdout [-]
     -p [ --preserve ] arg (=0): preserve whitespace
                                  0: no whitespace is preserved (default),
                                  1: comments are preserved,
@@ -68,6 +70,8 @@
                                  1: #line directives will be emitted (default)
     -x [ --extended ]: enable the #pragma wave system() directive
     -G [ --noguard ]: disable include guard detection
+ -g [ --listguards ]: list names of files flagged as 'include once' to a
+ file [arg] or to stdout [-]
     -s [ --state ] arg: load and save state information from/to the given
                                  file [arg] or 'wave.state' [-] (interactive mode
                                  only)
@@ -194,6 +198,10 @@
 <blockquote>
   <p dir="ltr">Enable the output of all defined macros. This includes the macro names, its parameter names (if the macro is a function like macro) and its definition. The path specifies the filename to use for the output of the generated macro list. If the filename given equals to <tt>'-'</tt> (without the quotes), the macro list is put into the standard output stream (stdout).</p>
 </blockquote>
+<p dir="ltr">-c [--macrocounts] path</p>
+<blockquote>
+ <p dir="ltr">Enable the output of all macro invocation counts. The path specifies the filename to use for the output of the generated list. If the filename given equals to <tt>'-'</tt> (without the quotes), the macro list is put into the standard output stream (stdout).</p>
+</blockquote>
 <p dir="ltr">-p [--preserve] arg </p>
 <blockquote>
   <p dir="ltr">Preserve the whitespace from the input stream not located inside of macro definitions. The argument defines the amount of whitespace to be preserved. A value of '0' (zero) skips all whitespace, a value of '1' preserves all the comments and a value of '2' will preserve all whitespace in the output.</p>
@@ -212,6 +220,13 @@
 <blockquote>
   <p dir="ltr">This option disables the automatic include guard detection normally performed by the Wave library during the processing of included files. For more information about automatic include guard detection please refer to The Context Object class reference. </p>
 </blockquote>
+<p dir="ltr">-g [--listguards] arg </p>
+<blockquote>
+ <p dir="ltr">This option lists all found include files which either contain a
+ <span class="preprocessor">#pragma once</span> or contain an include guard
+ into the given file. If the filename given equals to <tt>'-'</tt> (without the quotes), the
+ guards log is put into the standard output stream (stdout). For more information about automatic include guard detection please refer to The Context Object class reference. </p>
+</blockquote>
 <p dir="ltr">-s [--state]</p>
 <blockquote>
   <p dir="ltr">This option tries instructs the <tt>Wave</tt> tool to load the serialized information from the file given as the argument and to save back the internal state information at the end of the session to the same file. When using this option <tt>Wave</tt> loads and saves all defined macros (even the predefined ones) and the information about processed header files tagged with <span class="preprocessor">#pragma once</span> and/or identified to have include guards. </p>
@@ -273,7 +288,7 @@
 <font size="2">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) </font> </p>
 <span class="updated"></span>
 <p class="copyright"><span class="updated">Last updated:
- <!-- #BeginDate format:fcAm1m -->Tuesday, July 29, 2008 20:40<!-- #EndDate -->
+ <!-- #BeginDate format:fcAm1m -->Thursday, September 17, 2009 12:40<!-- #EndDate -->
 </span></p>
 </body>
 </html>

Modified: branches/release/libs/wave/test/testwave/collect_hooks_information.hpp
==============================================================================
--- branches/release/libs/wave/test/testwave/collect_hooks_information.hpp (original)
+++ branches/release/libs/wave/test/testwave/collect_hooks_information.hpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -671,6 +671,89 @@
         return this->base_type::throw_exception(ctx, e);
     }
 
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The function 'detected_include_guard' is called whenever either a
+ // include file is about to be added to the list of #pragma once headers.
+ // That means this header file will not be opened and parsed again even
+ // if it is specified in a later #include directive.
+ // This function is called as the result of a detected include guard
+ // scheme.
+ //
+ // The implemented heuristics for include guards detects two forms of
+ // include guards:
+ //
+ // #ifndef INCLUDE_GUARD_MACRO
+ // #define INCLUDE_GUARD_MACRO
+ // ...
+ // #endif
+ //
+ // or
+ //
+ // if !defined(INCLUDE_GUARD_MACRO)
+ // #define INCLUDE_GUARD_MACRO
+ // ...
+ // #endif
+ //
+ // note, that the parenthesis are optional (i.e. !defined INCLUDE_GUARD_MACRO
+ // will work as well). The code allows for any whitespace, newline and single
+ // '#' tokens before the #if/#ifndef and after the final #endif.
+ //
+ // The parameter 'ctx' is a reference to the context object used for
+ // instantiating the preprocessing iterators by the user.
+ //
+ // The parameter 'filename' contains the file system path of the
+ // opened file (this is relative to the directory of the currently
+ // processed file or a absolute path depending on the paths given as the
+ // include search paths).
+ //
+ // The parameter contains the name of the detected include guard.
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename ContextT>
+ void
+ detected_include_guard(ContextT const& ctx, std::string const& filename,
+ std::string const& include_guard)
+ {
+ BOOST_WAVETEST_OSSTREAM strm;
+ strm << "19: " << filename << ": " << include_guard << std::endl;
+ hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The function 'detected_pragma_once' is called whenever either a
+ // include file is about to be added to the list of #pragma once headers.
+ // That means this header file will not be opened and parsed again even
+ // if it is specified in a later #include directive.
+ // This function is called as the result of a detected directive
+ // #pragma once.
+ //
+ // The parameter 'ctx' is a reference to the context object used for
+ // instantiating the preprocessing iterators by the user.
+ //
+ // The parameter pragma_token refers to the token "#pragma" triggering
+ // this preprocessing hook.
+ //
+ // The parameter 'filename' contains the file system path of the
+ // opened file (this is relative to the directory of the currently
+ // processed file or a absolute path depending on the paths given as the
+ // include search paths).
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename ContextT, typename TokenT>
+ void
+ detected_pragma_once(ContextT const& ctx, TokenT const& pragma_token,
+ std::string const& filename)
+ {
+ BOOST_WAVETEST_OSSTREAM strm;
+ strm << "20: " << repr(pragma_token.get_position()) << ": "
+ << pragma_token.get_value() << ": " << filename << std::endl;
+ hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
+ }
+#endif
+
 private:
     std::string& hooks_trace;
 };

Modified: branches/release/libs/wave/test/testwave/testfiles/t_2_009.cpp
==============================================================================
--- branches/release/libs/wave/test/testwave/testfiles/t_2_009.cpp (original)
+++ branches/release/libs/wave/test/testwave/testfiles/t_2_009.cpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -47,6 +47,7 @@
 //H 10: t_2_009.cpp(15): #if
 //H 11: t_2_009.cpp(15): #if !defined(FILE_002_009_CPP) : 0
 //H 06:
+//H 19: $B(t_2_009.cpp): FILE_002_009_CPP
 //H 10: t_2_009.cpp(29): #include
 //H 01: t_2_009.cpp(19): USER_HEADER
 //H 02: "t_2_009.cpp"

Modified: branches/release/libs/wave/test/testwave/testfiles/t_9_016.cpp
==============================================================================
--- branches/release/libs/wave/test/testwave/testfiles/t_9_016.cpp (original)
+++ branches/release/libs/wave/test/testwave/testfiles/t_9_016.cpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -34,6 +34,7 @@
 //H 03: #
 //H 10: t_9_016.cpp(19): #endif
 //H 06:
+//H 19: $B(t_9_016.cpp): inclusion
 //H 10: t_9_016.cpp(13): # include "t_9_016.hpp"
 //H 04: "t_9_016.hpp"
 //H 05: $B(t_9_016.hpp) ($B(t_9_016.hpp))

Modified: branches/release/libs/wave/test/testwave/testfiles/test.cfg
==============================================================================
--- branches/release/libs/wave/test/testwave/testfiles/test.cfg (original)
+++ branches/release/libs/wave/test/testwave/testfiles/test.cfg 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -71,6 +71,7 @@
 t_2_016.cpp
 t_2_017.cpp
 t_2_018.cpp
+t_2_019.cpp
 
 #
 # t_3: Predefined macros

Modified: branches/release/tools/wave/cpp.cpp
==============================================================================
--- branches/release/tools/wave/cpp.cpp (original)
+++ branches/release/tools/wave/cpp.cpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -672,6 +672,7 @@
     std::ofstream output;
     std::ofstream traceout;
     std::ofstream includelistout;
+ std::ofstream listguardsout;
 
     trace_flags enable_trace = trace_nothing;
 
@@ -723,6 +724,31 @@
                 rdbuf(cout.rdbuf());
         }
 
+ // Open the stream where to output the list of included file names
+ if (vm.count("listguards")) {
+ // try to open the file, where to put the include list
+ fs::path listguards_file(boost::wave::util::create_path(
+ vm["listguards"].as<std::string>()));
+
+ if (listguards_file != "-") {
+ fs::create_directories(boost::wave::util::branch_path(listguards_file));
+ listguardsout.open(listguards_file.string().c_str());
+ if (!listguardsout.is_open()) {
+ cerr << "wave: could not open include guard list file: "
+ << listguards_file.string() << endl;
+ return -1;
+ }
+ }
+ enable_trace = trace_flags(enable_trace | trace_guards);
+ }
+ if ((enable_trace & trace_guards) && !listguardsout.is_open()) {
+ // by default list included names to std::cout
+ listguardsout.copyfmt(cout);
+ listguardsout.clear(cout.rdstate());
+ static_cast<std::basic_ios<char> &>(listguardsout).
+ rdbuf(cout.rdbuf());
+ }
+
     // enable preserving comments mode
     bool preserve_comments = false;
     bool preserve_whitespace = false;
@@ -759,8 +785,8 @@
     bool allow_output = true; // will be manipulated from inside the hooks object
     std::string default_outfile; // will be used from inside the hooks object
     trace_macro_expansion<token_type> hooks(preserve_whitespace,
- output, traceout, includelistout, enable_trace, enable_system_command,
- allow_output, default_outfile);
+ output, traceout, includelistout, listguardsout, enable_trace,
+ enable_system_command, allow_output, default_outfile);
 
     // enable macro invocation count, if appropriate
         if (vm.count("macrocounts"))
@@ -1206,6 +1232,9 @@
             ("extended,x", "enable the #pragma wave system() directive")
 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
             ("noguard,G", "disable include guard detection")
+ ("listguards,g", po::value<std::string>(),
+ "list names of files flagged as 'include once' to a file [arg] "
+ "or to stdout [-]")
 #endif
 #if BOOST_WAVE_SERIALIZATION != 0
             ("state,s", po::value<std::string>(),

Modified: branches/release/tools/wave/trace_macro_expansion.hpp
==============================================================================
--- branches/release/tools/wave/trace_macro_expansion.hpp (original)
+++ branches/release/tools/wave/trace_macro_expansion.hpp 2009-10-06 20:04:14 EDT (Tue, 06 Oct 2009)
@@ -54,7 +54,8 @@
     trace_nothing = 0, // disable tracing
     trace_macros = 1, // enable macro tracing
     trace_macro_counts = 2, // enable invocation counting
- trace_includes = 4 // enable include file tracing
+ trace_includes = 4, // enable include file tracing
+ trace_guards = 8 // enable include guard tracing
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -144,10 +145,11 @@
 public:
     trace_macro_expansion(bool preserve_whitespace_,
             std::ofstream &output_, std::ostream &tracestrm_,
- std::ostream &includestrm_, trace_flags flags_,
- bool enable_system_command_, bool& generate_output_,
- std::string const& default_outfile_)
- : outputstrm(output_), tracestrm(tracestrm_), includestrm(includestrm_),
+ std::ostream &includestrm_, std::ostream &guardstrm_,
+ trace_flags flags_, bool enable_system_command_,
+ bool& generate_output_, std::string const& default_outfile_)
+ : outputstrm(output_), tracestrm(tracestrm_),
+ includestrm(includestrm_), guardstrm(guardstrm_),
         level(0), flags(flags_), logging_flags(trace_nothing),
         enable_system_command(enable_system_command_),
         preserve_whitespace(preserve_whitespace_),
@@ -571,6 +573,58 @@
         }
     }
 
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // The function 'detected_include_guard' is called whenever either a
+ // include file is about to be added to the list of #pragma once headers.
+ // That means this header file will not be opened and parsed again even
+ // if it is specified in a later #include directive.
+ // This function is called as the result of a detected include guard
+ // scheme.
+ //
+ // The implemented heuristics for include guards detects two forms of
+ // include guards:
+ //
+ // #ifndef INCLUDE_GUARD_MACRO
+ // #define INCLUDE_GUARD_MACRO
+ // ...
+ // #endif
+ //
+ // or
+ //
+ // if !defined(INCLUDE_GUARD_MACRO)
+ // #define INCLUDE_GUARD_MACRO
+ // ...
+ // #endif
+ //
+ // note, that the parenthesis are optional (i.e. !defined INCLUDE_GUARD_MACRO
+ // will work as well). The code allows for any whitespace, newline and single
+ // '#' tokens before the #if/#ifndef and after the final #endif.
+ //
+ // The parameter 'ctx' is a reference to the context object used for
+ // instantiating the preprocessing iterators by the user.
+ //
+ // The parameter 'filename' contains the file system path of the
+ // opened file (this is relative to the directory of the currently
+ // processed file or a absolute path depending on the paths given as the
+ // include search paths).
+ //
+ // The parameter contains the name of the detected include guard.
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename ContextT>
+ void
+ detected_include_guard(ContextT const& ctx, std::string const& filename,
+ std::string const& include_guard)
+ {
+ if (enabled_guard_tracing()) {
+ guardstrm << include_guard << ":" << std::endl
+ << " " << filename << std::endl;
+ }
+ }
+#endif
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // The function 'may_skip_whitespace' will be called by the
@@ -1129,6 +1183,10 @@
     {
         return (flags & trace_includes);
     }
+ bool enabled_guard_tracing() const
+ {
+ return (flags & trace_guards);
+ }
     bool enabled_macro_counting() const
     {
         return logging_flags & trace_macro_counts;
@@ -1178,6 +1236,7 @@
     std::ofstream &outputstrm; // main output stream
     std::ostream &tracestrm; // trace output stream
     std::ostream &includestrm; // included list output stream
+ std::ostream &guardstrm; // include guard output stream
     int level; // indentation level
     trace_flags flags; // enabled globally
     trace_flags logging_flags; // enabled by a #pragma


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