Skip to content

Commit 5d80c8f

Browse files
committed
collect_in_array descriptions
1 parent 1b908c1 commit 5d80c8f

File tree

5 files changed

+97
-20
lines changed

5 files changed

+97
-20
lines changed

example/common_patches/tsc/tsc.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ TSC:
44
IOHCR:
55
_array:
66
G1_IO?: {}
7-
G2_IO*:
8-
_derivedFrom: "G1_IO1"
7+
#G2_IO*:
8+
# _derivedFrom: "G1_IO1"

example/incomplete-stm32l4x2.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
_svd: stm32l4x2.svd
22

3+
LCD:
4+
RAM_COM6:
5+
_array:
6+
S?? : {}
7+
38
# SVD incorrectly labels APB1ENR1 bit 18 as USART1EN instead of USART3EN.
49
# SVD incorrectly labels APB1ENR1 bit 26 as USBF instead of USBFSEN.
510
RCC:

src/patch/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,46 @@ fn check_offsets(offsets: &[u32], dim_increment: u32) -> bool {
637637
}
638638
true
639639
}
640+
641+
/// Tries to get common description (or displayNames) for register/field array with "%s" in index position.
642+
/// Returns `None` if incoming descriptions have more then 1 difference
643+
fn common_description(descs: &[Option<&str>], dim_index: &[String]) -> Option<Option<String>> {
644+
if let Some(desc0) = descs[0] {
645+
let idx0 = &dim_index[0];
646+
if desc0.contains(idx0) {
647+
for (i1, _) in desc0.match_indices(idx0) {
648+
let (s1, sx) = desc0.split_at(i1);
649+
let (_, s2) = sx.split_at(idx0.len());
650+
let dsc = Some(format!("{s1}%s{s2}"));
651+
let mut same = true;
652+
for (d, idx) in descs.iter().zip(dim_index).skip(1) {
653+
if d != &dsc
654+
.as_ref()
655+
.map(|desc| desc.replacen("%s", idx, 1))
656+
.as_deref()
657+
{
658+
same = false;
659+
break;
660+
}
661+
}
662+
if same {
663+
return Some(dsc);
664+
}
665+
}
666+
}
667+
}
668+
// If descriptions are identical, do not change.
669+
let desc0 = &descs[0];
670+
let mut same = true;
671+
for d in descs.iter().skip(1) {
672+
if d != desc0 {
673+
same = false;
674+
break;
675+
}
676+
}
677+
if same {
678+
Some(desc0.map(Into::into))
679+
} else {
680+
None
681+
}
682+
}

src/patch/peripheral.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use super::iterators::{MatchIter, Matched};
1010
use super::register::{RegisterExt, RegisterInfoExt};
1111
use super::yaml_ext::{AsType, GetVal, ToYaml};
1212
use super::{
13-
check_offsets, make_dim_element, matchname, matchsubspec, modify_dim_element, spec_ind,
14-
PatchResult, VAL_LVL,
13+
check_offsets, common_description, make_dim_element, matchname, matchsubspec,
14+
modify_dim_element, spec_ind, PatchResult, VAL_LVL,
1515
};
1616
use super::{make_cluster, make_interrupt, make_register};
1717

@@ -1207,21 +1207,43 @@ fn collect_in_array(
12071207
path
12081208
));
12091209
}
1210-
let mut rinfo = registers.swap_remove(0);
1211-
rinfo.name = if let Some(name) = rmod.get_str("name")? {
1210+
1211+
registers[0].name = if let Some(name) = rmod.get_str("name")? {
12121212
name.into()
12131213
} else {
12141214
format!("{}%s{}", &rspec[..li], &rspec[rspec.len() - ri..])
12151215
};
1216+
12161217
if let Some(desc) = rmod.get_str("description")? {
12171218
if desc != "_original" {
1218-
rinfo.description = Some(desc.into());
1219+
registers[0].description = Some(desc.into());
12191220
}
1220-
} else if dim_index[0] == "0" {
1221-
if let Some(desc) = rinfo.description.as_mut() {
1222-
*desc = desc.replace('0', "%s");
1221+
} else {
1222+
let descs: Vec<_> = registers.iter().map(|r| r.description.as_deref()).collect();
1223+
registers[0].description = common_description(&descs, &dim_index).ok_or_else(|| {
1224+
anyhow!(
1225+
"{}: registers cannot be collected into {rspec} array. Please, specify description",
1226+
path
1227+
)
1228+
})?;
1229+
}
1230+
if let Some(dname) = rmod.get_str("displayName")? {
1231+
if dname != "_original" {
1232+
registers[0].display_name = Some(dname.into());
12231233
}
1234+
} else {
1235+
let names: Vec<_> = registers
1236+
.iter()
1237+
.map(|r| r.display_name.as_deref())
1238+
.collect();
1239+
registers[0].display_name = common_description(&names, &dim_index).ok_or_else(|| {
1240+
anyhow!(
1241+
"{}: registers cannot be collected into {rspec} array. Please, specify displayName",
1242+
path
1243+
)
1244+
})?;
12241245
}
1246+
let rinfo = registers.swap_remove(0);
12251247
let mut reg = rinfo.array(
12261248
DimElement::builder()
12271249
.dim(dim as u32)

src/patch/register.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use yaml_rust::{yaml::Hash, Yaml};
99
use super::iterators::{MatchIter, Matched};
1010
use super::yaml_ext::{AsType, GetVal, ToYaml};
1111
use super::{
12-
check_offsets, make_dim_element, matchname, modify_dim_element, spec_ind, PatchResult, VAL_LVL,
12+
check_offsets, common_description, make_dim_element, matchname, modify_dim_element, spec_ind,
13+
PatchResult, VAL_LVL,
1314
};
1415
use super::{make_derived_enumerated_values, make_ev_array, make_ev_name, make_field};
1516

@@ -404,21 +405,27 @@ impl RegisterExt for Register {
404405
self.name
405406
));
406407
}
407-
let mut finfo = fields.swap_remove(0);
408-
if let Some(name) = fmod.get_str("name")? {
409-
finfo.name = name.into();
408+
fields[0].name = if let Some(name) = fmod.get_str("name")? {
409+
name.into()
410410
} else {
411-
finfo.name = format!("{}%s{}", &fspec[..li], &fspec[fspec.len() - ri..]);
412-
}
411+
format!("{}%s{}", &fspec[..li], &fspec[fspec.len() - ri..])
412+
};
413413
if let Some(desc) = fmod.get_str("description")? {
414414
if desc != "_original" {
415-
finfo.description = Some(desc.into());
415+
fields[0].description = Some(desc.into());
416416
}
417-
} else if dim_index[0] == "0" {
418-
if let Some(desc) = finfo.description.as_mut() {
419-
*desc = desc.replace('0', "%s");
417+
} else {
418+
let descs: Vec<_> = fields.iter().map(|r| r.description.as_deref()).collect();
419+
if let Some(desc) = common_description(&descs, &dim_index) {
420+
fields[0].description = desc;
421+
} else {
422+
return Err(anyhow!(
423+
"{}: fields cannot be collected into {fspec} array. Please, specify description",
424+
self.name
425+
));
420426
}
421427
}
428+
let finfo = fields.swap_remove(0);
422429
let field = finfo.array(
423430
DimElement::builder()
424431
.dim(dim as u32)

0 commit comments

Comments
 (0)