From ebe684d48210a936d212ed63548db83c6d2ca7e9 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Tue, 2 May 2006 23:07:57 +0000 Subject: [PATCH] Fixed the Wave tool to return the number of errors occured. [SVN r33910] --- ChangeLog | 5 ++- doc/compiletime_config.html | 46 ++++++++++---------- doc/supported_pragmas.html | 26 ++++++----- include/boost/wave/cpp_exceptions.hpp | 16 +++++-- include/boost/wave/util/interpret_pragma.hpp | 45 +++++++++++++++---- include/boost/wave/wave_config.hpp | 10 +++++ tool/cpp.cpp | 11 +++-- 7 files changed, 110 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92c4883..71f36e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -115,7 +115,10 @@ Boost V1.34.0 - Added the name of the generating compiler (BOOST_COMPILER) to the full Wave version info. - Fixed all Jamfile.v2 to correctly disable RTTI for VC7.1. - +- Added #pragma message("...") to be optionally supported by the Wave library. + This may be enabled by defining the BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE pp + constant to some value different from zero. + Sat Feb 18 2005 - Version 1.2.3 - Added a missing throw() specification to the function diff --git a/doc/compiletime_config.html b/doc/compiletime_config.html index bdb6675..c51c5b2 100644 --- a/doc/compiletime_config.html +++ b/doc/compiletime_config.html @@ -37,40 +37,39 @@ BOOST_WAVE_SUPPORT_WARNING_DIRECTIVE -

Support the #warning directive

+

Support the #warning directive

- BOOST_WAVE_SUPPORT_MS_EXTENSIONS + BOOST_WAVE_SUPPORT_MS_EXTENSIONS

Support several MS specific language extensions (i.e. __int8 et.al.)

- BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY + BOOST_WAVE_PREPROCESS_ERROR_MESSAGE_BODY

Enable the preprocessing of the message bodies - of #error and #warning + of #error and #warning directives.

- BOOST_WAVE_RETURN_PRAGMA_DIRECTIVES -

If defined, then the #pragma + BOOST_WAVE_RETURN_PRAGMA_DIRECTIVES +

If defined, then the #pragma directives are returned as a token sequence to the caller, if not defined, - the whole #pragma directive is skipped.

+ the whole #pragma directive is skipped.

- BOOST_WAVE_PREPROCESS_PRAGMA_BODY -

Enable the preprocessing of the bodies of + BOOST_WAVE_PREPROCESS_PRAGMA_BODY +

Enable the preprocessing of the bodies of all #pragma directives.
- Note though, that the body of an operator _Pragma() is preprocessed - always, as required by the C99 Standard [2]. + Note though, that the body of an operator _Pragma() is always preprocessed as this is required by the C99 Standard [2].

- BOOST_WAVE_ENABLE_COMMANDLINE_MACROS + BOOST_WAVE_ENABLE_COMMANDLINE_MACROS

Enable the functionality required to define macros with the command line syntax (-DMACRO(x)=definition)

- BOOST_WAVE_STRINGTYPE + BOOST_WAVE_STRINGTYPE

The tokens generated by the Wave library contain the token data and the file position, where this token was found in the input stream.
@@ -80,24 +79,28 @@ to the std::string type)

- BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS + BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS

If defined, then the preprocessor library supports variadics and placemarkers. Note, to support C99 mode, this constant must be defined too.

- BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH + BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH

If defined, it will determine the initial maximal possible include file nesting depth supported. It defaults to 1024.

- BOOST_WAVE_SUPPORT_PRAGMA_ONCE + BOOST_WAVE_SUPPORT_PRAGMA_ONCE

If defined, then the #pragma once directive is supported by Wave. This specifies that the file, in which the pragma resides, will be included - (opened) only once by the compiler in a build.

+ (opened) only once by the compiler in a build.

- BOOST_WAVE_SUPPORT_INCLUDE_NEXT -

If defined, then the #include_next directive is supported by Wave. This is syntactically equivalent to the #include directives, but may be used to inherit a header file (i.e. to include a file, which is named as the current file containing the #include_next).

+ BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE +

If defined, then the #pragma message("") directive is supported by Wave. This pragma simply generates a remark cotaining the message text. The body of the #pragma message is preprocessed whenever the BOOST_WAVE_PREPROCESS_PRAGMA_BODY constant is defined as well .

+ + + BOOST_WAVE_SUPPORT_INCLUDE_NEXT +

If defined, then the #include_next directive is supported by Wave. This is syntactically equivalent to the #include directives, but may be used to inherit a header file (i.e. to include a file, which is named as the current file containing the #include_next).

BOOST_WAVE_USE_STRICT_LEXER @@ -108,8 +111,7 @@ BOOST_WAVE_PRAGMA_KEYWORD

