38 std::cerr << " (assertion '" << assertion << "' failed)"; |
38 std::cerr << " (assertion '" << assertion << "' failed)"; |
39 std::cerr << std::endl; |
39 std::cerr << std::endl; |
40 } |
40 } |
41 |
41 |
42 inline void assert_fail_abort(const char *file, int line, |
42 inline void assert_fail_abort(const char *file, int line, |
43 const char *function, const char* message, |
43 const char *function, const char* message, |
44 const char *assertion) |
44 const char *assertion) |
45 { |
45 { |
46 assert_fail_log(file, line, function, message, assertion); |
46 assert_fail_log(file, line, function, message, assertion); |
47 std::abort(); |
47 std::abort(); |
48 } |
48 } |
49 |
49 |
50 namespace _assert_bits { |
50 namespace _assert_bits { |
51 |
51 |
52 |
52 |
53 inline const char* cstringify(const std::string& str) { |
53 inline const char* cstringify(const std::string& str) { |
54 return str.c_str(); |
54 return str.c_str(); |
55 } |
55 } |
56 |
56 |
57 inline const char* cstringify(const char* str) { |
57 inline const char* cstringify(const char* str) { |
58 return str; |
58 return str; |
59 } |
59 } |
60 } |
60 } |
61 } |
61 } |
62 |
62 |
63 #endif // LEMON_ASSERT_H |
63 #endif // LEMON_ASSERT_H |
64 |
64 |
65 #undef LEMON_ASSERT |
65 #undef LEMON_ASSERT |
66 #undef LEMON_FIXME |
66 #undef LEMON_FIXME |
67 #undef LEMON_DEBUG |
67 #undef LEMON_DEBUG |
68 |
68 |
69 #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
69 #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
70 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
70 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
71 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1 |
71 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1 |
72 #error "LEMON assertion system is not set properly" |
72 #error "LEMON assertion system is not set properly" |
73 #endif |
73 #endif |
74 |
74 |
75 #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
75 #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
76 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
76 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
77 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ |
77 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ |
78 defined(LEMON_ENABLE_ASSERTS)) && \ |
78 defined(LEMON_ENABLE_ASSERTS)) && \ |
79 (defined(LEMON_DISABLE_ASSERTS) || \ |
79 (defined(LEMON_DISABLE_ASSERTS) || \ |
80 defined(NDEBUG)) |
80 defined(NDEBUG)) |
81 #error "LEMON assertion system is not set properly" |
81 #error "LEMON assertion system is not set properly" |
82 #endif |
82 #endif |
83 |
83 |
84 |
84 |
134 /// \code |
134 /// \code |
135 /// g++ -DLEMON_DISABLE_ASSERTS |
135 /// g++ -DLEMON_DISABLE_ASSERTS |
136 /// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS' |
136 /// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS' |
137 /// \endcode |
137 /// \endcode |
138 /// The checking is also disabled when the standard macro \c NDEBUG is defined. |
138 /// The checking is also disabled when the standard macro \c NDEBUG is defined. |
139 /// |
139 /// |
140 /// The LEMON assertion system has a wide range of customization |
140 /// The LEMON assertion system has a wide range of customization |
141 /// properties. As a default behaviour the failed assertion prints a |
141 /// properties. As a default behaviour the failed assertion prints a |
142 /// short log message to the standard error and aborts the execution. |
142 /// short log message to the standard error and aborts the execution. |
143 /// |
143 /// |
144 /// The following modes can be used in the assertion system: |
144 /// The following modes can be used in the assertion system: |
145 /// |
145 /// |
146 /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log |
146 /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log |
147 /// message to the standard error and continues the execution. |
147 /// message to the standard error and continues the execution. |
148 /// - \c LEMON_ASSERT_ABORT This mode is similar to the \c |
148 /// - \c LEMON_ASSERT_ABORT This mode is similar to the \c |
149 /// LEMON_ASSERT_LOG, but it aborts the program. It is the default |
149 /// LEMON_ASSERT_LOG, but it aborts the program. It is the default |
153 /// \code |
153 /// \code |
154 /// void custom_assert_handler(const char* file, int line, const char* function, |
154 /// void custom_assert_handler(const char* file, int line, const char* function, |
155 /// const char* message, const char* assertion); |
155 /// const char* message, const char* assertion); |
156 /// \endcode |
156 /// \endcode |
157 /// The name of the function should be defined as the \c |
157 /// The name of the function should be defined as the \c |
158 /// LEMON_CUSTOM_ASSERT_HANDLER macro name. |
158 /// LEMON_CUSTOM_ASSERT_HANDLER macro name. |
159 /// \code |
159 /// \code |
160 /// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler |
160 /// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler |
161 /// \endcode |
161 /// \endcode |
162 /// Whenever an assertion is occured, the custom assertion |
162 /// Whenever an assertion is occured, the custom assertion |
163 /// handler is called with appropiate parameters. |
163 /// handler is called with appropiate parameters. |
164 /// |
164 /// |
165 /// The assertion mode can also be changed within one compilation unit. |
165 /// The assertion mode can also be changed within one compilation unit. |
166 /// If the macros are redefined with other settings and the |
166 /// If the macros are redefined with other settings and the |
167 /// \ref lemon/assert.h "assert.h" file is reincluded, then the |
167 /// \ref lemon/assert.h "assert.h" file is reincluded, then the |
168 /// behaviour is changed appropiately to the new settings. |
168 /// behaviour is changed appropiately to the new settings. |
169 # define LEMON_ASSERT(exp, msg) \ |
169 # define LEMON_ASSERT(exp, msg) \ |
170 (static_cast<void> (!!(exp) ? 0 : ( \ |
170 (static_cast<void> (!!(exp) ? 0 : ( \ |
171 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
171 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
172 LEMON_FUNCTION_NAME, \ |
172 LEMON_FUNCTION_NAME, \ |
173 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
173 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
174 |
174 |
175 /// \ingroup exceptions |
175 /// \ingroup exceptions |
176 /// |
176 /// |
177 /// \brief Macro for mark not yet implemented features. |
177 /// \brief Macro for mark not yet implemented features. |
178 /// |
178 /// |
180 /// It is close to be the shortcut of the following code: |
180 /// It is close to be the shortcut of the following code: |
181 /// \code |
181 /// \code |
182 /// LEMON_ASSERT(false, msg); |
182 /// LEMON_ASSERT(false, msg); |
183 /// \endcode |
183 /// \endcode |
184 /// |
184 /// |
185 /// \see LEMON_ASSERT |
185 /// \see LEMON_ASSERT |
186 # define LEMON_FIXME(msg) \ |
186 # define LEMON_FIXME(msg) \ |
187 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
187 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
188 ::lemon::_assert_bits::cstringify(msg), \ |
188 ::lemon::_assert_bits::cstringify(msg), \ |
189 static_cast<const char*>(0))) |
189 static_cast<const char*>(0))) |
190 |
190 |
191 /// \ingroup exceptions |
191 /// \ingroup exceptions |
192 /// |
192 /// |
193 /// \brief Macro for internal assertions |
193 /// \brief Macro for internal assertions |
194 /// |
194 /// |
208 /// |
208 /// |
209 /// This macro works like the \c LEMON_ASSERT macro, therefore the |
209 /// This macro works like the \c LEMON_ASSERT macro, therefore the |
210 /// current behaviour depends on the settings of \c LEMON_ASSERT |
210 /// current behaviour depends on the settings of \c LEMON_ASSERT |
211 /// macro. |
211 /// macro. |
212 /// |
212 /// |
213 /// \see LEMON_ASSERT |
213 /// \see LEMON_ASSERT |
214 # define LEMON_DEBUG(exp, msg) \ |
214 # define LEMON_DEBUG(exp, msg) \ |
215 (static_cast<void> (!!(exp) ? 0 : ( \ |
215 (static_cast<void> (!!(exp) ? 0 : ( \ |
216 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
216 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
217 LEMON_FUNCTION_NAME, \ |
217 LEMON_FUNCTION_NAME, \ |
218 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
218 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
219 |
219 |
220 #else |
220 #else |
221 |
221 |
222 # ifndef LEMON_ASSERT_HANDLER |
222 # ifndef LEMON_ASSERT_HANDLER |
223 # define LEMON_ASSERT(exp, msg) (static_cast<void>(0)) |
223 # define LEMON_ASSERT(exp, msg) (static_cast<void>(0)) |
224 # define LEMON_FIXME(msg) (static_cast<void>(0)) |
224 # define LEMON_FIXME(msg) (static_cast<void>(0)) |
225 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) |
225 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) |
226 # else |
226 # else |
227 # define LEMON_ASSERT(exp, msg) \ |
227 # define LEMON_ASSERT(exp, msg) \ |
228 (static_cast<void> (!!(exp) ? 0 : ( \ |
228 (static_cast<void> (!!(exp) ? 0 : ( \ |
229 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
229 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
230 LEMON_FUNCTION_NAME, \ |
230 LEMON_FUNCTION_NAME, \ |
231 ::lemon::_assert_bits::cstringify(msg), \ |
231 ::lemon::_assert_bits::cstringify(msg), \ |
232 #exp), 0))) |
232 #exp), 0))) |
233 # define LEMON_FIXME(msg) \ |
233 # define LEMON_FIXME(msg) \ |
234 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
234 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
235 ::lemon::_assert_bits::cstringify(msg), \ |
235 ::lemon::_assert_bits::cstringify(msg), \ |
236 static_cast<const char*>(0))) |
236 static_cast<const char*>(0))) |
237 |
237 |
238 # if LEMON_ENABLE_DEBUG |
238 # if LEMON_ENABLE_DEBUG |
239 # define LEMON_DEBUG(exp, msg) |
239 # define LEMON_DEBUG(exp, msg) |
240 (static_cast<void> (!!(exp) ? 0 : ( \ |
240 (static_cast<void> (!!(exp) ? 0 : ( \ |
241 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
241 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
242 LEMON_FUNCTION_NAME, \ |
242 LEMON_FUNCTION_NAME, \ |
243 ::lemon::_assert_bits::cstringify(msg), \ |
243 ::lemon::_assert_bits::cstringify(msg), \ |
244 #exp), 0))) |
244 #exp), 0))) |
245 # else |
245 # else |
246 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) |
246 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) |
247 # endif |
247 # endif |
248 # endif |
248 # endif |
249 |
249 |