$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r59537 - in trunk/libs/wave: . samples samples/custom_directives samples/custom_directives/build test/testwave test/testwave/testfiles
From: hartmut.kaiser_at_[hidden]
Date: 2010-02-06 18:23:32
Author: hkaiser
Date: 2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
New Revision: 59537
URL: http://svn.boost.org/trac/boost/changeset/59537
Log:
Wave: added found_unknown_directive preprocessing hook
Added:
   trunk/libs/wave/samples/custom_directives/
   trunk/libs/wave/samples/custom_directives/build/
   trunk/libs/wave/samples/custom_directives/build/Jamfile.v2   (contents, props changed)
   trunk/libs/wave/samples/custom_directives/custom_directives.cpp   (contents, props changed)
   trunk/libs/wave/samples/custom_directives/custom_directives.hpp   (contents, props changed)
   trunk/libs/wave/samples/custom_directives/custom_directives.input   (contents, props changed)
Text files modified: 
   trunk/libs/wave/ChangeLog                                   |     9 +++++++++                               
   trunk/libs/wave/samples/Jamfile.v2                          |     1 +                                       
   trunk/libs/wave/test/testwave/collect_hooks_information.hpp |    37 +++++++++++++++++++++++++++++++++++++   
   trunk/libs/wave/test/testwave/testfiles/t_2_005.cpp         |     3 ++-                                     
   4 files changed, 49 insertions(+), 1 deletions(-)
Modified: trunk/libs/wave/ChangeLog
==============================================================================
--- trunk/libs/wave/ChangeLog	(original)
+++ trunk/libs/wave/ChangeLog	2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
@@ -20,6 +20,15 @@
 
 CHANGELOG
 
+Boost V1.43.0
+- V2.0.5
+- Added new preprocessing hook: found_unknown_directive, which is being invoked 
+  whenever an unknown preprocessor directive (i.e. '#' followed by some 
+  identifier) is detected. IT allows to interprete the directive and to provide 
+  some replacement text.
+- Added new example: custom_directives demonstrating the usage of the new 
+  preprocessing hook.
+
 Boost V1.42.0
 - V2.0.4
 - Fixed Wave for latest changes in multi_pass iterator.
Modified: trunk/libs/wave/samples/Jamfile.v2
==============================================================================
--- trunk/libs/wave/samples/Jamfile.v2	(original)
+++ trunk/libs/wave/samples/Jamfile.v2	2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
@@ -17,3 +17,4 @@
 build-project real_positions/build ;
 build-project token_statistics/build ;
 build-project preprocess_pragma_output/build ;
