Skip to content

Commit 7733b94

Browse files
galaknashif
authored andcommitted
sanitycheck: Add functions to query device tree for filters
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>
1 parent 1acea13 commit 7733b94

File tree

2 files changed

+51
-13
lines changed

2 files changed

+51
-13
lines changed

scripts/sanity_chk/expr_parser.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,20 @@ def p_expr_single(p):
134134
"""expr : SYMBOL"""
135135
p[0] = ("exists", p[1])
136136

137+
def p_func(p):
138+
"""expr : SYMBOL OPAREN arg_intr CPAREN"""
139+
p[0] = [p[1]]
140+
p[0].append(p[3])
141+
142+
def p_arg_intr_single(p):
143+
"""arg_intr : const"""
144+
p[0] = [p[1]]
145+
146+
def p_arg_intr_mult(p):
147+
"""arg_intr : arg_intr COMMA const"""
148+
p[0] = copy.copy(p[1])
149+
p[0].append(p[3])
150+
137151
def p_list(p):
138152
"""list : OBRACKET list_intr CBRACKET"""
139153
p[0] = p[2]
@@ -182,13 +196,13 @@ def ast_sym_int(ast, env):
182196
return int(v, 10)
183197
return 0
184198

185-
def ast_expr(ast, env):
199+
def ast_expr(ast, env, edt):
186200
if ast[0] == "not":
187-
return not ast_expr(ast[1], env)
201+
return not ast_expr(ast[1], env, edt)
188202
elif ast[0] == "or":
189-
return ast_expr(ast[1], env) or ast_expr(ast[2], env)
203+
return ast_expr(ast[1], env, edt) or ast_expr(ast[2], env, edt)
190204
elif ast[0] == "and":
191-
return ast_expr(ast[1], env) and ast_expr(ast[2], env)
205+
return ast_expr(ast[1], env, edt) and ast_expr(ast[2], env, edt)
192206
elif ast[0] == "==":
193207
return ast_sym(ast[1], env) == ast[2]
194208
elif ast[0] == "!=":
@@ -207,10 +221,29 @@ def ast_expr(ast, env):
207221
return bool(ast_sym(ast[1], env))
208222
elif ast[0] == ":":
209223
return bool(re.match(ast[2], ast_sym(ast[1], env)))
224+
elif ast[0] == "dt_compat_enabled":
225+
compat = ast[1][0]
226+
for node in edt.nodes:
227+
if compat in node.compats and node.enabled:
228+
return True
229+
return False
230+
elif ast[0] == "dt_alias_exists":
231+
alias = ast[1][0]
232+
for node in edt.nodes:
233+
if alias in node.aliases and node.enabled:
234+
return True
235+
return False
236+
elif ast[0] == "dt_compat_enabled_with_alias":
237+
compat = ast[1][0]
238+
alias = ast[1][1]
239+
for node in edt.nodes:
240+
if node.enabled and alias in node.aliases and node.matching_compat == compat:
241+
return True
242+
return False
210243

211244
mutex = threading.Lock()
212245

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

225-
return ast_expr(ast, env)
258+
return ast_expr(ast, env, edt)
226259

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

247-
print(parse(line, local_env))
280+
print(parse(line, local_env, None))

scripts/sanitycheck

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ from itertools import islice
199199
from pathlib import Path
200200
from distutils.spawn import find_executable
201201

202+
ZEPHYR_BASE = os.getenv("ZEPHYR_BASE")
203+
if not ZEPHYR_BASE:
204+
sys.exit("$ZEPHYR_BASE environment variable undefined")
205+
206+
sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts", "dts"))
207+
import edtlib
208+
202209
import logging
203210

204211

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

212-
ZEPHYR_BASE = os.environ.get("ZEPHYR_BASE")
213-
if not ZEPHYR_BASE:
214-
sys.stderr.write("$ZEPHYR_BASE environment variable undefined.\n")
215-
exit(1)
216-
217219
# Use this for internal comparisons; that's what canonicalization is
218220
# for. Don't use it when invoking other components of the build system
219221
# to avoid confusing and hard to trace inconsistencies in error messages
@@ -1902,7 +1904,10 @@ class FilterBuilder(CMake):
19021904

19031905
if self.testcase and self.testcase.tc_filter:
19041906
try:
1905-
res = expr_parser.parse(self.testcase.tc_filter, filter_data)
1907+
dts_path = os.path.join(self.build_dir, "zephyr", self.platform.name + ".dts.pre.tmp")
1908+
edt = edtlib.EDT(dts_path, [os.path.join(ZEPHYR_BASE, "dts", "bindings")])
1909+
res = expr_parser.parse(self.testcase.tc_filter, filter_data, edt)
1910+
19061911
except (ValueError, SyntaxError) as se:
19071912
sys.stderr.write(
19081913
"Failed processing %s\n" % self.testcase.yamlfile)

0 commit comments

Comments
 (0)