carl9170: Update to latest upstream
[linux-libre-firmware.git] / carl9170fw / config / menu.c
index d9d16469859ab9e008686007b93a78acb23cf6e9..a5fbd6ccc006e05308f0ef24cf3cb1545a55cb15 100644 (file)
@@ -65,7 +65,8 @@ void menu_add_entry(struct symbol *sym)
 struct menu *menu_add_menu(void)
 {
        last_entry_ptr = &current_entry->list;
-       return current_menu = current_entry;
+       current_menu = current_entry;
+       return current_menu;
 }
 
 void menu_end_menu(void)
@@ -124,61 +125,76 @@ void menu_set_type(int type)
                sym_type_name(sym->type), sym_type_name(type));
 }
 
-static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
+static struct property *menu_add_prop(enum prop_type type, struct expr *expr,
+                                     struct expr *dep)
 {
-       struct property *prop = prop_alloc(type, current_entry->sym);
+       struct property *prop;
 
+       prop = xmalloc(sizeof(*prop));
+       memset(prop, 0, sizeof(*prop));
+       prop->type = type;
+       prop->file = current_file;
+       prop->lineno = zconf_lineno();
        prop->menu = current_entry;
        prop->expr = expr;
        prop->visible.expr = dep;
 
-       if (prompt) {
-               if (isspace(*prompt)) {
-                       prop_warn(prop, "leading whitespace ignored");
-                       while (isspace(*prompt))
-                               prompt++;
-               }
-               if (current_entry->prompt && current_entry != &rootmenu)
-                       prop_warn(prop, "prompt redefined");
+       /* append property to the prop list of symbol */
+       if (current_entry->sym) {
+               struct property **propp;
 
-               /* Apply all upper menus' visibilities to actual prompts. */
-               if(type == P_PROMPT) {
-                       struct menu *menu = current_entry;
+               for (propp = &current_entry->sym->prop;
+                    *propp;
+                    propp = &(*propp)->next)
+                       ;
+               *propp = prop;
+       }
 
-                       while ((menu = menu->parent) != NULL) {
-                               struct expr *dup_expr;
+       return prop;
+}
 
-                               if (!menu->visibility)
-                                       continue;
-                               /*
-                                * Do not add a reference to the
-                                * menu's visibility expression but
-                                * use a copy of it.  Otherwise the
-                                * expression reduction functions
-                                * will modify expressions that have
-                                * multiple references which can
-                                * cause unwanted side effects.
-                                */
-                               dup_expr = expr_copy(menu->visibility);
+struct property *menu_add_prompt(enum prop_type type, char *prompt,
+                                struct expr *dep)
+{
+       struct property *prop = menu_add_prop(type, NULL, dep);
 
-                               prop->visible.expr
-                                       = expr_alloc_and(prop->visible.expr,
-                                                        dup_expr);
-                       }
-               }
+       if (isspace(*prompt)) {
+               prop_warn(prop, "leading whitespace ignored");
+               while (isspace(*prompt))
+                       prompt++;
+       }
+       if (current_entry->prompt)
+               prop_warn(prop, "prompt redefined");
 
-               current_entry->prompt = prop;
+       /* Apply all upper menus' visibilities to actual prompts. */
+       if (type == P_PROMPT) {
+               struct menu *menu = current_entry;
+
+               while ((menu = menu->parent) != NULL) {
+                       struct expr *dup_expr;
+
+                       if (!menu->visibility)
+                               continue;
+                       /*
+                        * Do not add a reference to the menu's visibility
+                        * expression but use a copy of it. Otherwise the
+                        * expression reduction functions will modify
+                        * expressions that have multiple references which
+                        * can cause unwanted side effects.
+                        */
+                       dup_expr = expr_copy(menu->visibility);
+
+                       prop->visible.expr = expr_alloc_and(prop->visible.expr,
+                                                           dup_expr);
+               }
        }
+
+       current_entry->prompt = prop;
        prop->text = prompt;
 
        return prop;
 }
 
-struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
-{
-       return menu_add_prop(type, prompt, NULL, dep);
-}
-
 void menu_add_visibility(struct expr *expr)
 {
        current_entry->visibility = expr_alloc_and(current_entry->visibility,
@@ -187,12 +203,12 @@ void menu_add_visibility(struct expr *expr)
 
 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
 {
-       menu_add_prop(type, NULL, expr, dep);
+       menu_add_prop(type, expr, dep);
 }
 
 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
 {
-       menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
+       menu_add_prop(type, expr_alloc_symbol(sym), dep);
 }
 
 void menu_add_option_modules(void)
@@ -326,12 +342,10 @@ void menu_finalize(struct menu *parent)
                         * choice value symbols.
                         */
                        parentdep = expr_alloc_symbol(sym);
-               } else if (parent->prompt)
-                       /* Menu node for 'menu' */
-                       parentdep = parent->prompt->visible.expr;
-               else
-                       /* Menu node for 'if' */
+               } else {
+                       /* Menu node for 'menu', 'if' */
                        parentdep = parent->dep;
+               }
 
                /* For each child menu node... */
                for (menu = parent->list; menu; menu = menu->next) {
@@ -698,6 +712,21 @@ const char *menu_get_help(struct menu *menu)
                return "";
 }
 
+static void get_def_str(struct gstr *r, struct menu *menu)
+{
+       str_printf(r, "Defined at %s:%d\n",
+                  menu->file->name, menu->lineno);
+}
+
+static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix)
+{
+       if (!expr_is_yes(expr)) {
+               str_append(r, prefix);
+               expr_gstr_print(expr, r);
+               str_append(r, "\n");
+       }
+}
+
 static void get_prompt_str(struct gstr *r, struct property *prop,
                           struct list_head *head)
 {
@@ -705,7 +734,20 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
        struct menu *submenu[8], *menu, *location = NULL;
        struct jump_key *jump = NULL;
 
-       str_printf(r, "Prompt: %s\n", prop->text);
+       str_printf(r, "  Prompt: %s\n", prop->text);
+
+       get_dep_str(r, prop->menu->dep, "  Depends on: ");
+       /*
+        * Most prompts in Linux have visibility that exactly matches their
+        * dependencies. For these, we print only the dependencies to improve
+        * readability. However, prompts with inline "if" expressions and
+        * prompts with a parent that has a "visible if" expression have
+        * differing dependencies and visibility. In these rare cases, we
+        * print both.
+        */
+       if (!expr_eq(prop->menu->dep, prop->visible.expr))
+               get_dep_str(r, prop->visible.expr, "  Visible if: ");
+
        menu = prop->menu->parent;
        for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
                bool accessible = menu_is_visible(menu);
@@ -755,18 +797,6 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
        }
 }
 
