Skip to content

Commit dbc339b

Browse files
committed
Ext::KEYWORDS
1 parent 7622981 commit dbc339b

File tree

6 files changed

+160
-97
lines changed

6 files changed

+160
-97
lines changed

CHANGELOG-rust.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This changelog tracks the Rust `svdtools` project. See
88
* Allow to modify registers in `_cluster:`
99
* Add addressOffset check in `collect_in_cluster`
1010
* Refactor `RegisterBlockExt`, use `BlockPath` for better errors
11+
* Allow specs started with `_`
1112

1213
## [v0.3.11] 2024-03-06
1314

src/patch/device.rs

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,25 @@ pub type PerMatchIterMut<'a, 'b> = MatchIter<'b, std::slice::IterMut<'a, Periphe
1717

1818
/// Collecting methods for processing device contents
1919
pub trait DeviceExt {
20+
const KEYWORDS: &'static [&'static str] = &[
21+
"_svd",
22+
"_include",
23+
"_path",
24+
"_delete",
25+
"_copy",
26+
"_modify",
27+
"_clear_fields",
28+
"_add",
29+
"_derive",
30+
"_rebase",
31+
];
32+
2033
/// Iterates over all peripherals that match pspec
2134
fn iter_peripherals<'a, 'b>(&'a mut self, spec: &'b str) -> PerMatchIterMut<'a, 'b>;
2235

36+
/// Returns string of present peripherals
37+
fn present_peripherals(&self) -> String;
38+
2339
/// Work through a device, handling all peripherals
2440
fn process(&mut self, device: &Hash, config: &Config) -> PatchResult;
2541

@@ -63,6 +79,10 @@ impl DeviceExt for Device {
6379
self.peripherals.iter_mut().matched(spec)
6480
}
6581

