changeset 336:cda5a2aebbb6

Refactor things to be simpler.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 23 Feb 2016 15:26:29 +0200
parents 11d97063d6dd
children 5d3601778dff
files th_printf1.c th_string.c th_string.h
diffstat 3 files changed, 129 insertions(+), 125 deletions(-) [+]
line wrap: on
line diff
--- a/th_printf1.c	Tue Feb 23 14:59:07 2016 +0200
+++ b/th_printf1.c	Tue Feb 23 15:26:29 2016 +0200
@@ -6,69 +6,46 @@
  * Please read file 'COPYING' for information on license and distribution.
  */
 
-static int TH_PFUNC_NAME (th_printf_ctx *ctx, th_printf_vputch vputch,
-#ifdef TH_PFUNC_SIGNED
-    TH_PFUNC_TYPE_S pval,
-#else
-    TH_PFUNC_TYPE_U val,
-#endif
-    const int radix, const int f_flags, const int f_width, const int f_prec,
-#ifdef TH_PFUNC_SIGNED
-    const BOOL unsig,
-#endif
-    const BOOL upcase)
+static int TH_PFUNC_NAME (char *buf, const int len, int *pos,
+    TH_PFUNC_TYPE_S pval, const int f_radix, const int f_flags,
+    const int f_prec, const BOOL f_unsig, BOOL *f_neg)
 {
-    char buf[64];
-    size_t pos = 0;
-    char f_sign = 0;
-#ifdef TH_PFUNC_SIGNED
-    BOOL neg = FALSE;
-#endif
+    const BOOL f_upcase = f_flags & TH_PF_UPCASE;
 
-    if (radix > 16)
+    if (f_radix > 16)
         return EOF;
 
-#ifdef TH_PFUNC_SIGNED
     // Check for negative value
-    if (!unsig && pval < 0)
+    if (!f_unsig && pval < 0)
     {
-        neg = TRUE;
+        *f_neg = TRUE;
         pval = -pval;
     }
+    else
+        *f_neg = FALSE;
 
     // Render the value to a string in buf (reversed)
     TH_PFUNC_TYPE_U val = pval;
-#endif
 
     // Special case for value of 0 and precision 0
     if (val == 0 && f_prec == 0)
         return 0;
 
+    *pos = 0;
     do
     {
-        TH_PFUNC_TYPE_U digit = val % radix;
+        TH_PFUNC_TYPE_U digit = val % f_radix;
         if (digit < 10)
-            buf[pos] = '0' + digit;
+            buf[*pos] = '0' + digit;
         else
-            buf[pos] = (upcase ? 'A' : 'a') + digit - 10;
-        val /= radix;
-        pos++;
+            buf[*pos] = (f_upcase ? 'A' : 'a') + digit - 10;
+        val /= f_radix;
+        (*pos)++;
     }
-    while (val > 0 && pos < sizeof(buf) - 1);
-    buf[pos] = 0;
+    while (val > 0 && *pos < len - 1);
+    buf[*pos] = 0;
 
-    // Oops, the value did not fit in the buffer!
-    if (val > 0)
-        return EOF;
-
-    // Do we want a sign prefix? Not for unsigned values
-#ifdef TH_PFUNC_SIGNED
-    if (!unsig)
-        f_sign = (f_flags & TH_PF_SIGN) ? (neg ? '-' : '+') : (neg ? '-' : ((f_flags & TH_PF_SPACE) ? ' ' : 0));
-#endif
-
-    // Output the data
-    return th_printf_vput_intstr(ctx, vputch, buf, f_width, pos, f_prec, f_flags, f_sign);
+    return (val > 0) ? EOF : 1;
 }
 
 
--- a/th_string.c	Tue Feb 23 14:59:07 2016 +0200
+++ b/th_string.c	Tue Feb 23 15:26:29 2016 +0200
@@ -124,20 +124,37 @@
 //
 // Simple implementations of printf() type functions
 //
+static int th_printf_vput_pstr(th_printf_ctx *ctx, th_printf_vputch vputch, const char *str)
+{
+    while (*str)
+    {
+        int ret;
+        if ((ret = vputch(ctx, *str++)) == EOF)
+            return ret;
+    }
+    return 0;
+}
+
+
+static int th_printf_vput_repch(th_printf_ctx *ctx, th_printf_vputch vputch, int count, const char ch)
+{
+    while (count-- > 0)
+    {
+        int ret;
+        if ((ret = vputch(ctx, ch)) == EOF)
+            return ret;
+    }
+    return 0;
+}
+
+
 static int th_printf_pad_pre(th_printf_ctx *ctx, th_printf_vputch vputch,
     int f_width, const int f_flags)
 {
     if (f_width > 0 && (f_flags & TH_PF_LEFT) == 0)
-    {
-        const char pad = (f_flags & TH_PF_ZERO) ? '0' : ' ';
-        while (f_width--)
-        {
-            int ret;
-            if ((ret = vputch(ctx, pad)) == EOF)
-                return ret;
-        }
-    }
-    return 0;
+        return th_printf_vput_repch(ctx, vputch, f_width, (f_flags & TH_PF_ZERO) ? '0' : ' ');
+    else
+        return 0;
 }
 
 
