1 /* Print output of stream to given obstack.
2 Copyright (C) 1996-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
20 #include <math_ldbl_opt.h>
24 #include <printf_buffer.h>
26 struct __printf_buffer_obstack
28 struct __printf_buffer base
;
29 struct obstack
*obstack
;
31 /* obstack_1grow is called for compatibility reasons. This needs
32 one extra character, and this is the backing store for it. */
37 __printf_buffer_flush_obstack (struct __printf_buffer_obstack
*buf
)
39 /* About to switch buffers, so record the bytes written so far. */
40 buf
->base
.written
+= buf
->base
.write_ptr
- buf
->base
.write_base
;
42 if (buf
->base
.write_ptr
== &buf
->ch
+ 1)
44 /* Errors are reported via a callback mechanism (presumably for
45 process termination). */
46 obstack_1grow (buf
->obstack
, buf
->ch
);
47 buf
->base
.write_base
= obstack_next_free (buf
->obstack
);
48 buf
->base
.write_ptr
= buf
->base
.write_base
;
49 size_t size
= obstack_room (buf
->obstack
);
50 buf
->base
.write_end
= buf
->base
.write_ptr
+ size
;
51 /* Reserve the space on the obstack size. */
52 obstack_blank_fast (buf
->obstack
, size
);
56 /* Obtain the extra character. */
57 buf
->base
.write_base
= &buf
->ch
;
58 buf
->base
.write_ptr
= &buf
->ch
;
59 buf
->base
.write_end
= &buf
->ch
+ 1;
64 __obstack_vprintf_internal (struct obstack
*obstack
, const char *format
,
65 va_list args
, unsigned int mode_flags
)
67 /* Legacy setup code for compatibility. */
68 size_t room
= obstack_room (obstack
);
69 size_t size
= obstack_object_size (obstack
) + room
;
72 /* Get more memory. */
73 obstack_make_room (obstack
, 64);
75 /* Recompute how much room we have. */
76 room
= obstack_room (obstack
);
82 struct __printf_buffer_obstack buf
;
84 /* The obstack write location might be in the middle of an object. */
85 char *ptr
= obstack_next_free (obstack
);
86 char *end
= obstack_base (obstack
) + size
;
87 __printf_buffer_init (&buf
.base
, ptr
, end
- ptr
,
88 __printf_buffer_mode_obstack
);
90 buf
.obstack
= obstack
;
92 /* Now allocate the rest of the current chunk. */
93 obstack_blank_fast (obstack
, room
);
95 __printf_buffer (&buf
.base
, format
, args
, mode_flags
);
97 if (buf
.base
.write_ptr
== &buf
.ch
+ 1)
98 /* buf.ch is in use. Put it into the obstack. */
99 obstack_1grow (buf
.obstack
, buf
.ch
);
100 else if (buf
.base
.write_ptr
!= &buf
.ch
)
101 /* Shrink the buffer to the space we really currently need. */
102 obstack_blank_fast (buf
.obstack
, buf
.base
.write_ptr
- buf
.base
.write_end
);
104 return __printf_buffer_done (&buf
.base
);
108 __obstack_vprintf (struct obstack
*obstack
, const char *format
, va_list ap
)
110 return __obstack_vprintf_internal (obstack
, format
, ap
, 0);
112 ldbl_weak_alias (__obstack_vprintf
, obstack_vprintf
)
115 __obstack_printf (struct obstack
*obstack
, const char *format
, ...)
119 va_start (ap
, format
);
120 result
= __obstack_vprintf_internal (obstack
, format
, ap
, 0);
124 ldbl_weak_alias (__obstack_printf
, obstack_printf
)