diff options
author | Damien George <damien.p.george@gmail.com> | 2015-04-09 23:56:15 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2015-04-16 14:30:16 +0000 |
commit | 7f9d1d6ab923096582622b700bedb6a571518eac (patch) | |
tree | f97a0d56ba0279dd4ef2a44f00676193c4d49d8b /py/vstr.c | |
parent | 56beb01724d4f0027babc5d23f016efbde4c4190 (diff) |
py: Overhaul and simplify printf/pfenv mechanism.
Previous to this patch the printing mechanism was a bit of a tangled
mess. This patch attempts to consolidate printing into one interface.
All (non-debug) printing now uses the mp_print* family of functions,
mainly mp_printf. All these functions take an mp_print_t structure as
their first argument, and this structure defines the printing backend
through the "print_strn" function of said structure.
Printing from the uPy core can reach the platform-defined print code via
two paths: either through mp_sys_stdout_obj (defined pert port) in
conjunction with mp_stream_write; or through the mp_plat_print structure
which uses the MP_PLAT_PRINT_STRN macro to define how string are printed
on the platform. The former is only used when MICROPY_PY_IO is defined.
With this new scheme printing is generally more efficient (less layers
to go through, less arguments to pass), and, given an mp_print_t*
structure, one can call mp_print_str for efficiency instead of
mp_printf("%s", ...). Code size is also reduced by around 200 bytes on
Thumb2 archs.
Diffstat (limited to 'py/vstr.c')
-rw-r--r-- | py/vstr.c | 37 |
1 files changed, 9 insertions, 28 deletions
@@ -31,6 +31,7 @@ #include "py/mpconfig.h" #include "py/misc.h" +#include "py/mpprint.h" // returned value is always at least 1 greater than argument #define ROUND_ALLOC(a) (((a) & ((~0) - 7)) + 8) @@ -65,6 +66,12 @@ void vstr_init_fixed_buf(vstr_t *vstr, size_t alloc, char *buf) { vstr->fixed_buf = true; } +void vstr_init_print(vstr_t *vstr, size_t alloc, mp_print_t *print) { + vstr_init(vstr, alloc); + print->data = vstr; + print->print_strn = (mp_print_strn_t)vstr_add_strn; +} + void vstr_clear(vstr_t *vstr) { if (!vstr->fixed_buf) { m_del(char, vstr->buf, vstr->alloc); @@ -322,32 +329,6 @@ void vstr_vprintf(vstr_t *vstr, const char *fmt, va_list ap) { return; } - while (1) { - // try to print in the allocated space - // need to make a copy of the va_list because we may call vsnprintf multiple times - size_t size = vstr->alloc - vstr->len; - va_list ap2; - va_copy(ap2, ap); - int n = vsnprintf(vstr->buf + vstr->len, size, fmt, ap2); - va_end(ap2); - - // if that worked, return - if (n > -1 && (size_t)n < size) { - vstr->len += n; - return; - } - - // else try again with more space - if (n > -1) { // glibc 2.1 - // n + 1 is precisely what is needed - if (!vstr_ensure_extra(vstr, n + 1)) { - return; - } - } else { // glibc 2.0 - // increase to twice the old size - if (!vstr_ensure_extra(vstr, size * 2)) { - return; - } - } - } + mp_print_t print = {vstr, (mp_print_strn_t)vstr_add_strn}; + mp_vprintf(&print, fmt, ap); } |