@@ -145,28 +162,62 @@
     int f_width, const int f_flags)
 {
     if (f_width > 0 && (f_flags & TH_PF_LEFT))
-    {
-        const char pad = ' ';
-        while (f_width--)
-        {
-            int ret;
-            if ((ret = vputch(ctx, pad)) == EOF)
-                return ret;
-        }
-    }
-    return 0;
+        return th_printf_vput_repch(ctx, vputch, f_width, ' ');
+    else
+        return 0;
 }
 
 
-int th_printf_vput_intstr(th_printf_ctx *ctx, th_printf_vputch vputch,
-    const char *buf, const int f_width, int f_len, int f_prec, int f_flags,
-    const char f_sign)
+#define TH_PFUNC_NAME th_printf_vbuf_int
+#define TH_PFUNC_TYPE_S int
+#define TH_PFUNC_TYPE_U unsigned int
+#include "th_printf1.c"
+
+
+#define TH_PFUNC_NAME th_printf_vbuf_int64
+#define TH_PFUNC_TYPE_S int64_t
+#define TH_PFUNC_TYPE_U uint64_t
+#include "th_printf1.c"
+
+
+//#define TH_PFUNC_NAME th_printf_vput_size_t
+//#define TH_PFUNC_TYPE_U size_t
+//#include "th_printf1.c"
+
+
+static int th_printf_vput_int(th_printf_ctx *ctx, th_printf_vputch vputch, va_list ap,
+    const int f_radix, int f_flags, int f_width, int f_prec,
+    const BOOL f_unsig, char *(f_alt)(const int flags))
 {
-    // Calculate necessary padding, if any
-    int ret, nwidth;
+    char buf[64];
+    int f_len = 0, ret = 0, nwidth;
+    char f_sign, *f_altstr;
+    BOOL f_neg = FALSE;
+
 
+    if (f_flags & TH_PF_LONGLONG)
+    {
+        ret = th_printf_vbuf_int64(buf, sizeof(buf), &f_len, va_arg(ap, int64_t),
+            f_radix, f_flags, f_prec, f_unsig, &f_neg);
+    }
+    else
+    {
+       ret = th_printf_vbuf_int(buf, sizeof(buf), &f_len, va_arg(ap, unsigned int),
+            f_radix, f_flags, f_prec, f_unsig, &f_neg);
+    }
+
+    f_altstr = ret != 0 && (f_flags & TH_PF_ALT) && f_alt != NULL ? f_alt(f_flags) : NULL;
+    if (f_flags & TH_PF_ALT) f_width = 0;
+
+    if (ret == EOF)
+        return ret;
+
+    // Are we using a sign prefix?
+    f_sign = f_unsig ? 0 : ((f_flags & TH_PF_SIGN) ? (f_neg ? '-' : '+') : (f_neg ? '-' : ((f_flags & TH_PF_SPACE) ? ' ' : 0)));
+
+    // Calculate necessary padding, etc
     f_prec = (f_prec > f_len) ? f_prec - f_len : 0;
-    nwidth = f_width - f_len - f_prec - (f_sign ? 1 : 0);
+    nwidth = f_width - f_len - f_prec - (f_sign ? 1 : 0) - (f_altstr ? strlen(f_altstr) : 0);
 
     // Prefix padding?
     if (f_sign && (f_flags & TH_PF_ZERO) && (ret = vputch(ctx, f_sign)) == EOF)
@@ -175,6 +226,10 @@
     if ((ret = th_printf_pad_pre(ctx, vputch, nwidth, f_flags)) == EOF)
         return ret;
 
+    if (f_altstr && (ret = th_printf_vput_pstr(ctx, vputch, f_altstr)) == EOF)
+        return ret;
+
+    // Do we want a sign prefix? Not for unsigned values
     if (f_sign && (f_flags & TH_PF_ZERO) == 0 && (ret = vputch(ctx, f_sign)) == EOF)
         return ret;
 
@@ -197,20 +252,6 @@
 }
 
 
-#define TH_PFUNC_NAME th_printf_vput_int
-#define TH_PFUNC_SIGNED
-#define TH_PFUNC_TYPE_S int
-#define TH_PFUNC_TYPE_U unsigned int
-#include "th_printf1.c"
-
-
-#define TH_PFUNC_NAME th_printf_vput_int64
-#define TH_PFUNC_SIGNED
-#define TH_PFUNC_TYPE_S int64_t
-#define TH_PFUNC_TYPE_U uint64_t
-#include "th_printf1.c"
-
-
 static int th_printf_vput_str(th_printf_ctx *ctx, th_printf_vputch vputch,
     const char *str, int f_flags, const int f_width, const int f_prec)
 {
@@ -246,6 +287,19 @@
 }
 
 
