From b3f0061c61da5c9dd604e580e6f220c4a7bd44fa Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Wed, 28 Nov 2018 14:48:25 +0100 Subject: menuconfig: Only list duplicated choice symbols once When a Kconfig file defined a named choice and was included multiple times, the choice symbols were listed multiple times in the menuconfig as well (due to commit 17d7c1e ("menuconfig: Show all symbols at each menu location for multi.def. choices")). That's probably not what you want. Tweak it so that each symbol is only shown once, with the prompt that was used for it at whatever choice definition location is entered. Also change how the choice selection is displayed before the choice is entered, so that the prompt used for the selected symbol at that particular location is used. Previously, the prompt at the first definition location for the symbol was always used. (Note that all of this is only about how things are displayed. It's not essential to functionality, in case you're writing your own menuconfig.) --- menuconfig.py | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'menuconfig.py') diff --git a/menuconfig.py b/menuconfig.py index 88c3429..ecaf53a 100755 --- a/menuconfig.py +++ b/menuconfig.py @@ -1421,9 +1421,23 @@ def _shown_nodes(menu): # # Note: Named choices are pretty broken in the C tools, and this is # super obscure, so you probably won't find much that relies on this. - return [node - for choice_node in menu.item.nodes - for node in rec(choice_node.list)] + + # Do some additional work to avoid listing choice symbols twice if the + # entire choice is copy-pasted in multiple locations. We give the + # prompts at the current location precedence, in case it's not a 100% + # copy-paste. + seen_syms = {node.item for node in rec(menu.list) + if isinstance(node.item, Symbol)} + res = [] + for choice_node in menu.item.nodes: + for node in rec(choice_node.list): + # 'node is menu' checks if we're dealing with the current + # location + if node.item not in seen_syms or choice_node is menu: + res.append(node) + if isinstance(node.item, Symbol): + seen_syms.add(node.item) + return res return rec(menu.list) @@ -2791,9 +2805,19 @@ def _node_str(node): # choices in y mode sym = node.item.selection if sym: - for node_ in sym.nodes: - if node_.prompt: - s += " ({})".format(node_.prompt[0]) + for sym_node in sym.nodes: + # Use the prompt used at this choice location, in case the + # choice symbol is defined in multiple locations + if sym_node.parent is node and sym_node.prompt: + s += " ({})".format(sym_node.prompt[0]) + break + else: + # If the symbol isn't defined at this choice location, then + # just use whatever prompt we can find for it + for sym_node in sym.nodes: + if sym_node.prompt: + s += " ({})".format(sym_node.prompt[0]) + break # Print "--->" next to nodes that have menus that can potentially be # entered. Print "----" if the menu is empty. We don't allow those to be -- cgit v1.2.3