Skip to content

Commit

Permalink
collect_in_array descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Nov 24, 2023
1 parent 1b908c1 commit 5d80c8f
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 20 deletions.
4 changes: 2 additions & 2 deletions example/common_patches/tsc/tsc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ TSC:
IOHCR:
_array:
G1_IO?: {}
G2_IO*:
_derivedFrom: "G1_IO1"
#G2_IO*:
# _derivedFrom: "G1_IO1"
5 changes: 5 additions & 0 deletions example/incomplete-stm32l4x2.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
_svd: stm32l4x2.svd

LCD:
RAM_COM6:
_array:
S?? : {}

# SVD incorrectly labels APB1ENR1 bit 18 as USART1EN instead of USART3EN.
# SVD incorrectly labels APB1ENR1 bit 26 as USBF instead of USBFSEN.
RCC:
Expand Down
43 changes: 43 additions & 0 deletions src/patch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,3 +637,46 @@ fn check_offsets(offsets: &[u32], dim_increment: u32) -> bool {
}
true
}

/// Tries to get common description (or displayNames) for register/field array with "%s" in index position.
/// Returns `None` if incoming descriptions have more then 1 difference
fn common_description(descs: &[Option<&str>], dim_index: &[String]) -> Option<Option<String>> {
if let Some(desc0) = descs[0] {
let idx0 = &dim_index[0];
if desc0.contains(idx0) {
for (i1, _) in desc0.match_indices(idx0) {
let (s1, sx) = desc0.split_at(i1);
let (_, s2) = sx.split_at(idx0.len());
let dsc = Some(format!("{s1}%s{s2}"));
let mut same = true;
for (d, idx) in descs.iter().zip(dim_index).skip(1) {
if d != &dsc
.as_ref()
.map(|desc| desc.replacen("%s", idx, 1))
.as_deref()
{
same = false;
break;
}
}
if same {
return Some(dsc);
}
}
}
}
// If descriptions are identical, do not change.
let desc0 = &descs[0];
let mut same = true;
for d in descs.iter().skip(1) {
if d != desc0 {
same = false;
break;
}
}
if same {
Some(desc0.map(Into::into))
} else {
None
}
}
38 changes: 30 additions & 8 deletions src/patch/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use super::iterators::{MatchIter, Matched};
use super::register::{RegisterExt, RegisterInfoExt};
use super::yaml_ext::{AsType, GetVal, ToYaml};
use super::{
check_offsets, make_dim_element, matchname, matchsubspec, modify_dim_element, spec_ind,
PatchResult, VAL_LVL,
check_offsets, common_description, make_dim_element, matchname, matchsubspec,
modify_dim_element, spec_ind, PatchResult, VAL_LVL,
};
use super::{make_cluster, make_interrupt, make_register};

Expand Down Expand Up @@ -1207,21 +1207,43 @@ fn collect_in_array(
path
));
}
let mut rinfo = registers.swap_remove(0);
rinfo.name = if let Some(name) = rmod.get_str("name")? {

registers[0].name = if let Some(name) = rmod.get_str("name")? {
name.into()
} else {
format!("{}%s{}", &rspec[..li], &rspec[rspec.len() - ri..])
};

if let Some(desc) = rmod.get_str("description")? {
if desc != "_original" {
rinfo.description = Some(desc.into());
registers[0].description = Some(desc.into());
}
} else if dim_index[0] == "0" {
if let Some(desc) = rinfo.description.as_mut() {
*desc = desc.replace('0', "%s");
} else {
let descs: Vec<_> = registers.iter().map(|r| r.description.as_deref()).collect();
registers[0].description = common_description(&descs, &dim_index).ok_or_else(|| {
anyhow!(
"{}: registers cannot be collected into {rspec} array. Please, specify description",
path
)
})?;
}
if let Some(dname) = rmod.get_str("displayName")? {
if dname != "_original" {
registers[0].display_name = Some(dname.into());
}
} else {
let names: Vec<_> = registers
.iter()
.map(|r| r.display_name.as_deref())
.collect();
registers[0].display_name = common_description(&names, &dim_index).ok_or_else(|| {
anyhow!(
"{}: registers cannot be collected into {rspec} array. Please, specify displayName",
path
)
})?;
}
let rinfo = registers.swap_remove(0);
let mut reg = rinfo.array(
DimElement::builder()
.dim(dim as u32)
Expand Down
27 changes: 17 additions & 10 deletions src/patch/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use yaml_rust::{yaml::Hash, Yaml};
use super::iterators::{MatchIter, Matched};
use super::yaml_ext::{AsType, GetVal, ToYaml};
use super::{
check_offsets, make_dim_element, matchname, modify_dim_element, spec_ind, PatchResult, VAL_LVL,
check_offsets, common_description, make_dim_element, matchname, modify_dim_element, spec_ind,
PatchResult, VAL_LVL,
};
use super::{make_derived_enumerated_values, make_ev_array, make_ev_name, make_field};

Expand Down Expand Up @@ -404,21 +405,27 @@ impl RegisterExt for Register {
self.name
));
}
let mut finfo = fields.swap_remove(0);
if let Some(name) = fmod.get_str("name")? {
finfo.name = name.into();
fields[0].name = if let Some(name) = fmod.get_str("name")? {
name.into()
} else {
finfo.name = format!("{}%s{}", &fspec[..li], &fspec[fspec.len() - ri..]);
}
format!("{}%s{}", &fspec[..li], &fspec[fspec.len() - ri..])
};
if let Some(desc) = fmod.get_str("description")? {
if desc != "_original" {
finfo.description = Some(desc.into());
fields[0].description = Some(desc.into());
}
} else if dim_index[0] == "0" {
if let Some(desc) = finfo.description.as_mut() {
*desc = desc.replace('0', "%s");
} else {
let descs: Vec<_> = fields.iter().map(|r| r.description.as_deref()).collect();
if let Some(desc) = common_description(&descs, &dim_index) {
fields[0].description = desc;
} else {
return Err(anyhow!(
"{}: fields cannot be collected into {fspec} array. Please, specify description",
self.name
));
}
}
let finfo = fields.swap_remove(0);
let field = finfo.array(
DimElement::builder()
.dim(dim as u32)
Expand Down

0 comments on commit 5d80c8f

Please sign in to comment.