]> git.ipfire.org Git - thirdparty/glibc.git/blob - include/printf_buffer.h
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / include / printf_buffer.h
1 /* Multibyte and wide buffers for implementing printf-related functions.
2 Copyright (C) 2022-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 /* The naming of the multibyte and wide variants is intentionally
20 consistent, so that it is possible to use the Xprintf macro in
21 stdio-common/printf_buffer-char.h and
22 stdio-common/printf_buffer-wchar_t.h to select between them in
23 type-generic code. */
24
25 #ifndef PRINTF_BUFFER_H
26 #define PRINTF_BUFFER_H
27
28 #include <stdbool.h>
29 #include <stdint.h>
30 #include <sys/types.h>
31 #include <wchar.h>
32
33 /* <printf_buffer_as_file.h> introduces a way to use struct
34 __printf_buffer objects from FILE * streams. To avoid storing a
35 function pointer (or vtable pointer) in struct __printf_buffer
36 (which would defeat libio vtable hardening), a switch statement
37 over the different flush implementations is used to implement
38 __printf_buffer_flush.
39
40 __printf_buffer_mode_failed is special: it is the sticky failure
41 indicator. Unlike struct alloc_buffer, this is not folded into
42 write_ptr, so that snprintf and other string-writing functions can
43 discover the end of the string even in the error case, to be able
44 to add the null terminator. */
45 enum __printf_buffer_mode
46 {
47 __printf_buffer_mode_failed,
48 __printf_buffer_mode_sprintf,
49 __printf_buffer_mode_snprintf,
50 __printf_buffer_mode_sprintf_chk,
51 __printf_buffer_mode_to_file,
52 __printf_buffer_mode_asprintf,
53 __printf_buffer_mode_dprintf,
54 __printf_buffer_mode_strfmon,
55 __printf_buffer_mode_fp, /* For __printf_fp_l_buffer. */
56 __printf_buffer_mode_fp_to_wide, /* For __wprintf_fp_l_buffer. */
57 __printf_buffer_mode_fphex_to_wide, /* For __wprintf_fphex_l_buffer. */
58 __printf_buffer_mode_obstack, /* For __printf_buffer_flush_obstack. */
59 };
60
61 /* Buffer for fast character writing with overflow handling.
62 Typically embedded in another struct with further data that is used
63 by the flush function. */
64 struct __printf_buffer
65 {
66 /* These pointer members follow FILE streams. write_ptr and
67 write_end must be initialized to cover the target buffer. See
68 __printf_buffer_init.
69
70 Data can be written directly to *write_ptr while write_ptr !=
71 write_end, and write_ptr can be advanced accordingly. Note that
72 is not possible to use the apparently-unused part of the buffer
73 as scratch space because sprintf (and snprintf, but that is a bit
74 iffy) must only write the minimum number of characters produced
75 by the format string and its arguments.
76
77 write_base must be initialized to be equal to write_ptr. The
78 framework uses this pointer to compute the total number of
79 written bytes, together with the written field. See
80 __printf_buffer_done.
81
82 write_base and write_end are only read by the generic functions
83 after initialization, only the flush implementation called from
84 __printf_buffer_flush might change these pointers. See the
85 comment on Xprintf (buffer_do_flush) in Xprintf_buffer_flush.c
86 for details regarding the flush operation. */
87 char *write_base;
88 char *write_ptr;
89 char *write_end;
90
91 /* Number of characters written so far (excluding the current
92 buffer). Potentially updated on flush. The actual number of
93 written bytes also includes the unflushed-but-written buffer
94 part, write_ptr - write_base. A 64-bit value is used to avoid
95 the need for overflow checks. */
96 uint64_t written;
97
98 /* Identifies the flush callback. */
99 enum __printf_buffer_mode mode;
100 };
101
102 /* Marks the buffer as failed, so that __printf_buffer_has_failed
103 returns true and future flush operations are no-ops. */
104 static inline void
105 __printf_buffer_mark_failed (struct __printf_buffer *buf)
106 {
107 buf->mode = __printf_buffer_mode_failed;
108 }
109
110 /* Returns true if the sticky error indicator of the buffer has been
111 set to failed. */
112 static inline bool __attribute_warn_unused_result__
113 __printf_buffer_has_failed (struct __printf_buffer *buf)
114 {
115 return buf->mode == __printf_buffer_mode_failed;
116 }
117
118 /* Initialization of a buffer, using the memory region from [BASE, BASE +LEN)
119 as the initial buffer contents. LEN can be zero. */
120 static inline void
121 __printf_buffer_init (struct __printf_buffer *buf, char *base, size_t len,
122 enum __printf_buffer_mode mode)
123 {
124 buf->write_base = base;
125 buf->write_ptr = base;
126 buf->write_end = base + len;
127 buf->written = 0;
128 buf->mode = mode;
129 }
130
131 /* Called by printf_buffer_putc for a full buffer. */
132 void __printf_buffer_putc_1 (struct __printf_buffer *buf, char ch)
133 attribute_hidden;
134
135 /* Writes CH to BUF. */
136 static inline void
137 __printf_buffer_putc (struct __printf_buffer *buf, char ch)
138 {
139 if (buf->write_ptr != buf->write_end)
140 *buf->write_ptr++ = ch;
141 else
142 __printf_buffer_putc_1 (buf, ch);
143 }
144
145 /* Writes COUNT repeats of CH to BUF. */
146 void __printf_buffer_pad_1 (struct __printf_buffer *buf,
147 char ch, size_t count) attribute_hidden;
148
149 /* __printf_buffer_pad with fast path for no padding. COUNT is
150 ssize_t to accomodate signed uses in printf and elsewhere. */
151 static inline void
152 __printf_buffer_pad (struct __printf_buffer *buf, char ch, ssize_t count)
153 {
154 if (count > 0)
155 __printf_buffer_pad_1 (buf, ch, count);
156 }
157
158 /* Write COUNT bytes starting at S to BUF. S must not overlap with
159 the internal buffer. */
160 void __printf_buffer_write (struct __printf_buffer *buf, const char *s,
161 size_t count) attribute_hidden;
162
163 /* Write S to BUF. S must not overlap with the internal buffer. */
164 void __printf_buffer_puts_1 (struct __printf_buffer *buf, const char *s)
165 attribute_hidden;
166
167 static inline void
168 __printf_buffer_puts (struct __printf_buffer *buf, const char *s)
169 {
170 if (__builtin_constant_p (__builtin_strlen (s)))
171 __printf_buffer_write (buf, s, __builtin_strlen (s));
172 else
173 __printf_buffer_puts_1 (buf, s);
174 }
175
176 /* Returns the number of bytes written through the buffer, or -1 if
177 there was an error (that is, __printf_buffer_has_failed (BUF) is true).
178
179 The number of written bytes includes pending bytes in the buffer
180 (between BUF->write_base and BUF->write_ptr).
181
182 If the number is larger than INT_MAX, returns -1 and sets errno to
183 EOVERFLOW. This function does not flush the buffer. If the caller
184 needs the side effect of flushing, it has to do this
185 separately. */
186 int __printf_buffer_done (struct __printf_buffer *buf) attribute_hidden;
187
188 /* Internally used to call the flush function. This can be called
189 explicitly for certain modes to flush the buffer prematuraly. In
190 such cases, it is often the case that the buffer mode is statically
191 known, and the flush implementation can be called directly. */
192 bool __printf_buffer_flush (struct __printf_buffer *buf) attribute_hidden;
193
194 /* Wide version of struct __printf_buffer follows. */
195
196 enum __wprintf_buffer_mode
197 {
198 __wprintf_buffer_mode_failed,
199 __wprintf_buffer_mode_swprintf,
200 __wprintf_buffer_mode_to_file,
201 };
202
203 struct __wprintf_buffer
204 {
205 wchar_t *write_base;
206 wchar_t *write_ptr;
207 wchar_t *write_end;
208 uint64_t written;
209 enum __wprintf_buffer_mode mode;
210 };
211
212 static inline void
213 __wprintf_buffer_mark_failed (struct __wprintf_buffer *buf)
214 {
215 buf->mode = __wprintf_buffer_mode_failed;
216 }
217
218 static inline bool __attribute_warn_unused_result__
219 __wprintf_buffer_has_failed (struct __wprintf_buffer *buf)
220 {
221 return buf->mode == __wprintf_buffer_mode_failed;
222 }
223
224 static inline void
225 __wprintf_buffer_init (struct __wprintf_buffer *buf,
226 wchar_t *base, size_t len,
227 enum __wprintf_buffer_mode mode)
228 {
229 buf->write_base = base;
230 buf->write_ptr = base;
231 buf->write_end = base + len;
232 buf->written = 0;
233 buf->mode = mode;
234 }
235
236 void __wprintf_buffer_putc_1 (struct __wprintf_buffer *buf, wchar_t ch)
237 attribute_hidden;
238
239 static inline void
240 __wprintf_buffer_putc (struct __wprintf_buffer *buf, wchar_t ch)
241 {
242 if (buf->write_ptr != buf->write_end)
243 *buf->write_ptr++ = ch;
244 else
245 __wprintf_buffer_putc_1 (buf, ch);
246 }
247
248 void __wprintf_buffer_pad_1 (struct __wprintf_buffer *buf,
249 wchar_t ch, size_t count) attribute_hidden;
250
251 static inline void
252 __wprintf_buffer_pad (struct __wprintf_buffer *buf, char ch, ssize_t count)
253 {
254 if (count > 0)
255 __wprintf_buffer_pad_1 (buf, ch, count);
256 }
257
258 void __wprintf_buffer_write (struct __wprintf_buffer *buf, const wchar_t *s,
259 size_t count) attribute_hidden;
260
261 void __wprintf_buffer_puts (struct __wprintf_buffer *buf, const wchar_t *s)
262 attribute_hidden;
263
264 int __wprintf_buffer_done (struct __wprintf_buffer *buf) attribute_hidden;
265
266 bool __wprintf_buffer_flush (struct __wprintf_buffer *buf) attribute_hidden;
267
268 /* Type-generic convenience macros. They are useful if
269 printf_buffer-char.h or printf_buffer-wchar_t.h is included as
270 well. */
271
272 #define Xprintf_buffer Xprintf (buffer)
273 #define Xprintf_buffer_done Xprintf (buffer_done)
274 #define Xprintf_buffer_flush Xprintf (buffer_flush)
275 #define Xprintf_buffer_has_failed Xprintf (buffer_has_failed)
276 #define Xprintf_buffer_mark_failed Xprintf (buffer_mark_failed)
277 #define Xprintf_buffer_pad Xprintf (buffer_pad)
278 #define Xprintf_buffer_putc Xprintf (buffer_putc)
279 #define Xprintf_buffer_puts Xprintf (buffer_puts)
280 #define Xprintf_buffer_write Xprintf (buffer_write)
281
282 /* Commonly used buffers. */
283
284 struct __printf_buffer_snprintf
285 {
286 struct __printf_buffer base;
287 #define PRINTF_BUFFER_SIZE_DISCARD 128
288 char discard[PRINTF_BUFFER_SIZE_DISCARD]; /* Used in counting mode. */
289 };
290
291 /* Sets up [BUFFER, BUFFER + LENGTH) as the write target. If LENGTH
292 is positive, also writes a NUL byte to *BUFFER. */
293 void __printf_buffer_snprintf_init (struct __printf_buffer_snprintf *,
294 char *buffer, size_t length)
295 attribute_hidden;
296
297 /* Add the null terminator after everything has been written. The
298 return value is the one expected by printf (see __printf_buffer_done). */
299 int __printf_buffer_snprintf_done (struct __printf_buffer_snprintf *)
300 attribute_hidden;
301
302 /* Flush function implementations follow. They are called from
303 __printf_buffer_flush. Generic code should not call these flush
304 functions directly. Some modes have inline implementations. */
305
306 void __printf_buffer_flush_snprintf (struct __printf_buffer_snprintf *)
307 attribute_hidden;
308 struct __printf_buffer_to_file;
309 void __printf_buffer_flush_to_file (struct __printf_buffer_to_file *)
310 attribute_hidden;
311 struct __printf_buffer_asprintf;
312 void __printf_buffer_flush_asprintf (struct __printf_buffer_asprintf *)
313 attribute_hidden;
314 struct __printf_buffer_dprintf;
315 void __printf_buffer_flush_dprintf (struct __printf_buffer_dprintf *)
316 attribute_hidden;
317 struct __printf_buffer_fp;
318 void __printf_buffer_flush_fp (struct __printf_buffer_fp *)
319 attribute_hidden;
320 struct __printf_buffer_fp_to_wide;
321 void __printf_buffer_flush_fp_to_wide (struct __printf_buffer_fp_to_wide *)
322 attribute_hidden;
323 struct __printf_buffer_fphex_to_wide;
324 void __printf_buffer_flush_fphex_to_wide (struct
325 __printf_buffer_fphex_to_wide *)
326 attribute_hidden;
327 struct __printf_buffer_obstack;
328 void __printf_buffer_flush_obstack (struct __printf_buffer_obstack *)
329 attribute_hidden;
330
331 struct __wprintf_buffer_to_file;
332 void __wprintf_buffer_flush_to_file (struct __wprintf_buffer_to_file *)
333 attribute_hidden;
334
335 /* Buffer sizes. These can be tuned as necessary. There is a tension
336 here between stack consumption, cache usage, and additional system
337 calls or heap allocations (if the buffer is too small).
338
339 Also see PRINTF_BUFFER_SIZE_DISCARD above for snprintf. */
340
341 /* Fallback buffer if the underlying FILE * stream does not provide
342 buffer space. */
343 #define PRINTF_BUFFER_SIZE_TO_FILE_STAGE 128
344
345 /* Temporary buffer used during floating point digit translation. */
346 #define PRINTF_BUFFER_SIZE_DIGITS 64
347
348 /* Size of the initial on-stack buffer for asprintf. It should be
349 large enough to copy almost all asprintf usages with just a single
350 (final, correctly sized) heap allocation. */
351 #define PRINTF_BUFFER_SIZE_ASPRINTF 200
352
353 /* This should cover most of the packet-oriented file descriptors,
354 where boundaries between writes could be visible to readers. But
355 it is still small enough not to cause too many stack overflow issues. */
356 #define PRINTF_BUFFER_SIZE_DPRINTF 2048
357
358 #endif /* PRINTF_BUFFER_H */