]> mj.ucw.cz Git - libucw.git/commitdiff
printf to a growing buffer
authorPavel Charvat <pavel.charvat@netcentrum.cz>
Mon, 18 Sep 2006 12:57:07 +0000 (14:57 +0200)
committerPavel Charvat <pavel.charvat@netcentrum.cz>
Mon, 18 Sep 2006 12:57:07 +0000 (14:57 +0200)
lib/bbuf.c [new file with mode: 0644]
lib/bbuf.h
lib/bbuf.t [new file with mode: 0644]

diff --git a/lib/bbuf.c b/lib/bbuf.c
new file mode 100644 (file)
index 0000000..b664a79
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *     UCW Library -- A simple growing buffers for byte-sized items
+ *
+ *     (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ *     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 <stdio.h>
+
+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, "<Hello, %s!>", "World");
+  fputs(x, stdout);
+  x = bb_ofs_printf(&bb, 5, "<Hello, %50s!>\n", "World");
+  fputs(x, stdout);
+  bb_done(&bb);
+  return 0;
+}
+
+#endif
index 0d17f8ccfb77e372d8fb63d49a6ecf07393555a7..ad7ce39da7160f00aef9cd149d20e9c90d739639 100644 (file)
@@ -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 (file)
index 0000000..cfc70b3
--- /dev/null
@@ -0,0 +1,4 @@
+# Tests for growing buffers
+
+Run:   obj/lib/bbuf-t
+Out:   <Hello, World!><Hello,                                              World!>