From b56e3e3c3e0120ee2aab3923e4dc98a4166fbd63 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Sat, 25 Sep 2004 18:04:29 +0000 Subject: [PATCH] Updated Wave for Boost-review. [SVN r2314] --- ChangeLog | 35 +++ build/Jamfile | 2 +- doc/class_reference_context.html | 2 +- ...tml => class_reference_contextpolicy.html} | 138 +++++----- doc/class_reference_inputpolicy.html | 4 +- doc/class_reference_lexer.html | 4 +- doc/supported_pragmas.html | 12 +- include/boost/wave/cpp_context.hpp | 34 ++- ...e_policies.hpp => preprocessing_hooks.hpp} | 103 +++---- include/boost/wave/util/cpp_iterator.hpp | 5 +- include/boost/wave/util/cpp_macromap.hpp | 184 +++++++------ include/boost/wave/util/interpret_pragma.hpp | 143 +--------- include/boost/wave/util/macro_helpers.hpp | 42 ++- include/boost/wave/util/symbol_table.hpp | 4 - include/boost/wave/wave_config.hpp | 8 +- include/boost/wave/wave_version.hpp | 4 +- index.html | 6 +- samples/cpp_tokens/cpp_tokens.cpp | 4 +- samples/cpp_tokens/cpp_tokens_config.hpp | 154 +---------- samples/list_includes/list_includes.cpp | 8 +- .../list_includes/list_includes_config.hpp | 144 +--------- samples/quick_start/quick_start.cpp | 4 +- samples/waveidl/idl.cpp | 8 +- samples/waveidl/idl_config.hpp | 143 +--------- tool/cpp.cpp | 51 ++-- tool/cpp_config.hpp | 8 +- tool/cpp_version.hpp | 2 +- tool/stop_watch.hpp | 84 ++++++ tool/trace_macro_expansion.hpp | 252 ++++++++++-------- 29 files changed, 638 insertions(+), 954 deletions(-) rename doc/{class_reference_tracepolicy.html => class_reference_contextpolicy.html} (68%) rename include/boost/wave/{trace_policies.hpp => preprocessing_hooks.hpp} (73%) create mode 100644 tool/stop_watch.hpp diff --git a/ChangeLog b/ChangeLog index 9fc4360..5dc9f52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,41 @@ TODO (known issues): - Do a sourceforge release. +- Moved all of the #pragma wave option(value) operators out of the wavelib into + the wave driver program. Removed enable_trace() and trace_flags() policy + functions. Renamed trace_policy into context_policy. +- Added the defined_macro() and undefined_macro() preprocessing hooks to allow + easily to build macro cross referencers and such. + +Version 1.1.8 +- Replaced the usage of the string::erase() and string::insert() functions, + which were the only non-const string member functions used. +- Token pasting is now well defined in variadics mode (was in C++0x mode only). +- Changed the timing code in the wave driver to include the parsing of + files included by the --forceinclude command line switch. +- Performance measurements (very informal) [sec], the files are some of the + preprocessor specific test cases from Paul Mensonides chaos_pp library. + + std::string flex_string const_string const_string + 12 Byte 28 Byte + arithmetic.cpp 2.543 1.742 0.951 1.001 + array.cpp 2.453 1.762 0.951 1.011 + comparison.cpp 0.560 0.340 0.270 0.280 + control.cpp 0.590 0.340 0.290 0.300 + debug.cpp 0.370 0.310 0.190 0.190 + detection.cpp 0.050 0.060 0.030 0.030 + extended.cpp 0.370 0.260 0.190 0.190 + facilities.cpp 0.610 0.340 0.290 0.300 + iteration.cpp 1.081 0.550 0.410 0.450 + list.cpp 1.742 1.141 0.811 0.851 + logical.cpp 0.070 0.200 0.040 0.040 + punctuation.cpp 0.030 0.080 0.020 0.020 + repetition.cpp 1.392 0.851 0.650 0.690 + selection.cpp 0.440 0.270 0.210 0.220 + slot.cpp 0.680 0.350 0.240 0.270 + tuple.cpp 0.420 0.240 0.190 0.210 + + Wed Aug 25 13:23:27 WEDT 2004 Version 1.1.7 - Branched for Boost Release. diff --git a/build/Jamfile b/build/Jamfile index 625faa3..1fc8bb4 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -36,7 +36,7 @@ lib boost_wave # : ../src/$(SOURCES).cpp # : # build requirements # [ common-names ] # magic for install and auto-link features -# BOOST_FILESYSTEM_DYN_LINK=1 # tell source we're building dll's +# BOOST_WAVE_DYN_LINK=1 # tell source we're building dll's # dynamic # build only for dynamic runtimes # $(BOOST_ROOT) # $(BOOST_ROOT) diff --git a/doc/class_reference_context.html b/doc/class_reference_context.html index 2ad967d..5843612 100644 --- a/doc/class_reference_context.html +++ b/doc/class_reference_context.html @@ -137,7 +137,7 @@ topic The Input Policy.

If the template parameter TracePolicyT is omitted, the wave::macro_trace_policies::no_tracing policy type is used, i.e. by default there is no tracing performed. For further - information about the tracing policy, please refer to the topic The + information about the tracing policy, please refer to the topic The Tracing Policy.

Public Typedefs

The boost::wave::context template defines the following public typedefs, which may be useful while using this class:

diff --git a/doc/class_reference_tracepolicy.html b/doc/class_reference_contextpolicy.html similarity index 68% rename from doc/class_reference_tracepolicy.html rename to doc/class_reference_contextpolicy.html index 04236bc..02cee53 100644 --- a/doc/class_reference_tracepolicy.html +++ b/doc/class_reference_contextpolicy.html @@ -1,7 +1,7 @@ -The Tracing Policy +The Context Policy @@ -11,7 +11,7 @@

The - Tracing Policy + Context Policy @@ -26,47 +26,31 @@

Introduction
- Header 'wave/trace_policies.hpp' + Header 'wave/preprocessing_hooks.hpp' synopsis
Member functions

Introduction

-

There is implemented an unique tracing facility as a part of the Wave - library, which allows to selectively trace all stages of the macro expansion - process, involving the argument expansion and the rescanning of the replacement - results. This tracing facility greatly helps to understand foreign code or to - debug your own macros.

-

The tracing policy is used to trace the macro expansion of macros whenever - it is requested from inside the input stream to preprocess through the #pragma wave_option(trace: enable) - (or _Pragma("wave trace(enable)")) directive. The macro - tracing may be disabled again with the help of a #pragma wave_option(trace: - disable) (or _Pragma("wave trace(disable)")) directive. - Note though, that the Wave driver executable requires additionally - to specify the -t (--trace) command line option, which defines - the stream, where the trace output goes.

+

The context policy is used to provide callback hooks, which are called from inside the library into the user code, whenever

+
    +
  • a macro get's defined or undefind,
  • +
  • a macro is expanded or rescanned,
  • +
  • an include file is opened or left,
  • +
  • a pragma of the form 'wave option[(value)]' is recognised.
  • +

This policy type is used as a template parameter to the wave::context<> - object, where the default policy does no tracing at all.

-

Header wave/trace_policies.hpp + object, where the default policy proviedes empty hooks functions only.

+

