diff --git a/CHANGELOG-rust.md b/CHANGELOG-rust.md index 8882951..79b56b0 100644 --- a/CHANGELOG-rust.md +++ b/CHANGELOG-rust.md @@ -5,6 +5,8 @@ This changelog tracks the Rust `svdtools` project. See ## [Unreleased] +* Protect from using one `enumeratedValues` in fields with different width + ## [v0.3.17] 2024-07-05 * Support "isDefault" enum value in `svdtools html` diff --git a/src/patch/device.rs b/src/patch/device.rs index b66a81f..2ed3ed8 100644 --- a/src/patch/device.rs +++ b/src/patch/device.rs @@ -172,7 +172,7 @@ impl DeviceExt for Device { // Now process all peripherals for (periphspec, val) in device { let periphspec = periphspec.str()?; - if !periphspec.starts_with('_') { + if !Self::KEYWORDS.contains(&periphspec) { //val["_path"] = device["_path"]; // TODO: check self.process_peripheral(periphspec, val.hash()?, config) .with_context(|| format!("According to `{periphspec}`"))?; diff --git a/src/patch/peripheral.rs b/src/patch/peripheral.rs index 0cde9b4..c4d08bf 100644 --- a/src/patch/peripheral.rs +++ b/src/patch/peripheral.rs @@ -458,12 +458,12 @@ pub(crate) trait RegisterBlockExt: Name { rtag.name.drain(..len); } if let Some(dname) = rtag.display_name.as_mut() { - if glob.is_match(&dname) { + if glob.is_match(dname.as_str()) { dname.drain(..len); } } if let Some(name) = rtag.alternate_register.as_mut() { - if glob.is_match(&name) { + if glob.is_match(name.as_str()) { name.drain(..len); } } @@ -483,13 +483,13 @@ pub(crate) trait RegisterBlockExt: Name { rtag.name.truncate(nlen - len); } if let Some(dname) = rtag.display_name.as_mut() { - if glob.is_match(&dname) { + if glob.is_match(dname.as_str()) { let nlen = dname.len(); dname.truncate(nlen - len); } } if let Some(name) = rtag.alternate_register.as_mut() { - if glob.is_match(&name) { + if glob.is_match(name.as_str()) { let nlen = name.len(); name.truncate(nlen - len); } diff --git a/src/patch/register.rs b/src/patch/register.rs index 38ea9e7..21dfd3e 100644 --- a/src/patch/register.rs +++ b/src/patch/register.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use anyhow::{anyhow, Context}; use itertools::Itertools; use svd_parser::expand::{BlockPath, RegisterPath}; @@ -768,9 +770,11 @@ impl RegisterExt for Register { } else { let (fspec, ignore) = fspec.spec(); let mut offsets: Vec<_> = Vec::new(); + let mut width_vals = HashSet::new(); for (i, f) in self.fields().enumerate() { if matchname(&f.name, fspec) { - offsets.push((f.bit_range.offset, f.name.to_string(), i)); + offsets.push((f.bit_offset(), f.name.to_string(), i)); + width_vals.insert(f.bit_width()); } } if offsets.is_empty() { @@ -779,7 +783,11 @@ impl RegisterExt for Register { } let present = self.present_fields(); return Err(anyhow!( - "Could not find field {rpath}:{fspec}. Present fields: {present}.`" + "Could not find field {rpath}:{fspec}. Present fields: {present}." + )); + } else if width_vals.len() > 1 { + return Err(anyhow!( + "{rpath}:{fspec}. Same enumeratedValues are used for different fields." )); } let (min_offset, fname, min_offset_pos) = @@ -794,11 +802,9 @@ impl RegisterExt for Register { let access = ftag.access.or(reg_access).unwrap_or_default(); let checked_usage = check_usage(access, usage) .with_context(|| format!("In field {}", ftag.name))?; - if config.enum_derive == EnumAutoDerive::None - || ftag.bit_range.offset == *min_offset - { + if config.enum_derive == EnumAutoDerive::None || ftag.bit_offset() == *min_offset { let mut evs = make_ev_array(fmod)?.usage(make_usage(access, checked_usage)); - if ftag.bit_range.offset == *min_offset { + if ftag.bit_offset() == *min_offset { evs = evs.name(Some(name.clone())); } let evs = evs.build(VAL_LVL)?;