1 | /* Multibyte and wide buffers for implementing printf-related functions. |
2 | Copyright (C) 2022-2024 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, |
119 | END) as the initial buffer contents. */ |
120 | static inline void |
121 | __printf_buffer_init_end (struct __printf_buffer *buf, char *base, char *end, |
122 | enum __printf_buffer_mode mode) |
123 | { |
124 | buf->write_base = base; |
125 | buf->write_ptr = base; |
126 | buf->write_end = end; |
127 | buf->written = 0; |
128 | buf->mode = mode; |
129 | } |
130 | |
131 | /* Initialization of a buffer, using the memory region from [BASE, BASE +LEN) |
132 | as the initial buffer contents. LEN can be zero. */ |
133 | static inline void |
134 | __printf_buffer_init (struct __printf_buffer *buf, char *base, size_t len, |
135 | enum __printf_buffer_mode mode) |
136 | { |
137 | __printf_buffer_init_end (buf, base, end: base + len, mode); |
138 | } |
139 | |
140 | /* Called by printf_buffer_putc for a full buffer. */ |
141 | void __printf_buffer_putc_1 (struct __printf_buffer *buf, char ch) |
142 | attribute_hidden; |
143 | |
144 | /* Writes CH to BUF. */ |
145 | static inline void |
146 | __printf_buffer_putc (struct __printf_buffer *buf, char ch) |
147 | { |
148 | if (buf->write_ptr != buf->write_end) |
149 | *buf->write_ptr++ = ch; |
150 | else |
151 | __printf_buffer_putc_1 (buf, ch); |
152 | } |
153 | |
154 | /* Writes COUNT repeats of CH to BUF. */ |
155 | void __printf_buffer_pad_1 (struct __printf_buffer *buf, |
156 | char ch, size_t count) attribute_hidden; |
157 | |
158 | /* __printf_buffer_pad with fast path for no padding. COUNT is |
159 | ssize_t to accommodate signed uses in printf and elsewhere. */ |
160 | static inline void |
161 | __printf_buffer_pad (struct __printf_buffer *buf, char ch, ssize_t count) |
162 | { |
163 | if (count > 0) |
164 | __printf_buffer_pad_1 (buf, ch, count); |
165 | } |
166 | |
167 | /* Write COUNT bytes starting at S to BUF. S must not overlap with |
168 | the internal buffer. */ |
169 | void __printf_buffer_write (struct __printf_buffer *buf, const char *s, |
170 | size_t count) attribute_hidden; |
171 | |
172 | /* Write S to BUF. S must not overlap with the internal buffer. */ |
173 | void __printf_buffer_puts_1 (struct __printf_buffer *buf, const char *s) |
174 | attribute_hidden; |
175 | |
176 | static inline void |
177 | __printf_buffer_puts (struct __printf_buffer *buf, const char *s) |
178 | { |
179 | if (__builtin_constant_p (__builtin_strlen (s))) |
180 | __printf_buffer_write (buf, s, count: __builtin_strlen (s)); |
181 | else |
182 | __printf_buffer_puts_1 (buf, s); |
183 | } |
184 | |
185 | /* Returns the number of bytes written through the buffer, or -1 if |
186 | there was an error (that is, __printf_buffer_has_failed (BUF) is true). |
187 | |
188 | The number of written bytes includes pending bytes in the buffer |
189 | (between BUF->write_base and BUF->write_ptr). |
190 | |
191 | If the number is larger than INT_MAX, returns -1 and sets errno to |
192 | EOVERFLOW. This function does not flush the buffer. If the caller |
193 | needs the side effect of flushing, it has to do this |
194 | separately. */ |
195 | int __printf_buffer_done (struct __printf_buffer *buf) attribute_hidden; |
196 | |
197 | /* Internally used to call the flush function. This can be called |
198 | explicitly for certain modes to flush the buffer prematuraly. In |
199 | such cases, it is often the case that the buffer mode is statically |
200 | known, and the flush implementation can be called directly. */ |
201 | bool __printf_buffer_flush (struct __printf_buffer *buf) attribute_hidden; |
202 | |
203 | /* Wide version of struct __printf_buffer follows. */ |
204 | |
205 | enum __wprintf_buffer_mode |
206 | { |
207 | __wprintf_buffer_mode_failed, |
208 | __wprintf_buffer_mode_swprintf, |
209 | __wprintf_buffer_mode_to_file, |
210 | }; |
211 | |
212 | struct __wprintf_buffer |
213 | { |
214 | wchar_t *write_base; |
215 | wchar_t *write_ptr; |
216 | wchar_t *write_end; |
217 | uint64_t written; |
218 | enum __wprintf_buffer_mode mode; |
219 | }; |
220 | |
221 | static inline void |
222 | __wprintf_buffer_mark_failed (struct __wprintf_buffer *buf) |
223 | { |
224 | buf->mode = __wprintf_buffer_mode_failed; |
225 | } |
226 | |
227 | static inline bool __attribute_warn_unused_result__ |
228 | __wprintf_buffer_has_failed (struct __wprintf_buffer *buf) |
229 | { |
230 | return buf->mode == __wprintf_buffer_mode_failed; |
231 | } |
232 | |
233 | static inline void |
234 | __wprintf_buffer_init (struct __wprintf_buffer *buf, |
235 | wchar_t *base, size_t len, |
236 | enum __wprintf_buffer_mode mode) |
237 | { |
238 | buf->write_base = base; |
239 | buf->write_ptr = base; |
240 | buf->write_end = base + len; |
241 | buf->written = 0; |
242 | buf->mode = mode; |
243 | } |
244 | |
245 | void __wprintf_buffer_putc_1 (struct __wprintf_buffer *buf, wchar_t ch) |
246 | attribute_hidden; |
247 | |
248 | static inline void |
249 | __wprintf_buffer_putc (struct __wprintf_buffer *buf, wchar_t ch) |
250 | { |
251 | if (buf->write_ptr != buf->write_end) |
252 | *buf->write_ptr++ = ch; |
253 | else |
254 | __wprintf_buffer_putc_1 (buf, ch); |
255 | } |
256 | |
257 | void __wprintf_buffer_pad_1 (struct __wprintf_buffer *buf, |
258 | wchar_t ch, size_t count) attribute_hidden; |
259 | |
260 | static inline void |
261 | __wprintf_buffer_pad (struct __wprintf_buffer *buf, char ch, ssize_t count) |
262 | { |
263 | if (count > 0) |
264 | __wprintf_buffer_pad_1 (buf, ch, count); |
265 | } |
266 | |
267 | void __wprintf_buffer_write (struct __wprintf_buffer *buf, const wchar_t *s, |
268 | size_t count) attribute_hidden; |
269 | |
270 | void __wprintf_buffer_puts (struct __wprintf_buffer *buf, const wchar_t *s) |
271 | attribute_hidden; |
272 | |
273 | int __wprintf_buffer_done (struct __wprintf_buffer *buf) attribute_hidden; |
274 | |
275 | bool __wprintf_buffer_flush (struct __wprintf_buffer *buf) attribute_hidden; |
276 | |
277 | /* Type-generic convenience macros. They are useful if |
278 | printf_buffer-char.h or printf_buffer-wchar_t.h is included as |
279 | well. */ |
280 | |
281 | #define Xprintf_buffer Xprintf (buffer) |
282 | #define Xprintf_buffer_done Xprintf (buffer_done) |
283 | #define Xprintf_buffer_flush Xprintf (buffer_flush) |
284 | #define Xprintf_buffer_has_failed Xprintf (buffer_has_failed) |
285 | #define Xprintf_buffer_mark_failed Xprintf (buffer_mark_failed) |
286 | #define Xprintf_buffer_pad Xprintf (buffer_pad) |
287 | #define Xprintf_buffer_putc Xprintf (buffer_putc) |
288 | #define Xprintf_buffer_puts Xprintf (buffer_puts) |
289 | #define Xprintf_buffer_write Xprintf (buffer_write) |
290 | |
291 | /* Commonly used buffers. */ |
292 | |
293 | struct __printf_buffer_snprintf |
294 | { |
295 | struct __printf_buffer base; |
296 | #define PRINTF_BUFFER_SIZE_DISCARD 128 |
297 | char discard[PRINTF_BUFFER_SIZE_DISCARD]; /* Used in counting mode. */ |
298 | }; |
299 | |
300 | /* Sets up [BUFFER, BUFFER + LENGTH) as the write target. If LENGTH |
301 | is positive, also writes a NUL byte to *BUFFER. */ |
302 | void __printf_buffer_snprintf_init (struct __printf_buffer_snprintf *, |
303 | char *buffer, size_t length) |
304 | attribute_hidden; |
305 | |
306 | /* Add the null terminator after everything has been written. The |
307 | return value is the one expected by printf (see __printf_buffer_done). */ |
308 | int __printf_buffer_snprintf_done (struct __printf_buffer_snprintf *) |
309 | attribute_hidden; |
310 | |
311 | /* Flush function implementations follow. They are called from |
312 | __printf_buffer_flush. Generic code should not call these flush |
313 | functions directly. Some modes have inline implementations. */ |
314 | |
315 | void __printf_buffer_flush_snprintf (struct __printf_buffer_snprintf *) |
316 | attribute_hidden; |
317 | struct __printf_buffer_to_file; |
318 | void __printf_buffer_flush_to_file (struct __printf_buffer_to_file *) |
319 | attribute_hidden; |
320 | struct __printf_buffer_asprintf; |
321 | void __printf_buffer_flush_asprintf (struct __printf_buffer_asprintf *) |
322 | attribute_hidden; |
323 | struct __printf_buffer_dprintf; |
324 | void __printf_buffer_flush_dprintf (struct __printf_buffer_dprintf *) |
325 | attribute_hidden; |
326 | struct __printf_buffer_fp; |
327 | void __printf_buffer_flush_fp (struct __printf_buffer_fp *) |
328 | attribute_hidden; |
329 | struct __printf_buffer_fp_to_wide; |
330 | void __printf_buffer_flush_fp_to_wide (struct __printf_buffer_fp_to_wide *) |
331 | attribute_hidden; |
332 | struct __printf_buffer_fphex_to_wide; |
333 | void __printf_buffer_flush_fphex_to_wide (struct |
334 | __printf_buffer_fphex_to_wide *) |
335 | attribute_hidden; |
336 | struct __printf_buffer_obstack; |
337 | void __printf_buffer_flush_obstack (struct __printf_buffer_obstack *) |
338 | attribute_hidden; |
339 | |
340 | struct __wprintf_buffer_to_file; |
341 | void __wprintf_buffer_flush_to_file (struct __wprintf_buffer_to_file *) |
342 | attribute_hidden; |
343 | |
344 | /* Buffer sizes. These can be tuned as necessary. There is a tension |
345 | here between stack consumption, cache usage, and additional system |
346 | calls or heap allocations (if the buffer is too small). |
347 | |
348 | Also see PRINTF_BUFFER_SIZE_DISCARD above for snprintf. */ |
349 | |
350 | /* Fallback buffer if the underlying FILE * stream does not provide |
351 | buffer space. */ |
352 | #define PRINTF_BUFFER_SIZE_TO_FILE_STAGE 128 |
353 | |
354 | /* Temporary buffer used during floating point digit translation. */ |
355 | #define PRINTF_BUFFER_SIZE_DIGITS 64 |
356 | |
357 | /* Size of the initial on-stack buffer for asprintf. It should be |
358 | large enough to copy almost all asprintf usages with just a single |
359 | (final, correctly sized) heap allocation. */ |
360 | #define PRINTF_BUFFER_SIZE_ASPRINTF 200 |
361 | |
362 | /* This should cover most of the packet-oriented file descriptors, |
363 | where boundaries between writes could be visible to readers. But |
364 | it is still small enough not to cause too many stack overflow issues. */ |
365 | #define PRINTF_BUFFER_SIZE_DPRINTF 2048 |
366 | |
367 | #endif /* PRINTF_BUFFER_H */ |
368 | |