From e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:34:10 +0200 Subject: Adding upstream version 4.2.2. Signed-off-by: Daniel Baumann --- wsutil/ws_assert.h | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 wsutil/ws_assert.h (limited to 'wsutil/ws_assert.h') diff --git a/wsutil/ws_assert.h b/wsutil/ws_assert.h new file mode 100644 index 0000000..f4880fd --- /dev/null +++ b/wsutil/ws_assert.h @@ -0,0 +1,129 @@ +/** @file + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef __WS_ASSERT_H__ +#define __WS_ASSERT_H__ + +#include +#include +#include +#include +#include +#include + +#if defined(ENABLE_ASSERT) +#define WS_ASSERT_ENABLED 1 +#elif defined(NDEBUG) +#define WS_ASSERT_ENABLED 0 +#else +#define WS_ASSERT_ENABLED 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * We don't want to execute the expression without assertions because + * it might be time and space costly and the goal here is to optimize for + * that case. However removing it completely is not good enough + * because it might generate many unused variable warnings. So we use + * if (false) and let the compiler optimize away the dead execution branch. + */ +#define ws_assert_if_active(active, expr) \ + do { \ + if ((active) && !(expr)) \ + ws_error("assertion failed: %s", #expr); \ + } while (0) + +/* + * ws_abort_if_fail() is not conditional on having assertions enabled. + * Usually used to appease a static analyzer. + */ +#define ws_abort_if_fail(expr) \ + ws_assert_if_active(true, expr) + +/* + * ws_assert() cannot produce side effects, otherwise code will + * behave differently because of having assertions enabled/disabled, and + * probably introduce some difficult to track bugs. + */ +#define ws_assert(expr) \ + ws_assert_if_active(WS_ASSERT_ENABLED, expr) + + +#define ws_assert_streq(s1, s2) \ + ws_assert((s1) && (s2) && strcmp((s1), (s2)) == 0) + +#define ws_assert_utf8(str, len) \ + do { \ + const char *__assert_endptr; \ + if (WS_ASSERT_ENABLED && \ + !g_utf8_validate(str, len, &__assert_endptr)) { \ + ws_log_utf8_full(LOG_DOMAIN_UTF_8, LOG_LEVEL_ERROR, \ + __FILE__, __LINE__, __func__, \ + str, len, __assert_endptr); \ + } \ + } while (0) + +/* + * We don't want to disable ws_assert_not_reached() with (optional) assertions + * disabled. + * That would blast compiler warnings everywhere for no benefit, not + * even a miniscule performance gain. Reaching this function is always + * a programming error and will unconditionally abort execution. + * + * Note: With g_assert_not_reached() if the compiler supports unreachable + * built-ins (which recent versions of GCC and MSVC do) there is no warning + * blast with g_assert_not_reached() and G_DISABLE_ASSERT. However if that + * is not the case then g_assert_not_reached() is simply (void)0 and that + * causes the spurious warnings, because the compiler can't tell anymore + * that a certain code path is not used. We avoid that with + * ws_assert_not_reached(). There is no reason to ever use a no-op here. + */ +#define ws_assert_not_reached() \ + ws_error("assertion \"not reached\" failed") + +/* + * These macros can be used as an alternative to ws_assert() to + * assert some condition on function arguments. This must only be used + * to catch programming errors, in situations where an assertion is + * appropriate. And it should only be used if failing the condition + * doesn't necessarily lead to an inconsistent state for the program. + * + * It is possible to set the fatal log domain to "InvalidArg" to abort + * execution for debugging purposes, if one of these checks fail. + */ + +#define ws_warn_badarg(str) \ + ws_log_full(LOG_DOMAIN_EINVAL, LOG_LEVEL_WARNING, \ + __FILE__, __LINE__, __func__, \ + "invalid argument: %s", str) + +#define ws_return_str_if(expr, scope) \ + do { \ + if (WS_ASSERT_ENABLED && (expr)) { \ + ws_warn_badarg(#expr); \ + return wmem_strdup_printf(scope, "(invalid argument: %s)", #expr); \ + } \ + } while (0) + +#define ws_return_val_if(expr, val) \ + do { \ + if (WS_ASSERT_ENABLED && (expr)) { \ + ws_warn_badarg(#expr); \ + return (val); \ + } \ + } while (0) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __WS_ASSERT_H__ */ -- cgit v1.2.3