$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r60819 - trunk/tools/wave
From: hartmut.kaiser_at_[hidden]
Date: 2010-03-24 19:38:12
Author: hkaiser
Date: 2010-03-24 19:38:12 EDT (Wed, 24 Mar 2010)
New Revision: 60819
URL: http://svn.boost.org/trac/boost/changeset/60819
Log:
Wave: added new preprocessing hook: emit_line_directive, added corresponding functionality to wave driver
Text files modified: 
   trunk/tools/wave/cpp.cpp                   |     9 ++                                      
   trunk/tools/wave/cpp_version.hpp           |     4                                         
   trunk/tools/wave/trace_macro_expansion.hpp |    99 ++++++++++++++++++++++++++++++++++++++- 
   3 files changed, 104 insertions(+), 8 deletions(-)
Modified: trunk/tools/wave/cpp.cpp
==============================================================================
--- trunk/tools/wave/cpp.cpp	(original)
+++ trunk/tools/wave/cpp.cpp	2010-03-24 19:38:12 EDT (Wed, 24 Mar 2010)
@@ -841,7 +841,7 @@
     // control the generation of #line directives
         if (vm.count("line")) {
             int lineopt = vm["line"].as<int>();
-            if (0 != lineopt && 1 != lineopt) {
+            if (0 != lineopt && 1 != lineopt && 2 != lineopt) {
                 cerr << "wave: bogus value for --line command line option: " 
                     << lineopt << endl;
                 return -1;
@@ -849,6 +849,9 @@
             ctx.set_language(
                 boost::wave::enable_emit_line_directives(ctx.get_language(), 
                     lineopt != 0));
+
+            if (2 == lineopt) 
+                ctx.get_hooks().enable_relative_names_in_line_directives(true);
         }
 
     // control whether whitespace should be inserted to disambiguate output
@@ -1223,7 +1226,9 @@
             ("line,L", po::value<int>()->default_value(1), 
                 "control the generation of #line directives\n"
                             "0: no #line directives are generated,\n"
-                            "1: #line directives will be emitted (default)")
+                            "1: #line directives will be emitted (default),\n"
+                            "2: #line directives will be emitted using relative\n"
+                            "   filenames")
             ("disambiguate", po::value<int>()->default_value(1), 
                 "control whitespace insertion to disambiguate\n"
                 "consecutive tokens\n"
Modified: trunk/tools/wave/cpp_version.hpp
==============================================================================
--- trunk/tools/wave/cpp_version.hpp	(original)
+++ trunk/tools/wave/cpp_version.hpp	2010-03-24 19:38:12 EDT (Wed, 24 Mar 2010)
@@ -19,7 +19,7 @@
 
 #define CPP_VERSION_FULL_STR        BOOST_PP_STRINGIZE(CPP_VERSION_FULL)
 
-#define CPP_VERSION_DATE            20090602L
-#define CPP_VERSION_DATE_STR        "20090602"
+#define CPP_VERSION_DATE            20100324L
+#define CPP_VERSION_DATE_STR        "20100324"
 
 #endif // !defined(CPP_VERSION_HPP_CE4FE67F_63F9_468D_8364_C855F89D3C5D_INCLUDED)
Modified: trunk/tools/wave/trace_macro_expansion.hpp
==============================================================================
--- trunk/tools/wave/trace_macro_expansion.hpp	(original)
+++ trunk/tools/wave/trace_macro_expansion.hpp	2010-03-24 19:38:12 EDT (Wed, 24 Mar 2010)
@@ -154,7 +154,8 @@
         enable_system_command(enable_system_command_),
         preserve_whitespace(preserve_whitespace_),
         generate_output(generate_output_),
-        default_outfile(default_outfile_)
+        default_outfile(default_outfile_),
+        emit_relative_filenames(false)
     {
         using namespace std;    // some systems have time in namespace std
         time(&started_at);
@@ -172,6 +173,15 @@
         return counts;
     }
 
+    void enable_relative_names_in_line_directives(bool flag)
+    {
+        emit_relative_filenames = flag;
+    }
+    bool enable_relative_names_in_line_directives() const
+    {
+        return emit_relative_filenames;
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     //  
     //  The function 'expanding_function_like_macro' is called whenever a 
@@ -526,6 +536,79 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
+    //
+    //  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)
+    {
+        if (!need_emit_line_directives(ctx.get_language()) ||
+            !enable_relative_names_in_line_directives())
+        {
+            return false;
+        }
+
+    // emit a #line directive showing the relative filename instead
+    typename ContextT::position_type pos = act_token.get_position();
+    unsigned int column = 6;
+
+        typedef typename ContextT::token_type result_type;
+        using namespace boost::wave;
+
+        pos.set_column(1);
+        pending.push_back(result_type(T_PP_LINE, "#line", pos));
+
+        pos.set_column(column);      // account for '#line'
+        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;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
     //  
     //  The function 'opened_include_file' is called whenever a file referred 
     //  by an #include directive was successfully located and opened.
@@ -820,7 +903,7 @@
             // pop output preserve from the internal option stack
                 bool result = interpret_pragma_option_preserve_set(
                     preserve_options.top(), preserve_whitespace, ctx);
-                line_options.pop();
+                preserve_options.pop();
                 return result;
             }
             return false;
@@ -850,7 +933,13 @@
         if (T_IDENTIFIER == id) {
             if ((*it).get_value() == "push") {
             // push current line option onto the internal option stack
-                line_options.push(need_emit_line_directives(ctx.get_language()));
+                int mode = 0;
+                if (need_emit_line_directives(ctx.get_language())) {
+                    mode = 1;
+                    if (enable_relative_names_in_line_directives())
+                        mode = 2;
+                }
+                line_options.push(mode);
                 return true;
             }
             else if ((*it).get_value() == "pop") {
@@ -863,8 +952,9 @@
 
             // pop output line from the internal option stack
                 ctx.set_language(
-                    enable_emit_line_directives(ctx.get_language(), line_options.top()),
+                    enable_emit_line_directives(ctx.get_language(), 0 != line_options.top()),
                     false);
+                enable_relative_names_in_line_directives(2 == line_options.top());
                 line_options.pop();
                 return true;
             }
@@ -1255,6 +1345,7 @@
     std::stack<int> preserve_options;   // preserve option stack
 
     std::map<std::string, std::size_t> counts;    // macro invocation counts
+    bool emit_relative_filenames;   // emit relative names in #line directives
 };
 
 #undef BOOST_WAVE_GETSTRING