From 286e8120d8cfdfddaa12ab796164e8fbc8e6d2ba Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Thu, 26 Oct 2023 12:31:21 +0300 Subject: [PATCH] ignore if not exists --- CHANGELOG-rust.md | 1 + src/patch/device.rs | 5 +++-- src/patch/mod.rs | 15 +++++++++++++++ src/patch/peripheral.rs | 26 ++++++++++++++++++++------ src/patch/register.rs | 18 ++++++++++++++++-- 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/CHANGELOG-rust.md b/CHANGELOG-rust.md index b45611f2..2f831297 100644 --- a/CHANGELOG-rust.md +++ b/CHANGELOG-rust.md @@ -5,6 +5,7 @@ This changelog tracks the Rust `svdtools` project. See ## [Unreleased] +* Ignore rule if starts with "?@" and no matched instances * Move field with derived enums before other ## [v0.3.4] 2023-10-14 diff --git a/src/patch/device.rs b/src/patch/device.rs index 365ba1e6..9bcfe99a 100644 --- a/src/patch/device.rs +++ b/src/patch/device.rs @@ -9,7 +9,7 @@ use std::{fs::File, io::Read, path::Path}; use super::iterators::{MatchIter, Matched}; use super::peripheral::{PeripheralExt, RegisterBlockExt}; use super::yaml_ext::{AsType, GetVal}; -use super::{abspath, matchname, PatchResult, VAL_LVL}; +use super::{abspath, matchname, PatchResult, Spec, VAL_LVL}; use super::{make_address_block, make_address_blocks, make_cpu, make_interrupt, make_peripheral}; use super::{make_dim_element, modify_dim_element, modify_register_properties}; @@ -418,12 +418,13 @@ impl DeviceExt for Device { ) -> PatchResult { // Find all peripherals that match the spec let mut pcount = 0; + let (pspec, ignore) = pspec.spec(); for ptag in self.iter_peripherals(pspec) { pcount += 1; ptag.process(peripheral, update_fields) .with_context(|| format!("Processing peripheral `{}`", ptag.name))?; } - if pcount == 0 { + if !ignore && pcount == 0 { Err(anyhow!( "Could not find `{pspec}. Present peripherals: {}.`", self.peripherals.iter().map(|p| p.name.as_str()).join(", ") diff --git a/src/patch/mod.rs b/src/patch/mod.rs index fc111c05..78b431b8 100644 --- a/src/patch/mod.rs +++ b/src/patch/mod.rs @@ -637,3 +637,18 @@ fn check_offsets(offsets: &[u32], dim_increment: u32) -> bool { } true } + +pub trait Spec { + /// Return specification and `ignore_if_not_exists` flag + fn spec(&self) -> (&str, bool); +} + +impl Spec for str { + fn spec(&self) -> (&str, bool) { + if let Some(s) = self.strip_prefix("?@") { + (s, true) + } else { + (self, false) + } + } +} diff --git a/src/patch/peripheral.rs b/src/patch/peripheral.rs index 535256ac..4f69e0cb 100644 --- a/src/patch/peripheral.rs +++ b/src/patch/peripheral.rs @@ -11,7 +11,7 @@ use super::register::{RegisterExt, RegisterInfoExt}; use super::yaml_ext::{AsType, GetVal, ToYaml}; use super::{ check_offsets, make_dim_element, matchname, matchsubspec, modify_dim_element, spec_ind, - PatchResult, VAL_LVL, + PatchResult, Spec, VAL_LVL, }; use super::{make_cluster, make_interrupt, make_register}; @@ -412,6 +412,7 @@ impl RegisterBlockExt for Peripheral { } fn modify_register(&mut self, rspec: &str, rmod: &Hash) -> PatchResult { + // TODO: empty error let rtags = self.iter_registers(rspec).collect::>(); if !rtags.is_empty() { let register_builder = make_register(rmod)?; @@ -562,6 +563,7 @@ impl RegisterBlockExt for Peripheral { } fn modify_cluster(&mut self, cspec: &str, cmod: &Hash) -> PatchResult { + // TODO: empty error let ctags = self.iter_clusters(cspec).collect::>(); if !ctags.is_empty() { let cluster_builder = make_cluster(cmod)?; @@ -640,12 +642,13 @@ impl RegisterBlockExt for Peripheral { // Find all registers that match the spec let mut rcount = 0; let pname = self.name.clone(); + let (rspec, ignore) = rspec.spec(); for rtag in self.iter_registers(rspec) { rcount += 1; rtag.process(rmod, &pname, update_fields) .with_context(|| format!("Processing register `{}`", rtag.name))?; } - if rcount == 0 { + if !ignore && rcount == 0 { Err(anyhow!( "Could not find `{pname}:{rspec}. Present registers: {}.`", self.registers().map(|r| r.name.as_str()).join(", ") @@ -659,12 +662,13 @@ impl RegisterBlockExt for Peripheral { // Find all clusters that match the spec let mut ccount = 0; let pname = self.name.clone(); + let (cspec, ignore) = cspec.spec(); for ctag in self.iter_clusters(cspec) { ccount += 1; ctag.process(cmod, &pname, update_fields) .with_context(|| format!("Processing cluster `{}`", ctag.name))?; } - if ccount == 0 { + if !ignore && ccount == 0 { Err(anyhow!( "Could not find `{pname}:{cspec}. Present clusters: {}.`", self.clusters().map(|c| c.name.as_str()).join(", ") @@ -1095,12 +1099,13 @@ impl RegisterBlockExt for Cluster { // Find all registers that match the spec let mut rcount = 0; let pname = self.name.clone(); + let (rspec, ignore) = rspec.spec(); for rtag in self.iter_registers(rspec) { rcount += 1; rtag.process(rmod, &pname, update_fields) .with_context(|| format!("Processing register `{}`", rtag.name))?; } - if rcount == 0 { + if !ignore && rcount == 0 { Err(anyhow!( "Could not find `{pname}:{}:{rspec}. Present registers: {}.`", self.name, @@ -1115,12 +1120,13 @@ impl RegisterBlockExt for Cluster { // Find all clusters that match the spec let mut ccount = 0; let pname = self.name.clone(); + let (cspec, ignore) = cspec.spec(); for ctag in self.iter_clusters(cspec) { ccount += 1; ctag.process(cmod, &pname, update_fields) .with_context(|| format!("Processing cluster `{}`", ctag.name))?; } - if ccount == 0 { + if !ignore && ccount == 0 { Err(anyhow!( "Could not find `{pname}:{}:{cspec}. Present clusters: {}.`", self.name, @@ -1141,6 +1147,7 @@ fn collect_in_array( let mut registers = Vec::new(); let mut place = usize::MAX; let mut i = 0; + let (rspec, ignore) = rspec.spec(); while i < regs.len() { match ®s[i] { RegisterCluster::Register(Register::Single(r)) if matchname(&r.name, rspec) => { @@ -1153,6 +1160,9 @@ fn collect_in_array( } } if registers.is_empty() { + if ignore { + return Ok(()); + } return Err(anyhow!( "{path}: registers {rspec} not found. Present registers: {}.`", regs.iter() @@ -1256,9 +1266,9 @@ fn collect_in_cluster( if rspec == "description" { continue; } - rspecs.push(rspec.to_string()); let mut registers = Vec::new(); let mut i = 0; + let (rspec, ignore) = rspec.spec(); while i < regs.len() { match ®s[i] { RegisterCluster::Register(Register::Single(r)) if matchname(&r.name, rspec) => { @@ -1271,6 +1281,9 @@ fn collect_in_cluster( } } if registers.is_empty() { + if ignore { + continue; + } return Err(anyhow!( "{path}: registers {rspec} not found. Present registers: {}.`", regs.iter() @@ -1281,6 +1294,7 @@ fn collect_in_cluster( .join(", ") )); } + rspecs.push(rspec.to_string()); if single { if registers.len() > 1 { return Err(anyhow!("{path}: more than one registers {rspec} found")); diff --git a/src/patch/register.rs b/src/patch/register.rs index 54bb9eb7..342c36bd 100644 --- a/src/patch/register.rs +++ b/src/patch/register.rs @@ -9,7 +9,8 @@ use yaml_rust::{yaml::Hash, Yaml}; use super::iterators::{MatchIter, Matched}; use super::yaml_ext::{AsType, GetVal, ToYaml}; use super::{ - check_offsets, make_dim_element, matchname, modify_dim_element, spec_ind, PatchResult, VAL_LVL, + check_offsets, make_dim_element, matchname, modify_dim_element, spec_ind, PatchResult, Spec, + VAL_LVL, }; use super::{make_derived_enumerated_values, make_ev_array, make_ev_name, make_field}; @@ -360,6 +361,7 @@ impl RegisterExt for Register { let mut fields = Vec::new(); let mut place = usize::MAX; let mut i = 0; + let (fspec, ignore) = fspec.spec(); while i < fs.len() { match &fs[i] { Field::Single(f) if matchname(&f.name, fspec) => { @@ -372,6 +374,9 @@ impl RegisterExt for Register { } } if fields.is_empty() { + if ignore { + return Ok(()); + } return Err(anyhow!( "{}: fields {fspec} not found. Present fields: {}.`", self.name, @@ -432,9 +437,13 @@ impl RegisterExt for Register { Ok(()) } fn split_fields(&mut self, fspec: &str, fsplit: &Hash) -> PatchResult { + let (fspec, ignore) = fspec.spec(); let mut it = self.iter_fields(fspec); let (new_fields, name) = match (it.next(), it.next()) { (None, _) => { + if ignore { + return Ok(()); + } return Err(anyhow!( "Could not find any fields to split {}:{fspec}. Present fields: {}.`", self.name, @@ -686,6 +695,7 @@ impl RegisterExt for Register { set_enum(ftag, evs.clone(), orig_usage, true, access)?; } } else { + let (fspec, ignore) = fspec.spec(); let mut offsets: Vec<_> = Vec::new(); for (i, f) in self.fields().enumerate() { if matchname(&f.name, fspec) { @@ -693,6 +703,9 @@ impl RegisterExt for Register { } } if offsets.is_empty() { + if ignore { + return Ok(()); + } return Err(anyhow!( "Could not find field {pname}:{}:{fspec}. Present fields: {}.`", self.name, @@ -738,6 +751,7 @@ impl RegisterExt for Register { fn process_field_range(&mut self, pname: &str, fspec: &str, fmod: &[Yaml]) -> PatchResult { let mut set_any = false; + let (fspec, ignore) = fspec.spec(); for ftag in self.iter_fields(fspec) { ftag.write_constraint = Some(WriteConstraint::Range(WriteConstraintRange { min: fmod[0].i64()? as u64, @@ -745,7 +759,7 @@ impl RegisterExt for Register { })); set_any = true; } - if !set_any { + if !ignore && !set_any { return Err(anyhow!( "Could not find field {pname}:{}:{fspec}. Present fields: {}.`", self.name,