Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6a0f963

Browse files
committedFeb 15, 2024
change case defaults, fix bugs
1 parent a23a780 commit 6a0f963

File tree

13 files changed

+506
-284
lines changed

13 files changed

+506
-284
lines changed
 

‎.github/workflows/ci.yml

+6-5
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
include:
5757
- { rust: stable, vendor: Atmel, options: all }
5858
- { rust: stable, vendor: Atmel, options: "" }
59-
- { rust: stable, vendor: Freescale, options: all }
59+
- { rust: stable, vendor: Freescale, options: "--strict --atomics" }
6060
- { rust: stable, vendor: Freescale, options: "" }
6161
- { rust: stable, vendor: Fujitsu, options: "" }
6262
- { rust: stable, vendor: Fujitsu, options: "--atomics" }
@@ -80,16 +80,17 @@ jobs:
8080
- { rust: stable, vendor: Spansion, options: "--atomics" }
8181
- { rust: stable, vendor: STMicro, options: "" }
8282
- { rust: stable, vendor: STMicro, options: "--atomics" }
83-
- { rust: stable, vendor: STM32-patched, options: "--strict --pascal-enum-values --max-cluster-size --atomics --atomics-feature atomics --impl-debug --impl-defmt defmt" }
83+
- { rust: stable, vendor: STM32-patched, options: "--strict --max-cluster-size --atomics --atomics-feature atomics --impl-debug --impl-defmt defmt" }
8484
- { rust: stable, vendor: Toshiba, options: all }
8585
- { rust: stable, vendor: Toshiba, options: "" }
8686
# Test MSRV
87-
- { rust: 1.70.0, vendor: Nordic, options: "" }
87+
- { rust: 1.74.0, vendor: Nordic, options: "" }
8888
# Use nightly for architectures which don't support stable
8989
- { rust: nightly, vendor: MSP430, options: "--atomics" }
9090
- { rust: nightly, vendor: MSP430, options: "" }
91-
- { rust: nightly, vendor: Espressif, options: "--atomics" }
92-
- { rust: nightly, vendor: Espressif, options: "" }
91+
# Workaround for _1token0
92+
- { rust: nightly, vendor: Espressif, options: "--atomics --ident-format register::c:" }
93+
- { rust: nightly, vendor: Espressif, options: "--ident-format register::c:" }
9394

9495
steps:
9596
- uses: actions/checkout@v4

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77

88
## [Unreleased]
99

10+
- Bump MSRV to 1.74
1011
- Add `base-address-shift` config flag
12+
- Use `PascalCase` for type idents, fix case changing bugs, add `--ident-format` (`-f`) option flag
1113

1214
## [v0.31.5] - 2024-01-04
1315

‎Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ name = "svd2rust"
2525
repository = "https://github.com/rust-embedded/svd2rust/"
2626
version = "0.31.5"
2727
readme = "README.md"
28-
rust-version = "1.70"
28+
rust-version = "1.74"
2929

