summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasahiro Yamada <masahiroy@kernel.org>2024-04-21 18:02:51 +0900
committerMasahiro Yamada <masahiroy@kernel.org>2024-05-02 19:48:26 +0900
commit7284b4fbc8473965f9c053f3fa8b194af8ed4738 (patch)
tree14827e7f55a227ba728556bb6069bd8465f1d19c
parent377d9095117c084b835e38c020faf5a78e386f01 (diff)
kconfig: add menu_next() function and menu_for_each(_sub)_entry macros
Several functions require traversing menu entries sequentially. This commit introduces some helpers to simplify such operations. The menu_next() function facilitates depth-first traversal: 1. Descend to the child level if the current menu has one 2. Move to the next sibling at the same level if available 3. Ascend to the parent level if there is no more child or sibling The menu_for_each_sub_entry() macro iterates over all submenu entries using depth-first traverse. The menu_for_each_entry() macro is the same, but over all menu entries. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
-rw-r--r--scripts/kconfig/lkc.h5
-rw-r--r--scripts/kconfig/menu.c21
2 files changed, 26 insertions, 0 deletions
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index e7cc9e985c4f..cfb7e9ac41a3 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -79,6 +79,11 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
char *str_get(struct gstr *gs);
/* menu.c */
+struct menu *menu_next(struct menu *menu, struct menu *root);
+#define menu_for_each_sub_entry(menu, root) \
+ for (menu = menu_next(root, root); menu; menu = menu_next(menu, root))
+#define menu_for_each_entry(menu) \
+ menu_for_each_sub_entry(menu, &rootmenu)
void _menu_init(void);
void menu_warn(struct menu *menu, const char *fmt, ...);
struct menu *menu_add_menu(void);
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 3b822cd110f4..fe6af8700622 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -17,6 +17,27 @@ static const char nohelp_text[] = "There is no help available for this option.";
struct menu rootmenu;
static struct menu **last_entry_ptr;
+/**
+ * menu_next - return the next menu entry with depth-first traversal
+ * @menu: pointer to the current menu
+ * @root: root of the sub-tree to traverse. If NULL is given, the traveral
+ * continues until it reaches the end of the entire menu tree.
+ * return: the menu to visit next, or NULL when it reaches the end.
+ */
+struct menu *menu_next(struct menu *menu, struct menu *root)
+{
+ if (menu->list)
+ return menu->list;
+
+ while (menu != root && !menu->next)
+ menu = menu->parent;
+
+ if (menu == root)
+ return NULL;
+
+ return menu->next;
+}
+
void menu_warn(struct menu *menu, const char *fmt, ...)
{
va_list ap;