Skip to content

Commit 1bae477

Browse files
committed
parse non_intrinsic and intrinsic used modules
1 parent 2e1e486 commit 1bae477

File tree

1 file changed

+107
-54
lines changed

1 file changed

+107
-54
lines changed

src/fpm_source_parsing.f90

Lines changed: 107 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,7 @@ module fpm_source_parsing
2727
implicit none
2828

2929
private
30-
public :: parse_f_source, parse_c_source
31-
32-
character(15), parameter :: INTRINSIC_MODULE_NAMES(*) = &
33-
['iso_c_binding ', &
34-
'iso_fortran_env', &
35-
'ieee_arithmetic', &
36-
'ieee_exceptions', &
37-
'ieee_features ', &
38-
'omp_lib ']
30+
public :: parse_f_source, parse_c_source, parse_use_statement
3931

4032
contains
4133

@@ -77,7 +69,7 @@ function parse_f_source(f_filename,error) result(f_source)
7769
type(srcfile_t) :: f_source
7870
type(error_t), allocatable, intent(out) :: error
7971

80-
logical :: inside_module, inside_interface
72+
logical :: inside_module, inside_interface, using, intrinsic_module
8173
integer :: stat
8274
integer :: fh, n_use, n_include, n_mod, n_parent, i, j, ic, pass
8375
type(string_t), allocatable :: file_lines(:), file_lines_lower(:)
@@ -179,59 +171,24 @@ function parse_f_source(f_filename,error) result(f_source)
179171
end if
180172

181173
! Process 'USE' statements
182-
if (index(file_lines_lower(i)%s,'use ') == 1 .or. &
183-
index(file_lines_lower(i)%s,'use::') == 1) then
184-
185-
if (index(file_lines_lower(i)%s,'::') > 0) then
186-
187-
temp_string = split_n(file_lines_lower(i)%s,delims=':',n=2,stat=stat)
188-
if (stat /= 0) then
189-
call file_parse_error(error,f_filename, &
190-
'unable to find used module name',i, &
191-
file_lines_lower(i)%s,index(file_lines_lower(i)%s,'::'))
192-
return
193-
end if
174+
call parse_use_statement(f_filename,i,file_lines_lower(i)%s,using,intrinsic_module,mod_name,error)
175+
if (allocated(error)) return
194176

195-
mod_name = split_n(temp_string,delims=' ,',n=1,stat=stat)
196-
if (stat /= 0) then
197-
call file_parse_error(error,f_filename, &
198-
'unable to find used module name',i, &
199-
file_lines_lower(i)%s)
200-
return
201-
end if
177+
if (using) then
202178

203-
else
179+
! Not a valid module name?
180+
if (.not.is_fortran_name(mod_name)) cycle
204181

205-
mod_name = split_n(file_lines_lower(i)%s,n=2,delims=' ,',stat=stat)
206-
if (stat /= 0) then
207-
call file_parse_error(error,f_filename, &
208-
'unable to find used module name',i, &
209-
file_lines_lower(i)%s)
210-
return
211-
end if
212-
213-
end if
214-
215-
if (.not.is_fortran_name(mod_name)) then
216-
cycle
217-
end if
218-
219-
if (any([(index(mod_name,trim(INTRINSIC_MODULE_NAMES(j)))>0, &
220-
j=1,size(INTRINSIC_MODULE_NAMES))])) then
221-
cycle
222-
end if
182+
! Valid intrinsic module: not a dependency
183+
if (intrinsic_module) cycle
223184

224185
n_use = n_use + 1
225186

226-
if (pass == 2) then
227-
228-
f_source%modules_used(n_use)%s = mod_name
229-
230-
end if
187+
if (pass == 2) f_source%modules_used(n_use)%s = mod_name
231188

232189
cycle
233190

234-
end if
191+
endif
235192

