chiark / gitweb /
@@@ wip
[mLib] / utils / gprintf.c
index f527186373599d53b271ff4a12fa666610052996..b575e1f4ef495d148cf6cb16e57c69822b599d8b 100644 (file)
@@ -563,6 +563,54 @@ int gprintf(const struct gprintf_ops *ops, void *out, const char *p, ...)
   return (n);
 }
 
+/*----- Utilities ---------------------------------------------------------*/
+
+/* --- @gprintf_memputf@ --- *
+ *
+ * Arguments:  @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
+ *             @va_list *ap@ = captured format-arguments tail
+ *
+ * Returns:    The formatted length.
+ *
+ * Use:                Generic utility for mostly implementing the @nputf@ output
+ *             function, if you don't have a better option.
+ *
+ *             On entry, @*buf_inout@ should be null or a buffer pointer,
+ *             with @*sz_inout@ either zero or the buffer's size,
+ *             respectively.  On exit, @*buf_input@ and @*sz_inout@ will be
+ *             updated, if necessary, to describe a sufficiently large
+ *             buffer, and the formatted string will have been written to
+ *             the buffer.
+ *
+ *             When the buffer is no longer required, free it using @xfree@.
+ */
+
+size_t gprintf_memputf(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;
+  }
+
+#ifdef HAVE_SNPRINTF
+  n = vsnprintf(buf, maxsz + 1, p, ap);
+#else
+  n = vsprintf(buf, p, ap);
+#endif
+  assert(0 <= n && n <= maxsz);
+  return (n);
+}
+
 /*----- Standard printers -------------------------------------------------*/
 
 static int file_putch(void *out, int ch)