Skip to content

Commit ebeb609

Browse files
peffgitster
authored andcommitted
strbuf: add strbuf_vaddf
In a variable-args function, the code for writing into a strbuf is non-trivial. We ended up cutting and pasting it in several places because there was no vprintf-style function for strbufs (which in turn was held up by a lack of va_copy). Now that we have a fallback va_copy, we can add strbuf_vaddf, the strbuf equivalent of vsprintf. And we can clean up the cut and paste mess. Signed-off-by: Jeff King <[email protected]> Improved-by: Christian Couder <[email protected]> Signed-off-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ab8632a commit ebeb609

File tree

5 files changed

+25
-63
lines changed

5 files changed

+25
-63
lines changed

fsck.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -347,26 +347,14 @@ int fsck_object(struct object *obj, int strict, fsck_error error_func)
347347
int fsck_error_function(struct object *obj, int type, const char *fmt, ...)
348348
{
349349
va_list ap;
350-
int len;
351350
struct strbuf sb = STRBUF_INIT;
352351

353352
strbuf_addf(&sb, "object %s:", obj->sha1?sha1_to_hex(obj->sha1):"(null)");
354353

355354
va_start(ap, fmt);
356-
len = vsnprintf(sb.buf + sb.len, strbuf_avail(&sb), fmt, ap);
355+
strbuf_vaddf(&sb, fmt, ap);
357356
va_end(ap);
358357

359-
if (len < 0)
360-
len = 0;
361-
if (len >= strbuf_avail(&sb)) {
362-
strbuf_grow(&sb, len + 2);
363-
va_start(ap, fmt);
364-
len = vsnprintf(sb.buf + sb.len, strbuf_avail(&sb), fmt, ap);
365-
va_end(ap);
366-
if (len >= strbuf_avail(&sb))
367-
die("this should not happen, your snprintf is broken");
368-
}
369-
370358
error("%s", sb.buf);
371359
strbuf_release(&sb);
372360
return 1;

merge-recursive.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ static void flush_output(struct merge_options *o)
137137
__attribute__((format (printf, 3, 4)))
138138
static void output(struct merge_options *o, int v, const char *fmt, ...)
139139
{
140-
int len;
141140
va_list ap;
142141

143142
if (!show(o, v))
@@ -148,21 +147,9 @@ static void output(struct merge_options *o, int v, const char *fmt, ...)
148147
strbuf_setlen(&o->obuf, o->obuf.len + o->call_depth * 2);
149148

150149
va_start(ap, fmt);
151-
len = vsnprintf(o->obuf.buf + o->obuf.len, strbuf_avail(&o->obuf), fmt, ap);
150+
strbuf_vaddf(&o->obuf, fmt, ap);
152151
va_end(ap);
153152

154-
if (len < 0)
155-
len = 0;
156-
if (len >= strbuf_avail(&o->obuf)) {
157-
strbuf_grow(&o->obuf, len + 2);
158-
va_start(ap, fmt);
159-
len = vsnprintf(o->obuf.buf + o->obuf.len, strbuf_avail(&o->obuf), fmt, ap);
160-
va_end(ap);
161-
if (len >= strbuf_avail(&o->obuf)) {
162-
die("this should not happen, your snprintf is broken");
163-
}
164-
}
165-
strbuf_setlen(&o->obuf, o->obuf.len + len);
166153
strbuf_add(&o->obuf, "\n", 1);
167154
if (!o->buffer_output)
168155
flush_output(o);

strbuf.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,24 +195,29 @@ void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len)
195195

196196
void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
197197
{
198-
int len;
199198
va_list ap;
199+
va_start(ap, fmt);
200+
strbuf_vaddf(sb, fmt, ap);
201+
va_end(ap);
202+
}
203+
204+
void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
205+
{
206+
int len;
207+
va_list cp;
200208

201209
if (!strbuf_avail(sb))
202210
strbuf_grow(sb, 64);
203-
va_start(ap, fmt);
204-
len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
205-
va_end(ap);
211+
va_copy(cp, ap);
212+
len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, cp);
213+
va_end(cp);
206214
if (len < 0)
207-
die("your vsnprintf is broken");
215+
die("BUG: your vsnprintf is broken (returned %d)", len);
208216
if (len > strbuf_avail(sb)) {
209217
strbuf_grow(sb, len);
210-
va_start(ap, fmt);
211218
len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
212-
va_end(ap);
213-
if (len > strbuf_avail(sb)) {
214-
die("this should not happen, your snprintf is broken");
215-
}
219+
if (len > strbuf_avail(sb))
220+
die("BUG: your vsnprintf is broken (insatiable)");
216221
}
217222
strbuf_setlen(sb, sb->len + len);
218223
}

strbuf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *
120120

121121
__attribute__((format (printf,2,3)))
122122
extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
123+
__attribute__((format (printf,2,0)))
124+
extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
123125

124126
extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
125127
/* XXX: if read fails, any partial read is undone */

trace.c

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,28 +64,18 @@ static const char err_msg[] = "Could not trace into fd given by "
6464

6565
void trace_printf(const char *fmt, ...)
6666
{
67-
struct strbuf buf;
67+
struct strbuf buf = STRBUF_INIT;
6868
va_list ap;
69-
int fd, len, need_close = 0;
69+
int fd, need_close = 0;
7070

7171
fd = get_trace_fd(&need_close);
7272
if (!fd)
7373
return;
7474

7575
set_try_to_free_routine(NULL); /* is never reset */
76-
strbuf_init(&buf, 64);
7776
va_start(ap, fmt);
78-
len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap);
77+
strbuf_vaddf(&buf, fmt, ap);
7978
va_end(ap);
80-
if (len >= strbuf_avail(&buf)) {
81-
strbuf_grow(&buf, len - strbuf_avail(&buf) + 128);
82-
va_start(ap, fmt);
83-
len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap);
84-
va_end(ap);
85-
if (len >= strbuf_avail(&buf))
86-
die("broken vsnprintf");
87-
}
88-
strbuf_setlen(&buf, len);
8979

9080
write_or_whine_pipe(fd, buf.buf, buf.len, err_msg);
9181
strbuf_release(&buf);
@@ -96,28 +86,18 @@ void trace_printf(const char *fmt, ...)
9686

9787
void trace_argv_printf(const char **argv, const char *fmt, ...)
9888
{
99-
struct strbuf buf;
89+
struct strbuf buf = STRBUF_INIT;
10090
va_list ap;
101-
int fd, len, need_close = 0;
91+
int fd, need_close = 0;
10292

10393
fd = get_trace_fd(&need_close);
10494
if (!fd)
10595
return;
10696

10797
set_try_to_free_routine(NULL); /* is never reset */
108-
strbuf_init(&buf, 64);
10998
va_start(ap, fmt);
110-
len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap);
99+
strbuf_vaddf(&buf, fmt, ap);
111100
va_end(ap);
112-
if (len >= strbuf_avail(&buf)) {
113-
strbuf_grow(&buf, len - strbuf_avail(&buf) + 128);
114-
va_start(ap, fmt);
115-
len = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap);
116-
va_end(ap);
117-
if (len >= strbuf_avail(&buf))
118-
die("broken vsnprintf");
119-
}
120-
strbuf_setlen(&buf, len);
121101

122102
sq_quote_argv(&buf, argv, 0);
123103
strbuf_addch(&buf, '\n');

0 commit comments

Comments
 (0)