Skip to content

Commit 4f530c2

Browse files
committed
Show select/imply origin in menu display
This adds visibility of symbol dependency origins to help users realize why configuration values are being forced. When a symbol is controlled by select or imply statements, the main menu now displays which symbols are doing the controlling: -*- Crypto Library [selected by FEATURE_A, FEATURE_B] The symbol information window also shows the origin: Value: y (selected by: FEATURE_A, FEATURE_B) This eliminates the need to manually search through Kconfig files to understand dependency relationships.
1 parent 9b76d55 commit 4f530c2

File tree

1 file changed

+85
-1
lines changed

1 file changed

+85
-1
lines changed

menuconfig.py

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3453,10 +3453,27 @@ def _value_info(sym):
34533453
# Returns a string showing 'sym's value
34543454

34553455
# Only put quotes around the value for string symbols
3456-
return "Value: {}\n".format(
3456+
s = "Value: {}\n".format(
34573457
'"{}"'.format(sym.str_value) if sym.orig_type == STRING else sym.str_value
34583458
)
34593459

3460+
# Add origin information to explain where the value comes from
3461+
origin = sym.origin
3462+
if origin:
3463+
kind, sources = origin
3464+
if kind == "select":
3465+
if sources:
3466+
s += " (selected by: {})\n".format(", ".join(sources))
3467+
elif kind == "imply":
3468+
if sources:
3469+
s += " (implied by: {})\n".format(", ".join(sources))
3470+
elif kind == "default":
3471+
s += " (from default)\n"
3472+
elif kind == "assign":
3473+
s += " (user assigned)\n"
3474+
3475+
return s
3476+
34603477

34613478
def _choice_syms_info(choice):
34623479
# Returns a string listing the choice symbols in 'choice'. Adds
@@ -3818,6 +3835,68 @@ def _error(text):
38183835
_msg("Error", text)
38193836

38203837

3838+
def _get_force_info(sym):
3839+
# Returns a string indicating what's forcing a symbol's value, or None
3840+
# if the value is not being forced by select/imply.
3841+
#
3842+
# Example return values:
3843+
# " [selected by FOO]"
3844+
# " [implied by BAR, BAZ]"
3845+
3846+
if sym.orig_type not in (BOOL, TRISTATE):
3847+
return None
3848+
3849+
origin = sym.origin
3850+
if not origin:
3851+
return None
3852+
3853+
kind, sources = origin
3854+
if kind not in ("select", "imply") or not sources:
3855+
return None
3856+
3857+
# Format the force info string
3858+
prefix = "selected by" if kind == "select" else "implied by"
3859+
sym_names = _extract_controlling_symbols(sources)
3860+
3861+
if not sym_names:
3862+
return None
3863+
3864+
# Show up to 2 symbols to keep line length reasonable
3865+
if len(sym_names) <= 2:
3866+
return " [{} {}]".format(prefix, ", ".join(sym_names))
3867+
3868+
return " [{} {}, +{}]".format(prefix, ", ".join(sym_names[:2]), len(sym_names) - 2)
3869+
3870+
3871+
def _extract_controlling_symbols(expr_list):
3872+
# Extracts the primary controlling symbol from each expression string
3873+
# Returns a list of unique symbol names
3874+
#
3875+
# For "A && B", extracts "A" (the symbol doing the select/imply)
3876+
# For "A || B", extracts both "A" and "B"
3877+
# For simple "A", extracts "A"
3878+
#
3879+
# This avoids showing condition symbols as if they're doing the select/imply
3880+
3881+
sym_names = []
3882+
for expr in expr_list:
3883+
# Split on && first - we only want symbols before &&
3884+
# For "FOO && BAR", we want FOO (the selector), not BAR (the condition)
3885+
and_idx = expr.find(" && ")
3886+
primary = expr[:and_idx].strip() if and_idx != -1 else expr.strip()
3887+
3888+
# Now handle || - all parts are equal
3889+
if " || " in primary:
3890+
for part in primary.split(" || "):
3891+
part = part.strip()
3892+
if part and part not in sym_names:
3893+
sym_names.append(part)
3894+
elif primary and primary not in sym_names:
3895+
sym_names.append(primary)
3896+
3897+
return sym_names
3898+
3899+
38213900
def _node_str(node):
38223901
# Returns the complete menu entry text for a menu node.
38233902
#
@@ -3863,6 +3942,11 @@ def _node_str(node):
38633942

38643943
s += " (NEW)"
38653944

3945+
# Show what's controlling this symbol if it's selected/implied
3946+
force_info = _get_force_info(sym)
3947+
if force_info:
3948+
s += force_info
3949+
38663950
if isinstance(node.item, Choice) and node.item.tri_value == 2:
38673951
# Print the prompt of the selected symbol after the choice for
38683952
# choices in y mode

0 commit comments

Comments
 (0)