STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_adc_obj_t *self = self_in; mp_printf(print, "<ADC1 channel=%u on %q>", self->id, self->pin->name); }
STATIC void ffivar_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_ffivar_t *self = MP_OBJ_TO_PTR(self_in); // Variable value printed as cast to int mp_printf(print, "<ffivar @%p: 0x%x>", self->var, *(int*)self->var); }
STATIC void ubluepy_scan_entry_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { ubluepy_scan_entry_obj_t * self = (ubluepy_scan_entry_obj_t *)o; (void)self; mp_printf(print, "ScanEntry"); }
void TASK_Micropython (void *pvParameters) { // initialize the garbage collector with the top of our stack uint32_t sp = gc_helper_get_sp(); gc_collect_init (sp); bool safeboot = false; mptask_pre_init(); #ifndef DEBUG safeboot = PRCMGetSpecialBit(PRCM_SAFE_BOOT_BIT); #endif soft_reset: // GC init gc_init(&_boot, &_eheap); // MicroPython init mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_init(mp_sys_argv, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) // execute all basic initializations mpexception_init0(); mp_irq_init0(); pyb_sleep_init0(); pin_init0(); mperror_init0(); uart_init0(); timer_init0(); readline_init0(); mod_network_init0(); moduos_init0(); rng_init0(); pybsleep_reset_cause_t rstcause = pyb_sleep_get_reset_cause(); if (rstcause < PYB_SLP_SOFT_RESET) { if (rstcause == PYB_SLP_HIB_RESET) { // when waking up from hibernate we just want // to enable simplelink and leave it as is wlan_first_start(); } else { // only if not comming out of hibernate or a soft reset mptask_enter_ap_mode(); } // enable telnet and ftp servers_start(); } // initialize the serial flash file system mptask_init_sflash_filesystem(); // append the flash paths to the system path mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib)); // reset config variables; they should be set by boot.py MP_STATE_PORT(machine_config_main) = MP_OBJ_NULL; if (!safeboot) { // run boot.py int ret = pyexec_file("boot.py"); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } if (!ret) { // flash the system led mperror_signal_error(); } } // now we initialise sub-systems that need configuration from boot.py, // or whose initialisation can be safely deferred until after running // boot.py. // at this point everything is fully configured and initialised. if (!safeboot) { // run the main script from the current directory. if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { const char *main_py; if (MP_STATE_PORT(machine_config_main) == MP_OBJ_NULL) { main_py = "main.py"; } else { main_py = mp_obj_str_get_str(MP_STATE_PORT(machine_config_main)); } int ret = pyexec_file(main_py); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } if (!ret) { // flash the system led mperror_signal_error(); } } } // main script is finished, so now go into REPL mode. // the REPL mode can change, or it can request a soft reset. for ( ; ; ) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_raw_repl() != 0) { break; } } else { if (pyexec_friendly_repl() != 0) { break; } } } soft_reset_exit: // soft reset pyb_sleep_signal_soft_reset(); mp_printf(&mp_plat_print, "PYB: soft reboot\n"); // disable all callbacks to avoid undefined behaviour // when coming out of a soft reset mp_irq_disable_all(); // cancel the RTC alarm which might be running independent of the irq state pyb_rtc_disable_alarm(); // flush the serial flash buffer sflash_disk_flush(); // clean-up the user socket space modusocket_close_all_user_sockets(); // wait for pending transactions to complete mp_hal_delay_ms(20); goto soft_reset; }
STATIC void ffimod_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_ffimod_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "<ffimod %p>", self->handle); }
void TASK_Micropython (void *pvParameters) { // initialize the garbage collector with the top of our stack uint32_t sp = gc_helper_get_sp(); gc_collect_init (sp); bool safeboot = false; mptask_pre_init(); #ifndef DEBUG safeboot = PRCMGetSpecialBit(PRCM_SAFE_BOOT_BIT); #endif soft_reset: // GC init gc_init(&_boot, &_eheap); // MicroPython init mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_init(mp_sys_argv, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) // execute all basic initializations mpexception_init0(); mpcallback_init0(); pybsleep_init0(); mperror_init0(); uart_init0(); pin_init0(); timer_init0(); readline_init0(); mod_network_init0(); #if MICROPY_HW_ENABLE_RNG rng_init0(); #endif #ifdef LAUNCHXL // configure the stdio uart pins with the correct alternate functions // param 3 ("mode") is DON'T CARE" for AFs others than GPIO pin_config ((pin_obj_t *)&MICROPY_STDIO_UART_TX_PIN, MICROPY_STDIO_UART_TX_PIN_AF, 0, PIN_TYPE_STD_PU, PIN_STRENGTH_2MA); pin_config ((pin_obj_t *)&MICROPY_STDIO_UART_RX_PIN, MICROPY_STDIO_UART_RX_PIN_AF, 0, PIN_TYPE_STD_PU, PIN_STRENGTH_2MA); // instantiate the stdio uart mp_obj_t args[2] = { mp_obj_new_int(MICROPY_STDIO_UART), mp_obj_new_int(MICROPY_STDIO_UART_BAUD), }; pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args); // create a callback for the uart, in order to enable the rx interrupts uart_callback_new (pyb_stdio_uart, mp_const_none, MICROPY_STDIO_UART_RX_BUF_SIZE, INT_PRIORITY_LVL_3); #else pyb_stdio_uart = MP_OBJ_NULL; #endif pybsleep_reset_cause_t rstcause = pybsleep_get_reset_cause(); if (rstcause < PYB_SLP_SOFT_RESET) { if (rstcause == PYB_SLP_HIB_RESET) { // when waking up from hibernate we just want // to enable simplelink and leave it as is wlan_first_start(); } else { // only if not comming out of hibernate or a soft reset mptask_enter_ap_mode(); } // enable telnet and ftp servers_start(); } // initialize the serial flash file system mptask_init_sflash_filesystem(); // append the flash paths to the system path mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib)); // reset config variables; they should be set by boot.py MP_STATE_PORT(pyb_config_main) = MP_OBJ_NULL; if (!safeboot) { // run boot.py int ret = pyexec_file("boot.py"); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } if (!ret) { // flash the system led mperror_signal_error(); } } // now we initialise sub-systems that need configuration from boot.py, // or whose initialisation can be safely deferred until after running // boot.py. // at this point everything is fully configured and initialised. if (!safeboot) { // run the main script from the current directory. if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { const char *main_py; if (MP_STATE_PORT(pyb_config_main) == MP_OBJ_NULL) { main_py = "main.py"; } else { main_py = mp_obj_str_get_str(MP_STATE_PORT(pyb_config_main)); } int ret = pyexec_file(main_py); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } if (!ret) { // flash the system led mperror_signal_error(); } } } // main script is finished, so now go into REPL mode. // the REPL mode can change, or it can request a soft reset. for ( ; ; ) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_raw_repl() != 0) { break; } } else { if (pyexec_friendly_repl() != 0) { break; } } } soft_reset_exit: // soft reset pybsleep_signal_soft_reset(); mp_printf(&mp_plat_print, "PYB: soft reboot\n"); // disable all peripherals that could trigger a callback pyb_rtc_callback_disable(NULL); timer_disable_all(); uart_disable_all(); // flush the serial flash buffer sflash_disk_flush(); // clean-up the user socket space modusocket_close_all_user_sockets(); #if MICROPY_HW_HAS_SDCARD pybsd_disable(); #endif // wait for pending transactions to complete HAL_Delay(20); goto soft_reset; }
// function to run extra tests for things that can't be checked by scripts STATIC mp_obj_t extra_coverage(void) { // mp_printf (used by ports that don't have a native printf) { printf("# mp_printf\n"); mp_printf(&mp_plat_print, "%"); // nothing after percent mp_printf(&mp_plat_print, "%d %+d % d\n", -123, 123, 123); // sign mp_printf(&mp_plat_print, "%05d\n", -123); // negative number with zero padding mp_printf(&mp_plat_print, "%ld\n", 123); // long mp_printf(&mp_plat_print, "%X\n", 0x1abcdef); // capital hex mp_printf(&mp_plat_print, "%.2s %.3s\n", "abc", "abc"); // fixed string precision mp_printf(&mp_plat_print, "%.*s\n", -1, "abc"); // negative string precision mp_printf(&mp_plat_print, "%b %b\n", 0, 1); // bools mp_printf(&mp_plat_print, "%s\n", NULL); // null string mp_printf(&mp_plat_print, "%t\n"); // non-format char } // vstr { printf("# vstr\n"); vstr_t *vstr = vstr_new_size(16); vstr_hint_size(vstr, 32); vstr_add_str(vstr, "ts"); vstr_ins_byte(vstr, 1, 'e'); vstr_ins_char(vstr, 3, 't'); vstr_ins_char(vstr, 10, 's'); printf("%.*s\n", (int)vstr->len, vstr->buf); vstr_cut_head_bytes(vstr, 2); printf("%.*s\n", (int)vstr->len, vstr->buf); vstr_cut_tail_bytes(vstr, 10); printf("%.*s\n", (int)vstr->len, vstr->buf); vstr_printf(vstr, "t%cst", 'e'); printf("%.*s\n", (int)vstr->len, vstr->buf); vstr_cut_out_bytes(vstr, 3, 10); printf("%.*s\n", (int)vstr->len, vstr->buf); VSTR_FIXED(fix, 4); vstr_add_str(&fix, "large"); printf("%.*s\n", (int)fix.len, fix.buf); } // repl autocomplete { printf("# repl\n"); const char *str; mp_uint_t len = mp_repl_autocomplete("__n", 3, &mp_plat_print, &str); printf("%.*s\n", (int)len, str); mp_store_global(MP_QSTR_sys, mp_import_name(MP_QSTR_sys, mp_const_none, MP_OBJ_NEW_SMALL_INT(0))); mp_repl_autocomplete("sys.", 4, &mp_plat_print, &str); len = mp_repl_autocomplete("sys.impl", 8, &mp_plat_print, &str); printf("%.*s\n", (int)len, str); } // attrtuple { printf("# attrtuple\n"); static const qstr fields[] = {MP_QSTR_start, MP_QSTR_stop, MP_QSTR_step}; static const mp_obj_t items[] = {MP_OBJ_NEW_SMALL_INT(1), MP_OBJ_NEW_SMALL_INT(2), MP_OBJ_NEW_SMALL_INT(3)}; mp_obj_print_helper(&mp_plat_print, mp_obj_new_attrtuple(fields, 3, items), PRINT_REPR); printf("\n"); } return mp_const_none; }
STATIC void pyb_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_pin_obj_t *self = self_in; // pin name mp_printf(print, "Pin(%u)", self->phys_port); }
MP_NOINLINE int main_(int argc, char **argv) { mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4)); pre_process_options(argc, argv); char *heap = malloc(heap_size); gc_init(heap, heap + heap_size); mp_init(); #ifdef _WIN32 set_fmode_binary(); #endif mp_obj_list_init(mp_sys_path, 0); mp_obj_list_init(mp_sys_argv, 0); // set default compiler configuration mp_dynamic_compiler.small_int_bits = 31; mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 0; mp_dynamic_compiler.py_builtins_str_unicode = 1; const char *input_file = NULL; const char *output_file = NULL; const char *source_file = NULL; // parse main options for (int a = 1; a < argc; a++) { if (argv[a][0] == '-') { if (strcmp(argv[a], "-X") == 0) { a += 1; } else if (strcmp(argv[a], "-v") == 0) { mp_verbose_flag++; } else if (strncmp(argv[a], "-O", 2) == 0) { if (unichar_isdigit(argv[a][2])) { MP_STATE_VM(mp_optimise_value) = argv[a][2] & 0xf; } else { MP_STATE_VM(mp_optimise_value) = 0; for (char *p = argv[a] + 1; *p && *p == 'O'; p++, MP_STATE_VM(mp_optimise_value)++); } } else if (strcmp(argv[a], "-o") == 0) { if (a + 1 >= argc) { exit(usage(argv)); } a += 1; output_file = argv[a]; } else if (strcmp(argv[a], "-s") == 0) { if (a + 1 >= argc) { exit(usage(argv)); } a += 1; source_file = argv[a]; } else if (strncmp(argv[a], "-msmall-int-bits=", sizeof("-msmall-int-bits=") - 1) == 0) { char *end; mp_dynamic_compiler.small_int_bits = strtol(argv[a] + sizeof("-msmall-int-bits=") - 1, &end, 0); if (*end) { return usage(argv); } // TODO check that small_int_bits is within range of host's capabilities } else if (strcmp(argv[a], "-mno-cache-lookup-bc") == 0) { mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 0; } else if (strcmp(argv[a], "-mcache-lookup-bc") == 0) { mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 1; } else if (strcmp(argv[a], "-mno-unicode") == 0) { mp_dynamic_compiler.py_builtins_str_unicode = 0; } else if (strcmp(argv[a], "-municode") == 0) { mp_dynamic_compiler.py_builtins_str_unicode = 1; } else { return usage(argv); } } else { if (input_file != NULL) { mp_printf(&mp_stderr_print, "multiple input files\n"); exit(1); } input_file = argv[a]; } } if (input_file == NULL) { mp_printf(&mp_stderr_print, "no input file\n"); exit(1); } int ret = compile_and_save(input_file, output_file, source_file); #if MICROPY_PY_MICROPYTHON_MEM_INFO if (mp_verbose_flag) { mp_micropython_mem_info(0, NULL); } #endif mp_deinit(); return ret & 0xff; }
void pyb_switch_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_switch_obj_t *self = self_in; mp_printf(print, "Switch(%u)", SWITCH_ID(self)); }
STATIC void lwip_socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { lwip_socket_obj_t *self = self_in; mp_printf(print, "<socket state=%d timeout=%d incoming=%p off=%d>", self->state, self->timeout, self->incoming.pbuf, self->recv_offset); }
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); }
STATIC void lwip_socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { lwip_socket_obj_t *self = self_in; mp_printf(print, "<socket state=%d timeout=%d incoming=%p remaining=%d>", self->state, self->timeout, self->incoming.pbuf, self->leftover_count); }
STATIC void btree_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "<btree %p>", self->db); }
void pyb_led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_led_obj_t *self = self_in; mp_printf(print, "LED(%u)", LED_ID(self)); }
STATIC void ffifunc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_ffifunc_t *self = self_in; mp_printf(print, "<ffifunc %p>", self->func); }
STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_adc_obj_t *self = self_in; mp_printf(print, "<ADC, channel=%u>", (self->idx + 1)); }
STATIC void machine_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; machine_mem_obj_t *self = self_in; mp_printf(print, "<%u-bit memory>", 8 * self->elem_size); }
STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) { if (n_args == 0) { // print a general help message mp_printf(&mp_plat_print, "%s", help_text); } else { mp_obj_t args0 = args[0]; mp_obj_type_t *args0_type = mp_obj_get_type(args0); if (args0_type->name == MP_QSTR_bound_method) { args0 = ((mp_obj_t*)args0)[1]; // extract method args0_type = mp_obj_get_type(args0); } // see if we have specific help info for this instance for (size_t i = 0; i < MP_ARRAY_SIZE(help_table_instances); i++) { if (args0 == help_table_instances[i].obj) { mp_print_str(&mp_plat_print, help_table_instances[i].doc); //if (args0_type == &mp_type_module) { //TODO here we can list the things inside the module //} return mp_const_none; } } // see if we have specific help info for this type for (size_t i = 0; i < MP_ARRAY_SIZE(help_table_types); i++) { if (args0 == help_table_types[i].obj || args0_type == help_table_types[i].obj) { mp_print_str(&mp_plat_print, help_table_types[i].doc); return mp_const_none; } } // don't have specific help info, try instead to print something sensible mp_printf(&mp_plat_print, "object "); mp_obj_print(args0, PRINT_STR); mp_printf(&mp_plat_print, " is of type %q\n", args0_type->name); mp_map_t *map = NULL; if (args0_type == &mp_type_module) { map = mp_obj_dict_get_map(mp_obj_module_get_globals(args0)); } else { mp_obj_type_t *type; if (args0_type == &mp_type_type) { type = args0; } else { type = args0_type; } 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) { pyb_help_print_info_about_object(map->table[i].key, map->table[i].value); } } } } return mp_const_none; }
STATIC void esp_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { esp_timer_obj_t *self = self_in; mp_printf(print, "Timer(%p)", &self->timer); }
void led_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { board_led_obj_t *self = self_in; mp_printf(print, "LED(%lu)", self->led_id); }
STATIC void pyb_servo_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_servo_obj_t *self = self_in; mp_printf(print, "<Servo %lu at %luus>", self->servo_id, 10 * self->pulse_cur); }
STATIC void fun_bc_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_fun_bc_t *o = MP_OBJ_TO_PTR(o_in); mp_printf(print, "<function %q at 0x%p>", mp_obj_fun_get_name(o_in), o); }
STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_socket_t *self = self_in; mp_printf(print, "<_socket %d>", self->fd); }
STATIC void fficallback_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_fficallback_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "<fficallback %p>", self->func); }
STATIC void pyb_hspi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "HSPI(baudrate=%u, polarity=%u, phase=%u)", self->baudrate, self->polarity, self->phase); }
STATIC void ubluepy_characteristic_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { ubluepy_characteristic_obj_t * self = (ubluepy_characteristic_obj_t *)o; mp_printf(print, "Characteristic(handle: 0x" HEX2_FMT ", conn_handle: " HEX2_FMT ")", self->handle, self->p_service->p_periph->conn_handle); }
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 = MP_OBJ_TO_PTR(self_in); mp_printf(print, "UART(%u, baudrate=%u, timeout=%u, timeout_char=%u)", self->uart_id, UART_BAUDRATE, self->timeout, self->timeout_char); }
size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print, const char **compl_str) { // scan backwards to find start of "a.b.c" chain const char *org_str = str; const char *top = str + len; for (const char *s = top; --s >= str;) { if (!(unichar_isalpha(*s) || unichar_isdigit(*s) || *s == '_' || *s == '.')) { ++s; str = s; break; } } size_t nqstr = QSTR_TOTAL(); // begin search in outer global dict which is accessed from __main__ mp_obj_t obj = MP_OBJ_FROM_PTR(&mp_module___main__); mp_obj_t dest[2]; for (;;) { // get next word in string to complete const char *s_start = str; while (str < top && *str != '.') { ++str; } size_t s_len = str - s_start; if (str < top) { // a complete word, lookup in current object qstr q = qstr_find_strn(s_start, s_len); if (q == MP_QSTR_NULL) { // lookup will fail return 0; } mp_load_method_maybe(obj, q, dest); obj = dest[0]; // attribute, method, or MP_OBJ_NULL if nothing found if (obj == MP_OBJ_NULL) { // lookup failed return 0; } // skip '.' to move to next word ++str; } else { // end of string, do completion on this partial name // look for matches const char *match_str = NULL; size_t match_len = 0; qstr q_first = 0, q_last; for (qstr q = 1; q < nqstr; ++q) { size_t d_len; const char *d_str = (const char*)qstr_data(q, &d_len); if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { mp_load_method_maybe(obj, q, dest); if (dest[0] != MP_OBJ_NULL) { if (match_str == NULL) { match_str = d_str; match_len = d_len; } else { // search for longest common prefix of match_str and d_str // (assumes these strings are null-terminated) for (size_t j = s_len; j <= match_len && j <= d_len; ++j) { if (match_str[j] != d_str[j]) { match_len = j; break; } } } if (q_first == 0) { q_first = q; } q_last = q; } } } // nothing found if (q_first == 0) { // If there're no better alternatives, and if it's first word // in the line, try to complete "import". if (s_start == org_str) { static const char import_str[] = "import "; if (memcmp(s_start, import_str, s_len) == 0) { *compl_str = import_str + s_len; return sizeof(import_str) - 1 - s_len; } } return 0; } // 1 match found, or multiple matches with a common prefix if (q_first == q_last || match_len > s_len) { *compl_str = match_str + s_len; return match_len - s_len; } // multiple matches found, print them out #define WORD_SLOT_LEN (16) #define MAX_LINE_LEN (4 * WORD_SLOT_LEN) int line_len = MAX_LINE_LEN; // force a newline for first word for (qstr q = q_first; q <= q_last; ++q) { size_t d_len; const char *d_str = (const char*)qstr_data(q, &d_len); if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { mp_load_method_maybe(obj, q, dest); if (dest[0] != MP_OBJ_NULL) { int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len; if (gap < 2) { gap += WORD_SLOT_LEN; } if (line_len + gap + d_len <= MAX_LINE_LEN) { // TODO optimise printing of gap? for (int j = 0; j < gap; ++j) { mp_print_str(print, " "); } mp_print_str(print, d_str); line_len += gap + d_len; } else { mp_printf(print, "\n%s", d_str); line_len = d_len; } } } } mp_print_str(print, "\n"); return (size_t)(-1); // indicate many matches } } }
void pyb_rtc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_rtc_obj_t *self = self_in; mp_printf(print, "RTC (%u)", RTC_ID(self) ); }