Skip to content

Commit 207af67

Browse files
authored
Issue#1479: Modified architecture_025 to accept regular expressions as names (#1487)
* Issue#1479: Modified architecture_025 to accept regular expressions as names. * Issue#1479: Corrected error by resetting regexp names. * Issue#1479: Modified test for architecture_025 to test regular expressions as names. * Issue#1479: Modified docs for architecture_025. * Issue#1479: Formatting. * Issue#1479: Code improvement. * Issue#1479: Formatting.
1 parent a8e061a commit 207af67

File tree

5 files changed

+41
-18
lines changed

5 files changed

+41
-18
lines changed

docs/architecture_rules.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ architecture_025
516516
This rule checks for valid names for the architecture.
517517
Typical architecture names are: RTL, EMPTY, and BEHAVE.
518518
This rule allows the user to restrict what can be used for an architecture name.
519+
Note that regular expressions are accepted in the **names** field.
519520

520521
.. NOTE:: This rule is disabled by default.
521522
You can enable and configure the names using the following configuration.
@@ -531,6 +532,7 @@ This rule allows the user to restrict what can be used for an architecture name.
531532
- rtl
532533
- empty
533534
- behave
535+
- my_pattern.*
534536
535537
**Violation**
536538

tests/architecture/test_rule_025.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,54 +28,68 @@ def test_rule_025(self):
2828
lExpected = [3, 10, 17, 24]
2929
oRule.analyze(self.oFile)
3030
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
31-
self.assertEqual("Architecture identifier must be from this list: ", oRule._get_solution(None))
31+
self.assertEqual("Architecture identifier must match a name from this list: ", oRule._get_solution(None))
3232

3333
oRule.violations = []
3434
oRule.names = []
3535
oRule.names.append("rtl")
3636
lExpected = [10, 17, 24]
3737
oRule.analyze(self.oFile)
3838
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
39-
self.assertEqual("Architecture identifier must be from this list: rtl", oRule._get_solution(None))
39+
self.assertEqual("Architecture identifier must match a name from this list: rtl", oRule._get_solution(None))
4040

4141
oRule.violations = []
4242
oRule.names = ["ENTITY1"]
4343
lExpected = [3, 17, 24]
4444
oRule.analyze(self.oFile)
4545
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
46-
self.assertEqual("Architecture identifier must be from this list: ENTITY1", oRule._get_solution(None))
46+
self.assertEqual("Architecture identifier must match a name from this list: ENTITY1", oRule._get_solution(None))
4747

4848
oRule.violations = []
4949
oRule.names = ["BLUE"]
5050
lExpected = [3, 10, 24]
5151
oRule.analyze(self.oFile)
5252
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
53-
self.assertEqual("Architecture identifier must be from this list: BLUE", oRule._get_solution(None))
53+
self.assertEqual("Architecture identifier must match a name from this list: BLUE", oRule._get_solution(None))
5454

5555
oRule.violations = []
5656
oRule.names = ["CDC"]
5757
lExpected = [3, 10, 17]
5858
oRule.analyze(self.oFile)
5959
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
60-
self.assertEqual("Architecture identifier must be from this list: CDC", oRule._get_solution(None))
60+
self.assertEqual("Architecture identifier must match a name from this list: CDC", oRule._get_solution(None))
6161

6262
oRule.violations = []
6363
oRule.names = ["rtl", "CDC"]
6464
lExpected = [10, 17]
6565
oRule.analyze(self.oFile)
6666
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
67-
self.assertEqual("Architecture identifier must be from this list: rtl, CDC", oRule._get_solution(None))
67+
self.assertEqual("Architecture identifier must match a name from this list: rtl, CDC", oRule._get_solution(None))
6868

6969
oRule.violations = []
7070
oRule.names = ["rtl", "cdc", "blue"]
7171
lExpected = [10]
7272
oRule.analyze(self.oFile)
7373
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
74-
self.assertEqual("Architecture identifier must be from this list: rtl, cdc, blue", oRule._get_solution(None))
74+
self.assertEqual("Architecture identifier must match a name from this list: rtl, cdc, blue", oRule._get_solution(None))
7575

