77 character(*),
intent(in) :: line
78 type(
macro),
allocatable,
intent(inout) :: macros(:)
79 character(*),
intent(in) :: token
81 character(:),
allocatable :: val, name, temp
82 integer :: pos, paren_start, paren_end, i, npar, imacro
85 temp =
trim(adjustl(line(pos + 1:)))
87 paren_start = index(temp,
'(')
88 pos = index(temp,
' ')
89 if (pos > 0 .and. pos < paren_start) paren_start = 0
91 if (paren_start > 0)
then
92 name =
trim(temp(:paren_start - 1))
94 if (
global%undef .contains. name)
return
95 paren_end = index(temp,
')')
96 if (paren_end == 0)
then
97 if (
verbose) print *,
"Error: Unclosed parenthesis in macro definition: ",
trim(line)
100 val =
trim(adjustl(temp(paren_end + 1:)))
101 if (
verbose) print *,
"Raw value before allocation: ", val,
", length = ",
len(val)
103 temp = temp(paren_start + 1:paren_end - 1)
107 if (temp(pos:pos) ==
',')
then
112 if (
len_trim(temp) > 0) npar = npar + 1
114 if (.not.
allocated(macros))
allocate(macros(0))
116 if (name ==
'defined')
then
117 if (
verbose) print *,
'"defined" cannot be used a a macro name'
121 if (.not.
is_defined(name, macros, imacro))
then
122 call add(macros, name, val)
125 macros(imacro) =
macro(name, val)
128 if (index(temp,
'...') > 0)
then
129 macros(imacro)%is_variadic = .true.
131 if (
allocated(macros(imacro)%params))
deallocate(macros(imacro)%params)
132 allocate(macros(imacro)%params(npar))
135 do while (pos <=
len_trim(temp) .and. i <= npar)
136 do while (pos <=
len_trim(temp) .and. temp(pos:pos) ==
' ')
141 do while (pos <=
len_trim(temp) .and. temp(pos:pos) /=
',')
144 macros(imacro)%params(i) = temp(paren_start:pos - 1)
145 if (
verbose) print *,
"Param ", i,
": '", macros(imacro)%params(i), &
146 "', length = ",
len_trim(macros(imacro)%params(i))
150 if (
verbose) print *,
"Defined variadic macro: ",
trim(name), &
151 "(", (macros(imacro)%params(i) //
", ", i = 1, npar),
"...) = ",
trim(val)
153 macros(imacro)%is_variadic = .false.
154 if (
allocated(macros(imacro)%params))
deallocate(macros(imacro)%params)
155 allocate(macros(imacro)%params(npar))
158 do while (pos <=
len_trim(temp) .and. i <= npar)
159 do while (pos <=
len_trim(temp) .and. temp(pos:pos) ==
' ')
164 do while (pos <=
len_trim(temp) .and. temp(pos:pos) /=
',' .and. temp(pos:pos) /=
' ')
168 macros(imacro)%params(i) = temp(paren_start:pos - 1)
169 if (
verbose) print *,
"Param ", i,
": '",
trim(macros(imacro)%params(i)), &
170 "', length = ",
len_trim(macros(imacro)%params(i))
173 if (temp(pos:pos) ==
',') pos = pos + 1
176 if (
verbose) print *,
"Defined macro: ",
trim(name),
"(", (macros(imacro)%params(i) //
", ", i = 1, npar - 1), &
177 macros(imacro)%params(npar),
") = ",
trim(val)
180 pos = index(temp,
' ')
182 name =
trim(temp(:pos - 1))
183 val =
trim(adjustl(temp(pos + 1:)))
189 if (
global%undef .contains. name)
return
190 if (.not.
allocated(macros))
allocate(macros(0))
191 if (.not.
is_defined(name, macros, imacro))
then
192 call add(macros, name, val)
195 macros(imacro) =
macro(name, val)
subroutine, public handle_define(line, macros, token)
Process a define directive and register or update a macro Parses the line after #define,...
subroutine, public handle_undef(line, macros, token)
Process a undef directive and remove a macro from the table Finds the named macro in the current tabl...
logical function, public is_defined(name, macros, idx)
Check if a macro with given name exists in table.