82+
fn present_peripherals(&self) -> String {
83+
self.peripherals.iter().map(|p| p.name.as_str()).join(", ")
84+
}
85+
6686
fn process(&mut self, device: &Hash, config: &Config) -> PatchResult {
6787
// Handle any deletions
6888
for pspec in device.str_vec_iter("_delete")? {
@@ -182,13 +202,19 @@ impl DeviceExt for Device {
182202
.with_context(|| format!("Parsing file {contents}"))?;
183203
filedev
184204
.get_peripheral(pcopyname)
185-
.ok_or_else(|| anyhow!("peripheral {pcopyname} not found"))?
205+
.ok_or_else(|| {
206+
let present = self.present_peripherals();
207+
anyhow!("peripheral {pcopyname} not found. Present peripherals: {present}.")
208+
})?
186209
.clone()
187210
}
188211
[pcopyname] => {
189212
let mut new = self
190213
.get_peripheral(pcopyname)
191-
.ok_or_else(|| anyhow!("peripheral {pcopyname} not found"))?
214+
.ok_or_else(|| {
215+
let present = self.present_peripherals();
216+
anyhow!("peripheral {pcopyname} not found. Present peripherals: {present}.")
217+
})?
192218
.clone();
193219
// When copying from a peripheral in the same file, remove any interrupts.
194220
new.interrupt = Vec::new();
@@ -313,7 +339,10 @@ impl DeviceExt for Device {
313339
.enumerate()
314340
.find(|(_, f)| f.name == pderive)
315341
else {
316-
return Err(anyhow!("peripheral {pderive} not found"));
342+
let present = self.present_peripherals();
343+
return Err(anyhow!(
344+
"peripheral {pderive} not found. Present peripherals: {present}."
345+
));
317346
};
318347
Some(i)
319348
} else {
@@ -416,22 +445,19 @@ impl DeviceExt for Device {
416445
peripheral: &Hash,
417446
config: &Config,
418447
) -> PatchResult {
419-
// Find all peripherals that match the spec
420-
let mut pcount = 0;
421448
let (pspec, ignore) = pspec.spec();
422-
for ptag in self.iter_peripherals(pspec) {
423-
pcount += 1;
449+
let ptags = self.iter_peripherals(pspec).collect::<Vec<_>>();
450+
if ptags.is_empty() && !ignore {
451+
let present = self.present_peripherals();
452+
return Err(anyhow!(
453+
"Could not find `{pspec}. Present peripherals: {present}.`"
454+
));
455+
}
456+
for ptag in ptags {
424457
ptag.process(peripheral, config)
425458
.with_context(|| format!("Processing peripheral `{}`", ptag.name))?;
426459
}
427-
if !ignore && pcount == 0 {
428-
Err(anyhow!(
429-
"Could not find `{pspec}. Present peripherals: {}.`",
430-
self.peripherals.iter().map(|p| p.name.as_str()).join(", ")
431-
))
432-
} else {
433-
Ok(())
434-
}
460+
Ok(())
435461
}
436462
}
437463

src/patch/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ fn make_address_block(h: &Hash) -> Result<AddressBlockBuilder> {
382382

383383
fn make_dim_element(h: &Hash) -> Result<Option<DimElementBuilder>> {
384384
let mut d = DimElement::builder()
385-
.dim_index(if let Some(y) = h.get(&"dimIndex".to_yaml()) {
385+
.dim_index(if let Some(y) = h.get_yaml("dimIndex") {
386386
match y {
387387
Yaml::String(text) => Some(DimElement::parse_indexes(text).ok_or(DimIndexParse)?),
388388
Yaml::Array(a) => {
@@ -492,8 +492,8 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
492492
}
493493

494494
if let Some(write_constraint) = radd
495-
.get(&"_write_constraint".to_yaml())
496-
.or_else(|| radd.get(&"writeConstraint".to_yaml()))
495+
.get_yaml("_write_constraint")
496+
.or_else(|| radd.get_yaml("writeConstraint"))
497497
{
498498
let wc = match write_constraint {
499499
Yaml::String(s) if s == "none" => {

src/patch/peripheral.rs

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,42 @@ pub type RegMatchIterMut<'a, 'b> = MatchIter<'b, RegisterIterMut<'a>>;
2525

2626
/// Collecting methods for processing peripheral contents
2727
pub(crate) trait PeripheralExt: InterruptExt + RegisterBlockExt {
28+
const KEYWORDS: &'static [&'static str] = &[
29+
"_include",
30+
"_path",
31+
"_delete",
32+
"_copy",
33+
"_strip",
34+
"_strip_end",
35+
"_modify",
36+
"_clear_fields",
37+
"_add",
38+
"_derive",
39+
"_expand_array",
40+
"_expand_cluster",
41+
"_array",
42+
"_cluster",
43+
"_clusters",
44+
"_interrupts",
45+
];
46+
2847
/// Work through a peripheral, handling all registers
2948
fn process(&mut self, peripheral: &Hash, config: &Config) -> PatchResult;
3049
}
3150

3251
/// Collecting methods for processing cluster contents
3352
pub(crate) trait ClusterExt: RegisterBlockExt {
3453
const KEYWORDS: &'static [&'static str] = &[
35-
"_add",
36-
"_copy",
54+
"_include",
55+
"_path",
3756
"_delete",
38-
"_derive",
39-
"_modify",
57+
"_copy",
4058
"_strip",
4159
"_strip_end",
60+
"_modify",
61+
"_clear_fields",
62+
"_add",
63+
"_derive",
4264
"_expand_array",
4365
"_expand_cluster",
4466
"_array",
@@ -593,7 +615,7 @@ impl PeripheralExt for Peripheral {
593615
let ppath = BlockPath::new(&self.name);
594616

595617
// Handle deletions
596-
if let Some(deletions) = pmod.get(&"_delete".to_yaml()) {
618+
if let Some(deletions) = pmod.get_yaml("_delete") {
597619
match deletions {
598620
Yaml::String(rspec) => {
599621
self.delete_register(rspec)
@@ -776,10 +798,11 @@ impl PeripheralExt for Peripheral {
776798
// Handle registers
777799
for (rspec, register) in pmod {
778800
let rspec = rspec.str()?;
779-
if !rspec.starts_with('_') {
780-
self.process_register(rspec, register.hash()?, &ppath, config)
781-
.with_context(|| format!("According to `{rspec}`"))?;
801+
if Self::KEYWORDS.contains(&rspec) {
802+
continue;
782803
}
804+
self.process_register(rspec, register.hash()?, &ppath, config)
805+
.with_context(|| format!("According to `{rspec}`"))?;
783806
}
784807

785808
// Expand register arrays
@@ -805,10 +828,8 @@ impl PeripheralExt for Peripheral {
805828
// Handle clusters
806829
for (cspec, cluster) in pmod.hash_iter("_clusters") {
807830
let cspec = cspec.str()?;
808-
if !cspec.starts_with('_') {
809-
self.process_cluster(cspec, cluster.hash()?, &ppath, config)
810-
.with_context(|| format!("According to `{cspec}`"))?;
811-
}
831+
self.process_cluster(cspec, cluster.hash()?, &ppath, config)
832+
.with_context(|| format!("According to `{cspec}`"))?;
812833
}
813834

814835
Ok(())
@@ -851,7 +872,7 @@ impl InterruptExt for Peripheral {
851872
impl ClusterExt for Cluster {
852873
fn pre_process(&mut self, cmod: &Hash, parent: &BlockPath, _config: &Config) -> PatchResult {
853874
// Handle deletions
854-
if let Some(deletions) = cmod.get(&"_delete".to_yaml()) {
875+
if let Some(deletions) = cmod.get_yaml("_delete") {
855876
match deletions {
856877
Yaml::String(rspec) => {
857878
self.delete_register(rspec)
@@ -1025,19 +1046,18 @@ impl ClusterExt for Cluster {
10251046
// Handle clusters
10261047
for (cspec, cluster) in cmod.hash_iter("_clusters") {
10271048
let cspec = cspec.str()?;
1028-
if !cspec.starts_with('_') {
1029-
self.process_cluster(cspec, cluster.hash()?, &cpath, config)
1030-
.with_context(|| format!("According to `{cspec}`"))?;
1031-
}
1049+
self.process_cluster(cspec, cluster.hash()?, &cpath, config)
1050+
.with_context(|| format!("According to `{cspec}`"))?;
10321051
}
10331052

10341053
// Handle registers
10351054
for (rspec, register) in cmod {
10361055
let rspec = rspec.str()?;
1037-
if !rspec.starts_with('_') {
1038-
self.process_register(rspec, register.hash()?, &cpath, config)
1039-
.with_context(|| format!("According to `{rspec}`"))?;
1056+
if Self::KEYWORDS.contains(&rspec) {
1057+
continue;
10401058
}
1059+
self.process_register(rspec, register.hash()?, &cpath, config)
1060+
.with_context(|| format!("According to `{rspec}`"))?;
10411061
}
10421062

10431063
self.post_process(cmod, parent, config)

0 commit comments

Comments
 (0)