Skip to content

Commit 68027da

Browse files
committed
python
1 parent 286e812 commit 68027da

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

CHANGELOG-python.md

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ This changelog tracks the Python `svdtools` project. See
55

66
## [Unreleased]
77

8+
* Ignore rule if starts with "?@" and no matched instances
9+
810
## [v0.1.26] 2023-03-28
911

1012
* Bump python to 3.9 to fix CI

src/patch/peripheral.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,11 @@ fn collect_in_cluster(
13551355
}
13561356
rdict.insert(rspec.to_string(), registers);
13571357
}
1358+
if rdict.is_empty() {
1359+
return Err(anyhow!(
1360+
"{path}: registers cannot be collected into {cname} cluster. No matches found"
1361+
));
1362+
}
13581363
let address_offset = rdict
13591364
.values()
13601365
.min_by_key(|rs| rs[0].address_offset)

svdtools/patch.py

+40-8
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ def dict_constructor(loader, node, deep=False):
5656
yaml.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+
5966
def 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

@@ -1501,6 +1524,7 @@ def merge_fields(self, key, value):
15011524
def collect_fields_in_array(self, fspec, fmod):
15021525
"""Collect same fields in peripheral into register array."""
15031526
fields = []
1527+
fspec, ignore = get_spec(fspec)
15041528
li, ri = spec_ind(fspec)
15051529
for ftag in list(self.iter_fields(fspec)):
15061530
fname = ftag.findtext("name")
@@ -1509,6 +1533,8 @@ def collect_fields_in_array(self, fspec, fmod):
15091533
)
15101534
dim = len(fields)
15111535
if dim == 0:
1536+
if ignore:
1537+
return
15121538
raise SvdPatchError(
15131539
"{}: fields {} not found".format(self.rtag.findtext("name"), fspec)
15141540
)
@@ -1559,8 +1585,11 @@ def split_fields(self, fspec, fsplit):
15591585
Split all fspec in rtag.
15601586
Name and description can be customized with %s as a placeholder to the iterator value.
15611587
"""
1588+
fspec, ignore = get_spec(fspec)
15621589
fields = list(self.iter_fields(fspec))
15631590
if len(fields) == 0:
1591+
if ignore:
1592+
return
15641593
rname = self.rtag.find("name").text
15651594
raise RegisterMergeError(
15661595
f"Could not find any fields to split {rname}.{fspec}"
@@ -1666,6 +1695,8 @@ def process_field_enum(self, pname, fspec, field, usage="read-write"):
16661695
field = field["_replace_enum"]
16671696
replace_if_exists = True
16681697

1698+
fspec, ignore = get_spec(fspec)
1699+
16691700
derived, enum, enum_name, enum_usage = None, None, None, None
16701701
for ftag in sorted_fields(list(self.iter_fields(fspec))):
16711702
if "_derivedFrom" in field:
@@ -1719,17 +1750,18 @@ def process_field_enum(self, pname, fspec, field, usage="read-write"):
17191750
derived = enum_name
17201751
else:
17211752
ftag.append(make_derived_enumerated_values(derived))
1722-
if derived is None:
1753+
if not ignore and derived is None:
17231754
rname = self.rtag.find("name").text
17241755
raise MissingFieldError(f"Could not find {pname}:{rname}.{fspec}")
17251756

17261757
def process_field_range(self, pname, fspec, field):
17271758
"""Add a writeConstraint range given by field to all fspec in rtag."""
1759+
fspec, ignore = get_spec(fspec)
17281760
set_any = False
17291761
for ftag in self.iter_fields(fspec):
17301762
ftag.append(make_write_constraint(field))
17311763
set_any = True
1732-
if not set_any:
1764+
if not ignore and not set_any:
17331765
rname = self.rtag.find("name").text
17341766
raise MissingFieldError(f"Could not find {pname}:{rname}.{fspec}")
17351767

0 commit comments

Comments
 (0)