$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r60818 - in trunk/libs/wave: . samples samples/custom_directives samples/custom_directives/build samples/emit_custom_line_directives samples/emit_custom_line_directives/build
From: hartmut.kaiser_at_[hidden]
Date: 2010-03-24 19:37:25
Author: hkaiser
Date: 2010-03-24 19:37:24 EDT (Wed, 24 Mar 2010)
New Revision: 60818
URL: http://svn.boost.org/trac/boost/changeset/60818
Log:
Wave: added new preprocessing hook: emit_line_directive, fixed a couple related problems, added new example
Added:
   trunk/libs/wave/samples/emit_custom_line_directives/
   trunk/libs/wave/samples/emit_custom_line_directives/build/   (props changed)
   trunk/libs/wave/samples/emit_custom_line_directives/build/Jamfile.v2   (contents, props changed)
   trunk/libs/wave/samples/emit_custom_line_directives/emit_custom_line_directives.cpp   (contents, props changed)
   trunk/libs/wave/samples/emit_custom_line_directives/emit_custom_line_directives.hpp   (contents, props changed)
Properties modified: 
   trunk/libs/wave/samples/custom_directives/build/   (props changed)
Text files modified: 
   trunk/libs/wave/ChangeLog                                         |    14 ++++++++++++++                          
   trunk/libs/wave/samples/Jamfile.v2                                |     1 +                                       
   trunk/libs/wave/samples/custom_directives/custom_directives.input |     2 +-                                      
   3 files changed, 16 insertions(+), 1 deletions(-)
Modified: trunk/libs/wave/ChangeLog
==============================================================================
--- trunk/libs/wave/ChangeLog	(original)
+++ trunk/libs/wave/ChangeLog	2010-03-24 19:37:24 EDT (Wed, 24 Mar 2010)
@@ -22,6 +22,20 @@
 
 Boost V1.43.0
 - V2.0.5
+- Fixed line number counting for lines containing nothing but whitespace 
+  followed by a C++ comment if the next line is a pp directive.
+- Fixed emitting of a #line directive after returned from an include file.
+- A couple of fixes allowing to properly report the current line number in 
+  #line directives for different whitespace preserve modes (see --preserve/-p).
+- Added new preprocessing hook: emit_line_directive, allowing to customize the 
+  format of the generated #line directive.
+- Changed --line/-l command line option of the wave driver application to 
+  accept 0, 1, and 2 as options. The option values 0 and 1 behave as before 
+  (disable/enable the generation of #line directives), while the option value 2
+  will generate the #line directive using the relative filename (instead of the
+  absolute filename emitted from option 1). The default option is value 1.
+- Added new example: emit_custom_line_directives, demonstrating the use of the 
+  new preprocessing hook.
 - 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 
Modified: trunk/libs/wave/samples/Jamfile.v2
==============================================================================
--- trunk/libs/wave/samples/Jamfile.v2	(original)
+++ trunk/libs/wave/samples/Jamfile.v2	2010-03-24 19:37:24 EDT (Wed, 24 Mar 2010)
@@ -18,3 +18,4 @@
 build-project token_statistics/build ;
 build-project preprocess_pragma_output/build ;
 build-project custom_directives/build ;
+build-project emit_custom_line_directives/build ;
Modified: trunk/libs/wave/samples/custom_directives/custom_directives.input
==============================================================================
--- trunk/libs/wave/samples/custom_directives/custom_directives.input	(original)
+++ trunk/libs/wave/samples/custom_directives/custom_directives.input	2010-03-24 19:37:24 EDT (Wed, 24 Mar 2010)
@@ -2,7 +2,7 @@
 // in GLSL - OpenGL Shader Language).
 
 #version 150 core
-#extension all : require
+#extension all : require   // trailing comment
 
 // the following directive is not supported, so it will trigger an exception
 #not_supported_directive
