diff --git a/kconfiglib.py b/kconfiglib.py index 6ebd36c..1e75183 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -3148,6 +3148,22 @@ def _parse_cond(self): return expr + def _parse_depends(self): + # Parses 'depends on' with optional conditional: 'depends on A if B' + # Converts 'A if B' to '!B || A' (if B is false, dependency is satisfied; + # if B is true, dependency becomes A) + + expr = self._parse_expr(True) + + if self._check_token(_T_IF): + # Transform "A if B" into "!B || A" + expr = self._make_or((NOT, self._parse_expr(True)), expr) + + if self._tokens[self._tokens_i] is not None: + self._trailing_tokens_error() + + return expr + def _parse_props(self, node): # Parses and adds properties to the MenuNode 'node' (type, 'prompt', # 'default's, etc.) Properties are later copied up to symbols and @@ -3183,7 +3199,7 @@ def _parse_props(self, node): self._parse_error("expected 'on' after 'depends'") node.dep = self._make_and(node.dep, - self._expect_expr_and_eol()) + self._parse_depends()) elif t0 is _T_HELP: self._parse_help(node) diff --git a/tests/Kconddep b/tests/Kconddep new file mode 100644 index 0000000..dd18d7a --- /dev/null +++ b/tests/Kconddep @@ -0,0 +1,28 @@ +# Test conditional dependencies: "depends on A if B" +# Should be equivalent to "depends on !B || A" + +config COND_DEP_1 + bool + depends on A if B + +config COND_DEP_2 + bool + depends on (C && D) if E + +config COND_DEP_MIXED + bool + depends on A + depends on B if C + depends on D + +# Test with choice +choice COND_CHOICE + bool "conditional choice" + depends on X if Y +endchoice + +# Test multiple conditional dependencies combined +config MULTI_COND + bool + depends on A if B + depends on C if D diff --git a/testsuite.py b/testsuite.py index d4eed15..03cb294 100644 --- a/testsuite.py +++ b/testsuite.py @@ -1324,6 +1324,30 @@ def verify_prompts(items, *expected_prompts): "A || B || C") + print("Testing conditional dependencies (depends on A if B)") + + c = Kconfig("Kconfiglib/tests/Kconddep") + + # "depends on A if B" should become "!B || A" + verify_equal(expr_str(c.syms["COND_DEP_1"].direct_dep), "!B || A") + + # "depends on (C && D) if E" should become "!E || (C && D)" + verify_equal(expr_str(c.syms["COND_DEP_2"].direct_dep), "!E || (C && D)") + + # Multiple depends combined: "depends on A", "depends on B if C", "depends on D" + # Should become: "A && (!C || B) && D" + verify_equal(expr_str(c.syms["COND_DEP_MIXED"].direct_dep), + "A && (!C || B) && D") + + # Test with choice + verify_equal(expr_str(c.named_choices["COND_CHOICE"].direct_dep), "!Y || X") + + # Multiple conditional dependencies: "depends on A if B" and "depends on C if D" + # Should become: "(!B || A) && (!D || C)" + verify_equal(expr_str(c.syms["MULTI_COND"].direct_dep), + "(!B || A) && (!D || C)") + + print("Testing expr_items()") c = Kconfig("Kconfiglib/tests/Kexpr_items")