2017-01-21 07:17:51 -05:00
/*
* This file is part of the MicroPython project , http : //micropython.org/
*
* The MIT License ( MIT )
*
2020-06-03 18:40:05 -04:00
* SPDX - FileCopyrightText : Copyright ( c ) 2013 - 2016 Damien P . George
2017-01-21 07:17:51 -05:00
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
# include <stdio.h>
2017-01-21 20:12:54 -05:00
# include <string.h>
2017-01-21 07:17:51 -05:00
2018-11-09 19:41:08 -05:00
# include "genhdr/mpversion.h"
2017-01-21 07:17:51 -05:00
# include "py/builtin.h"
2017-06-20 13:56:05 -04:00
# include "py/mpconfig.h"
2017-01-21 20:12:54 -05:00
# include "py/objmodule.h"
2017-01-21 07:17:51 -05:00
2022-05-27 15:59:54 -04:00
# include "supervisor/shared/translate/translate.h"
2017-01-21 07:17:51 -05:00
# if MICROPY_PY_BUILTINS_HELP
2017-09-12 02:03:52 -04:00
const char mp_help_default_text [ ] =
2021-03-15 09:57:36 -04:00
" Welcome to MicroPython! \n "
" \n "
" For online docs please visit http://docs.micropython.org/ \n "
" \n "
" Control commands: \n "
" CTRL-A -- on a blank line, enter raw REPL mode \n "
" CTRL-B -- on a blank line, enter normal REPL mode \n "
" CTRL-C -- interrupt a running program \n "
" CTRL-D -- on a blank line, exit or do a soft reset \n "
" CTRL-E -- on a blank line, enter paste mode \n "
" \n "
" For further help on a specific object, type help(obj) \n "
2017-01-21 07:17:51 -05:00
;
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 " ) ;
}
2017-01-21 20:12:54 -05:00
# if MICROPY_PY_BUILTINS_HELP_MODULES
STATIC void mp_help_add_from_map ( mp_obj_t list , const mp_map_t * map ) {
for ( size_t i = 0 ; i < map - > alloc ; i + + ) {
2021-04-22 20:55:39 -04:00
if ( mp_map_slot_is_filled ( map , i ) ) {
2017-01-21 20:12:54 -05:00
mp_obj_list_append ( list , map - > table [ i ] . key ) ;
}
}
}
# if MICROPY_MODULE_FROZEN
STATIC void mp_help_add_from_names ( mp_obj_t list , const char * name ) {
while ( * name ) {
2021-12-11 06:40:21 -05:00
size_t len = strlen ( name ) ;
2017-01-21 20:12:54 -05:00
// name should end in '.py' and we strip it off
2021-12-11 06:40:21 -05:00
mp_obj_list_append ( list , mp_obj_new_str ( name , len - 3 ) ) ;
name + = len + 1 ;
2017-01-21 20:12:54 -05:00
}
}
# endif
2017-07-15 17:03:24 -04:00
// These externs were originally declared inside mp_help_print_modules(),
// but they triggered -Wnested-externs, so they were moved outside.
2022-02-16 16:33:54 -05:00
# if MICROPY_MODULE_FROZEN
extern const char mp_frozen_names [ ] ;
2017-07-15 17:03:24 -04:00
# endif
2017-01-21 20:12:54 -05:00
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 ) ;
2021-12-11 06:40:21 -05:00
# if MICROPY_MODULE_FROZEN
mp_help_add_from_names ( list , mp_frozen_names ) ;
2017-01-21 20:12:54 -05:00
# endif
// sort the list so it's printed in alphabetical order
2021-03-15 09:57:36 -04:00
mp_obj_list_sort ( 1 , & list , ( mp_map_t * ) & mp_const_empty_map ) ;
2017-01-21 20:12:54 -05:00
// print the list of modules in a column-first order
# define NUM_COLUMNS (4)
# define COLUMN_WIDTH (18)
2018-05-02 02:50:28 -04:00
size_t len ;
2017-01-21 20:12:54 -05:00
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 " ) ;
}
2021-04-22 20:55:39 -04:00
# if MICROPY_ENABLE_EXTERNAL_IMPORT
2017-01-21 20:12:54 -05:00
// let the user know there may be other modules available from the filesystem
2021-09-06 06:58:00 -04:00
serial_write_compressed ( translate ( " Plus any modules on the filesystem \n " ) ) ;
2021-04-22 20:55:39 -04:00
# endif
2017-01-21 20:12:54 -05:00
}
# endif
2017-01-21 07:17:51 -05:00
STATIC void mp_help_print_obj ( const mp_obj_t obj ) {
2017-01-21 20:12:54 -05:00
# if MICROPY_PY_BUILTINS_HELP_MODULES
if ( obj = = MP_OBJ_NEW_QSTR ( MP_QSTR_modules ) ) {
mp_help_print_modules ( ) ;
return ;
}
# endif
2020-01-08 19:01:14 -05:00
const mp_obj_type_t * type = mp_obj_get_type ( obj ) ;
2017-09-10 01:15:41 -04:00
2017-01-21 07:17:51 -05:00
// try to print something sensible about the given object
2021-08-08 11:27:50 -04:00
mp_cprintf ( MP_PYTHON_PRINTER , translate ( " object " ) ) ;
2017-01-21 07:17:51 -05:00
mp_obj_print ( obj , PRINT_STR ) ;
2020-12-30 18:47:35 -05:00
2021-08-08 11:27:50 -04:00
mp_cprintf ( MP_PYTHON_PRINTER , translate ( " is of type %q \n " ) , type - > name ) ;
2017-01-21 07:17:51 -05:00
mp_map_t * map = NULL ;
2017-09-10 01:15:41 -04:00
if ( type = = & mp_type_module ) {
2018-07-08 07:31:09 -04:00
map = & mp_obj_module_get_globals ( obj ) - > map ;
2017-01-21 07:17:51 -05:00
} else {
2017-09-10 01:15:41 -04:00
if ( type = = & mp_type_type ) {
type = MP_OBJ_TO_PTR ( obj ) ;
2017-01-21 07:17:51 -05:00
}
2018-07-08 07:31:09 -04:00
if ( type - > locals_dict ! = NULL ) {
map = & type - > locals_dict - > map ;
2017-01-21 07:17:51 -05:00
}
}
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 mp_obj_t mp_builtin_help ( size_t n_args , const mp_obj_t * args ) {
if ( n_args = = 0 ) {
2018-11-09 19:41:08 -05:00
// print a general help message. Translate only works on single strings on one line.
2021-08-08 11:27:50 -04:00
mp_cprintf ( MP_PYTHON_PRINTER ,
2021-10-21 18:07:07 -04:00
translate ( " Welcome to Adafruit CircuitPython %s! \n \n Visit circuitpython.org for more information. \n \n To list built-in modules type `help( \" modules \" )`. \n " ) ,
2021-08-08 11:27:50 -04:00
MICROPY_GIT_TAG ) ;
2017-01-21 07:17:51 -05:00
} else {
// try to print something sensible about the given object
mp_help_print_obj ( args [ 0 ] ) ;
}
return mp_const_none ;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN ( mp_builtin_help_obj , 0 , 1 , mp_builtin_help ) ;
# endif // MICROPY_PY_BUILTINS_HELP