Mercurial > hg > th-libs
diff th_printf.c @ 567:b75f42ca08ef
Massage th_vprintf_do() a bit, and factor out the format specifier handling
into a separate function and use through a callback. This breaks the
th_vprintf_do() API, unfortunately, but should make for further flexibility
in future.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 08 Jan 2020 02:17:37 +0200 |
parents | 3a852e9f70a6 |
children | 2fbe42d957c4 |
line wrap: on
line diff
--- a/th_printf.c Tue Jan 07 20:09:23 2020 +0200 +++ b/th_printf.c Wed Jan 08 02:17:37 2020 +0200 @@ -324,7 +324,77 @@ #endif -int th_vprintf_do(th_vprintf_ctx *ctx, th_vprintf_putch vputch, const char *fmt, va_list ap) +int th_vprintf_do_format( + th_vprintf_ctx *ctx, th_vprintf_putch vputch, + int f_width, int f_prec, int f_flags, + const char fmt, va_list ap) +{ + int ret; + + switch (fmt) + { + case 0: + // Unexpected end of format string + return -104; + + case 'c': + if ((ret = th_printf_pad_pre(ctx, vputch, f_width - 1, f_flags)) == EOF) + return ret; + + if ((ret = vputch(ctx, va_arg(ap, int))) == EOF) + return ret; + + return th_printf_pad_post(ctx, vputch, f_width - 1, f_flags); + + case 'o': + return th_vprintf_put_int(ctx, vputch, ap, 8, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_oct); + + case 'u': + case 'i': + case 'd': + return th_vprintf_put_int(ctx, vputch, ap, 10, f_flags, f_width, f_prec, fmt == 'u', NULL); + + case 'x': + case 'X': + if (fmt == 'X') + f_flags |= TH_PF_UPCASE; + + return th_vprintf_put_int(ctx, vputch, ap, 16, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_hex); + + case 'p': + // Check for invalid flags + if (f_flags & (TH_PF_LONG | TH_PF_LONGLONG)) + return -120; + +#if (TH_PTRSIZE == 32) + f_flags |= TH_PF_LONG; +#elif (TH_PTRSIZE == 64) + f_flags |= TH_PF_LONGLONG; +#endif + f_flags |= TH_PF_ALT | TH_PF_POINTER; + + return th_vprintf_put_int(ctx, vputch, ap, 16, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_hex); + +#ifdef TH_WIP_FLOAT_SUPPORT + case 'f': + case 'F': + return th_vprintf_put_float(ctx, vputch, ap, + f_flags, f_width, f_prec); +#endif + + case 's': + return th_vprintf_put_str(ctx, vputch, va_arg(ap, char *), + f_flags, f_width, f_prec); + + //case '%': + default: + return vputch(ctx, fmt); + } +} + + +int th_vprintf_do(th_vprintf_ctx *ctx, th_vprintf_putch vputch, + th_vprintf_format vformat, const char *fmt, va_list ap) { int ret = 0; @@ -440,75 +510,12 @@ return -202; } - switch (*fmt) - { - case 0: - return -104; - - case 'c': - 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; - - case 'o': - if ((ret = th_vprintf_put_int(ctx, vputch, ap, 8, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_oct)) == EOF) - goto out; - break; - - case 'u': - case 'i': - case 'd': - if ((ret = th_vprintf_put_int(ctx, vputch, ap, 10, f_flags, f_width, f_prec, *fmt == 'u', NULL)) == EOF) - goto out; - break; - - case 'x': - case 'X': - if (*fmt == 'X') - f_flags |= TH_PF_UPCASE; - if ((ret = th_vprintf_put_int(ctx, vputch, ap, 16, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_hex)) == EOF) - goto out; - break; + ret = vformat(ctx, vputch, f_width, f_prec, f_flags, *fmt, ap); + if (ret == EOF) + goto out; + if (ret < 0) + return ret; - case 'p': - if (f_flags & (TH_PF_LONG | TH_PF_LONGLONG)) - return -120; - -#if (TH_PTRSIZE == 32) - f_flags |= TH_PF_LONG; -#elif (TH_PTRSIZE == 64) - f_flags |= TH_PF_LONGLONG; -#endif - f_flags |= TH_PF_ALT | TH_PF_POINTER; - if ((ret = th_vprintf_put_int(ctx, vputch, ap, 16, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_hex)) == EOF) - goto out; - break; - -#ifdef TH_WIP_FLOAT_SUPPORT - case 'f': - case 'F': - if ((ret = th_vprintf_put_float(ctx, vputch, ap, - f_flags, f_width, f_prec)) == EOF) - goto out; - break; -#endif - - case 's': - if ((ret = th_vprintf_put_str(ctx, vputch, va_arg(ap, char *), - f_flags, f_width, f_prec)) == EOF) - goto out; - break; - - //case '%': - default: - if ((ret = vputch(ctx, *fmt)) == EOF) - goto out; - break; - } } fmt++; }