58 implicit none;
private
78 type(
context),
intent(in) :: ctx
79 type(
macro),
allocatable,
intent(inout) :: macros(:)
80 character(*),
intent(in) :: token
82 character(:),
allocatable :: val, name, temp
83 integer :: pos, paren_start, paren_end, i, npar, imacro
86 temp =
trim(adjustl(ctx%content(pos + 1:)))
88 paren_start =
index(temp,
'(')
89 pos =
index(temp,
' ')
90 if (pos > 0 .and. pos < paren_start) paren_start = 0
92 if (paren_start > 0)
then
93 name =
trim(temp(:paren_start - 1))
95 if (
global%undef .contains. name)
return
96 paren_end =
index(temp,
')')
97 if (paren_end == 0)
then
99 message=
'Synthax error', &
100 label=
label_type(
'Missing closing parenthesis in macro definition',
len_trim(ctx%content) + 1, 1), &
102 trim(ctx%content), ctx%line))
105 val =
trim(adjustl(temp(paren_end + 1:)))
106 temp = temp(paren_start + 1:paren_end - 1)
110 if (temp(pos:pos) ==
',')
then
115 if (
len_trim(temp) > 0) npar = npar + 1
117 if (.not.
allocated(macros))
allocate(macros(0))
119 if (name ==
'defined')
then
121 message=
'Reserved macro name', &
122 label=
label_type(
'"defined" cannot be used as a macro name', paren_start + 1,
len(name)), &
124 trim(ctx%content), ctx%line))
127 if (.not.
is_defined(name, macros, imacro))
then
128 call add(macros, name, val)
131 macros(imacro) =
macro(name, val)
134 if (
index(temp,
'...') > 0)
then
135 macros(imacro)%is_variadic = .true.
137 if (
allocated(macros(imacro)%params))
deallocate(macros(imacro)%params)
138 allocate(macros(imacro)%params(npar))
141 do while (pos <=
len_trim(temp) .and. i <= npar)
142 do while (pos <=
len_trim(temp) .and. temp(pos:pos) ==
' ')
147 do while (pos <=
len_trim(temp) .and. temp(pos:pos) /=
',')
150 macros(imacro)%params(i) = temp(paren_start:pos - 1)
155 macros(imacro)%is_variadic = .false.
156 if (
allocated(macros(imacro)%params))
deallocate(macros(imacro)%params)
157 allocate(macros(imacro)%params(npar))
160 do while (pos <=
len_trim(temp) .and. i <= npar)
161 do while (pos <=
len_trim(temp) .and. temp(pos:pos) ==
' ')
166 do while (pos <=
len_trim(temp) .and. temp(pos:pos) /=
',' .and. temp(pos:pos) /=
' ')
170 macros(imacro)%params(i) = temp(paren_start:pos - 1)
173 if (temp(pos:pos) ==
',') pos = pos + 1
178 pos =
index(temp,
' ')
180 name =
trim(temp(:pos - 1))
181 val =
trim(adjustl(temp(pos + 1:)))
187 if (
global%undef .contains. name)
return
188 if (.not.
allocated(macros))
allocate(macros(0))
189 if (.not.
is_defined(name, macros, imacro))
then
190 call add(macros, name, val)
193 macros(imacro) =
macro(name, val)
208 type(
context),
intent(in) :: ctx
209 type(
macro),
allocatable,
intent(inout) :: macros(:)
210 character(*),
intent(in) :: token
212 type(
macro),
allocatable :: temp_macros(:)
213 character(:),
allocatable :: name
218 name =
trim(adjustl(ctx%content(pos:)))
220 if (macros(i) == name)
then
228 message=
'Unknown macro', &
subroutine, public handle_undef(ctx, macros, token)
Process a undef directive and remove a macro from the table Finds the named macro in the current tabl...
subroutine, public handle_define(ctx, macros, token)
Process a define directive and register or update a macro Parses the line after #define,...
type(global_settings), public global
The single global instance used throughout fpx Initialized automatically with sensible defaults value...
logical function, public is_defined(name, macros, idx)
Check if a macro with given name exists in table.
pure character(len_trim(str)) function, public lowercase(str)
Convert string to lower case (respects contents of quotes).
Interface to render diagnostic messages and labels.
Add one or more macros to a dynamic table.
Remove a macro at given index.
Return current number of stored macros.
Return the trimmed length of a string.
Return the length of a string.
Return the trimmed string.
Source location and content snapshot for precise diagnostics Instances of this type are created for e...
Definition of diagnostic message.
Represents text as a sequence of ASCII code units. The derived type wraps an allocatable character ar...
Derived type representing a single preprocessor macro Extends string with macro-specific fields: rep...