@@ -56,6 +56,13 @@ def dict_constructor(loader, node, deep=False):
56
56
yaml .add_constructor (_mapping_tag , dict_constructor , yaml .SafeLoader )
57
57
58
58
59
+ def get_spec (spec ):
60
+ if spec .startswith ("?@" ):
61
+ return spec [2 :], True
62
+ else :
63
+ return spec , False
64
+
65
+
59
66
def matchname (name , spec ):
60
67
"""Check if name matches against a specification."""
61
68
if spec .startswith ("_" ):
@@ -646,6 +653,7 @@ def clear_fields(self, pspec):
646
653
def process_peripheral (self , pspec , peripheral , update_fields = True ):
647
654
"""Work through a peripheral, handling all registers."""
648
655
# Find all peripherals that match the spec
656
+ pspec , ignore = get_spec (pspec )
649
657
pcount = 0
650
658
for ptag in self .iter_peripherals (pspec ):
651
659
pcount += 1
@@ -763,7 +771,7 @@ def process_peripheral(self, pspec, peripheral, update_fields=True):
763
771
cluster = peripheral ["_clusters" ][cspec ]
764
772
p .process_cluster (cspec , cluster , update_fields )
765
773
766
- if pcount == 0 :
774
+ if not ignore and pcount == 0 :
767
775
raise MissingPeripheralError (f"Could not find { pspec } " )
768
776
769
777
@@ -1019,6 +1027,7 @@ def strip(self, substr, strip_end=False):
1019
1027
def collect_in_array (self , rspec , rmod ):
1020
1028
"""Collect same registers in peripheral into register array."""
1021
1029
registers = []
1030
+ rspec , ignore = get_spec (rspec )
1022
1031
li , ri = spec_ind (rspec )
1023
1032
for rtag in list (self .iter_registers (rspec )):
1024
1033
rname = rtag .findtext ("name" )
@@ -1031,6 +1040,8 @@ def collect_in_array(self, rspec, rmod):
1031
1040
)
1032
1041
dim = len (registers )
1033
1042
if dim == 0 :
1043
+ if ignore :
1044
+ return
1034
1045
raise SvdPatchError (
1035
1046
"{}: registers {} not found" .format (self .ptag .findtext ("name" ), rspec )
1036
1047
)
@@ -1087,6 +1098,7 @@ def collect_in_cluster(self, cname, cmod):
1087
1098
check = True
1088
1099
rspecs = [r for r in cmod if r != "description" ]
1089
1100
for rspec in rspecs :
1101
+ rspec , ignore = get_spec (rspec )
1090
1102
registers = []
1091
1103
for rtag , match_rspec in list (self .iter_registers_with_matches (rspec )):
1092
1104
rname = rtag .findtext ("name" )
@@ -1098,14 +1110,17 @@ def collect_in_cluster(self, cname, cmod):
1098
1110
int (rtag .findtext ("addressOffset" ), 0 ),
1099
1111
]
1100
1112
)
1113
+ if len (registers ) == 0 :
1114
+ if ignore :
1115
+ continue
1116
+ raise SvdPatchError (
1117
+ "{}: registers {rspec} not found" .format (self .ptag .findtext ("name" ))
1118
+ )
1101
1119
registers = sorted (registers , key = lambda r : r [2 ])
1102
1120
rdict [rspec ] = registers
1103
1121
bitmasks = [Register (r [0 ]).get_bitmask () for r in registers ]
1104
1122
if first :
1105
1123
dim = len (registers )
1106
- if dim == 0 :
1107
- check = False
1108
- break
1109
1124
dimIndex = "," .join ([r [1 ] for r in registers ])
1110
1125
offsets = [r [2 ] for r in registers ]
1111
1126
dimIncrement = 0
@@ -1127,6 +1142,12 @@ def collect_in_cluster(self, cname, cmod):
1127
1142
check = False
1128
1143
break
1129
1144
first = False
1145
+ if not rdict :
1146
+ raise SvdPatchError (
1147
+ "{}: registers cannot be collected into {} cluster. No matches found" .format (
1148
+ self .ptag .findtext ("name" ), cname
1149
+ )
1150
+ )
1130
1151
if not check :
1131
1152
raise SvdPatchError (
1132
1153
"{}: registers cannot be collected into {} cluster" .format (
@@ -1176,6 +1197,7 @@ def clear_fields(self, rspec):
1176
1197
def process_register (self , rspec , register , update_fields = True ):
1177
1198
"""Work through a register, handling all fields."""
1178
1199
# Find all registers that match the spec
1200
+ rspec , ignore = get_spec (rspec )
1179
1201
pname = self .ptag .find ("name" ).text
1180
1202
rcount = 0
1181
1203
for rtag in self .iter_registers (rspec ):
@@ -1228,7 +1250,7 @@ def process_register(self, rspec, register, update_fields=True):
1228
1250
for fspec in register .get ("_array" , {}):
1229
1251
fmod = register ["_array" ][fspec ]
1230
1252
r .collect_fields_in_array (fspec , fmod )
1231
- if rcount == 0 :
1253
+ if not ignore and rcount == 0 :
1232
1254
raise MissingRegisterError (f"Could not find { pname } :{ rspec } " )
1233
1255
1234
1256
def process_cluster_tag (
@@ -1266,12 +1288,13 @@ def process_cluster(
1266
1288
assert isinstance (cspec , str )
1267
1289
assert isinstance (cluster , OrderedDict )
1268
1290
assert isinstance (update_fields , bool )
1291
+ cspec , ignore = get_spec (cspec )
1269
1292
# Find all clusters that match the spec
1270
1293
ccount = 0
1271
1294
for ctag in self .iter_clusters (cspec ):
1272
1295
self .process_cluster_tag (ctag , cluster , update_fields )
1273
1296
ccount += 1
1274
- if ccount == 0 :
1297
+ if not ignore and ccount == 0 :
1275
1298
raise MissingClusterError (f"Could not find { self .name } :{ cspec } " )
1276
1299
1277
1300
@@ -1467,6 +1490,7 @@ def merge_fields(self, key, value):
1467
1490
Merge all fspec in rtag.
1468
1491
Support list of field to auto-merge, and dict with fspec or list of fspec
1469
1492
"""
1493
+ fspec , ignore = get_spec (fspec )
1470
1494
if isinstance (value , str ):
1471
1495
fields = list (self .iter_fields (value ))
1472
1496
name = key
@@ -1482,6 +1506,8 @@ def merge_fields(self, key, value):
1482
1506
fields = list (self .iter_fields (key ))
1483
1507
name = os .path .commonprefix ([f .find ("name" ).text for f in fields ])
1484
1508
if len (fields ) == 0 :
1509
+ if ignore :
1510
+ return
1485
1511
rname = self .rtag .find ("name" ).text
1486
1512
raise RegisterMergeError (
1487
1513
f"Could not find any fields to merge { rname } .{ fspec } "
@@ -1501,6 +1527,7 @@ def merge_fields(self, key, value):
1501
1527
def collect_fields_in_array (self , fspec , fmod ):
1502
1528
"""Collect same fields in peripheral into register array."""
1503
1529
fields = []
1530
+ fspec , ignore = get_spec (fspec )
1504
1531
li , ri = spec_ind (fspec )
1505
1532
for ftag in list (self .iter_fields (fspec )):
1506
1533
fname = ftag .findtext ("name" )
@@ -1509,6 +1536,8 @@ def collect_fields_in_array(self, fspec, fmod):
1509
1536
)
1510
1537
dim = len (fields )
1511
1538
if dim == 0 :
1539
+ if ignore :
1540
+ return
1512
1541
raise SvdPatchError (
1513
1542
"{}: fields {} not found" .format (self .rtag .findtext ("name" ), fspec )
1514
1543
)
@@ -1559,8 +1588,11 @@ def split_fields(self, fspec, fsplit):
1559
1588
Split all fspec in rtag.
1560
1589
Name and description can be customized with %s as a placeholder to the iterator value.
1561
1590
"""
1591
+ fspec , ignore = get_spec (fspec )
1562
1592
fields = list (self .iter_fields (fspec ))
1563
1593
if len (fields ) == 0 :
1594
+ if ignore :
1595
+ return
1564
1596
rname = self .rtag .find ("name" ).text
1565
1597
raise RegisterMergeError (
1566
1598
f"Could not find any fields to split { rname } .{ fspec } "
@@ -1666,6 +1698,8 @@ def process_field_enum(self, pname, fspec, field, usage="read-write"):
1666
1698
field = field ["_replace_enum" ]
1667
1699
replace_if_exists = True
1668
1700
1701
+ fspec , ignore = get_spec (fspec )
1702
+
1669
1703
derived , enum , enum_name , enum_usage = None , None , None , None
1670
1704
for ftag in sorted_fields (list (self .iter_fields (fspec ))):
1671
1705
if "_derivedFrom" in field :
@@ -1719,17 +1753,18 @@ def process_field_enum(self, pname, fspec, field, usage="read-write"):
1719
1753
derived = enum_name
1720
1754
else :
1721
1755
ftag .append (make_derived_enumerated_values (derived ))
1722
- if derived is None :
1756
+ if not ignore and derived is None :
1723
1757
rname = self .rtag .find ("name" ).text
1724
1758
raise MissingFieldError (f"Could not find { pname } :{ rname } .{ fspec } " )
1725
1759
1726
1760
def process_field_range (self , pname , fspec , field ):
1727
1761
"""Add a writeConstraint range given by field to all fspec in rtag."""
1762
+ fspec , ignore = get_spec (fspec )
1728
1763
set_any = False
1729
1764
for ftag in self .iter_fields (fspec ):
1730
1765
ftag .append (make_write_constraint (field ))
1731
1766
set_any = True
1732
- if not set_any :
1767
+ if not ignore and not set_any :
1733
1768
rname = self .rtag .find ("name" ).text
1734
1769
raise MissingFieldError (f"Could not find { pname } :{ rname } .{ fspec } " )
1735
1770
0 commit comments