From c8479475a1b2d0eb54583d6bf9957f2a45877578 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Tue, 2 Jan 2024 10:47:26 +0100 Subject: [PATCH] Add exhaustive canonical tests for enum configurations Test enum declarations with exhaustive configurations for the following criterias: 1. truncated: is the enum width a multiple of 8 or not ? this characteristic has an impact for some language generators 2. complete: does the enum define all possible values ? 3. open: does the enum allow for unknown or undefined values ? 4. with range: does the enum use a tag range declarations ? --- pdl-compiler/scripts/generate_cxx_backend.py | 8 +- .../src/bin/generate-canonical-tests.rs | 7 + pdl-compiler/tests/canonical/le_test_file.pdl | 98 ++++++++ .../tests/canonical/le_test_vectors.json | 227 ++++++++++++++++++ 4 files changed, 338 insertions(+), 2 deletions(-) diff --git a/pdl-compiler/scripts/generate_cxx_backend.py b/pdl-compiler/scripts/generate_cxx_backend.py index 4937079..0bb0d9c 100755 --- a/pdl-compiler/scripts/generate_cxx_backend.py +++ b/pdl-compiler/scripts/generate_cxx_backend.py @@ -817,7 +817,9 @@ def generate_enum_declaration(decl: ast.EnumDeclaration) -> str: enum_type = get_cxx_scalar_type(decl.width) tag_decls = [] for t in decl.tags: - tag_decls.append(f"{t.id} = {hex(t.value)},") + # Exclude default tags: DEFAULT = .. + if t.value is not None: + tag_decls.append(f"{t.id} = {hex(t.value)},") return dedent("""\ @@ -833,7 +835,9 @@ def generate_enum_to_text(decl: ast.EnumDeclaration) -> str: enum_name = decl.id tag_cases = [] for t in decl.tags: - tag_cases.append(f"case {enum_name}::{t.id}: return \"{t.id}\";") + # Exclude default tags: DEFAULT = .. + if t.value is not None: + tag_cases.append(f"case {enum_name}::{t.id}: return \"{t.id}\";") return dedent("""\ diff --git a/pdl-compiler/src/bin/generate-canonical-tests.rs b/pdl-compiler/src/bin/generate-canonical-tests.rs index 4ea3c82..acb0c12 100644 --- a/pdl-compiler/src/bin/generate-canonical-tests.rs +++ b/pdl-compiler/src/bin/generate-canonical-tests.rs @@ -241,6 +241,13 @@ fn main() { "Struct_FixedScalar_Field", "Struct_Size_Field", "Struct_Struct_Field", + "Enum_Incomplete_Truncated_Closed", + "Enum_Incomplete_Truncated_Open", + "Enum_Incomplete_Truncated_Closed_WithRange", + "Enum_Incomplete_Truncated_Open_WithRange", + "Enum_Complete_Truncated", + "Enum_Complete_Truncated_WithRange", + "Enum_Complete_WithRange", ], &module_name, ); diff --git a/pdl-compiler/tests/canonical/le_test_file.pdl b/pdl-compiler/tests/canonical/le_test_file.pdl index fa87314..833b723 100644 --- a/pdl-compiler/tests/canonical/le_test_file.pdl +++ b/pdl-compiler/tests/canonical/le_test_file.pdl @@ -838,3 +838,101 @@ struct Struct_Optional_Struct_Field_ { packet Struct_Optional_Struct_Field { s: Struct_Optional_Struct_Field_, } + +// Enum declarations +// +// Test enum declarations with exhaustive configurations for the +// following criterias: +// +// 1. truncated: is the enum width a multiple of 8 or not ? +// this characteristic has an impact for some language generators +// 2. complete: does the enum define all possible values ? +// 3. open: does the enum allow for unknown or undefined values ? +// 4. with range: does the enum use a tag range declarations ? + +enum Enum_Incomplete_Truncated_Closed_ : 3 { + A = 0, + B = 1, +} + +packet Enum_Incomplete_Truncated_Closed { + e: Enum_Incomplete_Truncated_Closed_, + _reserved_ : 5, +} + +enum Enum_Incomplete_Truncated_Open_ : 3 { + A = 0, + B = 1, + UNKNOWN = .. +} + +packet Enum_Incomplete_Truncated_Open { + e: Enum_Incomplete_Truncated_Open_, + _reserved_ : 5, +} + +enum Enum_Incomplete_Truncated_Closed_WithRange_ : 3 { + A = 0, + B = 1..6 { + X = 1, + Y = 2, + } +} + +packet Enum_Incomplete_Truncated_Closed_WithRange { + e: Enum_Incomplete_Truncated_Closed_WithRange_, + _reserved_ : 5, +} + +enum Enum_Incomplete_Truncated_Open_WithRange_ : 3 { + A = 0, + B = 1..6 { + X = 1, + Y = 2, + }, + UNKNOWN = .. +} + +packet Enum_Incomplete_Truncated_Open_WithRange { + e: Enum_Incomplete_Truncated_Open_WithRange_, + _reserved_ : 5, +} + +enum Enum_Complete_Truncated_ : 3 { + A = 0, + B = 1, + C = 2, + D = 3, + E = 4, + F = 5, + G = 6, + H = 7, +} + +packet Enum_Complete_Truncated { + e: Enum_Complete_Truncated_, + _reserved_ : 5, +} + +enum Enum_Complete_Truncated_WithRange_ : 3 { + A = 0, + B = 1..7 { + X = 1, + Y = 2, + } +} + +packet Enum_Complete_Truncated_WithRange { + e: Enum_Complete_Truncated_WithRange_, + _reserved_ : 5, +} + +enum Enum_Complete_WithRange_ : 8 { + A = 0, + B = 1, + C = 2..255, +} + +packet Enum_Complete_WithRange { + e: Enum_Complete_WithRange_, +} diff --git a/pdl-compiler/tests/canonical/le_test_vectors.json b/pdl-compiler/tests/canonical/le_test_vectors.json index 9ddff45..e6fb3b8 100644 --- a/pdl-compiler/tests/canonical/le_test_vectors.json +++ b/pdl-compiler/tests/canonical/le_test_vectors.json @@ -5095,5 +5095,232 @@ } } ] + }, + { + "packet": "Enum_Incomplete_Truncated_Closed", + "tests": [ + { + "packed": "00", + "unpacked": { + "e": 0 + } + }, + { + "packed": "01", + "unpacked": { + "e": 1 + } + } + ] + }, + { + "packet": "Enum_Incomplete_Truncated_Open", + "tests": [ + { + "packed": "00", + "unpacked": { + "e": 0 + } + }, + { + "packed": "01", + "unpacked": { + "e": 1 + } + }, + { + "packed": "02", + "unpacked": { + "e": 2 + } + } + ] + }, + { + "packet": "Enum_Incomplete_Truncated_Closed_WithRange", + "tests": [ + { + "packed": "00", + "unpacked": { + "e": 0 + } + }, + { + "packed": "01", + "unpacked": { + "e": 1 + } + }, + { + "packed": "02", + "unpacked": { + "e": 2 + } + } + ] + }, + { + "packet": "Enum_Incomplete_Truncated_Open_WithRange", + "tests": [ + { + "packed": "00", + "unpacked": { + "e": 0 + } + }, + { + "packed": "01", + "unpacked": { + "e": 1 + } + }, + { + "packed": "02", + "unpacked": { + "e": 2 + } + }, + { + "packed": "03", + "unpacked": { + "e": 3 + } + } + ] + }, + { + "packet": "Enum_Complete_Truncated", + "tests": [ + { + "packed": "00", + "unpacked": { + "e": 0 + } + }, + { + "packed": "01", + "unpacked": { + "e": 1 + } + }, + { + "packed": "02", + "unpacked": { + "e": 2 + } + }, + { + "packed": "03", + "unpacked": { + "e": 3 + } + }, + { + "packed": "04", + "unpacked": { + "e": 4 + } + }, + { + "packed": "05", + "unpacked": { + "e": 5 + } + }, + { + "packed": "06", + "unpacked": { + "e": 6 + } + }, + { + "packed": "07", + "unpacked": { + "e": 7 + } + } + ] + }, + { + "packet": "Enum_Complete_Truncated_WithRange", + "tests": [ + { + "packed": "00", + "unpacked": { + "e": 0 + } + }, + { + "packed": "01", + "unpacked": { + "e": 1 + } + }, + { + "packed": "02", + "unpacked": { + "e": 2 + } + }, + { + "packed": "03", + "unpacked": { + "e": 3 + } + }, + { + "packed": "04", + "unpacked": { + "e": 4 + } + }, + { + "packed": "05", + "unpacked": { + "e": 5 + } + }, + { + "packed": "06", + "unpacked": { + "e": 6 + } + }, + { + "packed": "07", + "unpacked": { + "e": 7 + } + } + ] + }, + { + "packet": "Enum_Complete_WithRange", + "tests": [ + { + "packed": "00", + "unpacked": { + "e": 0 + } + }, + { + "packed": "01", + "unpacked": { + "e": 1 + } + }, + { + "packed": "02", + "unpacked": { + "e": 2 + } + }, + { + "packed": "ff", + "unpacked": { + "e": 255 + } + } + ] } ]