2024-03-10 14:16:32

by Masahiro Yamada

[permalink] [raw]
Subject: [PATCH 1/3] kconfig: remove unneeded menu_is_visible() call in conf_write_defconfig()

When the condition 'sym == NULL' is met, the code will reach the
'next_menu' label regardless of the return value from menu_is_visible().

menu_is_visible() calculates some symbol values as a side-effect, for
instance by calling expr_calc_value(menu->visibility), but all the
symbol values will be calculated eventually.

Signed-off-by: Masahiro Yamada <[email protected]>
---

scripts/kconfig/confdata.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index c5b6487d68ac..0e35c4819cf1 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -799,10 +799,7 @@ int conf_write_defconfig(const char *filename)
while (menu != NULL)
{
sym = menu->sym;
- if (sym == NULL) {
- if (!menu_is_visible(menu))
- goto next_menu;
- } else if (!sym_is_choice(sym)) {
+ if (sym && !sym_is_choice(sym)) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE))
goto next_menu;
--
2.40.1



2024-03-10 14:16:41

by Masahiro Yamada

[permalink] [raw]
Subject: [PATCH 2/3] 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 <[email protected]>
---

scripts/kconfig/lkc.h | 5 +++++
scripts/kconfig/menu.c | 15 +++++++++++++++
2 files changed, 20 insertions(+)

diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index e69d7c59d930..5241dccd559e 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);
+#define menu_for_each_sub_entry(menu, root) \
+ for (struct menu *menu = (root)->list; menu != (root)->next && menu != (root)->parent; menu = menu_next(menu))
+#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 8498481e6afe..417dc01ac412 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -17,6 +17,21 @@ 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: the pointer to the current menu
+ */
+struct menu *menu_next(struct menu *menu)
+{
+ if (menu->list)
+ return menu->list;
+
+ while (!menu->next && menu->parent)
+ menu = menu->parent;
+
+ return menu->next;
+}
+
void menu_warn(struct menu *menu, const char *fmt, ...)
{
va_list ap;
--
2.40.1


2024-03-10 14:16:52

by Masahiro Yamada

[permalink] [raw]
Subject: [PATCH 3/3] kconfig: use menu_for_each_entry() to traverse menu tree

Use menu_for_each_entry() to traverse the menu tree instead of
implementing similar logic in each function.

Signed-off-by: Masahiro Yamada <[email protected]>
---

scripts/kconfig/confdata.c | 29 +++++------------------------
scripts/kconfig/parser.y | 15 +--------------
2 files changed, 6 insertions(+), 38 deletions(-)

diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 0e35c4819cf1..16066730a6a0 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -784,7 +784,6 @@ static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
int conf_write_defconfig(const char *filename)
{
struct symbol *sym;
- struct menu *menu;
FILE *out;

out = fopen(filename, "w");
@@ -793,23 +792,19 @@ int conf_write_defconfig(const char *filename)

sym_clear_all_valid();

- /* Traverse all menus to find all relevant symbols */
- menu = rootmenu.list;
-
- while (menu != NULL)
- {
+ menu_for_each_entry(menu) {
sym = menu->sym;
if (sym && !sym_is_choice(sym)) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE))
- goto next_menu;
+ continue;
sym->flags &= ~SYMBOL_WRITE;
/* If we cannot change the symbol - skip */
if (!sym_is_changeable(sym))
- goto next_menu;
+ continue;
/* If symbol equals to default value - skip */
if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
- goto next_menu;
+ continue;

/*
* If symbol is a choice value and equals to the
@@ -827,25 +822,11 @@ int conf_write_defconfig(const char *filename)
if (!sym_is_optional(cs) && sym == ds) {
if ((sym->type == S_BOOLEAN) &&
sym_get_tristate_value(sym) == yes)
- goto next_menu;
+ continue;
}
}
print_symbol_for_dotconfig(out, sym);
}
-next_menu:
- if (menu->list != NULL) {
- menu = menu->list;
- }
- else if (menu->next != NULL) {
- menu = menu->next;
- } else {
- while ((menu = menu->parent)) {
- if (menu->next != NULL) {
- menu = menu->next;
- break;
- }
- }
- }
}
fclose(out);
return 0;
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index b45bfaf0a02b..a69a453e4f44 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -473,8 +473,6 @@ assign_val:

void conf_parse(const char *name)
{
- struct menu *menu;
-
autoconf_cmd = str_new();

str_printf(&autoconf_cmd, "\ndeps_config := \\\n");
@@ -517,20 +515,9 @@ void conf_parse(const char *name)

menu_finalize(&rootmenu);

- menu = &rootmenu;
- while (menu) {
+ menu_for_each_entry(menu) {
if (menu->sym && sym_check_deps(menu->sym))
yynerrs++;
-
- if (menu->list) {
- menu = menu->list;
- continue;
- }
-
- while (!menu->next && menu->parent)
- menu = menu->parent;
-
- menu = menu->next;
}

if (yynerrs)
--
2.40.1