source: trunk/include/k/kHlpAssert.h@ 105

Last change on this file since 105 was 101, checked in by bird, 8 years ago

kHlpAssert.h: Workaround for buggy gcc7+ warnings. The fall thru warnings of gcc7+ thinks we can avoid if (!0) expressions in kHlpAssert* macors and issues misleading warnings. So, duplicate the macros for the kAssert*Failed* variations and drop the conditional, hoping that gcc gets it now.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 12.2 KB
Line 
1/* $Id: kHlpAssert.h 101 2017-10-02 10:37:39Z bird $ */
2/** @file
3 * kHlpAssert - Assertion Macros.
4 */
5
6/*
7 * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31#ifndef ___kHlpAssert_h___
32#define ___kHlpAssert_h___
33
34#include <k/kHlpDefs.h>
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40/** @defgroup grp_kHlpAssert - Assertion Macros
41 * @addtogroup grp_kHlp
42 * @{ */
43
44/** @def K_STRICT
45 * Assertions are enabled when K_STRICT is \#defined. */
46
47/** @def kHlpAssertBreakpoint
48 * Emits a breakpoint instruction or somehow triggers a debugger breakpoint.
49 */
50#ifdef _MSC_VER
51# define kHlpAssertBreakpoint() do { __debugbreak(); } while (0)
52#elif defined(__GNUC__) && K_OS == K_OS_SOLARIS && (K_ARCH == K_ARCH_AMD64 || K_ARCH == K_ARCH_X86_32)
53# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("int $3"); } while (0)
54#elif defined(__GNUC__) && (K_ARCH == K_ARCH_AMD64 || K_ARCH == K_ARCH_X86_32 || K_ARCH == K_ARCH_X86_16)
55# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("int3"); } while (0)
56#else
57# error "Port Me"
58#endif
59
60/** @def K_FUNCTION
61 * Undecorated function name macro expanded by the compiler.
62 */
63#if defined(__GNUC__)
64# define K_FUNCTION __func__
65#else
66# define K_FUNCTION __FUNCTION__
67#endif
68
69#ifdef K_STRICT
70
71# define kHlpAssert(expr) \
72 do { \
73 if (!(expr)) \
74 { \
75 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
76 kHlpAssertBreakpoint(); \
77 } \
78 } while (0)
79
80# define kHlpAssertStmt(expr, stmt) \
81 do { \
82 if (!(expr)) \
83 { \
84 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
85 kHlpAssertBreakpoint(); \
86 stmt; \
87 } \
88 } while (0)
89
90# define kHlpAssertReturn(expr, rcRet) \
91 do { \
92 if (!(expr)) \
93 { \
94 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
95 kHlpAssertBreakpoint(); \
96 return (rcRet); \
97 } \
98 } while (0)
99
100# define kHlpAssertStmtReturn(expr, stmt, rcRet) \
101 do { \
102 if (!(expr)) \
103 { \
104 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
105 kHlpAssertBreakpoint(); \
106 stmt; \
107 return (rcRet); \
108 } \
109 } while (0)
110
111# define kHlpAssertReturnVoid(expr) \
112 do { \
113 if (!(expr)) \
114 { \
115 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
116 kHlpAssertBreakpoint(); \
117 return; \
118 } \
119 } while (0)
120
121# define kHlpAssertStmtReturnVoid(expr, stmt) \
122 do { \
123 if (!(expr)) \
124 { \
125 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
126 kHlpAssertBreakpoint(); \
127 stmt; \
128 return; \
129 } \
130 } while (0)
131
132# define kHlpAssertMsg(expr, msg) \
133 do { \
134 if (!(expr)) \
135 { \
136 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
137 kHlpAssertMsg2 msg; \
138 kHlpAssertBreakpoint(); \
139 } \
140 } while (0)
141
142# define kHlpAssertMsgStmt(expr, msg, stmt) \
143 do { \
144 if (!(expr)) \
145 { \
146 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
147 kHlpAssertMsg2 msg; \
148 kHlpAssertBreakpoint(); \
149 stmt; \
150 } \
151 } while (0)
152
153# define kHlpAssertMsgReturn(expr, msg, rcRet) \
154 do { \
155 if (!(expr)) \
156 { \
157 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
158 kHlpAssertMsg2 msg; \
159 kHlpAssertBreakpoint(); \
160 return (rcRet); \
161 } \
162 } while (0)
163
164# define kHlpAssertMsgStmtReturn(expr, msg, stmt, rcRet) \
165 do { \
166 if (!(expr)) \
167 { \
168 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
169 kHlpAssertMsg2 msg; \
170 kHlpAssertBreakpoint(); \
171 stmt; \
172 return (rcRet); \
173 } \
174 } while (0)
175
176# define kHlpAssertMsgReturnVoid(expr, msg) \
177 do { \
178 if (!(expr)) \
179 { \
180 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
181 kHlpAssertMsg2 msg; \
182 kHlpAssertBreakpoint(); \
183 return; \
184 } \
185 } while (0)
186
187# define kHlpAssertMsgStmtReturnVoid(expr, msg, stmt) \
188 do { \
189 if (!(expr)) \
190 { \
191 kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
192 kHlpAssertMsg2 msg; \
193 kHlpAssertBreakpoint(); \
194 stmt; \
195 return; \
196 } \
197 } while (0)
198
199/* Same as above, only no expression. */
200
201# define kHlpAssertFailed() \
202 do { \
203 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
204 kHlpAssertBreakpoint(); \
205 } while (0)
206
207# define kHlpAssertFailedStmt(stmt) \
208 do { \
209 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
210 kHlpAssertBreakpoint(); \
211 stmt; \
212 } while (0)
213
214# define kHlpAssertFailedReturn(rcRet) \
215 do { \
216 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
217 kHlpAssertBreakpoint(); \
218 return (rcRet); \
219 } while (0)
220
221# define kHlpAssertFailedStmtReturn(stmt, rcRet) \
222 do { \
223 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
224 kHlpAssertBreakpoint(); \
225 stmt; \
226 return (rcRet); \
227 } while (0)
228
229# define kHlpAssertFailedReturnVoid() \
230 do { \
231 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
232 kHlpAssertBreakpoint(); \
233 return; \
234 } while (0)
235
236# define kHlpAssertFailedStmtReturnVoid(stmt) \
237 do { \
238 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
239 kHlpAssertBreakpoint(); \
240 stmt; \
241 return; \
242 } while (0)
243
244# define kHlpAssertMsgFailed(msg) \
245 do { \
246 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
247 kHlpAssertMsg2 msg; \
248 kHlpAssertBreakpoint(); \
249 } while (0)
250
251# define kHlpAssertMsgFailedStmt(msg, stmt) \
252 do { \
253 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
254 kHlpAssertMsg2 msg; \
255 kHlpAssertBreakpoint(); \
256 stmt; \
257 } while (0)
258
259# define kHlpAssertMsgFailedReturn(msg, rcRet) \
260 do { \
261 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
262 kHlpAssertMsg2 msg; \
263 kHlpAssertBreakpoint(); \
264 return (rcRet); \
265 } while (0)
266
267# define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) \
268 do { \
269 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
270 kHlpAssertMsg2 msg; \
271 kHlpAssertBreakpoint(); \
272 stmt; \
273 return (rcRet); \
274 } while (0)
275
276# define kHlpAssertMsgFailedReturnVoid(msg) \
277 do { \
278 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
279 kHlpAssertMsg2 msg; \
280 kHlpAssertBreakpoint(); \
281 return; \
282 } while (0)
283
284# define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) \
285 do { \
286 kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
287 kHlpAssertMsg2 msg; \
288 kHlpAssertBreakpoint(); \
289 stmt; \
290 return; \
291 } while (0)
292
293
294#else /* !K_STRICT */
295
296# define kHlpAssert(expr) do { } while (0)
297# define kHlpAssertStmt(expr, stmt) do { if (!(expr)) { stmt; } } while (0)
298# define kHlpAssertReturn(expr, rcRet) do { if (!(expr)) return (rcRet); } while (0)
299# define kHlpAssertStmtReturn(expr, stmt, rcRet) do { if (!(expr)) { stmt; return (rcRet); } } while (0)
300# define kHlpAssertReturnVoid(expr) do { if (!(expr)) return; } while (0)
301# define kHlpAssertStmtReturnVoid(expr, stmt) do { if (!(expr)) { stmt; return; } } while (0)
302# define kHlpAssertMsg(expr, msg) do { } while (0)
303# define kHlpAssertMsgStmt(expr, msg, stmt) do { if (!(expr)) { stmt; } } while (0)
304# define kHlpAssertMsgReturn(expr, msg, rcRet) do { if (!(expr)) return (rcRet); } while (0)
305# define kHlpAssertMsgStmtReturn(expr, msg, stmt, rcRet) do { if (!(expr)) { stmt; return (rcRet); } } while (0)
306# define kHlpAssertMsgReturnVoid(expr, msg) do { if (!(expr)) return; } while (0)
307# define kHlpAssertMsgStmtReturnVoid(expr, msg, stmt) do { if (!(expr)) { stmt; return; } } while (0)
308/* Same as above, only no expression: */
309# define kHlpAssertFailed() do { } while (0)
310# define kHlpAssertFailedStmt(stmt) do { stmt; } while (0)
311# define kHlpAssertFailedReturn(rcRet) do { return (rcRet); } while (0)
312# define kHlpAssertFailedStmtReturn(stmt, rcRet) do { stmt; return (rcRet); } while (0)
313# define kHlpAssertFailedReturnVoid() do { return; } while (0)
314# define kHlpAssertFailedStmtReturnVoid(stmt) do { stmt; return; } while (0)
315# define kHlpAssertMsgFailed(msg) do { } while (0)
316# define kHlpAssertMsgFailedStmt(msg, stmt) do { stmt; } while (0)
317# define kHlpAssertMsgFailedReturn(msg, rcRet) do { return (rcRet); } while (0)
318# define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) do { { stmt; return (rcRet); } } while (0)
319# define kHlpAssertMsgFailedReturnVoid(msg) do { return; } while (0)
320# define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) do { stmt; return; } while (0)
321
322#endif /* !K_STRICT */
323
324#define kHlpAssertPtr(ptr) kHlpAssertMsg(K_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr)))
325#define kHlpAssertPtrReturn(ptr, rcRet) kHlpAssertMsgReturn(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
326#define kHlpAssertPtrReturn(ptr, rcRet) kHlpAssertMsgReturn(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
327#define kHlpAssertPtrReturnVoid(ptr) kHlpAssertMsgReturnVoid(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)))
328#define kHlpAssertPtrNull(ptr) kHlpAssertMsg(!(ptr) || K_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr)))
329#define kHlpAssertPtrNullReturn(ptr, rcRet) kHlpAssertMsgReturn(!(ptr) || K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
330#define kHlpAssertPtrNullReturnVoid(ptr) kHlpAssertMsgReturnVoid(!(ptr) || K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)))
331#define kHlpAssertRC(rc) kHlpAssertMsg((rc) == 0, ("%s = %d\n", #rc, (rc)))
332#define kHlpAssertRCReturn(rc, rcRet) kHlpAssertMsgReturn((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)), (rcRet))
333#define kHlpAssertRCReturnVoid(rc) kHlpAssertMsgReturnVoid((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)))
334
335
336/**
337 * Helper function that displays the first part of the assertion message.
338 *
339 * @param pszExpr The expression.
340 * @param pszFile The file name.
341 * @param iLine The line number is the file.
342 * @param pszFunction The function name.
343 * @internal
344 */
345KHLP_DECL(void) kHlpAssertMsg1(const char *pszExpr, const char *pszFile, unsigned iLine, const char *pszFunction);
346
347/**
348 * Helper function that displays custom assert message.
349 *
350 * @param pszFormat Format string that get passed to vprintf.
351 * @param ... Format arguments.
352 * @internal
353 */
354KHLP_DECL(void) kHlpAssertMsg2(const char *pszFormat, ...);
355
356
357/** @} */
358
359#ifdef __cplusplus
360}
361#endif
362
363#endif
Note: See TracBrowser for help on using the repository browser.