67 implicit none;
private
93 logical,
public :: active
94 logical,
public :: has_met
134 subroutine handle_if(line, filename, line_num, macros, token)
135 character(*),
intent(in) :: line, filename
136 integer,
intent(in) :: line_num
137 type(
macro),
intent(in) :: macros(:)
138 character(*),
intent(in) :: token
140 character(:),
allocatable :: expr
141 logical :: result, parent_active
145 if (
verbose) print *,
"Error: Conditional nesting too deep at ",
trim(filename),
":", line_num
150 expr =
trim(adjustl(line(pos:)))
151 if (
verbose) print *,
"Evaluating #if: '",
trim(expr),
"'"
171 character(*),
intent(in) :: line
172 character(*),
intent(in) :: filename
173 integer,
intent(in) :: line_num
174 type(
macro),
intent(in) :: macros(:)
175 character(*),
intent(in) :: token
177 character(:),
allocatable :: name
178 logical :: defined, parent_active
182 if (
verbose) print *,
"Error: Conditional nesting too deep at ",
trim(filename),
":", line_num
187 name =
trim(adjustl(line(pos:)))
205 character(*),
intent(in) :: line
206 character(*),
intent(in) :: filename
207 integer,
intent(in) :: line_num
208 type(
macro),
intent(in) :: macros(:)
209 character(*),
intent(in) :: token
211 character(:),
allocatable :: name
212 logical :: defined, parent_active
216 if (
verbose) print *,
"Error: Conditional nesting too deep at ",
trim(filename),
":", line_num
221 name =
trim(adjustl(line(pos:)))
240 character(*),
intent(in) :: line, filename
241 integer,
intent(in) :: line_num
242 type(
macro),
intent(in) :: macros(:)
243 character(*),
intent(in) :: token
245 character(:),
allocatable :: expr
246 logical :: result, parent_active
250 if (
verbose) print *,
"Error: #elif without matching #if at ",
trim(filename),
":", line_num
255 expr =
trim(adjustl(line(pos:)))
276 character(*),
intent(in) :: line
277 character(*),
intent(in) :: filename
278 integer,
intent(in) :: line_num
279 type(
macro),
intent(in) :: macros(:)
280 character(*),
intent(in) :: token
282 character(:),
allocatable :: name
283 logical :: defined, parent_active
287 if (
verbose) print *,
"Error: #elifdef without matching #if at ",
trim(filename),
":", line_num
292 name =
trim(adjustl(line(pos:)))
313 character(*),
intent(in) :: line
314 character(*),
intent(in) :: filename
315 integer,
intent(in) :: line_num
316 type(
macro),
intent(in) :: macros(:)
317 character(*),
intent(in) :: token
319 character(:),
allocatable :: name
320 logical :: defined, parent_active
324 if (
verbose) print *,
"Error: #elifndef without matching #if at ",
trim(filename),
":", line_num
329 name =
trim(adjustl(line(pos:)))
348 character(*),
intent(in) :: filename
349 integer,
intent(in) :: line_num
350 logical :: parent_active
353 if (
verbose) print *,
"Error: #else without matching #if at ",
trim(filename),
":", line_num
375 character(*),
intent(in) :: filename
376 integer,
intent(in) :: line_num
379 if (
verbose) print *,
"Error: #endif without matching #if at ",
trim(filename),
":", line_num
subroutine, public handle_elifndef(line, filename, line_num, macros, token)
Process elifndef – test if a macro is not defined.
logical function, public is_active()
Determine if current line is inside an active conditional block.
subroutine, public handle_endif(filename, line_num)
Process endif – end of conditional block Pops the top state from the stack. Reports error on unmatche...
subroutine, public handle_else(filename, line_num)
Process else – final fallback branch Activates only if no previous if/elif branch was true.
integer, public cond_depth
Current nesting depth of conditional directives (0 = outside any if)
subroutine, public handle_ifndef(line, filename, line_num, macros, token)
Process ifndef – test if a macro is NOT defined.
subroutine, public handle_ifdef(line, filename, line_num, macros, token)
Process ifdef – test if a macro is defined.
subroutine, public handle_if(line, filename, line_num, macros, token)
Process a if directive with constant expression evaluation Evaluates the expression after if using ev...
subroutine, public handle_elif(line, filename, line_num, macros, token)
Process elif – alternative branch after if/elif Only activates if no previous branch in the group was...
subroutine, public handle_elifdef(line, filename, line_num, macros, token)
Process elifdef – test if a macro is defined.
type(cond_state), dimension(max_cond_depth), public cond_stack
Global stack of conditional states (depth-limited)
integer, parameter, public max_cond_depth
Maximum nesting depth for conditional statements, set to 50 to prevent overly complex logic.
logical, public verbose
Master switch for verbose diagnostic output Default value is .false. (quiet mode)....
logical function, public is_defined(name, macros, idx)
Check if a macro with given name exists in table.
logical function, public evaluate_expression(expr, macros, val)
Evaluates a preprocessor-style expression with macro substitution. Tokenizes the input expression,...
pure character(len_trim(str)) function, public uppercase(str)
Convert string to upper case (respects contents of quotes).
Return the length of a string.
Return the trimmed string.
State of a single conditional block.
Derived type representing a single preprocessor macro Extends string with macro-specific fields: rep...