Boost logo

Boost-Commit :

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


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