libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
assert.h
Go to the documentation of this file.
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license in the file COPYING
10 * or http://www.opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file COPYING.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2023 Saso Kiselkov. All rights reserved.
24 */
40#ifndef _ACF_UTILS_ASSERT_H_
41#define _ACF_UTILS_ASSERT_H_
42
43#include <assert.h>
44#include <stdlib.h>
45
46#include "log.h"
47#include "sysmacros.h"
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
53#if LIN || APL
54#define LACF_CRASH() abort()
55#else /* !LIN && !APL */
56#define EXCEPTION_ASSERTION_FAILED 0x8000
57#define LACF_CRASH() \
58 do { \
59 RaiseException(EXCEPTION_ASSERTION_FAILED, \
60 EXCEPTION_NONCONTINUABLE, 0, NULL); \
61 /* Needed to avoid no-return-value warnings */ \
62 abort(); \
63 } while (0)
64#endif /* !LIN && !APL */
65
78#define VERIFY(x) VERIFY_MSG(x, "%s", "")
79
91#define VERIFY_MSG(x, fmt, ...) \
92 do { \
93 if (COND_UNLIKELY(!(x))) { \
94 log_impl(log_basename(__FILE__), __LINE__, \
95 "assertion \"%s\" failed: " fmt, #x, __VA_ARGS__); \
96 LACF_CRASH(); \
97 } \
98 } while (0)
99
100#define VERIFY3_impl(x, op, y, type, fmt) \
101 do { \
102 type tmp_x = (type)(x); \
103 type tmp_y = (type)(y); \
104 if (COND_UNLIKELY(!(tmp_x op tmp_y))) { \
105 log_impl(log_basename(__FILE__), __LINE__, \
106 "assertion %s %s %s failed (" fmt " %s " \
107 fmt ")", #x, #op, #y, tmp_x, #op, tmp_y); \
108 LACF_CRASH(); \
109 } \
110 } while (0)
125#define VERIFY3S(x, op, y) VERIFY3_impl(x, op, y, long, "%lu")
126
132#if IBM
133#define VERIFY3U(x, op, y) \
134 VERIFY3_impl(x, op, y, unsigned long long, "0x%I64x")
135#else /* !IBM */
136#define VERIFY3U(x, op, y) \
137 VERIFY3_impl(x, op, y, unsigned long long, "0x%llx")
138#endif /* !IBM */
139
144#define VERIFY3F(x, op, y) VERIFY3_impl(x, op, y, double, "%f")
149#define VERIFY3P(x, op, y) VERIFY3_impl(x, op, y, void *, "%p")
154#define VERIFY0(x) VERIFY3S((x), ==, 0)
160#define VERIFY_FAIL() \
161 do { \
162 log_impl(log_basename(__FILE__), __LINE__, "Internal error"); \
163 LACF_CRASH(); \
164 } while (0)
165
183#ifdef DEBUG
184#define ASSERT(x) VERIFY(x)
185#define ASSERT3S(x, op, y) VERIFY3S(x, op, y)
186#define ASSERT3U(x, op, y) VERIFY3U(x, op, y)
187#define ASSERT3F(x, op, y) VERIFY3F(x, op, y)
188#define ASSERT3P(x, op, y) VERIFY3P(x, op, y)
189#define ASSERT0(x) VERIFY0(x)
190#define ASSERT_MSG(x, fmt, ...) VERIFY_MSG(x, fmt, __VA_ARGS__)
191#elif __STDC_VERSION__ >= 202311L
192/*
193 * Invoking the condition without checking can still end up compiling code.
194 * That's less than ideal, as it still ends up having a runtime cost. In
195 * C23, we have a native [[maybe_unused]] attribute, as well as our own
196 * generic UNUSED_ATTR substitute. You should really just use those to mark
197 * anything used by an ASSERT macro only as potentially unused, thus removing
198 * any runtime cost of disabled ASSERTs.
199 */
200#define ASSERT(x)
201#define ASSERT3S(x, op, y)
202#define ASSERT3U(x, op, y)
203#define ASSERT3F(x, op, y)
204#define ASSERT3P(x, op, y)
205#define ASSERT0(x)
206#define ASSERT_MSG(x, fmt, ...)
207#else /* !(__STDC_VERSION >= 202311L) */
208#define ASSERT(x) LACF_UNUSED(x)
209#define ASSERT3S(x, op, y) do { LACF_UNUSED(x); LACF_UNUSED(y); } while (0)
210#define ASSERT3U(x, op, y) do { LACF_UNUSED(x); LACF_UNUSED(y); } while (0)
211#define ASSERT3F(x, op, y) do { LACF_UNUSED(x); LACF_UNUSED(y); } while (0)
212#define ASSERT3P(x, op, y) do { LACF_UNUSED(x); LACF_UNUSED(y); } while (0)
213#define ASSERT0(x) LACF_UNUSED(x)
214#define ASSERT_MSG(x, fmt, ...) LACF_UNUSED(x)
215#endif /* !(__STDC_VERSION >= 202311L) */
216
217#ifdef __cplusplus
218}
219#endif
220
221#endif /* _ACF_UTILS_ASSERT_H_ */