diff --git a/CHANGELOG.md b/CHANGELOG.md index aee0f6fc..53589708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ Modifications by (in alphabetical order): * P. Vitt, University of Siegen, Germany * A. Voysey, UK Met Office +16/07/2026 PR #520 for #519. Fix truncation of a character length expression that + contains a comma (e.g. the arguments to an intrinsic such as + MAX) when the kind appears before the length in a char-selector. + 25/06/2026 PR #514 towards #428. Add some Fortran2008-only intrinsics. 19/06/2026 PR #513 for #512. Fix circular import in Fortran2008. diff --git a/src/fparser/two/Fortran2003.py b/src/fparser/two/Fortran2003.py index b9ad9972..ecc89765 100644 --- a/src/fparser/two/Fortran2003.py +++ b/src/fparser/two/Fortran2003.py @@ -1534,7 +1534,7 @@ def match(string: str): line = line[1:].lstrip() i = line.find(",") if i == -1: - return None, Scalar_Int_Initialization_Expr(line) + return None, Scalar_Int_Initialization_Expr(repmap(line)) v = line[i + 1 :].lstrip() line = line[:i].rstrip() if v[:3].upper() != "LEN": @@ -1543,6 +1543,8 @@ def match(string: str): if not v.startswith("="): return v = v[1:].lstrip() + v = repmap(v) + line = repmap(line) return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line) i = line.find(",") @@ -1553,6 +1555,8 @@ def match(string: str): if line[:4].upper() == "KIND" and line[4:].lstrip().startswith("="): line = line[4:].lstrip() line = line[1:].lstrip() + v = repmap(v) + line = repmap(line) return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line) def tostr(self): diff --git a/src/fparser/two/tests/test_fortran2003.py b/src/fparser/two/tests/test_fortran2003.py index 9c8e27e6..cfcefaa1 100644 --- a/src/fparser/two/tests/test_fortran2003.py +++ b/src/fparser/two/tests/test_fortran2003.py @@ -458,6 +458,21 @@ def test_char_selector(): # R424 assert isinstance(obj, tcls), repr(obj) assert str(obj) == "(LEN = 2, KIND = 8)" + # A length that is itself an expression containing a comma (e.g. the + # arguments to an intrinsic) must survive the splitting of the kind and + # length parts of the selector. The kind-first and positional forms of + # the selector previously left the length expression truncated at the + # inner comma. + obj = tcls("(kind=8,len=max(2, 0))") + assert isinstance(obj, tcls), repr(obj) + assert str(obj) == "(LEN = MAX(2, 0), KIND = 8)" + assert "F2PY" not in repr(obj) + + obj = tcls("(max(2, 0),8)") + assert isinstance(obj, tcls), repr(obj) + assert str(obj) == "(LEN = MAX(2, 0), KIND = 8)" + assert "F2PY" not in repr(obj) + def test_complex_literal_constant(): # R421 tcls = Complex_Literal_Constant