Skip to content

Commit d1ddb1b

Browse files
bors[bot]burrbull
andauthored
Merge #715
715: cows, cows everywhere r=Emilgardis a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 54a7f49 + a5a5fff commit d1ddb1b

File tree

6 files changed

+110
-150
lines changed

6 files changed

+110
-150
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
88
## [Unreleased]
99

1010
- Bump MSRV to 1.65
11+
- Optimize case change/sanitize
1112
- Fix dangling implicit derives
1213
- Fix escaping <> and & characters in doc attributes
1314

ci/svd2rust-regress/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[package]
2-
edition = "2018"
2+
edition = "2021"
33
name = "svd2rust-regress"
44
version = "0.1.0"
55
authors = ["James Munns <[email protected]>", "The svd2rust developers"]
66

77
[dependencies]
8-
reqwest = { version = "0.10", features= ["blocking"] }
8+
clap = { version = "4.1", features = ["color", "derive"] }
9+
svd2rust = { path = "../../" }
10+
reqwest = { version = "0.11", features= ["blocking"] }
911
rayon = "1.4"
10-
structopt = "0.2"
1112
error-chain = "0.12"
12-
inflections = "1.1"

ci/svd2rust-regress/src/main.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod errors;
55
mod svd_test;
66
mod tests;
77

8+
use clap::Parser;
89
use error_chain::ChainedError;
910
use rayon::prelude::*;
1011
use std::fs::File;
@@ -13,92 +14,91 @@ use std::path::PathBuf;
1314
use std::process::{exit, Command};
1415
use std::sync::atomic::{AtomicBool, Ordering};
1516
use std::time::Instant;
16-
use structopt::StructOpt;
1717

18-
#[derive(StructOpt, Debug)]
19-
#[structopt(name = "svd2rust-regress")]
18+
#[derive(Parser, Debug)]
19+
#[command(name = "svd2rust-regress")]
2020
struct Opt {
2121
/// Run a long test (it's very long)
22-
#[structopt(short = "l", long = "long-test")]
22+
#[clap(short = 'l', long)]
2323
long_test: bool,
2424

2525
/// Path to an `svd2rust` binary, relative or absolute.
2626
/// Defaults to `target/release/svd2rust[.exe]` of this repository
2727
/// (which must be already built)
28-
#[structopt(short = "p", long = "svd2rust-path", parse(from_os_str))]
28+
#[clap(short = 'p', long = "svd2rust-path")]
2929
bin_path: Option<PathBuf>,
3030

3131
// TODO: Consider using the same strategy cargo uses for passing args to rustc via `--`
3232
/// Run svd2rust with `--atomics`
33-
#[structopt(long = "atomics")]
33+
#[clap(long)]
3434
atomics: bool,
3535

3636
/// Filter by chip name, case sensitive, may be combined with other filters
37-
#[structopt(short = "c", long = "chip", raw(validator = "validate_chips"))]
37+
#[clap(short = 'c', long, value_parser = validate_chips)]
3838
chip: Vec<String>,
3939

4040
/// Filter by manufacturer, case sensitive, may be combined with other filters
41-
#[structopt(
42-
short = "m",
41+
#[clap(
42+
short = 'm',
4343
long = "manufacturer",
44-
raw(validator = "validate_manufacturer")
44+
value_parser = validate_manufacturer,
4545
)]
4646
mfgr: Option<String>,
4747

4848
/// Filter by architecture, case sensitive, may be combined with other filters
4949
/// Options are: "CortexM", "RiscV", "Msp430", "Mips" and "XtensaLX"
50-
#[structopt(
51-
short = "a",
50+
#[clap(
51+
short = 'a',
5252
long = "architecture",
53-
raw(validator = "validate_architecture")
53+
value_parser = validate_architecture,
5454
)]
5555
arch: Option<String>,
5656

5757
/// Include tests expected to fail (will cause a non-zero return code)
58-
#[structopt(short = "b", long = "bad-tests")]
58+
#[clap(short = 'b', long)]
5959
bad_tests: bool,
6060

6161
/// Enable formatting with `rustfmt`
62-
#[structopt(short = "f", long = "format")]
62+
#[clap(short = 'f', long)]
6363
format: bool,
6464

6565
/// Print all available test using the specified filters
66-
#[structopt(long = "list")]
66+
#[clap(long)]
6767
list: bool,
6868

6969
/// Path to an `rustfmt` binary, relative or absolute.
7070
/// Defaults to `$(rustup which rustfmt)`
71-
#[structopt(long = "rustfmt_bin_path", parse(from_os_str))]
71+
#[clap(long)]
7272
rustfmt_bin_path: Option<PathBuf>,
7373

7474
/// Specify what rustup toolchain to use when compiling chip(s)
75-
#[structopt(long = "toolchain", env = "RUSTUP_TOOLCHAIN")]
75+
#[clap(long = "toolchain")] // , env = "RUSTUP_TOOLCHAIN"
7676
rustup_toolchain: Option<String>,
7777

