Skip to content

Commit 99a95b7

Browse files
authored
Merge pull request #405 from albertziegenhagel/pp-nested-if
Fix nested pre-processor blocks
2 parents 81a33a1 + 7c24d0c commit 99a95b7

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

fortls/parsers/internal/parser.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,9 +2209,10 @@ def append_multiline_macro(def_value: str | tuple, line: str):
22092209
elif exc_continue:
22102210
log.debug("%s !!! Conditional EXCLUDED(%d)", line.strip(), i + 1)
22112211
continue
2212+
stack_is_true = all(scope[0] < 0 for scope in pp_stack)
22122213
# Handle variable/macro definitions files
22132214
match = FRegex.PP_DEF.match(line)
2214-
if (match is not None) and ((len(pp_stack) == 0) or (pp_stack[-1][0] < 0)):
2215+
if (match is not None) and stack_is_true:
22152216
output_file.append(line)
22162217
pp_defines.append(i + 1)
22172218
def_name = match.group(2)
@@ -2246,7 +2247,7 @@ def append_multiline_macro(def_value: str | tuple, line: str):
22462247
continue
22472248
# Handle include files
22482249
match = FRegex.PP_INCLUDE.match(line)
2249-
if (match is not None) and ((len(pp_stack) == 0) or (pp_stack[-1][0] < 0)):
2250+
if (match is not None) and stack_is_true:
22502251
log.debug("%s !!! Include statement(%d)", line.strip(), i + 1)
22512252
include_filename = match.group(1).replace('"', "")
22522253
include_path = None

test/test_preproc.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ def check_return(result_array, checks):
4242
string += hover_req(file_path, 30, 23)
4343
file_path = root_dir / "preproc_if_elif_skip.F90"
4444
string += hover_req(file_path, 30, 23)
45+
file_path = root_dir / "preproc_if_nested.F90"
46+
string += hover_req(file_path, 33, 23)
4547
config = str(root_dir / ".pp_conf.json")
4648
errcode, results = run_request(string, ["--config", config])
4749
assert errcode == 0
@@ -68,6 +70,7 @@ def check_return(result_array, checks):
6870
"```fortran90\nINTEGER, PARAMETER :: res = 0+1+0+0\n```",
6971
"```fortran90\nINTEGER, PARAMETER :: res = 0+0+0+1\n```",
7072
"```fortran90\nINTEGER, PARAMETER :: res = 1+0+0+0\n```",
73+
"```fortran90\nINTEGER, PARAMETER :: res = 0+0+1+0\n```",
7174
)
7275
assert len(ref_results) == len(results) - 1
7376
check_return(results[1:], ref_results)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
subroutine preprocessor_if_nested()
2+
3+
! This file, as used in test_preproc, tests that when there are nested
4+
! if-else preprocessor blocks, only the branches are used where ALL
5+
! statements leading to the definition evaluate to true.
6+
7+
#if 0
8+
#if 1
9+
#define PART1 1
10+
#else
11+
#define PART2 1
12+
#endif
13+
#else
14+
#if 1
15+
#define PART3 1
16+
#else
17+
#define PART4 1
18+
#endif
19+
#endif
20+
21+
#ifndef PART1
22+
#define PART1 0
23+
#endif
24+
#ifndef PART2
25+
#define PART2 0
26+
#endif
27+
#ifndef PART3
28+
#define PART3 0
29+
#endif
30+
#ifndef PART4
31+
#define PART4 0
32+
#endif
33+
34+
integer, parameter :: res = PART1+PART2+PART3+PART4
35+
36+
endsubroutine preprocessor_if_nested

0 commit comments

Comments
 (0)