diff options
author | Damien George <damien.p.george@gmail.com> | 2014-09-17 22:56:34 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-09-17 22:56:34 +0100 |
commit | 612045f53f7e5edf9faa359ee9ee52d490d58000 (patch) | |
tree | a021612e31ff6275246514405c4a8421c6eff5d7 /py | |
parent | 8a9b999f1c9a0edf84b2507940efb8deaaa380b8 (diff) | |
download | micropython-612045f53f7e5edf9faa359ee9ee52d490d58000.tar.gz micropython-612045f53f7e5edf9faa359ee9ee52d490d58000.zip |
py: Add native json printing using existing print framework.
Also add start of ujson module with dumps implemented. Enabled in unix
and stmhal ports. Test passes on both.
Diffstat (limited to 'py')
-rw-r--r-- | py/builtin.h | 1 | ||||
-rw-r--r-- | py/builtintables.c | 3 | ||||
-rw-r--r-- | py/mpconfig.h | 4 | ||||
-rw-r--r-- | py/obj.h | 3 | ||||
-rw-r--r-- | py/objbool.c | 14 | ||||
-rw-r--r-- | py/objdict.c | 7 | ||||
-rw-r--r-- | py/objlist.c | 5 | ||||
-rw-r--r-- | py/objnone.c | 6 | ||||
-rw-r--r-- | py/objstr.c | 32 | ||||
-rw-r--r-- | py/objstrunicode.c | 36 | ||||
-rw-r--r-- | py/objtuple.c | 19 | ||||
-rw-r--r-- | py/py.mk | 1 | ||||
-rw-r--r-- | py/qstrdefs.h | 5 |
13 files changed, 123 insertions, 13 deletions
diff --git a/py/builtin.h b/py/builtin.h index 1bb61f6ebc..9c8b2b9be2 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -89,3 +89,4 @@ extern struct _dummy_t mp_sys_stderr_obj; // extmod modules extern const mp_obj_module_t mp_module_uctypes; extern const mp_obj_module_t mp_module_zlibd; +extern const mp_obj_module_t mp_module_ujson; diff --git a/py/builtintables.c b/py/builtintables.c index 08b6b16493..391077d434 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -200,6 +200,9 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = { #if MICROPY_PY_ZLIBD { MP_OBJ_NEW_QSTR(MP_QSTR_zlibd), (mp_obj_t)&mp_module_zlibd }, #endif +#if MICROPY_PY_UJSON + { MP_OBJ_NEW_QSTR(MP_QSTR_ujson), (mp_obj_t)&mp_module_ujson }, +#endif // extra builtin modules as defined by a port MICROPY_PORT_BUILTIN_MODULES diff --git a/py/mpconfig.h b/py/mpconfig.h index adbcb0eb71..cf85533395 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -390,6 +390,10 @@ typedef double mp_float_t; #define MICROPY_PY_ZLIBD (0) #endif +#ifndef MICROPY_PY_UJSON +#define MICROPY_PY_UJSON (0) +#endif + /*****************************************************************************/ /* Hooks for a port to add builtins */ @@ -187,7 +187,8 @@ typedef enum { PRINT_STR = 0, PRINT_REPR = 1, PRINT_EXC = 2, // Special format for printing exception in unhandled exception message - PRINT_EXC_SUBCLASS = 4, // Internal flag for printing exception subclasses + PRINT_JSON = 3, + PRINT_EXC_SUBCLASS = 0x80, // Internal flag for printing exception subclasses } mp_print_kind_t; typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o, mp_print_kind_t kind); diff --git a/py/objbool.c b/py/objbool.c index dbe84d92e2..e6b5230f74 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -41,10 +41,18 @@ typedef struct _mp_obj_bool_t { STATIC void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_bool_t *self = self_in; - if (self->value) { - print(env, "True"); + if (MICROPY_PY_UJSON && kind == PRINT_JSON) { + if (self->value) { + print(env, "true"); + } else { + print(env, "false"); + } } else { - print(env, "False"); + if (self->value) { + print(env, "True"); + } else { + print(env, "False"); + } } } diff --git a/py/objdict.c b/py/objdict.c index a378bf6db8..a624320427 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -60,6 +60,9 @@ STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, mp_uint_t *cur) { STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_dict_t *self = self_in; bool first = true; + if (!(MICROPY_PY_UJSON && kind == PRINT_JSON)) { + kind = PRINT_REPR; + } print(env, "{"); mp_uint_t cur = 0; mp_map_elem_t *next = NULL; @@ -68,9 +71,9 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env print(env, ", "); } first = false; - mp_obj_print_helper(print, env, next->key, PRINT_REPR); + mp_obj_print_helper(print, env, next->key, kind); print(env, ": "); - mp_obj_print_helper(print, env, next->value, PRINT_REPR); + mp_obj_print_helper(print, env, next->value, kind); } print(env, "}"); } diff --git a/py/objlist.c b/py/objlist.c index 59390f371f..789a1600d3 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -49,12 +49,15 @@ STATIC mp_obj_t list_pop(mp_uint_t n_args, const mp_obj_t *args); STATIC void list_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_list_t *o = o_in; + if (!(MICROPY_PY_UJSON && kind == PRINT_JSON)) { + kind = PRINT_REPR; + } print(env, "["); for (mp_uint_t i = 0; i < o->len; i++) { if (i > 0) { print(env, ", "); } - mp_obj_print_helper(print, env, o->items[i], PRINT_REPR); + mp_obj_print_helper(print, env, o->items[i], kind); } print(env, "]"); } diff --git a/py/objnone.c b/py/objnone.c index a8d6071435..01536dcb34 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -38,7 +38,11 @@ typedef struct _mp_obj_none_t { } mp_obj_none_t; STATIC void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { - print(env, "None"); + if (MICROPY_PY_UJSON && kind == PRINT_JSON) { + print(env, "null"); + } else { + print(env, "None"); + } } STATIC mp_obj_t none_unary_op(mp_uint_t op, mp_obj_t o_in) { diff --git a/py/objstr.c b/py/objstr.c index b2afcdc98e..130af8a6af 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -92,9 +92,41 @@ void mp_str_print_quoted(void (*print)(void *env, const char *fmt, ...), void *e print(env, "%c", quote_char); } +#if MICROPY_PY_UJSON +STATIC void str_print_json(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, mp_uint_t str_len) { + print(env, "\""); + for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) { + if (*s == '"' || *s == '\\' || *s == '/') { + print(env, "\\%c", *s); + } else if (32 <= *s && *s <= 126) { + print(env, "%c", *s); + } else if (*s == '\b') { + print(env, "\\b"); + } else if (*s == '\f') { + print(env, "\\f"); + } else if (*s == '\n') { + print(env, "\\n"); + } else if (*s == '\r') { + print(env, "\\r"); + } else if (*s == '\t') { + print(env, "\\t"); + } else { + print(env, "\\u%04x", *s); + } + } + print(env, "\""); +} +#endif + STATIC void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { GET_STR_DATA_LEN(self_in, str_data, str_len); bool is_bytes = MP_OBJ_IS_TYPE(self_in, &mp_type_bytes); + #if MICROPY_PY_UJSON + if (kind == PRINT_JSON) { + str_print_json(print, env, str_data, str_len); + return; + } + #endif if (kind == PRINT_STR && !is_bytes) { print(env, "%.*s", str_len, str_data); } else { diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 8231eb9b16..0ee7f1dc9a 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -91,8 +91,44 @@ STATIC void uni_print_quoted(void (*print)(void *env, const char *fmt, ...), voi print(env, "%c", quote_char); } +#if MICROPY_PY_UJSON +STATIC void uni_print_json(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, uint str_len) { + print(env, "\""); + const byte *s = str_data, *top = str_data + str_len; + while (s < top) { + unichar ch; + ch = utf8_get_char(s); + s = utf8_next_char(s); + if (ch == '"' || ch == '\\' || ch == '/') { + print(env, "\\%c", ch); + } else if (32 <= ch && ch <= 126) { + print(env, "%c", ch); + } else if (*s == '\b') { + print(env, "\\b"); + } else if (*s == '\f') { + print(env, "\\f"); + } else if (*s == '\n') { + print(env, "\\n"); + } else if (*s == '\r') { + print(env, "\\r"); + } else if (*s == '\t') { + print(env, "\\t"); + } else { + print(env, "\\u%04x", ch); + } + } + print(env, "\""); +} +#endif + STATIC void uni_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { GET_STR_DATA_LEN(self_in, str_data, str_len); + #if MICROPY_PY_UJSON + if (kind == PRINT_JSON) { + uni_print_json(print, env, str_data, str_len); + return; + } + #endif if (kind == PRINT_STR) { print(env, "%.*s", str_len, str_data); } else { diff --git a/py/objtuple.c b/py/objtuple.c index 6abe7d2c64..2793e4838d 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -43,17 +43,26 @@ STATIC mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, mp_uint_t cur); void mp_obj_tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_tuple_t *o = o_in; - print(env, "("); + if (MICROPY_PY_UJSON && kind == PRINT_JSON) { + print(env, "["); + } else { + print(env, "("); + kind = PRINT_REPR; + } for (mp_uint_t i = 0; i < o->len; i++) { if (i > 0) { print(env, ", "); } - mp_obj_print_helper(print, env, o->items[i], PRINT_REPR); + mp_obj_print_helper(print, env, o->items[i], kind); } - if (o->len == 1) { - print(env, ","); + if (MICROPY_PY_UJSON && kind == PRINT_JSON) { + print(env, "]"); + } else { + if (o->len == 1) { + print(env, ","); + } + print(env, ")"); } - print(env, ")"); } STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { @@ -112,6 +112,7 @@ PY_O_BASENAME = \ pfenv_printf.o \ ../extmod/moductypes.o \ ../extmod/modzlibd.o \ + ../extmod/modujson.o \ # prepend the build destination prefix to the py object files PY_O = $(addprefix $(PY_BUILD)/, $(PY_O_BASENAME)) diff --git a/py/qstrdefs.h b/py/qstrdefs.h index d41029a1fa..41ffa1d201 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -463,3 +463,8 @@ Q(deleter) Q(zlibd) Q(decompress) #endif + +#if MICROPY_PY_UJSON +Q(ujson) +Q(dumps) +#endif |