diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a35a712..36b9c51b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/Cargo.lock b/Cargo.lock index 86748504..81d9a121 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" dependencies = [ "anstyle", "anstyle-parse", @@ -42,9 +42,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -350,17 +350,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" -version = "0.10.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" dependencies = [ + "anstream", + "anstyle", + "env_filter", "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -655,17 +665,6 @@ dependencies = [ "toml", ] -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "itoa" version = "1.0.10" @@ -941,14 +940,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.6" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.9", - "regex-syntax 0.7.5", + "regex-automata 0.4.5", + "regex-syntax 0.8.2", ] [[package]] @@ -962,13 +961,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.9" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", ] [[package]] @@ -979,9 +978,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" @@ -1209,9 +1208,9 @@ dependencies = [ [[package]] name = "svd-rs" -version = "0.14.7" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c82f375efa1d0145467e6cc98fa0e4e1a3f3d497cece4bcdda247f4904a77d4" +checksum = "6aea8090314157cc490b559da0c66f2228c066b56154f0321ad83b459a0a8278" dependencies = [ "once_cell", "regex", @@ -1320,15 +1319,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "termcolor" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.51" @@ -1709,15 +1699,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index b5aa0cc9..56b3189b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" @@ -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] @@ -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" diff --git a/src/config.rs b/src/config.rs index a68d98e7..1979db22 100644 --- a/src/config.rs +++ b/src/config.rs @@ -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()), @@ -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()), diff --git a/src/generate/register.rs b/src/generate/register.rs index bf078785..d8975df7 100644 --- a/src/generate/register.rs +++ b/src/generate/register.rs @@ -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() { @@ -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() @@ -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 { @@ -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)?; @@ -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); @@ -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); @@ -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); @@ -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() { @@ -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 { @@ -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, @@ -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) { diff --git a/src/lib.rs b/src/lib.rs index e8118099..6a0b754f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -564,7 +564,7 @@ //! |--------------------------------------------------------------------------------|:------:|:---------:|:---------:|:------:|:-----------:| //! | field_reader | | pascal | constant | R | _R | //! | field_writer | | pascal | constant | W | _W | -//! | enum_name | | pascal | constant | | _A | +//! | enum_name
enum_read_name | | pascal | constant | | _A | //! | enum_write_name | | pascal | constant | WO | _AW | //! | enum_value | | pascal | constant | | | //! | interrupt | | unchanged | constant | | |