1 /* A buffer that accumulates a string by piecewise concatenation.
2 Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation, either version 3 of the
7 License, or (at your option) any later version.
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2021. */
22 #include "string-buffer.h"
25 extern int sb_ensure_more_bytes (struct string_buffer
*buffer
,
34 sb_appendvf (struct string_buffer
*buffer
, const char *formatstring
,
39 /* Make a bit of room, so that the probability that the first vsnzprintf()
40 call succeeds is high. */
41 size_t room
= buffer
->allocated
- buffer
->length
;
44 if (sb_ensure_more_bytes (buffer
, 64) < 0)
50 room
= buffer
->allocated
- buffer
->length
;
53 va_copy (list_copy
, list
);
55 /* First vsnzprintf() call. */
56 ptrdiff_t ret
= vsnzprintf (buffer
->data
+ buffer
->length
, room
,
60 /* Failed. errno is set. */
68 /* The result has fit into room bytes. */
69 buffer
->length
+= (size_t) ret
;
74 /* The result was truncated. Make more room, for a second
76 if (sb_ensure_more_bytes (buffer
, (size_t) ret
) < 0)
84 /* Second vsnzprintf() call. */
85 room
= buffer
->allocated
- buffer
->length
;
86 ret
= vsnzprintf (buffer
->data
+ buffer
->length
, room
,
87 formatstring
, list_copy
);
90 /* Failed. errno is set. */
98 /* The result has fit into room bytes. */
99 buffer
->length
+= (size_t) ret
;
103 /* The return values of the vsnzprintf() calls are not
116 sb_appendf (struct string_buffer
*buffer
, const char *formatstring
, ...)
120 /* Make a bit of room, so that the probability that the first vsnzprintf()
121 call succeeds is high. */
122 size_t room
= buffer
->allocated
- buffer
->length
;
125 if (sb_ensure_more_bytes (buffer
, 64) < 0)
127 buffer
->error
= true;
131 room
= buffer
->allocated
- buffer
->length
;
134 va_start (args
, formatstring
);
136 /* First vsnzprintf() call. */
137 ptrdiff_t ret
= vsnzprintf (buffer
->data
+ buffer
->length
, room
,
141 /* Failed. errno is set. */
142 buffer
->error
= true;
149 /* The result has fit into room bytes. */
150 buffer
->length
+= (size_t) ret
;
155 /* The result was truncated. Make more room, for a second
156 vsnzprintf() call. */
157 if (sb_ensure_more_bytes (buffer
, (size_t) ret
) < 0)
159 buffer
->error
= true;
165 /* Second vsnzprintf() call. */
166 room
= buffer
->allocated
- buffer
->length
;
168 va_start (args
, formatstring
);
169 ret
= vsnzprintf (buffer
->data
+ buffer
->length
, room
,
173 /* Failed. errno is set. */
174 buffer
->error
= true;
181 /* The result has fit into room bytes. */
182 buffer
->length
+= (size_t) ret
;
186 /* The return values of the vsnzprintf() calls are not