3030
[package.metadata.deb]
3131
section = "rust"

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
![GitHub top language](https://img.shields.io/github/languages/top/rust-embedded/svd2rust)
2-
![Minimum Supported Rust Version](https://img.shields.io/badge/rustc-1.70+-blue.svg)
2+
![Minimum Supported Rust Version](https://img.shields.io/badge/rustc-1.74+-blue.svg)
33
[![crates.io](https://img.shields.io/crates/v/svd2rust.svg)](https://crates.io/crates/svd2rust)
44
[![crates.io](https://img.shields.io/crates/d/svd2rust.svg)](https://crates.io/crates/svd2rust)
55
[![Released API docs](https://docs.rs/svd2rust/badge.svg)](https://docs.rs/svd2rust)

‎ci/svd2rust-regress/src/svd_test.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use anyhow::{anyhow, Context, Result};
2-
use svd2rust::{util::ToSanitizedCase, Target};
2+
use svd2rust::{util::Case, Target};
33

44
use crate::{command::CommandExt, tests::TestCase, Opts, TestAll};
55
use std::io::prelude::*;
@@ -176,7 +176,7 @@ impl TestCase {
176176
Ok(val) => val,
177177
Err(_) => "rusttester".into(),
178178
};
179-
let chip_dir = output_dir.join(self.name().to_sanitized_snake_case().as_ref());
179+
let chip_dir = output_dir.join(Case::Snake.sanitize(&self.name()).as_ref());
180180
tracing::span::Span::current()
181181
.record("chip_dir", tracing::field::display(chip_dir.display()));
182182
if let Err(err) = fs::remove_dir_all(&chip_dir) {
@@ -195,7 +195,7 @@ impl TestCase {
195195
.env("USER", user)
196196
.arg("init")
197197
.arg("--name")
198-
.arg(self.name().to_sanitized_snake_case().as_ref())
198+
.arg(Case::Snake.sanitize(&self.name()).as_ref())
199199
.arg("--vcs")
200200
.arg("none")
201201
.arg(&chip_dir)

‎src/config.rs

+72-28
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
use anyhow::{bail, Result};
2-
use std::path::{Path, PathBuf};
2+
use std::{
3+
collections::HashMap,
4+
ops::{Deref, DerefMut},
5+
path::{Path, PathBuf},
6+
};
37

48
#[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(default))]
59
#[derive(Clone, PartialEq, Eq, Debug, Default)]
10+
#[non_exhaustive]
611
pub struct Config {
712
pub target: Target,
813
pub atomics: bool,
@@ -13,7 +18,6 @@ pub struct Config {
1318
pub ignore_groups: bool,
1419
pub keep_list: bool,
1520
pub strict: bool,
16-
pub pascal_enum_values: bool,
1721
pub feature_group: bool,
1822
pub feature_peripheral: bool,
1923
pub max_cluster_size: bool,
@@ -135,6 +139,7 @@ pub enum Case {
135139
#[derive(Clone, Debug, Default, PartialEq, Eq)]
136140
#[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(default))]
137141
pub struct IdentFormat {
142+
// Ident case. `None` means don't change
138143
pub case: Option<Case>,
139144
pub prefix: String,
140145
pub suffix: String,
@@ -153,8 +158,8 @@ impl IdentFormat {
153158
self.case = Some(Case::Pascal);
154159
self
155160
}
156-
pub fn scake_case(mut self) -> Self {
157-
self.case = Some(Case::Pascal);
161+
pub fn snake_case(mut self) -> Self {
162+
self.case = Some(Case::Snake);
158163
self
159164
}
160165
pub fn prefix(mut self, prefix: &str) -> Self {
@@ -169,32 +174,71 @@ impl IdentFormat {
169174

170175
#[derive(Clone, Debug, PartialEq, Eq)]
171176
#[cfg_attr(feature = "serde", derive(serde::Deserialize), serde(default))]
172-
pub struct IdentFormats {
173-
pub field_reader: IdentFormat,
174-
pub field_writer: IdentFormat,
175-
pub enum_name: IdentFormat,
176-
pub enum_write_name: IdentFormat,
177-
pub enum_value: IdentFormat,
178-
pub interrupt: IdentFormat,
179-
pub cluster: IdentFormat,
180-
pub register: IdentFormat,
181-
pub register_spec: IdentFormat,
182-
pub peripheral: IdentFormat,
183-
}
177+
pub struct IdentFormats(HashMap<String, IdentFormat>);
184178

185179
impl Default for IdentFormats {
186180
fn default() -> Self {
187-
Self {
188-
field_reader: IdentFormat::default().constant_case().suffix("_R"),
189-
field_writer: IdentFormat::default().constant_case().suffix("_W"),
190-
enum_name: IdentFormat::default().constant_case().suffix("_A"),
191-
enum_write_name: IdentFormat::default().constant_case().suffix("_AW"),
192-
enum_value: IdentFormat::default().constant_case(),
193-
interrupt: IdentFormat::default().constant_case(),
194-
cluster: IdentFormat::default().constant_case(),
195-
register: IdentFormat::default().constant_case(),
196-
register_spec: IdentFormat::default().constant_case().suffix("_SPEC"),
197-
peripheral: IdentFormat::default().constant_case(),
198-
}
181+
let mut map = HashMap::new();
182+
183+
map.insert("field_accessor".into(), IdentFormat::default().snake_case());
184+
map.insert(
185+
"field_reader".into(),
186+
IdentFormat::default().pascal_case().suffix("R"),
187+
);
188+
map.insert(
189+
"field_writer".into(),
190+
IdentFormat::default().pascal_case().suffix("W"),
191+
);
192+
map.insert("enum_name".into(), IdentFormat::default().pascal_case());
193+
map.insert(
194+
"enum_write_name".into(),
195+
IdentFormat::default().pascal_case().suffix("WO"),
196+
);
197+
map.insert("enum_value".into(), IdentFormat::default().pascal_case());
198+
map.insert(
199+
"enum_value_accessor".into(),
200+
IdentFormat::default().snake_case(),
201+
);
202+
map.insert("interrupt".into(), IdentFormat::default());
203+
map.insert("cluster".into(), IdentFormat::default().pascal_case());
204+
map.insert(
205+
"cluster_accessor".into(),
206+
IdentFormat::default().snake_case(),
207+
);
208+
map.insert("cluster_mod".into(), IdentFormat::default().snake_case());
209+
map.insert("register".into(), IdentFormat::default().pascal_case());
210+
map.insert(
211+
"register_spec".into(),
212+
IdentFormat::default().pascal_case().suffix("Spec"),
213+
);
214+
map.insert(
215+
"register_accessor".into(),
216+
IdentFormat::default().snake_case(),
217+
);
218+
map.insert("register_mod".into(), IdentFormat::default().snake_case());
219+
map.insert("peripheral".into(), IdentFormat::default().pascal_case());
220+
map.insert(
221+
"peripheral_singleton".into(),
222+
IdentFormat::default().snake_case(),
223+
);
224+
map.insert("peripheral_mod".into(), IdentFormat::default().snake_case());
225+
map.insert(
226+
"peripheral_feature".into(),
227+
IdentFormat::default().snake_case(),
228+
);
229+
230+
Self(map)
231+
}
232+
}
233+
234+
impl Deref for IdentFormats {
235+
type Target = HashMap<String, IdentFormat>;
236+
fn deref(&self) -> &Self::Target {
237+
&self.0
238+
}
239+
}
240+
impl DerefMut for IdentFormats {
241+
fn deref_mut(&mut self) -> &mut Self::Target {
242+
&mut self.0
199243
}
200244
}

‎src/generate/device.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::io::Write;
88
use std::path::Path;
99

1010
use crate::config::{Config, Target};
11-
use crate::util::{self, ident, ToSanitizedCase};
11+
use crate::util::{self, ident};
1212
use anyhow::{Context, Result};
1313

1414
use crate::generate::{interrupt, peripheral};
@@ -192,6 +192,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
192192
config,
193193
)?);
194194

195+
let feature_format = config.ident_formats.get("peripheral_feature").unwrap();
195196
for p in &d.peripherals {
196197
if config.target == Target::CortexM
197198
&& core_peripherals.contains(&p.name.to_uppercase().as_ref())
@@ -226,39 +227,45 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
226227
}
227228
let mut feature_attribute = TokenStream::new();
228229
if config.feature_group && p.group_name.is_some() {
229-
let feature_name = p.group_name.as_ref().unwrap().to_sanitized_snake_case();
230+
let feature_name = feature_format.apply(p.group_name.as_deref().unwrap());
230231
feature_attribute.extend(quote! { #[cfg(feature = #feature_name)] })
231232
};
232233

233234
let span = Span::call_site();
234235
match p {
235236
Peripheral::Single(_p) => {
236237
let p_name = util::name_of(p, config.ignore_groups);
237-
let p_snake = p_name.to_sanitized_snake_case();
238-
let p_ty = ident(&p_name, &config.ident_formats.peripheral, span);
238+
let p_feature = feature_format.apply(&p_name);
239+
let p_ty = ident(&p_name, &config, "peripheral", span);
240+
let p_singleton = ident(&p_name, &config, "peripheral_singleton", span);
239241
if config.feature_peripheral {
240-
feature_attribute.extend(quote! { #[cfg(feature = #p_snake)] })
242+
feature_attribute.extend(quote! { #[cfg(feature = #p_feature)] })
241243
};
242244
fields.extend(quote! {
243245
#[doc = #p_name]
244246
#feature_attribute
245-
pub #p_ty: #p_ty,
247+
pub #p_singleton: #p_ty,
246248
});
247-
exprs.extend(quote!(#feature_attribute #p_ty: #p_ty { _marker: PhantomData },));
249+
exprs.extend(
250+
quote!(#feature_attribute #p_singleton: #p_ty { _marker: PhantomData },),
251+
);
248252
}
249253
Peripheral::Array(p, dim_element) => {
250254
for p_name in names(p, dim_element) {
251-
let p_snake = p_name.to_sanitized_snake_case();
252-
let p_ty = ident(&p_name, &config.ident_formats.peripheral, span);
255+
let p_feature = feature_format.apply(&p_name);
256+
let p_ty = ident(&p_name, &config, "peripheral", span);
257+
let p_singleton = ident(&p_name, &config, "peripheral_singleton", span);
253258
if config.feature_peripheral {
254-
feature_attribute.extend(quote! { #[cfg(feature = #p_snake)] })
259+
feature_attribute.extend(quote! { #[cfg(feature = #p_feature)] })
255260
};
256261
fields.extend(quote! {
257262
#[doc = #p_name]
258263
#feature_attribute
259-
pub #p_ty: #p_ty,
264+
pub #p_singleton: #p_ty,
260265
});
261-
exprs.extend(quote!(#feature_attribute #p_ty: #p_ty { _marker: PhantomData },));
266+
exprs.extend(
267+
quote!(#feature_attribute #p_singleton: #p_ty { _marker: PhantomData },),
268+
);
262269
}
263270
}
264271
}

‎src/generate/interrupt.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::svd::Peripheral;
55
use proc_macro2::{Span, TokenStream};
66
use quote::quote;
77

8-
use crate::util::{self, ident, ToSanitizedCase};
8+
use crate::util::{self, ident};
99
use crate::{Config, Target};
1010
use anyhow::Result;
1111

@@ -47,14 +47,15 @@ pub fn render(
4747
let mut pos = 0;
4848
let mut mod_items = TokenStream::new();
4949
let span = Span::call_site();
50+
let feature_format = config.ident_formats.get("peripheral_feature").unwrap();
5051
for interrupt in &interrupts {
5152
while pos < interrupt.0.value {
5253
elements.extend(quote!(Vector { _reserved: 0 },));
5354
pos += 1;
5455
}
5556
pos += 1;
5657

57-
let i_ty = ident(&interrupt.0.name, &config.ident_formats.interrupt, span);
58+
let i_ty = ident(&interrupt.0.name, &config, "interrupt", span);
5859
let description = format!(
5960
"{} - {}",
6061
interrupt.0.value,
@@ -74,13 +75,13 @@ pub fn render(
7475
let mut feature_attribute = TokenStream::new();
7576
let mut not_feature_attribute = TokenStream::new();
7677
if config.feature_group && interrupt.1.is_some() {
77-
let feature_name = interrupt.1.as_ref().unwrap().to_sanitized_snake_case();
78+
let feature_name = feature_format.apply(interrupt.1.as_ref().unwrap());
7879
feature_attribute_flag = true;
7980
feature_attribute.extend(quote! { #[cfg(feature = #feature_name)] });
8081
not_feature_attribute.extend(quote! { feature = #feature_name, });
8182
}
8283
if config.feature_peripheral {
83-
let feature_name = interrupt.2.to_sanitized_snake_case();
84+
let feature_name = feature_format.apply(&interrupt.2);
8485
feature_attribute_flag = true;
8586
feature_attribute.extend(quote! { #[cfg(feature = #feature_name)] });
8687
not_feature_attribute.extend(quote! { feature = #feature_name, });

0 commit comments

Comments
 (0)
Please sign in to comment.