Skip to content

Commit bf170cd

Browse files
committed
Don't use quote concats to munge the Vec<Tokens> into one huge string
By manually iterating over the Vec<Token> when writing out to lib.rs we can insert new lines after each token. In addition we split up some of the inner quote repetition operator uses into regular iteration, too, to generate individual Tokens. This changes a typical lib.rs file from 2 to 20k lines (200k after rustfmt) which should help a lot to prevent tools (like rust when errors happen) from going insane and makes the files a lot more directly usable without having to rustfmt all the time. Signed-off-by: Daniel Egger <[email protected]>
1 parent bcae397 commit bf170cd

File tree

4 files changed

+145
-79
lines changed

4 files changed

+145
-79
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10-
- Correct handling of cluster size tag
10+
### Added
1111

1212
- Support of 64-bit fields
1313

14+
### Changed
15+
16+
- Break ultra-long single line output into multiple lines for better usability
17+
18+
### Fixed
19+
20+
- Correct handling of cluster size tag
21+
1422
## [v0.15.0] - 2019-07-25
1523

1624
- Logging system was introduced by `log` crate.

src/generate/peripheral.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,23 @@ pub fn render(
185185

186186
let description =
187187
util::escape_brackets(util::respace(p.description.as_ref().unwrap_or(&p.name)).as_ref());
188+
189+
let open = Ident::from("{");
190+
let close = Ident::from("}");
191+
188192
out.push(quote! {
189193
#[doc = #description]
190-
pub mod #name_sc {
191-
#(#mod_items)*
192-
}
194+
pub mod #name_sc #open
195+
});
196+
197+
for item in mod_items {
198+
out.push(quote! {
199+
#item
200+
});
201+
}
202+
203+
out.push(quote! {
204+
#close
193205
});
194206

195207
Ok(out)

src/generate/register.rs

Lines changed: 114 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use crate::svd::{
2+
Access, BitRange, Defaults, EnumeratedValues, Field, Peripheral, Register, RegisterCluster,
3+
Usage, WriteConstraint,
4+
};
15
use cast::u64;
26
use quote::Tokens;
3-
use crate::svd::{Access, BitRange, Defaults, EnumeratedValues, Field, Peripheral, Register,
4-
RegisterCluster, Usage, WriteConstraint};
57
use syn::Ident;
68

79
use crate::errors::*;
@@ -30,7 +32,8 @@ pub fn render(
3032
rsize.next_power_of_two()
3133
};
3234
let rty = rsize.to_ty()?;
33-
let description = util::escape_brackets(util::respace(&register.description.clone().unwrap()).as_ref());
35+
let description =
36+
util::escape_brackets(util::respace(&register.description.clone().unwrap()).as_ref());
3437

3538
let unsafety = unsafety(register.write_constraint.as_ref(), rsize);
3639

@@ -129,10 +132,21 @@ pub fn render(
129132
});
130133
}
131134

135+
let open = Ident::from("{");
136+
let close = Ident::from("}");
137+
132138
mod_items.push(quote! {
133-
impl super::#name_pc {
134-
#(#reg_impl_items)*
135-
}
139+
impl super::#name_pc #open
140+
});
141+
142+
for item in reg_impl_items {
143+
mod_items.push(quote! {
144+
#item
145+
});
146+
}
147+
148+
mod_items.push(quote! {
149+
#close
136150
});
137151

138152
if let Some(cur_fields) = register.fields.as_ref() {
@@ -160,19 +174,38 @@ pub fn render(
160174
}
161175
}
162176

177+
let open = Ident::from("{");
178+
let close = Ident::from("}");
179+
163180
if can_read {
164181
mod_items.push(quote! {
165-
impl R {
166-
#(#r_impl_items)*
167-
}
182+
impl R #open
183+
});
184+
185+
for item in r_impl_items {
186+
mod_items.push(quote! {
187+
#item
188+
});
189+
}
190+
191+
mod_items.push(quote! {
192+
#close
168193
});
169194
}
170195

171196
if can_write {
172197
mod_items.push(quote! {
173-
impl W {
174-
#(#w_impl_items)*
175-
}
198+
impl W #open
199+
});
200+
201+
for item in w_impl_items {
202+
mod_items.push(quote! {
203+
#item
204+
});
205+
}
206+
207+
mod_items.push(quote! {
208+
#close
176209
});
177210
}
178211

@@ -184,9 +217,17 @@ pub fn render(
184217
}
185218

