@@ -27,15 +27,7 @@ module fpm_source_parsing
27
27
implicit none
28
28
29
29
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
39
31
40
32
contains
41
33
@@ -77,7 +69,7 @@ function parse_f_source(f_filename,error) result(f_source)
77
69
type (srcfile_t) :: f_source
78
70
type (error_t), allocatable , intent (out ) :: error
79
71
80
- logical :: inside_module, inside_interface
72
+ logical :: inside_module, inside_interface, using, intrinsic_module
81
73
integer :: stat
82
74
integer :: fh, n_use, n_include, n_mod, n_parent, i, j, ic, pass
83
75
type (string_t), allocatable :: file_lines(:), file_lines_lower(:)
@@ -179,59 +171,24 @@ function parse_f_source(f_filename,error) result(f_source)
179
171
end if
180
172
181
173
! 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
194
176
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
202
178
203
- else
179
+ ! Not a valid module name?
180
+ if (.not. is_fortran_name(mod_name)) cycle
204
181
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
223
184
224
185
n_use = n_use + 1
225
186
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
231
188
232
189
cycle
233
190
234
- end if
191
+ endif
235
192
236
193
! Process 'INCLUDE' statements
237
194
ic = index (file_lines_lower(i)% s,' include' )
@@ -655,5 +612,101 @@ function parse_sequence(string,t1,t2,t3,t4) result(found)
655
612
656
613
end function parse_sequence
657
614
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
+
658
711
end module fpm_source_parsing
659
712
0 commit comments