From dee49b0c4c9b34ab6b341cd15ab6d0d8069a5072 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Wed, 29 Nov 2023 22:44:42 +0300 Subject: [PATCH] validate_all --- svd-rs/CHANGELOG.md | 3 +++ svd-rs/src/cluster.rs | 22 ++++++++++++++++++++++ svd-rs/src/device.rs | 12 ++++++++++++ svd-rs/src/enumeratedvalues.rs | 16 +++++++++------- svd-rs/src/field.rs | 18 ++++++++++++++++++ svd-rs/src/peripheral.rs | 32 +++++++++++++++++++++++++++++++- svd-rs/src/register.rs | 19 +++++++++++++++++++ 7 files changed, 114 insertions(+), 8 deletions(-) diff --git a/svd-rs/CHANGELOG.md b/svd-rs/CHANGELOG.md index e025307..ab2ca27 100644 --- a/svd-rs/CHANGELOG.md +++ b/svd-rs/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- fix `validate` on `Disabled` level, remove `mut` +- add `validate_all` for `Device` and childrens for recursive tree check + ## [v0.14.5] - 2023-11-22 - `default_value` for `EnumeratedValues` diff --git a/svd-rs/src/cluster.rs b/svd-rs/src/cluster.rs index 19656e3..ea380e0 100644 --- a/svd-rs/src/cluster.rs +++ b/svd-rs/src/cluster.rs @@ -7,6 +7,7 @@ use super::{ BuildError, Description, DimElement, EmptyToNone, MaybeArray, Name, Register, RegisterCluster, RegisterProperties, SvdError, ValidateLevel, }; +use std::ops::Deref; /// Cluster describes a sequence of neighboring registers within a peripheral. pub type Cluster = MaybeArray; @@ -253,6 +254,17 @@ impl ClusterInfo { } Ok(()) } + /// Validate the [`ClusterInfo`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + self.default_register_properties.validate(lvl)?; + for r in self.registers() { + r.validate_all(lvl)?; + } + for c in self.clusters() { + c.validate_all(lvl)?; + } + self.validate(lvl) + } /// Returns iterator over all descendant registers #[deprecated(since = "0.12.1", note = "Please use `all_registers` instead")] @@ -329,6 +341,16 @@ impl ClusterInfo { } } +impl Cluster { + /// Validate the [`Cluster`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + if let Self::Array(_, dim) = self { + dim.validate(lvl)?; + } + self.deref().validate_all(lvl) + } +} + impl Name for ClusterInfo { fn name(&self) -> &str { &self.name diff --git a/svd-rs/src/device.rs b/svd-rs/src/device.rs index 2265af7..aa9d443 100644 --- a/svd-rs/src/device.rs +++ b/svd-rs/src/device.rs @@ -372,6 +372,7 @@ impl Device { } self.validate(lvl) } + /// Validate the [`Device`] pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> { if !lvl.is_disabled() { @@ -382,6 +383,17 @@ impl Device { } Ok(()) } + /// Validate the [`Device`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + if let Some(cpu) = self.cpu.as_ref() { + cpu.validate(lvl)?; + } + self.default_register_properties.validate(lvl)?; + for p in &self.peripherals { + p.validate_all(lvl)?; + } + self.validate(lvl) + } /// Get peripheral by name pub fn get_peripheral(&self, name: &str) -> Option<&Peripheral> { diff --git a/svd-rs/src/enumeratedvalues.rs b/svd-rs/src/enumeratedvalues.rs index 3a8493e..aff085f 100644 --- a/svd-rs/src/enumeratedvalues.rs +++ b/svd-rs/src/enumeratedvalues.rs @@ -100,12 +100,7 @@ impl EnumeratedValuesBuilder { impl EnumeratedValues { /// Return default value if present pub fn default_value(&self) -> Option<&EnumeratedValue> { - for v in &self.values { - if v.is_default() { - return Some(v); - } - } - None + self.values.iter().find(|&v| v.is_default()) } /// Make a builder for [`EnumeratedValues`] @@ -135,7 +130,7 @@ impl EnumeratedValues { } self.validate(lvl) } - /// Validate the [`EnumeratedValues`]. + /// Validate the [`EnumeratedValues`] pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> { if !lvl.is_disabled() { if lvl.is_strict() { @@ -157,6 +152,13 @@ impl EnumeratedValues { Ok(()) } } + /// Validate the [`EnumeratedValues`] recursively. + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + for ev in &self.values { + ev.validate(lvl)?; + } + self.validate(lvl) + } pub(crate) fn check_range(&self, range: core::ops::Range) -> Result<(), SvdError> { for v in self.values.iter() { v.check_range(&range)?; diff --git a/svd-rs/src/field.rs b/svd-rs/src/field.rs index 153fe4e..86c3a9f 100644 --- a/svd-rs/src/field.rs +++ b/svd-rs/src/field.rs @@ -4,6 +4,7 @@ use super::{ MaybeArray, ModifiedWriteValues, Name, ReadAction, SvdError, Usage, ValidateLevel, WriteConstraint, }; +use std::ops::Deref; /// Describes a field or fields of a [register](crate::RegisterInfo). pub type Field = MaybeArray; @@ -334,6 +335,13 @@ impl FieldInfo { Ok(()) } + /// Validate the [`FieldInfo`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + for evs in &self.enumerated_values { + evs.validate_all(lvl)?; + } + self.validate(lvl) + } /// Get bit offset pub fn bit_offset(&self) -> u32 { @@ -377,6 +385,16 @@ impl FieldInfo { } } +impl Field { + /// Validate the [`Field`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + if let Self::Array(_, dim) = self { + dim.validate(lvl)?; + } + self.deref().validate_all(lvl) + } +} + impl Name for FieldInfo { fn name(&self) -> &str { &self.name diff --git a/svd-rs/src/peripheral.rs b/svd-rs/src/peripheral.rs index 967d864..7e86a2c 100644 --- a/svd-rs/src/peripheral.rs +++ b/svd-rs/src/peripheral.rs @@ -7,6 +7,7 @@ use super::{ AddressBlock, BuildError, Cluster, Description, DimElement, EmptyToNone, Interrupt, MaybeArray, Name, Register, RegisterCluster, RegisterProperties, SvdError, ValidateLevel, }; +use std::ops::Deref; /// A single peripheral or array of peripherals pub type Peripheral = MaybeArray; @@ -369,7 +370,7 @@ impl PeripheralInfo { self.validate(lvl) } - /// Validate the [`Peripheral`] + /// Validate the [`PeripheralInfo`] pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> { if !lvl.is_disabled() { // TODO @@ -388,6 +389,25 @@ impl PeripheralInfo { } Ok(()) } + /// Validate the [`PeripheralInfo`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + if let Some(abs) = self.address_block.as_ref() { + for ab in abs { + ab.validate(lvl)?; + } + } + for i in &self.interrupt { + i.validate(lvl)?; + } + self.default_register_properties.validate(lvl)?; + for r in self.registers() { + r.validate_all(lvl)?; + } + for c in self.clusters() { + c.validate_all(lvl)?; + } + self.validate(lvl) + } /// Returns iterator over child registers pub fn registers(&self) -> RegisterIter { @@ -492,6 +512,16 @@ impl PeripheralInfo { } } +impl Peripheral { + /// Validate the [`Peripheral`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + if let Self::Array(_, dim) = self { + dim.validate(lvl)?; + } + self.deref().validate_all(lvl) + } +} + impl Name for PeripheralInfo { fn name(&self) -> &str { &self.name diff --git a/svd-rs/src/register.rs b/svd-rs/src/register.rs index c9a1d56..a7d02a5 100644 --- a/svd-rs/src/register.rs +++ b/svd-rs/src/register.rs @@ -4,6 +4,7 @@ use super::{ ModifiedWriteValues, Name, ReadAction, RegisterProperties, SvdError, ValidateLevel, WriteConstraint, }; +use std::ops::Deref; /// A single register or array of registers. A register is a named, programmable resource that belongs to a [peripheral](crate::Peripheral). pub type Register = MaybeArray; @@ -358,6 +359,14 @@ impl RegisterInfo { } Ok(()) } + /// Validate the [`RegisterInfo`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + self.properties.validate(lvl)?; + for f in self.fields() { + f.validate_all(lvl)?; + } + self.validate(lvl) + } /// Returns iterator over child fields pub fn fields(&self) -> std::slice::Iter { @@ -386,6 +395,16 @@ impl RegisterInfo { } } +impl Register { + /// Validate the [`Register`] recursively + pub fn validate_all(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + if let Self::Array(_, dim) = self { + dim.validate(lvl)?; + } + self.deref().validate_all(lvl) + } +} + impl Name for RegisterInfo { fn name(&self) -> &str { &self.name