From 105c835e70a5bb80a256b3d10d1d03dee7bb23db Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Wed, 11 Apr 2018 20:35:40 +0200 Subject: Add helper for splitting expressions I've had to implement the logic for walking reverse dependencies (from select) a couple of times now, and it's always a bit tricky to get right. Reduce code duplication and simplify things by adding a helper function split_expr() that splits an expression into a list of either its AND or OR operands. A nice side effect is that e.g. the warning generated for selecting a symbol with unsatisfied direct dependencies now lists the selecting symbols in the order that they appear in the Kconfig files. split_expr() might be helpful for splitting other types of expressions as well, e.g. to put operands on separate lines when generating documentation. --- testsuite.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'testsuite.py') diff --git a/testsuite.py b/testsuite.py index 0cbe5d0..9a2f1fc 100644 --- a/testsuite.py +++ b/testsuite.py @@ -44,7 +44,10 @@ from kconfiglib import Kconfig, Symbol, Choice, COMMENT, MENU, \ BOOL, TRISTATE, HEX, STRING, \ TRI_TO_STR, \ - KconfigSyntaxError, expr_value, escape, unescape + escape, unescape, \ + expr_str, expr_value, split_expr, \ + OR, AND, \ + KconfigSyntaxError import difflib import errno import os @@ -849,6 +852,45 @@ g fail("recursive 'source' did not raise exception") + print("Testing split_expr()") + + def verify_split(to_split, op, operand_strs): + # The same hackage as in Kconfig.eval_string() + c._line = "if " + to_split + c._tokenize() + del c._tokens[0] + operands = split_expr(c._parse_expr(False), op) + + verify(len(operands) == len(operand_strs), + "Wrong number of operands when {} was split by {}" + .format(to_split, "OR" if op == OR else "AND")) + + for operand, operand_str in zip(operands, operand_strs): + verify_equal(expr_str(operand), operand_str) + + verify_split("A", OR, ("A", )) + verify_split("!A", OR, ("!A", )) + verify_split("A = B", OR, ("A = B", )) + verify_split("A && B", OR, ("A && B", )) + verify_split("A || B", OR, ("A", "B" )) + verify_split("(A || B) || C", OR, ("A", "B", "C" )) + verify_split("A || (B || C)", OR, ("A", "B", "C" )) + verify_split("A || !(B || C)", OR, ("A", "!(B || C)" )) + verify_split("A || (B && (C || D))", OR, ("A", "B && (C || D)")) + verify_split("(A && (B || C)) || D", OR, ("A && (B || C)", "D")) + + verify_split("A", AND, ("A", )) + verify_split("!A", AND, ("!A", )) + verify_split("A = B", AND, ("A = B", )) + verify_split("A || B", AND, ("A || B", )) + verify_split("A && B", AND, ("A", "B" )) + verify_split("(A && B) && C", AND, ("A", "B", "C" )) + verify_split("A && (B && C)", AND, ("A", "B", "C" )) + verify_split("A && !(B && C)", AND, ("A", "!(B && C)" )) + verify_split("A && (B || (C && D))", AND, ("A", "B || (C && D)")) + verify_split("(A || (B && C)) && D", AND, ("A || (B && C)", "D")) + + print("Testing visibility") c = Kconfig("Kconfiglib/tests/Kvisibility") -- cgit v1.2.3