summaryrefslogtreecommitdiff
path: root/py/vstr.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-04-09 23:56:15 +0100
committerDamien George <damien.p.george@gmail.com>2015-04-16 14:30:16 +0000
commit7f9d1d6ab923096582622b700bedb6a571518eac (patch)
treef97a0d56ba0279dd4ef2a44f00676193c4d49d8b /py/vstr.c
parent56beb01724d4f0027babc5d23f016efbde4c4190 (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.c37
1 files changed, 9 insertions, 28 deletions
diff --git a/py/vstr.c b/py/vstr.c
index 953e8edb5..45915e7c4 100644
--- a/py/vstr.c
+++ b/py/vstr.c
@@ -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);
}