7878
/// Use verbose output
79-
#[structopt(long = "verbose", short = "v", parse(from_occurrences))]
79+
#[clap(long, short = 'v', action = clap::ArgAction::Count)]
8080
verbose: u8,
8181
// TODO: Specify smaller subset of tests? Maybe with tags?
8282
// TODO: Compile svd2rust?
8383
}
8484

85-
fn validate_chips(s: String) -> Result<(), String> {
85+
fn validate_chips(s: &str) -> Result<(), String> {
8686
if tests::TESTS.iter().any(|t| t.chip == s) {
8787
Ok(())
8888
} else {
8989
Err(format!("Chip `{}` is not a valid value", s))
9090
}
9191
}
9292

93-
fn validate_architecture(s: String) -> Result<(), String> {
93+
fn validate_architecture(s: &str) -> Result<(), String> {
9494
if tests::TESTS.iter().any(|t| format!("{:?}", t.arch) == s) {
9595
Ok(())
9696
} else {
9797
Err(format!("Architecture `{s}` is not a valid value"))
9898
}
9999
}
100100

101-
fn validate_manufacturer(s: String) -> Result<(), String> {
101+
fn validate_manufacturer(s: &str) -> Result<(), String> {
102102
if tests::TESTS.iter().any(|t| format!("{:?}", t.mfgr) == s) {
103103
Ok(())
104104
} else {
@@ -140,7 +140,7 @@ fn read_file(path: &PathBuf, buf: &mut String) {
140140
}
141141

142142
fn main() {
143-
let opt = Opt::from_args();
143+
let opt = Opt::parse();
144144

145145
// Validate all test pre-conditions
146146
validate_tests(tests::TESTS);

ci/svd2rust-regress/src/svd_test.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,16 @@ pub fn test(
127127
.open(svd_toml)
128128
.chain_err(|| "Failed to open Cargo.toml for appending")?;
129129

130-
use crate::tests::Architecture::*;
130+
use crate::tests::Target;
131131
let crates = CRATES_ALL
132132
.iter()
133133
.chain(match &t.arch {
134-
CortexM => CRATES_CORTEX_M.iter(),
135-
RiscV => CRATES_RISCV.iter(),
136-
Mips => CRATES_MIPS.iter(),
137-
Msp430 => CRATES_MSP430.iter(),
138-
XtensaLX => CRATES_XTENSALX.iter(),
134+
Target::CortexM => CRATES_CORTEX_M.iter(),
135+
Target::RISCV => CRATES_RISCV.iter(),
136+
Target::Mips => CRATES_MIPS.iter(),
137+
Target::Msp430 => CRATES_MSP430.iter(),
138+
Target::XtensaLX => CRATES_XTENSALX.iter(),
139+
Target::None => unreachable!(),
139140
})
140141
.chain(if atomics {
141142
CRATES_ATOMICS.iter()
@@ -145,7 +146,7 @@ pub fn test(
145146
.chain(PROFILE_ALL.iter())
146147
.chain(FEATURES_ALL.iter())
147148
.chain(match &t.arch {
148-
XtensaLX => FEATURES_XTENSALX.iter(),
149+
Target::XtensaLX => FEATURES_XTENSALX.iter(),
149150
_ => [].iter(),
150151
});
151152

@@ -170,11 +171,12 @@ pub fn test(
170171
let lib_rs_file = path_helper_base(&chip_dir, &["src", "lib.rs"]);
171172
let svd2rust_err_file = path_helper_base(&chip_dir, &["svd2rust.err.log"]);
172173
let target = match t.arch {
173-
CortexM => "cortex-m",
174-
Msp430 => "msp430",
175-
Mips => "mips",
176-
RiscV => "riscv",
177-
XtensaLX => "xtensa-lx",
174+
Target::CortexM => "cortex-m",
175+
Target::Msp430 => "msp430",
176+
Target::Mips => "mips",
177+
Target::RISCV => "riscv",
178+
Target::XtensaLX => "xtensa-lx",
179+
Target::None => unreachable!(),
178180
};
179181
let mut svd2rust_bin = Command::new(bin_path);
180182
if atomics {
@@ -190,15 +192,18 @@ pub fn test(
190192
output.capture_outputs(
191193
true,
192194
"svd2rust",
193-
Some(&lib_rs_file)
194-
.filter(|_| (t.arch != CortexM) && (t.arch != Msp430) && (t.arch != XtensaLX)),
195+
Some(&lib_rs_file).filter(|_| {
196+
(t.arch != Target::CortexM)
197+
&& (t.arch != Target::Msp430)
198+
&& (t.arch != Target::XtensaLX)
199+
}),
195200
Some(&svd2rust_err_file),
196201
&[],
197202
)?;
198203
process_stderr_paths.push(svd2rust_err_file);
199204

200205
match t.arch {
201-
CortexM | Mips | Msp430 | XtensaLX => {
206+
Target::CortexM | Target::Mips | Target::Msp430 | Target::XtensaLX => {
202207
// TODO: Give error the path to stderr
203208
fs::rename(path_helper_base(&chip_dir, &["lib.rs"]), &lib_rs_file)
204209
.chain_err(|| "While moving lib.rs file")?

ci/svd2rust-regress/src/tests.rs

Lines changed: 6 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
1-
use inflections::Inflect;
2-
use std::borrow::Cow;
3-
4-
#[derive(Debug, PartialEq)]
5-
pub enum Architecture {
6-
// TODO: Coming soon!
7-
// Avr,
8-
CortexM,
9-
Mips,
10-
Msp430,
11-
RiscV,
12-
XtensaLX,
13-
}
1+
pub use svd2rust::util::Target;
2+
use svd2rust::util::ToSanitizedCase;
143

154
#[derive(Debug)]
165
pub enum Manufacturer {
@@ -41,7 +30,7 @@ pub enum RunWhen {
4130
}
4231

4332
pub struct TestCase {
44-
pub arch: Architecture,
33+
pub arch: Target,
4534
pub mfgr: Manufacturer,
4635
pub chip: &'static str,
4736
svd_url: Option<&'static str>,
@@ -75,59 +64,9 @@ impl TestCase {
7564
}
7665
}
7766

78-
use self::Architecture::*;
7967
use self::Manufacturer::*;
8068
use self::RunWhen::*;
81-
82-
/// List of chars that some vendors use in their peripheral/field names but
83-
/// that are not valid in Rust ident
84-
const BLACKLIST_CHARS: &[char] = &['(', ')', '[', ']'];
85-
86-
/// Lovingly stolen from `svd2rust`
87-
pub trait ToSanitizedCase {
88-
fn to_sanitized_not_keyword_snake_case(&self) -> Cow<str>;
89-
fn to_sanitized_snake_case(&self) -> Cow<str> {
90-
let s = self.to_sanitized_not_keyword_snake_case();
91-
sanitize_keyword(s)
92-
}
93-
}
94-
95-
impl ToSanitizedCase for str {
96-
fn to_sanitized_not_keyword_snake_case(&self) -> Cow<str> {
97-
const INTERNALS: [&str; 4] = ["set_bit", "clear_bit", "bit", "bits"];
98-
99-
let s = self.replace(BLACKLIST_CHARS, "");
100-
match s.chars().next().unwrap_or('\0') {
101-
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => {
102-
format!("_{}", s.to_snake_case()).into()
103-
}
104-
_ => {
105-
let s = Cow::from(s.to_snake_case());
106-
if INTERNALS.contains(&s.as_ref()) {
107-
s + "_"
108-
} else {
109-
s
110-
}
111-
}
112-
}
113-
}
114-
}
115-
116-
pub fn sanitize_keyword(sc: Cow<str>) -> Cow<str> {
117-
const KEYWORDS: [&str; 55] = [
118-
"abstract", "alignof", "as", "async", "await", "become", "box", "break", "const",
119-
"continue", "crate", "do", "dyn", "else", "enum", "extern", "false", "final", "fn", "for",
120-
"if", "impl", "in", "let", "loop", "macro", "match", "mod", "move", "mut", "offsetof",
121-
"override", "priv", "proc", "pub", "pure", "ref", "return", "self", "sizeof", "static",
122-
"struct", "super", "trait", "true", "try", "type", "typeof", "unsafe", "unsized", "use",
123-
"virtual", "where", "while", "yield",
124-
];
125-
if KEYWORDS.contains(&sc.as_ref()) {
126-
sc + "_"
127-
} else {
128-
sc
129-
}
130-
}
69+
use self::Target::{CortexM, Mips, Msp430, XtensaLX, RISCV};
13170

13271
// NOTE: All chip names must be unique!
13372
pub const TESTS: &[&TestCase] = &[
@@ -4175,7 +4114,7 @@ pub const TESTS: &[&TestCase] = &[
41754114
run_when: Always,
41764115
},
41774116
&TestCase {
4178-
arch: RiscV,
4117+
arch: RISCV,
41794118
mfgr: SiFive,
41804119
chip: "E310x",
41814120
svd_url: Some("https://raw.githubusercontent.com/riscv-rust/e310x/master/e310x.svd"),
@@ -4231,7 +4170,7 @@ pub const TESTS: &[&TestCase] = &[
42314170
run_when: Always,
42324171
},
42334172
&TestCase {
4234-
arch: RiscV,
4173+
arch: RISCV,
42354174
mfgr: Espressif,
42364175
chip: "esp32c3",
42374176
svd_url: Some(

0 commit comments

Comments
 (0)