25 |
25 |
26 #include <lemon/error.h> |
26 #include <lemon/error.h> |
27 |
27 |
28 namespace lemon { |
28 namespace lemon { |
29 |
29 |
30 inline void assert_fail_log(const char *file, int line, const char *function, |
30 inline void assert_fail_abort(const char *file, int line, |
31 const char *message, const char *assertion) |
31 const char *function, const char* message, |
|
32 const char *assertion) |
32 { |
33 { |
33 std::cerr << file << ":" << line << ": "; |
34 std::cerr << file << ":" << line << ": "; |
34 if (function) |
35 if (function) |
35 std::cerr << function << ": "; |
36 std::cerr << function << ": "; |
36 std::cerr << message; |
37 std::cerr << message; |
37 if (assertion) |
38 if (assertion) |
38 std::cerr << " (assertion '" << assertion << "' failed)"; |
39 std::cerr << " (assertion '" << assertion << "' failed)"; |
39 std::cerr << std::endl; |
40 std::cerr << std::endl; |
40 } |
|
41 |
|
42 inline void assert_fail_abort(const char *file, int line, |
|
43 const char *function, const char* message, |
|
44 const char *assertion) |
|
45 { |
|
46 assert_fail_log(file, line, function, message, assertion); |
|
47 std::abort(); |
41 std::abort(); |
48 } |
42 } |
49 |
43 |
50 namespace _assert_bits { |
44 namespace _assert_bits { |
51 |
45 |
61 } |
55 } |
62 |
56 |
63 #endif // LEMON_ASSERT_H |
57 #endif // LEMON_ASSERT_H |
64 |
58 |
65 #undef LEMON_ASSERT |
59 #undef LEMON_ASSERT |
66 #undef LEMON_FIXME |
|
67 #undef LEMON_DEBUG |
60 #undef LEMON_DEBUG |
68 |
61 |
69 #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
62 #if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
70 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
|
71 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1 |
63 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1 |
72 #error "LEMON assertion system is not set properly" |
64 #error "LEMON assertion system is not set properly" |
73 #endif |
65 #endif |
74 |
66 |
75 #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
67 #if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
76 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
|
77 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ |
68 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ |
78 defined(LEMON_ENABLE_ASSERTS)) && \ |
69 defined(LEMON_ENABLE_ASSERTS)) && \ |
79 (defined(LEMON_DISABLE_ASSERTS) || \ |
70 (defined(LEMON_DISABLE_ASSERTS) || \ |
80 defined(NDEBUG)) |
71 defined(NDEBUG)) |
81 #error "LEMON assertion system is not set properly" |
72 #error "LEMON assertion system is not set properly" |
82 #endif |
73 #endif |
83 |
74 |
84 |
75 |
85 #if defined LEMON_ASSERT_LOG |
76 #if defined LEMON_ASSERT_ABORT |
86 # undef LEMON_ASSERT_HANDLER |
|
87 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_log |
|
88 #elif defined LEMON_ASSERT_ABORT |
|
89 # undef LEMON_ASSERT_HANDLER |
77 # undef LEMON_ASSERT_HANDLER |
90 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort |
78 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort |
91 #elif defined LEMON_ASSERT_CUSTOM |
79 #elif defined LEMON_ASSERT_CUSTOM |
92 # undef LEMON_ASSERT_HANDLER |
80 # undef LEMON_ASSERT_HANDLER |
93 # ifndef LEMON_CUSTOM_ASSERT_HANDLER |
81 # ifndef LEMON_CUSTOM_ASSERT_HANDLER |
118 |
106 |
119 /// \ingroup exceptions |
107 /// \ingroup exceptions |
120 /// |
108 /// |
121 /// \brief Macro for assertion with customizable message |
109 /// \brief Macro for assertion with customizable message |
122 /// |
110 /// |
123 /// Macro for assertion with customizable message. \param exp An |
111 /// Macro for assertion with customizable message. |
124 /// expression that must be convertible to \c bool. If it is \c |
112 /// \param exp An expression that must be convertible to \c bool. If it is \c |
125 /// false, then an assertion is raised. The concrete behaviour depends |
113 /// false, then an assertion is raised. The concrete behaviour depends on the |
126 /// on the settings of the assertion system. \param msg A <tt>const |
114 /// settings of the assertion system. |
127 /// char*</tt> parameter, which can be used to provide information |
115 /// \param msg A <tt>const char*</tt> parameter, which can be used to provide |
128 /// about the circumstances of the failed assertion. |
116 /// information about the circumstances of the failed assertion. |
129 /// |
117 /// |
130 /// The assertions are enabled in the default behaviour. |
118 /// The assertions are enabled in the default behaviour. |
131 /// You can disable them with the following code: |
119 /// You can disable them with the following code: |
132 /// \code |
120 /// \code |
133 /// #define LEMON_DISABLE_ASSERTS |
121 /// #define LEMON_DISABLE_ASSERTS |
137 /// g++ -DLEMON_DISABLE_ASSERTS |
125 /// g++ -DLEMON_DISABLE_ASSERTS |
138 /// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS' |
126 /// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS' |
139 /// \endcode |
127 /// \endcode |
140 /// The checking is also disabled when the standard macro \c NDEBUG is defined. |
128 /// The checking is also disabled when the standard macro \c NDEBUG is defined. |
141 /// |
129 /// |
142 /// The LEMON assertion system has a wide range of customization |
130 /// As a default behaviour the failed assertion prints a short log message to |
143 /// properties. As a default behaviour the failed assertion prints a |
131 /// the standard error and aborts the execution. |
144 /// short log message to the standard error and aborts the execution. |
132 /// |
145 /// |
133 /// However, the following modes can be used in the assertion system: |
146 /// The following modes can be used in the assertion system: |
134 /// - \c LEMON_ASSERT_ABORT The failed assertion prints a short log message to |
147 /// |
135 /// the standard error and aborts the program. It is the default behaviour. |
148 /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log |
|
149 /// message to the standard error and continues the execution. |
|
150 /// - \c LEMON_ASSERT_ABORT This mode is similar to the \c |
|
151 /// LEMON_ASSERT_LOG, but it aborts the program. It is the default |
|
152 /// behaviour. |
|
153 /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler |
136 /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler |
154 /// function. |
137 /// function. |
155 /// \code |
138 /// \code |
156 /// void custom_assert_handler(const char* file, int line, |
139 /// void custom_assert_handler(const char* file, int line, |
157 /// const char* function, const char* message, |
140 /// const char* function, const char* message, |
175 LEMON_FUNCTION_NAME, \ |
158 LEMON_FUNCTION_NAME, \ |
176 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
159 ::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
177 |
160 |
178 /// \ingroup exceptions |
161 /// \ingroup exceptions |
179 /// |
162 /// |
180 /// \brief Macro for mark not yet implemented features. |
|
181 /// |
|
182 /// Macro for mark not yet implemented features and outstanding bugs. |
|
183 /// It is close to be the shortcut of the following code: |
|
184 /// \code |
|
185 /// LEMON_ASSERT(false, msg); |
|
186 /// \endcode |
|
187 /// |
|
188 /// \see LEMON_ASSERT |
|
189 # define LEMON_FIXME(msg) \ |
|
190 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
|
191 ::lemon::_assert_bits::cstringify(msg), \ |
|
192 static_cast<const char*>(0))) |
|
193 |
|
194 /// \ingroup exceptions |
|
195 /// |
|
196 /// \brief Macro for internal assertions |
163 /// \brief Macro for internal assertions |
197 /// |
164 /// |
198 /// Macro for internal assertions, it is used in the library to check |
165 /// Macro for internal assertions, it is used in the library to check |
199 /// the consistency of results of algorithms, several pre- and |
166 /// the consistency of results of algorithms, several pre- and |
200 /// postconditions and invariants. The checking is disabled by |
167 /// postconditions and invariants. The checking is disabled by |
222 |
189 |
223 #else |
190 #else |
224 |
191 |
225 # ifndef LEMON_ASSERT_HANDLER |
192 # ifndef LEMON_ASSERT_HANDLER |
226 # define LEMON_ASSERT(exp, msg) (static_cast<void>(0)) |
193 # define LEMON_ASSERT(exp, msg) (static_cast<void>(0)) |
227 # define LEMON_FIXME(msg) (static_cast<void>(0)) |
|
228 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) |
194 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) |
229 # else |
195 # else |
230 # define LEMON_ASSERT(exp, msg) \ |
196 # define LEMON_ASSERT(exp, msg) \ |
231 (static_cast<void> (!!(exp) ? 0 : ( \ |
197 (static_cast<void> (!!(exp) ? 0 : ( \ |
232 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
198 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
233 LEMON_FUNCTION_NAME, \ |
199 LEMON_FUNCTION_NAME, \ |
234 ::lemon::_assert_bits::cstringify(msg), \ |
200 ::lemon::_assert_bits::cstringify(msg), \ |
235 #exp), 0))) |
201 #exp), 0))) |
236 # define LEMON_FIXME(msg) \ |
|
237 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
|
238 ::lemon::_assert_bits::cstringify(msg), \ |
|
239 static_cast<const char*>(0))) |
|
240 |
|
241 # if LEMON_ENABLE_DEBUG |
202 # if LEMON_ENABLE_DEBUG |
242 # define LEMON_DEBUG(exp, msg) \ |
203 # define LEMON_DEBUG(exp, msg) \ |
243 (static_cast<void> (!!(exp) ? 0 : ( \ |
204 (static_cast<void> (!!(exp) ? 0 : ( \ |
244 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
205 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
245 LEMON_FUNCTION_NAME, \ |
206 LEMON_FUNCTION_NAME, \ |