7676
oRule.violations = []
7777
oRule.names = ["rtl", "cdc", "blue", "entity1"]
7878
lExpected = []
7979
oRule.analyze(self.oFile)
8080
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
81-
self.assertEqual("Architecture identifier must be from this list: rtl, cdc, blue, entity1", oRule._get_solution(None))
81+
self.assertEqual("Architecture identifier must match a name from this list: rtl, cdc, blue, entity1", oRule._get_solution(None))
82+
83+
oRule.violations = []
84+
oRule.names = [".ntit\w\d"]
85+
lExpected = [3, 17, 24]
86+
oRule.analyze(self.oFile)
87+
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
88+
self.assertEqual("Architecture identifier must match a name from this list: .ntit\w\d", oRule._get_solution(None))
89+
90+
oRule.violations = []
91+
oRule.names = ["\w\w\w", "b...", ".ntit\w\d"]
92+
lExpected = []
93+
oRule.analyze(self.oFile)
94+
self.assertEqual(lExpected, utils.extract_violation_lines_from_violation_object(oRule.violations))
95+
self.assertEqual("Architecture identifier must match a name from this list: \w\w\w, b..., .ntit\w\d", oRule._get_solution(None))

vsg/rules/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from .insert_token_next_to_token_if_it_does_not_exist_between_tokens_using_value_from_token import (
3333
insert_token_next_to_token_if_it_does_not_exist_between_tokens_using_value_from_token,
3434
)
35-
from .is_token_value_one_of import is_token_value_one_of
35+
from .does_token_value_match_one_of import does_token_value_match_one_of
3636
from .align_tokens_in_region_between_tokens import align_tokens_in_region_between_tokens
3737
from .align_tokens_in_region_between_tokens_unless_between_tokens import align_tokens_in_region_between_tokens_unless_between_tokens
3838
from .align_tokens_in_region_between_tokens_when_between_tokens_unless_between_tokens import (

vsg/rules/architecture/rule_025.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
# -*- coding: utf-8 -*-
22

3-
from vsg.rules import is_token_value_one_of
3+
from vsg.rules import does_token_value_match_one_of
44
from vsg.token import architecture_body as token
55

66

7-
class rule_025(is_token_value_one_of):
7+
class rule_025(does_token_value_match_one_of):
88
"""
99
This rule checks for valid names for the architecture.
1010
Typical architecture names are: RTL, EMPTY, and BEHAVE.
1111
This rule allows the user to restrict what can be used for an architecture name.
12+
Note that regular expressions are accepted in the **names** field.
1213
1314
.. NOTE:: This rule is disabled by default.
1415
You can enable and configure the names using the following configuration.
@@ -24,6 +25,7 @@ class rule_025(is_token_value_one_of):
2425
- rtl
2526
- empty
2627
- behave
28+
- my_pattern.*
2729
2830
**Violation**
2931
@@ -40,4 +42,4 @@ def __init__(self):
4042
super().__init__(token.identifier)
4143

4244
def _get_solution(self, iLineNumber):
43-
return "Architecture identifier must be from this list: " + ", ".join(self.names)
45+
return "Architecture identifier must match a name from this list: " + ", ".join(self.names)

vsg/rules/is_token_value_one_of.py renamed to vsg/rules/does_token_value_match_one_of.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# -*- coding: utf-8 -*-
22

3+
import re
34

45
from vsg import violation
56
from vsg.rule_group import naming
67

78

8-
class is_token_value_one_of(naming.Rule):
9+
class does_token_value_match_one_of(naming.Rule):
910
"""
10-
Checks if a token value is in a list of provided values.
11+
Checks if a token value matches one of provided regex patterns.
1112
"""
1213

1314
def __init__(self, token):
@@ -24,11 +25,15 @@ def _get_tokens_of_interest(self, oFile):
2425

2526
def _analyze(self, lToi):
2627
self.solution = self._get_solution(None)
27-
lower_names = []
28-
for sName in self.names:
29-
lower_names.append(sName.lower())
28+
lRegexNames = [re.compile(name, re.IGNORECASE) for name in self.names]
3029

3130
for oToi in lToi:
3231
lTokens = oToi.get_tokens()
33-
if not lTokens[0].get_lower_value() in lower_names:
32+
if self._check_for_violation(lTokens[0].get_lower_value(), lRegexNames):
3433
self.add_violation(violation.New(oToi.get_line_number(), oToi, self.solution))
34+
35+
def _check_for_violation(self, sToken, lRegexNames):
36+
for regex in lRegexNames:
37+
if regex.fullmatch(sToken) is not None:
38+
return False
39+
return True

0 commit comments

Comments
 (0)