Skip to content

Commit

Permalink
python
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Oct 26, 2023
1 parent 286e812 commit 68027da
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG-python.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ This changelog tracks the Python `svdtools` project. See

## [Unreleased]

* Ignore rule if starts with "?@" and no matched instances

## [v0.1.26] 2023-03-28

* Bump python to 3.9 to fix CI
Expand Down
5 changes: 5 additions & 0 deletions src/patch/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,11 @@ fn collect_in_cluster(
}
rdict.insert(rspec.to_string(), registers);
}
if rdict.is_empty() {
return Err(anyhow!(
"{path}: registers cannot be collected into {cname} cluster. No matches found"
));
}
let address_offset = rdict
.values()
.min_by_key(|rs| rs[0].address_offset)
Expand Down
48 changes: 40 additions & 8 deletions svdtools/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ def dict_constructor(loader, node, deep=False):
yaml.add_constructor(_mapping_tag, dict_constructor, yaml.SafeLoader)


def get_spec(spec):
if spec.startswith("?@"):
return spec[2:], True
else:
return spec, False


def matchname(name, spec):
"""Check if name matches against a specification."""
if spec.startswith("_"):
Expand Down Expand Up @@ -646,6 +653,7 @@ def clear_fields(self, pspec):
def process_peripheral(self, pspec, peripheral, update_fields=True):
"""Work through a peripheral, handling all registers."""
# Find all peripherals that match the spec
pspec, ignore = get_spec(pspec)
pcount = 0
for ptag in self.iter_peripherals(pspec):
pcount += 1
Expand Down Expand Up @@ -763,7 +771,7 @@ def process_peripheral(self, pspec, peripheral, update_fields=True):
cluster = peripheral["_clusters"][cspec]
p.process_cluster(cspec, cluster, update_fields)

if pcount == 0:
if not ignore and pcount == 0:
raise MissingPeripheralError(f"Could not find {pspec}")