Added: trunk/libs/wave/samples/emit_custom_line_directives/build/Jamfile.v2
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/emit_custom_line_directives/build/Jamfile.v2	2010-03-24 19:37:24 EDT (Wed, 24 Mar 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 emit_custom_line_directives
+    :   ../emit_custom_line_directives.cpp 
+        /boost/wave//boost_wave
+        /boost/thread//boost_thread
+        /boost/date_time//boost_date_time
+    ;  
+
Added: trunk/libs/wave/samples/emit_custom_line_directives/emit_custom_line_directives.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/emit_custom_line_directives/emit_custom_line_directives.cpp	2010-03-24 19:37:24 EDT (Wed, 24 Mar 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 "emit_custom_line_directives.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+//  Main entry point
+//
+//  This sample shows how to use the emit_line_directive preprocessing hooks 
+//  to customize the format of any generated #line directive. The sample will 
+//  emit #line directives formatted compatible with those generated by gcc:
+//
+//    # <lineno> <rel_file_name>
+//
+int main(int argc, char *argv[])
+{
+    if (2 != argc) {
+        std::cerr << "Usage: emit_custom_line_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,
+                emit_custom_line_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/emit_custom_line_directives/emit_custom_line_directives.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/wave/samples/emit_custom_line_directives/emit_custom_line_directives.hpp	2010-03-24 19:37:24 EDT (Wed, 24 Mar 2010)
@@ -0,0 +1,107 @@
+/*=============================================================================
+    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_emit_custom_line_directives_HOOKS_INCLUDED)
+#define BOOST_WAVE_emit_custom_line_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 emit_custom_line_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 emit_custom_line_directives_hooks
+:   public boost::wave::context_policies::default_preprocessing_hooks
+{
+public:
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The function 'emit_line_directive' is called whenever a #line directive
+    //  has to be emitted into the generated output.
+    //
+    //  The parameter 'ctx' is a reference to the context object used for 
+    //  instantiating the preprocessing iterators by the user.
+    //
+    //  The parameter 'pending' may be used to push tokens back into the input 
+    //  stream, which are to be used instead of the default output generated
+    //  for the #line directive.
+    //
+    //  The parameter 'act_token' contains the actual #pragma token, which may 
+    //  be used for error output. The line number stored in this token can be
+    //  used as the line number emitted as part of the #line directive.
+    //
+    //  If the return value is 'false', a default #line directive is emitted
+    //  by the library. A return value of 'true' will inhibit any further 
+    //  actions, the tokens contained in 'pending' will be copied verbatim 
+    //  to the output.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename ContextT, typename ContainerT>
+    bool 
+    emit_line_directive(ContextT const& ctx, ContainerT &pending, 
+        typename ContextT::token_type const& act_token)
+    {
+    // emit a #line directive showing the relative filename instead
+    typename ContextT::position_type pos = act_token.get_position();
+    unsigned int column = 1;
+
+        typedef typename ContextT::token_type result_type;
+        using namespace boost::wave;
+
+        pos.set_column(column);
+        pending.push_back(result_type(T_POUND, "#", pos));
+
+        pos.set_column(++column);      // account for '#'
+        pending.push_back(result_type(T_SPACE, " ", pos));
+
+    // 21 is the max required size for a 64 bit integer represented as a 
+    // string
+    char buffer[22];
+
+        using namespace std;    // for some systems sprintf is in namespace std
+        sprintf (buffer, "%d", pos.get_line());
+
+        pos.set_column(++column);                 // account for ' '
+        pending.push_back(result_type(T_INTLIT, buffer, pos));
+        pos.set_column(column += (unsigned int)strlen(buffer)); // account for <number>
+        pending.push_back(result_type(T_SPACE, " ", pos));
+        pos.set_column(++column);                 // account for ' '
+
+    std::string file("\"");
+    boost::filesystem::path filename(
+        boost::wave::util::create_path(ctx.get_current_relative_filename().c_str()));
+
+        using boost::wave::util::impl::escape_lit;
+        file += escape_lit(boost::wave::util::native_file_string(filename)) + "\"";
+
+        pending.push_back(result_type(T_STRINGLIT, file.c_str(), pos));
+        pos.set_column(column += (unsigned int)file.size());    // account for filename
+        pending.push_back(result_type(T_GENERATEDNEWLINE, "\n", pos));
+
+        return true;
+    }
+};
+
+#endif // !defined(BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED)