| |
1 /* |
| |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
| |
3 * |
| |
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. |
| |
5 * |
| |
6 * Redistribution and use in source and binary forms, with or without |
| |
7 * modification, are permitted provided that the following conditions are met: |
| |
8 * |
| |
9 * 1. Redistributions of source code must retain the above copyright |
| |
10 * notice, this list of conditions and the following disclaimer. |
| |
11 * |
| |
12 * 2. Redistributions in binary form must reproduce the above copyright |
| |
13 * notice, this list of conditions and the following disclaimer in the |
| |
14 * documentation and/or other materials provided with the distribution. |
| |
15 * |
| |
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| |
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| |
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| |
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| |
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| |
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| |
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| |
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| |
26 * POSSIBILITY OF SUCH DAMAGE. |
| |
27 */ |
| |
28 /** |
| |
29 * \file printf.h |
| |
30 * \brief Wrapper for write functions with a printf-like interface. |
| |
31 * \author Mike Becker |
| |
32 * \author Olaf Wintermann |
| |
33 * \copyright 2-Clause BSD License |
| |
34 */ |
| |
35 |
| |
36 #ifndef UCX_PRINTF_H |
| |
37 #define UCX_PRINTF_H |
| |
38 |
| |
39 #include "common.h" |
| |
40 #include "string.h" |
| |
41 #include <stdarg.h> |
| |
42 |
| |
43 #ifdef __cplusplus |
| |
44 extern "C" { |
| |
45 #endif |
| |
46 |
| |
47 |
| |
48 /** |
| |
49 * The maximum string length that fits into stack memory. |
| |
50 */ |
| |
51 extern unsigned const cx_printf_sbo_size; |
| |
52 |
| |
53 /** |
| |
54 * A \c fprintf like function which writes the output to a stream by |
| |
55 * using a write_func. |
| |
56 * |
| |
57 * @param stream the stream the data is written to |
| |
58 * @param wfc the write function |
| |
59 * @param fmt format string |
| |
60 * @param ... additional arguments |
| |
61 * @return the total number of bytes written |
| |
62 */ |
| |
63 __attribute__((__nonnull__(1, 2, 3), __format__(printf, 3, 4))) |
| |
64 int cx_fprintf( |
| |
65 void *stream, |
| |
66 cx_write_func wfc, |
| |
67 char const *fmt, |
| |
68 ... |
| |
69 ); |
| |
70 |
| |
71 /** |
| |
72 * A \c vfprintf like function which writes the output to a stream by |
| |
73 * using a write_func. |
| |
74 * |
| |
75 * @param stream the stream the data is written to |
| |
76 * @param wfc the write function |
| |
77 * @param fmt format string |
| |
78 * @param ap argument list |
| |
79 * @return the total number of bytes written |
| |
80 * @see cx_fprintf() |
| |
81 */ |
| |
82 __attribute__((__nonnull__)) |
| |
83 int cx_vfprintf( |
| |
84 void *stream, |
| |
85 cx_write_func wfc, |
| |
86 char const *fmt, |
| |
87 va_list ap |
| |
88 ); |
| |
89 |
| |
90 /** |
| |
91 * A \c asprintf like function which allocates space for a string |
| |
92 * the result is written to. |
| |
93 * |
| |
94 * \note The resulting string is guaranteed to be zero-terminated. |
| |
95 * |
| |
96 * @param allocator the CxAllocator used for allocating the string |
| |
97 * @param fmt format string |
| |
98 * @param ... additional arguments |
| |
99 * @return the formatted string |
| |
100 * @see cx_strfree_a() |
| |
101 */ |
| |
102 __attribute__((__nonnull__(1, 2), __format__(printf, 2, 3))) |
| |
103 cxmutstr cx_asprintf_a( |
| |
104 CxAllocator const *allocator, |
| |
105 char const *fmt, |
| |
106 ... |
| |
107 ); |
| |
108 |
| |
109 /** |
| |
110 * A \c asprintf like function which allocates space for a string |
| |
111 * the result is written to. |
| |
112 * |
| |
113 * \note The resulting string is guaranteed to be zero-terminated. |
| |
114 * |
| |
115 * @param fmt format string |
| |
116 * @param ... additional arguments |
| |
117 * @return the formatted string |
| |
118 * @see cx_strfree() |
| |
119 */ |
| |
120 #define cx_asprintf(fmt, ...) \ |
| |
121 cx_asprintf_a(cxDefaultAllocator, fmt, __VA_ARGS__) |
| |
122 |
| |
123 /** |
| |
124 * A \c vasprintf like function which allocates space for a string |
| |
125 * the result is written to. |
| |
126 * |
| |
127 * \note The resulting string is guaranteed to be zero-terminated. |
| |
128 * |
| |
129 * @param allocator the CxAllocator used for allocating the string |
| |
130 * @param fmt format string |
| |
131 * @param ap argument list |
| |
132 * @return the formatted string |
| |
133 * @see cx_asprintf_a() |
| |
134 */ |
| |
135 __attribute__((__nonnull__)) |
| |
136 cxmutstr cx_vasprintf_a( |
| |
137 CxAllocator const *allocator, |
| |
138 char const *fmt, |
| |
139 va_list ap |
| |
140 ); |
| |
141 |
| |
142 /** |
| |
143 * A \c vasprintf like function which allocates space for a string |
| |
144 * the result is written to. |
| |
145 * |
| |
146 * \note The resulting string is guaranteed to be zero-terminated. |
| |
147 * |
| |
148 * @param fmt format string |
| |
149 * @param ap argument list |
| |
150 * @return the formatted string |
| |
151 * @see cx_asprintf() |
| |
152 */ |
| |
153 #define cx_vasprintf(fmt, ap) cx_vasprintf_a(cxDefaultAllocator, fmt, ap) |
| |
154 |
| |
155 /** |
| |
156 * A \c printf like function which writes the output to a CxBuffer. |
| |
157 * |
| |
158 * @param buffer a pointer to the buffer the data is written to |
| |
159 * @param fmt the format string |
| |
160 * @param ... additional arguments |
| |
161 * @return the total number of bytes written |
| |
162 * @see ucx_fprintf() |
| |
163 */ |
| |
164 #define cx_bprintf(buffer, fmt, ...) cx_fprintf((CxBuffer*)buffer, \ |
| |
165 (cx_write_func) cxBufferWrite, fmt, __VA_ARGS__) |
| |
166 |
| |
167 |
| |
168 /** |
| |
169 * An \c sprintf like function which reallocates the string when the buffer is not large enough. |
| |
170 * |
| |
171 * The size of the buffer will be updated in \p len when necessary. |
| |
172 * |
| |
173 * \note The resulting string is guaranteed to be zero-terminated. |
| |
174 * |
| |
175 * @param str a pointer to the string buffer |
| |
176 * @param len a pointer to the length of the buffer |
| |
177 * @param fmt the format string |
| |
178 * @param ... additional arguments |
| |
179 * @return the length of produced string |
| |
180 */ |
| |
181 #define cx_sprintf(str, len, fmt, ...) cx_sprintf_a(cxDefaultAllocator, str, len, fmt, __VA_ARGS__) |
| |
182 |
| |
183 /** |
| |
184 * An \c sprintf like function which reallocates the string when the buffer is not large enough. |
| |
185 * |
| |
186 * The size of the buffer will be updated in \p len when necessary. |
| |
187 * |
| |
188 * \note The resulting string is guaranteed to be zero-terminated. |
| |
189 * |
| |
190 * \attention The original buffer MUST have been allocated with the same allocator! |
| |
191 * |
| |
192 * @param alloc the allocator to use |
| |
193 * @param str a pointer to the string buffer |
| |
194 * @param len a pointer to the length of the buffer |
| |
195 * @param fmt the format string |
| |
196 * @param ... additional arguments |
| |
197 * @return the length of produced string |
| |
198 */ |
| |
199 __attribute__((__nonnull__(1, 2, 3, 4), __format__(printf, 4, 5))) |
| |
200 int cx_sprintf_a(CxAllocator *alloc, char **str, size_t *len, const char *fmt, ... ); |
| |
201 |
| |
202 |
| |
203 /** |
| |
204 * An \c sprintf like function which reallocates the string when the buffer is not large enough. |
| |
205 * |
| |
206 * The size of the buffer will be updated in \p len when necessary. |
| |
207 * |
| |
208 * \note The resulting string is guaranteed to be zero-terminated. |
| |
209 * |
| |
210 * @param str a pointer to the string buffer |
| |
211 * @param len a pointer to the length of the buffer |
| |
212 * @param fmt the format string |
| |
213 * @param ap argument list |
| |
214 * @return the length of produced string |
| |
215 */ |
| |
216 #define cx_vsprintf(str, len, fmt, ap) cx_vsprintf_a(cxDefaultAllocator, str, len, fmt, ap) |
| |
217 |
| |
218 /** |
| |
219 * An \c sprintf like function which reallocates the string when the buffer is not large enough. |
| |
220 * |
| |
221 * The size of the buffer will be updated in \p len when necessary. |
| |
222 * |
| |
223 * \note The resulting string is guaranteed to be zero-terminated. |
| |
224 * |
| |
225 * \attention The original buffer MUST have been allocated with the same allocator! |
| |
226 * |
| |
227 * @param alloc the allocator to use |
| |
228 * @param str a pointer to the string buffer |
| |
229 * @param len a pointer to the length of the buffer |
| |
230 * @param fmt the format string |
| |
231 * @param ap argument list |
| |
232 * @return the length of produced string |
| |
233 */ |
| |
234 __attribute__((__nonnull__)) |
| |
235 int cx_vsprintf_a(CxAllocator *alloc, char **str, size_t *len, const char *fmt, va_list ap); |
| |
236 |
| |
237 |
| |
238 /** |
| |
239 * An \c sprintf like function which allocates a new string when the buffer is not large enough. |
| |
240 * |
| |
241 * The size of the buffer will be updated in \p len when necessary. |
| |
242 * |
| |
243 * The location of the resulting string will \em always be stored to \p str. When the buffer |
| |
244 * was sufficiently large, \p buf itself will be stored to the location of \p str. |
| |
245 * |
| |
246 * \note The resulting string is guaranteed to be zero-terminated. |
| |
247 * |
| |
248 * \remark When a new string needed to be allocated, the contents of \p buf will be |
| |
249 * poisoned after the call, because this function tries to produce the string in \p buf, first. |
| |
250 * |
| |
251 * @param buf a pointer to the buffer |
| |
252 * @param len a pointer to the length of the buffer |
| |
253 * @param str a pointer to the location |
| |
254 * @param fmt the format string |
| |
255 * @param ... additional arguments |
| |
256 * @return the length of produced string |
| |
257 */ |
| |
258 #define cx_sprintf_s(buf, len, str, fmt, ...) cx_sprintf_sa(cxDefaultAllocator, buf, len, str, fmt, __VA_ARGS__) |
| |
259 |
| |
260 /** |
| |
261 * An \c sprintf like function which allocates a new string when the buffer is not large enough. |
| |
262 * |
| |
263 * The size of the buffer will be updated in \p len when necessary. |
| |
264 * |
| |
265 * The location of the resulting string will \em always be stored to \p str. When the buffer |
| |
266 * was sufficiently large, \p buf itself will be stored to the location of \p str. |
| |
267 * |
| |
268 * \note The resulting string is guaranteed to be zero-terminated. |
| |
269 * |
| |
270 * \remark When a new string needed to be allocated, the contents of \p buf will be |
| |
271 * poisoned after the call, because this function tries to produce the string in \p buf, first. |
| |
272 * |
| |
273 * @param alloc the allocator to use |
| |
274 * @param buf a pointer to the buffer |
| |
275 * @param len a pointer to the length of the buffer |
| |
276 * @param str a pointer to the location |
| |
277 * @param fmt the format string |
| |
278 * @param ... additional arguments |
| |
279 * @return the length of produced string |
| |
280 */ |
| |
281 __attribute__((__nonnull__(1, 2, 4, 5), __format__(printf, 5, 6))) |
| |
282 int cx_sprintf_sa(CxAllocator *alloc, char *buf, size_t *len, char **str, const char *fmt, ... ); |
| |
283 |
| |
284 /** |
| |
285 * An \c sprintf like function which allocates a new string when the buffer is not large enough. |
| |
286 * |
| |
287 * The size of the buffer will be updated in \p len when necessary. |
| |
288 * |
| |
289 * The location of the resulting string will \em always be stored to \p str. When the buffer |
| |
290 * was sufficiently large, \p buf itself will be stored to the location of \p str. |
| |
291 * |
| |
292 * \note The resulting string is guaranteed to be zero-terminated. |
| |
293 * |
| |
294 * \remark When a new string needed to be allocated, the contents of \p buf will be |
| |
295 * poisoned after the call, because this function tries to produce the string in \p buf, first. |
| |
296 * |
| |
297 * @param buf a pointer to the buffer |
| |
298 * @param len a pointer to the length of the buffer |
| |
299 * @param str a pointer to the location |
| |
300 * @param fmt the format string |
| |
301 * @param ap argument list |
| |
302 * @return the length of produced string |
| |
303 */ |
| |
304 #define cx_vsprintf_s(buf, len, str, fmt, ap) cx_vsprintf_sa(cxDefaultAllocator, buf, len, str, fmt, ap) |
| |
305 |
| |
306 /** |
| |
307 * An \c sprintf like function which allocates a new string when the buffer is not large enough. |
| |
308 * |
| |
309 * The size of the buffer will be updated in \p len when necessary. |
| |
310 * |
| |
311 * The location of the resulting string will \em always be stored to \p str. When the buffer |
| |
312 * was sufficiently large, \p buf itself will be stored to the location of \p str. |
| |
313 * |
| |
314 * \note The resulting string is guaranteed to be zero-terminated. |
| |
315 * |
| |
316 * \remark When a new string needed to be allocated, the contents of \p buf will be |
| |
317 * poisoned after the call, because this function tries to produce the string in \p buf, first. |
| |
318 * |
| |
319 * @param alloc the allocator to use |
| |
320 * @param buf a pointer to the buffer |
| |
321 * @param len a pointer to the length of the buffer |
| |
322 * @param str a pointer to the location |
| |
323 * @param fmt the format string |
| |
324 * @param ap argument list |
| |
325 * @return the length of produced string |
| |
326 */ |
| |
327 __attribute__((__nonnull__)) |
| |
328 int cx_vsprintf_sa(CxAllocator *alloc, char *buf, size_t *len, char **str, const char *fmt, va_list ap); |
| |
329 |
| |
330 |
| |
331 #ifdef __cplusplus |
| |
332 } // extern "C" |
| |
333 #endif |
| |
334 |
| |
335 #endif //UCX_PRINTF_H |