From d25c8f8cc20f214b99fdd8e70a8ae8a7e86a94a7 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha Date: Fri, 29 Mar 2024 14:54:58 -0400 Subject: [PATCH 01/14] Updated build.rs to replace periods with underscores in test suite filenames --- build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.rs b/build.rs index 5761149f..bfce89ac 100644 --- a/build.rs +++ b/build.rs @@ -376,8 +376,8 @@ fn write_test_rs( for (t, testcase) in testcases.into_iter().enumerate().map(|(i, x)| (i + 1, x)) { // Write subtest to its own file. - let subtest_path = Path::new(&out_dir) - .join(format!("syntaxrules.{rulename}.{passfail}.{t}of{n_testcases}.sv")); + let subtest_path: std::path::PathBuf = Path::new(&out_dir) + .join(format!("syntaxrules_{rulename}_{passfail}_{t}of{n_testcases}.sv")); let mut out_subtest = File::create(&subtest_path).unwrap(); for line in testcase { let _ = writeln!(out_subtest, "{}", line); From 7ad6e182fc35c5f77ac7c7c3538cebc63bdacc03 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha Date: Fri, 29 Mar 2024 15:06:36 -0400 Subject: [PATCH 02/14] feat: added rule for checking package identifier matches filename --- ...ion-package_identifier_matches_filename.md | 6 ++ .../package_identifier_matches_filename.rs | 76 +++++++++++++++++++ .../package_identifier_matches_filename.sv | 2 + .../package_identifier_matches_filename.sv | 3 + 4 files changed, 87 insertions(+) create mode 100644 md/syntaxrules-explanation-package_identifier_matches_filename.md create mode 100644 src/syntaxrules/package_identifier_matches_filename.rs create mode 100644 testcases/syntaxrules/fail/package_identifier_matches_filename.sv create mode 100644 testcases/syntaxrules/pass/package_identifier_matches_filename.sv diff --git a/md/syntaxrules-explanation-package_identifier_matches_filename.md b/md/syntaxrules-explanation-package_identifier_matches_filename.md new file mode 100644 index 00000000..be4dd149 --- /dev/null +++ b/md/syntaxrules-explanation-package_identifier_matches_filename.md @@ -0,0 +1,6 @@ +Package Identifier should have the same name as the file it's in. + +```package Bar``` should be in ```some/path/to/Bar.sv``` + + +Note that as a result, only one package can be declared per file. \ No newline at end of file diff --git a/src/syntaxrules/package_identifier_matches_filename.rs b/src/syntaxrules/package_identifier_matches_filename.rs new file mode 100644 index 00000000..0e1ee628 --- /dev/null +++ b/src/syntaxrules/package_identifier_matches_filename.rs @@ -0,0 +1,76 @@ +use crate::config::ConfigOption; +use crate::linter::{SyntaxRule, SyntaxRuleResult}; +use sv_parser::{unwrap_locate, NodeEvent, RefNode, SyntaxTree, unwrap_node, Locate}; + +#[derive(Default)] +pub struct PackageIdentifierMatchesFilename; +impl SyntaxRule for PackageIdentifierMatchesFilename { + fn check( + &mut self, + syntax_tree: &SyntaxTree, + event: &NodeEvent, + _option: &ConfigOption, + ) -> SyntaxRuleResult { + let node = match event { + NodeEvent::Enter(x) => x, + NodeEvent::Leave(_) => { + return SyntaxRuleResult::Pass; + } + }; + + match node { + RefNode::PackageIdentifier(x) => { + let path_str = if let Some(x) = unwrap_locate!(node.clone()) { + if let Some((path, _)) = syntax_tree.get_origin(&x) { + path + } else { + return SyntaxRuleResult::Fail; + } + } else { + return SyntaxRuleResult::Fail; + }; + + let id: Option<&Locate> = match unwrap_node!(*x, SimpleIdentifier) { + Some(RefNode::SimpleIdentifier(id_)) => { + unwrap_locate!(id_) + }, + _ => None, + }; + + if id.is_none() { + return SyntaxRuleResult::Fail; + } + + let package_name = syntax_tree.get_str(id.unwrap()).unwrap(); + + let path = std::path::Path::new(path_str); + if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { + if file_name.ends_with(".sv") { + let file_ident = file_name.trim_end_matches(".sv"); + if package_name == file_ident { + return SyntaxRuleResult::Pass; + } + } + } + + SyntaxRuleResult::Fail + }, + + _ => SyntaxRuleResult::Pass, + } + + } + + fn name(&self) -> String { + String::from("package_identifier_matches_filename") + } + + fn hint(&self, _option: &ConfigOption) -> String { + String::from("Ensure that the package name name matches the file name. Package fooBar should be in some/path/to/fooBar.sv") + } + + fn reason(&self) -> String { + String::from("Encourages consistent file naming standards for packages and assists in searching for packages.") + } + +} diff --git a/testcases/syntaxrules/fail/package_identifier_matches_filename.sv b/testcases/syntaxrules/fail/package_identifier_matches_filename.sv new file mode 100644 index 00000000..5f91ea83 --- /dev/null +++ b/testcases/syntaxrules/fail/package_identifier_matches_filename.sv @@ -0,0 +1,2 @@ +package fooBar; +endpackage diff --git a/testcases/syntaxrules/pass/package_identifier_matches_filename.sv b/testcases/syntaxrules/pass/package_identifier_matches_filename.sv new file mode 100644 index 00000000..a16ae542 --- /dev/null +++ b/testcases/syntaxrules/pass/package_identifier_matches_filename.sv @@ -0,0 +1,3 @@ +package syntaxrules_package_identifier_matches_filename_pass_1of1; +endpackage + From 45febec43c49931889b7fa28faca125380f492da Mon Sep 17 00:00:00 2001 From: Shantanu Sinha Date: Fri, 29 Mar 2024 15:08:31 -0400 Subject: [PATCH 03/14] feat: added rule for checking program identifier matches filename --- ...ion-program_identifier_matches_filename.md | 6 ++ .../program_identifier_matches_filename.rs | 76 +++++++++++++++++++ .../program_identifier_matches_filename.sv | 2 + .../program_identifier_matches_filename.sv | 2 + 4 files changed, 86 insertions(+) create mode 100644 md/syntaxrules-explanation-program_identifier_matches_filename.md create mode 100644 src/syntaxrules/program_identifier_matches_filename.rs create mode 100644 testcases/syntaxrules/fail/program_identifier_matches_filename.sv create mode 100644 testcases/syntaxrules/pass/program_identifier_matches_filename.sv diff --git a/md/syntaxrules-explanation-program_identifier_matches_filename.md b/md/syntaxrules-explanation-program_identifier_matches_filename.md new file mode 100644 index 00000000..2ff88f6d --- /dev/null +++ b/md/syntaxrules-explanation-program_identifier_matches_filename.md @@ -0,0 +1,6 @@ +Program Identifier should have the same name as the file it's in. + +```program Bar``` should be in ```some/path/to/Bar.sv``` + + +Note that as a result, only one program can be declared per file. \ No newline at end of file diff --git a/src/syntaxrules/program_identifier_matches_filename.rs b/src/syntaxrules/program_identifier_matches_filename.rs new file mode 100644 index 00000000..7d32c6ac --- /dev/null +++ b/src/syntaxrules/program_identifier_matches_filename.rs @@ -0,0 +1,76 @@ +use crate::config::ConfigOption; +use crate::linter::{SyntaxRule, SyntaxRuleResult}; +use sv_parser::{unwrap_locate, NodeEvent, RefNode, SyntaxTree, unwrap_node, Locate}; + +#[derive(Default)] +pub struct ProgramIdentifierMatchesFilename; +impl SyntaxRule for ProgramIdentifierMatchesFilename { + fn check( + &mut self, + syntax_tree: &SyntaxTree, + event: &NodeEvent, + _option: &ConfigOption, + ) -> SyntaxRuleResult { + let node = match event { + NodeEvent::Enter(x) => x, + NodeEvent::Leave(_) => { + return SyntaxRuleResult::Pass; + } + }; + + match node { + RefNode::ProgramIdentifier(x) => { + let path_str = if let Some(x) = unwrap_locate!(node.clone()) { + if let Some((path, _)) = syntax_tree.get_origin(&x) { + path + } else { + return SyntaxRuleResult::Fail; + } + } else { + return SyntaxRuleResult::Fail; + }; + + let id: Option<&Locate> = match unwrap_node!(*x, SimpleIdentifier) { + Some(RefNode::SimpleIdentifier(id_)) => { + unwrap_locate!(id_) + }, + _ => None, + }; + + if id.is_none() { + return SyntaxRuleResult::Fail; + } + + let program_name = syntax_tree.get_str(id.unwrap()).unwrap(); + + let path = std::path::Path::new(path_str); + if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { + if file_name.ends_with(".sv") { + let file_ident = file_name.trim_end_matches(".sv"); + if program_name == file_ident { + return SyntaxRuleResult::Pass; + } + } + } + + SyntaxRuleResult::Fail + }, + + _ => SyntaxRuleResult::Pass, + } + + } + + fn name(&self) -> String { + String::from("program_identifier_matches_filename") + } + + fn hint(&self, _option: &ConfigOption) -> String { + String::from("Ensure that the program name matches the file name. program Bar should be in some/path/to/Bar.sv") + } + + fn reason(&self) -> String { + String::from("Encourages consistent file naming standards for packages and assists in searching for programs.") + } + +} diff --git a/testcases/syntaxrules/fail/program_identifier_matches_filename.sv b/testcases/syntaxrules/fail/program_identifier_matches_filename.sv new file mode 100644 index 00000000..5d6295ae --- /dev/null +++ b/testcases/syntaxrules/fail/program_identifier_matches_filename.sv @@ -0,0 +1,2 @@ +program Bar; +endprogram \ No newline at end of file diff --git a/testcases/syntaxrules/pass/program_identifier_matches_filename.sv b/testcases/syntaxrules/pass/program_identifier_matches_filename.sv new file mode 100644 index 00000000..9d84c677 --- /dev/null +++ b/testcases/syntaxrules/pass/program_identifier_matches_filename.sv @@ -0,0 +1,2 @@ +program syntaxrules_program_identifier_matches_filename_pass_1of1; +endprogram \ No newline at end of file From 5924f7764d9a50093b2bae4c89ee7b0acc12d6cb Mon Sep 17 00:00:00 2001 From: Shantanu Sinha Date: Fri, 29 Mar 2024 15:10:17 -0400 Subject: [PATCH 04/14] feat: added rule for checking interface identifier matches filename --- ...n-interface_identifier_matches_filename.md | 5 ++ .../interface_identifier_matches_filename.rs | 76 +++++++++++++++++++ .../interface_identifier_matches_filename.sv | 2 + .../interface_identifier_matches_filename.sv | 2 + 4 files changed, 85 insertions(+) create mode 100644 md/syntaxrules-explanation-interface_identifier_matches_filename.md create mode 100644 src/syntaxrules/interface_identifier_matches_filename.rs create mode 100644 testcases/syntaxrules/fail/interface_identifier_matches_filename.sv create mode 100644 testcases/syntaxrules/pass/interface_identifier_matches_filename.sv diff --git a/md/syntaxrules-explanation-interface_identifier_matches_filename.md b/md/syntaxrules-explanation-interface_identifier_matches_filename.md new file mode 100644 index 00000000..f0704dd0 --- /dev/null +++ b/md/syntaxrules-explanation-interface_identifier_matches_filename.md @@ -0,0 +1,5 @@ +Interface Identifier should have the same name as the file it's in. + +```interface Bar``` should be in ```some/path/to/Bar.sv``` + +Note that as a result, only one interface can be declared per file. \ No newline at end of file diff --git a/src/syntaxrules/interface_identifier_matches_filename.rs b/src/syntaxrules/interface_identifier_matches_filename.rs new file mode 100644 index 00000000..5551c828 --- /dev/null +++ b/src/syntaxrules/interface_identifier_matches_filename.rs @@ -0,0 +1,76 @@ +use crate::config::ConfigOption; +use crate::linter::{SyntaxRule, SyntaxRuleResult}; +use sv_parser::{unwrap_locate, NodeEvent, RefNode, SyntaxTree, unwrap_node, Locate}; + +#[derive(Default)] +pub struct InterfaceIdentifierMatchesFilename; +impl SyntaxRule for InterfaceIdentifierMatchesFilename { + fn check( + &mut self, + syntax_tree: &SyntaxTree, + event: &NodeEvent, + _option: &ConfigOption, + ) -> SyntaxRuleResult { + let node = match event { + NodeEvent::Enter(x) => x, + NodeEvent::Leave(_) => { + return SyntaxRuleResult::Pass; + } + }; + + match node { + RefNode::InterfaceIdentifier(x) => { + let path_str = if let Some(x) = unwrap_locate!(node.clone()) { + if let Some((path, _)) = syntax_tree.get_origin(&x) { + path + } else { + return SyntaxRuleResult::Fail; + } + } else { + return SyntaxRuleResult::Fail; + }; + + let id: Option<&Locate> = match unwrap_node!(*x, SimpleIdentifier) { + Some(RefNode::SimpleIdentifier(id_)) => { + unwrap_locate!(id_) + }, + _ => None, + }; + + if id.is_none() { + return SyntaxRuleResult::Fail; + } + + let interface_name = syntax_tree.get_str(id.unwrap()).unwrap(); + + let path = std::path::Path::new(path_str); + if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { + if file_name.ends_with(".sv") { + let file_ident = file_name.trim_end_matches(".sv"); + if interface_name == file_ident { + return SyntaxRuleResult::Pass; + } + } + } + + SyntaxRuleResult::Fail + }, + + _ => SyntaxRuleResult::Pass, + } + + } + + fn name(&self) -> String { + String::from("interface_identifier_matches_filename") + } + + fn hint(&self, _option: &ConfigOption) -> String { + String::from("Ensure that the interface name matches the file name. Interface Bar should be in some/path/to/Bar.sv") + } + + fn reason(&self) -> String { + String::from("Encourages consistent file naming standards for packages and assists in searching for interfaces.") + } + +} diff --git a/testcases/syntaxrules/fail/interface_identifier_matches_filename.sv b/testcases/syntaxrules/fail/interface_identifier_matches_filename.sv new file mode 100644 index 00000000..3a1aff0c --- /dev/null +++ b/testcases/syntaxrules/fail/interface_identifier_matches_filename.sv @@ -0,0 +1,2 @@ +interface Bar; +endinterface \ No newline at end of file diff --git a/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv b/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv new file mode 100644 index 00000000..c81a754a --- /dev/null +++ b/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv @@ -0,0 +1,2 @@ +interface syntaxrules_interface_identifier_matches_filename_pass_1of1; +endinterface \ No newline at end of file From e9e29397f64540f7ab6dc839f4e61610d5d4d154 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha Date: Fri, 29 Mar 2024 15:10:57 -0400 Subject: [PATCH 05/14] feat: added rule for checking module identifier matches filename --- .gitignore | 2 + ...tion-module_identifier_matches_filename.md | 5 ++ .../module_identifier_matches_filename.rs | 67 +++++++++++++++++++ .../module_identifier_matches_filename.sv | 2 + .../module_identifier_matches_filename.sv | 2 + 5 files changed, 78 insertions(+) create mode 100644 md/syntaxrules-explanation-module_identifier_matches_filename.md create mode 100644 src/syntaxrules/module_identifier_matches_filename.rs create mode 100644 testcases/syntaxrules/fail/module_identifier_matches_filename.sv create mode 100644 testcases/syntaxrules/pass/module_identifier_matches_filename.sv diff --git a/.gitignore b/.gitignore index 84c47ed7..e928e577 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /target **/*.rs.bk /Cargo.lock +.svlint.toml +.vscode diff --git a/md/syntaxrules-explanation-module_identifier_matches_filename.md b/md/syntaxrules-explanation-module_identifier_matches_filename.md new file mode 100644 index 00000000..d90c7d32 --- /dev/null +++ b/md/syntaxrules-explanation-module_identifier_matches_filename.md @@ -0,0 +1,5 @@ +Module Identifier should have the same name as the file it's in. + +```module Bar``` should be in ```some/path/to/Bar.sv``` + +Note that as a result, only one module can be declared per file. \ No newline at end of file diff --git a/src/syntaxrules/module_identifier_matches_filename.rs b/src/syntaxrules/module_identifier_matches_filename.rs new file mode 100644 index 00000000..39628a42 --- /dev/null +++ b/src/syntaxrules/module_identifier_matches_filename.rs @@ -0,0 +1,67 @@ +use crate::config::ConfigOption; +use crate::linter::{SyntaxRule, SyntaxRuleResult}; +use sv_parser::{unwrap_locate, NodeEvent, RefNode, SyntaxTree, unwrap_node}; + +#[derive(Default)] +pub struct ModuleIdentifierMatchesFilename; +impl SyntaxRule for ModuleIdentifierMatchesFilename { + fn check( + &mut self, + syntax_tree: &SyntaxTree, + event: &NodeEvent, + _option: &ConfigOption, + ) -> SyntaxRuleResult { + let node = match event { + NodeEvent::Enter(x) => x, + NodeEvent::Leave(_) => { + return SyntaxRuleResult::Pass; + } + }; + + match node { + RefNode::ModuleDeclaration(x) => { + let path_str = if let Some(x) = unwrap_locate!(node.clone()) { + if let Some((path, _)) = syntax_tree.get_origin(&x) { + path + } else { + return SyntaxRuleResult::Fail; + } + } else { + return SyntaxRuleResult::Fail; + }; + + let module_name = if let Some(RefNode::ModuleIdentifier(module_ident)) = unwrap_node!(*x, ModuleIdentifier) { + syntax_tree.get_str(module_ident).unwrap() + } else { + return SyntaxRuleResult::Fail; + }; + + // Use the extracted path_str and module_name to perform the file name check + let path = std::path::Path::new(&path_str); + if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { + if file_name.ends_with(".sv") { + let file_ident = file_name.trim_end_matches(".sv"); + if file_ident == module_name { + return SyntaxRuleResult::Pass; + } + } + } + SyntaxRuleResult::Fail + } + _ => SyntaxRuleResult::Pass, + } + + } + + fn name(&self) -> String { + String::from("module_identifier_matches_filename") + } + + fn hint(&self, _option: &ConfigOption) -> String { + String::from("Ensure that the module name matches the file name. module Bar should be in some/path/to/Bar.sv") + } + + fn reason(&self) -> String { + String::from("Encourages consistent file naming standards for packages and assists in searching for modules.") + } +} diff --git a/testcases/syntaxrules/fail/module_identifier_matches_filename.sv b/testcases/syntaxrules/fail/module_identifier_matches_filename.sv new file mode 100644 index 00000000..e5b30ca0 --- /dev/null +++ b/testcases/syntaxrules/fail/module_identifier_matches_filename.sv @@ -0,0 +1,2 @@ +module Bar; +endmodule \ No newline at end of file diff --git a/testcases/syntaxrules/pass/module_identifier_matches_filename.sv b/testcases/syntaxrules/pass/module_identifier_matches_filename.sv new file mode 100644 index 00000000..55956a6e --- /dev/null +++ b/testcases/syntaxrules/pass/module_identifier_matches_filename.sv @@ -0,0 +1,2 @@ +module syntaxrules_module_identifier_matches_filename_pass_1of1; +endmodule \ No newline at end of file From 0a58555ac521291dd441341e14ae765935636bcf Mon Sep 17 00:00:00 2001 From: ShantanuPSinha Date: Fri, 29 Mar 2024 19:12:20 +0000 Subject: [PATCH 06/14] Commit from GitHub Actions (Run mdgen) --- MANUAL.md | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/MANUAL.md b/MANUAL.md index 56850478..ab06ccf1 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -2179,6 +2179,39 @@ The most relevant clauses of IEEE1800-2017 are: +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +## Syntax Rule: `interface_identifier_matches_filename` + +### Hint + +Ensure that the interface name matches the file name. Interface Bar should be in some/path/to/Bar.sv + +### Reason + +Encourages consistent file naming standards for packages and assists in searching for interfaces. + +### Pass Example (1 of 1) +```systemverilog +interface syntaxrules_interface_identifier_matches_filename_pass_1of1; +endinterface +``` + +### Fail Example (1 of 1) +```systemverilog +interface Bar; +endinterface +``` + +### Explanation + +Interface Identifier should have the same name as the file it's in. + +```interface Bar``` should be in ```some/path/to/Bar.sv``` + +Note that as a result, only one interface can be declared per file. + + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ## Syntax Rule: `interface_port_with_modport` @@ -3640,6 +3673,39 @@ The most relevant clauses of IEEE1800-2017 are: +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +## Syntax Rule: `module_identifier_matches_filename` + +### Hint + +Ensure that the module name matches the file name. module Bar should be in some/path/to/Bar.sv + +### Reason + +Encourages consistent file naming standards for packages and assists in searching for modules. + +### Pass Example (1 of 1) +```systemverilog +module syntaxrules_module_identifier_matches_filename_pass_1of1; +endmodule +``` + +### Fail Example (1 of 1) +```systemverilog +module Bar; +endmodule +``` + +### Explanation + +Module Identifier should have the same name as the file it's in. + +```module Bar``` should be in ```some/path/to/Bar.sv``` + +Note that as a result, only one module can be declared per file. + + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ## Syntax Rule: `module_nonansi_forbidden` @@ -4429,6 +4495,41 @@ The most relevant clauses of IEEE1800-2017 are: +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +## Syntax Rule: `package_identifier_matches_filename` + +### Hint + +Ensure that the package name name matches the file name. Package fooBar should be in some/path/to/fooBar.sv + +### Reason + +Encourages consistent file naming standards for packages and assists in searching for packages. + +### Pass Example (1 of 1) +```systemverilog +package syntaxrules_package_identifier_matches_filename_pass_1of1; +endpackage + +``` + +### Fail Example (1 of 1) +```systemverilog +package fooBar; +endpackage +``` + +### Explanation + +Package Identifier should have the same name as the file it's in. + +```package Bar``` should be in ```some/path/to/Bar.sv``` + + +Note that as a result, only one package can be declared per file. + + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ## Syntax Rule: `package_item_not_in_package` @@ -4910,6 +5011,40 @@ The most relevant clauses of IEEE1800-2017 are: +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +## Syntax Rule: `program_identifier_matches_filename` + +### Hint + +Ensure that the program name matches the file name. program Bar should be in some/path/to/Bar.sv + +### Reason + +Encourages consistent file naming standards for packages and assists in searching for programs. + +### Pass Example (1 of 1) +```systemverilog +program syntaxrules_program_identifier_matches_filename_pass_1of1; +endprogram +``` + +### Fail Example (1 of 1) +```systemverilog +program Bar; +endprogram +``` + +### Explanation + +Program Identifier should have the same name as the file it's in. + +```program Bar``` should be in ```some/path/to/Bar.sv``` + + +Note that as a result, only one program can be declared per file. + + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ## Syntax Rule: `sequential_block_in_always_comb` From 86685a193847cd88ec6cf873169cda92d250851f Mon Sep 17 00:00:00 2001 From: Shantanu Sinha <5han7anu@Legion> Date: Mon, 1 Apr 2024 19:58:02 -0400 Subject: [PATCH 07/14] Restore build.rs with periods in test file names --- build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.rs b/build.rs index bfce89ac..fff78eeb 100644 --- a/build.rs +++ b/build.rs @@ -377,7 +377,7 @@ fn write_test_rs( for (t, testcase) in testcases.into_iter().enumerate().map(|(i, x)| (i + 1, x)) { // Write subtest to its own file. let subtest_path: std::path::PathBuf = Path::new(&out_dir) - .join(format!("syntaxrules_{rulename}_{passfail}_{t}of{n_testcases}.sv")); + .join(format!("syntaxrules.{rulename}.{passfail}.{t}of{n_testcases}.sv")); let mut out_subtest = File::create(&subtest_path).unwrap(); for line in testcase { let _ = writeln!(out_subtest, "{}", line); From 8ef88c897adab23347c701872e9f86ce5e2bbd40 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha <5han7anu@Legion> Date: Mon, 1 Apr 2024 21:56:22 -0400 Subject: [PATCH 08/14] Updated module_identifier_matches_filename rule to only match substring up to first non-identifier symbol --- .../module_identifier_matches_filename.rs | 28 +++++++++++++++---- .../module_identifier_matches_filename.sv | 2 +- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/syntaxrules/module_identifier_matches_filename.rs b/src/syntaxrules/module_identifier_matches_filename.rs index 39628a42..0eef843a 100644 --- a/src/syntaxrules/module_identifier_matches_filename.rs +++ b/src/syntaxrules/module_identifier_matches_filename.rs @@ -29,6 +29,7 @@ impl SyntaxRule for ModuleIdentifierMatchesFilename { } else { return SyntaxRuleResult::Fail; }; + let module_name = if let Some(RefNode::ModuleIdentifier(module_ident)) = unwrap_node!(*x, ModuleIdentifier) { syntax_tree.get_str(module_ident).unwrap() @@ -36,12 +37,29 @@ impl SyntaxRule for ModuleIdentifierMatchesFilename { return SyntaxRuleResult::Fail; }; - // Use the extracted path_str and module_name to perform the file name check + let path = std::path::Path::new(&path_str); - if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { - if file_name.ends_with(".sv") { - let file_ident = file_name.trim_end_matches(".sv"); - if file_ident == module_name { + if let Some(file_name_os_str) = path.file_name() { + if let Some(file_name) = file_name_os_str.to_str() { + // Iterate over each character in the file name to find the first non-identifier character + let mut identifier_end = 0; + for (i, c) in file_name.char_indices() { + if c.is_alphanumeric() || c == '_' || c == '$' { + identifier_end = i + c.len_utf8(); + } else { + // Stop at the first non-identifier character + break; + } + } + + let file_ident = &file_name[..identifier_end]; + + println !("\n\nPath: {:?}", path_str); + + println!("File: {}, Module: {}\n\n", file_ident, module_name); + + // Ignoring Case + if file_ident.eq_ignore_ascii_case(module_name) { return SyntaxRuleResult::Pass; } } diff --git a/testcases/syntaxrules/pass/module_identifier_matches_filename.sv b/testcases/syntaxrules/pass/module_identifier_matches_filename.sv index 55956a6e..09f23048 100644 --- a/testcases/syntaxrules/pass/module_identifier_matches_filename.sv +++ b/testcases/syntaxrules/pass/module_identifier_matches_filename.sv @@ -1,2 +1,2 @@ -module syntaxrules_module_identifier_matches_filename_pass_1of1; +module syntaxrules; endmodule \ No newline at end of file From 74da657eb94625cc20c8f77b97cc12cb17bb33e3 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha <5han7anu@Legion> Date: Mon, 1 Apr 2024 21:58:34 -0400 Subject: [PATCH 09/14] chore: removing debug print statements --- src/syntaxrules/module_identifier_matches_filename.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/syntaxrules/module_identifier_matches_filename.rs b/src/syntaxrules/module_identifier_matches_filename.rs index 0eef843a..c88f3433 100644 --- a/src/syntaxrules/module_identifier_matches_filename.rs +++ b/src/syntaxrules/module_identifier_matches_filename.rs @@ -41,7 +41,6 @@ impl SyntaxRule for ModuleIdentifierMatchesFilename { let path = std::path::Path::new(&path_str); if let Some(file_name_os_str) = path.file_name() { if let Some(file_name) = file_name_os_str.to_str() { - // Iterate over each character in the file name to find the first non-identifier character let mut identifier_end = 0; for (i, c) in file_name.char_indices() { if c.is_alphanumeric() || c == '_' || c == '$' { @@ -54,10 +53,6 @@ impl SyntaxRule for ModuleIdentifierMatchesFilename { let file_ident = &file_name[..identifier_end]; - println !("\n\nPath: {:?}", path_str); - - println!("File: {}, Module: {}\n\n", file_ident, module_name); - // Ignoring Case if file_ident.eq_ignore_ascii_case(module_name) { return SyntaxRuleResult::Pass; From b0ce4a75ec3b0f90d83a9fa5c26a0f9b8de7a073 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha <5han7anu@Legion> Date: Mon, 1 Apr 2024 21:59:39 -0400 Subject: [PATCH 10/14] feat: Updated package_identifier_matches_filename rule to only match substring up to first non-identifier symbol --- .../package_identifier_matches_filename.rs | 20 +++++++++++++++---- .../package_identifier_matches_filename.sv | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/syntaxrules/package_identifier_matches_filename.rs b/src/syntaxrules/package_identifier_matches_filename.rs index 0e1ee628..54dd59e4 100644 --- a/src/syntaxrules/package_identifier_matches_filename.rs +++ b/src/syntaxrules/package_identifier_matches_filename.rs @@ -44,10 +44,22 @@ impl SyntaxRule for PackageIdentifierMatchesFilename { let package_name = syntax_tree.get_str(id.unwrap()).unwrap(); let path = std::path::Path::new(path_str); - if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { - if file_name.ends_with(".sv") { - let file_ident = file_name.trim_end_matches(".sv"); - if package_name == file_ident { + if let Some(file_name_os_str) = path.file_name() { + if let Some(file_name) = file_name_os_str.to_str() { + let mut identifier_end = 0; + for (i, c) in file_name.char_indices() { + if c.is_alphanumeric() || c == '_' || c == '$' { + identifier_end = i + c.len_utf8(); + } else { + // Stop at the first non-identifier character + break; + } + } + + let file_ident = &file_name[..identifier_end]; + + // Ignoring Case + if file_ident.eq_ignore_ascii_case(package_name) { return SyntaxRuleResult::Pass; } } diff --git a/testcases/syntaxrules/pass/package_identifier_matches_filename.sv b/testcases/syntaxrules/pass/package_identifier_matches_filename.sv index a16ae542..991d5961 100644 --- a/testcases/syntaxrules/pass/package_identifier_matches_filename.sv +++ b/testcases/syntaxrules/pass/package_identifier_matches_filename.sv @@ -1,3 +1,3 @@ -package syntaxrules_package_identifier_matches_filename_pass_1of1; +package syntaxrules; endpackage From 0344a17b61bc7dc560a367f478e50afe62964cd1 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha <5han7anu@Legion> Date: Mon, 1 Apr 2024 22:06:29 -0400 Subject: [PATCH 11/14] feat: Updated interface_identifier_matches_filename rule to only match substring up to first non-identifier symbol --- .../interface_identifier_matches_filename.rs | 20 +++++++++++++++---- .../interface_identifier_matches_filename.sv | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/syntaxrules/interface_identifier_matches_filename.rs b/src/syntaxrules/interface_identifier_matches_filename.rs index 5551c828..683b9c7d 100644 --- a/src/syntaxrules/interface_identifier_matches_filename.rs +++ b/src/syntaxrules/interface_identifier_matches_filename.rs @@ -44,10 +44,22 @@ impl SyntaxRule for InterfaceIdentifierMatchesFilename { let interface_name = syntax_tree.get_str(id.unwrap()).unwrap(); let path = std::path::Path::new(path_str); - if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { - if file_name.ends_with(".sv") { - let file_ident = file_name.trim_end_matches(".sv"); - if interface_name == file_ident { + if let Some(file_name_os_str) = path.file_name() { + if let Some(file_name) = file_name_os_str.to_str() { + let mut identifier_end = 0; + for (i, c) in file_name.char_indices() { + if c.is_alphanumeric() || c == '_' || c == '$' { + identifier_end = i + c.len_utf8(); + } else { + // Stop at the first non-identifier character + break; + } + } + + let file_ident = &file_name[..identifier_end]; + + // Ignoring Case + if file_ident.eq_ignore_ascii_case(interface_name) { return SyntaxRuleResult::Pass; } } diff --git a/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv b/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv index c81a754a..02ee10f0 100644 --- a/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv +++ b/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv @@ -1,2 +1,2 @@ -interface syntaxrules_interface_identifier_matches_filename_pass_1of1; +interface syntaxrules; endinterface \ No newline at end of file From 65ab51ba55f8275a61834e581c8fce830eef797d Mon Sep 17 00:00:00 2001 From: Shantanu Sinha <5han7anu@Legion> Date: Mon, 1 Apr 2024 22:07:56 -0400 Subject: [PATCH 12/14] feat: Updated program_identifier_matches_filename rule to only match substring up to first non-identifier symbol --- .../program_identifier_matches_filename.rs | 20 +++++++++++++++---- .../program_identifier_matches_filename.sv | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/syntaxrules/program_identifier_matches_filename.rs b/src/syntaxrules/program_identifier_matches_filename.rs index 7d32c6ac..2f4ea1eb 100644 --- a/src/syntaxrules/program_identifier_matches_filename.rs +++ b/src/syntaxrules/program_identifier_matches_filename.rs @@ -44,10 +44,22 @@ impl SyntaxRule for ProgramIdentifierMatchesFilename { let program_name = syntax_tree.get_str(id.unwrap()).unwrap(); let path = std::path::Path::new(path_str); - if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { - if file_name.ends_with(".sv") { - let file_ident = file_name.trim_end_matches(".sv"); - if program_name == file_ident { + if let Some(file_name_os_str) = path.file_name() { + if let Some(file_name) = file_name_os_str.to_str() { + let mut identifier_end = 0; + for (i, c) in file_name.char_indices() { + if c.is_alphanumeric() || c == '_' || c == '$' { + identifier_end = i + c.len_utf8(); + } else { + // Stop at the first non-identifier character + break; + } + } + + let file_ident = &file_name[..identifier_end]; + + // Ignoring Case + if file_ident.eq_ignore_ascii_case(program_name) { return SyntaxRuleResult::Pass; } } diff --git a/testcases/syntaxrules/pass/program_identifier_matches_filename.sv b/testcases/syntaxrules/pass/program_identifier_matches_filename.sv index 9d84c677..6fac5532 100644 --- a/testcases/syntaxrules/pass/program_identifier_matches_filename.sv +++ b/testcases/syntaxrules/pass/program_identifier_matches_filename.sv @@ -1,2 +1,2 @@ -program syntaxrules_program_identifier_matches_filename_pass_1of1; +program syntaxrules; endprogram \ No newline at end of file From 73cad568a7ba94d443ebad2ce6d9b64d2bfbe968 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha <5han7anu@Legion> Date: Mon, 1 Apr 2024 23:07:35 -0400 Subject: [PATCH 13/14] docs: Updated documentation for the module/package/program/interface_identifier_matches_filename rules + updated contributing --- CONTRIBUTING.md | 1 + ...tion-interface_identifier_matches_filename.md | 16 +++++++++++++--- ...anation-module_identifier_matches_filename.md | 16 +++++++++++++--- ...nation-package_identifier_matches_filename.md | 15 ++++++++++++--- ...nation-program_identifier_matches_filename.md | 15 ++++++++++++--- 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a51b28f..25bafb4c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -147,3 +147,4 @@ under the Developer Certificate of Origin . - Taichi Ishitani (@taichi-ishitani) - Sosuke Hosokawa (@so298) - Jan Remes (@remes-codasip) +- Shantanu Sinha (@ShantanuPSinha) diff --git a/md/syntaxrules-explanation-interface_identifier_matches_filename.md b/md/syntaxrules-explanation-interface_identifier_matches_filename.md index f0704dd0..42b77494 100644 --- a/md/syntaxrules-explanation-interface_identifier_matches_filename.md +++ b/md/syntaxrules-explanation-interface_identifier_matches_filename.md @@ -1,5 +1,15 @@ -Interface Identifier should have the same name as the file it's in. +Interface identifier should have the same name as the file it's in. -```interface Bar``` should be in ```some/path/to/Bar.sv``` +```interface foo;``` is allowed to live in any file of naming convention ```foo ``` -Note that as a result, only one interface can be declared per file. \ No newline at end of file +According to Clause 5.6 of IEEE 1800-2017: + +> A simple identifier shall consist of a sequence of letters, digits, dollar signs (`$`), and underscore (`_`) characters. + +Any symbol defined outside this exhaustive list is considered a non-identifier. + +The stopping point for string matching has to be a non-identifier character. + +For example, the interface declaration ```interface foo;``` is valid in filenames such as ```foo-Bar.sv```, ```foo.debug.sv```, and ```foo-final-version.sv```. Each of these filenames begins with the interface identifier ```foo``` and is immediately followed by a non-identifier character (```-```, ```.```, or another acceptable symbol), making them compliant. A filename like ```FooBar.sv``` is invalid for the ```interface Foo;``` declaration since it does not contain a non-identifier character following the interface name. + +Note that as a consequence, only one interface can be declared per file. \ No newline at end of file diff --git a/md/syntaxrules-explanation-module_identifier_matches_filename.md b/md/syntaxrules-explanation-module_identifier_matches_filename.md index d90c7d32..4864e28a 100644 --- a/md/syntaxrules-explanation-module_identifier_matches_filename.md +++ b/md/syntaxrules-explanation-module_identifier_matches_filename.md @@ -1,5 +1,15 @@ -Module Identifier should have the same name as the file it's in. +Module identifier should have the same name as the file it's in. -```module Bar``` should be in ```some/path/to/Bar.sv``` +```module foo;``` is allowed to live in any file of naming convention ```foo ``` -Note that as a result, only one module can be declared per file. \ No newline at end of file +According to Clause 5.6 of IEEE 1800-2017: + +> A simple identifier shall consist of a sequence of letters, digits, dollar signs (`$`), and underscore (`_`) characters. + +Any symbol defined outside this exhaustive list is considered a non-identifier. + +The stopping point for string matching has to be a non-identifier character. + +For example, the module declaration ```module foo;``` is valid in filenames such as ```foo-Bar.sv```, ```foo.debug.sv```, and ```foo-final-version.sv```. Each of these filenames begins with the module identifier ```foo``` and is immediately followed by a non-identifier character (```-```, ```.```, or another acceptable symbol), making them compliant. A filename like ```FooBar.sv``` is invalid for the ```module Foo;``` declaration since it does not contain a non-identifier character following the module name. + +Note that as a consequence, only one module can be declared per file. \ No newline at end of file diff --git a/md/syntaxrules-explanation-package_identifier_matches_filename.md b/md/syntaxrules-explanation-package_identifier_matches_filename.md index be4dd149..56d7369f 100644 --- a/md/syntaxrules-explanation-package_identifier_matches_filename.md +++ b/md/syntaxrules-explanation-package_identifier_matches_filename.md @@ -1,6 +1,15 @@ -Package Identifier should have the same name as the file it's in. +Package identifier should have the same name as the file it's in. -```package Bar``` should be in ```some/path/to/Bar.sv``` +```package foo;``` is allowed to live in any file of naming convention ```foo ``` +According to Clause 5.6 of IEEE 1800-2017: -Note that as a result, only one package can be declared per file. \ No newline at end of file +> A simple identifier shall consist of a sequence of letters, digits, dollar signs (`$`), and underscore (`_`) characters. + +Any symbol defined outside this exhaustive list is considered a non-identifier. + +The stopping point for string matching has to be a non-identifier character. + +For example, the package declaration ```package foo;``` is valid in filenames such as ```foo-Bar.sv```, ```foo.debug.sv```, and ```foo-final-version.sv```. Each of these filenames begins with the package identifier ```foo``` and is immediately followed by a non-identifier character (```-```, ```.```, or another acceptable symbol), making them compliant. A filename like ```FooBar.sv``` is invalid for the ```package Foo;``` declaration since it does not contain a non-identifier character following the package name. + +Note that as a consequence, only one package can be declared per file. \ No newline at end of file diff --git a/md/syntaxrules-explanation-program_identifier_matches_filename.md b/md/syntaxrules-explanation-program_identifier_matches_filename.md index 2ff88f6d..3ac1b003 100644 --- a/md/syntaxrules-explanation-program_identifier_matches_filename.md +++ b/md/syntaxrules-explanation-program_identifier_matches_filename.md @@ -1,6 +1,15 @@ -Program Identifier should have the same name as the file it's in. +Program identifier should have the same name as the file it's in. -```program Bar``` should be in ```some/path/to/Bar.sv``` +```program foo;``` is allowed to live in any file of naming convention ```foo ``` +According to Clause 5.6 of IEEE 1800-2017: -Note that as a result, only one program can be declared per file. \ No newline at end of file +> A simple identifier shall consist of a sequence of letters, digits, dollar signs (`$`), and underscore (`_`) characters. + +Any symbol defined outside this exhaustive list is considered a non-identifier. + +The stopping point for string matching has to be a non-identifier character. + +For example, the program declaration ```program foo;``` is valid in filenames such as ```foo-Bar.sv```, ```foo.debug.sv```, and ```foo-final-version.sv```. Each of these filenames begins with the program identifier ```foo``` and is immediately followed by a non-identifier character (```-```, ```.```, or another acceptable symbol), making them compliant. A filename like ```FooBar.sv``` is invalid for the ```program Foo;``` declaration since it does not contain a non-identifier character following the program name. + +Note that as a consequence, only one program can be declared per file. \ No newline at end of file From 9f8472e2bef1545bbef0c50b1ae1727c15776de3 Mon Sep 17 00:00:00 2001 From: Shantanu Sinha <5han7anu@Legion> Date: Mon, 1 Apr 2024 23:21:08 -0400 Subject: [PATCH 14/14] docs: Updated testcases with an explanation for why identifier 'syntaxrules' works --- MANUAL.md | 88 +++++++++++++++---- .../interface_identifier_matches_filename.sv | 6 +- .../module_identifier_matches_filename.sv | 6 +- .../package_identifier_matches_filename.sv | 4 + .../program_identifier_matches_filename.sv | 6 +- 5 files changed, 90 insertions(+), 20 deletions(-) diff --git a/MANUAL.md b/MANUAL.md index ab06ccf1..b3c995fb 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -2193,8 +2193,12 @@ Encourages consistent file naming standards for packages and assists in searchin ### Pass Example (1 of 1) ```systemverilog -interface syntaxrules_interface_identifier_matches_filename_pass_1of1; +interface syntaxrules; endinterface + +// This testcase, when executed, is called from a file named "syntaxrules.interface_identifier_matches_filename.pass.1of1" +// The rule matches all valid characters up until the first non-identifier (in this case, the period). +// The file identifier to be matched in this case becomes "syntaxrules" which matches the interface identifier ``` ### Fail Example (1 of 1) @@ -2205,11 +2209,21 @@ endinterface ### Explanation -Interface Identifier should have the same name as the file it's in. +Interface identifier should have the same name as the file it's in. + +```interface foo;``` is allowed to live in any file of naming convention ```foo ``` + +According to Clause 5.6 of IEEE 1800-2017: + +> A simple identifier shall consist of a sequence of letters, digits, dollar signs (`$`), and underscore (`_`) characters. + +Any symbol defined outside this exhaustive list is considered a non-identifier. + +The stopping point for string matching has to be a non-identifier character. -```interface Bar``` should be in ```some/path/to/Bar.sv``` +For example, the interface declaration ```interface foo;``` is valid in filenames such as ```foo-Bar.sv```, ```foo.debug.sv```, and ```foo-final-version.sv```. Each of these filenames begins with the interface identifier ```foo``` and is immediately followed by a non-identifier character (```-```, ```.```, or another acceptable symbol), making them compliant. A filename like ```FooBar.sv``` is invalid for the ```interface Foo;``` declaration since it does not contain a non-identifier character following the interface name. -Note that as a result, only one interface can be declared per file. +Note that as a consequence, only one interface can be declared per file. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -3687,8 +3701,12 @@ Encourages consistent file naming standards for packages and assists in searchin ### Pass Example (1 of 1) ```systemverilog -module syntaxrules_module_identifier_matches_filename_pass_1of1; -endmodule +module syntaxrules; +endmodule + +// This testcase, when executed, is called from a file named "syntaxrules.module_identifier_matches_filename.pass.1of1" +// The rule matches all valid characters up until the first non-identifier (in this case, the period). +// The file identifier to be matched in this case becomes "syntaxrules" which matches the module identifier ``` ### Fail Example (1 of 1) @@ -3699,11 +3717,21 @@ endmodule ### Explanation -Module Identifier should have the same name as the file it's in. +Module identifier should have the same name as the file it's in. + +```module foo;``` is allowed to live in any file of naming convention ```foo ``` + +According to Clause 5.6 of IEEE 1800-2017: + +> A simple identifier shall consist of a sequence of letters, digits, dollar signs (`$`), and underscore (`_`) characters. + +Any symbol defined outside this exhaustive list is considered a non-identifier. -```module Bar``` should be in ```some/path/to/Bar.sv``` +The stopping point for string matching has to be a non-identifier character. -Note that as a result, only one module can be declared per file. +For example, the module declaration ```module foo;``` is valid in filenames such as ```foo-Bar.sv```, ```foo.debug.sv```, and ```foo-final-version.sv```. Each of these filenames begins with the module identifier ```foo``` and is immediately followed by a non-identifier character (```-```, ```.```, or another acceptable symbol), making them compliant. A filename like ```FooBar.sv``` is invalid for the ```module Foo;``` declaration since it does not contain a non-identifier character following the module name. + +Note that as a consequence, only one module can be declared per file. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -4509,9 +4537,13 @@ Encourages consistent file naming standards for packages and assists in searchin ### Pass Example (1 of 1) ```systemverilog -package syntaxrules_package_identifier_matches_filename_pass_1of1; +package syntaxrules; endpackage + +// This testcase, when executed, is called from a file named "syntaxrules.package_identifier_matches_filename.pass.1of1" +// The rule matches all valid characters up until the first non-identifier (in this case, the period). +// The file identifier to be matched in this case becomes "syntaxrules" which matches the package identifier ``` ### Fail Example (1 of 1) @@ -4522,12 +4554,21 @@ endpackage ### Explanation -Package Identifier should have the same name as the file it's in. +Package identifier should have the same name as the file it's in. + +```package foo;``` is allowed to live in any file of naming convention ```foo ``` + +According to Clause 5.6 of IEEE 1800-2017: + +> A simple identifier shall consist of a sequence of letters, digits, dollar signs (`$`), and underscore (`_`) characters. + +Any symbol defined outside this exhaustive list is considered a non-identifier. -```package Bar``` should be in ```some/path/to/Bar.sv``` +The stopping point for string matching has to be a non-identifier character. +For example, the package declaration ```package foo;``` is valid in filenames such as ```foo-Bar.sv```, ```foo.debug.sv```, and ```foo-final-version.sv```. Each of these filenames begins with the package identifier ```foo``` and is immediately followed by a non-identifier character (```-```, ```.```, or another acceptable symbol), making them compliant. A filename like ```FooBar.sv``` is invalid for the ```package Foo;``` declaration since it does not contain a non-identifier character following the package name. -Note that as a result, only one package can be declared per file. +Note that as a consequence, only one package can be declared per file. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -5025,8 +5066,12 @@ Encourages consistent file naming standards for packages and assists in searchin ### Pass Example (1 of 1) ```systemverilog -program syntaxrules_program_identifier_matches_filename_pass_1of1; +program syntaxrules; endprogram + +// This testcase, when executed, is called from a file named "syntaxrules.program_identifier_matches_filename.pass.1of1" +// The rule matches all valid characters up until the first non-identifier (in this case, the period). +// The file identifier to be matched in this case becomes "syntaxrules" which matches the program identifier ``` ### Fail Example (1 of 1) @@ -5037,12 +5082,21 @@ endprogram ### Explanation -Program Identifier should have the same name as the file it's in. +Program identifier should have the same name as the file it's in. + +```program foo;``` is allowed to live in any file of naming convention ```foo ``` + +According to Clause 5.6 of IEEE 1800-2017: + +> A simple identifier shall consist of a sequence of letters, digits, dollar signs (`$`), and underscore (`_`) characters. + +Any symbol defined outside this exhaustive list is considered a non-identifier. -```program Bar``` should be in ```some/path/to/Bar.sv``` +The stopping point for string matching has to be a non-identifier character. +For example, the program declaration ```program foo;``` is valid in filenames such as ```foo-Bar.sv```, ```foo.debug.sv```, and ```foo-final-version.sv```. Each of these filenames begins with the program identifier ```foo``` and is immediately followed by a non-identifier character (```-```, ```.```, or another acceptable symbol), making them compliant. A filename like ```FooBar.sv``` is invalid for the ```program Foo;``` declaration since it does not contain a non-identifier character following the program name. -Note that as a result, only one program can be declared per file. +Note that as a consequence, only one program can be declared per file. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv b/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv index 02ee10f0..acdcefbe 100644 --- a/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv +++ b/testcases/syntaxrules/pass/interface_identifier_matches_filename.sv @@ -1,2 +1,6 @@ interface syntaxrules; -endinterface \ No newline at end of file +endinterface + +// This testcase, when executed, is called from a file named "syntaxrules.interface_identifier_matches_filename.pass.1of1" +// The rule matches all valid characters up until the first non-identifier (in this case, the period). +// The file identifier to be matched in this case becomes "syntaxrules" which matches the interface identifier \ No newline at end of file diff --git a/testcases/syntaxrules/pass/module_identifier_matches_filename.sv b/testcases/syntaxrules/pass/module_identifier_matches_filename.sv index 09f23048..f45cd5f9 100644 --- a/testcases/syntaxrules/pass/module_identifier_matches_filename.sv +++ b/testcases/syntaxrules/pass/module_identifier_matches_filename.sv @@ -1,2 +1,6 @@ module syntaxrules; -endmodule \ No newline at end of file +endmodule + +// This testcase, when executed, is called from a file named "syntaxrules.module_identifier_matches_filename.pass.1of1" +// The rule matches all valid characters up until the first non-identifier (in this case, the period). +// The file identifier to be matched in this case becomes "syntaxrules" which matches the module identifier \ No newline at end of file diff --git a/testcases/syntaxrules/pass/package_identifier_matches_filename.sv b/testcases/syntaxrules/pass/package_identifier_matches_filename.sv index 991d5961..db846739 100644 --- a/testcases/syntaxrules/pass/package_identifier_matches_filename.sv +++ b/testcases/syntaxrules/pass/package_identifier_matches_filename.sv @@ -1,3 +1,7 @@ package syntaxrules; endpackage + +// This testcase, when executed, is called from a file named "syntaxrules.package_identifier_matches_filename.pass.1of1" +// The rule matches all valid characters up until the first non-identifier (in this case, the period). +// The file identifier to be matched in this case becomes "syntaxrules" which matches the package identifier \ No newline at end of file diff --git a/testcases/syntaxrules/pass/program_identifier_matches_filename.sv b/testcases/syntaxrules/pass/program_identifier_matches_filename.sv index 6fac5532..e6b9aa34 100644 --- a/testcases/syntaxrules/pass/program_identifier_matches_filename.sv +++ b/testcases/syntaxrules/pass/program_identifier_matches_filename.sv @@ -1,2 +1,6 @@ program syntaxrules; -endprogram \ No newline at end of file +endprogram + +// This testcase, when executed, is called from a file named "syntaxrules.program_identifier_matches_filename.pass.1of1" +// The rule matches all valid characters up until the first non-identifier (in this case, the period). +// The file identifier to be matched in this case becomes "syntaxrules" which matches the program identifier \ No newline at end of file