builtinhelp.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013-2016 Damien P. George
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include "py/builtin.h"
  29. #include "py/objmodule.h"
  30. #if MICROPY_PY_BUILTINS_HELP
  31. const char mp_help_default_text[] =
  32. "Welcome to MicroPython!\n"
  33. "\n"
  34. "For online docs please visit http://docs.micropython.org/\n"
  35. "\n"
  36. "Control commands:\n"
  37. " CTRL-A -- on a blank line, enter raw REPL mode\n"
  38. " CTRL-B -- on a blank line, enter normal REPL mode\n"
  39. " CTRL-C -- interrupt a running program\n"
  40. " CTRL-D -- on a blank line, exit or do a soft reset\n"
  41. " CTRL-E -- on a blank line, enter paste mode\n"
  42. "\n"
  43. "For further help on a specific object, type help(obj)\n"
  44. ;
  45. static void mp_help_print_info_about_object(mp_obj_t name_o, mp_obj_t value) {
  46. mp_print_str(MP_PYTHON_PRINTER, " ");
  47. mp_obj_print(name_o, PRINT_STR);
  48. mp_print_str(MP_PYTHON_PRINTER, " -- ");
  49. mp_obj_print(value, PRINT_STR);
  50. mp_print_str(MP_PYTHON_PRINTER, "\n");
  51. }
  52. #if MICROPY_PY_BUILTINS_HELP_MODULES
  53. static void mp_help_add_from_map(mp_obj_t list, const mp_map_t *map) {
  54. for (size_t i = 0; i < map->alloc; i++) {
  55. if (mp_map_slot_is_filled(map, i)) {
  56. mp_obj_list_append(list, map->table[i].key);
  57. }
  58. }
  59. }
  60. #if MICROPY_MODULE_FROZEN
  61. static void mp_help_add_from_names(mp_obj_t list, const char *name) {
  62. while (*name) {
  63. size_t len = strlen(name);
  64. // name should end in '.py' and we strip it off
  65. mp_obj_list_append(list, mp_obj_new_str(name, len - 3));
  66. name += len + 1;
  67. }
  68. }
  69. #endif
  70. static void mp_help_print_modules(void) {
  71. mp_obj_t list = mp_obj_new_list(0, NULL);
  72. mp_help_add_from_map(list, &mp_builtin_module_map);
  73. mp_help_add_from_map(list, &mp_builtin_extensible_module_map);
  74. #if MICROPY_MODULE_FROZEN
  75. extern const char mp_frozen_names[];
  76. mp_help_add_from_names(list, mp_frozen_names);
  77. #endif
  78. // sort the list so it's printed in alphabetical order
  79. mp_obj_list_sort(1, &list, (mp_map_t *)&mp_const_empty_map);
  80. // print the list of modules in a column-first order
  81. #define NUM_COLUMNS (4)
  82. #define COLUMN_WIDTH (18)
  83. size_t len;
  84. mp_obj_t *items;
  85. mp_obj_list_get(list, &len, &items);
  86. unsigned int num_rows = (len + NUM_COLUMNS - 1) / NUM_COLUMNS;
  87. for (unsigned int i = 0; i < num_rows; ++i) {
  88. unsigned int j = i;
  89. for (;;) {
  90. int l = mp_print_str(MP_PYTHON_PRINTER, mp_obj_str_get_str(items[j]));
  91. j += num_rows;
  92. if (j >= len) {
  93. break;
  94. }
  95. int gap = COLUMN_WIDTH - l;
  96. while (gap < 1) {
  97. gap += COLUMN_WIDTH;
  98. }
  99. while (gap--) {
  100. mp_print_str(MP_PYTHON_PRINTER, " ");
  101. }
  102. }
  103. mp_print_str(MP_PYTHON_PRINTER, "\n");
  104. }
  105. #if MICROPY_ENABLE_EXTERNAL_IMPORT
  106. // let the user know there may be other modules available from the filesystem
  107. mp_print_str(MP_PYTHON_PRINTER, "Plus any modules on the filesystem\n");
  108. #endif
  109. }
  110. #endif
  111. static void mp_help_print_obj(const mp_obj_t obj) {
  112. #if MICROPY_PY_BUILTINS_HELP_MODULES
  113. if (obj == MP_OBJ_NEW_QSTR(MP_QSTR_modules)) {
  114. mp_help_print_modules();
  115. return;
  116. }
  117. #endif
  118. const mp_obj_type_t *type = mp_obj_get_type(obj);
  119. // try to print something sensible about the given object
  120. mp_print_str(MP_PYTHON_PRINTER, "object ");
  121. mp_obj_print(obj, PRINT_STR);
  122. mp_printf(MP_PYTHON_PRINTER, " is of type %q\n", type->name);
  123. mp_map_t *map = NULL;
  124. if (type == &mp_type_module) {
  125. map = &mp_obj_module_get_globals(obj)->map;
  126. } else {
  127. if (type == &mp_type_type) {
  128. type = MP_OBJ_TO_PTR(obj);
  129. }
  130. if (MP_OBJ_TYPE_HAS_SLOT(type, locals_dict)) {
  131. map = &MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->map;
  132. }
  133. }
  134. if (map != NULL) {
  135. for (uint i = 0; i < map->alloc; i++) {
  136. mp_obj_t key = map->table[i].key;
  137. if (key != MP_OBJ_NULL) {
  138. mp_help_print_info_about_object(key, map->table[i].value);
  139. }
  140. }
  141. }
  142. }
  143. static mp_obj_t mp_builtin_help(size_t n_args, const mp_obj_t *args) {
  144. if (n_args == 0) {
  145. // print a general help message
  146. mp_print_str(MP_PYTHON_PRINTER, MICROPY_PY_BUILTINS_HELP_TEXT);
  147. } else {
  148. // try to print something sensible about the given object
  149. mp_help_print_obj(args[0]);
  150. }
  151. return mp_const_none;
  152. }
  153. MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, mp_builtin_help);
  154. #endif // MICROPY_PY_BUILTINS_HELP