diff options
Diffstat (limited to 'stmhal/printf.c')
-rw-r--r-- | stmhal/printf.c | 152 |
1 files changed, 4 insertions, 148 deletions
diff --git a/stmhal/printf.c b/stmhal/printf.c index c4731aa88d..d998a6277d 100644 --- a/stmhal/printf.c +++ b/stmhal/printf.c @@ -45,156 +45,12 @@ #include "formatfloat.h" #endif +int pfenv_vprintf(const pfenv_t *pfenv, const char *fmt, va_list args); + void pfenv_prints(const pfenv_t *pfenv, const char *str) { pfenv->print_strn(pfenv->data, str, strlen(str)); } -int pfenv_printf(const pfenv_t *pfenv, const char *fmt, va_list args) { - int chrs = 0; - for (;;) { - { - const char *f = fmt; - while (*f != '\0' && *f != '%') { - ++f; // XXX UTF8 advance char - } - if (f > fmt) { - pfenv->print_strn(pfenv->data, fmt, f - fmt); - chrs += f - fmt; - fmt = f; - } - } - - if (*fmt == '\0') { - break; - } - - // move past % character - ++fmt; - - // parse flags, if they exist - int flags = 0; - char fill = ' '; - while (*fmt != '\0') { - if (*fmt == '-') flags |= PF_FLAG_LEFT_ADJUST; - else if (*fmt == '+') flags |= PF_FLAG_SHOW_SIGN; - else if (*fmt == ' ') flags |= PF_FLAG_SPACE_SIGN; - else if (*fmt == '!') flags |= PF_FLAG_NO_TRAILZ; - else if (*fmt == '0') { - flags |= PF_FLAG_PAD_AFTER_SIGN; - fill = '0'; - } else break; - ++fmt; - } - - // parse width, if it exists - int width = 0; - for (; '0' <= *fmt && *fmt <= '9'; ++fmt) { - width = width * 10 + *fmt - '0'; - } - - // parse precision, if it exists - int prec = -1; - if (*fmt == '.') { - ++fmt; - if (*fmt == '*') { - ++fmt; - prec = va_arg(args, int); - } else { - prec = 0; - for (; '0' <= *fmt && *fmt <= '9'; ++fmt) { - prec = prec * 10 + *fmt - '0'; - } - } - if (prec < 0) { - prec = 0; - } - } - - // parse long specifiers (current not used) - //bool long_arg = false; - if (*fmt == 'l') { - ++fmt; - //long_arg = true; - } - - if (*fmt == '\0') { - break; - } - - switch (*fmt) { - case 'b': - if (va_arg(args, int)) { - chrs += pfenv_print_strn(pfenv, "true", 4, flags, fill, width); - } else { - chrs += pfenv_print_strn(pfenv, "false", 5, flags, fill, width); - } - break; - case 'c': - { - char str = va_arg(args, int); - chrs += pfenv_print_strn(pfenv, &str, 1, flags, fill, width); - break; - } - case 's': - { - const char *str = va_arg(args, const char*); - if (str) { - if (prec < 0) { - prec = strlen(str); - } - chrs += pfenv_print_strn(pfenv, str, prec, flags, fill, width); - } else { - chrs += pfenv_print_strn(pfenv, "(null)", 6, flags, fill, width); - } - break; - } - case 'u': - chrs += pfenv_print_int(pfenv, va_arg(args, int), 0, 10, 'a', flags, fill, width); - break; - case 'd': - chrs += pfenv_print_int(pfenv, va_arg(args, int), 1, 10, 'a', flags, fill, width); - break; - case 'x': - case 'p': // ? - chrs += pfenv_print_int(pfenv, va_arg(args, int), 0, 16, 'a', flags, fill, width); - break; - case 'X': - case 'P': // ? - chrs += pfenv_print_int(pfenv, va_arg(args, int), 0, 16, 'A', flags, fill, width); - break; -#if MICROPY_PY_BUILTINS_FLOAT - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - { -#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT - mp_float_t f = va_arg(args, double); - chrs += pfenv_print_float(pfenv, f, *fmt, flags, fill, width, prec); -#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE - // Currently pfenv_print_float uses snprintf, so if you want - // to use pfenv_print_float with doubles then you'll need - // fix it to not use snprintf first. Otherwise you'll have - // inifinite recursion. -#error Calling pfenv_print_float with double not supported from within printf -#else -#error Unknown MICROPY FLOAT IMPL -#endif - break; - } -#endif - default: - pfenv->print_strn(pfenv->data, fmt, 1); - chrs += 1; - break; - } - ++fmt; - } - return chrs; -} - STATIC void stdout_print_strn(void *data, const char *str, unsigned int len) { // TODO this needs to be replaced with a proper stdio interface ala CPython // send stdout to UART and USB CDC VCP @@ -211,13 +67,13 @@ static const pfenv_t pfenv_stdout = {0, stdout_print_strn}; int printf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - int ret = pfenv_printf(&pfenv_stdout, fmt, ap); + int ret = pfenv_vprintf(&pfenv_stdout, fmt, ap); va_end(ap); return ret; } int vprintf(const char *fmt, va_list ap) { - return pfenv_printf(&pfenv_stdout, fmt, ap); + return pfenv_vprintf(&pfenv_stdout, fmt, ap); } #if MICROPY_DEBUG_PRINTERS |