From 5875effc48b57fd19c9978b8300dc44e192c908e Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Wed, 11 May 2022 07:29:02 +0300 Subject: [PATCH 1/2] support nested deriveFrom --- svd-parser/CHANGELOG.md | 2 + svd-parser/src/expand.rs | 450 +++++++++++++++++++++++++-------------- 2 files changed, 296 insertions(+), 156 deletions(-) diff --git a/svd-parser/CHANGELOG.md b/svd-parser/CHANGELOG.md index 866f13dd..36ee2317 100644 --- a/svd-parser/CHANGELOG.md +++ b/svd-parser/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Support nested `derivedFrom` for `expand` + ## [v0.13.3] - 2022-05-09 - Add `expand_properties` (under `expand` feature) diff --git a/svd-parser/src/expand.rs b/svd-parser/src/expand.rs index 7ec54813..197d6564 100644 --- a/svd-parser/src/expand.rs +++ b/svd-parser/src/expand.rs @@ -8,98 +8,152 @@ use svd_rs::{ Device, EnumeratedValues, Field, Peripheral, Register, RegisterCluster, RegisterProperties, }; +#[derive(Clone, Debug, PartialEq, Hash, Eq)] +pub struct RPath { + peripheral: String, + path: Vec, +} + +impl RPath { + pub fn new(p: &str) -> Self { + Self { + peripheral: p.into(), + path: Vec::new(), + } + } + pub fn new_child(&self, name: &str) -> Self { + let mut child = self.clone(); + child.path.push(name.into()); + child + } + pub fn split_str(s: &str) -> (Option, String) { + Self::split_vec(s.split('.').collect()) + } + pub fn split_vec(mut v: Vec<&str>) -> (Option, String) { + let name = v.pop().unwrap().to_string(); + if v.is_empty() { + (None, name) + } else { + let mut rpath = Self::new(v[0]); + rpath.path = v[1..].iter().map(|c| c.to_string()).collect(); + (Some(rpath), name) + } + } + pub fn parent_name(&self) -> (Self, String) { + let mut parent = self.clone(); + let name = parent.path.pop().unwrap(); + (parent, name) + } + pub fn parent(&self) -> Self { + self.parent_name().0 + } +} + +#[derive(Clone, Debug, PartialEq, Hash, Eq)] +pub struct FPath { + register: RPath, + field: String, +} + +impl FPath { + pub fn new(r: &RPath, name: &str) -> Self { + Self { + register: r.clone(), + field: name.into(), + } + } +} + #[derive(Clone, Debug, Default)] struct Index<'a> { peripherals: HashMap, - clusters: HashMap, - registers: HashMap, - fields: HashMap, - evs: HashMap, + clusters: HashMap<(RPath, String), &'a Cluster>, + registers: HashMap<(RPath, String), &'a Register>, + fields: HashMap<(RPath, String), &'a Field>, + evs: HashMap<(FPath, String), &'a EnumeratedValues>, } impl<'a> Index<'a> { fn add_peripheral(&mut self, p: &'a Peripheral) { - let path = &p.name; if let Peripheral::Array(info, dim) = p { for name in names(info, dim) { - let path = name; + let path = RPath::new(&name); for r in p.registers() { self.add_register(&path, r); } for c in p.clusters() { self.add_cluster(&path, c); } - self.peripherals.insert(path, p); + self.peripherals.insert(name, p); } } + let path = RPath::new(&p.name); for r in p.registers() { - self.add_register(path, r); + self.add_register(&path, r); } for c in p.clusters() { - self.add_cluster(path, c); + self.add_cluster(&path, c); } - self.peripherals.insert(path.into(), p); + self.peripherals.insert(p.name.clone(), p); } - fn add_cluster(&mut self, path: &str, c: &'a Cluster) { + fn add_cluster(&mut self, path: &RPath, c: &'a Cluster) { if let Cluster::Array(info, dim) = c { for name in names(info, dim) { - let cpath = format!("{}.{}", path, name); + let cpath = RPath::new_child(path, &name); for r in c.registers() { self.add_register(&cpath, r); } for c in c.clusters() { self.add_cluster(&cpath, c); } - self.clusters.insert(cpath, c); + self.clusters.insert((path.clone(), name), c); } } - let cpath = format!("{}.{}", path, c.name); + let cpath = RPath::new_child(path, &c.name); for r in c.registers() { self.add_register(&cpath, r); } for c in c.clusters() { self.add_cluster(&cpath, c); } - self.clusters.insert(cpath, c); + self.clusters.insert((path.clone(), c.name.to_string()), c); } - fn add_register(&mut self, path: &str, r: &'a Register) { + fn add_register(&mut self, path: &RPath, r: &'a Register) { if let Register::Array(info, dim) = r { for name in names(info, dim) { - let rpath = format!("{}.{}", path, name); + let rpath = RPath::new_child(path, &name); for f in r.fields() { self.add_field(&rpath, f); } - self.registers.insert(rpath, r); + self.registers.insert((path.clone(), name), r); } } - let rpath = format!("{}.{}", path, r.name); + let rpath = RPath::new_child(path, &r.name); for f in r.fields() { self.add_field(&rpath, f); } - self.registers.insert(rpath, r); + self.registers.insert((path.clone(), r.name.to_string()), r); } - fn add_field(&mut self, path: &str, f: &'a Field) { + fn add_field(&mut self, path: &RPath, f: &'a Field) { if let Field::Array(info, dim) = f { for name in names(info, dim) { - let fpath = format!("{}.{}", path, name); + let fpath = FPath::new(path, &name); for evs in &f.enumerated_values { if let Some(name) = evs.name.as_ref() { - let epath = format!("{}.{}", fpath, name); - self.evs.insert(epath, evs); + self.evs.insert((fpath.clone(), name.to_string()), evs); } } - self.fields.insert(fpath, f); + self.fields.insert((path.clone(), name), f); } } - let fpath = format!("{}.{}", path, f.name); + let fpath = FPath::new(path, &f.name); for evs in &f.enumerated_values { if let Some(name) = evs.name.as_ref() { - let epath = format!("{}.{}", fpath, name); - self.evs.insert(epath, evs); + self.evs.insert((fpath.clone(), name.to_string()), evs); } } - self.fields.insert(fpath, f); + self.fields.insert((path.clone(), f.name.to_string()), f); } pub fn create(device: &'a Device) -> Self { @@ -109,21 +163,12 @@ impl<'a> Index<'a> { } index } - - pub fn get_base_peripheral(&self, path: &str) -> Option<&Peripheral> { - self.peripherals - .get(path) - .and_then(|&p| match &p.derived_from { - None => Some(p), - Some(dp) => self.get_base_peripheral(dp), - }) - } } fn expand_register_cluster( regs: &mut Vec, rc: RegisterCluster, - path: &str, + path: &RPath, index: &Index, ) -> Result<()> { match rc { @@ -136,28 +181,16 @@ fn expand_register_cluster( fn expand_cluster_array( regs: &mut Vec, mut c: Cluster, - path: &str, + path: &RPath, index: &Index, ) -> Result<()> { - let cpath = if let Some(dpath) = c.derived_from.as_ref() { - let cpath = dpath.to_string(); - if let Some(d) = index - .clusters - .get(dpath) - .or_else(|| index.clusters.get(&format!("{}.{}", path, dpath))) - { - if d.derived_from.is_some() { - return Err(anyhow!("Multiple derive for {} is not supported", dpath)); - } - c = c.derive_from(d); - c.derived_from = None; - } else { - return Err(anyhow!("Cluster {} not found", dpath)); - } - cpath - } else { - format!("{}.{}", path, c.name) - }; + let mut cpath = None; + if let Some(dpath) = c.derived_from.as_ref() { + let dpath = dpath.to_string(); + cpath = derive_cluster(&mut c, &dpath, path, index)?; + c.derived_from = None; + } + let cpath = cpath.unwrap_or_else(|| RPath::new_child(path, &c.name)); for rc in take(&mut c.children) { expand_register_cluster(&mut c.children, rc, &cpath, index)?; @@ -182,13 +215,111 @@ fn expand_cluster_array( Ok(()) } +fn derive_cluster( + c: &mut Cluster, + dpath: &str, + path: &RPath, + index: &Index, +) -> Result> { + let mut cpath = None; + let rdpath; + let (dparent, dname) = RPath::split_str(dpath); + let d = (match dparent { + Some(dparent) => { + if c.children.is_empty() { + cpath = Some(RPath::new_child(&dparent, &dname)); + } + rdpath = dparent.clone(); + index.clusters.get(&(dparent, dname)) + } + None => { + if c.children.is_empty() { + cpath = Some(RPath::new_child(path, &dname)); + } + rdpath = path.clone(); + index.clusters.get(&(path.clone(), dname)) + } + }) + .ok_or_else(|| anyhow!("cluster {} not found", dpath))?; + + *c = c.derive_from(d); + if let Some(dpath) = d.derived_from.as_ref() { + cpath = derive_cluster(c, dpath, &rdpath, index)?; + c.derived_from = None; + } + Ok(cpath) +} + +fn derive_register( + r: &mut Register, + dpath: &str, + path: &RPath, + index: &Index, +) -> Result> { + let mut rpath = None; + let rdpath; + let (dparent, dname) = RPath::split_str(dpath); + let d = (match dparent { + Some(dparent) => { + if r.fields.is_none() { + rpath = Some(RPath::new_child(&dparent, &dname)); + } + rdpath = dparent.clone(); + index.registers.get(&(dparent, dname)) + } + None => { + if r.fields.is_none() { + rpath = Some(RPath::new_child(path, &dname)); + } + rdpath = path.clone(); + index.registers.get(&(path.clone(), dname)) + } + }) + .ok_or_else(|| anyhow!("register {} not found", dpath))?; + + *r = r.derive_from(d); + if let Some(dpath) = d.derived_from.as_ref() { + rpath = derive_register(r, dpath, &rdpath, index)?; + } + Ok(rpath) +} + +fn derive_field(f: &mut Field, dpath: &str, rpath: &RPath, index: &Index) -> Result> { + let mut fpath = None; + let (dparent, dname) = RPath::split_str(dpath); + let rdpath; + let d = (match dparent { + Some(dparent) => { + if f.enumerated_values.is_empty() { + fpath = Some(FPath::new(&dparent, &dname)); + } + rdpath = dparent.clone(); + index.fields.get(&(dparent, dname)) + } + None => { + if f.enumerated_values.is_empty() { + fpath = Some(FPath::new(rpath, &dname)); + } + rdpath = rpath.clone(); + index.fields.get(&(rpath.clone(), dname)) + } + }) + .ok_or_else(|| anyhow!("field {} not found", dpath))?; + + *f = f.derive_from(d); + if let Some(dpath) = d.derived_from.as_ref() { + fpath = derive_field(f, dpath, &rdpath, index)?; + } + Ok(fpath) +} + fn expand_cluster(regs: &mut Vec, c: ClusterInfo) { for rc in c.children { match rc { RegisterCluster::Cluster(_) => unreachable!(), RegisterCluster::Register(mut r) => { r.name = format!("{}_{}", c.name, r.name); - r.address_offset = c.address_offset + r.address_offset; + r.address_offset += c.address_offset; regs.push(RegisterCluster::Register(r)); } } @@ -198,32 +329,20 @@ fn expand_cluster(regs: &mut Vec, c: ClusterInfo) { fn expand_register_array( regs: &mut Vec, mut r: Register, - path: &str, + path: &RPath, index: &Index, ) -> Result<()> { - let rpath = if let Some(dpath) = r.derived_from.as_ref() { - let rpath = dpath.to_string(); - if let Some(d) = index - .registers - .get(dpath) - .or_else(|| index.registers.get(&format!("{}.{}", path, dpath))) - { - if d.derived_from.is_some() { - return Err(anyhow!("multiple derive for {} is not supported", dpath)); - } - r = r.derive_from(d); - r.derived_from = None; - } else { - return Err(anyhow!("register {} not found", dpath)); - } - rpath - } else { - format!("{}.{}", path, r.name) - }; + let mut rpath = None; + if let Some(dpath) = r.derived_from.as_ref() { + let dpath = dpath.to_string(); + rpath = derive_register(&mut r, &dpath, path, index)?; + r.derived_from = None; + } + let rpath = rpath.unwrap_or_else(|| RPath::new_child(path, &r.name)); if let Some(field) = r.fields.as_mut() { for f in take(field) { - expand_field(field, f, path, &rpath, index)?; + expand_field(field, f, &rpath, index)?; } } @@ -248,35 +367,21 @@ fn expand_register_array( Ok(()) } -fn expand_field( - fields: &mut Vec, - mut f: Field, - regparent: &str, - rpath: &str, - index: &Index, -) -> Result<()> { - let fpath = if let Some(dpath) = f.derived_from.as_ref() { - let fpath = dpath.to_string(); - if let Some(d) = index - .fields - .get(dpath) - .or_else(|| index.fields.get(&format!("{}.{}", rpath, dpath))) - { - if d.derived_from.is_some() { - return Err(anyhow!("multiple derive for {} is not supported", dpath)); - } - f = f.derive_from(d); - f.derived_from = None; - } else { - return Err(anyhow!("field {} not found", dpath)); - } - fpath - } else { - format!("{}.{}", rpath, f.name) - }; +fn expand_field(fields: &mut Vec, mut f: Field, rpath: &RPath, index: &Index) -> Result<()> { + let mut fpath = None; + if let Some(dpath) = f.derived_from.as_ref() { + let dpath = dpath.to_string(); + fpath = derive_field(&mut f, &dpath, rpath, index)?; + f.derived_from = None; + } + let fpath = fpath.unwrap_or_else(|| FPath::new(rpath, &f.name)); for ev in &mut f.enumerated_values { - derive_enumerated_values(ev, regparent, rpath, &fpath, index)?; + if let Some(dpath) = ev.derived_from.as_ref() { + let dpath = dpath.to_string(); + derive_enumerated_values(ev, &dpath, &fpath, index)?; + ev.derived_from = None; + } } match f { @@ -304,73 +409,106 @@ fn expand_field( fn derive_enumerated_values( ev: &mut EnumeratedValues, - regparent: &str, - rpath: &str, - fpath: &str, + dpath: &str, + fpath: &FPath, index: &Index, ) -> Result<()> { - if let Some(dpath) = ev.derived_from.as_ref() { - let d = match dpath.chars().filter(|&c| c == '.').count() { - // Only EVNAME: Must be in one of fields in same register - 0 => { - if let Some(r) = index.registers.get(rpath) { - let mut found = None; - 'outer: for f in r.fields() { - for e in &f.enumerated_values { - if e.name.as_deref() == Some(dpath) { - found = Some(e); - break 'outer; - } - } + let mut v: Vec<&str> = dpath.split('.').collect(); + let dname = v.pop().unwrap().to_string(); + let d = if v.is_empty() { + // Only EVNAME: Must be in one of fields in same register + let rdpath = &fpath.register; + if let Some(r) = index.registers.get(&rdpath.parent_name()) { + let mut found = None; + 'outer: for f in r.fields() { + for e in &f.enumerated_values { + if e.name.as_deref() == Some(dpath) { + let fdpath = FPath::new(rdpath, &f.name); + found = Some((e, fdpath)); + break 'outer; } - found - } else { - None } } - // FIELD.EVNAME: Search in same field - 1 => index.evs.get(&format!("{}.{}", rpath, dpath)).copied(), - // FULL.PATH.EVNAME: - 2 => index.evs.get(&format!("{}.{}", regparent, dpath)).copied(), - _ => index.evs.get(dpath).copied(), - }; - if let Some(d) = d { - if d.derived_from.is_some() { - return Err(anyhow!("multiple derive for {} is not supported", dpath)); - } - *ev = ev.derive_from(d); - ev.derived_from = None; + found } else { - return Err(anyhow!( - "enumeratedValues {} not found, parent field: {}, regparent: {}", - dpath, - fpath, - regparent, - )); + None + } + } else { + let fdname = v.pop().unwrap().to_string(); + if v.is_empty() { + // FIELD.EVNAME + let fdpath = FPath::new(&fpath.register, &fdname); + index + .evs + .get(&(fdpath.clone(), dname)) + .copied() + .map(|d| (d, fdpath)) + } else { + let (rdpath, rdname) = RPath::split_vec(v); + let rdpath = if let Some(rdpath) = rdpath { + // FULL.PATH.EVNAME: + rdpath + } else { + // REG.FIELD.EVNAME + let mut rdpath = fpath.register.parent(); + rdpath.path.push(rdname); + rdpath + }; + let fdpath = FPath::new(&rdpath, &fdname); + index + .evs + .get(&(fdpath.clone(), dname)) + .copied() + .map(|d| (d, fdpath)) } + }; + + if let Some((d, fdpath)) = d { + *ev = ev.derive_from(d); + if let Some(dpath) = d.derived_from.as_ref() { + derive_enumerated_values(ev, dpath, &fdpath, index)?; + } + } else { + return Err(anyhow!( + "enumeratedValues {} not found, parent field: {:?}", + dpath, + fpath, + )); } Ok(()) } +fn derive_peripheral(p: &mut Peripheral, dpath: &str, index: &Index) -> Result> { + let mut path = None; + let d = index + .peripherals + .get(dpath) + .ok_or_else(|| anyhow!("peripheral {} not found", dpath))?; + if p.registers.is_none() { + path = Some(RPath::new(dpath)); + } + *p = p.derive_from(d); + if let Some(dpath) = d.derived_from.as_ref() { + path = derive_peripheral(p, dpath, index)?; + } + Ok(path) +} + /// Creates clone of device with expanded arrays of peripherals, clusters, registers and fields. /// Also resolves all `derivedFrom` reference pathes pub fn expand(indevice: &Device) -> Result { let mut device = indevice.clone(); - let index = Index::create(&indevice); + let index = Index::create(indevice); let peripherals = take(&mut device.peripherals); for mut p in peripherals { - let mut path = p.name.to_string(); + let mut path = None; if let Some(dpath) = p.derived_from.as_ref() { - path = dpath.into(); - if let Some(d) = index.get_base_peripheral(dpath) { - p = p.derive_from(d); - p.derived_from = None; - } else { - return Err(anyhow!("peripheral {} not found", dpath)); - } + let dpath = dpath.to_string(); + path = derive_peripheral(&mut p, &dpath, &index)?; } + let path = path.unwrap_or_else(|| RPath::new(&p.name)); if let Some(regs) = p.registers.as_mut() { for rc in take(regs) { expand_register_cluster(regs, rc, &path, &index)?; @@ -402,7 +540,7 @@ pub fn expand(indevice: &Device) -> Result { /// Takes register `size`, `access`, `reset_value` and `reset_mask` /// from peripheral or device properties if absent in register pub fn expand_properties(device: &mut Device) { - let default = device.default_register_properties.clone(); + let default = device.default_register_properties; for p in &mut device.peripherals { if p.derived_from.is_some() { continue; @@ -421,7 +559,7 @@ fn expand_properties_registers(regs: &mut [RegisterCluster], default: &RegisterP if c.derived_from.is_some() { continue; } - let default = c.default_register_properties.derive_from(&default); + let default = c.default_register_properties.derive_from(default); expand_properties_registers(&mut c.children, &default); } RegisterCluster::Register(r) => { From 9a4b4fc61fb1fae7dca0c89c4509b5159842275e Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Wed, 11 May 2022 21:41:23 +0300 Subject: [PATCH 2/2] review & other fixes --- svd-parser/src/expand.rs | 243 +++++++++++++++++++-------------------- 1 file changed, 117 insertions(+), 126 deletions(-) diff --git a/svd-parser/src/expand.rs b/svd-parser/src/expand.rs index 197d6564..3d061144 100644 --- a/svd-parser/src/expand.rs +++ b/svd-parser/src/expand.rs @@ -9,12 +9,12 @@ use svd_rs::{ }; #[derive(Clone, Debug, PartialEq, Hash, Eq)] -pub struct RPath { +pub struct RegisterPath { peripheral: String, path: Vec, } -impl RPath { +impl RegisterPath { pub fn new(p: &str) -> Self { Self { peripheral: p.into(), @@ -39,27 +39,24 @@ impl RPath { (Some(rpath), name) } } - pub fn parent_name(&self) -> (Self, String) { - let mut parent = self.clone(); - let name = parent.path.pop().unwrap(); - (parent, name) - } pub fn parent(&self) -> Self { - self.parent_name().0 + let mut parent = self.clone(); + parent.path.pop(); + parent } } #[derive(Clone, Debug, PartialEq, Hash, Eq)] -pub struct FPath { - register: RPath, - field: String, +pub struct FieldPath { + register: RegisterPath, + name: String, } -impl FPath { - pub fn new(r: &RPath, name: &str) -> Self { +impl FieldPath { + pub fn new(r: &RegisterPath, name: &str) -> Self { Self { register: r.clone(), - field: name.into(), + name: name.into(), } } } @@ -67,17 +64,17 @@ impl FPath { #[derive(Clone, Debug, Default)] struct Index<'a> { peripherals: HashMap, - clusters: HashMap<(RPath, String), &'a Cluster>, - registers: HashMap<(RPath, String), &'a Register>, - fields: HashMap<(RPath, String), &'a Field>, - evs: HashMap<(FPath, String), &'a EnumeratedValues>, + clusters: HashMap, + registers: HashMap, + fields: HashMap, + evs: HashMap<(FieldPath, String), &'a EnumeratedValues>, } impl<'a> Index<'a> { fn add_peripheral(&mut self, p: &'a Peripheral) { if let Peripheral::Array(info, dim) = p { for name in names(info, dim) { - let path = RPath::new(&name); + let path = RegisterPath::new(&name); for r in p.registers() { self.add_register(&path, r); } @@ -87,7 +84,7 @@ impl<'a> Index<'a> { self.peripherals.insert(name, p); } } - let path = RPath::new(&p.name); + let path = RegisterPath::new(&p.name); for r in p.registers() { self.add_register(&path, r); } @@ -97,63 +94,63 @@ impl<'a> Index<'a> { self.peripherals.insert(p.name.clone(), p); } - fn add_cluster(&mut self, path: &RPath, c: &'a Cluster) { + fn add_cluster(&mut self, path: &RegisterPath, c: &'a Cluster) { if let Cluster::Array(info, dim) = c { for name in names(info, dim) { - let cpath = RPath::new_child(path, &name); + let cpath = RegisterPath::new_child(path, &name); for r in c.registers() { self.add_register(&cpath, r); } for c in c.clusters() { self.add_cluster(&cpath, c); } - self.clusters.insert((path.clone(), name), c); + self.clusters.insert(cpath, c); } } - let cpath = RPath::new_child(path, &c.name); + let cpath = RegisterPath::new_child(path, &c.name); for r in c.registers() { self.add_register(&cpath, r); } for c in c.clusters() { self.add_cluster(&cpath, c); } - self.clusters.insert((path.clone(), c.name.to_string()), c); + self.clusters.insert(cpath, c); } - fn add_register(&mut self, path: &RPath, r: &'a Register) { + fn add_register(&mut self, path: &RegisterPath, r: &'a Register) { if let Register::Array(info, dim) = r { for name in names(info, dim) { - let rpath = RPath::new_child(path, &name); + let rpath = RegisterPath::new_child(path, &name); for f in r.fields() { self.add_field(&rpath, f); } - self.registers.insert((path.clone(), name), r); + self.registers.insert(rpath, r); } } - let rpath = RPath::new_child(path, &r.name); + let rpath = RegisterPath::new_child(path, &r.name); for f in r.fields() { self.add_field(&rpath, f); } - self.registers.insert((path.clone(), r.name.to_string()), r); + self.registers.insert(rpath, r); } - fn add_field(&mut self, path: &RPath, f: &'a Field) { + fn add_field(&mut self, path: &RegisterPath, f: &'a Field) { if let Field::Array(info, dim) = f { for name in names(info, dim) { - let fpath = FPath::new(path, &name); + let fpath = FieldPath::new(path, &name); for evs in &f.enumerated_values { if let Some(name) = evs.name.as_ref() { self.evs.insert((fpath.clone(), name.to_string()), evs); } } - self.fields.insert((path.clone(), name), f); + self.fields.insert(fpath, f); } } - let fpath = FPath::new(path, &f.name); + let fpath = FieldPath::new(path, &f.name); for evs in &f.enumerated_values { if let Some(name) = evs.name.as_ref() { self.evs.insert((fpath.clone(), name.to_string()), evs); } } - self.fields.insert((path.clone(), f.name.to_string()), f); + self.fields.insert(fpath, f); } pub fn create(device: &'a Device) -> Self { @@ -168,7 +165,7 @@ impl<'a> Index<'a> { fn expand_register_cluster( regs: &mut Vec, rc: RegisterCluster, - path: &RPath, + path: &RegisterPath, index: &Index, ) -> Result<()> { match rc { @@ -181,7 +178,7 @@ fn expand_register_cluster( fn expand_cluster_array( regs: &mut Vec, mut c: Cluster, - path: &RPath, + path: &RegisterPath, index: &Index, ) -> Result<()> { let mut cpath = None; @@ -190,7 +187,7 @@ fn expand_cluster_array( cpath = derive_cluster(&mut c, &dpath, path, index)?; c.derived_from = None; } - let cpath = cpath.unwrap_or_else(|| RPath::new_child(path, &c.name)); + let cpath = cpath.unwrap_or_else(|| RegisterPath::new_child(path, &c.name)); for rc in take(&mut c.children) { expand_register_cluster(&mut c.children, rc, &cpath, index)?; @@ -218,34 +215,30 @@ fn expand_cluster_array( fn derive_cluster( c: &mut Cluster, dpath: &str, - path: &RPath, + path: &RegisterPath, index: &Index, -) -> Result> { - let mut cpath = None; +) -> Result> { + let (dparent, dname) = RegisterPath::split_str(dpath); let rdpath; - let (dparent, dname) = RPath::split_str(dpath); - let d = (match dparent { - Some(dparent) => { - if c.children.is_empty() { - cpath = Some(RPath::new_child(&dparent, &dname)); - } - rdpath = dparent.clone(); - index.clusters.get(&(dparent, dname)) - } - None => { - if c.children.is_empty() { - cpath = Some(RPath::new_child(path, &dname)); - } - rdpath = path.clone(); - index.clusters.get(&(path.clone(), dname)) - } + let cluster_path; + let d = (if let Some(dparent) = dparent { + cluster_path = RegisterPath::new_child(&dparent, &dname); + rdpath = dparent; + index.clusters.get(&cluster_path) + } else { + cluster_path = RegisterPath::new_child(path, &dname); + rdpath = path.clone(); + index.clusters.get(&cluster_path) }) .ok_or_else(|| anyhow!("cluster {} not found", dpath))?; + let mut cpath = None; + if c.children.is_empty() { + cpath = Some(cluster_path); + } *c = c.derive_from(d); if let Some(dpath) = d.derived_from.as_ref() { cpath = derive_cluster(c, dpath, &rdpath, index)?; - c.derived_from = None; } Ok(cpath) } @@ -253,30 +246,27 @@ fn derive_cluster( fn derive_register( r: &mut Register, dpath: &str, - path: &RPath, + path: &RegisterPath, index: &Index, -) -> Result> { - let mut rpath = None; +) -> Result> { + let (dparent, dname) = RegisterPath::split_str(dpath); let rdpath; - let (dparent, dname) = RPath::split_str(dpath); - let d = (match dparent { - Some(dparent) => { - if r.fields.is_none() { - rpath = Some(RPath::new_child(&dparent, &dname)); - } - rdpath = dparent.clone(); - index.registers.get(&(dparent, dname)) - } - None => { - if r.fields.is_none() { - rpath = Some(RPath::new_child(path, &dname)); - } - rdpath = path.clone(); - index.registers.get(&(path.clone(), dname)) - } + let reg_path; + let d = (if let Some(dparent) = dparent { + reg_path = RegisterPath::new_child(&dparent, &dname); + rdpath = dparent; + index.registers.get(®_path) + } else { + reg_path = RegisterPath::new_child(path, &dname); + rdpath = path.clone(); + index.registers.get(®_path) }) .ok_or_else(|| anyhow!("register {} not found", dpath))?; + let mut rpath = None; + if r.fields.is_none() { + rpath = Some(reg_path); + } *r = r.derive_from(d); if let Some(dpath) = d.derived_from.as_ref() { rpath = derive_register(r, dpath, &rdpath, index)?; @@ -284,28 +274,30 @@ fn derive_register( Ok(rpath) } -fn derive_field(f: &mut Field, dpath: &str, rpath: &RPath, index: &Index) -> Result> { - let mut fpath = None; - let (dparent, dname) = RPath::split_str(dpath); +fn derive_field( + f: &mut Field, + dpath: &str, + rpath: &RegisterPath, + index: &Index, +) -> Result> { + let (dparent, dname) = RegisterPath::split_str(dpath); let rdpath; - let d = (match dparent { - Some(dparent) => { - if f.enumerated_values.is_empty() { - fpath = Some(FPath::new(&dparent, &dname)); - } - rdpath = dparent.clone(); - index.fields.get(&(dparent, dname)) - } - None => { - if f.enumerated_values.is_empty() { - fpath = Some(FPath::new(rpath, &dname)); - } - rdpath = rpath.clone(); - index.fields.get(&(rpath.clone(), dname)) - } + let field_path; + let d = (if let Some(dparent) = dparent { + field_path = FieldPath::new(&dparent, &dname); + rdpath = dparent; + index.fields.get(&field_path) + } else { + field_path = FieldPath::new(rpath, &dname); + rdpath = rpath.clone(); + index.fields.get(&field_path) }) .ok_or_else(|| anyhow!("field {} not found", dpath))?; + let mut fpath = None; + if f.enumerated_values.is_empty() { + fpath = Some(field_path); + } *f = f.derive_from(d); if let Some(dpath) = d.derived_from.as_ref() { fpath = derive_field(f, dpath, &rdpath, index)?; @@ -329,7 +321,7 @@ fn expand_cluster(regs: &mut Vec, c: ClusterInfo) { fn expand_register_array( regs: &mut Vec, mut r: Register, - path: &RPath, + path: &RegisterPath, index: &Index, ) -> Result<()> { let mut rpath = None; @@ -338,7 +330,7 @@ fn expand_register_array( rpath = derive_register(&mut r, &dpath, path, index)?; r.derived_from = None; } - let rpath = rpath.unwrap_or_else(|| RPath::new_child(path, &r.name)); + let rpath = rpath.unwrap_or_else(|| RegisterPath::new_child(path, &r.name)); if let Some(field) = r.fields.as_mut() { for f in take(field) { @@ -367,14 +359,19 @@ fn expand_register_array( Ok(()) } -fn expand_field(fields: &mut Vec, mut f: Field, rpath: &RPath, index: &Index) -> Result<()> { +fn expand_field( + fields: &mut Vec, + mut f: Field, + rpath: &RegisterPath, + index: &Index, +) -> Result<()> { let mut fpath = None; if let Some(dpath) = f.derived_from.as_ref() { let dpath = dpath.to_string(); fpath = derive_field(&mut f, &dpath, rpath, index)?; f.derived_from = None; } - let fpath = fpath.unwrap_or_else(|| FPath::new(rpath, &f.name)); + let fpath = fpath.unwrap_or_else(|| FieldPath::new(rpath, &f.name)); for ev in &mut f.enumerated_values { if let Some(dpath) = ev.derived_from.as_ref() { @@ -410,7 +407,7 @@ fn expand_field(fields: &mut Vec, mut f: Field, rpath: &RPath, index: &In fn derive_enumerated_values( ev: &mut EnumeratedValues, dpath: &str, - fpath: &FPath, + fpath: &FieldPath, index: &Index, ) -> Result<()> { let mut v: Vec<&str> = dpath.split('.').collect(); @@ -418,15 +415,13 @@ fn derive_enumerated_values( let d = if v.is_empty() { // Only EVNAME: Must be in one of fields in same register let rdpath = &fpath.register; - if let Some(r) = index.registers.get(&rdpath.parent_name()) { + if let Some(r) = index.registers.get(rdpath) { let mut found = None; - 'outer: for f in r.fields() { - for e in &f.enumerated_values { - if e.name.as_deref() == Some(dpath) { - let fdpath = FPath::new(rdpath, &f.name); - found = Some((e, fdpath)); - break 'outer; - } + for f in r.fields() { + let fdpath = FieldPath::new(rdpath, &f.name); + if let Some(d) = index.evs.get(&(fdpath.clone(), dname.clone())) { + found = Some((d, fdpath)); + break; } } found @@ -435,16 +430,11 @@ fn derive_enumerated_values( } } else { let fdname = v.pop().unwrap().to_string(); - if v.is_empty() { + let fdpath = if v.is_empty() { // FIELD.EVNAME - let fdpath = FPath::new(&fpath.register, &fdname); - index - .evs - .get(&(fdpath.clone(), dname)) - .copied() - .map(|d| (d, fdpath)) + FieldPath::new(&fpath.register, &fdname) } else { - let (rdpath, rdname) = RPath::split_vec(v); + let (rdpath, rdname) = RegisterPath::split_vec(v); let rdpath = if let Some(rdpath) = rdpath { // FULL.PATH.EVNAME: rdpath @@ -454,13 +444,9 @@ fn derive_enumerated_values( rdpath.path.push(rdname); rdpath }; - let fdpath = FPath::new(&rdpath, &fdname); - index - .evs - .get(&(fdpath.clone(), dname)) - .copied() - .map(|d| (d, fdpath)) - } + FieldPath::new(&rdpath, &fdname) + }; + index.evs.get(&(fdpath.clone(), dname)).map(|d| (d, fdpath)) }; if let Some((d, fdpath)) = d { @@ -478,18 +464,23 @@ fn derive_enumerated_values( Ok(()) } -fn derive_peripheral(p: &mut Peripheral, dpath: &str, index: &Index) -> Result> { +fn derive_peripheral( + p: &mut Peripheral, + dpath: &str, + index: &Index, +) -> Result> { let mut path = None; let d = index .peripherals .get(dpath) .ok_or_else(|| anyhow!("peripheral {} not found", dpath))?; if p.registers.is_none() { - path = Some(RPath::new(dpath)); + path = Some(RegisterPath::new(dpath)); } *p = p.derive_from(d); if let Some(dpath) = d.derived_from.as_ref() { path = derive_peripheral(p, dpath, index)?; + p.derived_from = None; } Ok(path) } @@ -508,7 +499,7 @@ pub fn expand(indevice: &Device) -> Result { let dpath = dpath.to_string(); path = derive_peripheral(&mut p, &dpath, &index)?; } - let path = path.unwrap_or_else(|| RPath::new(&p.name)); + let path = path.unwrap_or_else(|| RegisterPath::new(&p.name)); if let Some(regs) = p.registers.as_mut() { for rc in take(regs) { expand_register_cluster(regs, rc, &path, &index)?;