chiark / gitweb /
87d8917a592656e79d8b0ae3a0bf35d9d7024f42
[elogind.git] / src / basic / stdio-util.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 #pragma once
3
4 /***
5   This file is part of systemd.
6
7   Copyright 2010 Lennart Poettering
8 ***/
9
10 #if 0 /// elogind is musl-libc compatible and does not directly include printf.h
11 #include <printf.h>
12 #else
13 #include "parse-printf-format.h"
14 #endif // 0
15 #include <stdarg.h>
16 #include <stdio.h>
17 #include <sys/types.h>
18
19 #include "macro.h"
20
21 #define snprintf_ok(buf, len, fmt, ...) \
22         ((size_t) snprintf(buf, len, fmt, __VA_ARGS__) < (len))
23
24 #define xsprintf(buf, fmt, ...) \
25         assert_message_se(snprintf_ok(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__), "xsprintf: " #buf "[] must be big enough")
26
27 #define VA_FORMAT_ADVANCE(format, ap)                                   \
28 do {                                                                    \
29         int _argtypes[128];                                             \
30         size_t _i, _k;                                                  \
31         _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
32         assert(_k < ELEMENTSOF(_argtypes));                             \
33         for (_i = 0; _i < _k; _i++) {                                   \
34                 if (_argtypes[_i] & PA_FLAG_PTR)  {                     \
35                         (void) va_arg(ap, void*);                       \
36                         continue;                                       \
37                 }                                                       \
38                                                                         \
39                 switch (_argtypes[_i]) {                                \
40                 case PA_INT:                                            \
41                 case PA_INT|PA_FLAG_SHORT:                              \
42                 case PA_CHAR:                                           \
43                         (void) va_arg(ap, int);                         \
44                         break;                                          \
45                 case PA_INT|PA_FLAG_LONG:                               \
46                         (void) va_arg(ap, long int);                    \
47                         break;                                          \
48                 case PA_INT|PA_FLAG_LONG_LONG:                          \
49                         (void) va_arg(ap, long long int);               \
50                         break;                                          \
51                 case PA_WCHAR:                                          \
52                         (void) va_arg(ap, wchar_t);                     \
53                         break;                                          \
54                 case PA_WSTRING:                                        \
55                 case PA_STRING:                                         \
56                 case PA_POINTER:                                        \
57                         (void) va_arg(ap, void*);                       \
58                         break;                                          \
59                 case PA_FLOAT:                                          \
60                 case PA_DOUBLE:                                         \
61                         (void) va_arg(ap, double);                      \
62                         break;                                          \
63                 case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:                     \
64                         (void) va_arg(ap, long double);                 \
65                         break;                                          \
66                 default:                                                \
67                         assert_not_reached("Unknown format string argument."); \
68                 }                                                       \
69         }                                                               \
70 } while (false)