changeset 549:dfd6dcc486a6

Implement optional use of internal printf() implementation for use in th_strdup_vprintf().
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 31 Dec 2019 05:51:33 +0200
parents 41efdd004c3a
children 1d7a85b59a16
files th_string.c
diffstat 1 files changed, 55 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/th_string.c	Tue Dec 31 05:24:15 2019 +0200
+++ b/th_string.c	Tue Dec 31 05:51:33 2019 +0200
@@ -144,14 +144,6 @@
     ctx->ipos++;
     return ch;
 }
-
-
-static int th_stdio_vputch(th_vprintf_ctx *ctx, const char ch)
-{
-    ctx->pos++;
-    ctx->ipos++;
-    return fputc(ch, (FILE *) ctx->data);
-}
 #endif
 
 
@@ -195,6 +187,16 @@
 }
 
 
+#ifdef TH_USE_INTERNAL_SPRINTF
+static int th_stdio_vputch(th_vprintf_ctx *ctx, const char ch)
+{
+    ctx->pos++;
+    ctx->ipos++;
+    return fputc(ch, (FILE *) ctx->data);
+}
+#endif
+
+
 int th_vfprintf(FILE *fh, const char *fmt, va_list ap)
 {
 #ifdef TH_USE_INTERNAL_SPRINTF
@@ -213,10 +215,11 @@
 int th_fprintf(FILE *fh, const char *fmt, ...)
 {
     int ret;
+    va_list ap;
 #ifdef TH_USE_INTERNAL_SPRINTF
     th_vprintf_ctx ctx;
 #endif
-    va_list ap;
+
     va_start(ap, fmt);
 #ifdef TH_USE_INTERNAL_SPRINTF
     ctx.data = (void *) fh;
@@ -228,14 +231,56 @@
     ret = fprintf(fh, fmt, ap);
 #endif
     va_end(ap);
+
     return ret;
 }
 
 
 /* Simulate a sprintf() that allocates memory
  */
+#ifdef TH_USE_INTERNAL_SPRINTF
+static int th_pbuf_alloc_vputch1(th_vprintf_ctx *ctx, const char ch)
+{
+    ctx->pos++;
+    return ch;
+}
+
+static int th_pbuf_alloc_vputch2(th_vprintf_ctx *ctx, const char ch)
+{
+    ctx->buf[ctx->pos++] = ch;
+    return ch;
+}
+#endif
+
+
 char *th_strdup_vprintf(const char *fmt, va_list args)
 {
+#ifdef TH_USE_INTERNAL_SPRINTF
+    // Using internal printf() implementation
+    th_vprintf_ctx ctx;
+    va_list ap;
+
+    // Get size
+    va_copy(ap, args);
+    ctx.pos = 0;
+    th_vprintf_do(&ctx, th_pbuf_alloc_vputch1, fmt, ap);
+    va_end(ap);
+
+    // Allocate memory
+    ctx.size = ctx.pos + 1;
+    if ((ctx.buf = th_malloc(ctx.size)) == NULL)
+        return NULL;
+
+    va_copy(ap, args);
+    ctx.pos = 0;
+    th_vprintf_do(&ctx, th_pbuf_alloc_vputch2, fmt, ap);
+    va_end(ap);
+    ctx.buf[ctx.pos] = 0;
+
+    return ctx.buf;
+
+#else
+    // Using libc vsnprintf()
     int size = 64;
     char *buf, *tmp;
 
@@ -268,6 +313,7 @@
         else
             buf = tmp;
     }
+#endif
 }