Skip to content

Commit 7df6021

Browse files
committed
chore: Decouple c.funcpack generator options from generator cli
1 parent 2f0d7b2 commit 7df6021

File tree

10 files changed

+246
-152
lines changed

10 files changed

+246
-152
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
use clap::Parser;
2+
use reginald_codegen::{
3+
builtin::c::{self, funcpack::Element},
4+
regmap::TypeBitwidth,
5+
utils::Endianess,
6+
};
7+
8+
#[derive(Debug, Clone, Parser)]
9+
pub struct Cli {
10+
/// Generate functions and enums with the given endianess.
11+
///
12+
/// May be given multiple times. If not specified, both endianess
13+
/// versions will be generated.
14+
#[arg(long)]
15+
#[arg(action = clap::ArgAction::Append)]
16+
#[arg(verbatim_doc_comment)]
17+
#[arg(conflicts_with("dont_generate"))]
18+
pub endian: Vec<Endianess>,
19+
20+
/// For other endianess, generate only simple functions that defers to this implementation.
21+
///
22+
/// If generating both endianess versions, only generate one complete
23+
/// function implementation and have the other endianess defer to this
24+
#[arg(long)]
25+
#[arg(action = clap::ArgAction::Set)]
26+
#[arg(verbatim_doc_comment)]
27+
pub defer_to_endian: Option<Endianess>,
28+
29+
/// Make register structs bitfields to reduce their memory size
30+
///
31+
/// May reduce performance. Note that their memory layout will not match the actual register
32+
/// and the (un)packing functions must still be used.
33+
#[arg(long)]
34+
#[arg(action = clap::ArgAction::Set)]
35+
#[arg(default_value_t = Self::default().registers_as_bitfields)]
36+
#[arg(verbatim_doc_comment)]
37+
pub registers_as_bitfields: bool,
38+
39+
/// Max enum bitwidth before it is represented using macros instead of an enum.
40+
///
41+
/// Set to zero to have all enums be represented using macros.
42+
#[arg(long)]
43+
#[arg(action = clap::ArgAction::Set)]
44+
#[arg(default_value_t = Self::default().max_enum_bitwidth)]
45+
#[arg(verbatim_doc_comment)]
46+
pub max_enum_bitwidth: TypeBitwidth,
47+
48+
/// Header file that should be included at the top of the generated header
49+
///
50+
/// May be given multiple times.
51+
#[arg(long)]
52+
#[arg(action = clap::ArgAction::Append)]
53+
#[arg(verbatim_doc_comment)]
54+
pub add_include: Vec<String>,
55+
56+
/// Make all functions static inline.
57+
///
58+
/// May be disabled if splitting code into header and source.
59+
#[arg(long)]
60+
#[arg(action = clap::ArgAction::Set)]
61+
#[arg(default_value_t = Self::default().funcs_static_inline)]
62+
#[arg(verbatim_doc_comment)]
63+
pub funcs_static_inline: bool,
64+
65+
/// Generate function prototypes instead of full implementations.
66+
///
67+
/// May be enabled if splitting code into header and source.
68+
#[arg(long)]
69+
#[arg(action = clap::ArgAction::Set)]
70+
#[arg(default_value_t = Self::default().funcs_as_prototypes)]
71+
#[arg(verbatim_doc_comment)]
72+
pub funcs_as_prototypes: bool,
73+
74+
/// Surround file with a clang-format off guard
75+
#[arg(long)]
76+
#[arg(action = clap::ArgAction::Set)]
77+
#[arg(default_value_t = Self::default().clang_format_guard)]
78+
#[arg(verbatim_doc_comment)]
79+
pub clang_format_guard: bool,
80+
81+
/// Generate include guard
82+
#[arg(long)]
83+
#[arg(action = clap::ArgAction::Set)]
84+
#[arg(default_value_t = Self::default().include_guards)]
85+
#[arg(verbatim_doc_comment)]
86+
pub include_guards: bool,
87+
88+
/// Only generate a subset of the elements/sections usually included in
89+
/// a complete output file.
90+
///
91+
/// This option is mutually exclusive with 'dont_generate'
92+
/// If this option is not given, all elements are generated. This option
93+
/// may be given multiple times.
94+
/// Note that different components depend on each other. It is up to the
95+
/// user to generate all required sections, or add includes that provide
96+
/// those elements.
97+
#[arg(long)]
98+
#[arg(action = clap::ArgAction::Append)]
99+
#[arg(verbatim_doc_comment)]
100+
#[arg(conflicts_with("dont_generate"))]
101+
pub only_generate: Vec<Element>,
102+
103+
/// Skip generation of some element/section usually included in a complete
104+
/// output file.
105+
///
106+
/// This option is mutually exclusive with 'only_generate'
107+
/// Note that different components depend on each other. It is up to the
108+
/// user to generate all required sections, or add includes that provide
109+
/// those elements.
110+
#[arg(long)]
111+
#[arg(action = clap::ArgAction::Append)]
112+
#[arg(verbatim_doc_comment)]
113+
#[arg(conflicts_with("only_generate"))]
114+
pub dont_generate: Vec<Element>,
115+
}
116+
117+
impl Default for Cli {
118+
fn default() -> Self {
119+
Self {
120+
endian: vec![],
121+
defer_to_endian: None,
122+
registers_as_bitfields: false,
123+
max_enum_bitwidth: 31,
124+
add_include: vec![],
125+
funcs_static_inline: true,
126+
funcs_as_prototypes: false,
127+
clang_format_guard: true,
128+
include_guards: true,
129+
only_generate: vec![],
130+
dont_generate: vec![],
131+
}
132+
}
133+
}
134+
135+
impl From<&Cli> for c::funcpack::GeneratorOpts {
136+
fn from(cli: &Cli) -> Self {
137+
let mut to_generate = c::funcpack::GeneratorOpts::default().to_generate;
138+
139+
if !cli.only_generate.is_empty() {
140+
for to_gen in &cli.only_generate {
141+
to_generate.insert(*to_gen);
142+
}
143+
} else if !cli.dont_generate.is_empty() {
144+
for to_skip in &cli.only_generate {
145+
to_generate.remove(to_skip);
146+
}
147+
};
148+
149+
c::funcpack::GeneratorOpts {
150+
endian: cli.endian.clone(),
151+
defer_to_endian: cli.defer_to_endian,
152+
registers_as_bitfields: cli.registers_as_bitfields,
153+
max_enum_bitwidth: cli.max_enum_bitwidth,
154+
add_include: cli.add_include.clone(),
155+
funcs_static_inline: cli.funcs_static_inline,
156+
funcs_as_prototypes: cli.funcs_as_prototypes,
157+
clang_format_guard: cli.clang_format_guard,
158+
include_guards: cli.include_guards,
159+
to_generate,
160+
}
161+
}
162+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod funcpack;
2+
pub mod macromap;
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
mod c;
2+
13
use std::fs;
24
use std::path::PathBuf;
35

46
use clap::Parser;
5-
use reginald_codegen::builtin::c;
7+
use reginald_codegen::builtin::c as codegen_c;
68
use reginald_codegen::builtin::md;
79
use reginald_codegen::builtin::rs;
810
use reginald_codegen::error::Error;
@@ -43,9 +45,9 @@ pub struct Command {
4345
#[derive(Parser, Debug)]
4446
pub enum Generator {
4547
/// C header with register structs, and packing/unpacking functions
46-
CFuncpack(c::funcpack::GeneratorOpts),
48+
CFuncpack(c::funcpack::Cli),
4749
/// C header with field mask/shift macros
48-
CMacromap(c::macromap::GeneratorOpts),
50+
CMacromap(codegen_c::macromap::GeneratorOpts),
4951
/// Markdown datasheet
5052
MdDatasheet,
5153
/// Markdown decode report of register dump
@@ -65,8 +67,8 @@ pub fn cmd(generate: Command) -> Result<(), Error> {
6567
// Generate output:
6668
let mut out = String::new();
6769
match &generate.generator {
68-
Generator::CFuncpack(opts) => c::funcpack::generate(&mut out, &map, &generate.output, opts)?,
69-
Generator::CMacromap(opts) => c::macromap::generate(&mut out, &map, &generate.output, opts)?,
70+
Generator::CFuncpack(opts) => codegen_c::funcpack::generate(&mut out, &map, &generate.output, opts.into())?,
71+
Generator::CMacromap(opts) => codegen_c::macromap::generate(&mut out, &map, &generate.output, opts)?,
7072
Generator::MdDatasheet => md::datasheet::generate(&mut out, &map)?,
7173
Generator::MdRegdumpDecode(opts) => md::datasheet::regdump::generate(&mut out, &map, opts)?,
7274
Generator::RsStructs(opts) => rs::structs::generate(&mut out, &map, opts)?,

reginald_codegen/src/builtin/c/funcpack/enums.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ use crate::{
77

88
use reginald_utils::numbers_as_ranges;
99

10-
use super::{Element, Input, c_code, c_generate_doxy_comment, c_macro, generate_multiline_macro, is_enabled};
10+
use super::{Element, Input, c_code, c_generate_doxy_comment, c_macro, generate_multiline_macro};
1111

1212
/// Generate an enum
1313
pub fn generate_enum(out: &mut dyn Write, inp: &Input, e: &Enum) -> Result<(), Error> {
14-
if !is_enabled(inp, Element::Enums) {
14+
if !inp.opts.is_enabled(Element::Enums) {
1515
return Ok(());
1616
}
1717

@@ -48,7 +48,7 @@ pub fn generate_enum(out: &mut dyn Write, inp: &Input, e: &Enum) -> Result<(), E
4848

4949
/// Generate an enum validation func
5050
pub fn generate_enum_validation_macro(out: &mut dyn Write, inp: &Input, e: &Enum) -> Result<(), Error> {
51-
if !is_enabled(inp, Element::EnumValidationMacros) {
51+
if !inp.opts.is_enabled(Element::EnumValidationMacros) {
5252
return Ok(());
5353
}
5454

reginald_codegen/src/builtin/c/funcpack/layouts.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414

1515
use super::{
1616
Element, Input, assemble_numeric_field, c_code, c_fitting_unsigned_type, c_generate_doxy_comment, c_macro, enums,
17-
func_prefix, is_enabled, swap_loop,
17+
func_prefix, swap_loop,
1818
};
1919

2020
pub fn generate_layout(out: &mut dyn Write, inp: &Input, layout: &Layout) -> Result<(), Error> {
@@ -61,7 +61,7 @@ pub fn generate_layout(out: &mut dyn Write, inp: &Input, layout: &Layout) -> Res
6161
}
6262

6363
fn generate_layout_struct(out: &mut dyn Write, inp: &Input, layout: &Layout) -> Result<(), Error> {
64-
if !is_enabled(inp, Element::Structs) {
64+
if !inp.opts.is_enabled(Element::Structs) {
6565
return Ok(());
6666
}
6767

@@ -110,18 +110,18 @@ fn generate_layout_struct(out: &mut dyn Write, inp: &Input, layout: &Layout) ->
110110

111111
/// Generate register packing/unpacking funcs
112112
fn generate_layout_funcs(out: &mut dyn Write, inp: &Input, layout: &Layout) -> Result<(), Error> {
113-
if !is_enabled(inp, Element::StructConversionFuncs) {
113+
if !inp.opts.is_enabled(Element::StructConversionFuncs) {
114114
return Ok(());
115115
}
116116

117-
for endian in &inp.endian {
117+
for endian in &inp.opts.endian {
118118
generate_layout_pack_func(out, inp, layout, *endian)?;
119119
}
120-
for endian in &inp.endian {
120+
for endian in &inp.opts.endian {
121121
generate_layout_unpack_func(out, inp, layout, *endian)?;
122122
}
123123
generate_layout_validation_func(out, inp, layout)?;
124-
for endian in &inp.endian {
124+
for endian in &inp.opts.endian {
125125
generate_layout_try_unpack_func(out, inp, layout, *endian)?;
126126
}
127127

0 commit comments

Comments
 (0)