Header wave/preprocessing_hooks.hpp synopsis

 namespace boost {
 namespace wave {
-namespace trace_policies {
+namespace context_policies {
  
-    enum trace_flags {
-	        trace_nothing = 0,      // disable tracing
-			trace_macros = 1,       // enable macro tracing
-	        trace_includes = 2      // enable include file tracing
-    };
-
-    struct default_tracing {
+    struct default_preprocessing_hooks {
 
         // general control function
-        void enable_tracing(trace_flags enable);
-        trace_flags tracing_enabled();
-
-        // macro tracing functions
-        template <typename TokenT, typename ContainerT>
+        template <typename TokenT, typename ContainerT>
         void expanding_function_like_macro(TokenT const &macrodef, 
             std::vector<TokenT> const &formal_args, 
             ContainerT const &definition, TokenT const &macrocall, 
@@ -88,32 +72,29 @@
 
         void returning_from_include_file();
 
-        // interpretation of unknown #pragma's
-        template <typename TokenT, typename ContainerT>
-		        bool interpret_pragma(ContainerT &pending, 
-             TokenT const &option, ContainerT const &values, 
-             TokenT const &pragma_token, language_support language);
+        // interpretation of #pragma's of the form 
+        // 'wave option[(value)]'
+        template <typename ContextT, typename ContainerT>
+		bool interpret_pragma(ContextT const &ctx, ContainerT &pending, 
+            typename ContextT::token_type const &option, 
+            ContainerT const &values, 
+            typename ContextT::token_type const &pragma_token);
+
+        // macro definition hooks
+        template <
+            typename TokenT, typename ParametersT, typename DefinitionT
+        >
+        void defined_macro(TokenT const &name, bool is_functionlike,
+            ParametersT const &parameters, DefinitionT const &definition,
+            bool is_predefined);
+
+        template <typename StringT>
+        void undefined_macro(StringT const &name);
     };
 
-}   // namespace macro_trace_policy
-}   
-
+}}} // namespace boost::wave::context_policies

Member functions

-

General control functions

-

enable_tracing

-
    void enable_tracing(trace_flags enable);
-
-

The function enable_tracing is called, whenever the status of the - tracing was changed from inside the stream to preprocess.

-

The parameter enable is to be used as the new tracing status.

-
-

tracing_enabled

-
    trace_flags tracing_enabled();
-
-

The function tracing_enabled should return the current tracing status.

-
-

Tracing functions

-

Macro tracing functions

+

Macro expansion tracking functions

expanding_function_like_macro

    template <typename TokenT, typename ContainerT>
     void expanding_function_like_macro(TokenT const &macrodef, 
@@ -181,7 +162,7 @@
     expansion. This is a standard STL container containing the generated token 
     sequence.

-

Include file tracing functions

+

Include file tracing functions

opened_include_file

    void opened_include_file(std::string const &filename, 
         std::size_t include_depth, bool is_system_include);
@@ -203,16 +184,19 @@
   

The function returning_from_include_file is called, whenever an included file is about to be closed after it's processing is complete.

+

Interpretation of #pragma's

interpret_pragma

-
    template <typename TokenT, typename ContainerT>
-		   bool interpret_pragma(ContainerT &pending, 
-        TokenT const &option, ContainerT const &values, 
-        TokenT const &pragma_token, language_support language);
+
    template <typename Context, typename ContainerT>
+    bool interpret_pragma(ContextT const &ctx, ContainerT &pending, 
+        typename ContextT::token_type const &option, 
+        ContainerT const &values, 
+        typename ContextT::token_type const &pragma_token);
 

The function interpret_pragma is called, whenever an unrecognized #pragma wave ... or operator _Pragma("wave ...") is found in the input stream.

+

The ctx parameter provides a reference to the context_type used during instatiation of the preprocessing iterators by the user.

The pending parameter may be used to push tokens back into the input stream, which are to be used as the replacement text for the whole #pragma wave() directive. If this sequence is left empty, no replacement takes place, i.e. @@ -222,13 +206,43 @@ the pragma operator.

The pragma_token parameter contains the actual #pragma token, which may be used for extraction of the location information for some error output.

-

The language parameter contains the current language mode, in which - the Wave library operates.

If the return value is 'false', the whole #pragma directive is interpreted as unknown and a corresponding error message is issued. A return value of 'true' signs a successful interpretation of the given #pragma.

+

Macro definition

+

defined_macro

+
    template <
+        typename TokenT, typename ParametersT, typename DefinitionT
+    >
+    void defined_macro(TokenT const &name, bool is_functionlike,
+        ParametersT const &parameters, DefinitionT const &definition,
+        bool is_predefined);
+
+

The function defined_macro is called, whenever a macro was defined successfully.

+

The parameter name is a reference to the token holding the macro name.

+

The parameter is_functionlike is set to true, whenever the newly + defined macro is defined as a function like macro.

+

The parameter parameters holds the parameter tokens for the macro + definition. If the macro has no parameters or if it is a object like + macro, then this container is empty.

+

The parameter definition contains the token sequence given as the + replacement sequence (definition part) of the newly defined macro.

+

The parameter is_predefined is set to true for all macros predefined + during the initialisation pahase of the library.
+

+
+

undefined_macro

+
    template <typename StringT>
+    void undefined_macro(StringT const &name);
+
+
+

The function undefined_macro is called, whenever a macro definition + was removed successfully.

+

The parameter name holds the name of the macro, which definition was removed.
+

+
@@ -243,7 +257,7 @@ 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)

diff --git a/doc/class_reference_inputpolicy.html b/doc/class_reference_inputpolicy.html index 7a91a82..fbe119e 100644 --- a/doc/class_reference_inputpolicy.html +++ b/doc/class_reference_inputpolicy.html @@ -21,7 +21,7 @@ - +
@@ -117,7 +117,7 @@ - +
diff --git a/doc/class_reference_lexer.html b/doc/class_reference_lexer.html index 115fe78..fd88f03 100644 --- a/doc/class_reference_lexer.html +++ b/doc/class_reference_lexer.html @@ -20,7 +20,7 @@ - + @@ -86,7 +86,7 @@ - + diff --git a/doc/supported_pragmas.html b/doc/supported_pragmas.html index d7cd57e..2226bba 100644 --- a/doc/supported_pragmas.html +++ b/doc/supported_pragmas.html @@ -36,7 +36,7 @@ where 'wave' is the specific keyword, 'option' is the concrete pragma functionality to trigger and 'value' is an optional value to be supplied to the 'option' functionality. The following table lists - all possible pragma functions supported by the Wave library.

+ all possible pragma functions supported by the Wave library. For all recognised pragmas of this general form the interpret_pragma hook function from inside the context_policies are call, so that the user of the library is responsible for

@@ -55,14 +55,14 @@ macro expansion process. This is needed, even if there is given the --trace command line option, because the trace output is generated only, if there is at least one trace(enable) pragma found.

- + - + @@ -75,7 +75,7 @@ to be successful, if/when the return value is zero, otherwise an error is reported.

- + @@ -105,7 +105,7 @@ which specifies that the file, in which the pragma resides, will be included (opened) only once by the compiler in a build. This may be used to optimize the preprocessing of larger compilation units, which include a lot of files. Note though, that the #pragma once directive is supported only, if the compile time constant WAVE_SUPPORT_PRAGMA_ONCE was given during compilation of the library.

-

It is fairly easy to implement your own #pragma wave ... directives. All you have to do is to implement your own interpret_pragma function (see here) which should the handle additional directives. For an example of how to do it, you may have a look at the Wave driver application, which implements the #pragma wave timer() directive with the help of a supplied interpret_pragma function.

+

It is fairly easy to implement your own #pragma wave ... directives. All you have to do is to implement your own interpret_pragma function (see here) which should the handle additional directives. For an example of how to do it, you may have a look at the Wave driver application, which implements the #pragma wave timer() directive with the help of a supplied interpret_pragma function.

Supported pragma's

Wave library

Wave driver

stop

message

Stop the execution of Wave and print out the given message. This is very helpful for direct debugging purposes.

Wave library

Wave driver

Wave library

Wave driver

timer

@@ -120,7 +120,7 @@ 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)

 

