diff --git a/ChangeLog b/ChangeLog index 957076f..57c9a3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,7 +11,6 @@ TODO (known issues): macro expansion. - Fix the re2c lexer for iterators others then string::iterator (or more generally for iterators, which aren't random access iterators) -- Enforce, that #if/#endif are balanced file wise - Try to remove the second parameter from the pp_iterator<>::force_include function. - Fix the trigraph backslash problem in the re2c (C/C++ and IDL) scanners, if @@ -28,7 +27,9 @@ CHANGELOG expressions. - Fixed a bug in the testwave application which prevented the correct recognition of expected errors under certain circumstances. - +- Fixed a portability problem (for gcc 3.3.x) in the testwave application. +- Enforced that #if/#endif are balanced file wise. + Thu Apr 7 10:07:45 WEDT 2005 Version 1.1.16 - Fixed a bug in the white space eating component, which prevented a C++ diff --git a/include/boost/wave/cpp_exceptions.hpp b/include/boost/wave/cpp_exceptions.hpp index aa0ecdf..e990335 100644 --- a/include/boost/wave/cpp_exceptions.hpp +++ b/include/boost/wave/cpp_exceptions.hpp @@ -157,7 +157,8 @@ public: integer_overflow, illegal_operator_redefinition, ill_formed_integer_literal, - ill_formed_character_literal + ill_formed_character_literal, + unbalanced_if_endif }; preprocess_exception(char const *what_, error_code code, int line_, @@ -228,9 +229,10 @@ public: "this macro name cannot be used as a as it is an operator in C++", // illegal_operator_redefinition "ill formed integer literal or integer constant too large", // ill_formed_integer_literal "ill formed character literal", // ill_formed_character_literal + "unbalanced #if/#endif in include file" // unbalanced_if_endif }; BOOST_ASSERT(unexpected_error <= code && - code <= ill_formed_character_literal); + code <= unbalanced_if_endif); return preprocess_exception_errors[code]; } @@ -271,10 +273,11 @@ public: util::severity_error, // integer_overflow util::severity_error, // illegal_operator_redefinition util::severity_error, // ill_formed_integer_literal - util::severity_error // ill_formed_character_literal + util::severity_error, // ill_formed_character_literal + util::severity_warning // unbalanced_if_endif }; BOOST_ASSERT(unexpected_error <= code && - code <= ill_formed_character_literal); + code <= unbalanced_if_endif); return preprocess_exception_severity[code]; } static char const *severity_text(int code) diff --git a/include/boost/wave/cpp_iteration_context.hpp b/include/boost/wave/cpp_iteration_context.hpp index 0cfaf0d..9f797a2 100644 --- a/include/boost/wave/cpp_iteration_context.hpp +++ b/include/boost/wave/cpp_iteration_context.hpp @@ -45,11 +45,11 @@ namespace iteration_context_policies { // the beginning and the end of the loaded string. // /////////////////////////////////////////////////////////////////////////// - struct load_file_to_string { - + struct load_file_to_string + { template - class inner { - + class inner + { public: template static @@ -95,8 +95,8 @@ namespace iteration_context_policies { // istreambuf_iterators. // /////////////////////////////////////////////////////////////////////////////// - struct load_file { - + struct load_file + { template class inner { @@ -136,25 +136,28 @@ namespace iteration_context_policies { /////////////////////////////////////////////////////////////////////////////// // template -struct base_iteration_context { - +struct base_iteration_context +{ public: - base_iteration_context(BOOST_WAVE_STRINGTYPE const &fname) - : real_filename(fname), filename(fname), line(1), emitted_lines(1) + base_iteration_context( + BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0) + : real_filename(fname), filename(fname), line(1), emitted_lines(1), + if_block_depth(if_block_depth) {} base_iteration_context(IteratorT const &first_, IteratorT const &last_, - BOOST_WAVE_STRINGTYPE const &fname) + BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0) : first(first_), last(last_), real_filename(fname), filename(fname), - line(1), emitted_lines(1) + line(1), emitted_lines(1), if_block_depth(if_block_depth) {} // the actual input stream IteratorT first; // actual input stream position IteratorT last; // end of input stream BOOST_WAVE_STRINGTYPE real_filename; // real name of the current file - BOOST_WAVE_STRINGTYPE filename; // actual processed file + BOOST_WAVE_STRINGTYPE filename; // actual processed file int line; // line counter of underlying stream int emitted_lines; // count of emitted newlines + std::size_t if_block_depth; // depth of #if block recursion }; /////////////////////////////////////////////////////////////////////////////// diff --git a/include/boost/wave/util/cpp_iterator.hpp b/include/boost/wave/util/cpp_iterator.hpp index 1c5dd95..8870c15 100644 --- a/include/boost/wave/util/cpp_iterator.hpp +++ b/include/boost/wave/util/cpp_iterator.hpp @@ -224,7 +224,7 @@ private: typedef base_iteration_context base_iteration_context_type; typedef iteration_context - iteration_context_t; + iteration_context_type; // parse tree related types typedef @@ -361,7 +361,16 @@ pp_iterator_functor::returned_from_include() // restore the previous iteration context after finishing the preprocessing // of the included file + BOOST_WAVE_STRINGTYPE oldfile = iter_ctx->real_filename; + iter_ctx = ctx.pop_iteration_context(); + + // ensure the itegrity of the #if/#endif stack + if (iter_ctx->if_block_depth != ctx.get_if_block_depth()) { + using boost::wave::util::impl::escape_lit; + BOOST_WAVE_THROW(preprocess_exception, unbalanced_if_endif, + escape_lit(oldfile).c_str(), act_pos); + } must_emit_line_directive = true; seen_newline = true; @@ -1009,7 +1018,7 @@ fs::path native_path(file_path, fs::native); // preprocess the opened file boost::shared_ptr new_iter_ctx ( - new iteration_context_t(native_path.native_file_string().c_str(), + new iteration_context_type(native_path.native_file_string().c_str(), act_pos, ctx.get_language())); // call the include policy trace function @@ -1019,6 +1028,7 @@ fs::path native_path(file_path, fs::native); // store current file position iter_ctx->filename = act_pos.get_file(); iter_ctx->line = act_pos.get_line(); + iter_ctx->if_block_depth = ctx.get_if_block_depth(); // push the old iteration context onto the stack and continue with the new ctx.push_iteration_context(act_pos, iter_ctx); @@ -1721,7 +1731,7 @@ public: private: typedef boost::spirit::multi_pass - base_t; + base_type; typedef pp_iterator self_type; typedef boost::wave::util::functor_input functor_input_type; @@ -1733,7 +1743,7 @@ public: pp_iterator(ContextT &ctx, IteratorT const &first, IteratorT const &last, typename ContextT::position_type const &pos, boost::wave::language_support language) - : base_t(input_policy_type(ctx, first, last, pos, language)) + : base_type(input_policy_type(ctx, first, last, pos, language)) {} void force_include(char const *path_, bool is_last) diff --git a/include/boost/wave/util/iteration_context.hpp b/include/boost/wave/util/iteration_context.hpp index b6a4ee6..48cc974 100644 --- a/include/boost/wave/util/iteration_context.hpp +++ b/include/boost/wave/util/iteration_context.hpp @@ -26,10 +26,10 @@ namespace util { template class iteration_context_stack { - typedef std::stack base_t; + typedef std::stack base_type; public: - typedef typename base_t::size_type size_type; + typedef typename base_type::size_type size_type; iteration_context_stack() : max_include_nesting_depth(BOOST_WAVE_MAX_INCLUDE_LEVEL_DEPTH) @@ -40,12 +40,12 @@ public: size_type get_max_include_nesting_depth() const { return max_include_nesting_depth; } - typename base_t::size_type size() const { return iter_ctx.size(); } - typename base_t::value_type &top() { return iter_ctx.top(); } + typename base_type::size_type size() const { return iter_ctx.size(); } + typename base_type::value_type &top() { return iter_ctx.top(); } void pop() { iter_ctx.pop(); } template - void push(PositionT const &pos, typename base_t::value_type const &val) + void push(PositionT const &pos, typename base_type::value_type const &val) { if (iter_ctx.size() == max_include_nesting_depth) { char buffer[22]; // 21 bytes holds all NUL-terminated unsigned 64-bit numbers @@ -60,7 +60,7 @@ public: private: size_type max_include_nesting_depth; - base_t iter_ctx; + base_type iter_ctx; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/test/testwave/testfiles/006_029.cpp b/test/testwave/testfiles/006_029.cpp index d2079fd..52fa0d6 100644 --- a/test/testwave/testfiles/006_029.cpp +++ b/test/testwave/testfiles/006_029.cpp @@ -16,7 +16,7 @@ // Tests error reporting: ill-formed group in a source file. // 17.5: Errorneous #endif without #if in an included file. -//E +//E 006_029.hpp(47): warning: unbalanced #if/#endif in include file: $P(006_029.hpp) #if 1 #include "006_029.hpp" diff --git a/test/testwave/testfiles/006_030.cpp b/test/testwave/testfiles/006_030.cpp index f53055b..c5928a4 100644 --- a/test/testwave/testfiles/006_030.cpp +++ b/test/testwave/testfiles/006_030.cpp @@ -16,7 +16,7 @@ // Tests error reporting: ill-formed group in a source file. // 17.6: Errorneous unterminated #if section in an included file. -//E +//E 006_030.hpp(49): warning: unbalanced #if/#endif in include file: $P(006_030.hpp) #include "006_030.hpp" #endif diff --git a/test/testwave/testfiles/test.cfg b/test/testwave/testfiles/test.cfg index cb17d72..6a7f17c 100644 --- a/test/testwave/testfiles/test.cfg +++ b/test/testwave/testfiles/test.cfg @@ -159,8 +159,8 @@ 006_026.cpp 006_027.cpp 006_028.cpp -# 006_029.cpp -# 006_030.cpp +006_029.cpp +006_030.cpp 006_031.cpp # diff --git a/test/testwave/testwave.cpp b/test/testwave/testwave.cpp index 1fa82b3..4570c48 100644 --- a/test/testwave/testwave.cpp +++ b/test/testwave/testwave.cpp @@ -34,9 +34,9 @@ namespace fs = boost::filesystem; // equal to the number of failed tests // level 1: prints a short summary only // level 2: prints the names of the failed tests only -// level 3: prints the outcome of every test -// level 4: prints the expected and real result for failed tests -// level 5: prints the real result for succeeded tests +// level 3: prints the expected and real result for failed tests +// level 4: prints the outcome of every test +// level 5: prints the real result even for succeeded tests // // The default debug level is 1. // diff --git a/test/testwave/testwave_app.cpp b/test/testwave/testwave_app.cpp index 4aef99d..8285d51 100644 --- a/test/testwave/testwave_app.cpp +++ b/test/testwave/testwave_app.cpp @@ -267,7 +267,7 @@ testwave_app::test_a_file(std::string filename) !got_expected_result(filename, error, expected_error)) { // we expected an error but got none (or a different one) - if (debuglevel > 3) { + if (debuglevel > 2) { std::cerr << filename << ": failed" << std::endl << "result: " << std::endl << result << std::endl @@ -280,7 +280,7 @@ testwave_app::test_a_file(std::string filename) } else if (!got_expected_result(filename, result, expected)) { // no preprocessing error encountered - if (debuglevel > 3) { + if (debuglevel > 2) { std::cerr << filename << ": failed" << std::endl << "result: " << std::endl << result << std::endl @@ -296,7 +296,7 @@ testwave_app::test_a_file(std::string filename) << filename << ": succeeded" << std::endl << "result: " << std::endl << result << std::endl; } - else if (debuglevel > 2) { + else if (debuglevel > 3) { std::cerr << filename << ": succeeded" << std::endl; } } @@ -309,7 +309,7 @@ testwave_app::test_a_file(std::string filename) if (!got_expected_result(filename, error, expected_error)) { // the error was unexpected - if (debuglevel > 3) { + if (debuglevel > 2) { std::cerr << filename << ": failed" << std::endl; @@ -333,7 +333,7 @@ testwave_app::test_a_file(std::string filename) << filename << ": succeeded" << std::endl << "result: " << std::endl << error << std::endl; } - else if (debuglevel > 2) { + else if (debuglevel > 3) { // caught the expected error message std::cerr << filename << ": succeeded" << std::endl; }