Skip to content

Commit 74f3c6a

Browse files
albertziegenhagelgnikit
authored andcommitted
Ignore preprocessor lines when detecting fixed form fortran
Currently a file with the content ``` #if defined(A) && !defined(B) c This is a fixed-form style comment #endif ``` is categorized as free-form Fortran because the preprocess if-clause contains ampersands and exclamation marks. This commit makes the detection algorithm ignore all lines starting with `#` if pre-processing is enabled for that file. Pre-processor lines are not valid Fortran code and should IMO not be taken into account when trying to determine the Fortran form.
1 parent 71d5f40 commit 74f3c6a

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

fortls/helper_functions.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def expand_name(line: str, char_pos: int) -> str:
3838
return ""
3939

4040

41-
def detect_fixed_format(file_lines: list[str]) -> bool:
41+
def detect_fixed_format(file_lines: list[str], preproc: bool = False) -> bool:
4242
"""Detect fixed/free format by looking for characters in label columns
4343
and variable declarations before column 6. Treat intersection format
4444
files as free format.
@@ -47,6 +47,9 @@ def detect_fixed_format(file_lines: list[str]) -> bool:
4747
----------
4848
file_lines : list[str]
4949
List of consecutive file lines
50+
preproc : bool
51+
If true, preprocessor directives (lines starting with '#') will be
52+
ignored
5053
5154
Returns
5255
-------
@@ -68,8 +71,15 @@ def detect_fixed_format(file_lines: list[str]) -> bool:
6871
Lines wih ampersands are not fixed format
6972
>>> detect_fixed_format(['trailing line & ! comment'])
7073
False
74+
75+
But preprocessor lines might be ignored
76+
>>> detect_fixed_format(['#if defined(A) && !defined(B)'], preproc=True)
77+
True
7178
"""
7279
for line in file_lines:
80+
# Ignore preprocessor lines
81+
if preproc and line.startswith("#"):
82+
continue
7383
if FRegex.FREE_FORMAT_TEST.match(line):
7484
return False
7585
tmp_match = FRegex.VAR.match(line)

fortls/parsers/internal/parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ def load_from_disk(self) -> tuple[str | None, bool | None]:
902902

903903
self.hash = hash
904904
self.contents_split = contents.splitlines()
905-
self.fixed = detect_fixed_format(self.contents_split)
905+
self.fixed = detect_fixed_format(self.contents_split, self.preproc)
906906
self.contents_pp = self.contents_split
907907
self.nLines = len(self.contents_split)
908908
return None, True
@@ -1011,7 +1011,7 @@ def set_contents(self, contents_split: list, detect_format: bool = True):
10111011
self.contents_pp = self.contents_split
10121012
self.nLines = len(self.contents_split)
10131013
if detect_format:
1014-
self.fixed = detect_fixed_format(self.contents_split)
1014+
self.fixed = detect_fixed_format(self.contents_split, self.preproc)
10151015

10161016
def get_line(self, line_no: int, pp_content: bool = False) -> str:
10171017
"""Get single line from file"""

test/test_helper.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from fortls.helper_functions import detect_fixed_format
2+
3+
4+
def test_detect_fixed_format():
5+
assert detect_fixed_format([" free format"]) is False
6+
assert detect_fixed_format([" INTEGER, PARAMETER :: N = 10"]) is False
7+
assert detect_fixed_format(["C Fixed format"]) is True
8+
assert detect_fixed_format(["trailing line & ! comment"]) is False
9+
assert (
10+
detect_fixed_format(
11+
["#if defined(A) && !defined(B)", "C Fixed format", "#endif"], preproc=True
12+
)
13+
is True
14+
)
15+
assert (
16+
detect_fixed_format(
17+
["#if defined(A) && !defined(B)", " free format", "#endif"], preproc=True
18+
)
19+
is False
20+
)

0 commit comments

Comments
 (0)