@@ -22,6 +22,8 @@
#include "lkc.h"
#include "lxdialog/dialog.h"
+void debug_print_visibles(struct menu *menu);
+
static const char mconf_readme[] = N_(
"Overview\n"
"--------\n"
@@ -1025,6 +1027,9 @@ int main(int ac, char **av)
set_config_filename(conf_get_configname());
conf_set_message_callback(conf_message_callback);
+
+ debug_print_visibles(&rootmenu);
+
do {
conf(&rootmenu, NULL);
res = handle_exit();
@@ -430,6 +430,94 @@ bool menu_has_prompt(struct menu *menu)
return true;
}
+void debug_print_visibles(struct menu *menu);
+bool menu_is_visible_new(struct menu *menu);
+
+void debug_print_visibles(struct menu *menu)
+{
+ int diff;
+
+ for (; menu; menu = menu->next) {
+ if (menu->prompt) {
+ if ((diff = (menu_is_visible_new(menu) - menu_is_visible(menu))))
+ fprintf(stderr, "%s is now %s\n", menu->prompt->text,
+ diff > 0 ? "visible" : "invisible");
+ if (menu->list) {
+ debug_print_visibles(menu->list);
+ }
+ } else {
+ /*
+ * Check if there are menu entries without a
+ * prompt but with a list.
+ */
+ assert(!menu->list);
+ }
+ }
+}
+
+bool menu_is_visible_new(struct menu *menu)
+{
+ struct menu *child;
+ struct symbol *sym;
+ tristate visible;
+
+ /* If there is no prompt there nothing to visualize */
+ if (!menu->prompt)
+ return false;
+
+ /*
+ * If the menu entry has an associated visibility expression
+ * that evaluates to no, then it beats anything else.
+ */
+ if (menu->visibility) {
+ if (expr_calc_value(menu->visibility) == no)
+ return no;
+ }
+
+ /* Check the prompt's visibility. */
+ sym = menu->sym;
+ if (sym) {
+ sym_calc_value(sym);
+ visible = menu->prompt->visible.tri;
+ } else
+ visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
+
+ /*
+ * If we are not a menu or we are a menu but also a symbol and
+ * the calculated visibility is other than no, we're done.
+ */
+ if ((menu->prompt->type != P_MENU || sym) && visible != no) return true;
+
+ /*
+ * Now, we are probably a visible menue (and no symbol) but
+ * still have to find out if there is anything visible beneath
+ * us. If not, we want to be invisible.
+ *
+ * Or, we are an invisible symbol and want to be visible if
+ * there is something visible beneath us.
+ */
+
+ /*
+ * If we are an invisible symbol, we're done.
+ */
+ if (sym && sym_get_tristate_value(menu->sym) == no)
+ return false;
+
+ /*
+ * If we find a visible child, we also want to be visible.
+ * Otherwise we are invisible.
+ */
+ for (child = menu->list; child; child = child->next) {
+ if (menu_is_visible(child)) {
+ if (sym)
+ sym->flags |= SYMBOL_DEF_USER;
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool menu_is_visible(struct menu *menu)
{
struct menu *child;
Empty submenus are at least annoying but could also cause irritation. In general they can be suppressed by the kconfig-language but there might be cases when this becomes challenging. mconf has a function menu_is_visible() that was almost able to identify empty submenus. This function has been modified. Signed-off-by: Dirk Gouders <dirk@gouders.net> --- scripts/kconfig/mconf.c | 5 +++ scripts/kconfig/menu.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+)