From 512fc7b0cf23892a837a780d738cfb2ab67f8478 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 1 May 2026 16:19:11 +0200 Subject: [PATCH 1/4] Add duplicate detection to Rename transform --- src/transform/mod.rs | 26 +++++++++---------- src/transform/rename.rs | 57 ++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/transform/mod.rs b/src/transform/mod.rs index cb3e33b6..47dfd55e 100644 --- a/src/transform/mod.rs +++ b/src/transform/mod.rs @@ -55,18 +55,18 @@ impl std::fmt::Debug for NameCollisionErrors { } } -fn rename_opt(s: &mut Option, f: impl Fn(&mut String)) { +fn rename_opt(s: &mut Option, mut f: impl FnMut(&mut String)) { if let Some(s) = s { f(s) } } -pub fn map_block_names(ir: &mut IR, f: impl Fn(&mut String)) { - remap_names(NameKind::Block, &mut ir.blocks, &f).unwrap(); +pub fn map_block_names(ir: &mut IR, mut f: impl FnMut(&mut String)) { + remap_names(NameKind::Block, &mut ir.blocks, &mut f).unwrap(); for (_, d) in ir.devices.iter_mut() { for p in &mut d.peripherals { - rename_opt(&mut p.block, &f); + rename_opt(&mut p.block, &mut f); } } @@ -80,31 +80,31 @@ pub fn map_block_names(ir: &mut IR, f: impl Fn(&mut String)) { } } -pub fn map_fieldset_names(ir: &mut IR, f: impl Fn(&mut String)) { - remap_names(NameKind::Fieldset, &mut ir.fieldsets, &f).unwrap(); +pub fn map_fieldset_names(ir: &mut IR, mut f: impl FnMut(&mut String)) { + remap_names(NameKind::Fieldset, &mut ir.fieldsets, &mut f).unwrap(); for (_, b) in ir.blocks.iter_mut() { for i in b.items.iter_mut() { match &mut i.inner { BlockItemInner::Block(_p) => {} - BlockItemInner::Register(r) => rename_opt(&mut r.fieldset, &f), + BlockItemInner::Register(r) => rename_opt(&mut r.fieldset, &mut f), } } } } -pub fn map_enum_names(ir: &mut IR, f: impl Fn(&mut String)) { - remap_names(NameKind::Enum, &mut ir.enums, &f).unwrap(); +pub fn map_enum_names(ir: &mut IR, mut f: impl FnMut(&mut String)) { + remap_names(NameKind::Enum, &mut ir.enums, &mut f).unwrap(); for (_, fs) in ir.fieldsets.iter_mut() { for ff in fs.fields.iter_mut() { - rename_opt(&mut ff.enumm, &f); + rename_opt(&mut ff.enumm, &mut f); } } } -pub fn map_device_names(ir: &mut IR, f: impl Fn(&mut String)) { - remap_names(NameKind::Device, &mut ir.devices, &f).unwrap(); +pub fn map_device_names(ir: &mut IR, f: impl FnMut(&mut String)) { + remap_names(NameKind::Device, &mut ir.devices, f).unwrap(); } pub fn map_device_interrupt_names(ir: &mut IR, f: impl Fn(&mut String)) { @@ -191,7 +191,7 @@ pub fn map_descriptions(ir: &mut IR, mut ff: impl FnMut(&str) -> String) -> anyh fn remap_names( kind: NameKind, x: &mut BTreeMap, - f: impl Fn(&mut String), + mut f: impl FnMut(&mut String), ) -> Result<(), NameCollisionErrors> { let mut res = BTreeMap::new(); let mut errs = HashSet::new(); diff --git a/src/transform/rename.rs b/src/transform/rename.rs index 22bdf88a..79ba8e22 100644 --- a/src/transform/rename.rs +++ b/src/transform/rename.rs @@ -1,9 +1,13 @@ +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; + use serde::{Deserialize, Serialize}; use super::common::*; use crate::ir::*; -#[derive(Debug, Serialize, Deserialize, Default)] +#[derive(Clone, Copy, Debug, Serialize, Deserialize, Default, PartialEq, Eq, Hash)] pub enum RenameType { #[default] All, @@ -13,33 +17,62 @@ pub enum RenameType { Enum, } +impl RenameType { + pub fn fmt<'a>(&self) -> impl Fn(String) -> String + 'a { + let me = *self; + move |name: String| match me { + RenameType::All => unimplemented!(), + RenameType::Device => format!("device {name}"), + RenameType::Block => format!("block {name}"), + RenameType::Fieldset => format!("fieldset {name}"), + RenameType::Enum => format!("enum {name}"), + } + } +} + #[derive(Debug, Serialize, Deserialize)] pub struct Rename { pub from: RegexSet, pub to: String, #[serde(default)] pub r#type: RenameType, + #[serde(default = "get_true")] + pub error_on_duplicate: bool, } impl Rename { pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { - let renamer = |name: &mut String| { - if let Some(res) = match_expand(name, &self.from, &self.to) { - *name = res + let had_duplicates = Rc::new(RefCell::new(false)); + + let renamer = |ty: RenameType| { + let mut state = HashMap::new(); + let had_duplicates = had_duplicates.clone(); + let eod = self.error_on_duplicate; + + move |name: &mut String| { + if let Some(res) = match_expand(name, &self.from, &self.to) { + *had_duplicates.borrow_mut() |= + !can_rename(eod, &mut state, &res, name, ty.fmt()); + *name = res + } } }; match self.r#type { RenameType::All => { - super::map_device_names(ir, renamer); - super::map_block_names(ir, renamer); - super::map_fieldset_names(ir, renamer); - super::map_enum_names(ir, renamer); + super::map_device_names(ir, renamer(RenameType::Device)); + super::map_block_names(ir, renamer(RenameType::Block)); + super::map_fieldset_names(ir, renamer(RenameType::Fieldset)); + super::map_enum_names(ir, renamer(RenameType::Enum)); } - RenameType::Device => super::map_device_names(ir, renamer), - RenameType::Block => super::map_block_names(ir, renamer), - RenameType::Fieldset => super::map_fieldset_names(ir, renamer), - RenameType::Enum => super::map_enum_names(ir, renamer), + RenameType::Device => super::map_device_names(ir, renamer(RenameType::Device)), + RenameType::Block => super::map_block_names(ir, renamer(RenameType::Block)), + RenameType::Fieldset => super::map_fieldset_names(ir, renamer(RenameType::Fieldset)), + RenameType::Enum => super::map_enum_names(ir, renamer(RenameType::Enum)), + } + + if *had_duplicates.borrow() && self.error_on_duplicate { + anyhow::bail!("Failed to rename interrupts"); } Ok(()) From 77362c61012d38aaf666fcc6c35fd77a2325ba3e Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 1 May 2026 16:21:07 +0200 Subject: [PATCH 2/4] Add RenameType::Interrupt to Rename --- src/transform/mod.rs | 2 +- src/transform/rename.rs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/transform/mod.rs b/src/transform/mod.rs index 47dfd55e..7f34f1ea 100644 --- a/src/transform/mod.rs +++ b/src/transform/mod.rs @@ -107,7 +107,7 @@ pub fn map_device_names(ir: &mut IR, f: impl FnMut(&mut String)) { remap_names(NameKind::Device, &mut ir.devices, f).unwrap(); } -pub fn map_device_interrupt_names(ir: &mut IR, f: impl Fn(&mut String)) { +pub fn map_device_interrupt_names(ir: &mut IR, mut f: impl FnMut(&mut String)) { for (_, d) in ir.devices.iter_mut() { for i in &mut d.interrupts { f(&mut i.name); diff --git a/src/transform/rename.rs b/src/transform/rename.rs index 79ba8e22..28b5d1da 100644 --- a/src/transform/rename.rs +++ b/src/transform/rename.rs @@ -15,6 +15,7 @@ pub enum RenameType { Block, Fieldset, Enum, + Interrupt, } impl RenameType { @@ -26,6 +27,7 @@ impl RenameType { RenameType::Block => format!("block {name}"), RenameType::Fieldset => format!("fieldset {name}"), RenameType::Enum => format!("enum {name}"), + RenameType::Interrupt => format!("interrupt {name}"), } } } @@ -64,11 +66,15 @@ impl Rename { super::map_block_names(ir, renamer(RenameType::Block)); super::map_fieldset_names(ir, renamer(RenameType::Fieldset)); super::map_enum_names(ir, renamer(RenameType::Enum)); + super::map_device_interrupt_names(ir, renamer(RenameType::Interrupt)); } RenameType::Device => super::map_device_names(ir, renamer(RenameType::Device)), RenameType::Block => super::map_block_names(ir, renamer(RenameType::Block)), RenameType::Fieldset => super::map_fieldset_names(ir, renamer(RenameType::Fieldset)), RenameType::Enum => super::map_enum_names(ir, renamer(RenameType::Enum)), + RenameType::Interrupt => { + super::map_device_interrupt_names(ir, renamer(RenameType::Interrupt)) + } } if *had_duplicates.borrow() && self.error_on_duplicate { From 5389ea045d340e3ac9e7aac287500f606592fbbf Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 1 May 2026 16:22:00 +0200 Subject: [PATCH 3/4] Reimplement RenameInterrupts with Rename --- src/transform/rename_interrupts.rs | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/src/transform/rename_interrupts.rs b/src/transform/rename_interrupts.rs index 89d505b8..a9f8c6d6 100644 --- a/src/transform/rename_interrupts.rs +++ b/src/transform/rename_interrupts.rs @@ -1,9 +1,8 @@ -use std::collections::HashMap; - use serde::{Deserialize, Serialize}; use super::common::*; use crate::ir::*; +use crate::transform::rename::{Rename, RenameType}; #[derive(Debug, Serialize, Deserialize)] pub struct RenameInterrupts { @@ -15,25 +14,12 @@ pub struct RenameInterrupts { impl RenameInterrupts { pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { - let mut had_duplicate = false; - - for (dev_name, d) in ir.devices.iter_mut() { - let mut renames = HashMap::new(); - let fmt = |itr| format!("interrupt {itr} for device {dev_name}"); - - for i in &mut d.interrupts { - if let Some(name) = match_expand(&i.name, &self.from, &self.to) { - had_duplicate |= - !can_rename(self.error_on_duplicate, &mut renames, &name, &i.name, fmt); - i.name = name; - } - } + Rename { + from: self.from.clone(), + to: self.to.clone(), + r#type: RenameType::Interrupt, + error_on_duplicate: self.error_on_duplicate, } - - if had_duplicate && self.error_on_duplicate { - anyhow::bail!("Failed to rename interrupts"); - } - - Ok(()) + .run(ir) } } From a2f26af2c6731041a26e23c5511eb793fa326209 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 1 May 2026 16:24:55 +0200 Subject: [PATCH 4/4] Add RenameType::Peripheral and reimplement RenamePeripherals with it --- src/transform/mod.rs | 2 +- src/transform/rename.rs | 6 ++++++ src/transform/rename_peripherals.rs | 28 +++++++--------------------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/transform/mod.rs b/src/transform/mod.rs index 7f34f1ea..b129650e 100644 --- a/src/transform/mod.rs +++ b/src/transform/mod.rs @@ -115,7 +115,7 @@ pub fn map_device_interrupt_names(ir: &mut IR, mut f: impl FnMut(&mut String)) { } } -pub fn map_device_peripheral_names(ir: &mut IR, f: impl Fn(&mut String)) { +pub fn map_device_peripheral_names(ir: &mut IR, mut f: impl FnMut(&mut String)) { for (_, d) in ir.devices.iter_mut() { for p in &mut d.peripherals { f(&mut p.name); diff --git a/src/transform/rename.rs b/src/transform/rename.rs index 28b5d1da..c984a1e1 100644 --- a/src/transform/rename.rs +++ b/src/transform/rename.rs @@ -16,6 +16,7 @@ pub enum RenameType { Fieldset, Enum, Interrupt, + Peripheral, } impl RenameType { @@ -28,6 +29,7 @@ impl RenameType { RenameType::Fieldset => format!("fieldset {name}"), RenameType::Enum => format!("enum {name}"), RenameType::Interrupt => format!("interrupt {name}"), + RenameType::Peripheral => format!("peripheral {name}"), } } } @@ -67,6 +69,7 @@ impl Rename { super::map_fieldset_names(ir, renamer(RenameType::Fieldset)); super::map_enum_names(ir, renamer(RenameType::Enum)); super::map_device_interrupt_names(ir, renamer(RenameType::Interrupt)); + super::map_device_peripheral_names(ir, renamer(RenameType::Peripheral)); } RenameType::Device => super::map_device_names(ir, renamer(RenameType::Device)), RenameType::Block => super::map_block_names(ir, renamer(RenameType::Block)), @@ -75,6 +78,9 @@ impl Rename { RenameType::Interrupt => { super::map_device_interrupt_names(ir, renamer(RenameType::Interrupt)) } + RenameType::Peripheral => { + super::map_device_peripheral_names(ir, renamer(RenameType::Peripheral)) + } } if *had_duplicates.borrow() && self.error_on_duplicate { diff --git a/src/transform/rename_peripherals.rs b/src/transform/rename_peripherals.rs index 99985922..786d977d 100644 --- a/src/transform/rename_peripherals.rs +++ b/src/transform/rename_peripherals.rs @@ -1,9 +1,8 @@ -use std::collections::HashMap; - use serde::{Deserialize, Serialize}; use super::common::*; use crate::ir::*; +use crate::transform::rename::{Rename, RenameType}; #[derive(Debug, Serialize, Deserialize)] pub struct RenamePeripherals { @@ -15,25 +14,12 @@ pub struct RenamePeripherals { impl RenamePeripherals { pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> { - let mut had_duplicate = false; - - for (dev_name, d) in ir.devices.iter_mut() { - let mut renames = HashMap::new(); - let fmt = |peri| format!("peripheral {peri} for device {dev_name}"); - - for p in &mut d.peripherals { - if let Some(name) = match_expand(&p.name, &self.from, &self.to) { - had_duplicate |= - !can_rename(self.error_on_duplicate, &mut renames, &name, &p.name, fmt); - p.name = name; - } - } + Rename { + from: self.from.clone(), + to: self.to.clone(), + r#type: RenameType::Peripheral, + error_on_duplicate: self.error_on_duplicate, } - - if had_duplicate && self.error_on_duplicate { - anyhow::bail!("Failed to rename peripherals"); - } - - Ok(()) + .run(ir) } }