Skip to content

Commit 4bd75cd

Browse files
authored
Merge pull request #253 from rust-embedded/html-derive
Support derived registers/fields in "svdtools html"
2 parents cb60c01 + 1735659 commit 4bd75cd

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

CHANGELOG-rust.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ This changelog tracks the Rust `svdtools` project. See
55

66
## [Unreleased]
77

8+
* Support derived registers/fields in `svdtools html`
9+
810
## [v0.3.19] 2024-10-18
911

1012
* Fix deletion childrens on cluster modify
11-
* Sugar for simple `_split` and `_merge`
13+
* Sugar for simple `_split` and `_merge`
1214

1315
## [v0.3.18] 2024-08-10
1416

@@ -64,7 +66,7 @@ This changelog tracks the Rust `svdtools` project. See
6466
## [v0.3.9] 2024-01-19
6567

6668
* Use `<details>` instead of JavaScript in `html` template
67-
* Fix escape special characters on Windows
69+
* Fix escape special characters on Windows
6870

6971
## [v0.3.8] 2023-12-23
7072

src/html/html_cli.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use liquid::{
1818
};
1919
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
2020
use svd_parser::expand::{
21-
derive_cluster, derive_enumerated_values, derive_register, BlockPath, RegisterPath,
21+
derive_cluster, derive_enumerated_values, derive_field, derive_register, BlockPath,
22+
RegisterPath,
2223
};
2324
use svd_parser::{
2425
expand::{derive_peripheral, Index},
@@ -122,9 +123,12 @@ fn parse_cluster(
122123
cpath: &BlockPath,
123124
index: &Index,
124125
) -> anyhow::Result<()> {
126+
let mut cpath = cpath.clone();
125127
let ctag = if let Some(dfname) = ctag.derived_from.as_ref() {
126128
let mut ctag = ctag.clone();
127-
derive_cluster(&mut ctag, dfname, &cpath.parent().unwrap(), index)?;
129+
if let Some(path) = derive_cluster(&mut ctag, dfname, &cpath.parent().unwrap(), index)? {
130+
cpath = path;
131+
}
128132
Cow::Owned(ctag)
129133
} else {
130134
Cow::Borrowed(ctag)
@@ -162,16 +166,19 @@ fn parse_register_array(
162166
rpath: &RegisterPath,
163167
index: &Index,
164168
) -> anyhow::Result<()> {
169+
let mut rpath = rpath.clone();
165170
let rtag = if let Some(dfname) = rtag.derived_from.as_ref() {
166171
let mut rtag = rtag.clone();
167-
derive_register(&mut rtag, dfname, &rpath.block, index)?;
172+
if let Some(path) = derive_register(&mut rtag, dfname, &rpath.block, index)? {
173+
rpath = path;
174+
}
168175
Cow::Owned(rtag)
169176
} else {
170177
Cow::Borrowed(rtag)
171178
};
172179
match rtag.as_ref() {
173180
Register::Single(r) => {
174-
let register = parse_register(r, rpath, index)
181+
let register = parse_register(r, &rpath, index)
175182
.with_context(|| format!("In register {}", r.name))?;
176183
registers.push(register);
177184
}
@@ -184,7 +191,7 @@ fn parse_register_array(
184191
r.description = r
185192
.description
186193
.map(|d| d.replace("[%s]", &idx).replace("%s", &idx));
187-
let register = parse_register(&r, rpath, index)
194+
let register = parse_register(&r, &rpath, index)
188195
.with_context(|| format!("In register {}", r.name))?;
189196
registers.push(register);
190197
}
@@ -209,9 +216,19 @@ fn parse_register(
209216

210217
let mut flds = Vec::new();
211218
for f in rtag.fields() {
219+
let mut fpath = rpath.new_field(&f.name);
220+
let f = if let Some(dfname) = f.derived_from.as_ref() {
221+
let mut f = f.clone();
222+
if let Some(path) = derive_field(&mut f, dfname, rpath, index)? {
223+
fpath = path;
224+
}
225+
f
226+
} else {
227+
f.clone()
228+
};
212229
match f {
213230
Field::Single(f) => {
214-
flds.push(Cow::Borrowed(f));
231+
flds.push((f, fpath));
215232
}
216233
Field::Array(f, d) => {
217234
for (i, idx) in d.indexes().enumerate() {
@@ -225,22 +242,20 @@ fn parse_register(
225242
f.description = f
226243
.description
227244
.map(|d| d.replace("[%s]", &idx).replace("%s", &idx));
228-
flds.push(Cow::Owned(f));
245+
flds.push((f, fpath.clone()));
229246
}
230247
}
231248
}
232249
}
233250

234-
flds.sort_by_key(|f| f.bit_offset());
251+
flds.sort_by_key(|f| f.0.bit_offset());
235252

236253
let mut filling = 0_u64;
237254

238255
let mut fields = Vec::with_capacity(flds.len());
239-
for ftag in &flds {
256+
for (ftag, fpath) in &flds {
240257
register_fields_total += 1;
241258

242-
let fpath = rpath.new_field(&ftag.name);
243-
244259
let foffset = ftag.bit_offset();
245260
let fwidth = ftag.bit_width();
246261
let bit_mask = (u64::MAX >> (u64::BITS - fwidth)) << foffset;
@@ -256,7 +271,7 @@ fn parse_register(
256271
let mut doc = "Allowed values:<br>".to_string();
257272
let enums = if let Some(dfname) = enums.derived_from.as_ref() {
258273
let mut enums = enums.clone();
259-
derive_enumerated_values(&mut enums, dfname, &fpath, index)?;
274+
derive_enumerated_values(&mut enums, dfname, fpath, index)?;
260275
Cow::Owned(enums)
261276
} else {
262277
Cow::Borrowed(enums)
@@ -310,7 +325,7 @@ fn parse_register(
310325
2
311326
];
312327

313-
for ftag in flds.iter().rev() {
328+
for (ftag, _) in flds.iter().rev() {
314329
let foffset = ftag.bit_offset();
315330
let faccs = ftag.access.map(Access::as_str).unwrap_or(raccs);
316331
let access = short_access(faccs);

0 commit comments

Comments
 (0)