+build-project custom_directives/build ;
Added: trunk/libs/wave/samples/custom_directives/build/Jamfile.v2
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/custom_directives/build/Jamfile.v2	2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
@@ -0,0 +1,17 @@
+# Boost.Wave: A Standard compliant C++ preprocessor library
+#
+# Boost Wave Library Sample Build Jamfile (advanced_hooks)
+#
+# http://www.boost.org/
+#
+# Copyright (c) 2001-2010 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 custom_directives
+    :   ../custom_directives.cpp 
+        /boost/wave//boost_wave
+        /boost/thread//boost_thread
+        /boost/date_time//boost_date_time
+    ;  
+
Added: trunk/libs/wave/samples/custom_directives/custom_directives.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/custom_directives/custom_directives.cpp	2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
@@ -0,0 +1,124 @@
+/*=============================================================================
+    Boost.Wave: A Standard compliant C++ preprocessor library
+    Sample demonstrating the usage of advanced preprocessor hooks.
+    
+    http://www.boost.org/
+
+    Copyright (c) 2001-2010 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 "custom_directives.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+//  Main entry point
+//
+//  This sample shows how to use the advanced hooks to output not only the 
+//  preprocessed tokens but also the conditional directives found in the input
+//  file (these are  commented out, tough) and the tokens from inside the 
+//  conditional block which were not evaluated because the corresponding 
+//  condition was false. These tokens are commented out as well. 
+//
+int main(int argc, char *argv[])
+{
+    if (2 != argc) {
+        std::cerr << "Usage: custom_directives 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. The first template parameter
+    //  should match the iterator type to be used during construction of the
+    //  corresponding context object (see below).
+        typedef boost::wave::context<std::string::iterator, lex_iterator_type,
+                boost::wave::iteration_context_policies::load_file_to_string,
+                custom_directives_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 additionally may be used to initialize and define different 
+    // parameters of the actual preprocessing (not done here).
+    //
+    // The preprocessing of the input stream is done on the fly behind the 
+    // scenes during iteration over the context_type::iterator_type stream.
+    context_type ctx (instring.begin(), instring.end(), argv[1]);
+
+    ctx.set_language(boost::wave::enable_long_long(ctx.get_language()));
+    ctx.set_language(boost::wave::enable_preserve_comments(ctx.get_language()));
+    ctx.set_language(boost::wave::enable_prefer_pp_numbers(ctx.get_language()));
+
+    // analyze the input file, print out the preprocessed tokens
+    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/custom_directives/custom_directives.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/custom_directives/custom_directives.hpp	2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
@@ -0,0 +1,89 @@
+/*=============================================================================
+    Boost.Wave: A Standard compliant C++ preprocessor library
+    http://www.boost.org/
+
+    Copyright (c) 2001-2010 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_CUSTOM_DIRECTIVES_HOOKS_INCLUDED)
+#define BOOST_WAVE_CUSTOM_DIRECTIVES_HOOKS_INCLUDED
+
+#include <cstdio>
+#include <ostream>
+#include <string>
+#include <algorithm>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/wave/token_ids.hpp>
+#include <boost/wave/util/macro_helpers.hpp>
+#include <boost/wave/preprocessing_hooks.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//  
+//  The custom_directives_hooks policy class is used to register some
+//  of the more advanced (and probably more rarely used hooks with the Wave
+//  library.
+//
+//  This policy type is used as a template parameter to the boost::wave::context<>
+//  object.
+//
+///////////////////////////////////////////////////////////////////////////////
+class custom_directives_hooks
+:   public boost::wave::context_policies::default_preprocessing_hooks
+{
+public:
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The function 'found_unknown_directive' is called, whenever an unknown 
+    //  preprocessor directive was encountered.
+    //
+    //  The parameter 'ctx' is a reference to the context object used for 
+    //  instantiating the preprocessing iterators by the user.
+    //
+    //  The parameter 'directive' is a reference to the token holding the 
+    //  preprocessing directive.
+    //
+    //  The parameter 'line' holds the entire source line containing the
+    //  unknown directive.
+    //
+    //  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 
+    //  line containing the unknown directive.
+    //
+    //  The return value defines, whether the given expression has been 
+    //  properly interpreted by the hook function or not. If this function 
+    //  returns 'false', the library will raise an 'ill_formed_directive' 
+    //  preprocess_exception. Otherwise the tokens pushed back into 'pending'
+    //  are passed on to the user program.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename ContextT, typename ContainerT>
+    bool
+    found_unknown_directive(ContextT const& ctx, ContainerT const& line, 
+        ContainerT& pending)
+    {
+        namespace wave = boost::wave;
+
+        typedef typename ContainerT::const_iterator iterator_type;
+        iterator_type it = line.begin();
+        wave::token_id id = wave::util::impl::skip_whitespace(it, line.end());
+
+        if (id != wave::T_IDENTIFIER)
+            return false;       // nothing we could do
+
+        if ((*it).get_value() == "version" || (*it).get_value() == "extension")
+        {
+            // handle #version and #extension directives
+            std::copy(line.begin(), line.end(), std::back_inserter(pending));
+            return true;
+        }
+
+        return false;           // unknown directive
+    }
+};
+
+#endif // !defined(BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED)
Added: trunk/libs/wave/samples/custom_directives/custom_directives.input
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/custom_directives/custom_directives.input	2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
@@ -0,0 +1,8 @@
+// This example recognizes two additional preprocessor directives (as defined
+// in GLSL - OpenGL Shader Language).
+
+#version 150 core
+#extension all : require
+
+// the following directive is not supported, so it will trigger an exception
+#not_supported_directive
Modified: trunk/libs/wave/test/testwave/collect_hooks_information.hpp
==============================================================================
--- trunk/libs/wave/test/testwave/collect_hooks_information.hpp	(original)
+++ trunk/libs/wave/test/testwave/collect_hooks_information.hpp	2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
@@ -754,6 +754,43 @@
     }
 #endif 
 
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The function 'found_unknown_directive' is called, whenever an unknown 
+    //  preprocessor directive was encountered.
+    //
+    //  The parameter 'ctx' is a reference to the context object used for 
+    //  instantiating the preprocessing iterators by the user.
+    //
+    //  The parameter 'directive' is a reference to the token holding the 
+    //  preprocessing directive.
+    //
+    //  The parameter 'line' holds the entire source line containing the
+    //  unknown directive.
+    //
+    //  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 
+    //  line containing the unknown directive.
+    //
+    //  The return value defines, whether the given expression has been 
+    //  properly interpreted by the hook function or not. If this function 
+    //  returns 'false', the library will raise an 'ill_formed_directive' 
+    //  preprocess_exception. Otherwise the tokens pushed back into 'pending'
+    //  are passed on to the user program.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename ContextT, typename ContainerT>
+    bool
+    found_unknown_directive(ContextT const& ctx, ContainerT const& line, 
+        ContainerT& pending)
+    {
+        BOOST_WAVETEST_OSSTREAM strm;
+        strm << "21: " << repr((*line.begin()).get_position()) << ": " 
+             << boost::wave::util::impl::as_string(line) << std::endl;
+        hooks_trace += BOOST_WAVETEST_GETSTRING(strm);
+        return false; 
+    }
+
 private:
     std::string& hooks_trace;
 };
Modified: trunk/libs/wave/test/testwave/testfiles/t_2_005.cpp
==============================================================================
--- trunk/libs/wave/test/testwave/testfiles/t_2_005.cpp	(original)
+++ trunk/libs/wave/test/testwave/testfiles/t_2_005.cpp	2010-02-06 18:23:31 EST (Sat, 06 Feb 2010)
@@ -10,7 +10,8 @@
 // test the error reporting for unknown directives
 
 //R
-//E t_2_005.cpp(14): error: ill formed preprocessor directive: this_is_a_unknown_pp_directive
+//E t_2_005.cpp(14): error: ill formed preprocessor directive: #this_is_a_unknown_pp_directive with some parameter
 #this_is_a_unknown_pp_directive with some parameter
 
+//H 21: t_2_005.cpp(14): #this_is_a_unknown_pp_directive with some parameter
 //H 18: boost::wave::preprocess_exception