From cb66f41ebc4980f4e6b7543bece19e3b9daac25c Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 13 Jul 2014 23:07:42 +0300 Subject: py: Make print() accept "file" argument, and actually print to stream. And not system printf(), like it was before. For this, move pfenv_printf() from stmhal port to py/. --- stmhal/printf.c | 152 ++------------------------------------------------------ 1 file changed, 4 insertions(+), 148 deletions(-) (limited to 'stmhal/printf.c') diff --git a/stmhal/printf.c b/stmhal/printf.c index c4731aa88..d998a6277 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 -- cgit v1.2.3 From 1163cb9cb5e48153d1a6d723e8577d8ec3821692 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 20 Jul 2014 13:10:18 +0100 Subject: stmhal: Change calls to pfenv_printf to pfenv_vprintf. Fixes printing bugs introduced by cb66f41ebc4980f4e6b7543bece19e3b9daac25c. --- stmhal/printf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'stmhal/printf.c') diff --git a/stmhal/printf.c b/stmhal/printf.c index d998a6277..53c47c633 100644 --- a/stmhal/printf.c +++ b/stmhal/printf.c @@ -81,7 +81,7 @@ int DEBUG_printf(const char *fmt, ...) { (void)stream; 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; } @@ -124,7 +124,7 @@ int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { pfenv_t pfenv; pfenv.data = &strn_pfenv; pfenv.print_strn = strn_print_strn; - int len = pfenv_printf(&pfenv, fmt, ap); + int len = pfenv_vprintf(&pfenv, fmt, ap); // add terminating null byte if (size > 0) { if (strn_pfenv.remain == 0) { -- cgit v1.2.3 From 951ed9d02ffc826c68ee3af26c3530477e7e6156 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 20 Jul 2014 13:57:43 +0100 Subject: stmhal: Fix REPL printing by cooking output sent to stdout_obj. Recent changes to builtin print meant that print was printing to the mp_sys_stdout_obj, which was sending data raw to the USB CDC device. The data should be cooked so that \n turns into \r\n. --- stmhal/printf.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'stmhal/printf.c') diff --git a/stmhal/printf.c b/stmhal/printf.c index 53c47c633..db611f3d9 100644 --- a/stmhal/printf.c +++ b/stmhal/printf.c @@ -40,6 +40,7 @@ #endif #include "uart.h" #include "usb.h" +#include "pybstdio.h" #if MICROPY_PY_BUILTINS_FLOAT #include "formatfloat.h" @@ -47,22 +48,11 @@ 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)); +STATIC void stdout_print_strn(void *dummy_env, const char *str, unsigned int len) { + stdout_tx_strn_cooked(str, len); } -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 - if (pyb_uart_global_debug != PYB_UART_NONE) { - uart_tx_strn_cooked(pyb_uart_global_debug, str, len); - } - if (usb_vcp_is_enabled()) { - usb_vcp_send_strn_cooked(str, len); - } -} - -static const pfenv_t pfenv_stdout = {0, stdout_print_strn}; +STATIC const pfenv_t pfenv_stdout = {0, stdout_print_strn}; int printf(const char *fmt, ...) { va_list ap; -- cgit v1.2.3