186219
#[doc = #description]
187-
pub mod #name_sc {
188-
#(#mod_items)*
189-
}
220+
pub mod #name_sc #open
221+
});
222+
223+
for item in mod_items {
224+
out.push(quote! {
225+
#item
226+
});
227+
}
228+
229+
out.push(quote! {
230+
#close
190231
});
191232

192233
Ok(out)
@@ -225,7 +266,11 @@ pub fn fields(
225266
impl<'a> F<'a> {
226267
fn from(f: &'a Field) -> Result<Self> {
227268
// TODO(AJM) - do we need to do anything with this range type?
228-
let BitRange { offset, width, range_type: _ } = f.bit_range;
269+
let BitRange {
270+
offset,
271+
width,
272+
range_type: _,
273+
} = f.bit_range;
229274
let sc = f.name.to_sanitized_snake_case();
230275
let pc = f.name.to_sanitized_upper_case();
231276
let pc_r = Ident::from(&*format!("{}R", pc));
@@ -270,9 +315,10 @@ pub fn fields(
270315

271316
// TODO enumeratedValues
272317
for f in &fs {
273-
let can_read = [Access::ReadOnly, Access::ReadWriteOnce, Access::ReadWrite].contains(&access) &&
274-
(f.access != Some(Access::WriteOnly)) &&
275-
(f.access != Some(Access::WriteOnce));
318+
let can_read = [Access::ReadOnly, Access::ReadWriteOnce, Access::ReadWrite]
319+
.contains(&access)
320+
&& (f.access != Some(Access::WriteOnly))
321+
&& (f.access != Some(Access::WriteOnce));
276322
let can_write = (access != Access::ReadOnly) && (f.access != Some(Access::ReadOnly));
277323

278324
let bits = &f.bits;
@@ -490,15 +536,13 @@ pub fn fields(
490536
}
491537
});
492538

493-
let mut pc_r_impl_items = vec![
494-
quote! {
495-
///Value of the field as raw bits
496-
#[inline(always)]
497-
pub fn #bits(&self) -> #fty {
498-
self.bits
499-
}
500-
},
501-
];
539+
let mut pc_r_impl_items = vec![quote! {
540+
///Value of the field as raw bits
541+
#[inline(always)]
542+
pub fn #bits(&self) -> #fty {
543+
self.bits
544+
}
545+
}];
502546

503547
if f.width == 1 {
504548
pc_r_impl_items.push(quote! {
@@ -590,7 +634,9 @@ pub fn fields(
590634

591635
if base.is_none() {
592636
let variants_pc = variants.iter().map(|v| &v.pc);
593-
let variants_doc = variants.iter().map(|v| util::escape_brackets(&v.doc).to_owned());
637+
let variants_doc = variants
638+
.iter()
639+
.map(|v| util::escape_brackets(&v.doc).to_owned());
594640
mod_items.push(quote! {
595641
#[doc = #pc_w_doc]
596642
#[derive(Clone, Copy, Debug, PartialEq)]
@@ -744,26 +790,21 @@ impl Variant {
744790
// filter out all reserved variants, as we should not
745791
// generate code for them
746792
.filter(|field| field.name.to_lowercase() != "reserved")
747-
.map(
748-
|ev| {
749-
let value = u64(ev.value.ok_or_else(|| {
750-
format!("EnumeratedValue {} has no `<value>` field",
751-
ev.name)})?);
752-
753-
Ok(Variant {
754-
doc: ev.description
793+
.map(|ev| {
794+
let value = u64(ev.value.ok_or_else(|| {
795+
format!("EnumeratedValue {} has no `<value>` field", ev.name)
796+
})?);
797+
798+
Ok(Variant {
799+
doc: ev
800+
.description
755801
.clone()
756-
.unwrap_or_else(|| {
757-
format!("`{:b}`", value)
758-
}),
759-
pc: Ident::from(&*ev.name
760-
.to_sanitized_upper_case()),
761-
sc: Ident::from(&*ev.name
762-
.to_sanitized_snake_case()),
802+
.unwrap_or_else(|| format!("`{:b}`", value)),
803+
pc: Ident::from(&*ev.name.to_sanitized_upper_case()),
804+
sc: Ident::from(&*ev.name.to_sanitized_snake_case()),
763805
value,
764806
})
765-
},
766-
)
807+
})
767808
.collect::<Result<Vec<_>>>()
768809
}
769810
}
@@ -783,7 +824,8 @@ fn lookup<'a>(
783824
peripheral: &'a Peripheral,
784825
all_peripherals: &'a [Peripheral],
785826
) -> Result<Vec<(&'a EnumeratedValues, Option<Base<'a>>)>> {
786-
let evs = evs.iter()
827+
let evs = evs
828+
.iter()
787829
.map(|evs| {
788830
if let Some(base) = &evs.derived_from {
789831
let mut parts = base.split('.');
@@ -826,7 +868,10 @@ fn lookup<'a>(
826868
Ok(evs)
827869
}
828870

829-
fn lookup_filter<'a> (evs: &Vec<(&'a EnumeratedValues, Option<Base<'a>>)>, usage: Usage) -> Option<(&'a EnumeratedValues, Option<Base<'a>>)> {
871+
fn lookup_filter<'a>(
872+
evs: &Vec<(&'a EnumeratedValues, Option<Base<'a>>)>,
873+
usage: Usage,
874+
) -> Option<(&'a EnumeratedValues, Option<Base<'a>>)> {
830875
for (evs, base) in evs.iter() {
831876
if evs.usage == Some(usage) {
832877
return Some((*evs, base.clone()));
@@ -916,7 +961,8 @@ fn lookup_in_register<'r>(
916961
let mut matches = vec![];
917962

918963
for f in register.fields.as_ref().map(|v| &**v).unwrap_or(&[]) {
919-
if let Some(evs) = f.enumerated_values
964+
if let Some(evs) = f
965+
.enumerated_values
920966
.iter()
921967
.find(|evs| evs.name.as_ref().map(|s| &**s) == Some(base_evs))
922968
{
@@ -929,26 +975,25 @@ fn lookup_in_register<'r>(
929975
"EnumeratedValues {} not found in register {}",
930976
base_evs, register.name
931977
))?,
932-
Some(&(evs, field)) => if matches.len() == 1 {
933-
Ok((
934-
evs,
935-
Some(Base {
936-
field,
937-
register: None,
938-
peripheral: None,
939-
}),
940-
))
941-
} else {
942-
let fields = matches
943-
.iter()
944-
.map(|(f, _)| &f.name)
945-
.collect::<Vec<_>>();
946-
Err(format!(
947-
"Fields {:?} have an \
948-
enumeratedValues named {}",
949-
fields, base_evs
950-
))?
951-
},
978+
Some(&(evs, field)) => {
979+
if matches.len() == 1 {
980+
Ok((
981+
evs,
982+
Some(Base {
983+
field,
984+
register: None,
985+
peripheral: None,
986+
}),
987+
))
988+
} else {
989+
let fields = matches.iter().map(|(f, _)| &f.name).collect::<Vec<_>>();
990+
Err(format!(
991+
"Fields {:?} have an \
992+
enumeratedValues named {}",
993+
fields, base_evs
994+
))?
995+
}
996+
}
952997
}
953998
}
954999

src/main.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn run() -> Result<()> {
5454
env_logger::DEFAULT_FILTER_ENV
5555
))
5656
.takes_value(true)
57-
.possible_values(&["off", "error", "warn", "info", "debug", "trace"])
57+
.possible_values(&["off", "error", "warn", "info", "debug", "trace"]),
5858
)
5959
.version(concat!(
6060
env!("CARGO_PKG_VERSION"),
@@ -92,8 +92,11 @@ fn run() -> Result<()> {
9292

9393
let mut device_x = String::new();
9494
let items = generate::device::render(&device, target, nightly, &mut device_x)?;
95+
let mut file = File::create("lib.rs").expect("Couldn't create lib.rs file");
9596

96-
writeln!(File::create("lib.rs").unwrap(), "{}", quote!(#(#items)*)).unwrap();
97+
for item in items {
98+
writeln!(file, "{}", item).expect("Could not write item to lib.rs");
99+
}
97100

98101
if target == Target::CortexM {
99102
writeln!(File::create("device.x").unwrap(), "{}", device_x).unwrap();
@@ -109,13 +112,11 @@ fn setup_logging(matches: &clap::ArgMatches) {
109112
// env_logger's `RUST_LOG` environment variable.
110113
// * Override both of those if the logging level is set via the `--log`
111114
// command line argument.
112-
let env = env_logger::Env::default()
113-
.filter_or(env_logger::DEFAULT_FILTER_ENV, "info");
115+
let env = env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info");
114116
let mut builder = env_logger::Builder::from_env(env);
115117
builder.default_format_timestamp(false);
116118

117-
let log_lvl_from_env =
118-
std::env::var_os(env_logger::DEFAULT_FILTER_ENV).is_some();
119+
let log_lvl_from_env = std::env::var_os(env_logger::DEFAULT_FILTER_ENV).is_some();
119120

120121
if log_lvl_from_env {
121122
log::set_max_level(log::LevelFilter::Trace);

0 commit comments

Comments
 (0)