From 20678d6f125a6e33f806dee3bf50ee46f7a4ec8e Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 26 Oct 2020 14:33:02 +0100 Subject: Support for differenting between float and double. Messy- --- stc/cfmt.h | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/stc/cfmt.h b/stc/cfmt.h index d2fd5feb..aab85612 100644 --- a/stc/cfmt.h +++ b/stc/cfmt.h @@ -72,8 +72,8 @@ STC_INLINE const char* _cfmt_strftime(char* n, char buf[][_cfmt_sn], size_t maxs # define _cfmt_uschar() char: "c", signed char: "c", unsigned char: "hhu" #endif -#define _cfmt(x) _Generic ((x), \ - _Bool: "d:bool", \ +#define _cfmt(x) _Generic (x, \ + _Bool: "B", \ _cfmt_uschar(), \ short: "hd", \ unsigned short: "hu", \ @@ -83,8 +83,8 @@ STC_INLINE const char* _cfmt_strftime(char* n, char buf[][_cfmt_sn], size_t maxs unsigned long: "lu", \ long long: "lld", \ unsigned long long: "llu", \ - float: "g", \ - double: "g", \ + float: "4", \ + double: "8", \ long double: "Lg", \ char *: "s", \ void *: "p", \ @@ -95,7 +95,7 @@ STC_INLINE const char* _cfmt_strftime(char* n, char buf[][_cfmt_sn], size_t maxs inline auto _cfmt_fn(char*) {return sprintf;} inline auto _cfmt_fn(int s) {return _cfmt_printf;} inline auto _cfmt_fn(cstr_t*) {return cstr_fmt;} - inline auto _cfmt(bool x) {return "d:bool";} + inline auto _cfmt(bool x) {return "B";} inline auto _cfmt(char x) {return "c";} inline auto _cfmt(unsigned char x) {return "hhu";} inline auto _cfmt(short x) {return "hd";} @@ -106,8 +106,8 @@ STC_INLINE const char* _cfmt_strftime(char* n, char buf[][_cfmt_sn], size_t maxs inline auto _cfmt(unsigned long x) {return "lu";} inline auto _cfmt(long long x) {return "lld";} inline auto _cfmt(unsigned long long x) {return "llu";} - inline auto _cfmt(float x) {return "g";} - inline auto _cfmt(double x) {return "g";} + inline auto _cfmt(float x) {return "4";} + inline auto _cfmt(double x) {return "8";} inline auto _cfmt(long double x) {return "Lg";} inline auto _cfmt(const char *x) {return "s";} inline auto _cfmt(const void *x) {return "p";} @@ -184,9 +184,9 @@ _cfmt_printf(int s, const char* fmt, ...) { STC_DEF char * _cfmt_conv(int nargs, const char *fmt, ...) { - char *fmt1 = (char *) malloc(strlen(fmt)*2 + 1), *p = fmt1, *f, ch; + char *fmt1 = (char *) malloc(strlen(fmt)*25/10 + 1), *p = fmt1, *p0, *arg, ch; const char *fmt0 = fmt; - int n = 0; + int n = 0, align, deci; va_list args; va_start(args, fmt); do { @@ -204,14 +204,26 @@ _cfmt_conv(int nargs, const char *fmt, ...) { fprintf(stderr, "ERROR: c_print() missing argument(%d): %s\n", n, fmt0); break; } - *p++ = '%'; fmt += 1 + (fmt[1] == ':'); - f = va_arg(args, char *); - while (*fmt != '}' && *fmt) - if ((*p++ = *fmt++) == '*' && ++n <= nargs) - f = va_arg(args, char *); + arg = va_arg(args, char *); + *p++ = '%'; p0 = p; + align = deci = 0; + while (*fmt != '}' && *fmt) switch (*fmt) { + case '<': *p++ = '-', ++fmt, align = 1; break; + case '>': ++fmt, align = 1; break; + case '-': ++fmt; break; + case '*': if (++n <= nargs) arg = va_arg(args, char *); /* nobreak */ + default: if ((*p++ = *fmt++) == '.') deci = 1; + } if (!strchr("csdioxXufFeEaAgGnp", fmt[-1])) - while (*f) *p++ = *f++; + while (*arg) *p++ = *arg++; + if (p[-1] == 'B') + memmove(p0+1, p0, p-p0), *p0 = '+', *p++ = 'd'; + else if (*arg == 0 && strchr("48", p[-1])) { + if (deci) p[-1] = 'g'; + else strcpy(p - 1, p[-1] == '4' ? ".07g" : ".15g"), p += 3; + } else if (!align && strchr("cs", p[-1])) + memmove(p0+1, p0, p-p0), *p0 = '-', ++p; fmt += (*fmt == '}'); continue; } -- cgit v1.2.3