Line data Source code
1 : /*=============================================================================
2 : Boost.Wave: A Standard compliant C++ preprocessor library
3 :
4 : http://www.boost.org/
5 :
6 : Copyright (c) 2001-2012 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/throw_exception.hpp>
20 :
21 : #include <boost/wave/wave_config.hpp>
22 :
23 : // this must occur after all of the includes and before any code appears
24 : #ifdef BOOST_HAS_ABI_HEADERS
25 : #include BOOST_ABI_PREFIX
26 : #endif
27 :
28 : ///////////////////////////////////////////////////////////////////////////////
29 : // helper macro for throwing exceptions
30 : #if !defined(BOOST_WAVE_LEXER_THROW)
31 : #ifdef BOOST_NO_STRINGSTREAM
32 : #include <strstream>
33 : #define BOOST_WAVE_LEXER_THROW(cls, code, msg, line, column, name) \
34 : { \
35 : using namespace boost::wave; \
36 : std::strstream stream; \
37 : stream << cls::severity_text(cls::code) << ": " \
38 : << cls::error_text(cls::code); \
39 : if ((msg)[0] != 0) stream << ": " << (msg); \
40 : stream << std::ends; \
41 : std::string throwmsg = stream.str(); stream.freeze(false); \
42 : boost::throw_exception(cls(throwmsg.c_str(), cls::code, line, column, \
43 : name)); \
44 : } \
45 : /**/
46 : #else
47 : #include <sstream>
48 : #define BOOST_WAVE_LEXER_THROW(cls, code, msg, line, column, name) \
49 : { \
50 : using namespace boost::wave; \
51 : std::stringstream stream; \
52 : stream << cls::severity_text(cls::code) << ": " \
53 : << cls::error_text(cls::code); \
54 : if ((msg)[0] != 0) stream << ": " << (msg); \
55 : stream << std::ends; \
56 : boost::throw_exception(cls(stream.str().c_str(), cls::code, line, column, \
57 : name)); \
58 : } \
59 : /**/
60 : #endif // BOOST_NO_STRINGSTREAM
61 : #endif // BOOST_WAVE_LEXER_THROW
62 :
63 : #if !defined(BOOST_WAVE_LEXER_THROW_VAR)
64 : #ifdef BOOST_NO_STRINGSTREAM
65 : #include <strstream>
66 : #define BOOST_WAVE_LEXER_THROW_VAR(cls, codearg, msg, line, column, name) \
67 : { \
68 : using namespace boost::wave; \
69 : cls::error_code code = static_cast<cls::error_code>(codearg); \
70 : std::strstream stream; \
71 : stream << cls::severity_text(code) << ": " \
72 : << cls::error_text(code); \
73 : if ((msg)[0] != 0) stream << ": " << (msg); \
74 : stream << std::ends; \
75 : std::string throwmsg = stream.str(); stream.freeze(false); \
76 : boost::throw_exception(cls(throwmsg.c_str(), code, line, column, \
77 : name)); \
78 : } \
79 : /**/
80 : #else
81 : #include <sstream>
82 : #define BOOST_WAVE_LEXER_THROW_VAR(cls, codearg, msg, line, column, name) \
83 : { \
84 : using namespace boost::wave; \
85 : cls::error_code code = static_cast<cls::error_code>(codearg); \
86 : std::stringstream stream; \
87 : stream << cls::severity_text(code) << ": " \
88 : << cls::error_text(code); \
89 : if ((msg)[0] != 0) stream << ": " << (msg); \
90 : stream << std::ends; \
91 : boost::throw_exception(cls(stream.str().c_str(), code, line, column, \
92 : name)); \
93 : } \
94 : /**/
95 : #endif // BOOST_NO_STRINGSTREAM
96 : #endif // BOOST_WAVE_LEXER_THROW
97 :
98 : ///////////////////////////////////////////////////////////////////////////////
99 : namespace boost {
100 : namespace wave {
101 : namespace cpplexer {
102 :
103 : ///////////////////////////////////////////////////////////////////////////////
104 : // exception severity
105 : namespace util {
106 :
107 : enum severity {
108 : severity_remark = 0,
109 : severity_warning,
110 : severity_error,
111 : severity_fatal
112 : };
113 :
114 : inline char const *
115 0 : get_severity(severity level)
116 : {
117 0 : static char const *severity_text[] =
118 : {
119 : "remark", // severity_remark
120 : "warning", // severity_warning
121 : "error", // severity_error
122 : "fatal error" // severity_fatal
123 : };
124 0 : BOOST_ASSERT(severity_remark <= level && level <= severity_fatal);
125 0 : return severity_text[level];
126 : }
127 : }
128 :
129 : ///////////////////////////////////////////////////////////////////////////////
130 : // cpplexer_exception, the base class for all specific C++ lexer exceptions
131 0 : class BOOST_SYMBOL_VISIBLE cpplexer_exception
132 : : public std::exception
133 : {
134 : public:
135 0 : cpplexer_exception(std::size_t line_, std::size_t column_, char const *filename_) throw()
136 0 : : line(line_), column(column_)
137 : {
138 0 : unsigned int off = 0;
139 0 : while (off < sizeof(filename)-1 && *filename_)
140 0 : filename[off++] = *filename_++;
141 0 : filename[off] = 0;
142 : }
143 0 : ~cpplexer_exception() throw() {}
144 :
145 : virtual char const *what() const throw() = 0; // to be overloaded
146 : virtual char const *description() const throw() = 0;
147 : virtual int get_errorcode() const throw() = 0;
148 : virtual int get_severity() const throw() = 0;
149 : virtual bool is_recoverable() const throw() = 0;
150 :
151 0 : std::size_t line_no() const throw() { return line; }
152 : std::size_t column_no() const throw() { return column; }
153 0 : char const *file_name() const throw() { return filename; }
154 :
155 : protected:
156 : char filename[512];
157 : std::size_t line;
158 : std::size_t column;
159 : };
160 :
161 : ///////////////////////////////////////////////////////////////////////////////
162 : // lexing_exception error
163 0 : class BOOST_SYMBOL_VISIBLE lexing_exception :
164 : public cpplexer_exception
165 : {
166 : public:
167 : enum error_code {
168 : unexpected_error = 0,
169 : universal_char_invalid = 1,
170 : universal_char_base_charset = 2,
171 : universal_char_not_allowed = 3,
172 : invalid_long_long_literal = 4,
173 : generic_lexing_error = 5,
174 : generic_lexing_warning = 6
175 : };
176 :
177 0 : lexing_exception(char const *what_, error_code code, std::size_t line_,
178 : std::size_t column_, char const *filename_) throw()
179 0 : : cpplexer_exception(line_, column_, filename_),
180 0 : level(severity_level(code)), code(code)
181 : {
182 0 : unsigned int off = 0;
183 0 : while (off < sizeof(buffer)-1 && *what_)
184 0 : buffer[off++] = *what_++;
185 0 : buffer[off] = 0;
186 : }
187 0 : ~lexing_exception() throw() {}
188 :
189 0 : virtual char const *what() const throw()
190 : {
191 0 : return "boost::wave::lexing_exception";
192 : }
193 0 : virtual char const *description() const throw()
194 : {
195 0 : return buffer;
196 : }
197 0 : virtual int get_severity() const throw()
198 : {
199 0 : return level;
200 : }
201 0 : virtual int get_errorcode() const throw()
202 : {
203 0 : return code;
204 : }
205 0 : virtual bool is_recoverable() const throw()
206 : {
207 0 : switch (get_errorcode()) {
208 : case lexing_exception::universal_char_invalid:
209 : case lexing_exception::universal_char_base_charset:
210 : case lexing_exception::universal_char_not_allowed:
211 : case lexing_exception::invalid_long_long_literal:
212 : case lexing_exception::generic_lexing_warning:
213 : case lexing_exception::generic_lexing_error:
214 : return true; // for now allow all exceptions to be recoverable
215 :
216 0 : case lexing_exception::unexpected_error:
217 0 : default:
218 0 : break;
219 : }
220 0 : return false;
221 : }
222 :
223 0 : static char const *error_text(int code)
224 : {
225 : // error texts in this array must appear in the same order as the items in
226 : // the error enum above
227 0 : static char const *preprocess_exception_errors[] = {
228 : "unexpected error (should not happen)", // unexpected_error
229 : "universal character name specifies an invalid character", // universal_char_invalid
230 : "a universal character name cannot designate a character in the "
231 : "basic character set", // universal_char_base_charset
232 : "this universal character is not allowed in an identifier", // universal_char_not_allowed
233 : "long long suffixes are not allowed in pure C++ mode, "
234 : "enable long_long mode to allow these", // invalid_long_long_literal
235 : "generic lexer error", // generic_lexing_error
236 : "generic lexer warning" // generic_lexing_warning
237 : };
238 0 : return preprocess_exception_errors[code];
239 : }
240 :
241 0 : static util::severity severity_level(int code)
242 : {
243 0 : static util::severity preprocess_exception_severity[] = {
244 : util::severity_fatal, // unexpected_error
245 : util::severity_error, // universal_char_invalid
246 : util::severity_error, // universal_char_base_charset
247 : util::severity_error, // universal_char_not_allowed
248 : util::severity_warning, // invalid_long_long_literal
249 : util::severity_error, // generic_lexing_error
250 : util::severity_warning // invalid_long_long_literal
251 : };
252 0 : return preprocess_exception_severity[code];
253 : }
254 0 : static char const *severity_text(int code)
255 : {
256 0 : return util::get_severity(severity_level(code));
257 : }
258 :
259 : private:
260 : char buffer[512];
261 : util::severity level;
262 : error_code code;
263 : };
264 :
265 : ///////////////////////////////////////////////////////////////////////////////
266 : //
267 : // The is_recoverable() function allows to decide, whether it is possible
268 : // simply to continue after a given exception was thrown by Wave.
269 : //
270 : // This is kind of a hack to allow to recover from certain errors as long as
271 : // Wave doesn't provide better means of error recovery.
272 : //
273 : ///////////////////////////////////////////////////////////////////////////////
274 : inline bool
275 : is_recoverable(lexing_exception const& e)
276 : {
277 : return e.is_recoverable();
278 : }
279 :
280 : ///////////////////////////////////////////////////////////////////////////////
281 : } // namespace cpplexer
282 : } // namespace wave
283 : } // namespace boost
284 :
285 : // the suffix header occurs after all of the code
286 : #ifdef BOOST_HAS_ABI_HEADERS
287 : #include BOOST_ABI_SUFFIX
288 : #endif
289 :
290 : #endif // !defined(CPPLEXER_EXCEPTIONS_HPP_1A09DE1A_6D1F_4091_AF7F_5F13AB0D31AB_INCLUDED)
|