@@ -56,6 +56,13 @@ def dict_constructor(loader, node, deep=False):
5656yaml .add_constructor (_mapping_tag , dict_constructor , yaml .SafeLoader )
5757
5858
59+ def get_spec (spec ):
60+ if spec .startswith ("?@" ):
61+ return spec [2 :], True
62+ else :
63+ return spec , False
64+
65+
5966def matchname (name , spec ):
6067 """Check if name matches against a specification."""
6168 if spec .startswith ("_" ):
@@ -646,6 +653,7 @@ def clear_fields(self, pspec):
646653 def process_peripheral (self , pspec , peripheral , update_fields = True ):
647654 """Work through a peripheral, handling all registers."""
648655 # Find all peripherals that match the spec
656+ pspec , ignore = get_spec (pspec )
649657 pcount = 0
650658 for ptag in self .iter_peripherals (pspec ):
651659 pcount += 1
@@ -763,7 +771,7 @@ def process_peripheral(self, pspec, peripheral, update_fields=True):
763771 cluster = peripheral ["_clusters" ][cspec ]
764772 p .process_cluster (cspec , cluster , update_fields )
765773
766- if pcount == 0 :
774+ if not ignore and pcount == 0 :
767775 raise MissingPeripheralError (f"Could not find { pspec } " )
768776
769777
@@ -1019,6 +1027,7 @@ def strip(self, substr, strip_end=False):
10191027 def collect_in_array (self , rspec , rmod ):
10201028 """Collect same registers in peripheral into register array."""
10211029 registers = []
1030+ rspec , ignore = get_spec (rspec )
10221031 li , ri = spec_ind (rspec )
10231032 for rtag in list (self .iter_registers (rspec )):
10241033 rname = rtag .findtext ("name" )
@@ -1031,6 +1040,8 @@ def collect_in_array(self, rspec, rmod):
10311040 )
10321041 dim = len (registers )
10331042 if dim == 0 :
1043+ if ignore :
1044+ return
10341045 raise SvdPatchError (
10351046 "{}: registers {} not found" .format (self .ptag .findtext ("name" ), rspec )
10361047 )
@@ -1087,6 +1098,7 @@ def collect_in_cluster(self, cname, cmod):
10871098 check = True
10881099 rspecs = [r for r in cmod if r != "description" ]
10891100 for rspec in rspecs :
1101+ rspec , ignore = get_spec (rspec )
10901102 registers = []
10911103 for rtag , match_rspec in list (self .iter_registers_with_matches (rspec )):
10921104 rname = rtag .findtext ("name" )
@@ -1098,14 +1110,17 @@ def collect_in_cluster(self, cname, cmod):
10981110 int (rtag .findtext ("addressOffset" ), 0 ),
10991111 ]
11001112 )
1113+ if len (registers ) == 0 :
1114+ if ignore :
1115+ continue
1116+ raise SvdPatchError (
1117+ "{}: registers {rspec} not found" .format (self .ptag .findtext ("name" ))
1118+ )
11011119 registers = sorted (registers , key = lambda r : r [2 ])
11021120 rdict [rspec ] = registers
11031121 bitmasks = [Register (r [0 ]).get_bitmask () for r in registers ]
11041122 if first :
11051123 dim = len (registers )
1106- if dim == 0 :
1107- check = False
1108- break
11091124 dimIndex = "," .join ([r [1 ] for r in registers ])
11101125 offsets = [r [2 ] for r in registers ]
11111126 dimIncrement = 0
@@ -1127,6 +1142,12 @@ def collect_in_cluster(self, cname, cmod):
11271142 check = False
11281143 break
11291144 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+ )
11301151 if not check :
11311152 raise SvdPatchError (
11321153 "{}: registers cannot be collected into {} cluster" .format (
@@ -1176,6 +1197,7 @@ def clear_fields(self, rspec):
11761197 def process_register (self , rspec , register , update_fields = True ):
11771198 """Work through a register, handling all fields."""
11781199 # Find all registers that match the spec
1200+ rspec , ignore = get_spec (rspec )
11791201 pname = self .ptag .find ("name" ).text
11801202 rcount = 0
11811203 for rtag in self .iter_registers (rspec ):
@@ -1228,7 +1250,7 @@ def process_register(self, rspec, register, update_fields=True):
12281250 for fspec in register .get ("_array" , {}):
12291251 fmod = register ["_array" ][fspec ]
12301252 r .collect_fields_in_array (fspec , fmod )
1231- if rcount == 0 :
1253+ if not ignore and rcount == 0 :
12321254 raise MissingRegisterError (f"Could not find { pname } :{ rspec } " )
12331255
12341256 def process_cluster_tag (
@@ -1266,12 +1288,13 @@ def process_cluster(
12661288 assert isinstance (cspec , str )
12671289 assert isinstance (cluster , OrderedDict )
12681290 assert isinstance (update_fields , bool )
1291+ cspec , ignore = get_spec (cspec )
12691292 # Find all clusters that match the spec
12701293 ccount = 0
12711294 for ctag in self .iter_clusters (cspec ):
12721295 self .process_cluster_tag (ctag , cluster , update_fields )
12731296 ccount += 1
1274- if ccount == 0 :
1297+ if not ignore and ccount == 0 :
12751298 raise MissingClusterError (f"Could not find { self .name } :{ cspec } " )
12761299
12771300
@@ -1467,6 +1490,7 @@ def merge_fields(self, key, value):
14671490 Merge all fspec in rtag.
14681491 Support list of field to auto-merge, and dict with fspec or list of fspec
14691492 """
1493+ fspec , ignore = get_spec (fspec )
14701494 if isinstance (value , str ):
14711495 fields = list (self .iter_fields (value ))
14721496 name = key
@@ -1482,6 +1506,8 @@ def merge_fields(self, key, value):
14821506 fields = list (self .iter_fields (key ))
14831507 name = os .path .commonprefix ([f .find ("name" ).text for f in fields ])
14841508 if len (fields ) == 0 :
1509+ if ignore :
1510+ return
14851511 rname = self .rtag .find ("name" ).text
14861512 raise RegisterMergeError (
14871513 f"Could not find any fields to merge { rname } .{ fspec } "
@@ -1501,6 +1527,7 @@ def merge_fields(self, key, value):
15011527 def collect_fields_in_array (self , fspec , fmod ):
15021528 """Collect same fields in peripheral into register array."""
15031529 fields = []
1530+ fspec , ignore = get_spec (fspec )
15041531 li , ri = spec_ind (fspec )
15051532 for ftag in list (self .iter_fields (fspec )):
15061533 fname = ftag .findtext ("name" )
@@ -1509,6 +1536,8 @@ def collect_fields_in_array(self, fspec, fmod):
15091536 )
15101537 dim = len (fields )
15111538 if dim == 0 :
1539+ if ignore :
1540+ return
15121541 raise SvdPatchError (
15131542 "{}: fields {} not found" .format (self .rtag .findtext ("name" ), fspec )
15141543 )
@@ -1559,8 +1588,11 @@ def split_fields(self, fspec, fsplit):
15591588 Split all fspec in rtag.
15601589 Name and description can be customized with %s as a placeholder to the iterator value.
15611590 """
1591+ fspec , ignore = get_spec (fspec )
15621592 fields = list (self .iter_fields (fspec ))
15631593 if len (fields ) == 0 :
1594+ if ignore :
1595+ return
15641596 rname = self .rtag .find ("name" ).text
15651597 raise RegisterMergeError (
15661598 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"):
16661698 field = field ["_replace_enum" ]
16671699 replace_if_exists = True
16681700
1701+ fspec , ignore = get_spec (fspec )
1702+
16691703 derived , enum , enum_name , enum_usage = None , None , None , None
16701704 for ftag in sorted_fields (list (self .iter_fields (fspec ))):
16711705 if "_derivedFrom" in field :
@@ -1719,17 +1753,18 @@ def process_field_enum(self, pname, fspec, field, usage="read-write"):
17191753 derived = enum_name
17201754 else :
17211755 ftag .append (make_derived_enumerated_values (derived ))
1722- if derived is None :
1756+ if not ignore and derived is None :
17231757 rname = self .rtag .find ("name" ).text
17241758 raise MissingFieldError (f"Could not find { pname } :{ rname } .{ fspec } " )
17251759
17261760 def process_field_range (self , pname , fspec , field ):
17271761 """Add a writeConstraint range given by field to all fspec in rtag."""
1762+ fspec , ignore = get_spec (fspec )
17281763 set_any = False
17291764 for ftag in self .iter_fields (fspec ):
17301765 ftag .append (make_write_constraint (field ))
17311766 set_any = True
1732- if not set_any :
1767+ if not ignore and not set_any :
17331768 rname = self .rtag .find ("name" ).text
17341769 raise MissingFieldError (f"Could not find { pname } :{ rname } .{ fspec } " )
17351770
0 commit comments