Chris@16: /*============================================================================= Chris@16: Boost.Wave: A Standard compliant C++ preprocessor library Chris@16: Chris@16: http://www.boost.org/ Chris@16: Chris@16: Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost Chris@16: Software License, Version 1.0. (See accompanying file Chris@16: LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: =============================================================================*/ Chris@16: Chris@16: #if !defined(CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED) Chris@16: #define CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // this must occur after all of the includes and before any code appears Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_PREFIX Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { Chris@16: namespace wave { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // exception severity Chris@16: namespace util { Chris@16: Chris@16: enum severity { Chris@16: severity_remark = 0, Chris@16: severity_warning, Chris@16: severity_error, Chris@16: severity_fatal, Chris@16: severity_commandline_error, Chris@16: last_severity_code = severity_commandline_error Chris@16: }; Chris@16: Chris@16: inline char const * Chris@16: get_severity(int level) Chris@16: { Chris@16: static char const *severity_text[] = Chris@16: { Chris@16: "remark", // severity_remark Chris@16: "warning", // severity_warning Chris@16: "error", // severity_error Chris@16: "fatal error", // severity_fatal Chris@16: "command line error" // severity_commandline_error Chris@16: }; Chris@16: BOOST_ASSERT(severity_remark <= level && Chris@16: level <= last_severity_code); Chris@16: return severity_text[level]; Chris@16: } Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // cpp_exception, the base class for all specific C preprocessor exceptions Chris@16: class BOOST_SYMBOL_VISIBLE cpp_exception Chris@16: : public std::exception Chris@16: { Chris@16: public: Chris@16: cpp_exception(std::size_t line_, std::size_t column_, char const *filename_) throw() Chris@16: : line(line_), column(column_) Chris@16: { Chris@16: unsigned int off = 0; Chris@16: while (off < sizeof(filename)-1 && *filename_) Chris@16: filename[off++] = *filename_++; Chris@16: filename[off] = 0; Chris@16: } Chris@16: ~cpp_exception() throw() {} Chris@16: Chris@16: virtual char const *what() const throw() = 0; // to be overloaded Chris@16: virtual char const *description() const throw() = 0; Chris@16: virtual int get_errorcode() const throw() = 0; Chris@16: virtual int get_severity() const throw() = 0; Chris@16: virtual char const* get_related_name() const throw() = 0; Chris@16: virtual bool is_recoverable() const throw() = 0; Chris@16: Chris@16: std::size_t line_no() const throw() { return line; } Chris@16: std::size_t column_no() const throw() { return column; } Chris@16: char const *file_name() const throw() { return filename; } Chris@16: Chris@16: protected: Chris@16: char filename[512]; Chris@16: std::size_t line; Chris@16: std::size_t column; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // preprocessor error Chris@16: class BOOST_SYMBOL_VISIBLE preprocess_exception : Chris@16: public cpp_exception Chris@16: { Chris@16: public: Chris@16: enum error_code { Chris@16: no_error = 0, Chris@16: unexpected_error, Chris@16: macro_redefinition, Chris@16: macro_insertion_error, Chris@16: bad_include_file, Chris@16: bad_include_statement, Chris@16: ill_formed_directive, Chris@16: error_directive, Chris@16: warning_directive, Chris@16: ill_formed_expression, Chris@16: missing_matching_if, Chris@16: missing_matching_endif, Chris@16: ill_formed_operator, Chris@16: bad_define_statement, Chris@16: bad_define_statement_va_args, Chris@16: too_few_macroarguments, Chris@16: too_many_macroarguments, Chris@16: empty_macroarguments, Chris@16: improperly_terminated_macro, Chris@16: bad_line_statement, Chris@16: bad_line_number, Chris@16: bad_line_filename, Chris@16: bad_undefine_statement, Chris@16: bad_macro_definition, Chris@16: illegal_redefinition, Chris@16: duplicate_parameter_name, Chris@16: invalid_concat, Chris@16: last_line_not_terminated, Chris@16: ill_formed_pragma_option, Chris@16: include_nesting_too_deep, Chris@16: misplaced_operator, Chris@16: alreadydefined_name, Chris@16: undefined_macroname, Chris@16: invalid_macroname, Chris@16: unexpected_qualified_name, Chris@16: division_by_zero, Chris@16: integer_overflow, Chris@16: illegal_operator_redefinition, Chris@16: ill_formed_integer_literal, Chris@16: ill_formed_character_literal, Chris@16: unbalanced_if_endif, Chris@16: character_literal_out_of_range, Chris@16: could_not_open_output_file, Chris@16: incompatible_config, Chris@16: ill_formed_pragma_message, Chris@16: pragma_message_directive, Chris@16: last_error_number = pragma_message_directive Chris@16: }; Chris@16: Chris@16: preprocess_exception(char const *what_, error_code code, std::size_t line_, Chris@16: std::size_t column_, char const *filename_) throw() Chris@16: : cpp_exception(line_, column_, filename_), Chris@16: code(code) Chris@16: { Chris@16: unsigned int off = 0; Chris@16: while (off < sizeof(buffer) && *what_) Chris@16: buffer[off++] = *what_++; Chris@16: buffer[off] = 0; Chris@16: } Chris@16: ~preprocess_exception() throw() {} Chris@16: Chris@16: virtual char const *what() const throw() Chris@16: { Chris@16: return "boost::wave::preprocess_exception"; Chris@16: } Chris@16: virtual char const *description() const throw() Chris@16: { Chris@16: return buffer; Chris@16: } Chris@16: virtual int get_severity() const throw() Chris@16: { Chris@16: return severity_level(code); Chris@16: } Chris@16: virtual int get_errorcode() const throw() Chris@16: { Chris@16: return code; Chris@16: } Chris@16: virtual char const* get_related_name() const throw() Chris@16: { Chris@16: return ""; Chris@16: } Chris@16: virtual bool is_recoverable() const throw() Chris@16: { Chris@16: switch (get_errorcode()) { Chris@16: // these are the exceptions thrown during processing not supposed to Chris@16: // produce any tokens on the context::iterator level Chris@16: case preprocess_exception::no_error: // just a placeholder Chris@16: case preprocess_exception::macro_redefinition: Chris@16: case preprocess_exception::macro_insertion_error: Chris@16: case preprocess_exception::bad_macro_definition: Chris@16: case preprocess_exception::illegal_redefinition: Chris@16: case preprocess_exception::duplicate_parameter_name: Chris@16: case preprocess_exception::invalid_macroname: Chris@16: case preprocess_exception::bad_include_file: Chris@16: case preprocess_exception::bad_include_statement: Chris@16: case preprocess_exception::ill_formed_directive: Chris@16: case preprocess_exception::error_directive: Chris@16: case preprocess_exception::warning_directive: Chris@16: case preprocess_exception::ill_formed_expression: Chris@16: case preprocess_exception::missing_matching_if: Chris@16: case preprocess_exception::missing_matching_endif: Chris@16: case preprocess_exception::unbalanced_if_endif: Chris@16: case preprocess_exception::bad_define_statement: Chris@16: case preprocess_exception::bad_define_statement_va_args: Chris@16: case preprocess_exception::bad_line_statement: Chris@16: case preprocess_exception::bad_line_number: Chris@16: case preprocess_exception::bad_line_filename: Chris@16: case preprocess_exception::bad_undefine_statement: Chris@16: case preprocess_exception::division_by_zero: Chris@16: case preprocess_exception::integer_overflow: Chris@16: case preprocess_exception::ill_formed_integer_literal: Chris@16: case preprocess_exception::ill_formed_character_literal: Chris@16: case preprocess_exception::character_literal_out_of_range: Chris@16: case preprocess_exception::last_line_not_terminated: Chris@16: case preprocess_exception::include_nesting_too_deep: Chris@16: case preprocess_exception::illegal_operator_redefinition: Chris@16: case preprocess_exception::incompatible_config: Chris@16: case preprocess_exception::ill_formed_pragma_option: Chris@16: case preprocess_exception::ill_formed_pragma_message: Chris@16: case preprocess_exception::pragma_message_directive: Chris@16: return true; Chris@16: Chris@16: case preprocess_exception::unexpected_error: Chris@16: case preprocess_exception::ill_formed_operator: Chris@16: case preprocess_exception::too_few_macroarguments: Chris@16: case preprocess_exception::too_many_macroarguments: Chris@16: case preprocess_exception::empty_macroarguments: Chris@16: case preprocess_exception::improperly_terminated_macro: Chris@16: case preprocess_exception::invalid_concat: Chris@16: case preprocess_exception::could_not_open_output_file: Chris@16: break; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: static char const *error_text(int code) Chris@16: { Chris@16: // error texts in this array must appear in the same order as the items in Chris@16: // the error enum above Chris@16: static char const *preprocess_exception_errors[] = { Chris@16: "no error", // no_error Chris@16: "unexpected error (should not happen)", // unexpected_error Chris@16: "illegal macro redefinition", // macro_redefinition Chris@16: "macro definition failed (out of memory?)", // macro_insertion_error Chris@16: "could not find include file", // bad_include_file Chris@16: "ill formed #include directive", // bad_include_statement Chris@16: "ill formed preprocessor directive", // ill_formed_directive Chris@16: "encountered #error directive or #pragma wave stop()", // error_directive Chris@16: "encountered #warning directive", // warning_directive Chris@16: "ill formed preprocessor expression", // ill_formed_expression Chris@16: "the #if for this directive is missing", // missing_matching_if Chris@16: "detected at least one missing #endif directive", // missing_matching_endif Chris@16: "ill formed preprocessing operator", // ill_formed_operator Chris@16: "ill formed #define directive", // bad_define_statement Chris@16: "__VA_ARGS__ can only appear in the " Chris@16: "expansion of a C99 variadic macro", // bad_define_statement_va_args Chris@16: "too few macro arguments", // too_few_macroarguments Chris@16: "too many macro arguments", // too_many_macroarguments Chris@16: "empty macro arguments are not supported in pure C++ mode, " Chris@16: "use variadics mode to allow these", // empty_macroarguments Chris@16: "improperly terminated macro invocation " Chris@16: "or replacement-list terminates in partial " Chris@16: "macro expansion (not supported yet)", // improperly_terminated_macro Chris@16: "ill formed #line directive", // bad_line_statement Chris@16: "line number argument of #line directive " Chris@16: "should consist out of decimal digits " Chris@16: "only and must be in range of [1..INT_MAX]", // bad_line_number Chris@16: "filename argument of #line directive should " Chris@16: "be a narrow string literal", // bad_line_filename Chris@16: "#undef may not be used on this predefined name", // bad_undefine_statement Chris@16: "invalid macro definition", // bad_macro_definition Chris@16: "this predefined name may not be redefined", // illegal_redefinition Chris@16: "duplicate macro parameter name", // duplicate_parameter_name Chris@16: "pasting the following two tokens does not " Chris@16: "give a valid preprocessing token", // invalid_concat Chris@16: "last line of file ends without a newline", // last_line_not_terminated Chris@16: "unknown or illformed pragma option", // ill_formed_pragma_option Chris@16: "include files nested too deep", // include_nesting_too_deep Chris@16: "misplaced operator defined()", // misplaced_operator Chris@16: "the name is already used in this scope as " Chris@16: "a macro or scope name", // alreadydefined_name Chris@16: "undefined macro or scope name may not be imported", // undefined_macroname Chris@16: "ill formed macro name", // invalid_macroname Chris@16: "qualified names are supported in C++11 mode only", // unexpected_qualified_name Chris@16: "division by zero in preprocessor expression", // division_by_zero Chris@16: "integer overflow in preprocessor expression", // integer_overflow Chris@16: "this cannot be used as a macro name as it is " Chris@16: "an operator in C++", // illegal_operator_redefinition Chris@16: "ill formed integer literal or integer constant too large", // ill_formed_integer_literal Chris@16: "ill formed character literal", // ill_formed_character_literal Chris@16: "unbalanced #if/#endif in include file", // unbalanced_if_endif Chris@16: "expression contains out of range character literal", // character_literal_out_of_range Chris@16: "could not open output file", // could_not_open_output_file Chris@16: "incompatible state information", // incompatible_config Chris@16: "illformed pragma message", // ill_formed_pragma_message Chris@16: "encountered #pragma message directive" // pragma_message_directive Chris@16: }; Chris@16: BOOST_ASSERT(no_error <= code && code <= last_error_number); Chris@16: return preprocess_exception_errors[code]; Chris@16: } Chris@16: Chris@16: static util::severity severity_level(int code) Chris@16: { Chris@16: static util::severity preprocess_exception_severity[] = { Chris@16: util::severity_remark, // no_error Chris@16: util::severity_fatal, // unexpected_error Chris@16: util::severity_warning, // macro_redefinition Chris@16: util::severity_fatal, // macro_insertion_error Chris@16: util::severity_error, // bad_include_file Chris@16: util::severity_error, // bad_include_statement Chris@16: util::severity_error, // ill_formed_directive Chris@16: util::severity_fatal, // error_directive Chris@16: util::severity_warning, // warning_directive Chris@16: util::severity_error, // ill_formed_expression Chris@16: util::severity_error, // missing_matching_if Chris@16: util::severity_error, // missing_matching_endif Chris@16: util::severity_error, // ill_formed_operator Chris@16: util::severity_error, // bad_define_statement Chris@16: util::severity_error, // bad_define_statement_va_args Chris@16: util::severity_warning, // too_few_macroarguments Chris@16: util::severity_warning, // too_many_macroarguments Chris@16: util::severity_warning, // empty_macroarguments Chris@16: util::severity_error, // improperly_terminated_macro Chris@16: util::severity_warning, // bad_line_statement Chris@16: util::severity_warning, // bad_line_number Chris@16: util::severity_warning, // bad_line_filename Chris@16: util::severity_warning, // bad_undefine_statement Chris@16: util::severity_commandline_error, // bad_macro_definition Chris@16: util::severity_warning, // illegal_redefinition Chris@16: util::severity_error, // duplicate_parameter_name Chris@16: util::severity_error, // invalid_concat Chris@16: util::severity_warning, // last_line_not_terminated Chris@16: util::severity_warning, // ill_formed_pragma_option Chris@16: util::severity_fatal, // include_nesting_too_deep Chris@16: util::severity_error, // misplaced_operator Chris@16: util::severity_error, // alreadydefined_name Chris@16: util::severity_error, // undefined_macroname Chris@16: util::severity_error, // invalid_macroname Chris@16: util::severity_error, // unexpected_qualified_name Chris@16: util::severity_fatal, // division_by_zero Chris@16: util::severity_error, // integer_overflow Chris@16: util::severity_error, // illegal_operator_redefinition Chris@16: util::severity_error, // ill_formed_integer_literal Chris@16: util::severity_error, // ill_formed_character_literal Chris@16: util::severity_warning, // unbalanced_if_endif Chris@16: util::severity_warning, // character_literal_out_of_range Chris@16: util::severity_error, // could_not_open_output_file Chris@16: util::severity_remark, // incompatible_config Chris@16: util::severity_warning, // ill_formed_pragma_message Chris@16: util::severity_remark, // pragma_message_directive Chris@16: }; Chris@16: BOOST_ASSERT(no_error <= code && code <= last_error_number); Chris@16: return preprocess_exception_severity[code]; Chris@16: } Chris@16: static char const *severity_text(int code) Chris@16: { Chris@16: return util::get_severity(severity_level(code)); Chris@16: } Chris@16: Chris@16: private: Chris@16: char buffer[512]; Chris@16: error_code code; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Error during macro handling, this exception contains the related macro name Chris@16: class BOOST_SYMBOL_VISIBLE macro_handling_exception : Chris@16: public preprocess_exception Chris@16: { Chris@16: public: Chris@16: macro_handling_exception(char const *what_, error_code code, std::size_t line_, Chris@16: std::size_t column_, char const *filename_, char const *macroname) throw() Chris@16: : preprocess_exception(what_, code, line_, column_, filename_) Chris@16: { Chris@16: unsigned int off = 0; Chris@16: while (off < sizeof(name) && *macroname) Chris@16: name[off++] = *macroname++; Chris@16: name[off] = 0; Chris@16: } Chris@16: ~macro_handling_exception() throw() {} Chris@16: Chris@16: virtual char const *what() const throw() Chris@16: { Chris@16: return "boost::wave::macro_handling_exception"; Chris@16: } Chris@16: char const* get_related_name() const throw() Chris@16: { Chris@16: return name; Chris@16: } Chris@16: Chris@16: private: Chris@16: char name[512]; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The is_recoverable() function allows to decide, whether it is possible Chris@16: // simply to continue after a given exception was thrown by Wave. Chris@16: // Chris@16: // This is kind of a hack to allow to recover from certain errors as long as Chris@16: // Wave doesn't provide better means of error recovery. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: inline bool Chris@16: is_recoverable(cpp_exception const& e) Chris@16: { Chris@16: return e.is_recoverable(); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: } // namespace wave Chris@16: } // namespace boost Chris@16: Chris@16: // the suffix header occurs after all of the code Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_SUFFIX Chris@16: #endif Chris@16: Chris@16: #endif // !defined(CPP_EXCEPTIONS_HPP_5190E447_A781_4521_A275_5134FF9917D7_INCLUDED)