Skip to content

Commit

Permalink
Merge pull request #814 from rust-embedded/enum_read_name
Browse files Browse the repository at this point in the history
add enum_read_name
  • Loading branch information
burrbull authored Feb 22, 2024
2 parents d8f1468 + 9a87eae commit 25c35b6
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 96 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
- generic unsafe `W::bits` + safe `W::set`
- Add `base-address-shift` config flag
- Use `PascalCase` for type idents, fix case changing bugs, add `--ident-format` (`-f`) option flag
- Add `enum_read_name` for `read-only` enums

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

Expand Down
79 changes: 30 additions & 49 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ yaml = ["dep:serde_yaml"]
[dependencies]
clap = { version = "4.0", optional = true }
irx-config = { version = "=3.3.0", features = ["cmd", "toml-parser"], optional = true }
env_logger = { version = "0.10", optional = true }
env_logger = { version = "0.11", optional = true }
inflections = "1.1"
log = { version = "~0.4", features = ["std"] }
quote = "1.0"
Expand All @@ -55,7 +55,7 @@ thiserror = "1.0"
serde = { version = "1.0", optional = true }
serde_json = { version = "1.0.85", optional = true }
serde_yaml = { version = "0.9.11", optional = true }
regex = "1.9.0"
regex = "1.10.0"
html-escape = "0.2"

[dependencies.svd-parser]
Expand All @@ -64,7 +64,7 @@ version = "0.14.5"

[dependencies.svd-rs]
features = ["serde"]
version = "0.14.7"
version = "0.14.8"

