]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/obprintf.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / libio / obprintf.c
CommitLineData
2c6fe0bd 1/* Print output of stream to given obstack.
dff8da6b 2 Copyright (C) 1996-2024 Free Software Foundation, Inc.
2c6fe0bd 3 This file is part of the GNU C Library.
2c6fe0bd
UD
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
2c6fe0bd
UD
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
41bdb6e2 13 Lesser General Public License for more details.
2c6fe0bd 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
2c6fe0bd 18
a211d174 19#include <assert.h>
5365acc5 20#include <math_ldbl_opt.h>
2c6fe0bd 21#include <obstack.h>
5365acc5 22#include <printf.h>
2c6fe0bd 23#include <stdarg.h>
5365acc5 24#include <printf_buffer.h>
2c6fe0bd 25
5365acc5 26struct __printf_buffer_obstack
2c6fe0bd 27{
5365acc5 28 struct __printf_buffer base;
2c6fe0bd 29 struct obstack *obstack;
2c6fe0bd 30
5365acc5
FW
31 /* obstack_1grow is called for compatibility reasons. This needs
32 one extra character, and this is the backing store for it. */
33 char ch;
34};
2c6fe0bd 35
5365acc5
FW
36void
37__printf_buffer_flush_obstack (struct __printf_buffer_obstack *buf)
2c6fe0bd 38{
5365acc5
FW
39 /* About to switch buffers, so record the bytes written so far. */
40 buf->base.written += buf->base.write_ptr - buf->base.write_base;
2c6fe0bd 41
5365acc5 42 if (buf->base.write_ptr == &buf->ch + 1)
2c6fe0bd 43 {
5365acc5
FW
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);
2c6fe0bd
UD
53 }
54 else
5365acc5
FW
55 {
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;
60 }
2c6fe0bd
UD
61}
62
2c6fe0bd 63int
698fb75b
ZW
64__obstack_vprintf_internal (struct obstack *obstack, const char *format,
65 va_list args, unsigned int mode_flags)
2c6fe0bd 66{
5365acc5
FW
67 /* Legacy setup code for compatibility. */
68 size_t room = obstack_room (obstack);
69 size_t size = obstack_object_size (obstack) + room;
a211d174
UD
70 if (size == 0)
71 {
a211d174 72 /* Get more memory. */
b420597e 73 obstack_make_room (obstack, 64);
a211d174 74
b420597e 75 /* Recompute how much room we have. */
a211d174 76 room = obstack_room (obstack);
b420597e 77 size = room;
a211d174
UD
78
79 assert (size != 0);
80 }
81
5365acc5
FW
82 struct __printf_buffer_obstack buf;
83 {
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);
89 }
90 buf.obstack = obstack;
91
2c6fe0bd 92 /* Now allocate the rest of the current chunk. */
a211d174
UD
93 obstack_blank_fast (obstack, room);
94
5365acc5 95 __printf_buffer (&buf.base, format, args, mode_flags);
2c6fe0bd 96
5365acc5
FW
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);
2c6fe0bd 103
5365acc5 104 return __printf_buffer_done (&buf.base);
2c6fe0bd 105}
2c6fe0bd 106
698fb75b
ZW
107int
108__obstack_vprintf (struct obstack *obstack, const char *format, va_list ap)
109{
110 return __obstack_vprintf_internal (obstack, format, ap, 0);
111}
112ldbl_weak_alias (__obstack_vprintf, obstack_vprintf)
2c6fe0bd
UD
113
114int
698fb75b 115__obstack_printf (struct obstack *obstack, const char *format, ...)
2c6fe0bd
UD
116{
117 int result;
118 va_list ap;
119 va_start (ap, format);
698fb75b 120 result = __obstack_vprintf_internal (obstack, format, ap, 0);
2c6fe0bd
UD
121 va_end (ap);
122 return result;
123}
698fb75b 124ldbl_weak_alias (__obstack_printf, obstack_printf)