If this is defined to a string literal it will be used as the pragma keyword recogniyed by the library as specific Wave pragma's. This constant defaults to "wave", i.e. the library recognizes all #pragma wave option [(argument)] directives and dispatches the handling to the interpret_pragma() preprocessing hook function (see: Preprocessing Hooks). The arguments part of the pragma is optional.
-

- +

Using a different token type or lexer type in conjunction with Wave

@@ -209,7 +211,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/supported_pragmas.html b/doc/supported_pragmas.html index cb4fc1f..059fe2b 100644 --- a/doc/supported_pragmas.html +++ b/doc/supported_pragmas.html @@ -24,10 +24,20 @@ -

The Wave preprocessor tool supports specific #pragma - directives, which may be used to control some of the library features. All directives - described here are usable as conventional #pragma directives and as - operator _Pragma (if variadics are enabled). So for instance the +

+

Pragma directives supported by the Wave library
+ Pragma directives supported by the Wave tool

+
+

Pragma directives supported by the Wave library

+

The Wave preprocessor library natively supports the #pragma once and #pragma message("...") directives.

+

The #pragma once directive specifies that the file in which the pragma resides will be included + (opened) only once. 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 BOOST_WAVE_SUPPORT_PRAGMA_ONCE was given during compilation of the library.

+

The #pragma message(...) directive generates a remark containing the given message text. This may be useful to generate status messages directly from the preprocessed file. Note though, that the #pragma message(...) directive is supported only, if the compile time constant BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE was given during the compilation of the library. Note additionally, that the body of the message is preprocessed whenever the BOOST_WAVE_PREPROCESS_PRAGMA_BODY compile time constant was defined during compilation of the library.

+

Pragma directives supported by the Wave tool

+

The Wave preprocessor tool additionally supports specific #pragma directives, which may be used to control some of the tools features. These #pragma directives are implemented using the interpret_pragma() preprocessing hook (see here).

+

All directives + described here are usable as conventional #pragma directives and as operator _Pragma (if variadics are enabled). So for instance the following directives are functionally identical:

    #pragma wave trace(enable)  

and

@@ -108,11 +118,7 @@ only, if the BOOST_WAVE_PREPROCESS_PRAGMA_BODY compilation constant was specified during compilation. For more information about the possible compilation constants look here.

-

Additionally the Wave preprocessor library supports the #pragma once directive, - 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 BOOST_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 preprocessing hook function (see here) which should handle the additional directives. For an example of how to do it, you may have a look at the Wave driver application, which implements all of the pragma's listed above with the help of a supplied interpret_pragma function (for instance the #pragma wave timer() directive).

+

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

