Skip to content

Commit ec57af9

Browse files
committed
feat: Add keep_list arg to allow not to generate arrays
Use `[%s]` to create arrays and use `%s` to create lists ref: https://www.keil.com/pack/doc/CMSIS/SVD/html/elem_special.html
1 parent 589fb81 commit ec57af9

File tree

3 files changed

+106
-81
lines changed

3 files changed

+106
-81
lines changed

src/generate/peripheral.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,15 @@ fn expand_cluster(
712712
.eq((0..array_info.dim).map(Ok))
713713
});
714714

715-
let array_convertible = sequential_indexes && sequential_addresses;
715+
let convert_list = match config.keep_list {
716+
true => match &array_info.dim_name {
717+
Some(dim_name) => dim_name.contains("[%s]"),
718+
None => info.name.contains("[%s]"),
719+
},
720+
false => true,
721+
};
722+
723+
let array_convertible = sequential_indexes && sequential_addresses && convert_list;
716724

717725
if array_convertible {
718726
cluster_expanded.push(RegisterBlockField {
@@ -776,7 +784,15 @@ fn expand_register(
776784
.eq((0..array_info.dim).map(Ok))
777785
});
778786

779-
let array_convertible = sequential_indexes && sequential_addresses;
787+
let convert_list = match config.keep_list {
788+
true => match &array_info.dim_name {
789+
Some(dim_name) => dim_name.contains("[%s]"),
790+
None => info.name.contains("[%s]"),
791+
},
792+
false => true,
793+
};
794+
795+
let array_convertible = sequential_indexes && sequential_addresses && convert_list;
780796

781797
if array_convertible {
782798
register_expanded.push(RegisterBlockField {

src/main.rs

Lines changed: 86 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -20,86 +20,90 @@ fn run() -> Result<()> {
2020
use clap_conf::prelude::*;
2121
use std::io::Read;
2222

23-
let matches =
24-
App::new("svd2rust")
25-
.about("Generate a Rust API from SVD files")
26-
.arg(
27-
Arg::with_name("input")
28-
.help("Input SVD file")
29-
.short("i")
30-
.takes_value(true)
31-
.value_name("FILE"),
32-
)
33-
.arg(
34-
Arg::with_name("output")
35-
.long("output-dir")
36-
.help("Directory to place generated files")
37-
.short("o")
38-
.takes_value(true)
39-
.value_name("PATH"),
40-
)
41-
.arg(
42-
Arg::with_name("config")
43-
.long("config")
44-
.help("Config TOML file")
45-
.short("c")
46-
.takes_value(true)
47-
.value_name("TOML_FILE"),
48-
)
49-
.arg(
50-
Arg::with_name("target")
51-
.long("target")
52-
.help("Target architecture")
53-
.takes_value(true)
54-
.value_name("ARCH"),
55-
)
56-
.arg(
57-
Arg::with_name("nightly_features")
58-
.long("nightly")
59-
.help("Enable features only available to nightly rustc"),
60-
)
61-
.arg(Arg::with_name("const_generic").long("const_generic").help(
23+
let matches = App::new("svd2rust")
24+
.about("Generate a Rust API from SVD files")
25+
.arg(
26+
Arg::with_name("input")
27+
.help("Input SVD file")
28+
.short("i")
29+
.takes_value(true)
30+
.value_name("FILE"),
31+
)
32+
.arg(
33+
Arg::with_name("output")
34+
.long("output-dir")
35+
.help("Directory to place generated files")
36+
.short("o")
37+
.takes_value(true)
38+
.value_name("PATH"),
39+
)
40+
.arg(
41+
Arg::with_name("config")
42+
.long("config")
43+
.help("Config TOML file")
44+
.short("c")
45+
.takes_value(true)
46+
.value_name("TOML_FILE"),
47+
)
48+
.arg(
49+
Arg::with_name("target")
50+
.long("target")
51+
.help("Target architecture")
52+
.takes_value(true)
53+
.value_name("ARCH"),
54+
)
55+
.arg(
56+
Arg::with_name("nightly_features")
57+
.long("nightly")
58+
.help("Enable features only available to nightly rustc"),
59+
)
60+
.arg(
61+
Arg::with_name("const_generic").long("const_generic").help(
6262
"Use const generics to generate writers for same fields with different offsets",
63-
))
64-
.arg(
65-
Arg::with_name("ignore_groups")
66-
.long("ignore_groups")
67-
.help("Don't add alternateGroup name as prefix to register name"),
68-
)
69-
.arg(
70-
Arg::with_name("generic_mod")
71-
.long("generic_mod")
72-
.short("g")
73-
.help("Push generic mod in separate file"),
74-
)
75-
.arg(
76-
Arg::with_name("make_mod")
77-
.long("make_mod")
78-
.short("m")
79-
.help("Create mod.rs instead of lib.rs, without inner attributes"),
80-
)
81-
.arg(
82-
Arg::with_name("strict")
83-
.long("strict")
84-
.short("s")
85-
.help("Make advanced checks due to parsing SVD"),
86-
)
87-
.arg(
88-
Arg::with_name("log_level")
89-
.long("log")
90-
.short("l")
91-
.help(&format!(
92-
"Choose which messages to log (overrides {})",
93-
env_logger::DEFAULT_FILTER_ENV
94-
))
95-
.takes_value(true)
96-
.possible_values(&["off", "error", "warn", "info", "debug", "trace"]),
97-
)
98-
.version(concat!(
99-
env!("CARGO_PKG_VERSION"),
100-
include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt"))
101-
))
102-
.get_matches();
63+
),
64+
)
65+
.arg(
66+
Arg::with_name("ignore_groups")
67+
.long("ignore_groups")
68+
.help("Don't add alternateGroup name as prefix to register name"),
69+
)
70+
.arg(Arg::with_name("keep_list").long("keep_list").help(
71+
"Keep lists when generating code of dimElement, instead of trying to generate arrays",
72+
))
73+
.arg(
74+
Arg::with_name("generic_mod")
75+
.long("generic_mod")
76+
.short("g")
77+
.help("Push generic mod in separate file"),
78+
)
79+
.arg(
80+
Arg::with_name("make_mod")
81+
.long("make_mod")
82+
.short("m")
83+
.help("Create mod.rs instead of lib.rs, without inner attributes"),
84+
)
85+
.arg(
86+
Arg::with_name("strict")
87+
.long("strict")
88+
.short("s")
89+
.help("Make advanced checks due to parsing SVD"),
90+
)
91+
.arg(
92+
Arg::with_name("log_level")
93+
.long("log")
94+
.short("l")
95+
.help(&format!(
96+
"Choose which messages to log (overrides {})",
97+
env_logger::DEFAULT_FILTER_ENV
98+
))
99+
.takes_value(true)
100+
.possible_values(&["off", "error", "warn", "info", "debug", "trace"]),
101+
)
102+
.version(concat!(
103+
env!("CARGO_PKG_VERSION"),
104+
include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt"))
105+
))
106+
.get_matches();
103107

104108
let xml = &mut String::new();
105109
match matches.value_of("input") {
@@ -144,6 +148,8 @@ fn run() -> Result<()> {
144148
cfg.bool_flag("const_generic", Filter::Arg) || cfg.bool_flag("const_generic", Filter::Conf);
145149
let ignore_groups =
146150
cfg.bool_flag("ignore_groups", Filter::Arg) || cfg.bool_flag("ignore_groups", Filter::Conf);
151+
let keep_list =
152+
cfg.bool_flag("keep_list", Filter::Arg) || cfg.bool_flag("keep_list", Filter::Conf);
147153
let strict = cfg.bool_flag("strict", Filter::Arg) || cfg.bool_flag("strict", Filter::Conf);
148154

149155
let config = Config {
@@ -153,6 +159,7 @@ fn run() -> Result<()> {
153159
make_mod,
154160
const_generic,
155161
ignore_groups,
162+
keep_list,
156163
strict,
157164
output_dir: path.clone(),
158165
};

src/util.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub struct Config {
2424
pub make_mod: bool,
2525
pub const_generic: bool,
2626
pub ignore_groups: bool,
27+
pub keep_list: bool,
2728
pub strict: bool,
2829
pub output_dir: PathBuf,
2930
}
@@ -37,6 +38,7 @@ impl Default for Config {
3738
make_mod: false,
3839
const_generic: false,
3940
ignore_groups: false,
41+
keep_list: false,
4042
strict: false,
4143
output_dir: PathBuf::from("."),
4244
}

0 commit comments

Comments
 (0)