hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/scripts/kconfig/menu.c
....@@ -1,6 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3
- * Released under the terms of the GNU GPL v2.0.
44 */
55
66 #include <ctype.h>
....@@ -65,7 +65,8 @@
6565 struct menu *menu_add_menu(void)
6666 {
6767 last_entry_ptr = &current_entry->list;
68
- return current_menu = current_entry;
68
+ current_menu = current_entry;
69
+ return current_menu;
6970 }
7071
7172 void menu_end_menu(void)
....@@ -124,59 +125,74 @@
124125 sym_type_name(sym->type), sym_type_name(type));
125126 }
126127
127
-static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
128
+static struct property *menu_add_prop(enum prop_type type, struct expr *expr,
129
+ struct expr *dep)
128130 {
129
- struct property *prop = prop_alloc(type, current_entry->sym);
131
+ struct property *prop;
130132
133
+ prop = xmalloc(sizeof(*prop));
134
+ memset(prop, 0, sizeof(*prop));
135
+ prop->type = type;
136
+ prop->file = current_file;
137
+ prop->lineno = zconf_lineno();
131138 prop->menu = current_entry;
132139 prop->expr = expr;
133140 prop->visible.expr = dep;
134141
135
- if (prompt) {
136
- if (isspace(*prompt)) {
137
- prop_warn(prop, "leading whitespace ignored");
138
- while (isspace(*prompt))
139
- prompt++;
140
- }
141
- if (current_entry->prompt && current_entry != &rootmenu)
142
- prop_warn(prop, "prompt redefined");
142
+ /* append property to the prop list of symbol */
143
+ if (current_entry->sym) {
144
+ struct property **propp;
143145
144
- /* Apply all upper menus' visibilities to actual prompts. */
145
- if(type == P_PROMPT) {
146
- struct menu *menu = current_entry;
147
-
148
- while ((menu = menu->parent) != NULL) {
149
- struct expr *dup_expr;
150
-
151
- if (!menu->visibility)
152
- continue;
153
- /*
154
- * Do not add a reference to the
155
- * menu's visibility expression but
156
- * use a copy of it. Otherwise the
157
- * expression reduction functions
158
- * will modify expressions that have
159
- * multiple references which can
160
- * cause unwanted side effects.
161
- */
162
- dup_expr = expr_copy(menu->visibility);
163
-
164
- prop->visible.expr
165
- = expr_alloc_and(prop->visible.expr,
166
- dup_expr);
167
- }
168
- }
169
-
170
- current_entry->prompt = prop;
146
+ for (propp = &current_entry->sym->prop;
147
+ *propp;
148
+ propp = &(*propp)->next)
149
+ ;
150
+ *propp = prop;
171151 }
172
- prop->text = prompt;
173152
174153 return prop;
175154 }
176155
177
-struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
156
+struct property *menu_add_prompt(enum prop_type type, char *prompt,
157
+ struct expr *dep)
178158 {
179
- return menu_add_prop(type, prompt, NULL, dep);
159
+ struct property *prop = menu_add_prop(type, NULL, dep);
160
+
161
+ if (isspace(*prompt)) {
162
+ prop_warn(prop, "leading whitespace ignored");
163
+ while (isspace(*prompt))
164
+ prompt++;
165
+ }
166
+ if (current_entry->prompt)
167
+ prop_warn(prop, "prompt redefined");
168
+
169
+ /* Apply all upper menus' visibilities to actual prompts. */
170
+ if (type == P_PROMPT) {
171
+ struct menu *menu = current_entry;
172
+
173
+ while ((menu = menu->parent) != NULL) {
174
+ struct expr *dup_expr;
175
+
176
+ if (!menu->visibility)
177
+ continue;
178
+ /*
179
+ * Do not add a reference to the menu's visibility
180
+ * expression but use a copy of it. Otherwise the
181
+ * expression reduction functions will modify
182
+ * expressions that have multiple references which
183
+ * can cause unwanted side effects.
184
+ */
185
+ dup_expr = expr_copy(menu->visibility);
186
+
187
+ prop->visible.expr = expr_alloc_and(prop->visible.expr,
188
+ dup_expr);
189
+ }
190
+ }
191
+
192
+ current_entry->prompt = prop;
193
+ prop->text = prompt;
194
+
195
+ return prop;
180196 }
181197
182198 void menu_add_visibility(struct expr *expr)
....@@ -187,37 +203,34 @@
187203
188204 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
189205 {
190
- menu_add_prop(type, NULL, expr, dep);
206
+ menu_add_prop(type, expr, dep);
191207 }
192208
193209 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
194210 {
195
- menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
211
+ menu_add_prop(type, expr_alloc_symbol(sym), dep);
196212 }
197213
198
-void menu_add_option(int token, char *arg)
214
+void menu_add_option_modules(void)
199215 {
200
- switch (token) {
201
- case T_OPT_MODULES:
202
- if (modules_sym)
203
- zconf_error("symbol '%s' redefines option 'modules'"
204
- " already defined by symbol '%s'",
205
- current_entry->sym->name,
206
- modules_sym->name
207
- );
208
- modules_sym = current_entry->sym;
209
- break;
210
- case T_OPT_DEFCONFIG_LIST:
211
- if (!sym_defconfig_list)
212
- sym_defconfig_list = current_entry->sym;
213
- else if (sym_defconfig_list != current_entry->sym)
214
- zconf_error("trying to redefine defconfig symbol");
215
- sym_defconfig_list->flags |= SYMBOL_NO_WRITE;
216
- break;
217
- case T_OPT_ALLNOCONFIG_Y:
218
- current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
219
- break;
220
- }
216
+ if (modules_sym)
217
+ zconf_error("symbol '%s' redefines option 'modules' already defined by symbol '%s'",
218
+ current_entry->sym->name, modules_sym->name);
219
+ modules_sym = current_entry->sym;
220
+}
221
+
222
+void menu_add_option_defconfig_list(void)
223
+{
224
+ if (!sym_defconfig_list)
225
+ sym_defconfig_list = current_entry->sym;
226
+ else if (sym_defconfig_list != current_entry->sym)
227
+ zconf_error("trying to redefine defconfig symbol");
228
+ sym_defconfig_list->flags |= SYMBOL_NO_WRITE;
229
+}
230
+
231
+void menu_add_option_allnoconfig_y(void)
232
+{
233
+ current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
221234 }
222235
223236 static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
....@@ -329,12 +342,10 @@
329342 * choice value symbols.
330343 */
331344 parentdep = expr_alloc_symbol(sym);
332
- } else if (parent->prompt)
333
- /* Menu node for 'menu' */
334
- parentdep = parent->prompt->visible.expr;
335
- else
336
- /* Menu node for 'if' */
345
+ } else {
346
+ /* Menu node for 'menu', 'if' */
337347 parentdep = parent->dep;
348
+ }
338349
339350 /* For each child menu node... */
340351 for (menu = parent->list; menu; menu = menu->next) {
....@@ -701,6 +712,21 @@
701712 return "";
702713 }
703714
715
+static void get_def_str(struct gstr *r, struct menu *menu)
716
+{
717
+ str_printf(r, "Defined at %s:%d\n",
718
+ menu->file->name, menu->lineno);
719
+}
720
+
721
+static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix)
722
+{
723
+ if (!expr_is_yes(expr)) {
724
+ str_append(r, prefix);
725
+ expr_gstr_print(expr, r);
726
+ str_append(r, "\n");
727
+ }
728
+}
729
+
704730 static void get_prompt_str(struct gstr *r, struct property *prop,
705731 struct list_head *head)
706732 {
....@@ -708,7 +734,20 @@
708734 struct menu *submenu[8], *menu, *location = NULL;
709735 struct jump_key *jump = NULL;
710736
711
- str_printf(r, "Prompt: %s\n", prop->text);
737
+ str_printf(r, " Prompt: %s\n", prop->text);
738
+
739
+ get_dep_str(r, prop->menu->dep, " Depends on: ");
740
+ /*
741
+ * Most prompts in Linux have visibility that exactly matches their
742
+ * dependencies. For these, we print only the dependencies to improve
743
+ * readability. However, prompts with inline "if" expressions and
744
+ * prompts with a parent that has a "visible if" expression have
745
+ * differing dependencies and visibility. In these rare cases, we
746
+ * print both.
747
+ */
748
+ if (!expr_eq(prop->menu->dep, prop->visible.expr))
749
+ get_dep_str(r, prop->visible.expr, " Visible if: ");
750
+
712751 menu = prop->menu->parent;
713752 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
714753 bool accessible = menu_is_visible(menu);
....@@ -758,18 +797,6 @@
758797 }
759798 }
760799
761
-/*
762
- * get property of type P_SYMBOL
763
- */
764
-static struct property *get_symbol_prop(struct symbol *sym)
765
-{
766
- struct property *prop = NULL;
767
-
768
- for_all_properties(sym, prop, P_SYMBOL)
769
- break;
770
- return prop;
771
-}
772
-
773800 static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
774801 enum prop_type tok, const char *prefix)
775802 {
....@@ -809,32 +836,34 @@
809836 }
810837 }
811838 }
812
- for_all_prompts(sym, prop)
813
- get_prompt_str(r, prop, head);
814839
815
- prop = get_symbol_prop(sym);
816
- if (prop) {
817
- str_printf(r, " Defined at %s:%d\n", prop->menu->file->name,
818
- prop->menu->lineno);
819
- if (!expr_is_yes(prop->visible.expr)) {
820
- str_append(r, " Depends on: ");
821
- expr_gstr_print(prop->visible.expr, r);
822
- str_append(r, "\n");
840
+ /* Print the definitions with prompts before the ones without */
841
+ for_all_properties(sym, prop, P_SYMBOL) {
842
+ if (prop->menu->prompt) {
843
+ get_def_str(r, prop->menu);
844
+ get_prompt_str(r, prop->menu->prompt, head);
823845 }
824846 }
825847
826
- get_symbol_props_str(r, sym, P_SELECT, " Selects: ");
827
- if (sym->rev_dep.expr) {
828
- expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n");
829
- expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n");
830
- expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n");
848
+ for_all_properties(sym, prop, P_SYMBOL) {
849
+ if (!prop->menu->prompt) {
850
+ get_def_str(r, prop->menu);
851
+ get_dep_str(r, prop->menu->dep, " Depends on: ");
852
+ }
831853 }
832854
833
- get_symbol_props_str(r, sym, P_IMPLY, " Implies: ");
855
+ get_symbol_props_str(r, sym, P_SELECT, "Selects: ");
856
+ if (sym->rev_dep.expr) {
857
+ expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "Selected by [y]:\n");
858
+ expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "Selected by [m]:\n");
859
+ expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "Selected by [n]:\n");
860
+ }
861
+
862
+ get_symbol_props_str(r, sym, P_IMPLY, "Implies: ");
834863 if (sym->implied.expr) {
835
- expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n");
836
- expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n");
837
- expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n");
864
+ expr_gstr_print_revdep(sym->implied.expr, r, yes, "Implied by [y]:\n");
865
+ expr_gstr_print_revdep(sym->implied.expr, r, mod, "Implied by [m]:\n");
866
+ expr_gstr_print_revdep(sym->implied.expr, r, no, "Implied by [n]:\n");
838867 }
839868
840869 str_append(r, "\n\n");