From 569e544e7175e9dd461fe9e3ce9c67ea017cc321 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Tue, 31 Dec 2024 09:34:05 +0300 Subject: [PATCH 1/2] ignore support in modify_field and derive --- src/patch/peripheral.rs | 13 ++++++++----- src/patch/register.rs | 28 ++++++++++++++++------------ 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/patch/peripheral.rs b/src/patch/peripheral.rs index 2935aa4..bb57abe 100644 --- a/src/patch/peripheral.rs +++ b/src/patch/peripheral.rs @@ -247,6 +247,7 @@ pub(crate) trait RegisterBlockExt: Name { /// Remove fields from rname and mark it as derivedFrom rderive. /// Update all derivedFrom referencing rname fn derive_register(&mut self, rspec: &str, rderive: &Yaml, bpath: &BlockPath) -> PatchResult { + let (rspec, ignore) = rspec.spec(); let (rderive, info) = if let Some(rderive) = rderive.as_str() { ( rderive, @@ -277,12 +278,14 @@ pub(crate) trait RegisterBlockExt: Name { })?; } + let rtags = self.iter_registers(rspec).collect::>(); let mut found = Vec::new(); - for register in self.iter_registers(rspec) { - found.push(register.name.to_string()); - register.modify_from(info.clone(), VAL_LVL)?; - } - if found.is_empty() { + if !rtags.is_empty() { + for register in rtags { + found.push(register.name.to_string()); + register.modify_from(info.clone(), VAL_LVL)?; + } + } else if !ignore { super::check_dimable_name(rspec)?; let register = info.name(rspec.into()).build(VAL_LVL)?.single(); self.add_child(RegisterCluster::Register(register)); diff --git a/src/patch/register.rs b/src/patch/register.rs index 7552d3a..4116bcc 100644 --- a/src/patch/register.rs +++ b/src/patch/register.rs @@ -289,10 +289,16 @@ impl RegisterExt for Register { } fn modify_field(&mut self, fspec: &str, fmod: &Hash, rpath: &RegisterPath) -> PatchResult { + let (fspec, ignore) = fspec.spec(); let ftags = self.iter_fields(fspec).collect::>(); let field_builder = make_field(fmod, Some(rpath))?; let dim = make_dim_element(fmod)?; - if !ftags.is_empty() { + if ftags.is_empty() && !ignore { + let present = self.present_fields(); + return Err(anyhow!( + "Could not find `{rpath}:{fspec}. Present fields: {present}.`" + )); + } else { for ftag in ftags { modify_dim_element(ftag, &dim)?; if let Some(value) = fmod @@ -362,6 +368,7 @@ impl RegisterExt for Register { dpath.into() } } + let (fspec, ignore) = fspec.spec(); let info = if let Some(dpath) = fderive.as_str() { FieldInfo::builder().derived_from(Some(make_path(dpath, rpath))) } else if let Some(hash) = fderive.as_hash() { @@ -372,18 +379,15 @@ impl RegisterExt for Register { } else { return Err(anyhow!("derive: incorrect syntax for {fspec}")); }; - - let mut found = false; - for field in self.iter_fields(fspec) { - found = true; - field.modify_from(info.clone(), VAL_LVL)?; - } - if !found { - { - super::check_dimable_name(fspec)?; - let field = info.name(fspec.into()).build(VAL_LVL)?.single(); - self.fields.get_or_insert(Vec::new()).push(field); + let ftags = self.iter_fields(fspec).collect::>(); + if !ftags.is_empty() { + for field in ftags { + field.modify_from(info.clone(), VAL_LVL)?; } + } else if !ignore { + super::check_dimable_name(fspec)?; + let field = info.name(fspec.into()).build(VAL_LVL)?.single(); + self.fields.get_or_insert(Vec::new()).push(field); } Ok(()) } From dcaf59ea9c8cd0df6f940d62c1e24c1dfe96f9ba Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Thu, 2 Jan 2025 13:53:51 +0300 Subject: [PATCH 2/2] derive array --- src/patch/peripheral.rs | 21 +++++++++++++++------ src/patch/register.rs | 27 ++++++++++++++++++++------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/patch/peripheral.rs b/src/patch/peripheral.rs index bb57abe..8a16820 100644 --- a/src/patch/peripheral.rs +++ b/src/patch/peripheral.rs @@ -248,9 +248,10 @@ pub(crate) trait RegisterBlockExt: Name { /// Update all derivedFrom referencing rname fn derive_register(&mut self, rspec: &str, rderive: &Yaml, bpath: &BlockPath) -> PatchResult { let (rspec, ignore) = rspec.spec(); - let (rderive, info) = if let Some(rderive) = rderive.as_str() { + let (rderive, dim, info) = if let Some(rderive) = rderive.as_str() { ( rderive, + None, RegisterInfo::builder().derived_from(Some(rderive.into())), ) } else if let Some(hash) = rderive.as_hash() { @@ -259,6 +260,7 @@ pub(crate) trait RegisterBlockExt: Name { })?; ( rderive, + make_dim_element(hash)?, make_register(hash, Some(bpath))?.derived_from(Some(rderive.into())), ) } else { @@ -281,14 +283,21 @@ pub(crate) trait RegisterBlockExt: Name { let rtags = self.iter_registers(rspec).collect::>(); let mut found = Vec::new(); if !rtags.is_empty() { - for register in rtags { - found.push(register.name.to_string()); - register.modify_from(info.clone(), VAL_LVL)?; + for rtag in rtags { + found.push(rtag.name.to_string()); + modify_dim_element(rtag, &dim)?; + rtag.modify_from(info.clone(), VAL_LVL)?; } } else if !ignore { super::check_dimable_name(rspec)?; - let register = info.name(rspec.into()).build(VAL_LVL)?.single(); - self.add_child(RegisterCluster::Register(register)); + let reg = info.name(rspec.into()).build(VAL_LVL)?; + self.add_child(RegisterCluster::Register({ + if let Some(dim) = dim { + reg.array(dim.build(VAL_LVL)?) + } else { + reg.single() + } + })); } for rname in found { for r in self diff --git a/src/patch/register.rs b/src/patch/register.rs index 4116bcc..cd85e4c 100644 --- a/src/patch/register.rs +++ b/src/patch/register.rs @@ -369,25 +369,38 @@ impl RegisterExt for Register { } } let (fspec, ignore) = fspec.spec(); - let info = if let Some(dpath) = fderive.as_str() { - FieldInfo::builder().derived_from(Some(make_path(dpath, rpath))) + let (dim, info) = if let Some(dpath) = fderive.as_str() { + ( + None, + FieldInfo::builder().derived_from(Some(make_path(dpath, rpath))), + ) } else if let Some(hash) = fderive.as_hash() { let dpath = hash.get_str("_from")?.ok_or_else(|| { anyhow!("derive: source field not given, please add a _from field to {fspec}") })?; - make_field(hash, Some(rpath))?.derived_from(Some(make_path(dpath, rpath))) + ( + make_dim_element(hash)?, + make_field(hash, Some(rpath))?.derived_from(Some(make_path(dpath, rpath))), + ) } else { return Err(anyhow!("derive: incorrect syntax for {fspec}")); }; let ftags = self.iter_fields(fspec).collect::>(); if !ftags.is_empty() { - for field in ftags { - field.modify_from(info.clone(), VAL_LVL)?; + for ftag in ftags { + modify_dim_element(ftag, &dim)?; + ftag.modify_from(info.clone(), VAL_LVL)?; } } else if !ignore { super::check_dimable_name(fspec)?; - let field = info.name(fspec.into()).build(VAL_LVL)?.single(); - self.fields.get_or_insert(Vec::new()).push(field); + let field = info.name(fspec.into()).build(VAL_LVL)?; + self.fields.get_or_insert(Vec::new()).push({ + if let Some(dim) = dim { + field.array(dim.build(VAL_LVL)?) + } else { + field.single() + } + }); } Ok(()) }