mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-04 09:56:10 +00:00
The legacy macros were first deprecated in Zephyr v2.3. Now that Zephyr v2.4 has been released, that makes two releases where these macros have been deprecated, so it's OK to remove them. This leaves support for legacy binding syntax in place. Removing that is left to future work. We need to update various pieces of documentation related to flash partitions that never got updated when the new API was introduced. Consolidate this information in the flash_map.h API reference page, since that's really where users will run into it. This also gives us the opportunity to improve this documentation. Adjust a couple of kconfigfunctions.py and sanitycheck bits to use non-legacy edtlib APIs. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
281 lines
6.0 KiB
Python
281 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (c) 2016 Intel Corporation.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
import sys
|
|
import os
|
|
import copy
|
|
import threading
|
|
import re
|
|
|
|
try:
|
|
import ply.lex as lex
|
|
import ply.yacc as yacc
|
|
except ImportError:
|
|
sys.exit("PLY library for Python 3 not installed.\n"
|
|
"Please install the ply package using your workstation's\n"
|
|
"package manager or the 'pip' tool.")
|
|
|
|
reserved = {
|
|
'and' : 'AND',
|
|
'or' : 'OR',
|
|
'not' : 'NOT',
|
|
'in' : 'IN',
|
|
}
|
|
|
|
tokens = [
|
|
"HEX",
|
|
"STR",
|
|
"INTEGER",
|
|
"EQUALS",
|
|
"NOTEQUALS",
|
|
"LT",
|
|
"GT",
|
|
"LTEQ",
|
|
"GTEQ",
|
|
"OPAREN",
|
|
"CPAREN",
|
|
"OBRACKET",
|
|
"CBRACKET",
|
|
"COMMA",
|
|
"SYMBOL",
|
|
"COLON",
|
|
] + list(reserved.values())
|
|
|
|
def t_HEX(t):
|
|
r"0x[0-9a-fA-F]+"
|
|
t.value = str(int(t.value, 16))
|
|
return t
|
|
|
|
def t_INTEGER(t):
|
|
r"\d+"
|
|
t.value = str(int(t.value))
|
|
return t
|
|
|
|
def t_STR(t):
|
|
r'\"([^\\\n]|(\\.))*?\"|\'([^\\\n]|(\\.))*?\''
|
|
# nip off the quotation marks
|
|
t.value = t.value[1:-1]
|
|
return t
|
|
|
|
t_EQUALS = r"=="
|
|
|
|
t_NOTEQUALS = r"!="
|
|
|
|
t_LT = r"<"
|
|
|
|
t_GT = r">"
|
|
|
|
t_LTEQ = r"<="
|
|
|
|
t_GTEQ = r">="
|
|
|
|
t_OPAREN = r"[(]"
|
|
|
|
t_CPAREN = r"[)]"
|
|
|
|
t_OBRACKET = r"\["
|
|
|
|
t_CBRACKET = r"\]"
|
|
|
|
t_COMMA = r","
|
|
|
|
t_COLON = ":"
|
|
|
|
def t_SYMBOL(t):
|
|
r"[A-Za-z_][0-9A-Za-z_]*"
|
|
t.type = reserved.get(t.value, "SYMBOL")
|
|
return t
|
|
|
|
t_ignore = " \t\n"
|
|
|
|
def t_error(t):
|
|
raise SyntaxError("Unexpected token '%s'" % t.value)
|
|
|
|
lex.lex()
|
|
|
|
precedence = (
|
|
('left', 'OR'),
|
|
('left', 'AND'),
|
|
('right', 'NOT'),
|
|
('nonassoc', 'EQUALS', 'NOTEQUALS', 'GT', 'LT', 'GTEQ', 'LTEQ', 'IN'),
|
|
)
|
|
|
|
def p_expr_or(p):
|
|
'expr : expr OR expr'
|
|
p[0] = ("or", p[1], p[3])
|
|
|
|
def p_expr_and(p):
|
|
'expr : expr AND expr'
|
|
p[0] = ("and", p[1], p[3])
|
|
|
|
def p_expr_not(p):
|
|
'expr : NOT expr'
|
|
p[0] = ("not", p[2])
|
|
|
|
def p_expr_parens(p):
|
|
'expr : OPAREN expr CPAREN'
|
|
p[0] = p[2]
|
|
|
|
def p_expr_eval(p):
|
|
"""expr : SYMBOL EQUALS const
|
|
| SYMBOL NOTEQUALS const
|
|
| SYMBOL GT number
|
|
| SYMBOL LT number
|
|
| SYMBOL GTEQ number
|
|
| SYMBOL LTEQ number
|
|
| SYMBOL IN list
|
|
| SYMBOL COLON STR"""
|
|
p[0] = (p[2], p[1], p[3])
|
|
|
|
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]
|
|
|
|
def p_list_intr_single(p):
|
|
"""list_intr : const"""
|
|
p[0] = [p[1]]
|
|
|
|
def p_list_intr_mult(p):
|
|
"""list_intr : list_intr COMMA const"""
|
|
p[0] = copy.copy(p[1])
|
|
p[0].append(p[3])
|
|
|
|
def p_const(p):
|
|
"""const : STR
|
|
| number"""
|
|
p[0] = p[1]
|
|
|
|
def p_number(p):
|
|
"""number : INTEGER
|
|
| HEX"""
|
|
p[0] = p[1]
|
|
|
|
def p_error(p):
|
|
if p:
|
|
raise SyntaxError("Unexpected token '%s'" % p.value)
|
|
else:
|
|
raise SyntaxError("Unexpected end of expression")
|
|
|
|
if "PARSETAB_DIR" not in os.environ:
|
|
parser = yacc.yacc(debug=0)
|
|
else:
|
|
parser = yacc.yacc(debug=0, outputdir=os.environ["PARSETAB_DIR"])
|
|
|
|
def ast_sym(ast, env):
|
|
if ast in env:
|
|
return str(env[ast])
|
|
return ""
|
|
|
|
def ast_sym_int(ast, env):
|
|
if ast in env:
|
|
v = env[ast]
|
|
if v.startswith("0x") or v.startswith("0X"):
|
|
return int(v, 16)
|
|
else:
|
|
return int(v, 10)
|
|
return 0
|
|
|
|
def ast_expr(ast, env, edt):
|
|
if ast[0] == "not":
|
|
return not ast_expr(ast[1], env, edt)
|
|
elif ast[0] == "or":
|
|
return ast_expr(ast[1], env, edt) or ast_expr(ast[2], env, edt)
|
|
elif ast[0] == "and":
|
|
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] == "!=":
|
|
return ast_sym(ast[1], env) != ast[2]
|
|
elif ast[0] == ">":
|
|
return ast_sym_int(ast[1], env) > int(ast[2])
|
|
elif ast[0] == "<":
|
|
return ast_sym_int(ast[1], env) < int(ast[2])
|
|
elif ast[0] == ">=":
|
|
return ast_sym_int(ast[1], env) >= int(ast[2])
|
|
elif ast[0] == "<=":
|
|
return ast_sym_int(ast[1], env) <= int(ast[2])
|
|
elif ast[0] == "in":
|
|
return ast_sym(ast[1], env) in ast[2]
|
|
elif ast[0] == "exists":
|
|
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.status == "okay":
|
|
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.status == "okay":
|
|
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.status == "okay" and alias in node.aliases and node.matching_compat == compat:
|
|
return True
|
|
return False
|
|
|
|
mutex = threading.Lock()
|
|
|
|
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"""
|
|
|
|
# Like it's C counterpart, state machine is not thread-safe
|
|
mutex.acquire()
|
|
try:
|
|
ast = parser.parse(expr_text)
|
|
finally:
|
|
mutex.release()
|
|
|
|
return ast_expr(ast, env, edt)
|
|
|
|
# Just some test code
|
|
if __name__ == "__main__":
|
|
|
|
local_env = {
|
|
"A" : "1",
|
|
"C" : "foo",
|
|
"D" : "20",
|
|
"E" : 0x100,
|
|
"F" : "baz"
|
|
}
|
|
|
|
|
|
for line in open(sys.argv[1]).readlines():
|
|
lex.input(line)
|
|
for tok in iter(lex.token, None):
|
|
print(tok.type, tok.value)
|
|
|
|
parser = yacc.yacc()
|
|
print(parser.parse(line))
|
|
|
|
print(parse(line, local_env, None))
|