@@ -127,7 +133,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_exceptions.hpp b/include/boost/wave/cpp_exceptions.hpp index 0b19009..0c3182b 100644 --- a/include/boost/wave/cpp_exceptions.hpp +++ b/include/boost/wave/cpp_exceptions.hpp @@ -211,7 +211,9 @@ public: character_literal_out_of_range, could_not_open_output_file, incompatible_config, - last_error_number = incompatible_config + ill_formed_pragma_message, + pragma_message_directive, + last_error_number = pragma_message_directive }; preprocess_exception(char const *what_, error_code code, int line_, @@ -278,6 +280,9 @@ public: case preprocess_exception::include_nesting_too_deep: case preprocess_exception::illegal_operator_redefinition: case preprocess_exception::incompatible_config: + case preprocess_exception::ill_formed_pragma_option: + case preprocess_exception::ill_formed_pragma_message: + case preprocess_exception::pragma_message_directive: return true; case preprocess_exception::unexpected_error: @@ -287,7 +292,6 @@ public: case preprocess_exception::empty_macroarguments: case preprocess_exception::improperly_terminated_macro: case preprocess_exception::invalid_concat: - case preprocess_exception::ill_formed_pragma_option: case preprocess_exception::could_not_open_output_file: break; } @@ -343,7 +347,9 @@ public: "unbalanced #if/#endif in include file", // unbalanced_if_endif "character literal out of range", // character_literal_out_of_range "could not open output file", // could_not_open_output_file - "incompatible state information" // incompatible_config + "incompatible state information", // incompatible_config + "illformed pragma message", // ill_formed_pragma_message + "encountered #pragma message directive" // pragma_message_directive }; BOOST_ASSERT(unexpected_error <= code && code <= last_error_number); @@ -392,7 +398,9 @@ public: util::severity_warning, // unbalanced_if_endif util::severity_warning, // character_literal_out_of_range util::severity_error, // could_not_open_output_file - util::severity_remark // incompatible_config + util::severity_remark, // incompatible_config + util::severity_warning, // ill_formed_pragma_message + util::severity_remark, // pragma_message_directive }; BOOST_ASSERT(unexpected_error <= code && code <= last_error_number); diff --git a/include/boost/wave/util/interpret_pragma.hpp b/include/boost/wave/util/interpret_pragma.hpp index 22dc3ff..ee154f4 100644 --- a/include/boost/wave/util/interpret_pragma.hpp +++ b/include/boost/wave/util/interpret_pragma.hpp @@ -109,20 +109,16 @@ interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token, ), pattern_p(WhiteSpaceTokenType, TokenTypeMask)).hit) { - return false; + BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option, + impl::as_string(it, end).c_str(), + act_token.get_position()); } // remove the falsely matched closing parenthesis if (values.size() > 0) { - if (T_RIGHTPAREN == values.back()) { + BOOST_ASSERT(T_RIGHTPAREN == values.back()); typename ContainerT::reverse_iterator rit = values.rbegin(); - - values.erase((++rit).base()); - } - else { - BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_option, - "missing matching ')'", act_token.get_position()); - } + values.erase((++rit).base()); } // decode the option (call the context_policy hook) @@ -147,6 +143,37 @@ interpret_pragma(ContextT &ctx, typename ContextT::token_type const &act_token, return ctx.add_pragma_once_header(ctx.get_current_filename()); } #endif +#if BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE != 0 + else if ((*it).get_value() == "message") { + // #pragma message("") + using namespace boost::spirit; + ContainerT values; + + if (!parse (++it, end, + ch_p(T_LEFTPAREN) + >> lexeme_d[ + *(anychar_p[spirit_append_actor(values)] - ch_p(T_RIGHTPAREN)) + ] + >> ch_p(T_RIGHTPAREN), + pattern_p(WhiteSpaceTokenType, TokenTypeMask)).hit) + { + BOOST_WAVE_THROW(preprocess_exception, ill_formed_pragma_message, + impl::as_string(it, end).c_str(), + act_token.get_position()); + } + + // remove the falsely matched closing parenthesis + if (values.size() > 0) { + BOOST_ASSERT(T_RIGHTPAREN == values.back()); + typename ContainerT::reverse_iterator rit = values.rbegin(); + values.erase((++rit).base()); + } + + // output the message itself + BOOST_WAVE_THROW(preprocess_exception, pragma_message_directive, + impl::as_string(values).c_str(), act_token.get_position()); + } +#endif } return false; } diff --git a/include/boost/wave/wave_config.hpp b/include/boost/wave/wave_config.hpp index 8ad739d..893c807 100644 --- a/include/boost/wave/wave_config.hpp +++ b/include/boost/wave/wave_config.hpp @@ -61,6 +61,16 @@ #define BOOST_WAVE_SUPPORT_PRAGMA_ONCE 1 #endif +/////////////////////////////////////////////////////////////////////////////// +// Decide, whether to implement #pragma message("") +// +// To disable the implementation of #pragma message(""), define the following +// constant as zero before including this file. +// +#if !defined(BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE) +#define BOOST_WAVE_SUPPORT_PRAGMA_MESSAGE 1 +#endif + /////////////////////////////////////////////////////////////////////////////// // Decide, whether to implement #include_next // Please note, that this is an extension to the C++ Standard. diff --git a/tool/cpp.cpp b/tool/cpp.cpp index 44ffc31..14c5c9b 100644 --- a/tool/cpp.cpp +++ b/tool/cpp.cpp @@ -352,7 +352,7 @@ namespace { /////////////////////////////////////////////////////////////////////////// // Generate some meaningful error messages template - inline void + inline int report_error_message(Context &ctx, boost::wave::cpp_exception const &e) { // default error reporting @@ -387,6 +387,10 @@ namespace { default: break; } + + // errors count as one + return (e.get_severity() == boost::wave::util::severity_error || + e.get_severity() == boost::wave::util::severity_fatal) ? 1 : 0; } /////////////////////////////////////////////////////////////////////////// @@ -504,6 +508,7 @@ do_actual_work (std::string file_name, std::istream &instream, // current file position is saved for exception handling boost::wave::util::file_position_type current_position; auto_stop_watch elapsed_time(cerr); +int error_count = 0; try { // process the given file @@ -869,7 +874,7 @@ auto_stop_watch elapsed_time(cerr); catch (boost::wave::cpp_exception const &e) { // some preprocessing error if (is_interactive || boost::wave::is_recoverable(e)) { - report_error_message(ctx, e); + error_count += report_error_message(ctx, e); } else { throw; // re-throw for non-recoverable errors @@ -910,7 +915,7 @@ auto_stop_watch elapsed_time(cerr); << "unexpected exception caught." << endl; return 4; } - return 0; + return -error_count; // returns the number of errors as a negative integer } ///////////////////////////////////////////////////////////////////////////////