Loading...
Searching...
No Matches
Conditional

Definition

Full-featured conditional compilation (if / ifdef / else / endif) for the fpx preprocessor This module implements standard-conforming conditional compilation with support for:

  • #if with arbitrary constant expressions (using evaluate_expression)
  • #ifdef / #ifndef and #elifdef / #elifndef for testing macro existence
  • #elif chains (multiple alternative branches)
  • #else as final fallback
  • Proper nesting up to MAX_COND_DEPTH levels
  • Correct "first-match" semantics — once a branch is taken, later #elif/#else are skipped
  • Integration with macro expansion via is_defined() and expression evaluator

The state is maintained in a global stack (cond_stack) with cond_depth tracking nesting. The function is_active() is used throughout the preprocessor to decide whether a line should be emitted or skipped.

Examples

  1. Classic include guard pattern:
    #ifndef MY_HEADER_H
    #define MY_HEADER_H
    ! ... header content ...
    #endif
    ...
  2. Feature selection with if and elif:
    #if DEBUG >= 2
    print *, 'Extra verbose debugging enabled'
    #elif DEBUG == 1
    print *, 'Standard debugging'
    #else
    ! Silent mode
    #endif
    !..
  3. Cross-platform code selection:
    #ifdef _OPENMP
    use omp_lib
    #else
    integer, parameter :: omp_get_thread_num = 0
    #endif
    ...
  4. Complex expression in if (requires evaluate_expression support):
    #if defined(USE_MPI) && (MPI_VERSION >= 3)
    use mpi_f08
    #endif
    ...

Data Types

type  cond_state
 State of a single conditional block. More...

Variables

◆ cond_depth

integer, public cond_depth = 0

Current nesting depth of conditional directives (0 = outside any if).

Definition at line 103 of file conditional.f90.

◆ cond_stack

type(cond_state), dimension(max_cond_depth), public cond_stack

Global stack of conditional states (depth-limited).

Definition at line 99 of file conditional.f90.

Methods

◆ handle_elif()

subroutine, public handle_elif ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(in) macros,
character(*), intent(in) token )

Process elif – alternative branch after if/elif Only activates if no previous branch in the group was taken.

Parameters
[in]ctxContext source line containing the directive
[in]macrosCurrent macro table
[in]tokenUsually 'elif'

Remarks

Definition at line 232 of file conditional.f90.

◆ handle_elifdef()

subroutine, public handle_elifdef ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(in) macros,
character(*), intent(in) token )

Process elifdef – test if a macro is defined.

Parameters
[in]ctxContext source line containing the directive
[in]macrosCurrent macro table
[in]tokenUsually 'elifdef'

Remarks

Definition at line 269 of file conditional.f90.

◆ handle_elifndef()

subroutine, public handle_elifndef ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(in) macros,
character(*), intent(in) token )

Process elifndef – test if a macro is not defined.

Parameters
[in]ctxContext source line containing the directive
[in]macrosCurrent macro table
[in]tokenUsually 'elifndef'

Remarks

Definition at line 306 of file conditional.f90.

◆ handle_else()

subroutine, public handle_else ( type(context), intent(in) ctx)

Process else – final fallback branch Activates only if no previous if/elif branch was true.

Parameters
[in]ctxContext (for error messages)

Remarks

Definition at line 342 of file conditional.f90.

◆ handle_endif()

subroutine, public handle_endif ( type(context), intent(in) ctx)

Process endif – end of conditional block Pops the top state from the stack. Reports error on unmatched endif.

Parameters
[in]ctxContext (for error messages)

Remarks

Definition at line 371 of file conditional.f90.

◆ handle_if()

subroutine, public handle_if ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(in) macros,
character(*), intent(in) token )

Process a if directive with constant expression evaluation Evaluates the expression after if using evaluate_expression() and pushes a new state onto the conditional stack.

Parameters
[in]ctxContext source line containing the directive
[in]macrosCurrent macro table
[in]tokenUsually 'if'

Remarks

Definition at line 132 of file conditional.f90.

◆ handle_ifdef()

subroutine, public handle_ifdef ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(in) macros,
character(*), intent(in) token )

Process ifdef – test if a macro is defined.

Parameters
[in]ctxContext source line containing the directive
[in]macrosCurrent macro table
[in]tokenUsually 'ifdef'

Remarks

Definition at line 165 of file conditional.f90.

◆ handle_ifndef()

subroutine, public handle_ifndef ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(in) macros,
character(*), intent(in) token )

Process ifndef – test if a macro is NOT defined.

Parameters
[in]ctxContext source line containing the directive
[in]macrosCurrent macro table
[in]tokenUsually 'ifndef'

Remarks

Definition at line 198 of file conditional.f90.

◆ is_active()

logical function, public is_active

Determine if current line is inside an active conditional block.

Returns
.true. if all enclosing if/elif/else branches are active

Remarks

Definition at line 112 of file conditional.f90.