summaryrefslogtreecommitdiff
path: root/scripts/kconfig/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kconfig/menu.c')
-rw-r--r--scripts/kconfig/menu.c99
1 files changed, 97 insertions, 2 deletions
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 6587ac86d0d5..0f1a6513987c 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -15,7 +15,7 @@
static const char nohelp_text[] = "There is no help available for this option.";
-struct menu rootmenu;
+struct menu rootmenu = { .type = M_MENU };
static struct menu **last_entry_ptr;
/**
@@ -65,12 +65,13 @@ void _menu_init(void)
last_entry_ptr = &rootmenu.list;
}
-void menu_add_entry(struct symbol *sym)
+void menu_add_entry(struct symbol *sym, enum menu_type type)
{
struct menu *menu;
menu = xmalloc(sizeof(*menu));
memset(menu, 0, sizeof(*menu));
+ menu->type = type;
menu->sym = sym;
menu->parent = current_menu;
menu->filename = cur_filename;
@@ -574,8 +575,28 @@ const char *menu_get_prompt(const struct menu *menu)
return NULL;
}
+/**
+ * menu_get_parent_menu - return the parent menu or NULL
+ * @menu: pointer to the menu
+ * return: the parent menu, or NULL if there is no parent.
+ */
struct menu *menu_get_parent_menu(struct menu *menu)
{
+ for (menu = menu->parent; menu; menu = menu->parent)
+ if (menu->type == M_MENU)
+ return menu;
+
+ return NULL;
+}
+
+/**
+ * menu_get_menu_or_parent_menu - return the parent menu or the menu itself
+ * @menu: pointer to the menu
+ * return: the parent menu. If the given argument is already a menu, return
+ * itself.
+ */
+struct menu *menu_get_menu_or_parent_menu(struct menu *menu)
+{
enum prop_type type;
for (; menu != &rootmenu; menu = menu->parent) {
@@ -767,3 +788,77 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
if (sym)
get_symbol_str(help, sym, NULL);
}
+
+/**
+ * menu_dump - dump all menu entries in a tree-like format
+ */
+void menu_dump(void)
+{
+ struct menu *menu = &rootmenu;
+ unsigned long long bits = 0;
+ int indent = 0;
+
+ while (menu) {
+
+ for (int i = indent - 1; i >= 0; i--) {
+ if (bits & (1ULL << i)) {
+ if (i > 0)
+ printf("| ");
+ else
+ printf("|-- ");
+ } else {
+ if (i > 0)
+ printf(" ");
+ else
+ printf("`-- ");
+ }
+ }
+
+ switch (menu->type) {
+ case M_CHOICE:
+ printf("choice \"%s\"\n", menu->prompt->text);
+ break;
+ case M_COMMENT:
+ printf("comment \"%s\"\n", menu->prompt->text);
+ break;
+ case M_IF:
+ printf("if\n");
+ break;
+ case M_MENU:
+ printf("menu \"%s\"", menu->prompt->text);
+ if (!menu->sym) {
+ printf("\n");
+ break;
+ }
+ printf(" + ");
+ /* fallthrough */
+ case M_NORMAL:
+ printf("symbol %s\n", menu->sym->name);
+ break;
+ }
+ if (menu->list) {
+ bits <<= 1;
+ menu = menu->list;
+ if (menu->next)
+ bits |= 1;
+ else
+ bits &= ~1;
+ indent++;
+ continue;
+ }
+
+ while (menu && !menu->next) {
+ menu = menu->parent;
+ bits >>= 1;
+ indent--;
+ }
+
+ if (menu) {
+ menu = menu->next;
+ if (menu->next)
+ bits |= 1;
+ else
+ bits &= ~1;
+ }
+ }
+}