blob: e763d9778a08bc49ac1a19e6855fd9733c1a1bb9 [file] [log] [blame]
Ulf Magnusson62d57412018-12-17 20:09:47 +01001#!/usr/bin/env python3
2
3# Copyright (c) 2019, Nordic Semiconductor
4# SPDX-License-Identifier: BSD-3-Clause
5
6import os
7import shutil
8import sys
9
10import dtlib
11
12# Test suite for dtlib.py. Can be run directly as an executable.
13#
14# This script expects to be run from the directory its in. This simplifies
15# things, as paths in the output can be assumed below.
16
17# TODO: Factor out common code from error tests
18
19
20def run():
21 """
22 Runs all dtlib tests. Immediately exits with status 1 and a message on
23 stderr on test suite failures.
24 """
25 # Note: All code is within this function, even though some triple-quoted
26 # strings are unindented to make things less awkward
27
28 def fail(msg):
29 sys.exit("test failed: {}".format(msg))
30
31 def parse(dts, include_path=()):
32 open(".tmp.dts", "w").write(dts)
33 return dtlib.DT(".tmp.dts", include_path)
34
35 def verify_parse(dts, expected, include_path=()):
36 # The [1:] is so that the first line can be put on a separate line
37 # after """
38 dt = parse(dts[1:], include_path)
39
40 actual = str(dt)
41 expected = expected[1:-1]
42 if actual != expected:
43 fail("expected '{}' to parse as '{}', parsed as '{}'"
44 .format(dts, expected, actual))
45
46 return dt
47
48 def verify_error(dts, msg):
49 prefix = "expected '{}' to generate the error '{}', generated" \
50 .format(dts, msg)
51 try:
52 parse(dts[1:])
53 fail(prefix + " no error")
54 except dtlib.DTError as e:
55 if str(e) != msg:
56 fail("{} the error '{}'".format(prefix, e))
57 except Exception as e:
58 fail("{} the non-DTError '{}'".format(prefix, e))
59
60 # These might already exist from failed earlier runs
61
62 try:
63 os.mkdir(".tmp")
64 except OSError:
65 pass
66
67 try:
68 os.mkdir(".tmp2")
69 except OSError:
70 pass
71
72 #
73 # Test cell parsing
74 #
75
76 verify_parse("""
77/dts-v1/;
78
79/ {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +020080 a;
81 b = < >;
82 c = [ ];
83 d = < 10 20 >;
84 e = < 0U 1L 2UL 3LL 4ULL >;
85 f = < 0x10 0x20 >;
86 g = < 010 020 >;
87 h = /bits/ 8 < 0x10 0x20 (-1) >;
88 i = /bits/ 16 < 0x10 0x20 (-1) >;
89 j = /bits/ 32 < 0x10 0x20 (-1) >;
90 k = /bits/ 64 < 0x10 0x20 (-1) >;
Ulf Magnussonc2d702b2019-08-13 08:23:19 +020091 l = < 'a' 'b' 'c' >;
Ulf Magnusson62d57412018-12-17 20:09:47 +010092};
93""",
94"""
95/dts-v1/;
96
97/ {
98 a;
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +020099 b;
100 c;
101 d = < 0xa 0x14 >;
102 e = < 0x0 0x1 0x2 0x3 0x4 >;
103 f = < 0x10 0x20 >;
104 g = < 0x8 0x10 >;
105 h = [ 10 20 FF ];
106 i = /bits/ 16 < 0x10 0x20 0xffff >;
107 j = < 0x10 0x20 0xffffffff >;
108 k = /bits/ 64 < 0x10 0x20 0xffffffffffffffff >;
Ulf Magnussonc2d702b2019-08-13 08:23:19 +0200109 l = < 0x61 0x62 0x63 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100110};
111""")
112
113 verify_error("""
114/dts-v1/;
115
116/ {
117 a = /bits/ 16 < 0x10000 >;
118};
119""",
120".tmp.dts:4 (column 18): parse error: 65536 does not fit in 16 bits")
121
122 verify_error("""
123/dts-v1/;
124
125/ {
126 a = < 0x100000000 >;
127};
128""",
129".tmp.dts:4 (column 8): parse error: 4294967296 does not fit in 32 bits")
130
131 verify_error("""
132/dts-v1/;
133
134/ {
135 a = /bits/ 128 < 0 >;
136};
137""",
138".tmp.dts:4 (column 13): parse error: expected 8, 16, 32, or 64")
139
140 #
141 # Test bytes parsing
142 #
143
144 verify_parse("""
145/dts-v1/;
146
147/ {
148 a = [ ];
149 b = [ 12 34 ];
150 c = [ 1234 ];
151};
152""",
153"""
154/dts-v1/;
155
156/ {
157 a;
158 b = [ 12 34 ];
159 c = [ 12 34 ];
160};
161""")
162
163 verify_error("""
164/dts-v1/;
165
166/ {
167 a = [ 123 ];
168};
169""",
170".tmp.dts:4 (column 10): parse error: expected two-digit byte or ']'")
171
172 #
173 # Test string parsing
174 #
175
176 verify_parse(r"""
177/dts-v1/;
178
179/ {
180 a = "";
181 b = "ABC";
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200182 c = "\\\"\xab\377\a\b\t\n\v\f\r";
Ulf Magnusson62d57412018-12-17 20:09:47 +0100183};
184""",
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200185r"""
Ulf Magnusson62d57412018-12-17 20:09:47 +0100186/dts-v1/;
187
188/ {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200189 a = "";
190 b = "ABC";
191 c = "\\\"\xab\xff\a\b\t\n\v\f\r";
Ulf Magnusson62d57412018-12-17 20:09:47 +0100192};
193""")
194
195 verify_error(r"""
196/dts-v1/;
197
198/ {
199 a = "\400";
200};
201""",
202".tmp.dts:4 (column 6): parse error: octal escape out of range (> 255)")
203
204 #
Ulf Magnussonc2d702b2019-08-13 08:23:19 +0200205 # Test character literal parsing
206 #
207
208 verify_parse(r"""
209/dts-v1/;
210
211/ {
212 a = < '\'' >;
213 b = < '\x12' >;
214};
215""",
216"""
217/dts-v1/;
218
219/ {
220 a = < 0x27 >;
221 b = < 0x12 >;
222};
223""")
224
225 verify_error("""
226/dts-v1/;
227
228/ {
229 // Character literals are not allowed at the top level
230 a = 'x';
231};
232""",
233".tmp.dts:5 (column 6): parse error: malformed value")
234
235 verify_error("""
236/dts-v1/;
237
238/ {
239 a = < '' >;
240};
241""",
242".tmp.dts:4 (column 7): parse error: character literals must be length 1")
243
244 verify_error("""
245/dts-v1/;
246
247/ {
248 a = < '12' >;
249};
250""",
251".tmp.dts:4 (column 7): parse error: character literals must be length 1")
252
253 #
Ulf Magnusson62d57412018-12-17 20:09:47 +0100254 # Test /incbin/
255 #
256
257 open(".tmp.bin", "wb").write(b"\00\01\02\03")
258
259 verify_parse("""
260/dts-v1/;
261
262/ {
263 a = /incbin/ (".tmp.bin");
264 b = /incbin/ (".tmp.bin", 1, 1);
265 c = /incbin/ (".tmp.bin", 1, 2);
266};
267""",
268"""
269/dts-v1/;
270
271/ {
272 a = [ 00 01 02 03 ];
273 b = [ 01 ];
274 c = [ 01 02 ];
275};
276""")
277
278 open(".tmp/in_subdir", "wb").write(b"\00\01\02")
279
280 verify_parse("""
281/dts-v1/;
282
283/ {
284 a = /incbin/ ("in_subdir");
285};
286""",
287"""
288/dts-v1/;
289
290/ {
291 a = [ 00 01 02 ];
292};
293""",
294 include_path=(".tmp",))
295
296 verify_error(r"""
297/dts-v1/;
298
299/ {
300 a = /incbin/ ("missing");
301};
302""",
303".tmp.dts:4 (column 25): parse error: 'missing' could not be found")
304
305 #
306 # Test node merging
307 #
308
309 verify_parse("""
310/dts-v1/;
311
312/ {
313 l1: l2: l1: foo {
314 foo1 = [ 01 ];
315 l4: l5: bar {
316 bar1 = [ 01 ];
317 };
318 };
319};
320
321l3: &l1 {
322 foo2 = [ 02 ];
323 l6: l7: bar {
324 bar2 = [ 02 ];
325 };
326};
327
328&l3 {
329 foo3 = [ 03 ];
330};
331
332&{/foo} {
333 foo4 = [ 04 ];
334};
335
336&{/foo/bar} {
337 bar3 = [ 03 ];
338 l8: baz {};
339};
340
341/ {
342};
343
344/ {
345 top = [ 01 ];
346};
347""",
348"""
349/dts-v1/;
350
351/ {
352 top = [ 01 ];
353 l1: l2: l3: foo {
354 foo1 = [ 01 ];
355 foo2 = [ 02 ];
356 foo3 = [ 03 ];
357 foo4 = [ 04 ];
358 l4: l5: l6: l7: bar {
359 bar1 = [ 01 ];
360 bar2 = [ 02 ];
361 bar3 = [ 03 ];
362 l8: baz {
363 };
364 };
365 };
366};
367""")
368
369 verify_error("""
370/dts-v1/;
371
372/ {
373};
374
375&missing {
376};
377""",
378".tmp.dts:6 (column 1): parse error: undefined node label 'missing'")
379
380 verify_error("""
381/dts-v1/;
382
383/ {
384};
385
386&{foo} {
387};
388""",
Ulf Magnusson22827772019-08-15 10:00:55 +0200389".tmp.dts:6 (column 1): parse error: node path 'foo' does not start with '/'")
Ulf Magnusson62d57412018-12-17 20:09:47 +0100390
391 verify_error("""
392/dts-v1/;
393
394/ {
395};
396
397&{/foo} {
398};
399""",
Ulf Magnusson22827772019-08-15 10:00:55 +0200400".tmp.dts:6 (column 1): parse error: component 'foo' in path '/foo' does not exist")
Ulf Magnusson62d57412018-12-17 20:09:47 +0100401
402 #
403 # Test property labels
404 #
405
406 def verify_label2prop(label, expected):
407 actual = dt.label2prop[label].name
408 if actual != expected:
409 fail("expected label '{}' to map to prop '{}', mapped to prop '{}'"
410 .format(label, expected, actual))
411
412 dt = verify_parse("""
413/dts-v1/;
414
415/ {
416 a;
417 b;
418 l2: c;
419 l4: l5: l5: l4: d = < 0 >;
420};
421
422/ {
423 l1: b;
424 l3: c;
425 l6: d;
426};
427""",
428"""
429/dts-v1/;
430
431/ {
432 a;
433 l1: b;
434 l2: l3: c;
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200435 l4: l5: l6: d = < 0x0 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100436};
437""")
438
439 verify_label2prop("l1", "b")
440 verify_label2prop("l2", "c")
441 verify_label2prop("l3", "c")
442 verify_label2prop("l4", "d")
443 verify_label2prop("l5", "d")
444 verify_label2prop("l6", "d")
445
446 #
447 # Test offset labels
448 #
449
450 def verify_label2offset(label, expected_prop, expected_offset):
451 actual_prop, actual_offset = dt.label2prop_offset[label]
452 actual_prop = actual_prop.name
453 if (actual_prop, actual_offset) != (expected_prop, expected_offset):
454 fail("expected label '{}' to map to offset {} on prop '{}', "
455 "mapped to offset {} on prop '{}'"
456 .format(label, expected_offset, expected_prop, actual_offset,
457 actual_prop))
458
459 dt = verify_parse("""
460/dts-v1/;
461
462/ {
Ulf Magnusson929837a2019-08-16 09:35:03 +0200463 a = l01: l02: < l03: &node l04: l05: 2 l06: >,
464 l07: l08: [ l09: 03 l10: l11: 04 l12: l13: ] l14:, "A";
Ulf Magnusson62d57412018-12-17 20:09:47 +0100465
Ulf Magnusson929837a2019-08-16 09:35:03 +0200466 b = < 0 > l23: l24:;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100467
Ulf Magnusson929837a2019-08-16 09:35:03 +0200468 node: node {
469 };
Ulf Magnusson62d57412018-12-17 20:09:47 +0100470};
471""",
472"""
473/dts-v1/;
474
475/ {
Ulf Magnusson06b746c2019-08-09 20:38:17 +0200476 a = l01: l02: < l03: &node l04: l05: 0x2 l06: l07: l08: >, [ l09: 03 l10: l11: 04 l12: l13: l14: ], "A";
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200477 b = < 0x0 l23: l24: >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100478 node: node {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200479 phandle = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100480 };
481};
482""")
483
484 verify_label2offset("l01", "a", 0)
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200485 verify_label2offset("l02", "a", 0)
486 verify_label2offset("l04", "a", 4)
Ulf Magnusson62d57412018-12-17 20:09:47 +0100487 verify_label2offset("l05", "a", 4)
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200488 verify_label2offset("l06", "a", 8)
489 verify_label2offset("l09", "a", 8)
490 verify_label2offset("l10", "a", 9)
Ulf Magnusson62d57412018-12-17 20:09:47 +0100491
492 verify_label2offset("l23", "b", 4)
493 verify_label2offset("l24", "b", 4)
494
495 #
496 # Test unit_addr
497 #
498
499 def verify_unit_addr(path, expected):
500 node = dt.get_node(path)
501 if node.unit_addr != expected:
502 fail("expected {!r} to have unit_addr '{}', was '{}'"
503 .format(node, expected, node.unit_addr))
504
505 dt = verify_parse("""
506/dts-v1/;
507
508/ {
509 no-unit-addr {
510 };
511
512 unit-addr@ABC {
513 };
514
515 unit-addr-non-numeric@foo-bar {
516 };
517};
518""",
519"""
520/dts-v1/;
521
522/ {
523 no-unit-addr {
524 };
525 unit-addr@ABC {
526 };
527 unit-addr-non-numeric@foo-bar {
528 };
529};
530""")
531
532 verify_unit_addr("/no-unit-addr", "")
533 verify_unit_addr("/unit-addr@ABC", "ABC")
534 verify_unit_addr("/unit-addr-non-numeric@foo-bar", "foo-bar")
535
536 #
537 # Test node path references
538 #
539
540 verify_parse("""
541/dts-v1/;
542
543/ {
544 a = &label;
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200545 b = [ 01 ], &label;
546 c = [ 01 ], &label, <2>;
547 d = &{/abc};
Ulf Magnusson62d57412018-12-17 20:09:47 +0100548 label: abc {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200549 e = &label;
550 f = &{/abc};
Ulf Magnusson62d57412018-12-17 20:09:47 +0100551 };
552};
553""",
554"""
555/dts-v1/;
556
557/ {
Ulf Magnusson06b746c2019-08-09 20:38:17 +0200558 a = &label;
559 b = [ 01 ], &label;
560 c = [ 01 ], &label, < 0x2 >;
561 d = &{/abc};
Ulf Magnusson62d57412018-12-17 20:09:47 +0100562 label: abc {
Ulf Magnusson06b746c2019-08-09 20:38:17 +0200563 e = &label;
564 f = &{/abc};
Ulf Magnusson62d57412018-12-17 20:09:47 +0100565 };
566};
567""")
568
569 verify_error("""
570/dts-v1/;
571
572/ {
573 sub {
574 x = &missing;
575 };
576};
577""",
578"/sub: undefined node label 'missing'")
579
580 verify_error("""
581/dts-v1/;
582
583/ {
584 sub {
585 x = &{/sub/missing};
586 };
587};
588""",
Ulf Magnusson22827772019-08-15 10:00:55 +0200589"/sub: component 'missing' in path '/sub/missing' does not exist")
Ulf Magnusson62d57412018-12-17 20:09:47 +0100590
591 #
592 # Test phandles
593 #
594
Ulf Magnusson62d57412018-12-17 20:09:47 +0100595 verify_parse("""
596/dts-v1/;
597
598/ {
599 x = < &a &{/b} &c >;
600
601 dummy1 {
602 phandle = < 1 >;
603 };
604
605 dummy2 {
606 phandle = < 3 >;
607 };
608
609 a: a {
610 };
611
612 b {
613 };
614
615 c: c {
616 phandle = < 0xFF >;
617 };
618};
619""",
620"""
621/dts-v1/;
622
623/ {
Ulf Magnusson06b746c2019-08-09 20:38:17 +0200624 x = < &a &{/b} &c >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100625 dummy1 {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200626 phandle = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100627 };
628 dummy2 {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200629 phandle = < 0x3 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100630 };
631 a: a {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200632 phandle = < 0x2 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100633 };
634 b {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200635 phandle = < 0x4 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100636 };
637 c: c {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200638 phandle = < 0xff >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100639 };
640};
641""")
642
643 # Check that a node can be assigned a phandle to itself. This just forces a
644 # phandle to be allocated on it. The C tools support this too.
645 verify_parse("""
646/dts-v1/;
647
648/ {
649 dummy {
650 phandle = < 1 >;
651 };
652
653 a {
654 foo: phandle = < &{/a} >;
655 };
656
657 label: b {
658 bar: phandle = < &label >;
659 };
660};
661""",
662"""
663/dts-v1/;
664
665/ {
666 dummy {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200667 phandle = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100668 };
669 a {
Ulf Magnusson06b746c2019-08-09 20:38:17 +0200670 foo: phandle = < &{/a} >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100671 };
672 label: b {
Ulf Magnusson06b746c2019-08-09 20:38:17 +0200673 bar: phandle = < &label >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100674 };
675};
676""")
677
678 verify_error("""
679/dts-v1/;
680
681/ {
682 sub {
683 x = < &missing >;
684 };
685};
686""",
687"/sub: undefined node label 'missing'")
688
689 verify_error("""
690/dts-v1/;
691
692/ {
693 a: sub {
694 x = /bits/ 16 < &a >;
695 };
696};
697""",
698".tmp.dts:5 (column 19): parse error: phandle references are only allowed in arrays with 32-bit elements")
699
700 verify_error("""
701/dts-v1/;
702
703/ {
704 foo {
705 phandle = [ 00 ];
706 };
707};
708""",
709"/foo: bad phandle length (1), expected 4 bytes")
710
711 verify_error("""
712/dts-v1/;
713
714/ {
715 foo {
716 phandle = < 0 >;
717 };
718};
719""",
720"/foo: bad value 0x00000000 for phandle")
721
722 verify_error("""
723/dts-v1/;
724
725/ {
726 foo {
727 phandle = < (-1) >;
728 };
729};
730""",
731"/foo: bad value 0xffffffff for phandle")
732
733 verify_error("""
734/dts-v1/;
735
736/ {
737 foo {
738 phandle = < 17 >;
739 };
740
741 bar {
742 phandle = < 17 >;
743 };
744};
745""",
746"/bar: duplicated phandle 0x11 (seen before at /foo)")
747
748 verify_error("""
749/dts-v1/;
750
751/ {
752 foo {
753 phandle = < &{/bar} >;
754 };
755
756 bar {
757 };
758};
759""",
760"/foo: phandle refers to another node")
761
762 # Test phandle2node
763
764 def verify_phandle2node(prop, offset, expected_name):
765 phandle = dtlib.to_num(dt.root.props[prop].value[offset:offset + 4])
766 actual_name = dt.phandle2node[phandle].name
767
768 if actual_name != expected_name:
769 fail("expected {} to be a phandle for {}, was a phandle for {}"
770 .format(prop, expected_name, actual_name))
771
772 dt = parse("""
773/dts-v1/;
774
775/ {
776 phandle_ = < &{/node1} 0 1 >;
777 phandles = < 0 &{/node2} 1 &{/node3} >;
778
779 node1 {
780 phandle = < 123 >;
781 };
782
783 node2 {
784 };
785
786 node3 {
787 };
788};
789""")
790
791 verify_phandle2node("phandle_", 0, "node1")
792 verify_phandle2node("phandles", 4, "node2")
793 verify_phandle2node("phandles", 12, "node3")
794
795 #
796 # Test mixed value type assignments
797 #
798
799 verify_parse("""
800/dts-v1/;
801
802/ {
803 x = /bits/ 8 < 0xFF 0xFF >,
804 &abc,
805 < 0xFF &abc 0xFF &abc >,
806 &abc,
807 [ FF FF ],
808 "abc";
809
810 abc: abc {
811 };
812};
813""",
814"""
815/dts-v1/;
816
817/ {
Ulf Magnusson06b746c2019-08-09 20:38:17 +0200818 x = [ FF FF ], &abc, < 0xff &abc 0xff &abc >, &abc, [ FF FF ], "abc";
Ulf Magnusson62d57412018-12-17 20:09:47 +0100819 abc: abc {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200820 phandle = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100821 };
822};
823""")
824
825 #
826 # Test property deletion
827 #
828
829 verify_parse("""
830/dts-v1/;
831
832/ {
833 keep = < 1 >;
834 delete = < &sub >, &sub;
835 /delete-property/ missing;
836 /delete-property/ delete;
837 sub: sub {
838 y = < &sub >, &sub;
839 };
840};
841
842&sub {
843 /delete-property/ y;
844};
845""",
846"""
847/dts-v1/;
848
849/ {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200850 keep = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100851 sub: sub {
852 };
853};
854""")
855
856 #
857 # Test node deletion
858 #
859
860 verify_parse("""
861/dts-v1/;
862
863/ {
864 sub1 {
865 x = < 1 >;
866 sub2 {
867 x = < &sub >, &sub;
868 };
869 /delete-node/ sub2;
870 };
871
872 sub3: sub3 {
873 x = < &sub >, &sub;
874 };
875
876 sub4 {
877 x = < &sub >, &sub;
878 };
879};
880
881/delete-node/ &sub3;
882/delete-node/ &{/sub4};
883""",
884"""
885/dts-v1/;
886
887/ {
888 sub1 {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200889 x = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100890 };
891};
892""")
893
894 verify_error("""
895/dts-v1/;
896
897/ {
898};
899
900/delete-node/ &missing;
901""",
902".tmp.dts:6 (column 15): parse error: undefined node label 'missing'")
903
Ulf Magnusson22827772019-08-15 10:00:55 +0200904 verify_error("""
905/dts-v1/;
906
907/delete-node/ {
908""",
909".tmp.dts:3 (column 15): parse error: expected label (&foo) or path (&{/foo/bar}) reference")
910
Ulf Magnusson62d57412018-12-17 20:09:47 +0100911 #
912 # Test /include/ (which is handled in the lexer)
913 #
914
915 # Verify that /include/ searches the current directory
916
917 open(".tmp/same-dir-1", "w").write("""
918 x = [ 00 ];
919 /include/ "same-dir-2"
920""")
921 open(".tmp/same-dir-2", "w").write("""
922 y = [ 01 ];
923 /include/ "same-dir-3"
924""")
925 open(".tmp/same-dir-3", "w").write("""
926 z = [ 02 ];
927""")
928
929 verify_parse("""
930/dts-v1/;
931
932/ {
933 /include/ ".tmp/same-dir-1"
934};
935""",
936"""
937/dts-v1/;
938
939/ {
940 x = [ 00 ];
941 y = [ 01 ];
942 z = [ 02 ];
943};
944""")
945
946 # Test tricky includes and include paths
947
948 open(".tmp2.dts", "w").write("""
949/dts-v1/;
950/ {
951""")
952 open(".tmp3.dts", "w").write("""
953 x = <1>;
954""")
955 open(".tmp/via-include-path-1", "w").write("""
956 = /include/ "via-include-path-2"
957""")
958 open(".tmp2/via-include-path-2", "w").write("""
959 <2>;
960};
961""")
962
963 verify_parse("""
964/include/ ".tmp2.dts"
965/include/ ".tmp3.dts"
966y /include/ "via-include-path-1"
967""",
968"""
969/dts-v1/;
970
971/ {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +0200972 x = < 0x1 >;
973 y = < 0x2 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +0100974};
975""",
976 include_path=(".tmp", ".tmp2",))
977
978 verify_error("""
979/include/ "missing"
980""",
981".tmp.dts:1 (column 1): parse error: 'missing' could not be found")
982
983 # Verify that an error in an included file points to the right location
984
985 open(".tmp2.dts", "w").write("""\
986
987
988 x
989""")
990
991 verify_error("""
992
993
994/include/ ".tmp2.dts"
995""",
996".tmp2.dts:3 (column 3): parse error: expected '/dts-v1/;' at start of file")
997
998# Test recursive /include/ detection
999
1000 open(".tmp2.dts", "w").write("""\
1001/include/ ".tmp3.dts"
1002""")
1003 open(".tmp3.dts", "w").write("""\
1004/include/ ".tmp.dts"
1005""")
1006
1007 verify_error("""
1008/include/ ".tmp2.dts"
1009""",
1010"""\
1011.tmp3.dts:1 (column 1): parse error: recursive /include/:
1012.tmp.dts:1 ->
1013.tmp2.dts:1 ->
1014.tmp3.dts:1 ->
1015.tmp.dts\
1016""")
1017
1018 verify_error("""
1019/include/ ".tmp.dts"
1020""",
1021"""\
1022.tmp.dts:1 (column 1): parse error: recursive /include/:
1023.tmp.dts:1 ->
1024.tmp.dts\
1025""")
1026
1027 #
1028 # Test /omit-if-no-ref/
1029 #
1030
1031 verify_parse("""
1032/dts-v1/;
1033
1034/ {
1035 x = < &{/referenced} >, &referenced2;
1036
1037 /omit-if-no-ref/ referenced {
1038 };
1039
1040 referenced2: referenced2 {
1041 };
1042
1043 /omit-if-no-ref/ unreferenced {
1044 };
1045
1046 l1: /omit-if-no-ref/ unreferenced2 {
1047 };
1048
1049 /omit-if-no-ref/ l2: unreferenced3 {
1050 };
1051
1052 unreferenced4: unreferenced4 {
1053 };
1054
1055 unreferenced5 {
1056 };
1057};
1058
1059/omit-if-no-ref/ &referenced2;
1060/omit-if-no-ref/ &unreferenced4;
1061/omit-if-no-ref/ &{/unreferenced5};
1062""",
1063"""
1064/dts-v1/;
1065
1066/ {
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001067 x = < &{/referenced} >, &referenced2;
Ulf Magnusson62d57412018-12-17 20:09:47 +01001068 referenced {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +02001069 phandle = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +01001070 };
1071 referenced2: referenced2 {
1072 };
1073};
1074""")
1075
1076 verify_error("""
1077/dts-v1/;
1078
1079/ {
1080 /omit-if-no-ref/ x = "";
1081};
1082""",
1083".tmp.dts:4 (column 21): parse error: /omit-if-no-ref/ can only be used on nodes")
1084
1085 verify_error("""
1086/dts-v1/;
1087
1088/ {
1089 /omit-if-no-ref/ x;
1090};
1091""",
1092".tmp.dts:4 (column 20): parse error: /omit-if-no-ref/ can only be used on nodes")
1093
1094 verify_error("""
1095/dts-v1/;
1096
1097/ {
1098 /omit-if-no-ref/ {
1099 };
1100};
1101""",
1102".tmp.dts:4 (column 19): parse error: expected node or property name")
1103
1104 verify_error("""
1105/dts-v1/;
1106
1107/ {
1108 /omit-if-no-ref/ = < 0 >;
1109};
1110""",
1111".tmp.dts:4 (column 19): parse error: expected node or property name")
1112
1113 verify_error("""
1114/dts-v1/;
1115
1116/ {
1117};
1118
1119/omit-if-no-ref/ &missing;
1120""",
1121".tmp.dts:6 (column 18): parse error: undefined node label 'missing'")
1122
Ulf Magnusson22827772019-08-15 10:00:55 +02001123 verify_error("""
1124/dts-v1/;
1125
1126/omit-if-no-ref/ {
1127""",
1128".tmp.dts:3 (column 18): parse error: expected label (&foo) or path (&{/foo/bar}) reference")
1129
Ulf Magnusson62d57412018-12-17 20:09:47 +01001130 #
1131 # Test expressions
1132 #
1133
1134 verify_parse("""
1135/dts-v1/;
1136
1137/ {
1138 ter1 = < (0 ? 1 : 0 ? 2 : 3) >;
1139 ter2 = < (0 ? 1 : 1 ? 2 : 3) >;
1140 ter3 = < (1 ? 1 : 0 ? 2 : 3) >;
1141 ter4 = < (1 ? 1 : 1 ? 2 : 3) >;
1142 or1 = < (0 || 0) >;
1143 or2 = < (0 || 1) >;
1144 or3 = < (1 || 0) >;
1145 or4 = < (1 || 1) >;
1146 and1 = < (0 && 0) >;
1147 and2 = < (0 && 1) >;
1148 and3 = < (1 && 0) >;
1149 and4 = < (1 && 1) >;
1150 bitor = < (1 | 2) >;
1151 bitxor = < (7 ^ 2) >;
1152 bitand = < (3 & 6) >;
1153 eq1 = < (1 == 0) >;
1154 eq2 = < (1 == 1) >;
1155 neq1 = < (1 != 0) >;
1156 neq2 = < (1 != 1) >;
1157 lt1 = < (1 < 2) >;
1158 lt2 = < (2 < 2) >;
1159 lt3 = < (3 < 2) >;
1160 lteq1 = < (1 <= 2) >;
1161 lteq2 = < (2 <= 2) >;
1162 lteq3 = < (3 <= 2) >;
1163 gt1 = < (1 > 2) >;
1164 gt2 = < (2 > 2) >;
1165 gt3 = < (3 > 2) >;
1166 gteq1 = < (1 >= 2) >;
1167 gteq2 = < (2 >= 2) >;
1168 gteq3 = < (3 >= 2) >;
1169 lshift = < (2 << 3) >;
1170 rshift = < (16 >> 3) >;
1171 add = < (3 + 4) >;
1172 sub = < (7 - 4) >;
1173 mul = < (3 * 4) >;
1174 div = < (11 / 3) >;
1175 mod = < (11 % 3) >;
1176 unary_minus = < (-3) >;
1177 bitnot = < (~1) >;
1178 not0 = < (!-1) >;
1179 not1 = < (!0) >;
1180 not2 = < (!1) >;
1181 not3 = < (!2) >;
1182 nest = < (((--3) + (-2)) * (--(-2))) >;
Ulf Magnussonc2d702b2019-08-13 08:23:19 +02001183 char_lits = < ('a' + 'b') >;
Ulf Magnusson62d57412018-12-17 20:09:47 +01001184};
1185""",
1186"""
1187/dts-v1/;
1188
1189/ {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +02001190 ter1 = < 0x3 >;
1191 ter2 = < 0x2 >;
1192 ter3 = < 0x1 >;
1193 ter4 = < 0x1 >;
1194 or1 = < 0x0 >;
1195 or2 = < 0x1 >;
1196 or3 = < 0x1 >;
1197 or4 = < 0x1 >;
1198 and1 = < 0x0 >;
1199 and2 = < 0x0 >;
1200 and3 = < 0x0 >;
1201 and4 = < 0x1 >;
1202 bitor = < 0x3 >;
1203 bitxor = < 0x5 >;
1204 bitand = < 0x2 >;
1205 eq1 = < 0x0 >;
1206 eq2 = < 0x1 >;
1207 neq1 = < 0x1 >;
1208 neq2 = < 0x0 >;
1209 lt1 = < 0x1 >;
1210 lt2 = < 0x0 >;
1211 lt3 = < 0x0 >;
1212 lteq1 = < 0x1 >;
1213 lteq2 = < 0x1 >;
1214 lteq3 = < 0x0 >;
1215 gt1 = < 0x0 >;
1216 gt2 = < 0x0 >;
1217 gt3 = < 0x1 >;
1218 gteq1 = < 0x0 >;
1219 gteq2 = < 0x1 >;
1220 gteq3 = < 0x1 >;
1221 lshift = < 0x10 >;
1222 rshift = < 0x2 >;
1223 add = < 0x7 >;
1224 sub = < 0x3 >;
1225 mul = < 0xc >;
1226 div = < 0x3 >;
1227 mod = < 0x2 >;
1228 unary_minus = < 0xfffffffd >;
1229 bitnot = < 0xfffffffe >;
1230 not0 = < 0x0 >;
1231 not1 = < 0x1 >;
1232 not2 = < 0x0 >;
1233 not3 = < 0x0 >;
1234 nest = < 0xfffffffe >;
Ulf Magnussonc2d702b2019-08-13 08:23:19 +02001235 char_lits = < 0xc3 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +01001236};
1237""")
1238
1239 verify_error("""
1240/dts-v1/;
1241
1242/ {
1243 a = < (1/(-1 + 1)) >;
1244};
1245""",
1246".tmp.dts:4 (column 18): parse error: division by zero")
1247
1248 verify_error("""
1249/dts-v1/;
1250
1251/ {
1252 a = < (1%0) >;
1253};
1254""",
1255".tmp.dts:4 (column 11): parse error: division by zero")
1256
1257 #
1258 # Test comment removal
1259 #
1260
1261 verify_parse("""
1262/**//dts-v1//**/;//
1263//
1264// foo
1265/ /**/{// foo
1266x/**/=/*
1267foo
1268*/</**/1/***/>/****/;/**/}/*/**/;
1269""",
1270"""
1271/dts-v1/;
1272
1273/ {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +02001274 x = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +01001275};
1276""")
1277
1278 #
1279 # Test get_node()
1280 #
1281
1282 def verify_path_is(path, node_name):
1283 try:
1284 node = dt.get_node(path)
1285 if node.name != node_name:
1286 fail("expected {} to lead to {}, lead to {}"
1287 .format(path, node_name, node.name))
1288 except dtlib.DTError:
Ulf Magnusson4cac3712019-09-04 14:43:17 +02001289 fail("no node found for path " + path)
Ulf Magnusson62d57412018-12-17 20:09:47 +01001290
1291 def verify_path_error(path, msg):
1292 prefix = "expected looking up '{}' to generate the error '{}', " \
1293 "generated ".format(path, msg)
1294 try:
1295 dt.get_node(path)
1296 fail(prefix + " no error")
1297 except dtlib.DTError as e:
1298 if str(e) != msg:
1299 fail("{} the error '{}'".format(prefix, e))
1300 except Exception as e:
1301 fail("{} the non-DTError '{}'".format(prefix, e))
1302
1303 def verify_path_exists(path):
1304 if not dt.has_node(path):
1305 fail("expected path '{}' to exist, didn't".format(path))
1306
1307 def verify_path_missing(path):
1308 if dt.has_node(path):
1309 fail("expected path '{}' to not exist, did".format(path))
1310
1311 dt = parse("""
1312/dts-v1/;
1313
1314/ {
1315 foo {
1316 bar {
1317 };
1318 };
1319
1320 baz {
1321 };
1322};
1323""")
1324
1325 verify_path_is("/", "/")
1326 verify_path_is("//", "/")
1327 verify_path_is("///", "/")
1328 verify_path_is("/foo", "foo")
1329 verify_path_is("//foo", "foo")
1330 verify_path_is("///foo", "foo")
1331 verify_path_is("/foo/bar", "bar")
1332 verify_path_is("//foo//bar", "bar")
1333 verify_path_is("///foo///bar", "bar")
1334 verify_path_is("/baz", "baz")
1335
1336 verify_path_error("", "no alias '' found -- did you forget the leading '/' in the node path?")
1337 verify_path_error("missing", "no alias 'missing' found -- did you forget the leading '/' in the node path?")
Ulf Magnusson22827772019-08-15 10:00:55 +02001338 verify_path_error("/missing", "component 'missing' in path '/missing' does not exist")
1339 verify_path_error("/foo/missing", "component 'missing' in path '/foo/missing' does not exist")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001340
1341 verify_path_exists("/")
1342 verify_path_exists("/foo")
1343 verify_path_exists("/foo/bar")
1344
1345 verify_path_missing("/missing")
1346 verify_path_missing("/foo/missing")
1347
1348 #
1349 # Test /aliases
1350 #
1351
1352 def verify_alias_target(alias, node_name):
1353 verify_path_is(alias, node_name)
1354 if alias not in dt.alias2node:
1355 fail("expected {} to be in alias2node".format(alias))
1356 if dt.alias2node[alias].name != node_name:
1357 fail("expected alias {} to lead to {}, lead to {}"
1358 .format(alias, node_name, dt.alias2node[alias].name))
1359
1360 dt = parse("""
1361/dts-v1/;
1362
1363/ {
1364 aliases {
1365 alias1 = &l1;
1366 alias2 = &l2;
1367 alias3 = &{/sub/node3};
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001368 alias4 = &{/node4};
Ulf Magnusson62d57412018-12-17 20:09:47 +01001369 };
1370
1371 l1: node1 {
1372 };
1373
1374 l2: node2 {
1375 };
1376
1377 sub {
1378 node3 {
1379 };
1380 };
1381
1382 node4 {
1383 node5 {
1384 };
1385 };
1386};
1387""")
1388
1389 verify_alias_target("alias1", "node1")
1390 verify_alias_target("alias2", "node2")
1391 verify_alias_target("alias3", "node3")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001392 verify_path_is("alias4/node5", "node5")
1393
1394 verify_path_error("alias4/node5/node6",
Ulf Magnusson22827772019-08-15 10:00:55 +02001395 "component 'node6' in path 'alias4/node5/node6' does not exist")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001396
1397 verify_error("""
1398/dts-v1/;
1399
1400/ {
1401 aliases {
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001402 a = [ 00 ];
1403 };
1404};
1405""",
1406"expected property 'a' on /aliases in .tmp.dts to be assigned with either 'a = &foo' or 'a = \"/path/to/node\"', not 'a = [ 00 ];'")
1407
1408 verify_error(r"""
1409/dts-v1/;
1410
1411/ {
1412 aliases {
1413 a = "\xFF";
1414 };
1415};
1416""",
1417r"value of property 'a' (b'\xff\x00') on /aliases in .tmp.dts is not valid UTF-8")
1418
1419 verify_error("""
1420/dts-v1/;
1421
1422/ {
1423 aliases {
Ulf Magnusson62d57412018-12-17 20:09:47 +01001424 A = "/aliases";
1425 };
1426};
1427""",
1428"/aliases: alias property name 'A' should include only characters from [0-9a-z-]")
1429
1430 verify_error(r"""
1431/dts-v1/;
1432
1433/ {
1434 aliases {
Ulf Magnusson62d57412018-12-17 20:09:47 +01001435 a = "/missing";
1436 };
1437};
1438""",
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001439"property 'a' on /aliases in .tmp.dts points to the non-existent node \"/missing\"")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001440
1441 #
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001442 # Test Property.type
Ulf Magnusson62d57412018-12-17 20:09:47 +01001443 #
1444
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001445 def verify_type(prop, expected):
1446 actual = dt.root.props[prop].type
1447 if actual != expected:
1448 fail("expected {} to have type {}, had type {}"
1449 .format(prop, expected, actual))
1450
1451 dt = parse("""
1452/dts-v1/;
1453
1454/ {
1455 empty;
1456 bytes1 = [ ];
1457 bytes2 = [ 01 ];
1458 bytes3 = [ 01 02 ];
1459 bytes4 = foo: [ 01 bar: 02 ];
1460 bytes5 = /bits/ 8 < 1 2 3 >;
1461 num = < 1 >;
1462 nums1 = < >;
1463 nums2 = < >, < >;
1464 nums3 = < 1 2 >;
1465 nums4 = < 1 2 >, < 3 >, < 4 >;
1466 string = "foo";
1467 strings = "foo", "bar";
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001468 path1 = &node;
1469 path2 = &{/node};
Ulf Magnussonc42873f2019-08-13 11:52:10 +02001470 phandle1 = < &node >;
1471 phandle2 = < &{/node} >;
1472 phandles1 = < &node &node >;
1473 phandles2 = < &node >, < &node >;
1474 phandle-and-nums-1 = < &node 1 >;
1475 phandle-and-nums-2 = < &node 1 2 &node 3 4 >;
1476 phandle-and-nums-3 = < &node 1 2 >, < &node 3 4 >;
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001477 compound1 = < 1 >, [ 02 ];
1478 compound2 = "foo", < >;
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001479
1480 node: node {
1481 };
1482};
1483""")
1484
1485 verify_type("empty", dtlib.TYPE_EMPTY)
1486 verify_type("bytes1", dtlib.TYPE_BYTES)
1487 verify_type("bytes2", dtlib.TYPE_BYTES)
1488 verify_type("bytes3", dtlib.TYPE_BYTES)
1489 verify_type("bytes4", dtlib.TYPE_BYTES)
1490 verify_type("bytes5", dtlib.TYPE_BYTES)
1491 verify_type("num", dtlib.TYPE_NUM)
1492 verify_type("nums1", dtlib.TYPE_NUMS)
1493 verify_type("nums2", dtlib.TYPE_NUMS)
1494 verify_type("nums3", dtlib.TYPE_NUMS)
1495 verify_type("nums4", dtlib.TYPE_NUMS)
1496 verify_type("string", dtlib.TYPE_STRING)
1497 verify_type("strings", dtlib.TYPE_STRINGS)
1498 verify_type("phandle1", dtlib.TYPE_PHANDLE)
1499 verify_type("phandle2", dtlib.TYPE_PHANDLE)
Ulf Magnussonc42873f2019-08-13 11:52:10 +02001500 verify_type("phandles1", dtlib.TYPE_PHANDLES)
1501 verify_type("phandles2", dtlib.TYPE_PHANDLES)
1502 verify_type("phandle-and-nums-1", dtlib.TYPE_PHANDLES_AND_NUMS)
1503 verify_type("phandle-and-nums-2", dtlib.TYPE_PHANDLES_AND_NUMS)
1504 verify_type("phandle-and-nums-3", dtlib.TYPE_PHANDLES_AND_NUMS)
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001505 verify_type("path1", dtlib.TYPE_PATH)
1506 verify_type("path2", dtlib.TYPE_PATH)
1507 verify_type("compound1", dtlib.TYPE_COMPOUND)
1508 verify_type("compound2", dtlib.TYPE_COMPOUND)
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001509
1510 #
1511 # Test Property.to_{num,nums,string,strings,node}()
1512 #
1513
1514 dt = parse(r"""
1515/dts-v1/;
1516
1517/ {
1518 u = < 1 >;
1519 s = < 0xFFFFFFFF >;
1520 u8 = /bits/ 8 < 1 >;
1521 u16 = /bits/ 16 < 1 2 >;
1522 u64 = /bits/ 64 < 1 >;
1523 bytes = [ 01 02 03 ];
1524 empty;
1525 zero = < >;
1526 two_u = < 1 2 >;
1527 two_s = < 0xFFFFFFFF 0xFFFFFFFE >;
1528 three_u = < 1 2 3 >;
1529 three_u_split = < 1 >, < 2 >, < 3 >;
1530 empty_string = "";
1531 string = "foo\tbar baz";
1532 invalid_string = "\xff";
1533 strings = "foo", "bar", "baz";
1534 invalid_strings = "foo", "\xff", "bar";
1535 ref = <&{/target}>;
Ulf Magnussonc42873f2019-08-13 11:52:10 +02001536 refs = <&{/target} &{/target2}>;
1537 refs2 = <&{/target}>, <&{/target2}>;
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001538 path = &{/target};
1539 manualpath = "/target";
1540 missingpath = "/missing";
1541
1542 target {
1543 phandle = < 100 >;
1544 };
Ulf Magnussonc42873f2019-08-13 11:52:10 +02001545
1546 target2 {
1547 };
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001548};
1549""")
1550
1551 # Test Property.to_num()
1552
1553 def verify_to_num(prop, signed, expected):
Ulf Magnusson62d57412018-12-17 20:09:47 +01001554 try:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001555 actual = dt.root.props[prop].to_num(signed)
Ulf Magnusson62d57412018-12-17 20:09:47 +01001556 except dtlib.DTError as e:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001557 fail("failed to convert '{}' to {} number: {}"
1558 .format(prop, "a signed" if signed else "an unsigned", e))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001559
1560 if actual != expected:
1561 fail("expected {} to have the {} numeric value {:#x}, had the "
1562 "value {:#x}".format(prop, "signed" if signed else "unsigned",
1563 expected, actual))
1564
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001565 def verify_to_num_error(prop, msg):
1566 prefix = "expected fetching '{}' as a number to generate the error " \
1567 "'{}', generated".format(prop, msg)
Ulf Magnusson62d57412018-12-17 20:09:47 +01001568 try:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001569 dt.root.props[prop].to_num()
Ulf Magnusson62d57412018-12-17 20:09:47 +01001570 fail(prefix + " no error")
1571 except dtlib.DTError as e:
1572 if str(e) != msg:
1573 fail("{} the error '{}'".format(prefix, e))
1574 except Exception as e:
1575 fail("{} the non-DTError '{}'".format(prefix, e))
1576
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001577 verify_to_num("u", False, 1)
1578 verify_to_num("u", True, 1)
1579 verify_to_num("s", False, 0xFFFFFFFF)
1580 verify_to_num("s", True, -1)
1581
1582 verify_to_num_error("two_u", "expected property 'two_u' on / in .tmp.dts to be assigned with 'two_u = < (number) >;', not 'two_u = < 0x1 0x2 >;'")
1583 verify_to_num_error("u8", "expected property 'u8' on / in .tmp.dts to be assigned with 'u8 = < (number) >;', not 'u8 = [ 01 ];'")
1584 verify_to_num_error("u16", "expected property 'u16' on / in .tmp.dts to be assigned with 'u16 = < (number) >;', not 'u16 = /bits/ 16 < 0x1 0x2 >;'")
1585 verify_to_num_error("u64", "expected property 'u64' on / in .tmp.dts to be assigned with 'u64 = < (number) >;', not 'u64 = /bits/ 64 < 0x1 >;'")
1586 verify_to_num_error("string", "expected property 'string' on / in .tmp.dts to be assigned with 'string = < (number) >;', not 'string = \"foo\\tbar baz\";'")
1587
1588 # Test Property.to_nums()
1589
1590 def verify_to_nums(prop, signed, expected):
Ulf Magnusson62d57412018-12-17 20:09:47 +01001591 try:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001592 actual = dt.root.props[prop].to_nums(signed)
Ulf Magnusson62d57412018-12-17 20:09:47 +01001593 except dtlib.DTError as e:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001594 fail("failed to convert '{}' to {} numbers: {}"
1595 .format(prop, "signed" if signed else "unsigned", e))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001596
1597 if actual != expected:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001598 fail("expected {} to give the {} numbers {}, gave {}"
Ulf Magnusson62d57412018-12-17 20:09:47 +01001599 .format(prop, "signed" if signed else "unsigned", expected,
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001600 actual))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001601
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001602 def verify_to_nums_error(prop, msg):
1603 prefix = "expected converting '{}' to numbers to generate the error " \
1604 "'{}', generated".format(prop, msg)
Ulf Magnusson62d57412018-12-17 20:09:47 +01001605 try:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001606 dt.root.props[prop].to_nums()
Ulf Magnusson62d57412018-12-17 20:09:47 +01001607 fail(prefix + " no error")
1608 except dtlib.DTError as e:
1609 if str(e) != msg:
1610 fail("{} the error '{}'".format(prefix, e))
1611 except Exception as e:
1612 fail("{} the non-DTError '{}'".format(prefix, e))
1613
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001614 verify_to_nums("zero", False, [])
1615 verify_to_nums("u", False, [1])
1616 verify_to_nums("two_u", False, [1, 2])
1617 verify_to_nums("two_u", True, [1, 2])
1618 verify_to_nums("two_s", False, [0xFFFFFFFF, 0xFFFFFFFE])
1619 verify_to_nums("two_s", True, [-1, -2])
1620 verify_to_nums("three_u", False, [1, 2, 3])
1621 verify_to_nums("three_u_split", False, [1, 2, 3])
1622
Ulf Magnusson11019542019-08-09 20:38:17 +02001623 verify_to_nums_error("empty", "expected property 'empty' on / in .tmp.dts to be assigned with 'empty = < (number) (number) ... >;', not 'empty;'")
1624 verify_to_nums_error("string", "expected property 'string' on / in .tmp.dts to be assigned with 'string = < (number) (number) ... >;', not 'string = \"foo\\tbar baz\";'")
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001625
1626 # Test Property.to_bytes()
1627
1628 def verify_to_bytes(prop, expected):
Ulf Magnusson62d57412018-12-17 20:09:47 +01001629 try:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001630 actual = dt.root.props[prop].to_bytes()
1631 except dtlib.DTError as e:
1632 fail("failed to convert '{}' to bytes: {}".format(prop, e))
1633
1634 if actual != expected:
1635 fail("expected {} to give the bytes {}, gave {}"
1636 .format(prop, expected, actual))
1637
1638 def verify_to_bytes_error(prop, msg):
1639 prefix = "expected converting '{}' to bytes to generate the error " \
1640 "'{}', generated".format(prop, msg)
1641 try:
1642 dt.root.props[prop].to_bytes()
Ulf Magnusson62d57412018-12-17 20:09:47 +01001643 fail(prefix + " no error")
1644 except dtlib.DTError as e:
1645 if str(e) != msg:
1646 fail("{} the error '{}'".format(prefix, e))
1647 except Exception as e:
1648 fail("{} the non-DTError '{}'".format(prefix, e))
1649
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001650 verify_to_bytes("u8", b"\x01")
1651 verify_to_bytes("bytes", b"\x01\x02\x03")
1652
Ulf Magnusson11019542019-08-09 20:38:17 +02001653 verify_to_bytes_error("u16", "expected property 'u16' on / in .tmp.dts to be assigned with 'u16 = [ (byte) (byte) ... ];', not 'u16 = /bits/ 16 < 0x1 0x2 >;'")
1654 verify_to_bytes_error("empty", "expected property 'empty' on / in .tmp.dts to be assigned with 'empty = [ (byte) (byte) ... ];', not 'empty;'")
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001655
1656 # Test Property.to_string()
1657
Ulf Magnusson62d57412018-12-17 20:09:47 +01001658 def verify_to_string(prop, expected):
1659 try:
1660 actual = dt.root.props[prop].to_string()
1661 except dtlib.DTError as e:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001662 fail("failed to convert '{}' to string: {}".format(prop, e))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001663
1664 if actual != expected:
1665 fail("expected {} to have the value '{}', had the value '{}'"
1666 .format(prop, expected, actual))
1667
1668 def verify_to_string_error(prop, msg):
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001669 prefix = "expected converting '{}' to string to generate the error " \
Ulf Magnusson62d57412018-12-17 20:09:47 +01001670 "'{}', generated".format(prop, msg)
1671 try:
1672 dt.root.props[prop].to_string()
1673 fail(prefix + " no error")
1674 except dtlib.DTError as e:
1675 if str(e) != msg:
1676 fail("{} the error '{}'".format(prefix, e))
1677 except Exception as e:
1678 fail("{} the non-DTError '{}'".format(prefix, e))
1679
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001680 verify_to_string("empty_string", "")
1681 verify_to_string("string", "foo\tbar baz")
1682
Ulf Magnusson11019542019-08-09 20:38:17 +02001683 verify_to_string_error("u", "expected property 'u' on / in .tmp.dts to be assigned with 'u = \"string\";', not 'u = < 0x1 >;'")
1684 verify_to_string_error("strings", "expected property 'strings' on / in .tmp.dts to be assigned with 'strings = \"string\";', not 'strings = \"foo\", \"bar\", \"baz\";'")
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001685 verify_to_string_error("invalid_string", r"value of property 'invalid_string' (b'\xff\x00') on / in .tmp.dts is not valid UTF-8")
1686
1687 # Test Property.to_strings()
Ulf Magnusson62d57412018-12-17 20:09:47 +01001688
1689 def verify_to_strings(prop, expected):
1690 try:
1691 actual = dt.root.props[prop].to_strings()
1692 except dtlib.DTError as e:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001693 fail("failed to convert '{}' to strings: {}".format(prop, e))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001694
1695 if actual != expected:
1696 fail("expected {} to have the value '{}', had the value '{}'"
1697 .format(prop, expected, actual))
1698
1699 def verify_to_strings_error(prop, msg):
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001700 prefix = "expected converting '{}' to strings to generate the error " \
Ulf Magnusson62d57412018-12-17 20:09:47 +01001701 "'{}', generated".format(prop, msg)
1702 try:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001703 dt.root.props[prop].to_strings()
Ulf Magnusson62d57412018-12-17 20:09:47 +01001704 fail(prefix + " no error")
1705 except dtlib.DTError as e:
1706 if str(e) != msg:
1707 fail("{} the error '{}'".format(prefix, e))
1708 except Exception as e:
1709 fail("{} the non-DTError '{}'".format(prefix, e))
1710
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001711 verify_to_strings("empty_string", [""])
1712 verify_to_strings("string", ["foo\tbar baz"])
1713 verify_to_strings("strings", ["foo", "bar", "baz"])
1714
Ulf Magnusson11019542019-08-09 20:38:17 +02001715 verify_to_strings_error("u", "expected property 'u' on / in .tmp.dts to be assigned with 'u = \"string\", \"string\", ... ;', not 'u = < 0x1 >;'")
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001716 verify_to_strings_error("invalid_strings", r"value of property 'invalid_strings' (b'foo\x00\xff\x00bar\x00') on / in .tmp.dts is not valid UTF-8")
1717
1718 # Test Property.to_node()
1719
Ulf Magnusson62d57412018-12-17 20:09:47 +01001720 def verify_to_node(prop, path):
1721 try:
1722 actual = dt.root.props[prop].to_node().path
1723 except dtlib.DTError as e:
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001724 fail("failed to convert '{}' to node: {}".format(prop, e))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001725
1726 if actual != path:
1727 fail("expected {} to point to {}, pointed to {}"
1728 .format(prop, path, actual))
1729
1730 def verify_to_node_error(prop, msg):
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001731 prefix = "expected converting '{}' to a node to generate the error " \
Ulf Magnusson62d57412018-12-17 20:09:47 +01001732 "'{}', generated".format(prop, msg)
1733 try:
1734 dt.root.props[prop].to_node()
1735 fail(prefix + " no error")
1736 except dtlib.DTError as e:
1737 if str(e) != msg:
1738 fail("{} the error '{}'".format(prefix, e))
1739 except Exception as e:
1740 fail("{} the non-DTError '{}'".format(prefix, e))
1741
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001742 verify_to_node("ref", "/target")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001743
Ulf Magnusson11019542019-08-09 20:38:17 +02001744 verify_to_node_error("u", "expected property 'u' on / in .tmp.dts to be assigned with 'u = < &foo >;', not 'u = < 0x1 >;'")
1745 verify_to_node_error("string", "expected property 'string' on / in .tmp.dts to be assigned with 'string = < &foo >;', not 'string = \"foo\\tbar baz\";'")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001746
Ulf Magnussonc42873f2019-08-13 11:52:10 +02001747 # Test Property.to_nodes()
1748
1749 def verify_to_nodes(prop, paths):
1750 try:
1751 actual = [node.path for node in dt.root.props[prop].to_nodes()]
1752 except dtlib.DTError as e:
1753 fail("failed to convert '{}' to nodes: {}".format(prop, e))
1754
1755 if actual != paths:
1756 fail("expected {} to point to the paths {}, pointed to {}"
1757 .format(prop, paths, actual))
1758
1759 def verify_to_nodes_error(prop, msg):
1760 prefix = "expected converting '{}' to a nodes to generate the error " \
1761 "'{}', generated".format(prop, msg)
1762 try:
1763 dt.root.props[prop].to_nodes()
1764 fail(prefix + " no error")
1765 except dtlib.DTError as e:
1766 if str(e) != msg:
1767 fail("{} the error '{}'".format(prefix, e))
1768 except Exception as e:
1769 fail("{} the non-DTError '{}'".format(prefix, e))
1770
1771 verify_to_nodes("zero", [])
1772 verify_to_nodes("ref", ["/target"])
1773 verify_to_nodes("refs", ["/target", "/target2"])
1774 verify_to_nodes("refs2", ["/target", "/target2"])
1775
1776 verify_to_nodes_error("u", "expected property 'u' on / in .tmp.dts to be assigned with 'u = < &foo &bar ... >;', not 'u = < 0x1 >;'")
1777 verify_to_nodes_error("string", "expected property 'string' on / in .tmp.dts to be assigned with 'string = < &foo &bar ... >;', not 'string = \"foo\\tbar baz\";'")
1778
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001779 # Test Property.to_path()
Ulf Magnusson62d57412018-12-17 20:09:47 +01001780
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001781 def verify_to_path(prop, path):
1782 try:
1783 actual = dt.root.props[prop].to_path().path
1784 except dtlib.DTError as e:
1785 fail("failed to convert '{}' to path: {}".format(prop, e))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001786
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001787 if actual != path:
1788 fail("expected {} to contain the path {}, contained {}"
1789 .format(prop, path, actual))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001790
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001791 def verify_to_path_error(prop, msg):
1792 prefix = "expected converting '{}' to a path to generate the error " \
1793 "'{}', generated".format(prop, msg)
1794 try:
1795 dt.root.props[prop].to_path()
1796 fail(prefix + " no error")
1797 except dtlib.DTError as e:
1798 if str(e) != msg:
1799 fail("{} the error '{}'".format(prefix, e))
1800 except Exception as e:
1801 fail("{} the non-DTError '{}'".format(prefix, e))
Ulf Magnusson62d57412018-12-17 20:09:47 +01001802
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001803 verify_to_path("path", "/target")
1804 verify_to_path("manualpath", "/target")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001805
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001806 verify_to_path_error("u", "expected property 'u' on / in .tmp.dts to be assigned with either 'u = &foo' or 'u = \"/path/to/node\"', not 'u = < 0x1 >;'")
1807 verify_to_path_error("missingpath", "property 'missingpath' on / in .tmp.dts points to the non-existent node \"/missing\"")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001808
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001809 # Test top-level to_num() and to_nums()
1810
1811 def verify_raw_to_num(fn, prop, length, signed, expected):
1812 try:
1813 actual = fn(dt.root.props[prop].value, length, signed)
1814 except dtlib.DTError as e:
1815 fail("failed to convert '{}' to {} number(s) with {}: {}"
1816 .format(prop, "signed" if signed else "unsigned",
1817 fn.__name__, e))
1818
1819 if actual != expected:
1820 fail("expected {}(<{}>, {}, {}) to be {}, was {}"
1821 .format(fn.__name__, prop, length, signed, expected, actual))
1822
1823 def verify_raw_to_num_error(fn, data, length, msg):
1824 prefix = "expected {}() called with data='{}', length='{}' to " \
1825 "generate the error '{}', generated" \
1826 .format(fn.__name__, data, length, msg)
1827 try:
1828 fn(data, length)
1829 fail(prefix + " no error")
1830 except dtlib.DTError as e:
1831 if str(e) != msg:
1832 fail("{} the error '{}'".format(prefix, e))
1833 except Exception as e:
1834 fail("{} the non-DTError '{}'".format(prefix, e))
1835
1836 verify_raw_to_num(dtlib.to_num, "u", None, False, 1)
1837 verify_raw_to_num(dtlib.to_num, "u", 4, False, 1)
1838 verify_raw_to_num(dtlib.to_num, "s", None, False, 0xFFFFFFFF)
1839 verify_raw_to_num(dtlib.to_num, "s", None, True, -1)
1840 verify_raw_to_num(dtlib.to_nums, "empty", 4, False, [])
1841 verify_raw_to_num(dtlib.to_nums, "u16", 2, False, [1, 2])
1842 verify_raw_to_num(dtlib.to_nums, "two_s", 4, False, [0xFFFFFFFF, 0xFFFFFFFE])
1843 verify_raw_to_num(dtlib.to_nums, "two_s", 4, True, [-1, -2])
Ulf Magnusson62d57412018-12-17 20:09:47 +01001844
1845 verify_raw_to_num_error(dtlib.to_num, 0, 0, "'0' has type 'int', expected 'bytes'")
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001846 verify_raw_to_num_error(dtlib.to_num, b"", 0, "'length' must be greater than zero, was 0")
Ulf Magnusson73df9de2019-08-15 11:46:44 +02001847 verify_raw_to_num_error(dtlib.to_num, b"foo", 2, "b'foo' is 3 bytes long, expected 2")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001848 verify_raw_to_num_error(dtlib.to_nums, 0, 0, "'0' has type 'int', expected 'bytes'")
Ulf Magnusson06b746c2019-08-09 20:38:17 +02001849 verify_raw_to_num_error(dtlib.to_nums, b"", 0, "'length' must be greater than zero, was 0")
Ulf Magnusson73df9de2019-08-15 11:46:44 +02001850 verify_raw_to_num_error(dtlib.to_nums, b"foooo", 2, "b'foooo' is 5 bytes long, expected a length that's a a multiple of 2")
Ulf Magnusson62d57412018-12-17 20:09:47 +01001851
1852 #
1853 # Test duplicate label error
1854 #
1855
1856 verify_error("""
1857/dts-v1/;
1858
1859/ {
1860 sub1 {
1861 label: foo {
1862 };
1863 };
1864
1865 sub2 {
1866 label: bar {
1867 };
1868 };
1869};
1870""",
1871"Label 'label' appears on /sub1/foo and on /sub2/bar")
1872
1873 verify_error("""
1874/dts-v1/;
1875
1876/ {
1877 sub {
1878 label: foo {
1879 };
1880 };
1881};
1882/ {
1883 sub {
1884 label: bar {
1885 };
1886 };
1887};
1888""",
1889"Label 'label' appears on /sub/bar and on /sub/foo")
1890
1891 verify_error("""
1892/dts-v1/;
1893
1894/ {
1895 foo: a = < 0 >;
1896 foo: node {
1897 };
1898};
1899""",
1900"Label 'foo' appears on /node and on property 'a' of node /")
1901
1902 verify_error("""
1903/dts-v1/;
1904
1905/ {
1906 foo: a = < 0 >;
1907 node {
1908 foo: b = < 0 >;
1909 };
1910};
1911""",
1912"Label 'foo' appears on property 'a' of node / and on property 'b' of node /node")
1913
1914 verify_error("""
1915/dts-v1/;
1916
1917/ {
1918 foo: a = foo: < 0 >;
1919};
1920""",
1921"Label 'foo' appears in the value of property 'a' of node / and on property 'a' of node /")
1922
1923 # Giving the same label twice for the same node is fine
1924 verify_parse("""
1925/dts-v1/;
1926
1927/ {
1928 sub {
1929 label: foo {
1930 };
1931 };
1932};
1933/ {
1934
1935 sub {
1936 label: foo {
1937 };
1938 };
1939};
1940""",
1941"""
1942/dts-v1/;
1943
1944/ {
1945 sub {
1946 label: foo {
1947 };
1948 };
1949};
1950""")
1951
1952 # Duplicate labels are fine if one of the nodes is deleted
1953 verify_parse("""
1954/dts-v1/;
1955
1956/ {
1957 label: foo {
1958 };
1959 label: bar {
1960 };
1961};
1962
1963/delete-node/ &{/bar};
1964""",
1965"""
1966/dts-v1/;
1967
1968/ {
1969 label: foo {
1970 };
1971};
1972""")
1973
1974 #
1975 # Test overriding/deleting a property with references
1976 #
1977
1978 verify_parse("""
1979/dts-v1/;
1980
1981/ {
1982 x = &foo, < &foo >;
1983 y = &foo, < &foo >;
1984 foo: foo {
1985 };
1986};
1987
1988/ {
1989 x = < 1 >;
1990 /delete-property/ y;
1991};
1992""",
1993"""
1994/dts-v1/;
1995
1996/ {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +02001997 x = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +01001998 foo: foo {
1999 };
2000};
2001""")
2002
2003 #
2004 # Test self-referential node
2005 #
2006
2007 verify_parse("""
2008/dts-v1/;
2009
2010/ {
2011 label: foo {
2012 x = &{/foo}, &label, < &label >;
2013 };
2014};
2015""",
2016"""
2017/dts-v1/;
2018
2019/ {
2020 label: foo {
Ulf Magnusson06b746c2019-08-09 20:38:17 +02002021 x = &{/foo}, &label, < &label >;
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +02002022 phandle = < 0x1 >;
Ulf Magnusson62d57412018-12-17 20:09:47 +01002023 };
2024};
2025""")
2026
2027 #
2028 # Test /memreserve/
2029 #
2030
2031 dt = verify_parse("""
2032/dts-v1/;
2033
2034l1: l2: /memreserve/ (1 + 1) (2 * 2);
2035/memreserve/ 0x100 0x200;
2036
2037/ {
2038};
2039""",
2040"""
2041/dts-v1/;
2042
2043l1: l2: /memreserve/ 0x0000000000000002 0x0000000000000004;
2044/memreserve/ 0x0000000000000100 0x0000000000000200;
2045
2046/ {
2047};
2048""")
2049
2050 expected = [(["l1", "l2"], 2, 4), ([], 0x100, 0x200)]
2051 if dt.memreserves != expected:
2052 fail("expected {} for dt.memreserve, got {}"
2053 .format(expected, dt.memreserves))
2054
Ulf Magnusson929837a2019-08-16 09:35:03 +02002055 verify_error("""
2056/dts-v1/;
2057
2058foo: / {
2059};
2060""",
2061".tmp.dts:3 (column 6): parse error: expected /memreserve/ after labels at beginning of file")
2062
Ulf Magnusson62d57412018-12-17 20:09:47 +01002063 #
2064 # Test __repr__() functions
2065 #
2066
2067 def verify_repr(obj, expected):
2068 if repr(obj) != expected:
2069 fail("expected repr() to be '{}', was '{}'"
2070 .format(expected, repr(obj)))
2071
2072 dt = parse("""
2073/dts-v1/;
2074
2075/ {
2076 x = < 0 >;
2077 sub {
2078 y = < 1 >;
2079 };
2080};
2081""",
2082 include_path=("foo", "bar"))
2083
2084 verify_repr(dt, "DT(filename='.tmp.dts', include_path=('foo', 'bar'))")
2085 verify_repr(dt.root.props["x"], "<Property 'x' at '/' in '.tmp.dts'>")
2086 verify_repr(dt.root.nodes["sub"], "<Node /sub in '.tmp.dts'>")
2087
2088 #
2089 # Test names
2090 #
2091
2092 # The C tools disallow '@' in property names, but otherwise accept the same
2093 # characters in node and property names. Emulate that instead of the DT spec
2094 # (v0.2), which gives different characters for nodes and properties.
2095 verify_parse(r"""
2096/dts-v1/;
2097
2098/ {
2099 // A leading \ is accepted but ignored in node/propert names
2100 \aA0,._+*#?- = &_, &{/aA0,._+*#?@-};
2101
Ulf Magnussonc2d702b2019-08-13 08:23:19 +02002102 // Names that overlap with operators and integer literals
2103
Ulf Magnusson62d57412018-12-17 20:09:47 +01002104 + = [ 00 ];
2105 * = [ 02 ];
2106 - = [ 01 ];
2107 ? = [ 03 ];
Ulf Magnussonc2d702b2019-08-13 08:23:19 +02002108 0 = [ 04 ];
2109 0x123 = [ 05 ];
Ulf Magnusson62d57412018-12-17 20:09:47 +01002110
2111 _: \aA0,._+*#?@- {
2112 };
Ulf Magnussonc2d702b2019-08-13 08:23:19 +02002113
2114 0 {
2115 };
Ulf Magnusson62d57412018-12-17 20:09:47 +01002116};
2117""",
2118"""
2119/dts-v1/;
2120
2121/ {
Ulf Magnusson06b746c2019-08-09 20:38:17 +02002122 aA0,._+*#?- = &_, &{/aA0,._+*#?@-};
Ulf Magnusson62d57412018-12-17 20:09:47 +01002123 + = [ 00 ];
2124 * = [ 02 ];
2125 - = [ 01 ];
2126 ? = [ 03 ];
Ulf Magnussonc2d702b2019-08-13 08:23:19 +02002127 0 = [ 04 ];
2128 0x123 = [ 05 ];
Ulf Magnusson62d57412018-12-17 20:09:47 +01002129 _: aA0,._+*#?@- {
2130 };
Ulf Magnussonc2d702b2019-08-13 08:23:19 +02002131 0 {
2132 };
Ulf Magnusson62d57412018-12-17 20:09:47 +01002133};
2134""")
2135
2136 verify_error(r"""
2137/dts-v1/;
2138
2139/ {
2140 foo@3;
2141};
2142""",
2143".tmp.dts:4 (column 7): parse error: '@' is only allowed in node names")
2144
2145 verify_error(r"""
2146/dts-v1/;
2147
2148/ {
2149 foo@3 = < 0 >;
2150};
2151""",
2152".tmp.dts:4 (column 8): parse error: '@' is only allowed in node names")
2153
2154 verify_error(r"""
2155/dts-v1/;
2156
2157/ {
2158 foo@2@3 {
2159 };
2160};
2161""",
2162".tmp.dts:4 (column 10): parse error: multiple '@' in node name")
2163
2164 #
2165 # Test bad formatting
2166 #
2167
2168 verify_parse("""
2169/dts-v1/;/{l1:l2:foo{l3:l4:bar{l5:x=l6:/bits/8<l7:1 l8:2>l9:,[03],"a";};};};
2170""",
2171"""
2172/dts-v1/;
2173
2174/ {
2175 l1: l2: foo {
2176 l3: l4: bar {
Ulf Magnussonc9ac5e62019-08-09 00:44:33 +02002177 l5: x = l6: [ l7: 01 l8: 02 l9: ], [ 03 ], "a";
Ulf Magnusson62d57412018-12-17 20:09:47 +01002178 };
2179 };
2180};
2181""")
2182
2183 #
2184 # Test misc. errors and non-errors
2185 #
2186
2187 verify_error("", ".tmp.dts:1 (column 1): parse error: expected '/dts-v1/;' at start of file")
2188
2189 verify_error("""
2190/dts-v1/;
2191""",
2192".tmp.dts:2 (column 1): parse error: no root node defined")
2193
2194 verify_error("""
2195/dts-v1/; /plugin/;
2196""",
2197".tmp.dts:1 (column 11): parse error: /plugin/ is not supported")
2198
2199 verify_error("""
2200/dts-v1/;
2201
2202/ {
2203 foo: foo {
2204 };
2205};
2206
2207// Only one label supported before label references at the top level
2208l1: l2: &foo {
2209};
2210""",
2211".tmp.dts:9 (column 5): parse error: expected label reference (&foo)")
2212
2213 verify_error("""
2214/dts-v1/;
2215
2216/ {
2217 foo: {};
2218};
2219""",
2220".tmp.dts:4 (column 14): parse error: expected node or property name")
2221
2222 # Multiple /dts-v1/ at the start of a file is fine
2223 verify_parse("""
2224/dts-v1/;
2225/dts-v1/;
2226
2227/ {
2228};
2229""",
2230"""
2231/dts-v1/;
2232
2233/ {
2234};
2235""")
2236
2237 print("all tests passed")
2238
2239 # Only remove these if tests succeed. They're handy to have around otherwise.
2240 shutil.rmtree(".tmp")
2241 shutil.rmtree(".tmp2")
2242 os.remove(".tmp.dts")
2243 os.remove(".tmp2.dts")
2244 os.remove(".tmp3.dts")
2245 os.remove(".tmp.bin")
2246
2247
2248if __name__ == "__main__":
2249 run()