dtlib: add lineno/filename to string representation of a DT

Output lineno/filename as comments in the string representation of a DT
to help with debugging DT issues. Also, remove the added comments when
comparing the string representation of a DT to a reference string in the
DT testsuite.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
This commit is contained in:
Benjamin Cabé 2024-10-21 18:29:14 +02:00 committed by Benjamin Cabé
commit afdb62d1e2
2 changed files with 40 additions and 5 deletions

View file

@ -202,13 +202,37 @@ class Node:
Returns a DTS representation of the node. Called automatically if the Returns a DTS representation of the node. Called automatically if the
node is print()ed. node is print()ed.
""" """
s = "".join(label + ": " for label in self.labels) def safe_relpath(filename):
# Returns a relative path to the file, or the absolute path if
# a relative path cannot be established (on Windows with files
# in different drives, for example).
try:
return os.path.relpath(filename, start=os.getcwd())
except ValueError:
return filename
rel_filename = safe_relpath(self.filename)
s = f"\n/* node '{self.path}' defined in {rel_filename}:{self.lineno} */\n"
s += "".join(label + ": " for label in self.labels)
s += f"{self.name} {{\n" s += f"{self.name} {{\n"
lines = []
comments = {}
for prop in self.props.values(): for prop in self.props.values():
prop_str = textwrap.indent(str(prop), "\t") prop_str = textwrap.indent(str(prop), "\t")
s += prop_str + "\n" lines.extend(prop_str.splitlines(True))
rel_filename = safe_relpath(prop.filename)
comment = f"/* in {rel_filename}:{prop.lineno} */"
comments[len(lines)-1] = comment
if lines:
max_len = max([ len(line.rstrip()) for line in lines ])
for i, line in enumerate(lines):
if i in comments:
line += " " * (max_len - len(line) + 1) + comments[i] + "\n"
s += line
for child in self.nodes.values(): for child in self.nodes.values():
s += textwrap.indent(child.__str__(), "\t") + "\n" s += textwrap.indent(child.__str__(), "\t") + "\n"

View file

@ -26,6 +26,17 @@ from devicetree import dtlib
# - to run a particular test function or functions, use # - to run a particular test function or functions, use
# '-k test_function_pattern_goes_here' # '-k test_function_pattern_goes_here'
def uncomment(dts):
'''Trim added comments from a DT string.'''
# remove node comments, including leading empty line
dts = re.sub(r'\n\n[ \t]*/\*.*?\*/\n', '\n', dts, flags=re.DOTALL)
# remove property comments
dts = re.sub(r'[ \t]*/\*.*?\*/\n', '\n', dts)
return dts
def parse(dts, include_path=(), **kwargs): def parse(dts, include_path=(), **kwargs):
'''Parse a DTS string 'dts', using the given include path. '''Parse a DTS string 'dts', using the given include path.
@ -48,7 +59,7 @@ def verify_parse(dts, expected, include_path=()):
dt = parse(dts[1:], include_path) dt = parse(dts[1:], include_path)
actual = str(dt) actual = uncomment(str(dt))
expected = expected[1:-1] expected = expected[1:-1]
assert actual == expected, f'unexpected round-trip on {dts}' assert actual == expected, f'unexpected round-trip on {dts}'
@ -1029,7 +1040,7 @@ def test_include_curdir(tmp_path):
}; };
""") """)
dt = dtlib.DT("test.dts") dt = dtlib.DT("test.dts")
assert str(dt) == """ assert uncomment(str(dt)) == """
/dts-v1/; /dts-v1/;
/ { / {
@ -1086,7 +1097,7 @@ y /include/ "via-include-path-1"
y = < 0x2 >; y = < 0x2 >;
}; };
"""[1:-1] """[1:-1]
assert str(dt) == expected_dt assert uncomment(str(dt)) == expected_dt
def test_include_misc(tmp_path): def test_include_misc(tmp_path):
'''Miscellaneous /include/ tests.''' '''Miscellaneous /include/ tests.'''