Loading...
Searching...
No Matches
diagnostics.f90
Go to the documentation of this file.
1!> @file
2!! @defgroup group_diagnostics Diagnostics
3!! Diagnostic directives for the fpx preprocessor.
4!!
5!! This module implements the handling of the preprocessor directives
6!! `#error` and `#warning`, allowing source files to emit user-defined
7!! diagnostics during preprocessing.
8!!
9!! These directives are commonly used to enforce configuration requirements,
10!! reject unsupported platforms, report deprecated features, or notify users
11!! about assumptions made during compilation.
12!!
13!! Supported directives:
14!!
15!! - `#error`
16!! Emits a fatal diagnostic and immediately terminates preprocessing.
17!!
18!! - `#warning`
19!! Emits a non-fatal diagnostic message while allowing preprocessing to
20!! continue normally.
21!!
22!! The diagnostic text consists of the remainder of the directive line
23!! following the keyword itself.
24!!
25!! @note
26!! The routines implemented in this module do not perform macro expansion on
27!! the diagnostic message. Any expansion must have been completed before the
28!! directive handler is invoked.
29!!
30!! @section diagnostics_examples Examples
31!!
32!! 1. Reject unsupported platforms:
33!! @code{.f90}
34!! #ifdef __VAX__
35!! #error "VAX systems are not supported."
36!! #endif
37!! ...
38!! @endcode
39!!
40!! 2. Enforce configuration requirements:
41!! @code{.f90}
42!! #ifndef MPI_VERSION
43!! #error "MPI support must be enabled."
44!! #endif
45!! ...
46!! @endcode
47!!
48!! 3. Warn about deprecated functionality:
49!! @code{.f90}
50!! #ifdef USE_LEGACY_SOLVER
51!! #warning "USE_LEGACY_SOLVER is deprecated and will be removed."
52!! #endif
53!! ...
54!! @endcode
55!!
56!! 4. Notify users of unusual configurations:
57!! @code{.f90}
58!! #if PRECISION > 64
59!! #warning "Using extended precision may affect performance."
60!! #endif
61!! ...
62!! @endcode
63!!
64!! 5. Emit custom informational messages:
65!! @code{.f90}
66!! #warning "Building experimental version."
67!! ...
68!! @endcode
69!!
70!! @see
71!! <a href="~/group__group__logging.html">logging</a> @n
72!! <a href="~/group__group__context.html">context</a>
73module fpx_diagnostics
74 use, intrinsic :: iso_fortran_env, only: stdout => output_unit
75 use fpx_logging
76 use fpx_macro
77 use fpx_global
78 use fpx_string
79 use fpx_context
80
81 implicit none; private
82
83 public :: handle_error, &
85
86contains
87
88 !> Process a `#error` directive.
89 !!
90 !! Extracts the message following the directive keyword and immediately
91 !! terminates preprocessing using an `error stop` statement.
92 !!
93 !! This directive is intended for unrecoverable situations such as
94 !! unsupported targets, invalid configurations, or missing prerequisites.
95 !!
96 !! @param[in] ctx
97 !! Source context containing the complete `#error` directive.
98 !! @param[inout] macros
99 !! Active macro table. Present for interface consistency and not modified.
100 !! @param[in] token
101 !! Directive keyword, typically `"error"`.
102 !!
103 !! @ingroup group_diagnostics
104 subroutine handle_error(ctx, macros, token)
105 type(context), intent(in) :: ctx
106 type(macro), allocatable, intent(inout) :: macros(:)
107 character(*), intent(in) :: token
108 !private
109 integer :: pos
110
111 pos = index(lowercase(ctx%content), token) + len(token)
112 error stop trim(adjustl(ctx%content(pos + 1:)))
113 end subroutine
114
115 !> Process a `#warning` directive.
116 !!
117 !! Extracts the message following the directive keyword and writes it to
118 !! the standard output stream without interrupting preprocessing.
119 !!
120 !! This directive is intended for non-fatal conditions such as deprecated
121 !! features, unusual build settings, or informational notices.
122 !!
123 !! @param[in] ctx
124 !! Source context containing the complete `#warning` directive.
125 !! @param[inout] macros
126 !! Active macro table. Present for interface consistency and not modified.
127 !! @param[in] token
128 !! Directive keyword, typically `"warning"`.
129 !!
130 !! @ingroup group_diagnostics
131 subroutine handle_warning(ctx, macros, token)
132 type(context), intent(in) :: ctx
133 type(macro), allocatable, intent(inout) :: macros(:)
134 character(*), intent(in) :: token
135 !private
136 integer :: pos
137
138 pos = index(lowercase(ctx%content), token) + len(token)
139 write(stdout, '(A)') trim(adjustl(ctx%content(pos + 1:)))
140 end subroutine
141end module
subroutine, public handle_error(ctx, macros, token)
Process a #error directive.
subroutine, public handle_warning(ctx, macros, token)
Process a #warning directive.
pure character(len_trim(str)) function, public lowercase(str)
Convert string to lower case (respects contents of quotes).
Definition string.f90:852
Locate the position of a substring.
Definition string.f90:395
Return the length of a string object.
Definition string.f90:164
Remove trailing blanks from a string object.
Definition string.f90:240
Snapshot of a source location within the preprocessing stream.
Definition context.f90:114
Representation of a preprocessor macro.
Definition macro.f90:135