236193
! Process 'INCLUDE' statements
237194
ic = index(file_lines_lower(i)%s,'include')
@@ -655,5 +612,101 @@ function parse_sequence(string,t1,t2,t3,t4) result(found)
655612

656613
end function parse_sequence
657614

615+
! Process 'USE' statements
616+
617+
! USE [, intrinsic] :: module_name [, only: only_list]
618+
! USE [, non_intrinsic] :: module_name [, only: only_list]
619+
subroutine parse_use_statement(f_filename,i,line,use_stmt,is_intrinsic,module_name,error)
620+
character(*), intent(in) :: f_filename,line
621+
integer, intent(in) :: i ! line number
622+
logical, intent(out) :: use_stmt,is_intrinsic
623+
character(:), allocatable, intent(out) :: module_name
624+
type(error_t), allocatable, intent(out) :: error
625+
626+
character(15), parameter :: INTRINSIC_NAMES(*) = &
627+
['iso_c_binding ', &
628+
'iso_fortran_env', &
629+
'ieee_arithmetic', &
630+
'ieee_exceptions', &
631+
'ieee_features ', &
632+
'omp_lib ']
633+
634+
character(len=:), allocatable :: lowercase,temp_string
635+
integer :: colons,intr,nonintr,j,stat
636+
logical :: has_intrinsic_name
637+
638+
use_stmt = .false.
639+
is_intrinsic = .false.
640+
if (len_trim(line)<=0) return
641+
642+
! Preprocess: lowercase, remove heading spaces
643+
lowercase = lower(trim(adjustl(line)))
644+
645+
! 'use' should be the first string in the adjustl line
646+
use_stmt = index(lowercase,'use')==1; if (.not.use_stmt) return
647+
colons = index(lowercase,'::')
648+
nonintr = 0
649+
intr = 0
650+
intrinsicness: if (colons>3) then
651+
652+
end if intrinsicness
653+
654+
! If declared intrinsic, check that it is true
655+
print *, 'colons=',colons
656+
print *, 'intr=',intr
657+
print *, 'nonintr=',nonintr
658+
659+
if (colons>3) then
660+
661+
! If there is an intrinsic/non-intrinsic spec
662+
nonintr = index(lowercase(1:colons-1),'non_intrinsic')
663+
if (nonintr==0) intr = index(lowercase(1:colons-1),'intrinsic')
664+
665+
666+
temp_string = split_n(lowercase,delims=':',n=2,stat=stat)
667+
if (stat /= 0) then
668+
call file_parse_error(error,f_filename, &
669+
'unable to find used module name',i, &
670+
lowercase,colons)
671+
return
672+
end if
673+
674+
module_name = split_n(temp_string,delims=' ,',n=1,stat=stat)
675+
if (stat /= 0) then
676+
call file_parse_error(error,f_filename, &
677+
'unable to find used module name',i, &
678+
lowercase)
679+
return
680+
end if
681+
682+
else
683+
684+
module_name = split_n(lowercase,n=2,delims=' ,',stat=stat)
685+
if (stat /= 0) then
686+
call file_parse_error(error,f_filename, &
687+
'unable to find used module name',i, &
688+
lowercase)
689+
return
690+
end if
691+
692+
end if
693+
694+
! If declared intrinsic, check that it is true
695+
has_intrinsic_name = any([(index(module_name,trim(INTRINSIC_NAMES(j)))>0, &
696+
j=1,size(INTRINSIC_NAMES))])
697+
if (intr>0 .and. .not.has_intrinsic_name) then
698+
call file_parse_error(error,f_filename, &
699+
'module is declared intrinsic but it is not ',i, &
700+
lowercase)
701+
return
702+
endif
703+
704+
! Should we treat this as an intrinsic module
705+
is_intrinsic = nonintr==0 .and. & ! not declared non-intrinsic
706+
(intr>0 .or. has_intrinsic_name)
707+
708+
end subroutine parse_use_statement
709+
710+
658711
end module fpm_source_parsing
659712

0 commit comments

Comments
 (0)