+static char * th_printf_altfmt_o(const int flags)
+{
+    (flags);
+    return "0";
+}
+
+
+static char * th_printf_altfmt_x(const int flags)
+{
+    return (flags & TH_PF_UPCASE) ? "0X" : "0x";
+}
+
+
 int th_vprintf_do(th_printf_ctx *ctx, th_printf_vputch vputch, const char *fmt, va_list ap)
 {
     int ret = 0;
@@ -354,65 +408,36 @@
                     break;
 
                 case 'o':
-                    if (f_flags & TH_PF_LONGLONG)
-                    {
-                        if ((ret = th_printf_vput_int64(ctx, vputch, va_arg(ap, int64_t),
-                            8, f_flags, f_width, f_prec, TRUE, FALSE)) == EOF)
-                            goto out;
-                    }
-                    else
-                    {
-                        if ((ret = th_printf_vput_int(ctx, vputch, va_arg(ap, unsigned int),
-                            8, f_flags, f_width, f_prec, TRUE, FALSE)) == EOF)
-                            goto out;
-                    }
+                    if ((ret = th_printf_vput_int(ctx, vputch, ap, 8, f_flags, f_width, f_prec, TRUE, th_printf_altfmt_o)) == EOF)
+                        goto out;
                     break;
 
                 case 'u':
                 case 'i':
                 case 'd':
-                    if (f_flags & TH_PF_LONGLONG)
-                    {
-                        if ((ret = th_printf_vput_int64(ctx, vputch, va_arg(ap, int64_t),
-                            10, f_flags, f_width, f_prec, *fmt == 'u', FALSE)) == EOF)
-                            goto out;
-                    }
-                    else
-                    {
-                        if ((ret = th_printf_vput_int(ctx, vputch, va_arg(ap, unsigned int),
-                            10, f_flags, f_width, f_prec, *fmt == 'u', FALSE)) == EOF)
-                            goto out;
-                    }
+                    if ((ret = th_printf_vput_int(ctx, vputch, ap, 10, f_flags, f_width, f_prec, *fmt == 'u', NULL)) == EOF)
+                        goto out;
                     break;
 
                 case 'x':
                 case 'X':
-                    if (f_flags & TH_PF_LONGLONG)
-                    {
-                        if ((ret = th_printf_vput_int64(ctx, vputch, va_arg(ap, int64_t),
-                            16, f_flags, f_width, f_prec, TRUE, *fmt == 'X')) == EOF)
-                            goto out;
-                    }
-                    else
-                    {
-                        if ((ret = th_printf_vput_int(ctx, vputch, va_arg(ap, unsigned int),
-                            16, f_flags, f_width, f_prec, TRUE, *fmt == 'X')) == EOF)
-                            goto out;
-                    }
+                    if (*fmt == 'X')
+                        f_flags |= TH_PF_UPCASE;
+                    if ((ret = th_printf_vput_int(ctx, vputch, ap, 16, f_flags, f_width, f_prec, TRUE, th_printf_altfmt_x)) == EOF)
+                        goto out;
                     break;
 
                 case 'p':
 #if (TH_PTRSIZE == 32)
-                    if ((ret = th_printf_vput_int(ctx, vputch, (int32_t) va_arg(ap, void *),
-                        16, f_flags, f_width, f_prec, TRUE, FALSE)) == EOF)
-                        goto out;
+                    f_flags = TH_PF_LONG;
+                    f_prec = 4*2;
 #elif (TH_PTRSIZE == 64)
-                    if ((ret = th_printf_vput_int64(ctx, vputch, (int64_t) va_arg(ap, void *),
-                        16, f_flags, f_width, f_prec, TRUE, FALSE)) == EOF)
+                    f_flags = TH_PF_LONGLONG;
+                    f_prec = 8*2;
+#endif
+//                    f_flags |= TH_PF_ZERO;
+                    if ((ret = th_printf_vput_int(ctx, vputch, ap, 16, f_flags, f_width, f_prec, TRUE, th_printf_altfmt_x)) == EOF)
                         goto out;
-#else
-#    error TH_PTRSIZE not defined
-#endif
                     break;
 
                 case 'f':
--- a/th_string.h	Tue Feb 23 14:59:07 2016 +0200
+++ b/th_string.h	Tue Feb 23 15:26:29 2016 +0200
@@ -61,6 +61,8 @@
 
     TH_PF_LONG  = 0x1000,
     TH_PF_LONGLONG = 0x2000,
+
+    TH_PF_UPCASE = 0x8000,
 };