source: tags/svn.1.5.4/ARBDB/arb_assert.h

Last change on this file was 7669, checked in by westram, 14 years ago
  • merge from dev [7638] [7639] [7646] [7645] [7647] [7648] [7649] [7650] [7651] [7652]
    • compatibility with cppcheck 1.49 (assert + ASSERT_RESULT)
    • fixed (AWT and WINDOW)
      • missing const attributes
      • uninitialized/unused/wrong-scoped/useless variables
      • alloc/free/delete mismatches
      • use assertions instead of null-pointer-assignments
    • removed
      • AW_device_Xm fast/slow/fastflag
    • new class AW_scalar
      • can hold any AW_awar-value
        • uses int32_t (AW_awar is based on GB_INT which is 32 bit)
      • knows its type
      • use in
        • AW_option_struct / AW_toggle_struct (both classes were identical → replaced them by new class AW_widget_value_pair)
        • in AW_variable_update_struct (now VarUpdateInfo)
        • in AW_select_table_struct (now AW_selection_list_entry)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/*  ====================================================================
2
3    File      : arb_assert.h
4    Purpose   : Global assert macro
5
6
7  Coded by Ralf Westram (coder@reallysoft.de) in August 2002
8  Copyright Department of Microbiology (Technical University Munich)
9
10  Visit our web site at: http://www.arb-home.de/
11
12
13  ==================================================================== */
14
15#ifndef ARB_ASSERT_H
16#define ARB_ASSERT_H
17
18// [WhyIncludeHere]
19// need to include all headers needed for unit-tests here [sic]
20// if only included inside test_global.h, developing with active unit-tests
21// will always break non-unit-test-builds.
22
23#ifndef _STDARG_H
24#include <stdarg.h>
25#endif
26#ifndef _STDIO_H
27#include <stdio.h>
28#endif
29#ifndef _STDLIB_H
30#include <stdlib.h>
31#endif
32#ifndef _ERRNO_H
33#include <errno.h>
34#endif
35#ifndef _STRING_H
36#include <string.h>
37#endif
38
39/* ------------------------------------------------------------
40 * Define SIMPLE_ARB_ASSERT before including this header
41 * to avoid ARBDB dependency!
42 *
43 * ASSERT_CRASH                 if assert fails debugger stops at assert macro
44 * ASSERT_BACKTRACE_AND_CRASH   like ASSERT_CRASH - with backtrace
45 * ASSERT_ERROR                 assert prints an error and ARB exits
46 * ASSERT_PRINT                 assert prints a message (anyway) and ARB continues
47 * ASSERT_NONE                  assertions inactive
48 *
49 * ------------------------------------------------------------ */
50
51// check correct definition of DEBUG/NDEBUG
52#ifndef NDEBUG
53# ifndef DEBUG
54#  error Neither DEBUG nor NDEBUG is defined!
55# endif
56#else
57# ifdef DEBUG
58#  error Both DEBUG and NDEBUG are defined - only one should be!
59# endif
60#endif
61
62#ifdef arb_assert
63#error arb_assert already defined
64#endif
65
66// only use ONE of the following ASSERT_xxx defines :
67
68#if defined(DEBUG) && !defined(DEVEL_RELEASE)
69
70// assert that raises SIGSEGV (recommended for DEBUG version!)
71// # define ASSERT_CRASH
72# define ASSERT_BACKTRACE_AND_CRASH
73// test if a bug has to do with assertion code
74// # define ASSERT_NONE
75
76#else
77
78// no assert (recommended for final version!)
79# define ASSERT_NONE
80// assert as error in final version (allows basic debugging of NDEBUG version)
81// # define ASSERT_ERROR
82// assert as print in final version (allows basic debugging of NDEBUG version)
83// # define ASSERT_PRINT
84
85#endif
86
87// ------------------------------------------------------------
88
89#if defined(__cplusplus)
90inline void provoke_core_dump() {
91    // cppcheck-suppress nullPointer
92    *(int*)0 = 0;
93}
94#else // !defined(__cplusplus)
95#define provoke_core_dump() do { *(int*)0 = 0; } while(0)
96#endif
97
98// ------------------------------------------------------------
99
100#if defined(SIMPLE_ARB_ASSERT)
101
102// code here is independent from ARBDB!
103
104#define ARB_SIGSEGV(backtrace) do {                             \
105        provoke_core_dump();                                    \
106    } while (0)
107
108#ifndef ASSERT_NONE
109# define arb_assert(cond)                                               \
110    do {                                                                \
111        if (!(cond)) {                                                  \
112            fprintf(stderr, "Assertion '%s' failed in '%s' #%i\n",      \
113                    #cond, __FILE__, __LINE__);                         \
114            provoke_core_dump();                                        \
115        }                                                               \
116    } while (0)
117#endif
118
119
120// ------------------------------------------------------------
121
122#else
123
124/* Provoke a SIGSEGV (which will stop the debugger or terminated the application)
125 * Do backtrace manually here and uninstall SIGSEGV-handler
126 * (done because automatic backtrace on SIGSEGV lacks name of current function)
127 */
128
129#ifndef ARB_CORE_H
130#include <arb_core.h>
131#endif
132
133#define ARB_SIGSEGV(backtrace) do {                             \
134        if (backtrace) GBK_dump_backtrace(NULL, "ARB_SIGSEGV"); \
135        GBK_install_SIGSEGV_handler(false);                     \
136        provoke_core_dump();                                    \
137    } while (0)
138
139
140# define arb_assert_crash(cond)                 \
141    do {                                        \
142        if (!(cond)) ARB_SIGSEGV(0);            \
143    } while (0)
144
145# define arb_assert_backtrace_and_crash(cond)                           \
146    do {                                                                \
147        if (!(cond)) {                                                  \
148            fputs(GBK_assert_msg(#cond, __FILE__, __LINE__), stderr);   \
149            fflush(stderr);                                             \
150            ARB_SIGSEGV(1);                                             \
151        }                                                               \
152    } while (0)
153
154#ifdef ASSERT_CRASH
155# define arb_assert(cond) arb_assert_crash(cond)
156#endif
157
158#ifdef ASSERT_BACKTRACE_AND_CRASH
159# define arb_assert(cond) arb_assert_backtrace_and_crash(cond)
160#endif
161
162#ifdef ASSERT_ERROR
163# define arb_assert(cond) assert_or_exit(cond)
164#endif
165
166#ifdef ASSERT_PRINT
167# define arb_assert(cond)                                               \
168    do {                                                                \
169        fprintf(stderr, "at %s #%i\n", __FILE__, __LINE__);             \
170        if (!(cond)) fprintf(stderr, "assertion '%s' failed!\n", #cond); \
171        fflush(stderr);                                                 \
172    } while (0)
173#endif
174
175#endif // SIMPLE_ARB_ASSERT
176
177// ------------------------------------------------------------
178
179#ifdef ASSERT_NONE
180# define arb_assert(cond)
181#else
182# define ASSERTION_USED
183#endif
184
185#undef ASSERT_CRASH
186#undef ASSERT_BACKTRACE_AND_CRASH
187#undef ASSERT_ERROR
188#undef ASSERT_PRINT
189#undef ASSERT_NONE
190
191#ifndef arb_assert
192# error arb_assert has not been defined -- check ASSERT_xxx definitions
193#endif
194
195#if !defined(SIMPLE_ARB_ASSERT)
196#define assert_or_exit(cond)                                            \
197    do {                                                                \
198        if (!(cond)) {                                                  \
199            GBK_terminate(GBK_assert_msg(#cond, __FILE__, __LINE__));   \
200        }                                                               \
201    } while (0)
202#endif // SIMPLE_ARB_ASSERT
203
204// ------------------------------------------------------------
205
206#ifdef UNIT_TESTS
207#ifndef TEST_GLOBAL_H
208#include <test_global.h> // overrides arb_assert()!
209#endif
210#else
211#define RUNNING_TEST() false
212#endif
213
214// ------------------------------------------------------------
215// logical operators (mostly used for assertions)
216
217// Note: 'conclusion' is not evaluated if 'hypothesis' is wrong!
218#define implicated(hypothesis,conclusion) (!(hypothesis) || !!(conclusion))
219
220#ifdef __cplusplus
221inline bool correlated(bool hypo1, bool hypo2) { return implicated(hypo1, hypo2) == implicated(hypo2, hypo1); } // equivalence!
222inline bool contradicted(bool hypo1, bool hypo2) { return !correlated(hypo1, hypo2); } // non-equivalence!
223#endif
224
225// ------------------------------------------------------------
226// use the following macros for parameters etc. only appearing in one version
227
228#ifdef DEBUG
229# define IF_DEBUG(x) x
230# define IF_NDEBUG(x)
231#else
232# define IF_DEBUG(x)
233# define IF_NDEBUG(x) x
234#endif
235
236#ifdef ASSERTION_USED
237# define IF_ASSERTION_USED(x) x
238#else
239# define IF_ASSERTION_USED(x)
240#endif
241
242// ------------------------------------------------------------
243// Assert specific result in DEBUG and silence __ATTR__USERESULT warnings in NDEBUG.
244//
245// The value 'Expected' (or 'Limit') should be side-effect-free (it is only executed in DEBUG mode).
246// The given 'Expr' is evaluated under all conditions!
247//
248// Important note:
249//      When you swap 'Expected' and 'Expr' by mistake,
250//      code working in DEBUG, may suddenly stop working in NDEBUG!
251
252#ifdef ASSERTION_USED
253
254# define ASSERT_RESULT(Type, Expected, Expr) do {       \
255        Type value = (Expr);                            \
256        arb_assert(value == (Expected));                \
257    } while (0)
258
259# define ASSERT_RESULT_PREDICATE(Pred, Expr) do {       \
260        arb_assert(Pred(Expr));                         \
261    } while (0)
262
263#else
264
265# define ASSERT_RESULT(Type, Expected, Expr) do {       \
266        (void)Expr;                                     \
267    } while(0)
268
269# define ASSERT_RESULT_PREDICATE(Pred, Expr) do {       \
270        (void)Expr;                                     \
271    } while(0)
272
273#endif
274
275#define ASSERT_NULL_RESULT(ptrExpr) ASSERT_RESULT(const void*, NULL, ptrExpr)
276#define ASSERT_NO_ERROR(errorExpr)  ASSERT_RESULT(GB_ERROR, NULL, errorExpr)
277
278#define ASSERT_TRUE(boolExpr)  ASSERT_RESULT(bool, true, boolExpr)
279#define ASSERT_FALSE(boolExpr) ASSERT_RESULT(bool, false, boolExpr)
280
281// ------------------------------------------------------------
282// UNCOVERED is used to document/test missing test coverage
283// see ../INCLUDE/test_global.h@UNCOVERED
284
285#ifndef UNCOVERED
286#define UNCOVERED()
287#endif
288
289// ------------------------------------------------------------
290
291#ifdef DEVEL_RELEASE
292# ifdef ASSERTION_USED
293#  error Assertions enabled in release
294# endif
295#endif
296
297// ------------------------------------------------------------
298
299#if !defined(SIMPLE_ARB_ASSERT)
300#ifndef ARB_CORE_H
301#include <arb_core.h>
302#endif
303#endif // SIMPLE_ARB_ASSERT
304
305#else
306#error arb_assert.h included twice
307#endif // ARB_ASSERT_H
308
Note: See TracBrowser for help on using the repository browser.