2 * Copyright (c) 2018 Eugene Syromyatnikov <evgsyr@gmail.com>
5 * SPDX-License-Identifier: LGPL-2.1-or-later
8 #ifndef STRACE_XSTRING_H
9 # define STRACE_XSTRING_H
14 # include "error_prints.h"
15 # include "gcc_compat.h"
18 * Print to static buffer and die on (really unexpected) errors and overflows.
19 * Shouldn't be used directly; please refer to helper macros xsnprintf and
22 * @param str String buffer to print into.
23 * @param size Size of the string buffer in bytes.
24 * @param func Function name from which this function is called.
25 * @param argstr Stringified arguments (including format argument).
26 * @param format Format string.
27 * @param ... Format arguments.
28 * @return Number of characters printed, excluding terminating null byte
29 * (the same as s(n)printf).
31 static inline int ATTRIBUTE_FORMAT((printf, 5, 6))
32 xsnprintf_(char *str, size_t size, const char *func, const char *argstr,
33 const char *format, ...)
39 ret = vsnprintf(str, size, format, ap);
42 if (ret < 0 || (unsigned int) ret >= size)
43 error_msg_and_die("%s: got unexpected return value %d for "
44 "snprintf(buf, %zu, %s)",
45 func, ret, size, argstr);
51 * snprintf that dies on (really unexpected) errors and overflows.
53 * @param str_ String buffer to print into.
54 * @param size_ Size of the string buffer in bytes.
55 * @param fmt_ Format string.
56 * @param ... Format arguments.
58 # define xsnprintf(str_, size_, fmt_, ...) \
59 xsnprintf_((str_), (size_), __func__, #fmt_ ", " #__VA_ARGS__, \
63 * Print to a character array buffer and die on (really unexpected) errors and
64 * overflows. Buffer size is obtained with sizeof().
66 * @param str_ Character array buffer to print into.
67 * @param fmt_ Format string.
68 * @param ... Format arguments.
70 # define xsprintf(str_, fmt_, ...) \
71 xsnprintf((str_), sizeof(str_) + MUST_BE_ARRAY(str_), (fmt_), \
75 get_pos_diff_(char *str, size_t size, char *pos, const char *func,
78 if ((str + size) < str)
79 error_msg_and_die("%s: string size overflow (%p+%zu) in %s",
80 func, str, size, call);
82 if (pos > (str + size))
83 error_msg_and_die("%s: got position (%p) beyond string "
85 func, pos, str, size, call);
88 error_msg_and_die("%s: got position %p before string %p in %s",
89 func, pos, str, call);
95 * Helper function for constructing string in a character array by appending
96 * new formatted parts. Returns new position. Fails on error or buffer
97 * overflow, in line with the rest of x* functions. Obtains buffer size via
100 * @param str_ Character array buffer to print into.
101 * @param pos_ Current position.
102 * @param fmt_ Format string.
103 * @param ... Format arguments.
104 * @return New position.
106 # define xappendstr(str_, pos_, fmt_, ...) \
107 (xsnprintf((pos_), sizeof(str_) + MUST_BE_ARRAY(str_) - \
108 get_pos_diff_((str_), sizeof(str_), (pos_), __func__, \
109 "xappendstr(" #str_ ", " #pos_ ", " #fmt_ ", " \
111 (fmt_), ##__VA_ARGS__) + (pos_))
113 #endif /* !STRACE_XSTRING_H */