Skip to content

Commit afdb62d

Browse files
committed
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é <[email protected]> Signed-off-by: Luca Burelli <[email protected]>
1 parent 6b325da commit afdb62d

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

scripts/dts/python-devicetree/src/devicetree/dtlib.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,37 @@ def __str__(self):
202202
Returns a DTS representation of the node. Called automatically if the
203203
node is print()ed.
204204
"""
205-
s = "".join(label + ": " for label in self.labels)
205+
def safe_relpath(filename):
206+
# Returns a relative path to the file, or the absolute path if
207+
# a relative path cannot be established (on Windows with files
208+
# in different drives, for example).
209+
try:
210+
return os.path.relpath(filename, start=os.getcwd())
211+
except ValueError:
212+
return filename
213+
214+
rel_filename = safe_relpath(self.filename)
215+
s = f"\n/* node '{self.path}' defined in {rel_filename}:{self.lineno} */\n"
216+
s += "".join(label + ": " for label in self.labels)
206217

207218
s += f"{self.name} {{\n"
208219

220+
lines = []
221+
comments = {}
209222
for prop in self.props.values():
210223
prop_str = textwrap.indent(str(prop), "\t")
211-
s += prop_str + "\n"
224+
lines.extend(prop_str.splitlines(True))
225+
226+
rel_filename = safe_relpath(prop.filename)
227+
comment = f"/* in {rel_filename}:{prop.lineno} */"
228+
comments[len(lines)-1] = comment
229+
230+
if lines:
231+
max_len = max([ len(line.rstrip()) for line in lines ])
232+
for i, line in enumerate(lines):
233+
if i in comments:
234+
line += " " * (max_len - len(line) + 1) + comments[i] + "\n"
235+
s += line
212236

213237
for child in self.nodes.values():
214238
s += textwrap.indent(child.__str__(), "\t") + "\n"

scripts/dts/python-devicetree/tests/test_dtlib.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@
2626
# - to run a particular test function or functions, use
2727
# '-k test_function_pattern_goes_here'
2828

29+
def uncomment(dts):
30+
'''Trim added comments from a DT string.'''
31+
32+
# remove node comments, including leading empty line
33+
dts = re.sub(r'\n\n[ \t]*/\*.*?\*/\n', '\n', dts, flags=re.DOTALL)
34+
35+
# remove property comments
36+
dts = re.sub(r'[ \t]*/\*.*?\*/\n', '\n', dts)
37+
38+
return dts
39+
2940
def parse(dts, include_path=(), **kwargs):
3041
'''Parse a DTS string 'dts', using the given include path.
3142
@@ -48,7 +59,7 @@ def verify_parse(dts, expected, include_path=()):
4859

4960
dt = parse(dts[1:], include_path)
5061

51-
actual = str(dt)
62+
actual = uncomment(str(dt))
5263
expected = expected[1:-1]
5364
assert actual == expected, f'unexpected round-trip on {dts}'
5465

@@ -1029,7 +1040,7 @@ def test_include_curdir(tmp_path):
10291040
};
10301041
""")
10311042
dt = dtlib.DT("test.dts")
1032-
assert str(dt) == """
1043+
assert uncomment(str(dt)) == """
10331044
/dts-v1/;
10341045
10351046
/ {
@@ -1086,7 +1097,7 @@ def test_include_is_lexical(tmp_path):
10861097
y = < 0x2 >;
10871098
};
10881099
"""[1:-1]
1089-
assert str(dt) == expected_dt
1100+
assert uncomment(str(dt)) == expected_dt
10901101

10911102
def test_include_misc(tmp_path):
10921103
'''Miscellaneous /include/ tests.'''

0 commit comments

Comments
 (0)