Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions codegen-tests/snapshot-tests/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn generated_path(output_base: &Path, lang: Language) -> PathBuf {
fn generate_snapshot_fixture(lang: Language) -> String {
let tempdir = tempfile::tempdir().expect("failed to create temp output directory");
let output_base = tempdir.path().join("generated");
let generated_path = generated_path(&output_base, lang.clone());
let generated_path = generated_path(&output_base, lang);
let output = output_base
.to_str()
.expect("temp output path should be valid UTF-8")
Expand All @@ -34,7 +34,7 @@ fn generate_snapshot_fixture(lang: Language) -> String {
separate: false,
};

CodegenPipeline::run(config).expect("codegen should succeed for snapshot fixture");
CodegenPipeline::run(&config).expect("codegen should succeed for snapshot fixture");

fs::read_to_string(generated_path).expect("generated file should be readable")
}
Expand Down
2 changes: 1 addition & 1 deletion codegen-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ mod tests {
"#[inline(always)]",
);

CodegenPipeline::run(config).context("codegen failed")
CodegenPipeline::run(&config).context("codegen failed")
}

fn run_quiet(command: &mut Command, label: &str) -> Result<()> {
Expand Down
48 changes: 24 additions & 24 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::path::Path;
pub struct CodegenPipeline;

impl CodegenPipeline {
pub fn run(config: CodegenConfig) -> anyhow::Result<()> {
pub fn run(config: &CodegenConfig) -> anyhow::Result<()> {
let mut parsed_dbcs = config.inputs.iter().map(|input| {
let data = fs::read_to_string(input)
.with_context(|| format!("Unable to read input file `{input}`"))?;
Expand All @@ -47,26 +47,26 @@ impl CodegenPipeline {

let mut dbc = IRBuilder::to_ir(merged_parsed_dbc);

TransformationPipeline::new()
.add(ComputeBitvecPositions)
.add(AttachMessageSignalUsage)
.add(InferSignalTypes)
TransformationPipeline::default()
.add_node(ComputeBitvecPositions)
.add_node(AttachMessageSignalUsage)
.add_node(InferSignalTypes)
.run(&mut dbc);

let mut diagnostics = Diagnostics::default();
CheckPipeline::new()
.add(CheckZeroZeroRanges {
.add_node(CheckZeroZeroRanges {
zero_zero_range_allows_all: config.zero_zero_range_allows_all,
})
.add(CheckUniqueMessageIds)
.add(CheckSignalLayoutValidity)
.add(CheckMessageSignalUsage)
.add(CheckUnsupportedMultiplexing)
.add(CheckEnumVariants)
.add(CheckSignalPhysicalRangeRepresentable {
.add_node(CheckUniqueMessageIds)
.add_node(CheckSignalLayoutValidity)
.add_node(CheckMessageSignalUsage)
.add_node(CheckUnsupportedMultiplexing)
.add_node(CheckEnumVariants)
.add_node(CheckSignalPhysicalRangeRepresentable {
zero_zero_range_allows_all: config.zero_zero_range_allows_all,
})
.add(CheckSignalScalingArithmeticSafety)
.add_node(CheckSignalScalingArithmeticSafety)
.run(&dbc, &mut diagnostics);

diagnostics.emit();
Expand All @@ -75,23 +75,23 @@ impl CodegenPipeline {
anyhow::bail!("En error was found during validation phase!");
}

TransformationPipeline::new()
.add(SanitizeSignalEnumVariantNames)
.add(DeduplicateSignalValueEnums {
TransformationPipeline::default()
.add_node(SanitizeSignalEnumVariantNames)
.add_node(DeduplicateSignalValueEnums {
dedup_enabled: !config.no_enum_dedup,
})
.add(PrefixSignalValueEnumName {
.add_node(PrefixSignalValueEnumName {
dedup_enabled: !config.no_enum_dedup,
})
.add(AttachSignalValueEnumType)
.add(SanitizeMessageNames)
.add(SanitizeSVENames)
.add(SanitizeSignalNames)
.add_node(AttachSignalValueEnumType)
.add_node(SanitizeMessageNames)
.add_node(SanitizeSVENames)
.add_node(SanitizeSignalNames)
.run(&mut dbc);

match &config.lang {
Language::Rust => {
let code = codegen::rust::RustGen::generate(&dbc, &config);
let code = codegen::rust::RustGen::generate(&dbc, config);
let out =
PathBuf::from(&config.output).with_extension(config.lang.file_extension());
std::fs::write(out, code)?;
Expand All @@ -105,12 +105,12 @@ impl CodegenPipeline {
.and_then(|stem| stem.to_str())
.context("C++ output path must have a valid UTF-8 file stem")?;

for generated in codegen::cpp::CppGen::generate_separate(&dbc, &config, stem) {
for generated in codegen::cpp::CppGen::generate_separate(&dbc, config, stem) {
std::fs::write(parent.join(generated.file_name), generated.contents)?;
}
}
Language::Cpp => {
let code = codegen::cpp::CppGen::generate(&dbc, &config);
let code = codegen::cpp::CppGen::generate(&dbc, config);
let out =
PathBuf::from(&config.output).with_extension(config.lang.file_extension());
std::fs::write(out, code)?;
Expand Down
56 changes: 33 additions & 23 deletions src/codegen/cpp.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::collections::{BTreeMap, BTreeSet};
use std::{
collections::{BTreeMap, BTreeSet},
string::ToString,
};

use heck::ToSnakeCase;

Expand Down Expand Up @@ -36,6 +39,7 @@ fn cpp_code_injections(out: &mut Generator, config: &CodegenConfig, point: CppCo
}

impl CppGen {
#[must_use]
pub fn generate(file: &DbcFile, config: &CodegenConfig) -> String {
let mut out = Generator::new();

Expand All @@ -57,6 +61,7 @@ impl CppGen {
out.into_string()
}

#[must_use]
pub fn generate_separate(
file: &DbcFile,
config: &CodegenConfig,
Expand Down Expand Up @@ -172,10 +177,10 @@ impl CppGen {

let mut emitted_enum_idxs = BTreeSet::new();
for signal in &file.signals {
if let Some(idx) = signal.signal_value_enum_idx {
if emitted_enum_idxs.insert(idx.0) {
Self::signal_value_enum(out, signal, &file.signal_value_enums[idx.0], config);
}
if let Some(idx) = signal.signal_value_enum_idx
&& emitted_enum_idxs.insert(idx.0)
{
Self::signal_value_enum(out, signal, &file.signal_value_enums[idx.0], config);
}
}
}
Expand Down Expand Up @@ -340,10 +345,10 @@ impl CppGen {
fn emit_message_id(out: &mut Generator, msg: &Message) {
match msg.id {
MessageId::Standard(id) => {
line!(out, "static constexpr CanId ID = CanId::standard({});", id)
line!(out, "static constexpr CanId ID = CanId::standard({});", id);
}
MessageId::Extended(id) => {
line!(out, "static constexpr CanId ID = CanId::extended({});", id)
line!(out, "static constexpr CanId ID = CanId::extended({});", id);
}
}
}
Expand Down Expand Up @@ -836,8 +841,8 @@ impl CppGen {
];

if let Some(comment) = &msg.comment {
lines.push("".into());
lines.extend(comment.lines().map(|l| l.to_string()));
lines.push(String::new());
lines.extend(comment.lines().map(ToString::to_string));
}

line!(out, "/**");
Expand All @@ -855,7 +860,7 @@ impl CppGen {
let max = layout.max;
let unit = &signal.unit;
let receivers = if signal.receivers.is_empty() {
"".into()
String::new()
} else {
signal
.receivers
Expand Down Expand Up @@ -898,8 +903,8 @@ impl CppGen {
];

if let Some(comment) = &signal.comment {
lines.push("".into());
lines.extend(comment.lines().map(|l| l.to_string()));
lines.push(String::new());
lines.extend(comment.lines().map(ToString::to_string));
}

line!(out, "/**");
Expand Down Expand Up @@ -1402,7 +1407,7 @@ impl CppGen {

start_block!(out, "std::visit([&msg](const auto& v)");
line!(out, "using T = std::decay_t<decltype(v)>;");
for (mux_value, _) in &muxed_sigs {
for mux_value in muxed_sigs.keys() {
let variant_class = format!("{}Mux{}", msg_name, mux_value);
start_block!(out, "if constexpr (std::is_same_v<T, {}>)", variant_class);
line!(out, "msg.set_mux_{}(v);", mux_value);
Expand Down Expand Up @@ -1438,7 +1443,7 @@ impl CppGen {
mux_layout,
);
start_block!(out, "switch (mux_raw)");
for (mux_value, _) in &muxed_sigs {
for mux_value in muxed_sigs.keys() {
let variant_class = format!("{}Mux{}", msg_name, mux_value);
start_block!(out, "case {}:", mux_value);
line!(out, "{} inner{{}};", variant_class);
Expand Down Expand Up @@ -1955,7 +1960,7 @@ impl CppGen {
let field_name = signal.name.raw.to_snake_case();
let invalid_var = format!("{}_out_of_range", field_name);
let mut constructor_args = Self::test_vars(signals, valid_suffix);
constructor_args[bad_idx] = invalid_var.clone();
constructor_args[bad_idx].clone_from(&invalid_var);
constructor_args.extend(trailing_args.iter().cloned());

start_block!(out, "");
Expand Down Expand Up @@ -2358,7 +2363,12 @@ impl CppGen {
}

if Self::is_bool_signal(signal, file) {
return if ordinal % 2 == 0 { "false" } else { "true" }.to_string();
return if ordinal.is_multiple_of(2) {
"false"
} else {
"true"
}
.to_string();
}

let layout = &file.signal_layouts[signal.layout.0];
Expand Down Expand Up @@ -2426,7 +2436,7 @@ impl CppGen {
let candidates = [
layout.min + 1.0,
layout.max - 1.0,
(layout.min + layout.max) / 2.0,
f64::midpoint(layout.min, layout.max),
layout.min,
layout.max,
];
Expand Down Expand Up @@ -2463,12 +2473,12 @@ impl CppGen {
let min = layout.min;
let max = layout.max;
let type_min = if phys_type == "float" {
f32::MIN as f64
f64::from(f32::MIN)
} else {
f64::MIN
};
let type_max = if phys_type == "float" {
f32::MAX as f64
f64::from(f32::MAX)
} else {
f64::MAX
};
Expand Down Expand Up @@ -2531,7 +2541,7 @@ impl CppGen {
match ordinal % 3 {
0 => layout.min,
1 => layout.max,
_ => (layout.min + layout.max) / 2.0,
_ => f64::midpoint(layout.min, layout.max),
}
} else {
match ordinal % 5 {
Expand Down Expand Up @@ -2583,7 +2593,7 @@ impl CppGen {
let midpoint = low
.checked_add(high)
.map(|v| v / 2)
.or_else(|| if low <= 0 && high >= 0 { Some(0) } else { None });
.or(if low <= 0 && 0 <= high { Some(0) } else { None });

let mut candidates = Vec::new();
let ordered = if prefer_bounds {
Expand Down Expand Up @@ -2708,7 +2718,7 @@ impl CppGen {
let used = enum_def
.variants
.iter()
.map(|variant| variant.value as i128)
.map(|variant| i128::from(variant.value))
.collect::<BTreeSet<_>>();
let layout = &file.signal_layouts[signal.layout.0];
let (low, high) = Self::integer_raw_range(layout);
Expand All @@ -2721,7 +2731,7 @@ impl CppGen {
muxed: &BTreeMap<u64, Vec<&Signal>>,
file: &DbcFile,
) -> Option<i128> {
let used = muxed.keys().map(|value| *value as i128).collect();
let used = muxed.keys().map(|value| i128::from(*value)).collect();
let layout = &file.signal_layouts[mux_signal.layout.0];
let (low, high) = Self::integer_raw_range(layout);

Expand Down
6 changes: 5 additions & 1 deletion src/codegen/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ pub struct Generator {
}

impl Generator {
#[must_use]
pub fn new() -> Self {
Self::with_indent(" ")
}

#[must_use]
pub fn with_indent(indent: &str) -> Self {
Self {
buffer: String::new(),
Expand Down Expand Up @@ -45,14 +47,16 @@ impl Generator {
if !text.is_empty() {
self.push_indent();
self.buffer.push_str(text);
self.buffer.push_str("\n");
self.buffer.push('\n');
}
}

#[must_use]
pub fn get(&self) -> &str {
&self.buffer
}

#[must_use]
pub fn into_string(self) -> String {
self.buffer
}
Expand Down
Loading