changeset 251:7b76108248e9

More work on printing functions.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 16 Feb 2016 20:32:02 +0200
parents f4b541e0433e
children 80ffeb316596
files th_string.c th_string.h
diffstat 2 files changed, 38 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/th_string.c	Tue Feb 16 19:05:00 2016 +0200
+++ b/th_string.c	Tue Feb 16 20:32:02 2016 +0200
@@ -111,7 +111,7 @@
 //
 // Simple implementations of printf() type functions
 //
-static int th_vput_int(void *ctx, int (*vputch)(void *ctx, const char ch),
+static int th_vput_int(th_printf_ctx *ctx, int (*vputch)(th_printf_ctx *ctx, const char ch),
     int val, const int radix, const char padMode, const char padChar,
     const int width, const BOOL unsig, const BOOL upcase, const BOOL sign)
 {
@@ -191,7 +191,7 @@
 }
 
 
-static int th_vput_str(void *ctx, int (*vputch)(void *ctx, const char ch),
+static int th_vput_str(th_printf_ctx *ctx, int (*vputch)(th_printf_ctx *ctx, const char ch),
     const char *str, const char padMode, const char padChar,
     const int width, const int prec)
 {
@@ -234,7 +234,9 @@
 }
 
 
-int th_vprintf_do(void *ctx, int (*vputch)(void *ctx, const char ch), const char *fmt, va_list ap)
+int th_vprintf_do(th_printf_ctx *ctx,
+    int (*vputch)(th_printf_ctx *ctx, const char ch),
+    const char *fmt, va_list ap, const BOOL eol)
 {
     int ret = 0;
 
@@ -294,10 +296,6 @@
 
             switch (*fmt)
             {
-                case '%':
-                    vputch(ctx, *fmt);
-                    break;
-
                 case 0:
                     return -104;
 
@@ -341,30 +339,27 @@
                         goto out;
                     break;
 
+                case '%':
                 default:
-                    vputch(ctx, *fmt);
+                    if ((ret = vputch(ctx, *fmt)) == EOF)
+                        goto out;
                     break;
             }
         }
         fmt++;
     }
 
+    if (eol)
+        ret = vputch(ctx, 0);
+
 out:
-    return ret;
+    return ret == EOF ? ret : ctx->pos - 1;
 }
 
 
 #ifdef TH_USE_INTERNAL_SPRINTF
-typedef struct
+static int th_pbuf_vputch(th_printf_ctx *ctx, const char ch)
 {
-    char *buf;
-    size_t size, pos;
-} th_pbuf_ctx;
-
-
-static int th_pbuf_vputch(void *pctx, const char ch)
-{
-    th_pbuf_ctx *ctx = (th_pbuf_ctx *) pctx;
     if (ctx->pos < ctx->size)
         ctx->buf[ctx->pos] = ch;
     ctx->pos++;
@@ -372,9 +367,10 @@
 }
 
 
-static int th_stdio_vputch(void *ctx, const char ch)
+static int th_stdio_vputch(th_printf_ctx *ctx, const char ch)
 {
-    return fputc(ch, (FILE *) ctx);
+    ctx->pos++;
+    return fputc(ch, (FILE *) ctx->data);
 }
 #endif
 
@@ -382,12 +378,12 @@
 int th_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
 {
 #ifdef TH_USE_INTERNAL_SPRINTF
-    th_pbuf_ctx ctx;
+    th_printf_ctx ctx;
     ctx.buf = buf;
     ctx.size = size;
     ctx.pos = 0;
 
-    return th_vprintf_do((void *) &ctx, th_pbuf_vputch, fmt, ap);
+    return th_vprintf_do(&ctx, th_pbuf_vputch, fmt, ap, TRUE);
 #else
     return vsnprintf(buf, size, fmt, ap);
 #endif
@@ -412,7 +408,11 @@
 int th_vfprintf(FILE *fh, const char *fmt, va_list ap)
 {
 #ifdef TH_USE_INTERNAL_SPRINTF
-    return th_vprintf_do((void *) fh, th_stdio_vputch, fmt, ap);
+    th_printf_ctx ctx;
+    ctx.data = (void *) fh;
+    ctx.pos = 0;
+
+    return th_vprintf_do(&ctx, th_stdio_vputch, fmt, ap, FALSE);
 #else
     return vfprintf(fh, fmt, ap);
 #endif
@@ -422,10 +422,15 @@
 int th_fprintf(FILE *fh, const char *fmt, ...)
 {
     int ret;
+#ifdef TH_USE_INTERNAL_SPRINTF
+    th_printf_ctx ctx;
+#endif
     va_list ap;
     va_start(ap, fmt);
 #ifdef TH_USE_INTERNAL_SPRINTF
-    ret = th_vprintf_do((void *) fh, th_stdio_vputch, fmt, ap);
+    ctx.data = (void *) fh;
+    ctx.pos = 0;
+    ret = th_vprintf_do(&ctx, th_stdio_vputch, fmt, ap, FALSE);
 #else
     ret = fprintf(fh, fmt, ap);
 #endif
--- a/th_string.h	Tue Feb 16 19:05:00 2016 +0200
+++ b/th_string.h	Tue Feb 16 20:32:02 2016 +0200
@@ -48,6 +48,14 @@
 };
 
 
+typedef struct
+{
+    char *buf;
+    size_t size, pos;
+    void *data;
+} th_printf_ctx;
+
+
 /* Normal NUL-terminated string functions
  */
 char    *th_strdup(const char *src);
@@ -60,7 +68,7 @@
 char    *th_strrcasecmp(char *haystack, const char *needle);
 void    th_strip_ctrlchars(char *str);
 
-int     th_vprintf_do(void *ctx, int (*vputch)(void *ctx, const char ch), const char *fmt, va_list ap);
+int     th_vprintf_do(th_printf_ctx *ctx, int (*vputch)(th_printf_ctx *ctx, const char ch), const char *fmt, va_list ap, const BOOL eol);
 int     th_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap);
 int     th_snprintf(char *buf, size_t size, const char *fmt, ...);
 int     th_vfprintf(FILE *fh, const char *fmt, va_list ap);