diff --git a/include/boost/wave/cpp_context.hpp b/include/boost/wave/cpp_context.hpp index f929172..cb67ff4 100644 --- a/include/boost/wave/cpp_context.hpp +++ b/include/boost/wave/cpp_context.hpp @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include @@ -61,7 +61,7 @@ template < typename IteratorT, typename LexIteratorT, typename InputPolicyT = iteration_context_policies::load_file_to_string, - typename TraceT = trace_policies::default_tracing + typename TraceT = context_policies::default_preprocessing_hooks > class context { @@ -170,11 +170,7 @@ public: iter_size_type get_max_include_nesting_depth() const { return iter_ctxs.get_max_include_nesting_depth(); } -// enable/disable tracing - void enable_tracing(trace_policies::trace_flags enable) - { trace.enable_tracing(enable); } - trace_policies::trace_flags tracing_enabled() - { return trace.tracing_enabled(); } +// access the trace policy trace_policy_type &get_trace_policy() { return trace; } @@ -259,16 +255,28 @@ public: bool add_pragma_once_header(std::string const &filename) { return includes.add_pragma_once_header(filename); } #endif - + +// forwarding functions for the context policy hooks template bool interpret_pragma(ContainerT &pending, token_type const &option, - ContainerT const &values, token_type const &act_token, - boost::wave::language_support language) + ContainerT const &values, token_type const &act_token) { - return trace.interpret_pragma(pending, option, values, act_token, - language); + return trace.interpret_pragma(*this, pending, option, values, + act_token); } - + template + void defined_macro(token_type const &name, bool is_functionlike, + ParametersT const ¶meters, DefinitionT const &definition, + bool is_predefined) + { + trace.defined_macro(name, is_functionlike, parameters, definition, + is_predefined); + } + void undefined_macro(typename token_type::string_type const &name) + { + trace.undefined_macro(name); + } + private: // the main input stream target_iterator_type const &first; // underlying input stream diff --git a/include/boost/wave/trace_policies.hpp b/include/boost/wave/preprocessing_hooks.hpp similarity index 73% rename from include/boost/wave/trace_policies.hpp rename to include/boost/wave/preprocessing_hooks.hpp index 1fcfe2a..a0cdc63 100644 --- a/include/boost/wave/trace_policies.hpp +++ b/include/boost/wave/preprocessing_hooks.hpp @@ -8,54 +8,24 @@ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#if !defined(TRACE_POLICIES_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED) -#define TRACE_POLICIES_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED +#if !defined(PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED) +#define PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED #include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace wave { -namespace trace_policies { +namespace context_policies { /////////////////////////////////////////////////////////////////////////////// // -// trace_flags: enable single tracing functionality -// -/////////////////////////////////////////////////////////////////////////////// -enum trace_flags { - trace_nothing = 0, // disable tracing - trace_macros = 1, // enable macro tracing - trace_includes = 2 // enable include file tracing -}; - -/////////////////////////////////////////////////////////////////////////////// -// -// The default_tracing class is a placeholder for all macro -// expansion trace hooks contained inside the macro expansion engine +// The default_preprocessing_hooks class is a placeholder for all +// preprocessing hooks called from inside the preprocessing engine // /////////////////////////////////////////////////////////////////////////////// -struct default_tracing { +struct default_preprocessing_hooks { - /////////////////////////////////////////////////////////////////////////// - // - // The function enable_tracing is called, whenever the status of the - // tracing was changed. - // - // The parameter 'enable' is to be used as the new tracing status. - // - /////////////////////////////////////////////////////////////////////////// - void enable_tracing(trace_flags flags) - {} - - /////////////////////////////////////////////////////////////////////////// - // - // The function tracing_enabled should return the current tracing status. - // - /////////////////////////////////////////////////////////////////////////// - trace_flags tracing_enabled() - { return trace_nothing; } - /////////////////////////////////////////////////////////////////////////// // // The function 'expanding_function_like_macro' is called, whenever a @@ -158,6 +128,9 @@ struct default_tracing { // The function 'interpret_pragma' is called, whenever a #pragma wave // directive is found, which isn't known to the core Wave library. // + // 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 as the replacement text for the whole // #pragma wave() directive. @@ -170,28 +143,68 @@ struct default_tracing { // The parameter 'act_token' contains the actual #pragma token, which may // be used for error output. // - // The parameter 'language' contains the current language mode, in which - // the Wave library operates. - // // If the return value is 'false', the whole #pragma directive is // interpreted as unknown and a corresponding error message is issued. A // return value of 'true' signs a successful interpretation of the given // #pragma. // /////////////////////////////////////////////////////////////////////////// - template + template bool - interpret_pragma(ContainerT &pending, TokenT const &option, - ContainerT const &values, TokenT const &act_token, - boost::wave::language_support language) + interpret_pragma(ContextT const &ctx, ContainerT &pending, + typename ContextT::token_type const &option, ContainerT const &values, + typename ContextT::token_type const &act_token) { return false; } + + /////////////////////////////////////////////////////////////////////////// + // + // The function 'defined_macro' is called, whenever a macro was defined + // successfully. + // + // The parameter 'name' is a reference to the token holding the macro name. + // + // The parameter 'is_functionlike' is set to true, whenever the newly + // defined macro is defined as a function like macro. + // + // The parameter 'parameters' holds the parameter tokens for the macro + // definition. If the macro has no parameters or if it is a object like + // macro, then this container is empty. + // + // The parameter 'definition' contains the token sequence given as the + // replacement sequence (definition part) of the newly defined macro. + // + // The parameter 'is_predefined' is set to true for all macros predefined + // during the initialisation pahase of the library. + // + /////////////////////////////////////////////////////////////////////////// + template + void + defined_macro(TokenT const ¯o_name, bool is_functionlike, + ParametersT const ¶meters, DefinitionT const &definition, + bool is_predefined) + {} + + /////////////////////////////////////////////////////////////////////////// + // + // The function 'undefined_macro' is called, whenever a macro definition + // was removed successfully. + // + // The parameter 'name' holds the name of the macro, which definition was + // removed. + // + /////////////////////////////////////////////////////////////////////////// + template + void + undefined_macro(StringT const ¯o_name) + {} + }; /////////////////////////////////////////////////////////////////////////////// -} // namespace trace_policies +} // namespace context_policies } // namespace wave } // namespace boost -#endif // !defined(TRACE_POLICIES_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED) +#endif // !defined(PREPROCESSING_HOOKS_HPP_338DE478_A13C_4B63_9BA9_041C917793B8_INCLUDED) diff --git a/include/boost/wave/util/cpp_iterator.hpp b/include/boost/wave/util/cpp_iterator.hpp index 58ccf3e..f127ba6 100644 --- a/include/boost/wave/util/cpp_iterator.hpp +++ b/include/boost/wave/util/cpp_iterator.hpp @@ -149,7 +149,7 @@ std::string::iterator end = macrostring.end(); while(begin != end && isspace(*begin)) ++begin; -// parse the macr definition +// parse the macro definition position_type act_pos("command line", 0); boost::spirit::tree_parse_info hit = predef_macros_type::parse_predefined_macro( @@ -1651,8 +1651,7 @@ pp_iterator_functor::interpret_pragma( if (it == end) // eof reached return false; - return boost::wave::util::interpret_pragma(ctx, act_token, it, end, result, - ctx.get_language()); + return boost::wave::util::interpret_pragma(ctx, act_token, it, end, result); } /////////////////////////////////////////////////////////////////////////////// diff --git a/include/boost/wave/util/cpp_macromap.hpp b/include/boost/wave/util/cpp_macromap.hpp index 6cef92e..a5b13d2 100644 --- a/include/boost/wave/util/cpp_macromap.hpp +++ b/include/boost/wave/util/cpp_macromap.hpp @@ -112,24 +112,24 @@ template class macromap { typedef macromap self_type; - typedef typename ContextT::token_type token_type; - typedef typename token_type::string_type string_type; - typedef typename token_type::position_type position_type; + typedef typename ContextT::token_type token_type; + typedef typename token_type::string_type string_type; + typedef typename token_type::position_type position_type; // type of a token sequence - typedef typename ContextT::token_sequence_type definition_container_t; + typedef typename ContextT::token_sequence_type definition_container_type; - typedef macro_definition - macro_definition_t; + typedef macro_definition + macro_definition_type; - typedef symbol_table defined_macros_t; - typedef typename defined_macros_t::value_type::second_type macro_ref_t; + typedef symbol_table defined_macros_type; + typedef typename defined_macros_type::value_type::second_type macro_ref_type; - typedef std::vector parameter_container_t; + typedef std::vector parameter_container_type; public: macromap(ContextT &ctx_) - : current_macros(0), defined_macros(new defined_macros_t(1)), + : current_macros(0), defined_macros(new defined_macros_type(1)), main_pos("", 0), ctx(ctx_), macro_uid(1) { current_macros = defined_macros.get(); @@ -137,11 +137,12 @@ public: ~macromap() {} bool add_macro(token_type const &name, bool has_parameters, - parameter_container_t ¶meters, definition_container_t &definition, - bool is_predefined = false, defined_macros_t *scope = 0); + parameter_container_type ¶meters, + definition_container_type &definition, bool is_predefined = false, + defined_macros_type *scope = 0); bool is_defined(string_type const &name, - typename defined_macros_t::iterator &it, - defined_macros_t *scope = 0) const; + typename defined_macros_type::iterator &it, + defined_macros_type *scope = 0) const; template bool is_defined(IteratorT const &begin, IteratorT const &end); bool remove_macro(string_type const &name, bool even_predefined = false); @@ -155,9 +156,9 @@ public: IteratorT const &first, IteratorT const &last, bool expand_undefined, bool *seen_qualified_name = 0); - void init_predefined_macros(defined_macros_t *scope = 0, + void init_predefined_macros(defined_macros_type *scope = 0, bool at_global_scope = true); - void predefine_macro(defined_macros_t *scope, string_type const &name, + void predefine_macro(defined_macros_type *scope, string_type const &name, token_type const &t); void reset_macromap(); @@ -182,9 +183,9 @@ protected: template bool expand_macro(ContainerT &pending, token_type const &name, - typename defined_macros_t::iterator it, + typename defined_macros_type::iterator it, IteratorT &first, IteratorT const &last, bool expand_undefined, - defined_macros_t *scope = 0, ContainerT *queue_symbol = 0, + defined_macros_type *scope = 0, ContainerT *queue_symbol = 0, bool *seen_qualified_name = 0); template @@ -199,13 +200,13 @@ protected: template void expand_replacement_list( - macro_definition_t const ¯odefinition, + macro_definition_type const ¯odefinition, std::vector &arguments, bool expand_undefined, ContainerT &expanded); template void rescan_replacement_list(token_type const &curr_token, - macro_definition_t ¯odef, ContainerT &replacement_list, + macro_definition_type ¯odef, ContainerT &replacement_list, ContainerT &expanded, bool expand_undefined, bool *seen_qualified_name); template @@ -223,18 +224,18 @@ protected: position_type const &pos, ContainerT &rescanned); static bool - definition_equals(definition_container_t const &definition, - definition_container_t const &new_definition); + definition_equals(definition_container_type const &definition, + definition_container_type const &new_definition); static bool - parameters_equal(parameter_container_t const ¶meters, - parameter_container_t const &new_definition); + parameters_equal(parameter_container_type const ¶meters, + parameter_container_type const &new_definition); static bool token_equals(token_type const &left, token_type const &right); private: - defined_macros_t *current_macros; // current symbol table - boost::shared_ptr defined_macros; // global symbol table + defined_macros_type *current_macros; // current symbol table + boost::shared_ptr defined_macros; // global symbol table token_type act_token; // current token position_type main_pos; // last token position in the pp_iterator @@ -304,20 +305,20 @@ macromap::token_equals(token_type const &left, token_type const &right template inline bool -macromap::definition_equals(definition_container_t const &definition, - definition_container_t const &new_definition) +macromap::definition_equals(definition_container_type const &definition, + definition_container_type const &new_definition) { - typedef definition_container_t::const_iterator const_iterator_t; + typedef definition_container_type::const_iterator const_iterator_type; -typename const_iterator_t first1 = definition.begin(); -typename const_iterator_t last1 = definition.end(); -typename const_iterator_t first2 = new_definition.begin(); -typename const_iterator_t last2 = new_definition.end(); +typename const_iterator_type first1 = definition.begin(); +typename const_iterator_type last1 = definition.end(); +typename const_iterator_type first2 = new_definition.begin(); +typename const_iterator_type last2 = new_definition.end(); while (first1 != last1 && token_equals(*first1, *first2)) { // skip whitespace, if both sequences have a whitespace next - token_id id1 = impl::next_token::peek(first1, last1, false); - token_id id2 = impl::next_token::peek(first2, last2, false); + token_id id1 = impl::next_token::peek(first1, last1, false); + token_id id2 = impl::next_token::peek(first2, last2, false); if (IS_CATEGORY(id1, WhiteSpaceTokenType) && IS_CATEGORY(id2, WhiteSpaceTokenType)) @@ -343,17 +344,17 @@ typename const_iterator_t last2 = new_definition.end(); template inline bool -macromap::parameters_equal(parameter_container_t const ¶meters, - parameter_container_t const &new_parameters) +macromap::parameters_equal(parameter_container_type const ¶meters, + parameter_container_type const &new_parameters) { if (parameters.size() != new_parameters.size()) return false; // different parameter count - typedef parameter_container_t::const_iterator const_iterator_t; + typedef parameter_container_type::const_iterator const_iterator_type; -typename const_iterator_t first1 = parameters.begin(); -typename const_iterator_t last1 = parameters.end(); -typename const_iterator_t first2 = new_parameters.begin(); +typename const_iterator_type first1 = parameters.begin(); +typename const_iterator_type last1 = parameters.end(); +typename const_iterator_type first2 = new_parameters.begin(); while (first1 != last1) { // parameters are different, if the corresponding tokens are different @@ -371,8 +372,8 @@ typename const_iterator_t first2 = new_parameters.begin(); template inline bool macromap::add_macro(token_type const &name, bool has_parameters, - parameter_container_t ¶meters, definition_container_t &definition, - bool is_predefined, defined_macros_t *scope) + parameter_container_type ¶meters, definition_container_type &definition, + bool is_predefined, defined_macros_type *scope) { if (!is_predefined && is_special_macroname (name.get_value())) { // exclude special macro names @@ -381,8 +382,8 @@ macromap::add_macro(token_type const &name, bool has_parameters, } // try to define the new macro -defined_macros_t *current_scope = scope ? scope : current_macros; -typename defined_macros_t::iterator it = current_scope->find(name.get_value()); +defined_macros_type *current_scope = scope ? scope : current_macros; +typename defined_macros_type::iterator it = current_scope->find(name.get_value()); if (it != current_scope->end()) { // redefinition, should not be different @@ -400,14 +401,14 @@ typename defined_macros_t::iterator it = current_scope->find(name.get_value()); if (has_parameters) { std::set names; - typedef typename parameter_container_t::iterator - parameter_iterator_t; + typedef typename parameter_container_type::iterator + parameter_iterator_type; typedef typename std::set::iterator - name_iterator_t; + name_iterator_type; - parameter_iterator_t end = parameters.end(); - for (parameter_iterator_t it = parameters.begin(); it != end; ++it) { - name_iterator_t pit = names.find((*it).get_value()); + parameter_iterator_type end = parameters.end(); + for (parameter_iterator_type it = parameters.begin(); it != end; ++it) { + name_iterator_type pit = names.find((*it).get_value()); if (pit != names.end()) { // duplicate parameter name @@ -419,11 +420,11 @@ typename defined_macros_t::iterator it = current_scope->find(name.get_value()); } // insert a new macro node - std::pair p = + std::pair p = current_scope->insert( - defined_macros_t::value_type( + defined_macros_type::value_type( name.get_value(), - macro_ref_t(new macro_definition_t(name, + macro_ref_type(new macro_definition_type(name, has_parameters, is_predefined, ++macro_uid) ) ) @@ -437,6 +438,10 @@ typename defined_macros_t::iterator it = current_scope->find(name.get_value()); // add the parameters and the definition std::swap((*p.first).second->macroparameters, parameters); std::swap((*p.first).second->macrodefinition, definition); + +// call the context supplied preprocessing hook + ctx.defined_macro(name, has_parameters, parameters, definition, + is_predefined); return true; } @@ -448,8 +453,8 @@ typename defined_macros_t::iterator it = current_scope->find(name.get_value()); template inline bool macromap::is_defined(typename token_type::string_type const &name, - typename defined_macros_t::iterator &it, - defined_macros_t *scope) const + typename defined_macros_type::iterator &it, + defined_macros_type *scope) const { if (0 == scope) scope = current_macros; @@ -483,7 +488,7 @@ macromap::is_defined(IteratorT const &begin, IteratorT it = begin; string_type name ((*it).get_value()); - typename defined_macros_t::iterator cit( + typename defined_macros_type::iterator cit( current_macros -> find(name)); if (++it != end) { @@ -506,7 +511,7 @@ inline bool macromap::remove_macro(string_type const &name, bool even_predefined) { - typename defined_macros_t::iterator it = current_macros->find(name); + typename defined_macros_type::iterator it = current_macros->find(name); if (it != current_macros->end()) { if ((*it).second->is_predefined) { @@ -516,6 +521,9 @@ macromap::remove_macro(string_type const &name, } } current_macros->erase(it); + + // call the context supplied preprocessing hook function + ctx.undefined_macro(name); return true; } else if (is_special_macroname(name)) { @@ -665,7 +673,7 @@ macromap::expand_tokensequence_worker( // if there exist pending tokens (tokens, which are already preprocessed), then // return the next one from there if (!pending.empty()) { - on_exit::pop_front pop_front_token(pending); + on_exit::pop_front pop_front_token(pending); return act_token = pending.front(); } @@ -717,7 +725,7 @@ macromap::expand_tokensequence_worker_classical( { // unknown to us pragma or supplied replacement, return the // next token - on_exit::pop_front pop_token(pending); + on_exit::pop_front pop_token(pending); return act_token = pending.front(); } @@ -728,7 +736,7 @@ macromap::expand_tokensequence_worker_classical( } token_type name_token (*first); - typename defined_macros_t::iterator it; + typename defined_macros_type::iterator it; if (is_defined(name_token.get_value(), it)) { // the current token contains an identifier, which is currently @@ -751,7 +759,7 @@ macromap::expand_tokensequence_worker_classical( } else if (!pending.empty()) { // return the first token from the pending queue - on_exit::pop_front pop_queue (pending); + on_exit::pop_front pop_queue (pending); return act_token = pending.front(); } @@ -1096,12 +1104,12 @@ template template inline void macromap::expand_replacement_list( - macro_definition_t const ¯odef, + macro_definition_type const ¯odef, std::vector &arguments, bool expand_undefined, ContainerT &expanded) { using namespace boost::wave; - typedef typename macro_definition_t::const_definition_iterator_t + typedef typename macro_definition_type::const_definition_iterator_t macro_definition_iter_t; std::vector expanded_args(arguments.size()); @@ -1254,7 +1262,7 @@ template template inline void macromap::rescan_replacement_list(token_type const &curr_token, - macro_definition_t ¯o_def, ContainerT &replacement_list, + macro_definition_type ¯o_def, ContainerT &replacement_list, ContainerT &expanded, bool expand_undefined, bool *seen_qualified_name) { using namespace boost::wave; @@ -1336,9 +1344,9 @@ template template inline bool macromap::expand_macro(ContainerT &expanded, - token_type const &curr_token, typename defined_macros_t::iterator it, + token_type const &curr_token, typename defined_macros_type::iterator it, IteratorT &first, IteratorT const &last, - bool expand_undefined, defined_macros_t *scope, + bool expand_undefined, defined_macros_type *scope, ContainerT *queue_symbol, bool *seen_qualified_name) { using namespace boost::wave; @@ -1366,7 +1374,7 @@ macromap::expand_macro(ContainerT &expanded, } // ensure the parameters to be replaced with special parameter tokens -macro_definition_t ¯o_def = *(*it).second.get(); +macro_definition_type ¯o_def = *(*it).second.get(); macro_def.replace_parameters(); @@ -1579,7 +1587,7 @@ boost::spirit::parse_info hit = is_defined(result.begin(), result.end()) ? "1" : "0", main_pos)); -on_exit::pop_front pop_front_token(pending); +on_exit::pop_front pop_front_token(pending); return act_token = pending.front(); } @@ -1661,13 +1669,13 @@ macromap::resolve_operator_pragma(IteratorT &first, string_type token_str = (*it_exp).get_value(); pragma_cmd += token_str.substr(1, token_str.size() - 2); } - pragma_cmd = impl::unescape_lit(pragma_cmd); + string_type pragma_cmd_unesc = impl::unescape_lit(pragma_cmd); // tokenize the pragma body typedef typename ContextT::lexer_type lexer_type; ContainerT pragma; - std::string pragma_cmd_str(pragma_cmd.c_str()); + std::string pragma_cmd_str(pragma_cmd_unesc.c_str()); lexer_type it = lexer_type(pragma_cmd_str.begin(), pragma_cmd_str.end(), pragma_token.get_position(), ctx.get_language()); lexer_type end = lexer_type(); @@ -1677,7 +1685,7 @@ macromap::resolve_operator_pragma(IteratorT &first, // analyze the preprocessed tokensequence and eventually dispatch to the // associated action if (interpret_pragma(ctx, pragma_token, pragma.begin(), pragma.end(), - pending, ctx.get_language())) + pending)) { return true; // successfully recognized a wave specific pragma } @@ -1708,6 +1716,11 @@ macromap::is_invalid_concat(string_type new_value, lexer_type end = lexer_type(); for (/**/; it != end; ++it) rescanned.push_back(*it); + +#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 + if (boost::wave::need_variadics(ctx.get_language())) + return false; // in variadics mode token pasting is well defined +#endif // test if the newly generated token sequence contains more than 1 token // the second one is the T_EOF token @@ -1813,6 +1826,25 @@ macromap::concat_tokensequence(ContainerT &expanded) error_string, main_pos); } +#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 + if (boost::wave::need_variadics(ctx.get_language())) { + // remove the prev, '##' and the next tokens from the sequence + expanded.erase(prev, ++next); // remove not needed tokens + + // replace the old token (pointed to by *prev) with the retokenized + // sequence + typename ContainerT::reverse_iterator rit = rescanned.rbegin(); + + BOOST_ASSERT(rit != rescanned.rend()); + rescanned.erase((++rit).base()); + expanded.splice(next, rescanned); + + // the last token of the inserted sequence is the new previous + prev = next; + --prev; + } + else +#endif // BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 { // we leave the token_id unchanged, but unmark the token as // disabled, if appropriate @@ -2076,10 +2108,10 @@ namespace predefined_macros { template inline void -macromap::predefine_macro(defined_macros_t *scope, +macromap::predefine_macro(defined_macros_type *scope, string_type const &name, token_type const &t) { -definition_container_t macrodefinition; +definition_container_type macrodefinition; std::vector param; macrodefinition.push_back(t); @@ -2089,13 +2121,13 @@ std::vector param; template inline void -macromap::init_predefined_macros(defined_macros_t *scope, +macromap::init_predefined_macros(defined_macros_type *scope, bool at_global_scope) { using namespace predefined_macros; // if no scope is given, use the current one -defined_macros_t *current_scope = scope ? scope : current_macros; +defined_macros_type *current_scope = scope ? scope : current_macros; // first, add the static macros position_type pos; diff --git a/include/boost/wave/util/interpret_pragma.hpp b/include/boost/wave/util/interpret_pragma.hpp index cc9cab3..64d3288 100644 --- a/include/boost/wave/util/interpret_pragma.hpp +++ b/include/boost/wave/util/interpret_pragma.hpp @@ -11,8 +11,6 @@ #if !defined(INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED) #define INTERPRET_PRAGMA_HPP_B1F2315E_C5CE_4ED1_A343_0EF548B7942A_INCLUDED -#include -#include #include #include @@ -31,7 +29,6 @@ #include #include #include -#include #if !defined(spirit_append_actor) #if SPIRIT_VERSION >= 0x1700 @@ -48,114 +45,6 @@ namespace boost { namespace wave { namespace util { -/////////////////////////////////////////////////////////////////////////////// -namespace impl { - -/////////////////////////////////////////////////////////////////////////////// -// -// Interpret the different Wave specific pragma directives/operators -// -/////////////////////////////////////////////////////////////////////////////// -template -inline bool -interpret_pragma_trace(ContextT &ctx, ContainerT const &values, - typename ContextT::token_type const &act_token) -{ - typedef typename ContextT::token_type token_type; - typedef typename token_type::string_type string_type; - -bool valid_option = false; - - if (1 == values.size()) { - token_type const &value = values.front(); - - using namespace boost::wave::trace_policies; - if (value.get_value() == "enable" || - value.get_value() == "on" || - value.get_value() == "1") - { - ctx.enable_tracing(static_cast( - ctx.tracing_enabled() | trace_macros)); - valid_option = true; - } - else if (value.get_value() == "disable" || - value.get_value() == "off" || - value.get_value() == "0") - { - ctx.enable_tracing(static_cast( - ctx.tracing_enabled() & ~trace_macros)); - valid_option = true; - } - } - if (!valid_option) { - // unknown option value - string_type option_str ("trace"); - - if (values.size() > 0) { - option_str += "("; - option_str += impl::as_string(values); - option_str += ")"; - } - BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option, - option_str, act_token.get_position()); - } - return true; -} - -template -inline bool -interpret_pragma_system(ContextT &/*ctx*/, ContainerT &pending, - ContainerT const &values, typename ContextT::token_type const &act_token, - boost::wave::language_support language) -{ - typedef typename ContextT::token_type token_type; - typedef typename token_type::string_type string_type; - - if (0 == values.size()) { - BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option, - "system", act_token.get_position()); - } - -string_type stdout_file(std::tmpnam(0)); -string_type stderr_file(std::tmpnam(0)); -string_type system_str(impl::as_string(values)); -string_type native_cmd(system_str); - - system_str += " >" + stdout_file + " 2>" + stderr_file; - if (0 != std::system(system_str.c_str())) { - // unable to spawn the command - string_type error_str("unable to spawn command: "); - - error_str += native_cmd; - BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option, - error_str, act_token.get_position()); - } - -// rescan the content of the stdout_file and insert it as the -// _Pragma replacement - typedef typename ContextT::lexer_type lexer_type; - typedef typename ContextT::input_policy_type input_policy_type; - typedef boost::wave::iteration_context iteration_context_t; - -iteration_context_t iter_ctx(stdout_file.c_str(), act_token.get_position(), - language); -ContainerT pragma; - - for (/**/; iter_ctx.first != iter_ctx.last; ++iter_ctx.first) - pragma.push_back(*iter_ctx.first); - -// prepend the newly generated token sequence to the 'pending' container - pending.splice(pending.begin(), pragma); - -// erase the created tempfiles - std::remove(stdout_file.c_str()); - std::remove(stderr_file.c_str()); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -} // namespace impl - /////////////////////////////////////////////////////////////////////////////// // // The function interpret_pragma interprets the given token sequence as the @@ -166,8 +55,7 @@ ContainerT pragma; template inline bool interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token, - IteratorT it, IteratorT const &end, ContainerT &pending, - boost::wave::language_support language) + IteratorT it, IteratorT const &end, ContainerT &pending) { typedef typename ContextT::token_type token_type; typedef typename token_type::string_type string_type; @@ -177,13 +65,8 @@ interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token, // this is a wave specific option, it should have the form: // #pragma wave option(value) // where '(value)' is required only for some pragma directives - // - // supported #pragma directives so far: - // wave trace(enable) or wave trace(1) - // wave trace(disable) or wave trace(0) - // wave stop(error message) - // wave system(command) - + // all of the given #pragma operators are forwarded to the supplied + // context_policy using namespace boost::spirit; token_type option; ContainerT values; @@ -218,24 +101,8 @@ interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token, } } - // decode the option - if (option.get_value() == "trace") { - // enable/disable tracing option - return impl::interpret_pragma_trace(ctx, values, act_token); - } - else if (option.get_value() == "stop") { - // stop the execution and output the argument - BOOST_WAVE_THROW(preprocess_exception, error_directive, - impl::as_string(values), act_token.get_position()); - } - else if (option.get_value() == "system") { - // try to spawn the given argument as a system command and return the - // std::cout of this process as the replacement of this _Pragma - return impl::interpret_pragma_system(ctx, pending, values, - act_token, language); - } - else if (!ctx.interpret_pragma( - pending, option, values, act_token, language)) + // decode the option (call the context_policy hook) + if (!ctx.interpret_pragma(pending, option, values, act_token)) { // unknown #pragma option string_type option_str (option.get_value()); diff --git a/include/boost/wave/util/macro_helpers.hpp b/include/boost/wave/util/macro_helpers.hpp index bee05c6..43e488f 100644 --- a/include/boost/wave/util/macro_helpers.hpp +++ b/include/boost/wave/util/macro_helpers.hpp @@ -27,12 +27,20 @@ namespace impl { inline StringT escape_lit(StringT const &value) { - StringT result(value); + StringT result; typename StringT::size_type pos = 0; - while ((pos = result.find_first_of ("\"\\?", pos)) != StringT::npos) - { - result.insert (pos, 1, '\\'); - pos += 2; + typename StringT::size_type pos1 = value.find_first_of ("\"\\?", 0); + if (StringT::npos != pos1) { + do { + result += value.substr(pos, pos1-pos) + + StringT("\\") + + StringT(1, value[pos1]); + pos1 = value.find_first_of ("\"\\?", pos = pos1+1); + } while (StringT::npos != pos1); + result += value.substr(pos); + } + else { + result = value; } return result; } @@ -42,15 +50,23 @@ namespace impl { inline StringT unescape_lit(StringT const &value) { - StringT result(value); + StringT result; typename StringT::size_type pos = 0; - while ((pos = result.find_first_of ("\\", pos)) != StringT::npos) - { - if ('\\' == result[pos+1] || '\"' == result[pos+1] || - '?' == result[pos+1]) - { - result.erase(pos, 1); - } + typename StringT::size_type pos1 = value.find_first_of ("\\", 0); + if (StringT::npos != pos1) { + do { + if ('\\' == value[pos1+1] || '\"' == value[pos1+1] || + '?' == value[pos1+1]) + { + result += value.substr(pos, pos1-pos); + } + pos1 = value.find_first_of ("\\", pos = pos1+1); + } while (pos1 != StringT::npos); + result += value.substr(pos); + } + else { + // the string doesn't contain any escaped character sequences + result = value; } return result; } diff --git a/include/boost/wave/util/symbol_table.hpp b/include/boost/wave/util/symbol_table.hpp index cb0a3fb..af0880a 100644 --- a/include/boost/wave/util/symbol_table.hpp +++ b/include/boost/wave/util/symbol_table.hpp @@ -12,10 +12,6 @@ #define SYMBOL_TABLE_HPP_32B0F7C6_3DD6_4113_95A5_E16516C6F45A_INCLUDED #include -#include - -#include -#include /////////////////////////////////////////////////////////////////////////////// namespace boost { diff --git a/include/boost/wave/wave_config.hpp b/include/boost/wave/wave_config.hpp index 17a6c21..acd541b 100644 --- a/include/boost/wave/wave_config.hpp +++ b/include/boost/wave/wave_config.hpp @@ -149,13 +149,17 @@ // This include is needed for the boost::fast_allocator class used in the // BOOST_WAVE_STRINGTYPE above. // Configure Boost.Pool thread support (for now: no thread support at all) -#define BOOST_NO_MT -#include +//#define BOOST_NO_MT +//#include +// Use the following, if you want to incorporate Maxim Yegorushkin's +// const_string library (http://sourceforge.net/projects/conststring/), which +// may be even faster, than using the flex_string class from above //#define BOOST_WAVE_STRINGTYPE boost::const_string // //#include //#include +//#include #endif diff --git a/include/boost/wave/wave_version.hpp b/include/boost/wave/wave_version.hpp index dcb6139..006f128 100644 --- a/include/boost/wave/wave_version.hpp +++ b/include/boost/wave/wave_version.hpp @@ -16,11 +16,11 @@ // BOOST_WAVE_VERSION & 0x0000FF is the sub-minor version // BOOST_WAVE_VERSION & 0x00FF00 is the minor version // BOOST_WAVE_VERSION & 0xFF0000 is the major version -#define BOOST_WAVE_VERSION 0x010107 +#define BOOST_WAVE_VERSION 0x010109 // The following defines contain the same information as above #define BOOST_WAVE_VERSION_MAJOR 1 #define BOOST_WAVE_VERSION_MINOR 1 -#define BOOST_WAVE_VERSION_SUBMINOR 7 +#define BOOST_WAVE_VERSION_SUBMINOR 9 #endif // !defined(WAVE_VERSION_H_9D79ABDB_AC54_4C0A_89B1_F70A2DCFE21E_INCLUDED) diff --git a/index.html b/index.html index d4d6fb5..44f9f17 100644 --- a/index.html +++ b/index.html @@ -41,7 +41,7 @@ Policy - @@ -100,8 +100,8 @@ 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)

-Saturday, August 21, 2004 19:47 \ No newline at end of file +Sunday, September 12, 2004 10:36 \ No newline at end of file diff --git a/samples/cpp_tokens/cpp_tokens.cpp b/samples/cpp_tokens/cpp_tokens.cpp index d281a8f..b107f19 100644 --- a/samples/cpp_tokens/cpp_tokens.cpp +++ b/samples/cpp_tokens/cpp_tokens.cpp @@ -75,8 +75,8 @@ main(int argc, char *argv[]) // to dump the token information carried by a given token (see loop below). typedef boost::wave::cpp_token_sample::slex_token<> token_type; typedef boost::wave::cpp_token_sample::slex_iterator - lex_iterator_t; - typedef boost::wave::context + lex_iterator_type; + typedef boost::wave::context context_type; // The C++ preprocessor iterator shouldn't be constructed directly. It is to be diff --git a/samples/cpp_tokens/cpp_tokens_config.hpp b/samples/cpp_tokens/cpp_tokens_config.hpp index 29b65bf..4339781 100644 --- a/samples/cpp_tokens/cpp_tokens_config.hpp +++ b/samples/cpp_tokens/cpp_tokens_config.hpp @@ -15,97 +15,8 @@ #define CPP_TOKENS_HPP_7C0F1F14_6ACA_4439_A073_32C61C0DB6C5_INCLUDED /////////////////////////////////////////////////////////////////////////////// -// Define the maximal include nesting depth allowed. If this value isn't -// defined it defaults to 1024 -// -// To define a new initial include nesting depth uncomment the following and -// supply a new integer value. -// -//#define BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to support variadics and placemarkers -// -// To implement support variadics and placemarkers uncomment the following -// -#define BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement a #warning directive as -// -// To implement #warning directives, uncomment the following -// -#define BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement #pragma once -// -// To implement #pragma once, uncomment the following -// -#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement #include_next -// Please note, that this is an extension to the C++ Standard. -// -// To implement #include_next, uncomment the following -// -#define BOOST_WAVE_SUPPORT_INCLUDE_NEXT 0 - -/////////////////////////////////////////////////////////////////////////////// -// Undefine the following, to enable some MS specific language extensions: -// __int8, __int16, __int32, __int64, __based, __declspec, __cdecl, -// __fastcall, __stdcall, __try, __except, __finally, __leave, __inline, -// __asm -#define BOOST_WAVE_SUPPORT_MS_EXTENSIONS 0 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the message body of the #error and #warning directives to be -// preprocessed before the diagnostic is issued. -// -// Uncommenting the following will preprocess the message bodies of #error and -// #warning messages before the error (warning) is issued -// -#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 0 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the #pragma directives to be returned to the caller (optionally after -// preprocessing the body) -// -// Undefining the following will skip #pragma directives, so that the caller -// will not see them. -// -#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 0 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the body of a #pragma directive to be preprocessed before the -// directive is returned to the caller. -// -// Uncommenting the following will preprocess the bodies of #pragma directives -// -#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 0 - -/////////////////////////////////////////////////////////////////////////////// -// Allow to define macros with the command line syntax (-DMACRO(x)=definition) -// -// Uncommenting the following will enable the possibility to define macros -// based on the command line syntax -// -#define BOOST_WAVE_ENABLE_COMMANDLINE_MACROS 0 - -/////////////////////////////////////////////////////////////////////////////// -// Define the string type to be used to store the token values and the file -// names inside a file_position template class -// - -// use the following, if you have a fast std::allocator -#define BOOST_WAVE_STRINGTYPE wave::util::flex_string< \ - char, std::char_traits, std::allocator, \ - wave::util::CowString > \ - > \ - /**/ -#include +// Include the configuration stuff for the Wave library itself +#include /////////////////////////////////////////////////////////////////////////////// // Uncomment the following, if you need debug output, the @@ -113,17 +24,7 @@ // the generated debug output //#define BOOST_SPIRIT_DEBUG -/////////////////////////////////////////////////////////////////////////////// -// debug rules, subrules and grammars only, for possible flags see -// spirit/debug.hpp #if defined(BOOST_SPIRIT_DEBUG) - -#define BOOST_SPIRIT_DEBUG_FLAGS ( \ - BOOST_SPIRIT_DEBUG_FLAGS_NODES | \ - BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES \ - ) \ - /**/ - /////////////////////////////////////////////////////////////////////////////// // debug flags for the pp-iterator library, possible flags (defined in // wave_config.hpp): @@ -142,53 +43,6 @@ /**/ #endif -/////////////////////////////////////////////////////////////////////////////// -// -// For all recognized preprocessor statements the output parse trees -// formatted as xml are printed. The formatted parse trees are streamed to the -// std::ostream defined by the WAVE_DUMP_PARSE_TREE_OUT constant. -// -// Uncomment the following, if you want to see these parse trees. -// -//#define BOOST_WAVE_DUMP_PARSE_TREE 1 -//#define BOOST_WAVE_DUMP_PARSE_TREE_OUT std::cerr - -/////////////////////////////////////////////////////////////////////////////// -// -// For all #if and #elif directives the preprocessed expressions are printed. -// These expressions are streamed to the std::ostream defined by the -// WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT constant. -// -// Uncomment the following, if you want to see the preprocessed expressions -// -//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS 1 -//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to use the separate compilation model for the instantiation -// of the C++ lexer objects. -// -// If this is defined, you should explicitly instantiate the C++ lexer -// template with the correct parameters in a separate compilation unit of -// your program (see the files instantiate_slex_lexer.cpp and -// instantiate_re2c_lexer.cpp). -// -// To use the lexer inclusion model, uncomment the following -// -#define BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION 1 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to use the separate compilation model for the instantiation -// of the grammar objects. -// -// If this is defined, you should explicitly instantiate the grammar -// templates with the correct parameters in a separate compilation unit of -// your program (see the files instantiate_cpp_grammar.cpp). -// -// To use the grammar inclusion model, uncomment the following -// -#define BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1 - /////////////////////////////////////////////////////////////////////////////// // MSVC specific #pragma's #if defined(BOOST_MSVC) @@ -198,8 +52,4 @@ #pragma inline_recursion(on) #endif // defined(BOOST_MSVC) -/////////////////////////////////////////////////////////////////////////////// -// Now include the cofiguration stuff for the Wave library itself -#include - #endif // !defined(CPP_TOKENS_HPP_7C0F1F14_6ACA_4439_A073_32C61C0DB6C5_INCLUDED) diff --git a/samples/list_includes/list_includes.cpp b/samples/list_includes/list_includes.cpp index da97af4..8b8fc0c 100644 --- a/samples/list_includes/list_includes.cpp +++ b/samples/list_includes/list_includes.cpp @@ -40,7 +40,7 @@ /////////////////////////////////////////////////////////////////////////////// // Include the default context trace policies -#include +#include /////////////////////////////////////////////////////////////////////////////// // include lexer specifics, import lexer names @@ -108,7 +108,7 @@ long seconds = long(std::difftime(compilation_time.get_time(), /////////////////////////////////////////////////////////////////////////////// // policy class struct trace_include_files -: public boost::wave::trace_policies::default_tracing +: public boost::wave::context_policies::default_preprocessing_hooks { trace_include_files(set &files_) : files(files_) {} @@ -159,9 +159,9 @@ boost::wave::util::file_position_type current_position; // used by the Wave library. typedef boost::wave::cpplexer::lex_iterator< boost::wave::cpplexer::lex_token<> > - lex_iterator_t; + lex_iterator_type; typedef boost::wave::context< - std::string::iterator, lex_iterator_t, + std::string::iterator, lex_iterator_type, boost::wave::iteration_context_policies::load_file_to_string, trace_include_files > context_type; diff --git a/samples/list_includes/list_includes_config.hpp b/samples/list_includes/list_includes_config.hpp index ac1df0e..9d05cf0 100644 --- a/samples/list_includes/list_includes_config.hpp +++ b/samples/list_includes/list_includes_config.hpp @@ -13,99 +13,6 @@ #if !defined(LIST_INCLUDES_CONFIG_HPP_0DE80E47_8D50_4DFA_9C1C_0EECAA8A934A_INCLUDED) #define LIST_INCLUDES_CONFIG_HPP_0DE80E47_8D50_4DFA_9C1C_0EECAA8A934A_INCLUDED -/////////////////////////////////////////////////////////////////////////////// -// Define the maximal include nesting depth allowed. If this value isn't -// defined it defaults to 1024 -// -// To define a new initial include nesting depth uncomment the following and -// supply a new integer value. -// -//#define BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to support variadics and placemarkers -// -// To implement support variadics and placemarkers uncomment the following -// -#define BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement a #warning directive as -// -// To implement #warning directives, uncomment the following -// -#define BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement #pragma once -// -// To implement #pragma once, uncomment the following -// -#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement #include_next -// Please note, that this is an extension to the C++ Standard. -// -// To implement #include_next, uncomment the following -// -#define BOOST_WAVE_SUPPORT_INCLUDE_NEXT 1 - -/////////////////////////////////////////////////////////////////////////////// -// Undefine the following, to enable some MS specific language extensions: -// __int8, __int16, __int32, __int64, __based, __declspec, __cdecl, -// __fastcall, __stdcall, __try, __except, __finally, __leave, __inline, -// __asm -#define BOOST_WAVE_SUPPORT_MS_EXTENSIONS 0 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the message body of the #error and #warning directives to be -// preprocessed before the diagnostic is issued. -// -// Uncommenting the following will preprocess the message bodies of #error and -// #warning messages before the error (warning) is issued -// -#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the #pragma directives to be returned to the caller (optionally after -// preprocessing the body) -// -// Undefining the following will skip #pragma directives, so that the caller -// will not see them. -// -#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 0 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the body of a #pragma directive to be preprocessed before the -// directive is returned to the caller. -// -// Uncommenting the following will preprocess the bodies of #pragma directives -// -#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 0 - -/////////////////////////////////////////////////////////////////////////////// -// Allow to define macros with the command line syntax (-DMACRO(x)=definition) -// -// Uncommenting the following will enable the possibility to define macros -// based on the command line syntax -// -#define BOOST_WAVE_ENABLE_COMMANDLINE_MACROS 0 - -/////////////////////////////////////////////////////////////////////////////// -// Define the string type to be used to store the token values and the file -// names inside a file_position template class -// - -// use the following, if you have a fast std::allocator -#define BOOST_WAVE_STRINGTYPE wave::util::flex_string< \ - char, std::char_traits, std::allocator, \ - wave::util::CowString > \ - > \ - /**/ -#include - /////////////////////////////////////////////////////////////////////////////// // Uncomment the following, if you need debug output, the // BOOST_SPIRIT_DEBUG_FLAGS constants below help to fine control the amount of @@ -142,51 +49,8 @@ #endif /////////////////////////////////////////////////////////////////////////////// -// -// For all recognized preprocessor statements the output parse trees -// formatted as xml are printed. The formatted parse trees are streamed to the -// std::ostream defined by the WAVE_DUMP_PARSE_TREE_OUT constant. -// -// Uncomment the following, if you want to see these parse trees. -// -//#define BOOST_WAVE_DUMP_PARSE_TREE 1 -//#define BOOST_WAVE_DUMP_PARSE_TREE_OUT std::cerr - -/////////////////////////////////////////////////////////////////////////////// -// -// For all #if and #elif directives the preprocessed expressions are printed. -// These expressions are streamed to the std::ostream defined by the -// WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT constant. -// -// Uncomment the following, if you want to see the preprocessed expressions -// -//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS 1 -//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to use the separate compilation model for the instantiation -// of the C++ lexer objects. -// -// If this is defined, you should explicitly instantiate the C++ lexer -// template with the correct parameters in a separate compilation unit of -// your program (see the files instantiate_slex_lexer.cpp and -// instantiate_re2c_lexer.cpp). -// -// To use the lexer inclusion model, uncomment the following -// -#define BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION 1 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to use the separate compilation model for the instantiation -// of the grammar objects. -// -// If this is defined, you should explicitly instantiate the grammar -// templates with the correct parameters in a separate compilation unit of -// your program (see the files instantiate_cpp_grammar.cpp). -// -// To use the grammar inclusion model, uncomment the following -// -#define BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1 +// Now include the cofiguration stuff for the Wave library itself +#include /////////////////////////////////////////////////////////////////////////////// // MSVC specific #pragma's @@ -197,8 +61,4 @@ #pragma inline_recursion(on) #endif // defined(BOOST_MSVC) -/////////////////////////////////////////////////////////////////////////////// -// Now include the cofiguration stuff for the Wave library itself -#include - #endif // !defined(LIST_INCLUDES_CONFIG_HPP_0DE80E47_8D50_4DFA_9C1C_0EECAA8A934A_INCLUDED) diff --git a/samples/quick_start/quick_start.cpp b/samples/quick_start/quick_start.cpp index 8311383..f5cafae 100644 --- a/samples/quick_start/quick_start.cpp +++ b/samples/quick_start/quick_start.cpp @@ -53,12 +53,12 @@ boost::wave::util::file_position_type current_position; // The template boost::wave::cpplexer::lex_iterator<> is the lexer type to // be used by the Wave library. - typedef boost::wave::cpplexer::lex_iterator lex_iterator_t; + typedef boost::wave::cpplexer::lex_iterator 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 + typedef boost::wave::context context_type; // The preprocessor iterator shouldn't be constructed directly. It is diff --git a/samples/waveidl/idl.cpp b/samples/waveidl/idl.cpp index 1332172..1f09a44 100644 --- a/samples/waveidl/idl.cpp +++ b/samples/waveidl/idl.cpp @@ -74,8 +74,8 @@ int print_version() { typedef boost::wave::idllexer::lex_iterator< boost::wave::cpplexer::lex_token<> > - lex_iterator_t; - typedef boost::wave::context + lex_iterator_type; + typedef boost::wave::context context_type; string version (context_type::get_version_string()); @@ -254,8 +254,8 @@ boost::wave::util::file_position_type current_position; // the Wave library, but it is possible to use your own types. typedef boost::wave::idllexer::lex_iterator< boost::wave::cpplexer::lex_token<> > - lex_iterator_t; - typedef boost::wave::context + lex_iterator_type; + typedef boost::wave::context context_type; // The C++ preprocessor iterators shouldn't be constructed directly. They diff --git a/samples/waveidl/idl_config.hpp b/samples/waveidl/idl_config.hpp index 569ccba..560c376 100644 --- a/samples/waveidl/idl_config.hpp +++ b/samples/waveidl/idl_config.hpp @@ -14,94 +14,6 @@ #if !defined(IDL_CONFIG_HPP_012D7524_FF3F_482F_9123_91966C72F4EA_INCLUDED) #define IDL_CONFIG_HPP_012D7524_FF3F_482F_9123_91966C72F4EA_INCLUDED -/////////////////////////////////////////////////////////////////////////////// -// Define the maximal include nesting depth allowed. If this value isn't -// defined it defaults to 1024 -// -// To define a new initial include nesting depth uncomment the following and -// supply a new integer value. -// -//#define BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to support variadics and placemarkers -// -// To implement support variadics and placemarkers uncomment the following -// -#define BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement a #warning directive as -// -// To implement #warning directives, uncomment the following -// -#define BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement #pragma once -// -// To implement #pragma once, uncomment the following -// -#define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 0 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to implement #include_next -// Please note, that this is an extension to the C++ Standard. -// -// To implement #include_next, uncomment the following -// -#define BOOST_WAVE_SUPPORT_INCLUDE_NEXT 0 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the message body of the #error and #warning directives to be -// preprocessed before the diagnostic is issued. -// -// Uncommenting the following will preprocess the message bodies of #error and -// #warning messages before the error (warning) is issued -// -#define BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the #pragma directives to be returned to the caller (optionally after -// preprocessing the body) -// -// Undefining the following will skip #pragma directives, so that the caller -// will not see them. -// -#define BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES 1 - -/////////////////////////////////////////////////////////////////////////////// -// Allow the body of a #pragma directive to be preprocessed before the -// directive is returned to the caller. -// -// Uncommenting the following will preprocess the bodies of #pragma directives -// -#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 1 - -/////////////////////////////////////////////////////////////////////////////// -// Allow to define macros with the command line syntax (-DMACRO(x)=definition) -// -// Uncommenting the following will enable the possibility to define macros -// based on the command line syntax -// -#define BOOST_WAVE_ENABLE_COMMANDLINE_MACROS 1 - -/////////////////////////////////////////////////////////////////////////////// -// Define the string type to be used to store the token values and the file -// names inside a file_position template class -// -#define BOOST_WAVE_STRINGTYPE boost::wave::util::flex_string< \ - char, std::char_traits, std::allocator, \ - boost::wave::util::CowString< \ - boost::wave::util::AllocatorStringStorage \ - > \ - > \ - /**/ - -// This include is needed for the flex_string class used in the -// BOOST_WAVE_STRINGTYPE above. -#include - /////////////////////////////////////////////////////////////////////////////// // Uncomment the following, if you need debug output, the // BOOST_SPIRIT_DEBUG_FLAGS constants below help to fine control the amount of @@ -138,55 +50,8 @@ #endif /////////////////////////////////////////////////////////////////////////////// -// -// For all recognized preprocessor statements the output parse trees -// formatted as xml are printed. The formatted parse trees are streamed to the -// std::ostream defined by the BOOST_WAVE_DUMP_PARSE_TREE_OUT constant. -// -// Uncomment the following, if you want to see these parse trees. -// -//#define BOOST_WAVE_DUMP_PARSE_TREE 1 -//#define BOOST_WAVE_DUMP_PARSE_TREE_OUT std::cerr - -/////////////////////////////////////////////////////////////////////////////// -// -// For all #if and #elif directives the preprocessed expressions are printed. -// These expressions are streamed to the std::ostream defined by the -// BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT constant. -// -// Uncomment the following, if you want to see the preprocessed expressions -// -//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS 1 -//#define BOOST_WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to use the separate compilation model for the instantiation -// of the C++ lexer objects. -// -// If this is defined, you should explicitly instantiate the C++ lexer -// template with the correct parameters in a separate compilation unit of -// your program (see the files instantiate_slex_lexer.cpp and -// instantiate_re2c_lexer.cpp). -// -// To use the lexer inclusion model, uncomment the following -// -#define BOOST_WAVE_SEPARATE_LEXER_INSTANTIATION 1 - -/////////////////////////////////////////////////////////////////////////////// -// Decide, whether to use the separate compilation model for the instantiation -// of the grammar objects. -// -// If this is defined, you should explicitly instantiate the grammar -// templates with the correct parameters in a separate compilation unit of -// your program (see the files instantiate_cpp_grammar.cpp). -// -// To use the grammar inclusion model, uncomment the following -// -#define BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1 - -/////////////////////////////////////////////////////////////////////////////// -// configure Boost.Pool thread support (for now: no thread support at all) -#define BOOST_NO_MT +// Now include the cofiguration stuff for the Wave library itself +#include /////////////////////////////////////////////////////////////////////////////// // MSVC specific #pragma's @@ -197,8 +62,4 @@ #pragma inline_recursion(on) #endif // defined(BOOST_MSVC) -/////////////////////////////////////////////////////////////////////////////// -// Now include the cofiguration stuff for the Wave library itself -#include - #endif // !defined(IDL_CONFIG_HPP_012D7524_FF3F_482F_9123_91966C72F4EA_INCLUDED) diff --git a/tool/cpp.cpp b/tool/cpp.cpp index 683adc3..8c013de 100644 --- a/tool/cpp.cpp +++ b/tool/cpp.cpp @@ -73,9 +73,9 @@ int print_version() { typedef boost::wave::cpplexer::lex_iterator< boost::wave::cpplexer::lex_token<> > - lex_iterator_t; + lex_iterator_type; typedef boost::wave::context< - std::string::iterator, lex_iterator_t, + std::string::iterator, lex_iterator_type, boost::wave::iteration_context_policies::load_file_to_string, trace_macro_expansion> context_type; @@ -253,22 +253,18 @@ namespace { /////////////////////////////////////////////////////////////////////////////// // do the actual preprocessing int -do_actual_work (std::string file_name, po::variables_map const &vm) +do_actual_work (std::string file_name, std::istream &instream, + po::variables_map const &vm) { // current file position is saved for exception handling boost::wave::util::file_position_type current_position; try { // process the given file - ifstream instream(file_name.c_str()); string instring; - if (!instream.is_open()) { - cerr << "wave: could not open input file: " << file_name << endl; - return -1; - } instream.unsetf(std::ios::skipws); - + #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) // this is known to be very slow for large files on some systems copy (istream_iterator(instream), @@ -283,9 +279,9 @@ boost::wave::util::file_position_type current_position; // the Wave library, but it is possible to use your own types. typedef boost::wave::cpplexer::lex_iterator< boost::wave::cpplexer::lex_token<> > - lex_iterator_t; + lex_iterator_type; typedef boost::wave::context< - std::string::iterator, lex_iterator_t, + std::string::iterator, lex_iterator_type, boost::wave::iteration_context_policies::load_file_to_string, trace_macro_expansion> context_type; @@ -297,8 +293,7 @@ boost::wave::util::file_position_type current_position; // The preprocessing of the input stream is done on the fly behind the // scenes during iteration over the context_type::iterator_type stream. std::ofstream traceout; - boost::wave::trace_policies::trace_flags enable_trace = - boost::wave::trace_policies::trace_nothing; + trace_flags enable_trace = trace_nothing; if (vm.count("traceto")) { // try to open the file, where to put the trace output @@ -312,10 +307,9 @@ boost::wave::util::file_position_type current_position; return -1; } } - enable_trace = boost::wave::trace_policies::trace_macros; + enable_trace = trace_macros; } - if ((enable_trace & boost::wave::trace_policies::trace_macros) && - !traceout.is_open()) + if ((enable_trace & trace_macros) && !traceout.is_open()) { // by default trace to std::cerr traceout.copyfmt(cerr); @@ -441,6 +435,7 @@ boost::wave::util::file_position_type current_position; } // analyze the input file + auto_stop_watch elapsed_time(vm.count("timer") > 0, cout); context_type::iterator_type first = ctx.begin(); context_type::iterator_type last = ctx.end(); @@ -461,8 +456,6 @@ boost::wave::util::file_position_type current_position; } // loop over all generated tokens outputing the generated text - auto_stop_watch elapsed_time(vm.count("timer") > 0, cout); - while (first != last) { // print out the string representation of this token (skip comments) using namespace boost::wave; @@ -611,7 +604,7 @@ main (int argc, char *argv[]) // ... act as required if (vm.count("help")) { po::options_description desc_help ( - "Usage: wave [options] [@config-file(s)] file"); + "Usage: wave [options] [@config-file(s)] [file]"); desc_help.add(desc_cmdline).add(desc_generic).add(desc_ext); cout << desc_help << endl; @@ -634,13 +627,23 @@ main (int argc, char *argv[]) // if there is no input file given, then exit if (0 == arguments.size() || 0 == arguments[0].value.size()) { - cerr << "wave: no input file given, " - << "use --help to get a hint." << endl; - return 5; +// cerr << "wave: no input file given, " +// << "use --help to get a hint." << endl; +// return 5; + // preprocess the given input file + return do_actual_work("stdin", std::cin, vm); } + else { + std::string file_name(arguments[0].value[0]); + ifstream instream(file_name.c_str()); - // preprocess the given input file - return do_actual_work(arguments[0].value[0], vm); + // preprocess the given input file + if (!instream.is_open()) { + cerr << "wave: could not open input file: " << file_name << endl; + return -1; + } + return do_actual_work(file_name, instream, vm); + } } catch (std::exception &e) { cout << "wave: exception caught: " << e.what() << endl; diff --git a/tool/cpp_config.hpp b/tool/cpp_config.hpp index 8b7542c..e4c94b5 100644 --- a/tool/cpp_config.hpp +++ b/tool/cpp_config.hpp @@ -12,10 +12,6 @@ #if !defined(CPP_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED) #define CPP_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED -/////////////////////////////////////////////////////////////////////////////// -// Include the configuration stuff for the Wave library itself -#include - /////////////////////////////////////////////////////////////////////////////// // Uncomment the following, if you need debug output, the // BOOST_SPIRIT_DEBUG_FLAGS constants below helps to fine control the amount of @@ -51,6 +47,10 @@ /**/ #endif +/////////////////////////////////////////////////////////////////////////////// +// Include the configuration stuff for the Wave library itself +#include + /////////////////////////////////////////////////////////////////////////////// // MSVC specific #pragma's #if defined(BOOST_MSVC) diff --git a/tool/cpp_version.hpp b/tool/cpp_version.hpp index 9e4777f..7f6e873 100644 --- a/tool/cpp_version.hpp +++ b/tool/cpp_version.hpp @@ -15,6 +15,6 @@ #define CPP_VERSION_MAJOR BOOST_WAVE_VERSION_MAJOR #define CPP_VERSION_MINOR BOOST_WAVE_VERSION_MINOR #define CPP_VERSION_SUBMINOR BOOST_WAVE_VERSION_SUBMINOR -#define CPP_VERSION_DATE 20040825L +#define CPP_VERSION_DATE 20040911L #endif // !defined(CPP_VERSION_HPP_CE4FE67F_63F9_468D_8364_C855F89D3C5D_INCLUDED) diff --git a/tool/stop_watch.hpp b/tool/stop_watch.hpp new file mode 100644 index 0000000..774b40f --- /dev/null +++ b/tool/stop_watch.hpp @@ -0,0 +1,84 @@ +/*============================================================================= + Wave: A Standard compliant C++ preprocessor library + http://spirit.sourceforge.net/ + + Copyright (c) 2001-2004 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(STOP_WATCH_HPP_HK040911_INCLUDED) +#define STOP_WATCH_HPP_HK040911_INCLUDED + +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// +class stop_watch : public boost::timer { + + typedef boost::timer base_t; + +public: + stop_watch() : is_suspended_since(0), suspended_overall(0) {} + + void suspend() + { + if (0 == is_suspended_since) { + // if not already suspended + is_suspended_since = this->base_t::elapsed(); + } + } + void resume() + { + if (0 != is_suspended_since) { + // if really suspended + suspended_overall += this->base_t::elapsed() - is_suspended_since; + is_suspended_since = 0; + } + } + double elapsed() const + { + if (0 == is_suspended_since) { + // currently running + return this->base_t::elapsed() - suspended_overall; + } + + // currently suspended + BOOST_ASSERT(is_suspended_since >= suspended_overall); + return is_suspended_since - suspended_overall; + } + + std::string format_elapsed_time() const + { + double current = elapsed(); + char time_buffer[sizeof("1234:56:78.90 abcd.")+1]; + + using namespace std; + if (current >= 3600) { + // show hours + sprintf (time_buffer, "%d:%02d:%02d.%03d hrs.", + (int)(current) / 3600, ((int)(current) % 3600) / 60, + ((int)(current) % 3600) % 60, + (int)(current * 1000) % 1000); + } + else if (current >= 60) { + // show minutes + sprintf (time_buffer, "%d:%02d.%03d min.", + (int)(current) / 60, (int)(current) % 60, + (int)(current * 1000) % 1000); + } + else { + // show seconds + sprintf(time_buffer, "%d.%03d sec.", (int)current, + (int)(current * 1000) % 1000); + } + return time_buffer; + } + +private: + double is_suspended_since; + double suspended_overall; +}; + +#endif // !defined(STOP_WATCH_HPP_HK040911_INCLUDED) diff --git a/tool/trace_macro_expansion.hpp b/tool/trace_macro_expansion.hpp index a71628c..e5391a3 100644 --- a/tool/trace_macro_expansion.hpp +++ b/tool/trace_macro_expansion.hpp @@ -10,18 +10,20 @@ #if !defined(TRACE_MACRO_EXPANSION_HPP_D8469318_8407_4B9D_A19F_13CA60C1661F_INCLUDED) #define TRACE_MACRO_EXPANSION_HPP_D8469318_8407_4B9D_A19F_13CA60C1661F_INCLUDED +#include #include #include #include #include -#include #include #include -#include +#include #include +#include "stop_watch.hpp" + #ifdef BOOST_NO_STRINGSTREAM #include #define BOOST_WAVE_OSSTREAM std::ostrstream @@ -38,75 +40,13 @@ std::string BOOST_WAVE_GETSTRING(std::ostrstream& ss) #define BOOST_WAVE_OSSTREAM std::ostringstream #endif -/////////////////////////////////////////////////////////////////////////////// -// -class stop_watch : public boost::timer { - - typedef boost::timer base_t; - -public: - stop_watch() : is_suspended_since(0), suspended_overall(0) {} - - void suspend() - { - if (0 == is_suspended_since) { - // if not already suspended - is_suspended_since = this->base_t::elapsed(); - } - } - void resume() - { - if (0 != is_suspended_since) { - // if really suspended - suspended_overall += this->base_t::elapsed() - is_suspended_since; - is_suspended_since = 0; - } - } - double elapsed() const - { - if (0 == is_suspended_since) { - // currently running - return this->base_t::elapsed() - suspended_overall; - } - - // currently suspended - BOOST_ASSERT(is_suspended_since >= suspended_overall); - return is_suspended_since - suspended_overall; - } - - std::string format_elapsed_time() const - { - double current = elapsed(); - char time_buffer[sizeof("1234:56:78.90 abcd.")+1]; - - using namespace std; - if (current >= 3600) { - // show hours - sprintf (time_buffer, "%d:%02d:%02d.%03d hrs.", - (int)(current) / 3600, ((int)(current) % 3600) / 60, - ((int)(current) % 3600) % 60, - (int)(current * 1000) % 1000); - } - else if (current >= 60) { - // show minutes - sprintf (time_buffer, "%d:%02d.%03d min.", - (int)(current) / 60, (int)(current) % 60, - (int)(current * 1000) % 1000); - } - else { - // show seconds - sprintf(time_buffer, "%d.%03d sec.", (int)current, - (int)(current * 1000) % 1000); - } - return time_buffer; - } - -private: - double is_suspended_since; - double suspended_overall; +// trace_flags: enable single tracing functionality +enum trace_flags { + trace_nothing = 0, // disable tracing + trace_macros = 1, // enable macro tracing + trace_includes = 2 // enable include file tracing }; - /////////////////////////////////////////////////////////////////////////////// // // The trace_macro_expansion policy is used to trace the macro expansion of @@ -120,38 +60,17 @@ private: // /////////////////////////////////////////////////////////////////////////////// class trace_macro_expansion -: public boost::wave::trace_policies::default_tracing +: public boost::wave::context_policies::default_preprocessing_hooks { public: - trace_macro_expansion(std::ostream &outstrm_, - boost::wave::trace_policies::trace_flags flags_) - : outstrm(outstrm_), level(0), - flags(flags_), logging_flags(boost::wave::trace_policies::trace_nothing) + trace_macro_expansion(std::ostream &outstrm_, trace_flags flags_) + : outstrm(outstrm_), level(0), flags(flags_), logging_flags(trace_nothing) { } ~trace_macro_expansion() { } - /////////////////////////////////////////////////////////////////////////// - // - // The function enable_tracing is called, whenever the status of the - // tracing was changed. - // - // The parameter 'enable' is to be used as the new tracing status. - // - /////////////////////////////////////////////////////////////////////////// - void enable_tracing(boost::wave::trace_policies::trace_flags flags) - { logging_flags = flags; } - - /////////////////////////////////////////////////////////////////////////// - // - // The function tracing_enabled should return the current tracing status. - // - /////////////////////////////////////////////////////////////////////////// - boost::wave::trace_policies::trace_flags tracing_enabled() - { return logging_flags; } - /////////////////////////////////////////////////////////////////////////// // // The function 'expanding_function_like_macro' is called, whenever a @@ -343,6 +262,9 @@ public: // The function 'interpret_pragma' is called, whenever a #pragma wave // directive is found, which isn't known to the core Wave library. // + // 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 as the replacement text for the whole // #pragma wave() directive. @@ -355,37 +277,159 @@ public: // The parameter 'act_token' contains the actual #pragma token, which may // be used for error output. // - // The parameter 'language' contains the current language mode, in which - // the Wave library operates. - // // If the return value is 'false', the whole #pragma directive is // interpreted as unknown and a corresponding error message is issued. A // return value of 'true' signs a successful interpretation of the given // #pragma. // /////////////////////////////////////////////////////////////////////////// - template + template bool - interpret_pragma(ContainerT &pending, TokenT const &option, - ContainerT const &values, TokenT const &act_token, - boost::wave::language_support language) + interpret_pragma(ContextT const &ctx, ContainerT &pending, + typename ContextT::token_type const &option, ContainerT const &values, + typename ContextT::token_type const &act_token) { + typedef typename ContextT::token_type token_type; + if (option.get_value() == "timer") { // #pragma wave timer(value) if (0 == values.size()) { // no value means '1' using namespace boost::wave; - timer(TokenT(T_INTLIT, "1", act_token.get_position())); + timer(token_type(T_INTLIT, "1", act_token.get_position())); } else { timer(values.front()); } return true; } + else if (option.get_value() == "trace") { + // enable/disable tracing option + return interpret_pragma_trace(ctx, values, act_token); + } + else if (option.get_value() == "system") { + // try to spawn the given argument as a system command and return the + // std::cout of this process as the replacement of this _Pragma + return interpret_pragma_system(ctx, pending, values, act_token); + } + if (option.get_value() == "stop") { + // stop the execution and output the argument + BOOST_WAVE_THROW(preprocess_exception, error_directive, + boost::wave::util::impl::as_string(values), + act_token.get_position()); + } return false; } protected: + // Interpret the different Wave specific pragma directives/operators + template + bool + interpret_pragma_trace(ContextT const &/*ctx*/, ContainerT const &values, + typename ContextT::token_type const &act_token) + { + typedef typename ContextT::token_type token_type; + typedef typename token_type::string_type string_type; + + bool valid_option = false; + + if (1 == values.size()) { + token_type const &value = values.front(); + + if (value.get_value() == "enable" || + value.get_value() == "on" || + value.get_value() == "1") + { + // #pragma wave trace(enable) + enable_tracing(static_cast( + tracing_enabled() | trace_macros)); + valid_option = true; + } + else if (value.get_value() == "disable" || + value.get_value() == "off" || + value.get_value() == "0") + { + // #pragma wave trace(disable) + enable_tracing(static_cast( + tracing_enabled() & ~trace_macros)); + valid_option = true; + } + } + if (!valid_option) { + // unknown option value + string_type option_str ("trace"); + + if (values.size() > 0) { + option_str += "("; + option_str += boost::wave::util::impl::as_string(values); + option_str += ")"; + } + BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option, + option_str, act_token.get_position()); + } + return true; + } + + template + bool + interpret_pragma_system(ContextT const &ctx, ContainerT &pending, + ContainerT const &values, + typename ContextT::token_type const &act_token) + { + typedef typename ContextT::token_type token_type; + typedef typename token_type::string_type string_type; + + if (0 == values.size()) return false; // ill_formed_pragma_option + + string_type stdout_file(std::tmpnam(0)); + string_type stderr_file(std::tmpnam(0)); + string_type system_str(boost::wave::util::impl::as_string(values)); + string_type native_cmd(system_str); + + system_str += " >" + stdout_file + " 2>" + stderr_file; + if (0 != std::system(system_str.c_str())) { + // unable to spawn the command + string_type error_str("unable to spawn command: "); + + error_str += native_cmd; + BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option, + error_str, act_token.get_position()); + } + + // rescan the content of the stdout_file and insert it as the + // _Pragma replacement + typedef typename ContextT::lexer_type lexer_type; + typedef typename ContextT::input_policy_type input_policy_type; + typedef boost::wave::iteration_context + iteration_context_type; + + iteration_context_type iter_ctx(stdout_file.c_str(), + act_token.get_position(), ctx.get_language()); + ContainerT pragma; + + for (/**/; iter_ctx.first != iter_ctx.last; ++iter_ctx.first) + pragma.push_back(*iter_ctx.first); + + // prepend the newly generated token sequence to the 'pending' container + pending.splice(pending.begin(), pragma); + + // erase the created tempfiles + std::remove(stdout_file.c_str()); + std::remove(stderr_file.c_str()); + return true; + } + + // The function enable_tracing is called, whenever the status of the + // tracing was changed. + // The parameter 'enable' is to be used as the new tracing status. + void enable_tracing(trace_flags flags) + { logging_flags = flags; } + + // The function tracing_enabled should return the current tracing status. + trace_flags tracing_enabled() + { return logging_flags; } + + // Helper functions for generating the trace output void open_trace_body(char const *label = 0) { if (label) @@ -421,12 +465,10 @@ protected: bool enabled_macro_tracing() const { - using namespace boost::wave::trace_policies; return (flags & trace_macros) && (logging_flags & trace_macros); } bool enabled_include_tracing() const { - using namespace boost::wave::trace_policies; return (flags & trace_includes) && (logging_flags & trace_includes); } @@ -457,8 +499,8 @@ protected: private: std::ostream &outstrm; // output stream int level; // indentation level - boost::wave::trace_policies::trace_flags flags; // enabled globally - boost::wave::trace_policies::trace_flags logging_flags; // enabled by a #pragma + trace_flags flags; // enabled globally + trace_flags logging_flags; // enabled by a #pragma stop_watch elapsed_time; // trace timings };
The Tracing + The Context Policy