[dependencies.syn]
version = "2.0"
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ impl IdentFormats {
("field_reader".into(), pascal.clone().suffix("R")),
("field_writer".into(), pascal.clone().suffix("W")),
("enum_name".into(), pascal.clone()),
("enum_read_name".into(), pascal.clone()),
("enum_write_name".into(), pascal.clone().suffix("WO")),
("enum_value".into(), pascal.clone()),
("interrupt".into(), IdentFormat::default()),
Expand All @@ -273,6 +274,7 @@ impl IdentFormats {
("field_reader".into(), constant.clone().suffix("_R")),
("field_writer".into(), constant.clone().suffix("_W")),
("enum_name".into(), constant.clone().suffix("_A")),
("enum_read_name".into(), constant.clone().suffix("_A")),
("enum_write_name".into(), constant.clone().suffix("_AW")),
("enum_value".into(), constant.clone()),
("interrupt".into(), constant.clone()),
Expand Down
73 changes: 30 additions & 43 deletions src/generate/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,14 @@ pub fn fields(
lookup_results.push((ev, epath));
}

let mut evs_r = None;
let read_enum = lookup_filter(&lookup_results, Usage::Read);
let write_enum = lookup_filter(&lookup_results, Usage::Write);

// does the read and the write value has the same name? If we have the same,
// we can reuse read value type other than generating a new one.
let writer_reader_different_enum = !(can_read
&& can_write
&& matches!((read_enum, write_enum), (Some(e1), Some(e2)) if e1.0 == e2.0));

let brief_suffix = if let Field::Array(_, de) = &f {
if let Some(range) = de.indexes_as_range() {
Expand Down Expand Up @@ -652,14 +659,13 @@ pub fn fields(

// get the type of value structure. It can be generated from either name field
// in enumeratedValues if it's an enumeration, or from field name directly if it's not.
let value_read_ty = if let Some((evs, _)) = lookup_filter(&lookup_results, Usage::Read)
{
ident(
evs.name.as_deref().unwrap_or(&name),
config,
"enum_name",
span,
)
let value_read_ty = if let Some((evs, _)) = read_enum {
let fmt = if writer_reader_different_enum {
"enum_read_name"
} else {
"enum_name"
};
ident(evs.name.as_deref().unwrap_or(&name), config, fmt, span)
} else {
// raw_field_value_read_ty
fty.clone()
Expand All @@ -674,10 +680,7 @@ pub fn fields(
// information in enumeratedValues;
// if it's not enumeratedValues, always derive the read proxy as we do not need to re-export
// it again from BitReader or FieldReader.
let should_derive_reader = matches!(
lookup_filter(&lookup_results, Usage::Read),
Some((_, None)) | None
);
let should_derive_reader = matches!(read_enum, Some((_, None)) | None);

// derive the read proxy structure if necessary.
if should_derive_reader {
Expand Down Expand Up @@ -712,11 +715,7 @@ pub fn fields(

// if this is an enumeratedValues not derived from base, generate the enum structure
// and implement functions for each value in enumeration.
if let Some((evs, None)) = lookup_filter(&lookup_results, Usage::Read) {
// we have enumeration for read, record this. If the enumeration for write operation
// later on is the same as the read enumeration, we reuse and do not generate again.
evs_r = Some(evs);

if let Some((evs, None)) = read_enum {
// parse enum variants from enumeratedValues svd record
let mut variants = Variant::from_enumerated_values(evs, config)?;

Expand Down Expand Up @@ -856,9 +855,7 @@ pub fn fields(

// if this value is derived from a base, generate `pub use` code for each read proxy and value
// if necessary.
if let Some((evs, Some(base))) = lookup_filter(&lookup_results, Usage::Read) {
// preserve value; if read type equals write type, writer would not generate value type again
evs_r = Some(evs);
if let Some((_, Some(base))) = read_enum {
// generate pub use field_1 reader as field_2 reader
let base_field = util::replace_suffix(&base.field.name, "");
let base_r = ident(&base_field, config, "field_reader", span);
Expand Down Expand Up @@ -969,19 +966,17 @@ pub fn fields(
// gets a brief of write proxy
let field_writer_brief = format!("Field `{name}{brief_suffix}` writer - {description}");

let value_write_ty =
if let Some((evs, _)) = lookup_filter(&lookup_results, Usage::Write) {
let writer_reader_different_enum = evs_r != Some(evs);
let fmt = if writer_reader_different_enum {
"enum_write_name"
} else {
"enum_name"
};
ident(evs.name.as_deref().unwrap_or(&name), config, fmt, span)
let value_write_ty = if let Some((evs, _)) = write_enum {
let fmt = if writer_reader_different_enum {
"enum_write_name"
} else {
// raw_field_value_write_ty
fty.clone()
"enum_name"
};
ident(evs.name.as_deref().unwrap_or(&name), config, fmt, span)
} else {
// raw_field_value_write_ty
fty.clone()
};

// name of write proxy type
let writer_ty = ident(&name, config, "field_writer", span);
Expand All @@ -990,7 +985,7 @@ pub fn fields(
let mut unsafety = unsafety(f.write_constraint.as_ref(), width);

// if we writes to enumeratedValues, generate its structure if it differs from read structure.
if let Some((evs, None)) = lookup_filter(&lookup_results, Usage::Write) {
if let Some((evs, None)) = write_enum {
// parse variants from enumeratedValues svd record
let mut variants = Variant::from_enumerated_values(evs, config)?;
let map = enums_to_map(evs);
Expand All @@ -1011,10 +1006,6 @@ pub fn fields(
unsafety = false;
}

// does the read and the write value has the same name? If we have the same,
// we can reuse read value type other than generating a new one.
let writer_reader_different_enum = evs_r != Some(evs);

// generate write value structure and From conversation if we can't reuse read value structure.
if writer_reader_different_enum {
if variants.is_empty() {
Expand Down Expand Up @@ -1056,10 +1047,7 @@ pub fn fields(

// derive writer. We derive writer if the write proxy is in current register module,
// or writer in different register have different _SPEC structures
let should_derive_writer = matches!(
lookup_filter(&lookup_results, Usage::Write),
Some((_, None)) | None
);
let should_derive_writer = matches!(write_enum, Some((_, None)) | None);

// derive writer structure by type alias to generic write proxy structure.
if should_derive_writer {
Expand Down Expand Up @@ -1128,7 +1116,7 @@ pub fn fields(
});
}

if let Some((evs, Some(base))) = lookup_filter(&lookup_results, Usage::Write) {
if let Some((_, Some(base))) = write_enum {
// if base.register == None, derive write from the same module. This is allowed because both
// the generated and source write proxy are in the same module.
// we never reuse writer for writer in different module does not have the same _SPEC strcuture,
Expand All @@ -1147,7 +1135,6 @@ pub fn fields(
}
// if base.register == None, it emits pub use structure from same module.
if base.register() != fpath.register() {
let writer_reader_different_enum = evs_r != Some(evs);
if writer_reader_different_enum {
// use the same enum structure name
if !writer_enum_derives.contains(&value_write_ty) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@
//! |--------------------------------------------------------------------------------|:------:|:---------:|:---------:|:------:|:-----------:|
//! | field_reader | | pascal | constant | R | _R |
//! | field_writer | | pascal | constant | W | _W |
//! | enum_name | | pascal | constant | | _A |
//! | enum_name <br> enum_read_name | | pascal | constant | | _A |
//! | enum_write_name | | pascal | constant | WO | _AW |
//! | enum_value | | pascal | constant | | |
//! | interrupt | | unchanged | constant | | |
Expand Down

0 comments on commit 25c35b6

Please sign in to comment.