mirror of
https://github.com/systemd/systemd.git
synced 2026-07-12 10:34:12 +00:00
In general we almost never hit those asserts in production code, so users see them very rarely, if ever. But either way, we just need something that users can pass to the developers. We have quite a few of those asserts, and some have fairly nice messages, but many are like "WTF?" or "???" or "unexpected something". The error that is printed includes the file location, and function name. In almost all functions there's at most one assert, so the function name alone is enough to identify the failure for a developer. So we don't get much extra from the message, and we might just as well drop them. Dropping them makes our code a tiny bit smaller, and most importantly, improves development experience by making it easy to insert such an assert in the code without thinking how to phrase the argument.
65 lines
3.8 KiB
C
65 lines
3.8 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
#pragma once
|
|
|
|
#include <printf.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
|
|
#include "macro.h"
|
|
#include "memory-util.h"
|
|
|
|
#define snprintf_ok(buf, len, fmt, ...) \
|
|
((size_t) snprintf(buf, len, fmt, __VA_ARGS__) < (len))
|
|
|
|
#define xsprintf(buf, fmt, ...) \
|
|
assert_message_se(snprintf_ok(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__), "xsprintf: " #buf "[] must be big enough")
|
|
|
|
#define VA_FORMAT_ADVANCE(format, ap) \
|
|
do { \
|
|
int _argtypes[128]; \
|
|
size_t _i, _k; \
|
|
/* See https://github.com/google/sanitizers/issues/992 */ \
|
|
if (HAS_FEATURE_MEMORY_SANITIZER) \
|
|
zero(_argtypes); \
|
|
_k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
|
|
assert(_k < ELEMENTSOF(_argtypes)); \
|
|
for (_i = 0; _i < _k; _i++) { \
|
|
if (_argtypes[_i] & PA_FLAG_PTR) { \
|
|
(void) va_arg(ap, void*); \
|
|
continue; \
|
|
} \
|
|
\
|
|
switch (_argtypes[_i]) { \
|
|
case PA_INT: \
|
|
case PA_INT|PA_FLAG_SHORT: \
|
|
case PA_CHAR: \
|
|
(void) va_arg(ap, int); \
|
|
break; \
|
|
case PA_INT|PA_FLAG_LONG: \
|
|
(void) va_arg(ap, long int); \
|
|
break; \
|
|
case PA_INT|PA_FLAG_LONG_LONG: \
|
|
(void) va_arg(ap, long long int); \
|
|
break; \
|
|
case PA_WCHAR: \
|
|
(void) va_arg(ap, wchar_t); \
|
|
break; \
|
|
case PA_WSTRING: \
|
|
case PA_STRING: \
|
|
case PA_POINTER: \
|
|
(void) va_arg(ap, void*); \
|
|
break; \
|
|
case PA_FLOAT: \
|
|
case PA_DOUBLE: \
|
|
(void) va_arg(ap, double); \
|
|
break; \
|
|
case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
|
|
(void) va_arg(ap, long double); \
|
|
break; \
|
|
default: \
|
|
assert_not_reached(); \
|
|
} \
|
|
} \
|
|
} while (false)
|