Skip to content

Commit

Permalink
Don't try to validate length of strings without length (#118)
Browse files Browse the repository at this point in the history
Single character appear like character array variables but with
no length.  The variable length array style rule should not apply
and this change adds an exemption for them.
  • Loading branch information
MatthewHambley authored Aug 24, 2023
1 parent b1b8566 commit 0340b1c
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 7 deletions.
8 changes: 6 additions & 2 deletions source/stylist/fortran.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,8 @@ class AutoCharArrayIntent(FortranRule):
subroutine or function arguments have intent(in) to avoid writing
outside the given array.
"""
def _message(self, name, intent):
@staticmethod
def __message(name, intent):
return (f"Arguments of type character(*) must have intent IN, but "
f"{name} has intent {intent}.")

Expand Down Expand Up @@ -630,6 +631,9 @@ def examine_fortran(self, subject: FortranSource) -> List[Issue]:
if not type_spec.items[0] == "CHARACTER":
continue
param_value = type_spec.items[1]
# If no length is specified we don't care
if param_value is None:
continue
# This might be a length selector, if so get the param value
if isinstance(param_value, Fortran2003.Length_Selector):
param_value = param_value.items[1]
Expand All @@ -654,7 +658,7 @@ def examine_fortran(self, subject: FortranSource) -> List[Issue]:
if intent_attr.items[1].string == "IN":
continue
issues.append(Issue(
self._message(
self.__message(
declaration.items[2].string,
intent_attr.items[1]
),
Expand Down
45 changes: 40 additions & 5 deletions unit-tests/fortran_auto_char_array_intent_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import stylist.fortran
from stylist.source import FortranSource, SourceStringReader

TEST_CASE = """
NORMAL_TEST_CASE = """
program cases
! A char array outside a function or subroutine, no exception
character (*) :: autochar_glob
Expand All @@ -30,28 +30,63 @@
end program cases
"""

TEST_EXPECTATION = [
NORMAL_TEST_EXPECTATION = [
('12: Arguments of type character(*) must have intent IN, '
'but autochar_inout has intent INOUT.'),
('14: Arguments of type character(*) must have intent IN, '
'but autochar_out has intent OUT.')
]

SINGLE_CHAR_CASE = """
program single_char
implicit none
character :: single_program_character
contains
subroutine single_character( char_in, char_inout, char_out, char_def )
implicit none
character, intent(in) :: char_in
character, intent(inout) :: char_inout
character, intent(out) :: char_out
character :: char_def
end subroutine single_character
end program single_char
"""


class TestAutoCharArrayIntent:
"""
Tests the rule that variable length character arguments should
have intent(in)
"""

def test(self):
def test_normal_behaviour(self):
"""
Ensures the test case produces exactly the issues in expectation
"""
reader = SourceStringReader(TEST_CASE)
reader = SourceStringReader(NORMAL_TEST_CASE)
source = FortranSource(reader)
unit_under_test = stylist.fortran.AutoCharArrayIntent()
issues = unit_under_test.examine(source)
strings = [str(issue) for issue in issues]

assert strings == TEST_EXPECTATION
assert strings == NORMAL_TEST_EXPECTATION

def test_single_char(self):
"""
Ensures the test can handle no length being specified.
"""
reader = SourceStringReader(SINGLE_CHAR_CASE)
source = FortranSource(reader)
test_unit = stylist.fortran.AutoCharArrayIntent()
issues = test_unit.examine(source)

strings = [str(issue) for issue in issues]
assert strings == []

0 comments on commit 0340b1c

Please sign in to comment.