Skip to content

Commit 83d5f10

Browse files
authored
Merge pull request #178 from rust-embedded/desc
collect in cluster/array descriptions
2 parents 1b908c1 + 1721984 commit 83d5f10

File tree

7 files changed

+97
-20
lines changed

7 files changed

+97
-20
lines changed

CHANGELOG-rust.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This changelog tracks the Rust `svdtools` project. See
77

88
* Move field with derived enums before other
99
* `-1` for default enum value
10+
* Update `displayName` during collect, improve searching common `description`
1011
* mmaps: peripheral arrays, bump `svd` crates
1112

1213
## [v0.3.4] 2023-10-14

example/common_patches/tsc/tsc.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ TSC:
44
IOHCR:
55
_array:
66
G1_IO?: {}
7+
G1_IO*:
8+
Disabled: [0, "Gx_IOy Schmitt trigger hysteresis disabled"]
9+
Enabled: [1, "Gx_IOy Schmitt trigger hysteresis enabled"]
710
G2_IO*:
811
_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/html/html_cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ fn parse_register(
245245
filling |= bit_mask;
246246

247247
let faccs = ftag.access.map(Access::as_str).unwrap_or(raccs);
248-
let enums = ftag.enumerated_values.get(0);
248+
let enums = ftag.enumerated_values.first();
249249
let wc = &ftag.write_constraint;
250250
let mut fdoc = None;
251251
if enums.is_some() || wc.is_some() || faccs == "read-only" {

src/patch/mod.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ fn make_dim_element(h: &Hash) -> Result<Option<DimElementBuilder>> {
337337
}
338338
Some(v)
339339
}
340-
_ => return Err(DimIndexParse).map_err(Into::into),
340+
_ => return Err(DimIndexParse.into()),
341341
}
342342
} else {
343343
None
@@ -637,3 +637,42 @@ 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(|dsc| dsc.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[1..] {
672+
if d != desc0 {
673+
same = false;
674+
break;
675+
}
676+
}
677+
same.then(|| desc0.map(Into::into))
678+
}

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)