C/C++ Library, mos@ua 1.0
cpplib-mos
dbc.h
Go to the documentation of this file.
1
37#ifndef DBC_H
38#define DBC_H
39
40#include <stdio.h>
41#include <stdlib.h>
42#include <assert.h>
43#include "hdp.h"
44#include "utils.h"
45
50#define PRECONDITION_ERROR 0xF000001 // much bigger than maximum errno error value
51
56#define POSTCONDITION_ERROR 0xF000002
57
63#define INVARIANT_ERROR 0xF000003
68#define CHECK_ERROR 0xF000004
69
70#define MAX_DBC_ERROR_MESSAGE 255
71
76typedef struct {
77 int err;
78 char msg[MAX_DBC_ERROR_MESSAGE+1];
79} DbC_Error;
80
81#ifdef NDEBUG
82#define NDEBUG_CHECKS
83#define NDEBUG_PRECONDITIONS
84#define NDEBUG_POSTCONDITIONS
85#define NDEBUG_INVARIANTS
86#endif
87
88#ifdef DEBUG_ONLY_PRECONDITIONS
89#ifdef NDEBUG_PRECONDITIONS
90#undef NDEBUG_PRECONDITIONS
91#endif
92#ifndef NDEBUG_CHECKS
93#define NDEBUG_CHECKS
94#endif
95#ifndef NDEBUG_POSTCONDITIONS
96#define NDEBUG_POSTCONDITIONS
97#endif
98#ifndef NDEBUG_INVARIANTS
99#define NDEBUG_INVARIANTS
100#endif
101#endif
102
103// check:
104#ifdef NDEBUG_CHECKS
105#define check(condition, message)
106#else
107#if defined __cplusplus && defined EXCEPTION_POLICY
108#define check(condition, message) \
109 ({ \
110 if (!(condition)) { \
111 DbC_Error *e = (DbC_Error*)Nu(malloc(sizeof(DbC_Error))); \
112 e->err = CHECK_ERROR; \
113 strcpy(e->msg, concat_12str((char*)"Assertion fail", message[0] ? (char*)": " : (char*)"", message, (char*)", assertion: \"", #condition, (char*)"\", function: \"", __func__, (char*)"\":", int2str(__LINE__), (char*)", file: \"", __FILE__, (char*)"\"")); \
114 throw e; \
115 } \
116 })
117#else // EXIT_POLICY (default)
127#define check(condition, message) \
128 if (!(condition)) \
129 do { \
130 fprintf (stderr, "Assertion fail%s%s, assertion: \"%s\", function: \"%s\":%d, file: \"%s\"\n", \
131 message[0] ? ": " : "", message, #condition, __func__, __LINE__ , __FILE__); \
132 *((int*)0) = 0; \
133 abort (); \
134 } while (0)
135#endif
136#endif
137
138
139// precondition:
140#ifdef NDEBUG_PRECONDITIONS
141#define require(condition, message)
142#else
143#if defined __cplusplus && defined EXCEPTION_POLICY
144#define require(condition, message) \
145 ({ \
146 if (!(condition)) { \
147 DbC_Error *e = (DbC_Error*)Nu(malloc(sizeof(DbC_Error))); \
148 e->err = PRECONDITION_ERROR; \
149 strcpy(e->msg, concat_12str((char*)"Precondition fail", message[0] ? (char*)": " : (char*)"", message, (char*)", assertion: \"", #condition, (char*)"\", function: \"", __func__, (char*)"\":", int2str(__LINE__), (char*)", file: \"", __FILE__, (char*)"\"")); \
150 throw e; \
151 } \
152 })
153#else // EXIT_POLICY (default)
163#define require(condition, message) \
164 if (!(condition)) \
165 do { \
166 fprintf (stderr, "Precondition fail%s%s, assertion: \"%s\", function: \"%s\":%d, file: \"%s\"\n", \
167 message[0] ? ": " : "", message, #condition, __func__, __LINE__ , __FILE__); \
168 *((int*)0) = 0; \
169 abort (); \
170 } while (0)
171#endif
172#endif
173
174
175// postcondition:
176#ifdef NDEBUG_POSTCONDITIONS
177#define ensure(condition, message)
178#else
179#if defined __cplusplus && defined EXCEPTION_POLICY
180#define ensure(condition, message) \
181 ({ \
182 if (!(condition)) { \
183 DbC_Error *e = (DbC_Error*)Nu(malloc(sizeof(DbC_Error))); \
184 e->err = POSTCONDITION_ERROR; \
185 strcpy(e->msg, concat_12str((char*)"Postcondition fail", message[0] ? (char*)": " : (char*)"", message, (char*)", assertion: \"", #condition, (char*)"\", function: \"", __func__, (char*)"\":", int2str(__LINE__), (char*)", file: \"", __FILE__, (char*)"\"")); \
186 throw e; \
187 } \
188 })
189#else // EXIT_POLICY (default)
199#define ensure(condition, message) \
200 if (!(condition)) \
201 do { \
202 fprintf (stderr, "Postcondition fail%s%s, assertion: \"%s\", function: \"%s\":%d, file: \"%s\"\n", \
203 message[0] ? ": " : "", message, #condition, __func__, __LINE__ , __FILE__); \
204 *((int*)0) = 0; \
205 abort (); \
206 } while (0)
207#endif
208#endif
209
210//
211// invariant:
212#ifdef NDEBUG_INVARIANTS
213#define invariant(condition, message)
214#else
215#if defined __cplusplus && defined EXCEPTION_POLICY
216#define invariant(condition, message) \
217 ({ \
218 if (!(condition)) { \
219 DbC_Error *e = (DbC_Error*)Nu(malloc(sizeof(DbC_Error))); \
220 e->err = INVARIANT_ERROR; \
221 strcpy(e->msg, concat_12str((char*)"Invariant fail", message[0] ? (char*)": " : (char*)"", message, (char*)", assertion: \"", #condition, (char*)"\", function: \"", __func__, (char*)"\":", int2str(__LINE__), (char*)", file: \"", __FILE__, (char*)"\"")); \
222 throw e; \
223 } \
224 })
225#else // EXIT_POLICY (default)
235#define invariant(condition, message) \
236 if (!(condition)) \
237 do { \
238 fprintf (stderr, "Invariant fail%s%s, assertion: \"%s\", function: \"%s\":%d, file: \"%s\"\n", \
239 message[0] ? ": " : "", message, #condition, __func__, __LINE__ , __FILE__); \
240 *((int*)0) = 0; \
241 abort (); \
242 } while (0)
243#endif
244#endif
245
254#define IS_DbC_ERROR(e) ((e) >= PRECONDITION_ERROR && (e) <= CHECK_ERROR)
255
264#define DbC_ERROR_2_STR(e) \
265 ({ \
266 char*res = (char*)""; \
267 switch(e) { \
268 case PRECONDITION_ERROR: \
269 res = (char*)"PRECONDITION_ERROR"; \
270 break; \
271 case POSTCONDITION_ERROR: \
272 res = (char*)"POSTCONDITION_ERROR"; \
273 break; \
274 case INVARIANT_ERROR: \
275 res = (char*)"INVARIANT_ERROR"; \
276 break; \
277 case CHECK_ERROR: \
278 res = (char*)"CHECK_ERROR"; \
279 break; \
280 } \
281 res; \
282 })
283
284#endif
285
354//#define CATCH_DBC
355//#define CATCH_ALL
356
357#if defined __cplusplus && defined EXCEPTION_POLICY
358#define rescue_retry \
359 __body_start_label__: \
360 try {
361
362#ifdef CATCH_ALL
363#define rescue_begin \
364 } \
365 catch(...) {
366#else
367#define rescue_begin \
368 } \
369 catch(DbC_Error* e) {
370#endif
371
372#define rescue_end \
373 throw; \
374 }
375
376#define retry \
377 goto __body_start_label__;
378#else
379//#warning "Only avaliable in C++ with EXCEPTION_POLICY"
384#define rescue_retry \
385 _Pragma("GCC warning \"Only avaliable in C++ with EXCEPTION_POLICY\"")
386
391#define rescue_begin \
392 _Pragma("GCC warning \"Only avaliable in C++ with EXCEPTION_POLICY\"")
393
398#define rescue_end
399
404#define retry \
405 _Pragma("GCC warning \"Only avaliable in C++ with EXCEPTION_POLICY\"")
406#endif
407
408/* ************************************************** */
412/* ************************************************** */
413
414/* ************************************************** */
418/* ************************************************** */
419
Handle Defensive Programming module.
DbC exceptions throw a pointer to this structure.
Definition dbc.h:76
Useful common functions and macros.