2525 */
2626
2727#include <stdio.h>
28+ #include <string.h>
2829
2930#include "py/builtin.h"
31+ #include "py/objmodule.h"
3032
3133#if MICROPY_PY_BUILTINS_HELP
3234
@@ -53,7 +55,87 @@ STATIC void mp_help_print_info_about_object(mp_obj_t name_o, mp_obj_t value) {
5355 mp_print_str (MP_PYTHON_PRINTER , "\n" );
5456}
5557
58+ #if MICROPY_PY_BUILTINS_HELP_MODULES
59+ STATIC void mp_help_add_from_map (mp_obj_t list , const mp_map_t * map ) {
60+ for (size_t i = 0 ; i < map -> alloc ; i ++ ) {
61+ if (MP_MAP_SLOT_IS_FILLED (map , i )) {
62+ mp_obj_list_append (list , map -> table [i ].key );
63+ }
64+ }
65+ }
66+
67+ #if MICROPY_MODULE_FROZEN
68+ STATIC void mp_help_add_from_names (mp_obj_t list , const char * name ) {
69+ while (* name ) {
70+ size_t l = strlen (name );
71+ // name should end in '.py' and we strip it off
72+ mp_obj_list_append (list , mp_obj_new_str (name , l - 3 , false));
73+ name += l + 1 ;
74+ }
75+ }
76+ #endif
77+
78+ STATIC void mp_help_print_modules (void ) {
79+ mp_obj_t list = mp_obj_new_list (0 , NULL );
80+
81+ mp_help_add_from_map (list , & mp_builtin_module_map );
82+
83+ #if MICROPY_MODULE_WEAK_LINKS
84+ mp_help_add_from_map (list , & mp_builtin_module_weak_links_map );
85+ #endif
86+
87+ #if MICROPY_MODULE_FROZEN_STR
88+ extern const char mp_frozen_str_names [];
89+ mp_help_add_from_names (list , mp_frozen_str_names );
90+ #endif
91+
92+ #if MICROPY_MODULE_FROZEN_MPY
93+ extern const char mp_frozen_mpy_names [];
94+ mp_help_add_from_names (list , mp_frozen_mpy_names );
95+ #endif
96+
97+ // sort the list so it's printed in alphabetical order
98+ mp_obj_list_sort (1 , & list , (mp_map_t * )& mp_const_empty_map );
99+
100+ // print the list of modules in a column-first order
101+ #define NUM_COLUMNS (4)
102+ #define COLUMN_WIDTH (18)
103+ mp_uint_t len ;
104+ mp_obj_t * items ;
105+ mp_obj_list_get (list , & len , & items );
106+ unsigned int num_rows = (len + NUM_COLUMNS - 1 ) / NUM_COLUMNS ;
107+ for (unsigned int i = 0 ; i < num_rows ; ++ i ) {
108+ unsigned int j = i ;
109+ for (;;) {
110+ int l = mp_print_str (MP_PYTHON_PRINTER , mp_obj_str_get_str (items [j ]));
111+ j += num_rows ;
112+ if (j >= len ) {
113+ break ;
114+ }
115+ int gap = COLUMN_WIDTH - l ;
116+ while (gap < 1 ) {
117+ gap += COLUMN_WIDTH ;
118+ }
119+ while (gap -- ) {
120+ mp_print_str (MP_PYTHON_PRINTER , " " );
121+ }
122+ }
123+ mp_print_str (MP_PYTHON_PRINTER , "\n" );
124+ }
125+
126+ // let the user know there may be other modules available from the filesystem
127+ mp_print_str (MP_PYTHON_PRINTER , "Plus any modules on the filesystem\n" );
128+ }
129+ #endif
130+
56131STATIC void mp_help_print_obj (const mp_obj_t obj ) {
132+ #if MICROPY_PY_BUILTINS_HELP_MODULES
133+ if (obj == MP_OBJ_NEW_QSTR (MP_QSTR_modules )) {
134+ mp_help_print_modules ();
135+ return ;
136+ }
137+ #endif
138+
57139 // try to print something sensible about the given object
58140 mp_print_str (MP_PYTHON_PRINTER , "object " );
59141 mp_obj_print (obj , PRINT_STR );
0 commit comments