From: Pavel Charvat Date: Mon, 18 Sep 2006 12:57:07 +0000 (+0200) Subject: printf to a growing buffer X-Git-Tag: holmes-import~533 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=6a3e2a5bc9b84ac6b0b8efc38455fb93a212fea7;p=libucw.git printf to a growing buffer --- diff --git a/lib/bbuf.c b/lib/bbuf.c new file mode 100644 index 00000000..b664a79d --- /dev/null +++ b/lib/bbuf.c @@ -0,0 +1,70 @@ +/* + * UCW Library -- A simple growing buffers for byte-sized items + * + * (c) 2006 Pavel Charvat + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include "lib/lib.h" +#include "lib/bbuf.h" + +#include + +char * +bb_ofs_vprintf(bb_t *bb, uns ofs, char *fmt, va_list args) +{ + bb_grow(bb, ofs + 1); + va_list args2; + va_copy(args2, args); + int cnt = vsnprintf(bb->ptr + ofs, bb->len - ofs, fmt, args2); + va_end(args2); + if (cnt < 0) + { + /* Our C library doesn't support C99 return value of vsnprintf, so we need to iterate */ + do + { + bb_do_grow(bb, bb->len + 1); + va_copy(args2, args); + cnt = vsnprintf(bb->ptr + ofs, bb->len - ofs, fmt, args2); + va_end(args2); + } + while (cnt < 0); + } + else if (cnt >= bb->len - ofs) + { + bb_do_grow(bb, ofs + cnt + 1); + va_copy(args2, args); + int cnt2 = vsnprintf(bb->ptr + ofs, bb->len - ofs, fmt, args2); + va_end(args2); + ASSERT(cnt2 == cnt); + } + return bb->ptr + ofs; +} + +char * +bb_ofs_printf(bb_t *bb, uns ofs, char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + char *res = bb_ofs_vprintf(bb, ofs, fmt, args); + va_end(args); + return res; +} + +#ifdef TEST + +int main(void) +{ + bb_t bb; + bb_init(&bb); + char *x = bb_ofs_printf(&bb, 0, "", "World"); + fputs(x, stdout); + x = bb_ofs_printf(&bb, 5, "\n", "World"); + fputs(x, stdout); + bb_done(&bb); + return 0; +} + +#endif diff --git a/lib/bbuf.h b/lib/bbuf.h index 0d17f8cc..ad7ce39d 100644 --- a/lib/bbuf.h +++ b/lib/bbuf.h @@ -14,4 +14,7 @@ #define GBUF_PREFIX(x) bb_##x #include "lib/gbuf.h" +char *bb_ofs_vprintf(bb_t *bb, uns ofs, char *fmt, va_list args); +char *bb_ofs_printf(bb_t *bb, uns ofs, char *fmt, ...); + #endif diff --git a/lib/bbuf.t b/lib/bbuf.t new file mode 100644 index 00000000..cfc70b31 --- /dev/null +++ b/lib/bbuf.t @@ -0,0 +1,4 @@ +# Tests for growing buffers + +Run: obj/lib/bbuf-t +Out: