Mercurial > hg > th-libs
changeset 299:0311f139fcf6
Refactor how various printf modifier flags etc. are handled. Still needs
work and refining.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 22 Feb 2016 18:31:11 +0200 |
parents | 86fe17a2ed81 |
children | 385d0b40a6c8 |
files | th_string.c th_string.h |
diffstat | 2 files changed, 106 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/th_string.c Mon Feb 22 18:29:53 2016 +0200 +++ b/th_string.c Mon Feb 22 18:31:11 2016 +0200 @@ -124,21 +124,43 @@ // // Simple implementations of printf() type functions // -static int th_printf_vput_pad(th_printf_ctx *ctx, th_printf_vputch vputch, int nwidth, const char padChar) +static int th_printf_pad_pre(th_printf_ctx *ctx, th_printf_vputch vputch, + int f_width, const int f_flags) { - while (nwidth--) + if (f_width > 0 && (f_flags & TH_PF_LEFT) == 0) { - int ret; - if ((ret = vputch(ctx, padChar)) == EOF) - return ret; + char pad = (f_flags & TH_PF_ZERO) ? '0' : ' '; + while (f_width--) + { + int ret; + if ((ret = vputch(ctx, pad)) == EOF) + return ret; + } + } + return 0; +} + + +static int th_printf_pad_post(th_printf_ctx *ctx, th_printf_vputch vputch, + int f_width, const int f_flags) +{ + if (f_width > 0 && (f_flags & TH_PF_LEFT)) + { + char pad = ' '; + while (f_width--) + { + int ret; + if ((ret = vputch(ctx, pad)) == EOF) + return ret; + } } return 0; } static int th_printf_vput_int(th_printf_ctx *ctx, th_printf_vputch vputch, - int pval, const int radix, const char padMode, const char padChar, - const int f_width, const BOOL unsig, const BOOL upcase, const BOOL f_sign) + int pval, const int radix, const int f_flags, + const int f_width, const BOOL unsig, const BOOL upcase) { char buf[64]; size_t pos = 0; @@ -177,7 +199,7 @@ // Do we want a sign prefix? Not for unsigned values if (!unsig) { - char ch = f_sign ? (neg ? '-' : '+') : (neg ? '-' : 0); + char ch = (f_flags & TH_PF_SIGN) ? (neg ? '-' : '+') : (neg ? '-' : ((f_flags & TH_PF_SPACE) ? ' ' : 0)); if (ch && (ret = vputch(ctx, ch)) == EOF) goto out; } @@ -186,7 +208,7 @@ int nwidth = f_width - pos; // Prefix padding? - if (padMode != '-' && nwidth > 0 && (ret = th_printf_vput_pad(ctx, vputch, nwidth, padMode)) == EOF) + if ((ret = th_printf_pad_pre(ctx, vputch, nwidth, f_flags)) == EOF) goto out; // Output the value @@ -197,7 +219,7 @@ } // Postfix padding? - if (padMode == '-' && nwidth > 0 && (ret = th_printf_vput_pad(ctx, vputch, nwidth, ' ')) == EOF) + if ((ret = th_printf_pad_post(ctx, vputch, nwidth, f_flags)) == EOF) goto out; out: @@ -206,8 +228,7 @@ static int th_printf_vput_str(th_printf_ctx *ctx, th_printf_vputch vputch, - const char *str, const char padMode, const char padChar, - const int f_width, const int f_prec) + const char *str, const int f_flags, const int f_width, const int f_prec) { int nwidth, ret = 0; @@ -218,7 +239,7 @@ nwidth = f_width - strlen(str); // Prefix padding? - if (padMode != '-' && nwidth > 0 && (ret = th_printf_vput_pad(ctx, vputch, nwidth, padMode)) == EOF) + if ((ret = th_printf_pad_pre(ctx, vputch, nwidth, f_flags)) == EOF) goto out; while (*str) @@ -228,7 +249,7 @@ } // Postfix padding? - if (padMode == '-' && nwidth > 0 && (ret = th_printf_vput_pad(ctx, vputch, nwidth, ' ')) == EOF) + if ((ret = th_printf_pad_post(ctx, vputch, nwidth, f_flags)) == EOF) goto out; out: @@ -249,33 +270,45 @@ } else { - char padMode = ' ', padChar = 0; - int f_width = 0, f_prec = -1; - BOOL f_sign = FALSE; + int f_width = 0, f_prec = 1, f_flags = 0; + BOOL end = FALSE; fmt++; - // Check for field sign - if (*fmt == '+') - { - f_sign = TRUE; - fmt++; - } - - // Check for padding - if (*fmt == '0' || *fmt == '-' || *fmt == '\'') + // Check for flags + while (!end) { - padMode = *fmt++; - if (padMode == '\'') + switch (*fmt) { - padChar = *fmt++; - if (*fmt != '\'') - return -101; - fmt++; + case '#': + f_flags |= TH_PF_ALT; + break; + + case '+': + f_flags |= TH_PF_SIGN; + break; + + case '0': + f_flags |= TH_PF_ZERO; + break; + + case '-': + f_flags |= TH_PF_LEFT; + break; + + case ' ': + f_flags |= TH_PF_SPACE; + break; + + case '\'': + f_flags |= TH_PF_GROUP; + break; + + default: + end = TRUE; + break; } - - if (*fmt == 0) - return -102; + if (!end) fmt++; } // Get field width @@ -286,13 +319,12 @@ if (*fmt == '.') { fmt++; - if (!th_isdigit(*fmt)) - return -103; - // If no digit after '.', precision is to be 0 f_prec = 0; while (th_isdigit(*fmt)) f_prec = f_prec * 10 + (*fmt++ - '0'); + + f_flags &= ~ TH_PF_ZERO; } // Check for length modifiers (NOT SUPPORTED CURRENTLY) @@ -313,42 +345,49 @@ return -104; case 'c': - if (padMode != ' ' || f_width > 0 || f_prec >= 0 || f_sign) - return -105; + if ((ret = th_printf_pad_pre(ctx, vputch, f_width - 1, f_flags)) == EOF) + goto out; + if ((ret = vputch(ctx, va_arg(ap, int))) == EOF) + goto out; + if ((ret = th_printf_pad_post(ctx, vputch, f_width - 1, f_flags)) == EOF) + goto out; + break; - if ((ret = vputch(ctx, va_arg(ap, int))) == EOF) + case 'o': + if ((ret = th_printf_vput_int(ctx, vputch, va_arg(ap, unsigned int), + 8, f_flags, f_width, FALSE, FALSE)) == EOF) goto out; break; case 'u': + case 'i': case 'd': - if ((padMode != '0' && padMode != '-' && padMode != ' ') || f_prec >= 0) - return -105; - if ((ret = th_printf_vput_int(ctx, vputch, va_arg(ap, unsigned int), - 10, padMode, padChar, f_width, *fmt == 'u', FALSE, f_sign)) == EOF) + 10, f_flags, f_width, *fmt == 'u', FALSE)) == EOF) goto out; break; case 'x': case 'X': - if ((padMode != '0' && padMode != '-' && padMode != ' ') || f_prec >= 0) - return -106; + if ((ret = th_printf_vput_int(ctx, vputch, va_arg(ap, unsigned int), + 16, f_flags, f_width, TRUE, *fmt == 'X')) == EOF) + goto out; + break; - if ((ret = th_printf_vput_int(ctx, vputch, va_arg(ap, unsigned int), - 16, padMode, padChar, f_width, TRUE, *fmt == 'X', FALSE)) == EOF) + case 'p': + if ((ret = th_printf_vput_int(ctx, vputch, va_arg(ap, void *), + 16, f_flags, f_width, TRUE, FALSE)) == EOF) goto out; break; case 'f': - goto out; + case 'F': + return -112; break; case 's': - if ((padMode != '-' && padMode != ' ') || f_sign) - return -108; - - if ((ret = th_printf_vput_str(ctx, vputch, va_arg(ap, char *), padMode, padChar, f_width, f_prec)) == EOF) + if ((ret = th_printf_vput_str(ctx, vputch, va_arg(ap, char *), + f_flags, f_width, f_prec)) == EOF) goto out; break;
--- a/th_string.h Mon Feb 22 18:29:53 2016 +0200 +++ b/th_string.h Mon Feb 22 18:31:11 2016 +0200 @@ -48,6 +48,19 @@ }; +enum +{ + TH_PF_NONE = 0x00, + TH_PF_ALT = 0x01, + TH_PF_SIGN = 0x02, + TH_PF_SPACE = 0x04, + TH_PF_GROUP = 0x08, + + TH_PF_ZERO = 0x10, + TH_PF_LEFT = 0x20, +}; + + typedef struct { char *buf;