-/*
- * get property of type P_SYMBOL
- */
-static struct property *get_symbol_prop(struct symbol *sym)
-{
-       struct property *prop = NULL;
-
-       for_all_properties(sym, prop, P_SYMBOL)
-               break;
-       return prop;
-}
-
 static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
                                 enum prop_type tok, const char *prefix)
 {
@@ -806,32 +836,34 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
                        }
                }
        }
-       for_all_prompts(sym, prop)
-               get_prompt_str(r, prop, head);
-
-       prop = get_symbol_prop(sym);
-       if (prop) {
-               str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
-                       prop->menu->lineno);
-               if (!expr_is_yes(prop->visible.expr)) {
-                       str_append(r, "  Depends on: ");
-                       expr_gstr_print(prop->visible.expr, r);
-                       str_append(r, "\n");
+
+       /* Print the definitions with prompts before the ones without */
+       for_all_properties(sym, prop, P_SYMBOL) {
+               if (prop->menu->prompt) {
+                       get_def_str(r, prop->menu);
+                       get_prompt_str(r, prop->menu->prompt, head);
+               }
+       }
+
+       for_all_properties(sym, prop, P_SYMBOL) {
+               if (!prop->menu->prompt) {
+                       get_def_str(r, prop->menu);
+                       get_dep_str(r, prop->menu->dep, "  Depends on: ");
                }
        }
 
-       get_symbol_props_str(r, sym, P_SELECT, "  Selects: ");
+       get_symbol_props_str(r, sym, P_SELECT, "Selects: ");
        if (sym->rev_dep.expr) {
-               expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "  Selected by [y]:\n");
-               expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "  Selected by [m]:\n");
-               expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "  Selected by [n]:\n");
+               expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, "Selected by [y]:\n");
+               expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, "Selected by [m]:\n");
+               expr_gstr_print_revdep(sym->rev_dep.expr, r, no, "Selected by [n]:\n");
        }
 
-       get_symbol_props_str(r, sym, P_IMPLY, "  Implies: ");
+       get_symbol_props_str(r, sym, P_IMPLY, "Implies: ");
        if (sym->implied.expr) {
-               expr_gstr_print_revdep(sym->implied.expr, r, yes, "  Implied by [y]:\n");
-               expr_gstr_print_revdep(sym->implied.expr, r, mod, "  Implied by [m]:\n");
-               expr_gstr_print_revdep(sym->implied.expr, r, no, "  Implied by [n]:\n");
+               expr_gstr_print_revdep(sym->implied.expr, r, yes, "Implied by [y]:\n");
+               expr_gstr_print_revdep(sym->implied.expr, r, mod, "Implied by [m]:\n");
+               expr_gstr_print_revdep(sym->implied.expr, r, no, "Implied by [n]:\n");
        }
 
        str_append(r, "\n\n");