Skip to content

Commit

Permalink
sanitycheck: Add functions to query device tree for filters
Browse files Browse the repository at this point in the history
Add the following functions to allow filtering based on device tree

dt_compat_enabled(compat) - Returns true if a device tree node
compatible matches 'compat' and the node is enabled.

dt_alias_exists(alias) - Returns true if a device tree node exists with
'alias' and the node is enabled.

dt_compat_enabled_with_alias - Returns true if a device tree node
compatible matches 'compat' and the node has 'alias' and the node is
enabled.

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
  • Loading branch information
galak authored and nashif committed Nov 4, 2019
1 parent 1acea13 commit 7733b94
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 13 deletions.
47 changes: 40 additions & 7 deletions scripts/sanity_chk/expr_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ def p_expr_single(p):
"""expr : SYMBOL"""
p[0] = ("exists", p[1])

def p_func(p):
"""expr : SYMBOL OPAREN arg_intr CPAREN"""
p[0] = [p[1]]
p[0].append(p[3])

def p_arg_intr_single(p):
"""arg_intr : const"""
p[0] = [p[1]]

def p_arg_intr_mult(p):
"""arg_intr : arg_intr COMMA const"""
p[0] = copy.copy(p[1])
p[0].append(p[3])

def p_list(p):
"""list : OBRACKET list_intr CBRACKET"""
p[0] = p[2]
Expand Down Expand Up @@ -182,13 +196,13 @@ def ast_sym_int(ast, env):
return int(v, 10)
return 0

def ast_expr(ast, env):
def ast_expr(ast, env, edt):
if ast[0] == "not":
return not ast_expr(ast[1], env)
return not ast_expr(ast[1], env, edt)
elif ast[0] == "or":
return ast_expr(ast[1], env) or ast_expr(ast[2], env)
return ast_expr(ast[1], env, edt) or ast_expr(ast[2], env, edt)
elif ast[0] == "and":
return ast_expr(ast[1], env) and ast_expr(ast[2], env)
return ast_expr(ast[1], env, edt) and ast_expr(ast[2], env, edt)
elif ast[0] == "==":
return ast_sym(ast[1], env) == ast[2]
elif ast[0] == "!=":
Expand All @@ -207,10 +221,29 @@ def ast_expr(ast, env):
return bool(ast_sym(ast[1], env))
elif ast[0] == ":":
return bool(re.match(ast[2], ast_sym(ast[1], env)))
elif ast[0] == "dt_compat_enabled":
compat = ast[1][0]
for node in edt.nodes:
if compat in node.compats and node.enabled:
return True
return False
elif ast[0] == "dt_alias_exists":
alias = ast[1][0]
for node in edt.nodes:
if alias in node.aliases and node.enabled:
return True
return False
elif ast[0] == "dt_compat_enabled_with_alias":
compat = ast[1][0]
alias = ast[1][1]
for node in edt.nodes:
if node.enabled and alias in node.aliases and node.matching_compat == compat:
return True
return False

mutex = threading.Lock()

def parse(expr_text, env):
def parse(expr_text, env, edt):
"""Given a text representation of an expression in our language,
use the provided environment to determine whether the expression
is true or false"""
Expand All @@ -222,7 +255,7 @@ def parse(expr_text, env):
finally:
mutex.release()

return ast_expr(ast, env)
return ast_expr(ast, env, edt)

# Just some test code
if __name__ == "__main__":
Expand All @@ -244,4 +277,4 @@ def parse(expr_text, env):
parser = yacc.yacc()
print(parser.parse(line))

print(parse(line, local_env))
print(parse(line, local_env, None))
17 changes: 11 additions & 6 deletions scripts/sanitycheck
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@ from itertools import islice
from pathlib import Path
from distutils.spawn import find_executable

ZEPHYR_BASE = os.getenv("ZEPHYR_BASE")
if not ZEPHYR_BASE:
sys.exit("$ZEPHYR_BASE environment variable undefined")

sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts", "dts"))
import edtlib

import logging


Expand All @@ -209,11 +216,6 @@ report_lock = threading.Lock()
log_format = "%(levelname)s %(name)s::%(module)s.%(funcName)s():%(lineno)d: %(message)s"
logging.basicConfig(format=log_format, level=30)

ZEPHYR_BASE = os.environ.get("ZEPHYR_BASE")
if not ZEPHYR_BASE:
sys.stderr.write("$ZEPHYR_BASE environment variable undefined.\n")
exit(1)

# Use this for internal comparisons; that's what canonicalization is
# for. Don't use it when invoking other components of the build system
# to avoid confusing and hard to trace inconsistencies in error messages
Expand Down Expand Up @@ -1902,7 +1904,10 @@ class FilterBuilder(CMake):

if self.testcase and self.testcase.tc_filter:
try:
res = expr_parser.parse(self.testcase.tc_filter, filter_data)
dts_path = os.path.join(self.build_dir, "zephyr", self.platform.name + ".dts.pre.tmp")
edt = edtlib.EDT(dts_path, [os.path.join(ZEPHYR_BASE, "dts", "bindings")])
res = expr_parser.parse(self.testcase.tc_filter, filter_data, edt)

except (ValueError, SyntaxError) as se:
sys.stderr.write(
"Failed processing %s\n" % self.testcase.yamlfile)
Expand Down

0 comments on commit 7733b94

Please sign in to comment.