Expand Down Expand Up @@ -1019,6 +1027,7 @@ def strip(self, substr, strip_end=False):
def collect_in_array(self, rspec, rmod):
"""Collect same registers in peripheral into register array."""
registers = []
rspec, ignore = get_spec(rspec)
li, ri = spec_ind(rspec)
for rtag in list(self.iter_registers(rspec)):
rname = rtag.findtext("name")
Expand All @@ -1031,6 +1040,8 @@ def collect_in_array(self, rspec, rmod):
)
dim = len(registers)
if dim == 0:
if ignore:
return
raise SvdPatchError(
"{}: registers {} not found".format(self.ptag.findtext("name"), rspec)
)
Expand Down Expand Up @@ -1087,6 +1098,7 @@ def collect_in_cluster(self, cname, cmod):
check = True
rspecs = [r for r in cmod if r != "description"]
for rspec in rspecs:
rspec, ignore = get_spec(rspec)
registers = []
for rtag, match_rspec in list(self.iter_registers_with_matches(rspec)):
rname = rtag.findtext("name")
Expand All @@ -1098,14 +1110,17 @@ def collect_in_cluster(self, cname, cmod):
int(rtag.findtext("addressOffset"), 0),
]
)
if len(registers) == 0:
if ignore:
continue
raise SvdPatchError(
"{}: registers {rspec} not found".format(self.ptag.findtext("name"))
)
registers = sorted(registers, key=lambda r: r[2])
rdict[rspec] = registers
bitmasks = [Register(r[0]).get_bitmask() for r in registers]
if first:
dim = len(registers)
if dim == 0:
check = False
break
dimIndex = ",".join([r[1] for r in registers])
offsets = [r[2] for r in registers]
dimIncrement = 0
Expand All @@ -1127,6 +1142,12 @@ def collect_in_cluster(self, cname, cmod):
check = False
break
first = False
if not rdict:
raise SvdPatchError(
"{}: registers cannot be collected into {} cluster. No matches found".format(
self.ptag.findtext("name"), cname
)
)
if not check:
raise SvdPatchError(
"{}: registers cannot be collected into {} cluster".format(
Expand Down Expand Up @@ -1176,6 +1197,7 @@ def clear_fields(self, rspec):
def process_register(self, rspec, register, update_fields=True):
"""Work through a register, handling all fields."""
# Find all registers that match the spec
rspec, ignore = get_spec(rspec)
pname = self.ptag.find("name").text
rcount = 0
for rtag in self.iter_registers(rspec):
Expand Down Expand Up @@ -1228,7 +1250,7 @@ def process_register(self, rspec, register, update_fields=True):
for fspec in register.get("_array", {}):
fmod = register["_array"][fspec]
r.collect_fields_in_array(fspec, fmod)
if rcount == 0:
if not ignore and rcount == 0:
raise MissingRegisterError(f"Could not find {pname}:{rspec}")

def process_cluster_tag(
Expand Down Expand Up @@ -1266,12 +1288,13 @@ def process_cluster(
assert isinstance(cspec, str)
assert isinstance(cluster, OrderedDict)
assert isinstance(update_fields, bool)
cspec, ignore = get_spec(cspec)
# Find all clusters that match the spec
ccount = 0
for ctag in self.iter_clusters(cspec):
self.process_cluster_tag(ctag, cluster, update_fields)
ccount += 1
if ccount == 0:
if not ignore and ccount == 0:
raise MissingClusterError(f"Could not find {self.name}:{cspec}")


Expand Down Expand Up @@ -1501,6 +1524,7 @@ def merge_fields(self, key, value):
def collect_fields_in_array(self, fspec, fmod):
"""Collect same fields in peripheral into register array."""
fields = []
fspec, ignore = get_spec(fspec)
li, ri = spec_ind(fspec)
for ftag in list(self.iter_fields(fspec)):
fname = ftag.findtext("name")
Expand All @@ -1509,6 +1533,8 @@ def collect_fields_in_array(self, fspec, fmod):
)
dim = len(fields)
if dim == 0:
if ignore:
return
raise SvdPatchError(
"{}: fields {} not found".format(self.rtag.findtext("name"), fspec)
)
Expand Down Expand Up @@ -1559,8 +1585,11 @@ def split_fields(self, fspec, fsplit):
Split all fspec in rtag.
Name and description can be customized with %s as a placeholder to the iterator value.
"""
fspec, ignore = get_spec(fspec)
fields = list(self.iter_fields(fspec))
if len(fields) == 0:
if ignore:
return
rname = self.rtag.find("name").text
raise RegisterMergeError(
f"Could not find any fields to split {rname}.{fspec}"
Expand Down Expand Up @@ -1666,6 +1695,8 @@ def process_field_enum(self, pname, fspec, field, usage="read-write"):
field = field["_replace_enum"]
replace_if_exists = True

fspec, ignore = get_spec(fspec)

derived, enum, enum_name, enum_usage = None, None, None, None
for ftag in sorted_fields(list(self.iter_fields(fspec))):
if "_derivedFrom" in field:
Expand Down Expand Up @@ -1719,17 +1750,18 @@ def process_field_enum(self, pname, fspec, field, usage="read-write"):
derived = enum_name
else:
ftag.append(make_derived_enumerated_values(derived))
if derived is None:
if not ignore and derived is None:
rname = self.rtag.find("name").text
raise MissingFieldError(f"Could not find {pname}:{rname}.{fspec}")

def process_field_range(self, pname, fspec, field):
"""Add a writeConstraint range given by field to all fspec in rtag."""
fspec, ignore = get_spec(fspec)
set_any = False
for ftag in self.iter_fields(fspec):
ftag.append(make_write_constraint(field))
set_any = True
if not set_any:
if not ignore and not set_any:
rname = self.rtag.find("name").text
raise MissingFieldError(f"Could not find {pname}:{rname}.{fspec}")

Expand Down

0 comments on commit 68027da

Please sign in to comment.