summaryrefslogtreecommitdiffstats
path: root/src/lib/kStuff/include/k/kHlpAssert.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/kStuff/include/k/kHlpAssert.h')
-rw-r--r--src/lib/kStuff/include/k/kHlpAssert.h369
1 files changed, 369 insertions, 0 deletions
diff --git a/src/lib/kStuff/include/k/kHlpAssert.h b/src/lib/kStuff/include/k/kHlpAssert.h
new file mode 100644
index 0000000..45105d1
--- /dev/null
+++ b/src/lib/kStuff/include/k/kHlpAssert.h
@@ -0,0 +1,369 @@
+/* $Id: kHlpAssert.h 119 2021-12-19 13:01:47Z bird $ */
+/** @file
+ * kHlpAssert - Assertion Macros.
+ */
+
+/*
+ * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef ___kHlpAssert_h___
+#define ___kHlpAssert_h___
+
+#include <k/kHlpDefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup grp_kHlpAssert - Assertion Macros
+ * @addtogroup grp_kHlp
+ * @{ */
+
+/** @def K_STRICT
+ * Assertions are enabled when K_STRICT is \#defined. */
+
+/** @def kHlpAssertBreakpoint
+ * Emits a breakpoint instruction or somehow triggers a debugger breakpoint.
+ */
+#ifdef _MSC_VER
+# define kHlpAssertBreakpoint() do { __debugbreak(); } while (0)
+#elif defined(__GNUC__) && K_OS == K_OS_SOLARIS && (K_ARCH == K_ARCH_AMD64 || K_ARCH == K_ARCH_X86_32)
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("int $3"); } while (0)
+#elif defined(__GNUC__) && (K_ARCH == K_ARCH_AMD64 || K_ARCH == K_ARCH_X86_32 || K_ARCH == K_ARCH_X86_16)
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("int3"); } while (0)
+#elif defined(__GNUC__) && (K_ARCH == K_ARCH_ARM_64 || K_ARCH == K_ARCH_ARM_32) /* probably not supported by older ARM CPUs */
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("brk #0x1"); } while (0)
+#elif defined(__GNUC__) && (K_ARCH == K_ARCH_SPARC_32)
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("unimp 0"); } while (0) /*??*/
+#elif defined(__GNUC__) && (K_ARCH == K_ARCH_SPARC_64)
+# define kHlpAssertBreakpoint() do { __asm__ __volatile__ ("illtrap 0"); } while (0) /*??*/
+#else
+# error "Port Me"
+#endif
+
+/** @def K_FUNCTION
+ * Undecorated function name macro expanded by the compiler.
+ */
+#if defined(__GNUC__)
+# define K_FUNCTION __func__
+#else
+# define K_FUNCTION __FUNCTION__
+#endif
+
+#ifdef K_STRICT
+
+# define kHlpAssert(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ } \
+ } while (0)
+
+# define kHlpAssertStmt(expr, stmt) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } \
+ } while (0)
+
+# define kHlpAssertReturn(expr, rcRet) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } \
+ } while (0)
+
+# define kHlpAssertStmtReturn(expr, stmt, rcRet) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } \
+ } while (0)
+
+# define kHlpAssertReturnVoid(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } \
+ } while (0)
+
+# define kHlpAssertStmtReturnVoid(expr, stmt) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } \
+ } while (0)
+
+# define kHlpAssertMsg(expr, msg) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgStmt(expr, msg, stmt) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgReturn(expr, msg, rcRet) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgStmtReturn(expr, msg, stmt, rcRet) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgReturnVoid(expr, msg) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } \
+ } while (0)
+
+# define kHlpAssertMsgStmtReturnVoid(expr, msg, stmt) \
+ do { \
+ if (!(expr)) \
+ { \
+ kHlpAssertMsg1(#expr, __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } \
+ } while (0)
+
+/* Same as above, only no expression. */
+
+# define kHlpAssertFailed() \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ } while (0)
+
+# define kHlpAssertFailedStmt(stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } while (0)
+
+# define kHlpAssertFailedReturn(rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertFailedStmtReturn(stmt, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertFailedReturnVoid() \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } while (0)
+
+# define kHlpAssertFailedStmtReturnVoid(stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } while (0)
+
+# define kHlpAssertMsgFailed(msg) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmt(msg, stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } while (0)
+
+# define kHlpAssertMsgFailedReturn(msg, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertMsgFailedReturnVoid(msg) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } while (0)
+
+
+#else /* !K_STRICT */
+
+# define kHlpAssert(expr) do { } while (0)
+# define kHlpAssertStmt(expr, stmt) do { if (!(expr)) { stmt; } } while (0)
+# define kHlpAssertReturn(expr, rcRet) do { if (!(expr)) return (rcRet); } while (0)
+# define kHlpAssertStmtReturn(expr, stmt, rcRet) do { if (!(expr)) { stmt; return (rcRet); } } while (0)
+# define kHlpAssertReturnVoid(expr) do { if (!(expr)) return; } while (0)
+# define kHlpAssertStmtReturnVoid(expr, stmt) do { if (!(expr)) { stmt; return; } } while (0)
+# define kHlpAssertMsg(expr, msg) do { } while (0)
+# define kHlpAssertMsgStmt(expr, msg, stmt) do { if (!(expr)) { stmt; } } while (0)
+# define kHlpAssertMsgReturn(expr, msg, rcRet) do { if (!(expr)) return (rcRet); } while (0)
+# define kHlpAssertMsgStmtReturn(expr, msg, stmt, rcRet) do { if (!(expr)) { stmt; return (rcRet); } } while (0)
+# define kHlpAssertMsgReturnVoid(expr, msg) do { if (!(expr)) return; } while (0)
+# define kHlpAssertMsgStmtReturnVoid(expr, msg, stmt) do { if (!(expr)) { stmt; return; } } while (0)
+/* Same as above, only no expression: */
+# define kHlpAssertFailed() do { } while (0)
+# define kHlpAssertFailedStmt(stmt) do { stmt; } while (0)
+# define kHlpAssertFailedReturn(rcRet) do { return (rcRet); } while (0)
+# define kHlpAssertFailedStmtReturn(stmt, rcRet) do { stmt; return (rcRet); } while (0)
+# define kHlpAssertFailedReturnVoid() do { return; } while (0)
+# define kHlpAssertFailedStmtReturnVoid(stmt) do { stmt; return; } while (0)
+# define kHlpAssertMsgFailed(msg) do { } while (0)
+# define kHlpAssertMsgFailedStmt(msg, stmt) do { stmt; } while (0)
+# define kHlpAssertMsgFailedReturn(msg, rcRet) do { return (rcRet); } while (0)
+# define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) do { { stmt; return (rcRet); } } while (0)
+# define kHlpAssertMsgFailedReturnVoid(msg) do { return; } while (0)
+# define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) do { stmt; return; } while (0)
+
+#endif /* !K_STRICT */
+
+#define kHlpAssertPtr(ptr) kHlpAssertMsg(K_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr)))
+#define kHlpAssertPtrReturn(ptr, rcRet) kHlpAssertMsgReturn(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
+#define kHlpAssertPtrReturn(ptr, rcRet) kHlpAssertMsgReturn(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
+#define kHlpAssertPtrReturnVoid(ptr) kHlpAssertMsgReturnVoid(K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)))
+#define kHlpAssertPtrNull(ptr) kHlpAssertMsg(!(ptr) || K_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr)))
+#define kHlpAssertPtrNullReturn(ptr, rcRet) kHlpAssertMsgReturn(!(ptr) || K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)), (rcRet))
+#define kHlpAssertPtrNullReturnVoid(ptr) kHlpAssertMsgReturnVoid(!(ptr) || K_VALID_PTR(ptr), ("%s = %p -> %d\n", #ptr, (ptr), (rcRet)))
+#define kHlpAssertRC(rc) kHlpAssertMsg((rc) == 0, ("%s = %d\n", #rc, (rc)))
+#define kHlpAssertRCReturn(rc, rcRet) kHlpAssertMsgReturn((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)), (rcRet))
+#define kHlpAssertRCReturnVoid(rc) kHlpAssertMsgReturnVoid((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)))
+
+
+/**
+ * Helper function that displays the first part of the assertion message.
+ *
+ * @param pszExpr The expression.
+ * @param pszFile The file name.
+ * @param iLine The line number is the file.
+ * @param pszFunction The function name.
+ * @internal
+ */
+KHLP_DECL(void) kHlpAssertMsg1(const char *pszExpr, const char *pszFile, unsigned iLine, const char *pszFunction);
+
+/**
+ * Helper function that displays custom assert message.
+ *
+ * @param pszFormat Format string that get passed to vprintf.
+ * @param ... Format arguments.
+ * @internal
+ */
+KHLP_DECL(void) kHlpAssertMsg2(const char *pszFormat, ...);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif