Skip to content

Commit ecf8de9

Browse files
authored
Merge pull request #280 from rust-embedded/add-position
Calculate _add position for peripherals and registers
2 parents c605222 + 7ba7e53 commit ecf8de9

File tree

5 files changed

+59
-10
lines changed

5 files changed

+59
-10
lines changed

CHANGELOG-rust.md

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

66
## [Unreleased]
77

8+
* Calculate `_add` position for peripherals and registers
9+
810
## [v0.4.4] 2025-02-08
911

1012
* Add `prefix` and `suffix` as opposite to `strip` and `strip_end`

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ rust-version = "1.70"
2929
clap = { version = "4.5", features = ["derive", "cargo", "color"] }
3030
serde = { version = "1.0", features = ["derive"] }
3131
quick-xml = { version = "0.36", features = ["serialize"] }
32-
svd-rs = { version = "0.14.9", features = ["serde", "derive-from"] }
33-
svd-parser = { version = "0.14.7", features = ["expand"] }
34-
svd-encoder = "0.14.5"
32+
svd-rs = { version = "0.14.11", features = ["serde", "derive-from"] }
33+
svd-parser = { version = "0.14.8", features = ["expand"] }
34+
svd-encoder = "0.14.6"
3535
# serde_yaml 0.9.x looks broken
3636
serde_yaml = "0.8.26"
3737
serde_json = { version = "1.0", features = ["preserve_order"] }

src/patch/device.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{fs::File, io::Read, path::Path};
99
use super::iterators::{MatchIter, Matched};
1010
use super::peripheral::{PeripheralExt, RegisterBlockExt};
1111
use super::yaml_ext::{AsType, GetVal};
12-
use super::{abspath, matchname, Config, PatchResult, Spec, VAL_LVL};
12+
use super::{abspath, adding_pos, matchname, Config, PatchResult, Spec, VAL_LVL};
1313
use super::{make_address_block, make_address_blocks, make_cpu, make_interrupt, make_peripheral};
1414
use super::{make_dim_element, modify_dim_element, modify_register_properties};
1515

@@ -307,7 +307,8 @@ impl DeviceExt for Device {
307307
pnew.single()
308308
};
309309

310-
self.peripherals.push(pnew);
310+
let pos = adding_pos(&pnew, &self.peripherals, |p| p.base_address);
311+
self.peripherals.insert(pos, pnew);
311312
Ok(())
312313
}
313314

src/patch/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,20 @@ fn opt_interpolate<T: Interpolate>(path: &Option<&T>, s: Option<&str>) -> Option
853853
}
854854
}
855855

856+
fn adding_pos<'a, T, U: Eq + Ord>(
857+
new: &'a T,
858+
iter: impl IntoIterator<Item = &'a T>,
859+
f: impl Fn(&'a T) -> U,
860+
) -> usize {
861+
let address = f(new);
862+
iter.into_iter()
863+
.enumerate()
864+
.filter(|(_, p)| f(p) <= address)
865+
.max_by_key(|(_, p)| f(p))
866+
.map(|(i, _)| i + 1)
867+
.unwrap_or(0)
868+
}
869+
856870
trait Interpolate {
857871
fn interpolate<'a>(&self, s: &'a str) -> Cow<'a, str>;
858872
fn interpolate_opt(&self, s: Option<&str>) -> Option<String> {

src/patch/peripheral.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use super::iterators::{MatchIter, Matched};
1212
use super::register::{RegisterExt, RegisterInfoExt};
1313
use super::yaml_ext::{AsType, GetVal, ToYaml};
1414
use super::{
15-
check_offsets, common_description, make_dim_element, matchname, matchsubspec,
15+
adding_pos, check_offsets, common_description, make_dim_element, matchname, matchsubspec,
1616
modify_dim_element, spec_ind, Config, PatchResult, Spec, VAL_LVL,
1717
};
1818
use super::{make_cluster, make_interrupt, make_register};
@@ -161,6 +161,14 @@ pub(crate) trait RegisterBlockExt: Name {
161161

162162
fn add_child(&mut self, child: RegisterCluster);
163163

164+
fn insert_child(&mut self, pos: usize, child: RegisterCluster) {
165+
if let Some(children) = self.children_mut() {
166+
children.insert(pos, child);
167+
} else {
168+
self.add_child(child);
169+
}
170+
}
171+
164172
/// Delete registers and clusters matched by rspec inside ptag
165173
fn delete_child(&mut self, rcspec: &str) -> PatchResult {
166174
if let Some(children) = self.children_mut() {
@@ -214,7 +222,8 @@ pub(crate) trait RegisterBlockExt: Name {
214222
Self::RB_TYPE
215223
));
216224
}
217-
self.add_child(RegisterCluster::Register({
225+
226+
let rnew = RegisterCluster::Register({
218227
let reg = make_register(radd, Some(bpath))?
219228
.name(rname.into())
220229
.build(VAL_LVL)?;
@@ -223,7 +232,18 @@ pub(crate) trait RegisterBlockExt: Name {
223232
} else {
224233
reg.single()
225234
}
226-
}));
235+
});
236+
237+
if let Some(children) = self.children() {
238+
let pos = adding_pos(&rnew, children, |rc| match rc {
239+
RegisterCluster::Register(r) => r.address_offset,
240+
RegisterCluster::Cluster(c) => c.address_offset,
241+
});
242+
self.insert_child(pos, rnew);
243+
} else {
244+
self.add_child(rnew);
245+
}
246+
227247
Ok(())
228248
}
229249

@@ -235,7 +255,8 @@ pub(crate) trait RegisterBlockExt: Name {
235255
Self::RB_TYPE
236256
));
237257
}
238-
self.add_child(RegisterCluster::Cluster({
258+
259+
let cnew = RegisterCluster::Cluster({
239260
let cl = make_cluster(cadd, Some(bpath))?
240261
.name(cname.into())
241262
.build(VAL_LVL)?;
@@ -244,7 +265,18 @@ pub(crate) trait RegisterBlockExt: Name {
244265
} else {
245266
cl.single()
246267
}
247-
}));
268+
});
269+
270+
if let Some(children) = self.children() {
271+
let pos = adding_pos(&cnew, children, |rc| match rc {
272+
RegisterCluster::Register(r) => r.address_offset,
273+
RegisterCluster::Cluster(c) => c.address_offset,
274+
});
275+
self.insert_child(pos, cnew);
276+
} else {
277+
self.add_child(cnew);
278+
}
279+
248280
Ok(())
249281
}
250282

0 commit comments

Comments
 (0)