summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2020-10-26 14:33:02 +0100
committerTyge Løvset <[email protected]>2020-10-26 14:33:02 +0100
commit20678d6f125a6e33f806dee3bf50ee46f7a4ec8e (patch)
tree677f19ec812c1f80d57153197bb0c41a46132073
parent1387465b9b77d1404782ba88b440c163c724a2c6 (diff)
downloadSTC-modified-20678d6f125a6e33f806dee3bf50ee46f7a4ec8e.tar.gz
STC-modified-20678d6f125a6e33f806dee3bf50ee46f7a4ec8e.zip
Support for differenting between float and double. Messy-
-rw-r--r--stc/cfmt.h42
1 files 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;
}