| 1 | /*============================================================================= |
|---|
| 2 | Boost.Wave: A Standard compliant C++ preprocessor library |
|---|
| 3 | |
|---|
| 4 | http://www.boost.org/ |
|---|
| 5 | |
|---|
| 6 | Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost |
|---|
| 7 | Software License, Version 1.0. (See accompanying file |
|---|
| 8 | LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
|---|
| 9 | =============================================================================*/ |
|---|
| 10 | |
|---|
| 11 | #if !defined(CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED) |
|---|
| 12 | #define CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED |
|---|
| 13 | |
|---|
| 14 | #include <exception> |
|---|
| 15 | #include <string> |
|---|
| 16 | |
|---|
| 17 | #include <boost/assert.hpp> |
|---|
| 18 | #include <boost/config.hpp> |
|---|
| 19 | #include <boost/wave/wave_config.hpp> |
|---|
| 20 | |
|---|
| 21 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 22 | // helper macro for throwing exceptions |
|---|
| 23 | #if !defined(BOOST_WAVE_LEXER_THROW) |
|---|
| 24 | #ifdef BOOST_NO_STRINGSTREAM |
|---|
| 25 | #include <strstream> |
|---|
| 26 | #define BOOST_WAVE_LEXER_THROW(cls, code, msg, line, column, name) \ |
|---|
| 27 | { \ |
|---|
| 28 | using namespace boost::wave; \ |
|---|
| 29 | std::strstream stream; \ |
|---|
| 30 | stream << cls::severity_text(cls::code) << ": " \ |
|---|
| 31 | << cls::error_text(cls::code); \ |
|---|
| 32 | if (msg[0] != 0) stream << ": " << msg; \ |
|---|
| 33 | stream << std::ends; \ |
|---|
| 34 | std::string throwmsg = stream.str(); stream.freeze(false); \ |
|---|
| 35 | throw cls(throwmsg.c_str(), cls::code, line, column, name); \ |
|---|
| 36 | } \ |
|---|
| 37 | /**/ |
|---|
| 38 | #else |
|---|
| 39 | #include <sstream> |
|---|
| 40 | #define BOOST_WAVE_LEXER_THROW(cls, code, msg, line, column, name) \ |
|---|
| 41 | { \ |
|---|
| 42 | using namespace boost::wave; \ |
|---|
| 43 | std::stringstream stream; \ |
|---|
| 44 | stream << cls::severity_text(cls::code) << ": " \ |
|---|
| 45 | << cls::error_text(cls::code); \ |
|---|
| 46 | if (msg[0] != 0) stream << ": " << msg; \ |
|---|
| 47 | stream << std::ends; \ |
|---|
| 48 | throw cls(stream.str().c_str(), cls::code, line, column, name); \ |
|---|
| 49 | } \ |
|---|
| 50 | /**/ |
|---|
| 51 | #endif // BOOST_NO_STRINGSTREAM |
|---|
| 52 | #endif // BOOST_WAVE_LEXER_THROW |
|---|
| 53 | |
|---|
| 54 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 55 | namespace boost { |
|---|
| 56 | namespace wave { |
|---|
| 57 | namespace cpplexer { |
|---|
| 58 | |
|---|
| 59 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 60 | // exception severity |
|---|
| 61 | namespace util { |
|---|
| 62 | |
|---|
| 63 | enum severity { |
|---|
| 64 | severity_remark = 0, |
|---|
| 65 | severity_warning, |
|---|
| 66 | severity_error, |
|---|
| 67 | severity_fatal |
|---|
| 68 | }; |
|---|
| 69 | |
|---|
| 70 | inline char const * |
|---|
| 71 | get_severity(severity level) |
|---|
| 72 | { |
|---|
| 73 | static char const *severity_text[] = |
|---|
| 74 | { |
|---|
| 75 | "remark", // severity_remark |
|---|
| 76 | "warning", // severity_warning |
|---|
| 77 | "error", // severity_error |
|---|
| 78 | "fatal error" // severity_fatal |
|---|
| 79 | }; |
|---|
| 80 | BOOST_ASSERT(severity_remark <= level && level <= severity_fatal); |
|---|
| 81 | return severity_text[level]; |
|---|
| 82 | } |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 86 | // cpplexer_exception, the base class for all specific C++ lexer exceptions |
|---|
| 87 | class cpplexer_exception |
|---|
| 88 | : public std::exception |
|---|
| 89 | { |
|---|
| 90 | public: |
|---|
| 91 | cpplexer_exception(int line_, int column_, char const *filename_) throw() |
|---|
| 92 | : line(line_), column(column_) |
|---|
| 93 | { |
|---|
| 94 | unsigned int off = 0; |
|---|
| 95 | while (off < sizeof(filename) && *filename_) |
|---|
| 96 | filename[off++] = *filename_++; |
|---|
| 97 | filename[off] = 0; |
|---|
| 98 | } |
|---|
| 99 | ~cpplexer_exception() throw() {} |
|---|
| 100 | |
|---|
| 101 | virtual char const *what() const throw() = 0; // to be overloaded |
|---|
| 102 | virtual char const *description() const throw() = 0; |
|---|
| 103 | |
|---|
| 104 | int line_no() const throw() { return line; } |
|---|
| 105 | int column_no() const throw() { return column; } |
|---|
| 106 | char const *file_name() const throw() { return filename; } |
|---|
| 107 | |
|---|
| 108 | protected: |
|---|
| 109 | char filename[512]; |
|---|
| 110 | int line; |
|---|
| 111 | int column; |
|---|
| 112 | }; |
|---|
| 113 | |
|---|
| 114 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 115 | // lexing_exception error |
|---|
| 116 | class lexing_exception : |
|---|
| 117 | public cpplexer_exception |
|---|
| 118 | { |
|---|
| 119 | public: |
|---|
| 120 | enum error_code { |
|---|
| 121 | unexpected_error = 0, |
|---|
| 122 | universal_char_invalid = 1, |
|---|
| 123 | universal_char_base_charset = 2, |
|---|
| 124 | universal_char_not_allowed = 3, |
|---|
| 125 | invalid_long_long_literal = 4, |
|---|
| 126 | generic_lexing_error = 5 |
|---|
| 127 | }; |
|---|
| 128 | |
|---|
| 129 | lexing_exception(char const *what_, error_code code, int line_, |
|---|
| 130 | int column_, char const *filename_) throw() |
|---|
| 131 | : cpplexer_exception(line_, column_, filename_), |
|---|
| 132 | level(severity_level(code)) |
|---|
| 133 | { |
|---|
| 134 | unsigned int off = 0; |
|---|
| 135 | while (off < sizeof(buffer) && *what_) |
|---|
| 136 | buffer[off++] = *what_++; |
|---|
| 137 | buffer[off] = 0; |
|---|
| 138 | } |
|---|
| 139 | ~lexing_exception() throw() {} |
|---|
| 140 | |
|---|
| 141 | virtual char const *what() const throw() |
|---|
| 142 | { |
|---|
| 143 | return "boost::wave::lexing_exception"; |
|---|
| 144 | } |
|---|
| 145 | virtual char const *description() const throw() |
|---|
| 146 | { |
|---|
| 147 | return buffer; |
|---|
| 148 | } |
|---|
| 149 | util::severity get_severity() |
|---|
| 150 | { |
|---|
| 151 | return level; |
|---|
| 152 | } |
|---|
| 153 | |
|---|
| 154 | static char const *error_text(int code) |
|---|
| 155 | { |
|---|
| 156 | // error texts in this array must appear in the same order as the items in |
|---|
| 157 | // the error enum above |
|---|
| 158 | static char const *preprocess_exception_errors[] = { |
|---|
| 159 | "unexpected error (should not happen)", // unexpected_error |
|---|
| 160 | "universal character name specifies an invalid character", // universal_char_invalid |
|---|
| 161 | "a universal character name cannot designate a character in the " |
|---|
| 162 | "basic character set", // universal_char_base_charset |
|---|
| 163 | "this universal character is not allowed in an identifier", // universal_char_not_allowed |
|---|
| 164 | "long long suffixes are not allowed in pure C++ mode, " |
|---|
| 165 | "enable long_long mode to allow these", // invalid_long_long_literal |
|---|
| 166 | "generic lexing error" // generic_lexing_error |
|---|
| 167 | }; |
|---|
| 168 | return preprocess_exception_errors[code]; |
|---|
| 169 | } |
|---|
| 170 | |
|---|
| 171 | static util::severity severity_level(int code) |
|---|
| 172 | { |
|---|
| 173 | static util::severity preprocess_exception_severity[] = { |
|---|
| 174 | util::severity_fatal, // unexpected_error |
|---|
| 175 | util::severity_error, // universal_char_invalid |
|---|
| 176 | util::severity_error, // universal_char_base_charset |
|---|
| 177 | util::severity_error, // universal_char_not_allowed |
|---|
| 178 | util::severity_warning, // invalid_long_long_literal |
|---|
| 179 | util::severity_error // generic_lexing_error |
|---|
| 180 | }; |
|---|
| 181 | return preprocess_exception_severity[code]; |
|---|
| 182 | } |
|---|
| 183 | static char const *severity_text(int code) |
|---|
| 184 | { |
|---|
| 185 | return util::get_severity(severity_level(code)); |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | private: |
|---|
| 189 | char buffer[512]; |
|---|
| 190 | util::severity level; |
|---|
| 191 | }; |
|---|
| 192 | |
|---|
| 193 | /////////////////////////////////////////////////////////////////////////////// |
|---|
| 194 | } // namespace cpplexer |
|---|
| 195 | } // namespace wave |
|---|
| 196 | } // namespace boost |
|---|
| 197 | |
|---|
| 198 | #endif // !defined(CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED) |
|---|