diff options
| -rw-r--r-- | examples/find_symbol.py | 19 | ||||
| -rw-r--r-- | kconfiglib.py | 24 | ||||
| -rw-r--r-- | tests/Kexpr_items | 11 | ||||
| -rw-r--r-- | testsuite.py | 21 |
4 files changed, 61 insertions, 14 deletions
diff --git a/examples/find_symbol.py b/examples/find_symbol.py index 55e6345..adc4d73 100644 --- a/examples/find_symbol.py +++ b/examples/find_symbol.py @@ -59,7 +59,7 @@ # config OPROFILE # ... (tons more lines) -from kconfiglib import Kconfig, Symbol, Choice, MENU, COMMENT, NOT +from kconfiglib import Kconfig, Symbol, expr_items, Choice, MENU, COMMENT, NOT import sys def expr_contains_sym(expr, sym_name): @@ -70,18 +70,11 @@ def expr_contains_sym(expr, sym_name): Note that "foo" is represented as a constant symbol, like in the C implementation. """ - # Choice symbols have a Choice instance propagated to the conditions of - # their properties, so we need this test rather than - # isinstance(expr, Symbol) - if not isinstance(expr, tuple): - return expr.name == sym_name - - if expr[0] == NOT: - return expr_contains_sym(expr[1], sym_name) - - # AND, OR, or relation - return expr_contains_sym(expr[1], sym_name) or \ - expr_contains_sym(expr[2], sym_name) + for item in expr_items(expr): + if item.name == sym_name: + return True + + return False def sc_references_sym(sc, sym_name): """ diff --git a/kconfiglib.py b/kconfiglib.py index cee793e..82edcb6 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -4422,6 +4422,30 @@ def expr_str(expr): _REL_TO_STR[expr[0]], expr_str(expr[2])) +def expr_items(expr): + """ + Returns a set() of all items (symbols and choices) that appear in the + expression 'expr'. + """ + + deps = set() + + def rec(subexpr): + if not isinstance(subexpr, tuple): + # Symbol or choice + deps.add(subexpr) + + elif subexpr[0] == NOT: + rec(subexpr[1]) + + else: + # AND, OR, or relation + rec(subexpr[1]) + rec(subexpr[2]) + + rec(expr) + return deps + def split_expr(expr, op): """ Returns a list containing the top-level AND or OR operands in the diff --git a/tests/Kexpr_items b/tests/Kexpr_items new file mode 100644 index 0000000..fb97ace --- /dev/null +++ b/tests/Kexpr_items @@ -0,0 +1,11 @@ +config TEST + bool + default A && (B || !C && D = "E") || F > G || !!!H + +choice CHOICE + bool "choice" + +config TEST_CHOICE + bool "test choice" if A + +endchoice diff --git a/testsuite.py b/testsuite.py index d976c12..1f1bc32 100644 --- a/testsuite.py +++ b/testsuite.py @@ -45,7 +45,7 @@ from kconfiglib import Kconfig, Symbol, Choice, COMMENT, MENU, MenuNode, \ BOOL, TRISTATE, HEX, STRING, \ TRI_TO_STR, \ escape, unescape, \ - expr_str, expr_value, split_expr, \ + expr_str, expr_value, expr_items, split_expr, \ OR, AND, \ KconfigSyntaxError import difflib @@ -990,6 +990,25 @@ g "A || B || C") + print("Testing expr_items()") + + c = Kconfig("Kconfiglib/tests/Kexpr_items") + + def verify_expr_items(expr, *sym_names): + verify_equal(tuple(sorted(item.name for item in expr_items(expr))), + sym_names) + + verify_expr_items( + c.syms["TEST"].defaults[0][0], + "A", "B", "C", "D", "E", "F", "G", "H" + ) + + verify_expr_items( + c.syms["TEST_CHOICE"].nodes[0].prompt[1], + "A", "CHOICE" + ) + + print("Testing split_expr()") def verify_split(to_split, op, operand_strs): |
