X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/912f6431247d27e2144c5c078bd47396d95f5175..08bb7015a9e28c5c9d38fe05a6f6644bc21fa527:/utils/gprintf.c diff --git a/utils/gprintf.c b/utils/gprintf.c index 8825bd1..45cd35a 100644 --- a/utils/gprintf.c +++ b/utils/gprintf.c @@ -48,6 +48,7 @@ #include "darray.h" #include "dstr.h" #include "gprintf.h" +#include "growbuf.h" #include "macros.h" /*----- Tunable constants -------------------------------------------------*/ @@ -373,7 +374,7 @@ int vgprintf(const struct gprintf_ops *ops, void *out, break; default: fprintf(stderr, - "FATAL dstr_vputf: unknown format specifier `%c'\n", p[-1]); + "FATAL vgprintf: unknown format specifier `%c'\n", p[-1]); abort(); } @@ -408,8 +409,8 @@ int vgprintf(const struct gprintf_ops *ops, void *out, /* --- Output the literal portion --- */ if (fs->n) { - if (ops->putm(out, fs->p, fs->n)) return (-1); - tot += fs->n; + n = ops->putm(out, fs->p, fs->n); if (n < 0) return (-1); + tot += n; } /* --- And now the variable portion --- */ @@ -419,8 +420,8 @@ int vgprintf(const struct gprintf_ops *ops, void *out, case 0: break; case '%': - if (ops->putch(out, '%')) return (-1); - tot++; break; + n = ops->putch(out, '%'); if (n < 0) return (-1); + tot += n; break; default: abort(); } @@ -500,8 +501,8 @@ int vgprintf(const struct gprintf_ops *ops, void *out, break; #else # define MSG "" - if (ops->putm(out, MSG, sizeof(MSG) - 1)) return (-1); - tot += sizeof(MSG) - 1; continue; + n = ops->putm(out, MSG, sizeof(MSG) - 1); if (n < 0) return (-1); + tot += n; continue; # undef MSG #endif case 's': @@ -526,14 +527,14 @@ int vgprintf(const struct gprintf_ops *ops, void *out, switch (fs->fmt) { #define CASE(code, ty) \ case fmt_##code: \ - i = ops->nputf(out, sz, dd.buf, fa[fs->arg].u.code); \ + n = ops->nputf(out, sz, dd.buf, fa[fs->arg].u.code); \ break; OUTPUT_FMTTYPES(CASE) #undef CASE default: abort(); } - if (i < 0) return (-1); - tot += i; + if (n < 0) return (-1); + tot += n; } /* --- We're done --- */ @@ -571,7 +572,8 @@ int gprintf(const struct gprintf_ops *ops, void *out, const char *p, ...) /* --- @gprintf_memputf@ --- * * - * Arguments: @char **buf_inout@ = address of output buffer pointer + * Arguments: @arena *a@ = memory allocation arena + * @char **buf_inout@ = address of output buffer pointer * @size_t *sz_inout@ = address of buffer size * @size_t maxsz@ = buffer size needed for this operation * @const char *p@ = pointer to format string @@ -589,27 +591,20 @@ int gprintf(const struct gprintf_ops *ops, void *out, const char *p, ...) * buffer, and the formatted string will have been written to * the buffer. * - * When the buffer is no longer required, free it using @xfree@. + * When the buffer is no longer required, free it using + * @x_free@. */ -size_t gprintf_memputf(char **buf_inout, size_t *sz_inout, - size_t maxsz, const char *p, va_list ap) +size_t gprintf_memputf(arena *a, char **buf_inout, size_t *sz_inout, + size_t maxsz, const char *p, va_list ap) { - char *buf = *buf_inout; - size_t sz = *sz_inout; int n; - if (sz <= maxsz) { - if (!sz) sz = 32; - while (sz <= maxsz) sz *= 2; - if (buf) xfree(buf); - buf = xmalloc(sz); *buf_inout = buf; *sz_inout = sz; - } - + GROWBUF_REPLACE(size_t, a, *buf_inout, *sz_inout, maxsz, 64, 1); #ifdef HAVE_SNPRINTF - n = vsnprintf(buf, maxsz + 1, p, ap); + n = vsnprintf(*buf_inout, maxsz + 1, p, ap); #else - n = vsprintf(buf, p, ap); + n = vsprintf(*buf_inout, p, ap); #endif assert(0 <= n && n <= maxsz); return (n);