Skip to content

Commit 0e1c6f8

Browse files
authored
Merge pull request #13 from dsprenkels/issue_1
Implement parsing of value groups
2 parents fe2250e + f4ab7c6 commit 0e1c6f8

File tree

1 file changed

+100
-7
lines changed

1 file changed

+100
-7
lines changed

build.rs

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ mod gen {
117117
writeln!(w, "//!")?;
118118

119119
writeln!(w, "//! # Variants")?;
120-
writeln!(w, "//! | | Pinout | Mcuage | Operating temperature | Operating voltage | Max speed |")?;
120+
writeln!(w, "//! | | Pinout | Mcu age | Operating temperature | Operating voltage | Max speed |")?;
121121
writeln!(w, "//! |--------|--------|---------|-----------------------|-------------------|-----------|")?;
122122
for variant in mcu.variants.iter() {
123123
let pinout_label = variant.pinout.as_ref().map(|p| p.replace('_', "-").to_owned()).unwrap_or_else(|| String::new());
@@ -145,12 +145,9 @@ mod gen {
145145
let ty = integer_type(register.size);
146146

147147
if !register.caption.is_empty() {
148-
let mut caption = register.caption.trim().to_owned();
149-
if !caption.ends_with('.') { caption.push('.') }
150-
151-
writeln!(w, "/// {}", caption)?;
148+
writeln!(w, "/// {}", format_caption(&register.caption))?;
152149
} else {
153-
writeln!(w, "/// {} register", register.name)?;
150+
writeln!(w, "/// `{}` register", register.name)?;
154151
}
155152

156153
let mut bitfields = register_bitfields.iter().filter_map(|&(reg,bitfield)| {
@@ -176,16 +173,55 @@ mod gen {
176173
for (register, bitfield) in register_bitfields {
177174
let ty = integer_type(bitfield.size);
178175

179-
writeln!(w, "/// Bitfield on register {}", register.name)?;
176+
writeln!(w, "/// Bitfield on register `{}`", register.name)?;
180177
writeln!(w, "pub const {}: *mut {} = {:#X} as *mut {};",
181178
bitfield.name, ty, bitfield.mask, ty)?;
182179
writeln!(w)?;
183180

184181
}
185182

183+
for value_group in ordered_value_groups(&mcu) {
184+
if !value_group.caption.is_empty() {
185+
writeln!(w, "/// {}", value_group.caption)?;
186+
} else {
187+
writeln!(w, "/// `{}` value group", value_group.name)?;
188+
}
189+
writeln!(w, "#[allow(non_upper_case_globals)]")? ;
190+
writeln!(w, "pub mod {} {{", value_group.name.to_lowercase())?;
191+
for val in unique_value_group_values(&value_group).iter() {
192+
let first_char = val.name.chars().next().expect("empty value name");
193+
let name = if !first_char.is_alphabetic() && first_char != '_' {
194+
format!("_{}", val.name)
195+
} else {
196+
val.name.to_owned()
197+
};
198+
199+
if !val.caption.is_empty() {
200+
let ty = "u32";
201+
writeln!(w, " /// {}", format_caption(&val.caption))?;
202+
writeln!(w, " pub const {}: {} = {:#X};", name, ty, val.value)?;
203+
}
204+
}
205+
writeln!(w, "}}")?;
206+
writeln!(w)?;
207+
}
208+
186209
Ok(())
187210
}
188211

212+
fn format_caption(caption: &str) -> String {
213+
let mut result = caption.to_owned();
214+
// Escape special characters in markdown
215+
result = result.replace("[", "\\[").replace("]", "\\]");
216+
217+
// Trim and make a sentence
218+
result = result.trim().to_owned();
219+
if !result.ends_with('.') {
220+
result.push('.')
221+
}
222+
result
223+
}
224+
189225
fn ordered_registers(mcu: &Mcu) -> Vec<Register> {
190226
let mut unique_registers = self::unique_registers(mcu);
191227
insert_high_low_variants(&mut unique_registers);
@@ -196,6 +232,19 @@ mod gen {
196232
registers
197233
}
198234

235+
fn ordered_value_groups(mcu: &Mcu) -> Vec<ValueGroup> {
236+
let mut value_groups = Vec::new();
237+
for module in mcu.modules.iter() {
238+
for value_group in module.value_groups.iter() {
239+
value_groups.push(value_group.clone());
240+
}
241+
}
242+
value_groups = unique_value_groups(&value_groups);
243+
value_groups.sort_by(|vg1, vg2| vg1.partial_cmp(vg2).unwrap());
244+
245+
value_groups
246+
}
247+
199248
fn insert_high_low_variants(registers: &mut HashMap<String, Register>) {
200249
let wide_registers: Vec<_> = registers.values()
201250
.filter(|r| r.size == 2)
@@ -257,6 +306,50 @@ mod gen {
257306
result
258307
}
259308

309+
fn unique_value_groups(value_groups: &[ValueGroup]) -> Vec<ValueGroup> {
310+
let mut value_groups = value_groups.to_owned();
311+
loop {
312+
let mut remove_idx = None;
313+
for (idx, value_group) in value_groups.iter().enumerate() {
314+
if value_groups.iter().filter(|vg| {
315+
if vg.name == value_group.name {
316+
assert_eq!(*vg, value_group);
317+
true
318+
} else {
319+
false
320+
}
321+
}).count() > 1 {
322+
remove_idx = Some(idx);
323+
}
324+
}
325+
match remove_idx {
326+
Some(idx) => value_groups.remove(idx),
327+
None => break,
328+
};
329+
}
330+
value_groups
331+
}
332+
333+
/// Collect al the values in a ValueGroup and deduplicate the,/
334+
///
335+
/// As in the bitfield descriptions, the value-group decriptions contain
336+
/// values with duplicate names. We will skip every value which is
337+
/// ambiguous. See `documentable_bitfields` for more context on this
338+
/// issue.
339+
fn unique_value_group_values(value_group: &ValueGroup) -> Vec<Value> {
340+
let mut values = value_group.values.clone();
341+
let mut remove_names = HashSet::new();
342+
for value in values.iter() {
343+
if values.iter().filter(|v| v.name == value.name).count() > 1 {
344+
remove_names.insert(value.name.to_owned());
345+
}
346+
}
347+
for name in remove_names {
348+
values.retain(|v| v.name != name);
349+
}
350+
values
351+
}
352+
260353
/// Gets the integer type of a specified width.
261354
fn integer_type(byte_count: u32) -> &'static str {
262355
match byte_count {

0 commit comments

Comments
 (0)