STATIC void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_exception_t *o = MP_OBJ_TO_PTR(o_in); mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; bool is_subclass = kind & PRINT_EXC_SUBCLASS; if (!is_subclass && (k == PRINT_REPR || k == PRINT_EXC)) { mp_print_str(print, qstr_str(o->base.type->name)); } if (k == PRINT_EXC) { mp_print_str(print, ": "); } if (k == PRINT_STR || k == PRINT_EXC) { if (o->args == NULL || o->args->len == 0) { mp_print_str(print, ""); return; } else if (o->args->len == 1) { #if MICROPY_PY_UERRNO // try to provide a nice OSError error message if (o->base.type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(o->args->items[0])) { qstr qst = mp_errno_to_str(o->args->items[0]); if (qst != MP_QSTR_NULL) { mp_printf(print, "[Errno %d] %q", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), qst); return; } } #endif mp_obj_print_helper(print, o->args->items[0], PRINT_STR); return; } } mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind); }
STATIC void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); bool first = true; if (!(MICROPY_PY_UJSON && kind == PRINT_JSON)) { kind = PRINT_REPR; } if (MICROPY_PY_COLLECTIONS_ORDEREDDICT && self->base.type != &mp_type_dict) { mp_printf(print, "%q(", self->base.type->name); } mp_print_str(print, "{"); size_t cur = 0; mp_map_elem_t *next = NULL; while ((next = dict_iter_next(self, &cur)) != NULL) { if (!first) { mp_print_str(print, ", "); } first = false; mp_obj_print_helper(print, next->key, kind); mp_print_str(print, ": "); mp_obj_print_helper(print, next->value, kind); } mp_print_str(print, "}"); if (MICROPY_PY_COLLECTIONS_ORDEREDDICT && self->base.type != &mp_type_dict) { mp_print_str(print, ")"); } }
STATIC void mp_help_print_info_about_object(mp_obj_t name_o, mp_obj_t value) { mp_print_str(MP_PYTHON_PRINTER, " "); mp_obj_print(name_o, PRINT_STR); mp_print_str(MP_PYTHON_PRINTER, " -- "); mp_obj_print(value, PRINT_STR); mp_print_str(MP_PYTHON_PRINTER, "\n"); }
// helper function to print an exception with traceback void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { if (mp_obj_is_exception_instance(exc)) { size_t n, *values; mp_obj_exception_get_traceback(exc, &n, &values); if (n > 0) { assert(n % 3 == 0); mp_print_str(print, "Traceback (most recent call last):\n"); for (int i = n - 3; i >= 0; i -= 3) { #if MICROPY_ENABLE_SOURCE_LINE mp_printf(print, " File \"%q\", line %d", values[i], (int)values[i + 1]); #else mp_printf(print, " File \"%q\"", values[i]); #endif // the block name can be NULL if it's unknown qstr block = values[i + 2]; if (block == MP_QSTR_NULL) { mp_print_str(print, "\n"); } else { mp_printf(print, ", in %q\n", block); } } } } mp_obj_print_helper(print, exc, PRINT_EXC); mp_print_str(print, "\n"); }
void mp_warning(const char *msg, ...) { va_list args; va_start(args, msg); mp_print_str(MICROPY_ERROR_PRINTER, "Warning: "); mp_vprintf(MICROPY_ERROR_PRINTER, msg, args); mp_print_str(MICROPY_ERROR_PRINTER, "\n"); va_end(args); }
/// \method __str__() /// Return a string describing the pin object. STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pin_obj_t *self = MP_OBJ_TO_PTR(self_in); // pin name mp_printf(print, "Pin(Pin.cpu.%q, mode=Pin.", self->name); uint32_t mode = pin_get_mode(self); if (mode == GPIO_MODE_ANALOG) { // analog mp_print_str(print, "ANALOG)"); } else { // IO mode bool af = false; qstr mode_qst; if (mode == GPIO_MODE_INPUT) { mode_qst = MP_QSTR_IN; } else if (mode == GPIO_MODE_OUTPUT_PP) { mode_qst = MP_QSTR_OUT; } else if (mode == GPIO_MODE_OUTPUT_OD) { mode_qst = MP_QSTR_OPEN_DRAIN; } else { af = true; if (mode == GPIO_MODE_AF_PP) { mode_qst = MP_QSTR_ALT; } else { mode_qst = MP_QSTR_ALT_OPEN_DRAIN; } } mp_print_str(print, qstr_str(mode_qst)); // pull mode qstr pull_qst = MP_QSTR_NULL; uint32_t pull = pin_get_pull(self); if (pull == GPIO_PULLUP) { pull_qst = MP_QSTR_PULL_UP; } else if (pull == GPIO_PULLDOWN) { pull_qst = MP_QSTR_PULL_DOWN; } if (pull_qst != MP_QSTR_NULL) { mp_printf(print, ", pull=Pin.%q", pull_qst); } // AF mode if (af) { mp_uint_t af_idx = pin_get_af(self); const pin_af_obj_t *af_obj = pin_find_af_by_index(self, af_idx); if (af_obj == NULL) { mp_printf(print, ", af=%d)", af_idx); } else { mp_printf(print, ", af=Pin.%q)", af_obj->name); } } else { mp_print_str(print, ")"); } } }
STATIC #endif void mp_obj_attrtuple_print_helper(const mp_print_t *print, const qstr *fields, mp_obj_tuple_t *o) { mp_print_str(print, "("); for (mp_uint_t i = 0; i < o->len; i++) { if (i > 0) { mp_print_str(print, ", "); } mp_printf(print, "%q=", fields[i]); mp_obj_print_helper(print, o->items[i], PRINT_REPR); } mp_print_str(print, ")"); }
STATIC void mp_help_print_modules(void) { mp_obj_t list = mp_obj_new_list(0, NULL); mp_help_add_from_map(list, &mp_builtin_module_map); #if MICROPY_MODULE_WEAK_LINKS mp_help_add_from_map(list, &mp_builtin_module_weak_links_map); #endif #if MICROPY_MODULE_FROZEN_STR extern const char mp_frozen_str_names[]; mp_help_add_from_names(list, mp_frozen_str_names); #endif #if MICROPY_MODULE_FROZEN_MPY extern const char mp_frozen_mpy_names[]; mp_help_add_from_names(list, mp_frozen_mpy_names); #endif // sort the list so it's printed in alphabetical order mp_obj_list_sort(1, &list, (mp_map_t*)&mp_const_empty_map); // print the list of modules in a column-first order #define NUM_COLUMNS (4) #define COLUMN_WIDTH (18) mp_uint_t len; mp_obj_t *items; mp_obj_list_get(list, &len, &items); unsigned int num_rows = (len + NUM_COLUMNS - 1) / NUM_COLUMNS; for (unsigned int i = 0; i < num_rows; ++i) { unsigned int j = i; for (;;) { int l = mp_print_str(MP_PYTHON_PRINTER, mp_obj_str_get_str(items[j])); j += num_rows; if (j >= len) { break; } int gap = COLUMN_WIDTH - l; while (gap < 1) { gap += COLUMN_WIDTH; } while (gap--) { mp_print_str(MP_PYTHON_PRINTER, " "); } } mp_print_str(MP_PYTHON_PRINTER, "\n"); } // let the user know there may be other modules available from the filesystem mp_print_str(MP_PYTHON_PRINTER, "Plus any modules on the filesystem\n"); }
STATIC void list_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_list_t *o = MP_OBJ_TO_PTR(o_in); if (!(MICROPY_PY_UJSON && kind == PRINT_JSON)) { kind = PRINT_REPR; } mp_print_str(print, "["); for (size_t i = 0; i < o->len; i++) { if (i > 0) { mp_print_str(print, ", "); } mp_obj_print_helper(print, o->items[i], kind); } mp_print_str(print, "]"); }
STATIC void bool_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_bool_t *self = self_in; if (MICROPY_PY_UJSON && kind == PRINT_JSON) { if (self->value) { mp_print_str(print, "true"); } else { mp_print_str(print, "false"); } } else { if (self->value) { mp_print_str(print, "True"); } else { mp_print_str(print, "False"); } } }
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_uart_obj_t *self = self_in; if (!self->is_enabled) { mp_printf(print, "UART(%u)", self->uart_id); } else { mp_int_t bits = (self->uart.Init.WordLength == UART_WORDLENGTH_8B ? 8 : 9); if (self->uart.Init.Parity != UART_PARITY_NONE) { bits -= 1; } mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=", self->uart_id, self->uart.Init.BaudRate, bits); if (self->uart.Init.Parity == UART_PARITY_NONE) { mp_print_str(print, "None"); } else { mp_printf(print, "%u", self->uart.Init.Parity == UART_PARITY_EVEN ? 0 : 1); } if (self->uart.Init.HwFlowCtl) { mp_printf(print, ", flow="); if (self->uart.Init.HwFlowCtl & UART_HWCONTROL_RTS) { mp_printf(print, "RTS%s", self->uart.Init.HwFlowCtl & UART_HWCONTROL_CTS ? "|" : ""); } if (self->uart.Init.HwFlowCtl & UART_HWCONTROL_CTS) { mp_printf(print, "CTS"); } } mp_printf(print, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u)", self->uart.Init.StopBits == UART_STOPBITS_1 ? 1 : 2, self->timeout, self->timeout_char, self->read_buf_len == 0 ? 0 : self->read_buf_len - 1); // -1 to adjust for usable length of buffer } }
STATIC void closure_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_closure_t *o = MP_OBJ_TO_PTR(o_in); mp_print_str(print, "<closure "); mp_obj_print_helper(print, o->fun, PRINT_REPR); mp_printf(print, " at %p, n_closed=%u ", o, (int)o->n_closed); for (mp_uint_t i = 0; i < o->n_closed; i++) { if (o->closed[i] == MP_OBJ_NULL) { mp_print_str(print, "(nil)"); } else { mp_obj_print_helper(print, o->closed[i], PRINT_REPR); } mp_print_str(print, " "); } mp_print_str(print, ">"); }
STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_float_t o_val = mp_obj_float_get(o_in); #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT char buf[16]; const int precision = 7; #else char buf[32]; const int precision = 16; #endif mp_format_float(o_val, buf, sizeof(buf), 'g', precision, '\0'); mp_print_str(print, buf); if (strchr(buf, '.') == NULL && strchr(buf, 'e') == NULL && strchr(buf, 'n') == NULL) { // Python floats always have decimal point (unless inf or nan) mp_print_str(print, ".0"); } }
STATIC void dict_view_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; assert(MP_OBJ_IS_TYPE(self_in, &dict_view_type)); mp_obj_dict_view_t *self = MP_OBJ_CAST(self_in); bool first = true; mp_print_str(print, mp_dict_view_names[self->kind]); mp_print_str(print, "(["); mp_obj_t self_iter = dict_view_getiter(self_in); mp_obj_t next = MP_OBJ_NULL; while ((next = dict_view_it_iternext(self_iter)) != MP_OBJ_STOP_ITERATION) { if (!first) { mp_print_str(print, ", "); } first = false; mp_obj_print_helper(print, next, PRINT_REPR); } mp_print_str(print, "])"); }
STATIC void uni_print_quoted(const mp_print_t *print, const byte *str_data, uint str_len) { // this escapes characters, but it will be very slow to print (calling print many times) bool has_single_quote = false; bool has_double_quote = false; for (const byte *s = str_data, *top = str_data + str_len; !has_double_quote && s < top; s++) { if (*s == '\'') { has_single_quote = true; } else if (*s == '"') { has_double_quote = true; } } unichar quote_char = '\''; if (has_single_quote && !has_double_quote) { quote_char = '"'; } mp_printf(print, "%c", quote_char); 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 == quote_char) { mp_printf(print, "\\%c", quote_char); } else if (ch == '\\') { mp_print_str(print, "\\\\"); } else if (32 <= ch && ch <= 126) { mp_printf(print, "%c", ch); } else if (ch == '\n') { mp_print_str(print, "\\n"); } else if (ch == '\r') { mp_print_str(print, "\\r"); } else if (ch == '\t') { mp_print_str(print, "\\t"); } else if (ch < 0x100) { mp_printf(print, "\\x%02x", ch); } else if (ch < 0x10000) { mp_printf(print, "\\u%04x", ch); } else { mp_printf(print, "\\U%08x", ch); } } mp_printf(print, "%c", quote_char); }
STATIC void range_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "range(" INT_FMT ", " INT_FMT "", self->start, self->stop); if (self->step == 1) { mp_print_str(print, ")"); } else { mp_printf(print, ", " INT_FMT ")", self->step); } }
STATIC void range_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_range_t *self = self_in; mp_printf(print, "range(%d, %d", self->start, self->stop); if (self->step == 1) { mp_print_str(print, ")"); } else { mp_printf(print, ", %d)", self->step); } }
STATIC mp_obj_t mp_builtin_help(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { // print a general help message mp_print_str(MP_PYTHON_PRINTER, MICROPY_PY_BUILTINS_HELP_TEXT); } else { // try to print something sensible about the given object mp_help_print_obj(args[0]); } return mp_const_none; }
STATIC void array_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_array_t *o = o_in; if (o->typecode == BYTEARRAY_TYPECODE) { mp_print_str(print, "bytearray(b"); mp_str_print_quoted(print, o->items, o->len, true); } else { mp_printf(print, "array('%c'", o->typecode); if (o->len > 0) { mp_print_str(print, ", ["); for (mp_uint_t i = 0; i < o->len; i++) { if (i > 0) { mp_print_str(print, ", "); } mp_obj_print_helper(print, mp_binary_get_val_array(o->typecode, o->items, i), PRINT_REPR); } mp_print_str(print, "]"); } } mp_print_str(print, ")"); }
STATIC void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_exception_t *o = MP_OBJ_TO_PTR(o_in); mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; bool is_subclass = kind & PRINT_EXC_SUBCLASS; if (!is_subclass && (k == PRINT_REPR || k == PRINT_EXC)) { mp_print_str(print, qstr_str(o->base.type->name)); } if (k == PRINT_EXC) { mp_print_str(print, ": "); } if (k == PRINT_STR || k == PRINT_EXC) { if (o->args == NULL || o->args->len == 0) { mp_print_str(print, ""); return; } else if (o->args->len == 1) { mp_obj_print_helper(print, o->args->items[0], PRINT_STR); return; } } mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind); }
void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { // There can be data structures nested too deep, or just recursive MP_STACK_CHECK(); #ifndef NDEBUG if (o_in == MP_OBJ_NULL) { mp_print_str(print, "(nil)"); return; } #endif mp_obj_type_t *type = mp_obj_get_type(o_in); if (type->print != NULL) { type->print((mp_print_t*)print, o_in, kind); } else { mp_printf(print, "<%q>", type->name); } }
void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; // The size of this buffer is rather arbitrary. If it's not large // enough, a dynamic one will be allocated. char stack_buf[sizeof(mp_int_t) * 4]; char *buf = stack_buf; mp_uint_t buf_size = sizeof(stack_buf); mp_uint_t fmt_size; char *str = mp_obj_int_formatted(&buf, &buf_size, &fmt_size, self_in, 10, NULL, '\0', '\0'); mp_print_str(print, str); if (buf != stack_buf) { m_del(char, buf, buf_size); } }
STATIC void mp_help_print_obj(mp_obj_t obj) { #if MICROPY_PY_BUILTINS_HELP_MODULES if (obj == MP_OBJ_NEW_QSTR(MP_QSTR_modules)) { mp_help_print_modules(); return; } #endif // Extract method from bound method, for better error messages if (mp_obj_get_type(obj)->name == MP_QSTR_bound_method) { obj = ((mp_obj_t*)obj)[1]; // extract method } // Hook into platform-specific help for this object extern bool mp_plat_specific_help(mp_obj_t obj); if (mp_plat_specific_help(obj)) { return; } // try to print something sensible about the given object mp_print_str(MP_PYTHON_PRINTER, "object "); mp_obj_print(obj, PRINT_STR); mp_printf(MP_PYTHON_PRINTER, " is of type %s\n", mp_obj_get_type_str(obj)); mp_map_t *map = NULL; if (MP_OBJ_IS_TYPE(obj, &mp_type_module)) { map = mp_obj_dict_get_map(mp_obj_module_get_globals(obj)); } else { mp_obj_type_t *type; if (MP_OBJ_IS_TYPE(obj, &mp_type_type)) { type = obj; } else { type = mp_obj_get_type(obj); } if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &mp_type_dict)) { map = mp_obj_dict_get_map(type->locals_dict); } } if (map != NULL) { for (uint i = 0; i < map->alloc; i++) { if (map->table[i].key != MP_OBJ_NULL) { mp_help_print_info_about_object(map->table[i].key, map->table[i].value); } } } }
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_uart_obj_t *self = self_in; if (!self->is_enabled) { mp_printf(print, "UART(%lu)", self->uart_id); } else { #if 0 mp_printf(print, "UART(%lu, baudrate=%u, bits=%u, stop=%u", self->uart_id, self->uart.Init.BaudRate, self->uart.Init.WordLength == UART_WORDLENGTH_8B ? 8 : 9, self->uart.Init.StopBits == UART_STOPBITS_1 ? 1 : 2); if (self->uart.Init.Parity == UART_PARITY_NONE) { mp_print_str(print, ", parity=None)"); } else { mp_printf(print, ", parity=%u)", self->uart.Init.Parity == UART_PARITY_EVEN ? 0 : 1); } #endif } }
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_uart_obj_t *self = self_in; if (!self->is_enabled) { mp_printf(print, "UART(%u)", self->uart_id); } else { mp_int_t bits = (self->uart.Init.WordLength == UART_WORDLENGTH_8B ? 8 : 9); if (self->uart.Init.Parity != UART_PARITY_NONE) { bits -= 1; } mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=", self->uart_id, self->uart.Init.BaudRate, bits); if (self->uart.Init.Parity == UART_PARITY_NONE) { mp_print_str(print, "None"); } else { mp_printf(print, "%u", self->uart.Init.Parity == UART_PARITY_EVEN ? 0 : 1); } mp_printf(print, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u)", self->uart.Init.StopBits == UART_STOPBITS_1 ? 1 : 2, self->timeout, self->timeout_char, self->read_buf_len); } }
STATIC void complex_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_complex_t *o = MP_OBJ_TO_PTR(o_in); #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT char buf[16]; const int precision = 7; #else char buf[32]; const int precision = 16; #endif if (o->real == 0) { mp_format_float(o->imag, buf, sizeof(buf), 'g', precision, '\0'); mp_printf(print, "%sj", buf); } else { mp_format_float(o->real, buf, sizeof(buf), 'g', precision, '\0'); mp_printf(print, "(%s", buf); if (o->imag >= 0 || isnan(o->imag)) { mp_print_str(print, "+"); } mp_format_float(o->imag, buf, sizeof(buf), 'g', precision, '\0'); mp_printf(print, "%sj)", buf); } }
STATIC void set_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in); #if MICROPY_PY_BUILTINS_FROZENSET bool is_frozen = MP_OBJ_IS_TYPE(self_in, &mp_type_frozenset); #endif if (self->set.used == 0) { #if MICROPY_PY_BUILTINS_FROZENSET if (is_frozen) { mp_print_str(print, "frozen"); } #endif mp_print_str(print, "set()"); return; } bool first = true; #if MICROPY_PY_BUILTINS_FROZENSET if (is_frozen) { mp_print_str(print, "frozenset("); } #endif mp_print_str(print, "{"); for (size_t i = 0; i < self->set.alloc; i++) { if (MP_SET_SLOT_IS_FILLED(&self->set, i)) { if (!first) { mp_print_str(print, ", "); } first = false; mp_obj_print_helper(print, self->set.table[i], PRINT_REPR); } } mp_print_str(print, "}"); #if MICROPY_PY_BUILTINS_FROZENSET if (is_frozen) { mp_print_str(print, ")"); } #endif }
void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_tuple_t *o = o_in; if (MICROPY_PY_UJSON && kind == PRINT_JSON) { mp_print_str(print, "["); } else { mp_print_str(print, "("); kind = PRINT_REPR; } for (mp_uint_t i = 0; i < o->len; i++) { if (i > 0) { mp_print_str(print, ", "); } mp_obj_print_helper(print, o->items[i], kind); } if (MICROPY_PY_UJSON && kind == PRINT_JSON) { mp_print_str(print, "]"); } else { if (o->len == 1) { mp_print_str(print, ","); } mp_print_str(print, ")"); } }
void pyb_switch_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mp_print_str(print, "Switch()"); }
STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_obj_adc_t *self = self_in; mp_print_str(print, "<ADC on "); mp_obj_print_helper(print, self->pin_name, PRINT_STR); mp_printf(print, " channel=%lu>", self->channel); }