diff options
-rw-r--r-- | fpm/src/FPM_Filesystem.f90 | 2 | ||||
-rw-r--r-- | fpm/src/FPM_Sourcefiles.f90 | 141 |
2 files changed, 87 insertions, 56 deletions
diff --git a/fpm/src/FPM_Filesystem.f90 b/fpm/src/FPM_Filesystem.f90 index a20c7ab..cc0487d 100644 --- a/fpm/src/FPM_Filesystem.f90 +++ b/fpm/src/FPM_Filesystem.f90 @@ -18,7 +18,7 @@ integer function number_of_rows(s) result(nrows) rewind(s) nrows = 0 do - read(s, *, iostat=ios) r + read(s, '(A)', iostat=ios) r if (ios /= 0) exit nrows = nrows + 1 end do diff --git a/fpm/src/FPM_Sourcefiles.f90 b/fpm/src/FPM_Sourcefiles.f90 index 63067c9..78230d4 100644 --- a/fpm/src/FPM_Sourcefiles.f90 +++ b/fpm/src/FPM_Sourcefiles.f90 @@ -5,7 +5,7 @@ implicit none private public srcfile_ptr, srcfile_t -public scan_f_sources +public scan_sources integer, parameter, public :: FPM_UNIT_UNKNOWN = -1 integer, parameter, public :: FPM_UNIT_PROGRAM = 1 @@ -47,42 +47,44 @@ end type srcfile_t contains -subroutine scan_f_sources(file_names,f_sources) +subroutine scan_sources(file_names,sources) ! Enumerate Fortran sources and resolve file ! dependencies ! type(string_t), intent(in) :: file_names(:) - type(srcfile_t), allocatable, intent(out), target :: f_sources(:) + type(srcfile_t), allocatable, intent(out), target :: sources(:) integer :: i, j - logical :: is_f_source(size(file_names)) - type(string_t), allocatable :: f_file_names(:) + logical :: is_source(size(file_names)) + type(string_t), allocatable :: src_file_names(:) - is_f_source = [(str_ends_with(lower(file_names(i)%s), ".f90"),i=1,size(file_names))] - f_file_names = pack(file_names,is_f_source) + is_source = [(str_ends_with(lower(file_names(i)%s), ".f90"),i=1,size(file_names))] + src_file_names = pack(file_names,is_source) - allocate(f_sources(size(f_file_names))) + allocate(sources(size(src_file_names))) - do i = 1, size(f_file_names) + do i = 1, size(src_file_names) - f_sources(i) = parse_f_source(f_file_names(i)%s) + if (str_ends_with(lower(file_names(i)%s), ".f90")) then + sources(i) = parse_f_source(src_file_names(i)%s) + end if end do - do i=1,size(f_sources) - write(*,*) 'Filename: "',f_sources(i)%file_name,'"' - write(*,*) ' Module name: "',f_sources(i)%unit_name,'"' - do j=1,size(f_sources(i)%module_dependencies) - write(*,*) ' Uses: "',f_sources(i)%module_dependencies(j)%s,'"' + do i=1,size(sources) + write(*,*) 'Filename: "',sources(i)%file_name,'"' + write(*,*) ' Module name: "',sources(i)%unit_name,'"' + do j=1,size(sources(i)%module_dependencies) + write(*,*) ' Uses: "',sources(i)%module_dependencies(j)%s,'"' end do - do j=1,size(f_sources(i)%include_dependencies) - write(*,*) ' Includes: "',f_sources(i)%include_dependencies(j)%s,'"' + do j=1,size(sources(i)%include_dependencies) + write(*,*) ' Includes: "',sources(i)%include_dependencies(j)%s,'"' end do end do - call resolve_f_dependencies(f_sources) + call resolve_dependencies(sources) -end subroutine scan_f_sources +end subroutine scan_sources function parse_f_source(f_filename) result(f_source) @@ -92,7 +94,7 @@ function parse_f_source(f_filename) result(f_source) character(*), intent(in) :: f_filename type(srcfile_t) :: f_source - integer :: fh, n_use, n_include, i, j, pass + integer :: fh, n_use, n_include, i, j, ic, pass type(string_t), allocatable :: file_lines(:) character(:), allocatable :: line_parts(:) character(:), allocatable :: temp_string, use_module_name @@ -108,8 +110,21 @@ function parse_f_source(f_filename) result(f_source) n_include = 0 file_loop: do i=1,size(file_lines) + ! Skip lines that are continued: not statements + if (i > 1) then + ic = index(file_lines(i-1)%s,'!') + if (ic < 1) then + ic = len(file_lines(i-1)%s) + end if + temp_string = trim(file_lines(i-1)%s(1:ic)) + if (len(temp_string) > 0 .and. index(temp_string,'&') == len(temp_string)) then + cycle + end if + end if + ! Process 'USE' statements - if (index(adjustl(lower(file_lines(i)%s)),'use') == 1) then + if (index(adjustl(lower(file_lines(i)%s)),'use ') == 1 .or. & + index(adjustl(lower(file_lines(i)%s)),'use::') == 1) then if (index(file_lines(i)%s,'::') > 0) then @@ -125,6 +140,10 @@ function parse_f_source(f_filename) result(f_source) end if + if (.not.validate_name(use_module_name)) then + cycle + end if + if (any([(index(use_module_name,trim(INTRINSIC_MODULE_NAMES(j)))>0, & j=1,size(INTRINSIC_MODULE_NAMES))])) then cycle @@ -206,57 +225,69 @@ function parse_f_source(f_filename) result(f_source) end do -end function parse_f_source + contains + function validate_name(name) result(valid) + character(*), intent(in) :: name + logical :: valid -subroutine resolve_f_dependencies(f_sources) - ! After enumerating all source files: resolve file dependencies - ! by searching on module names & include files - ! - type(srcfile_t), intent(inout), target :: f_sources(:) + integer :: i - integer :: n_use, n_include, n_depend - integer :: i, j, k + if (lower(name(1:1)) < 'a' .or. & + lower(name(1:1)) > 'z') then - do i=1,size(f_sources) - - n_use = size(f_sources(i)%module_dependencies) - n_include = size(f_sources(i)%include_dependencies) - n_depend = n_use + n_include + valid = .false. + return + end if - allocate(f_sources(i)%file_dependencies(n_depend)) + do i=1,len(name) - do j=1,n_use + if (.not.( & + (name(i:i) >= '0' .and. name(i:i) <= '9').or. & + (lower(name(i:i)) >= 'a' .and. lower(name(i:i)) <= 'z').or. & + name(i:i) == '_') ) then + + valid = .false. + return + end if - do k=1,size(f_sources) + end do - if (f_sources(i)%module_dependencies(j)%s == f_sources(k)%unit_name) then - f_sources(i)%file_dependencies(j)%ptr => f_sources(k) - exit - end if - - end do + valid = .true. + return - if (.not.associated(f_sources(i)%file_dependencies(j)%ptr)) then - write(*,*) '(!) Unable to find source for module dependency: ',f_sources(i)%module_dependencies(j)%s - stop - end if + end function validate_name - end do +end function parse_f_source + + +subroutine resolve_dependencies(sources) + ! After enumerating all source files: resolve file dependencies + ! by searching on module names + ! + type(srcfile_t), intent(inout), target :: sources(:) + + integer :: n_depend, i, j, k + + do i=1,size(sources) + + n_depend = size(sources(i)%module_dependencies) + + allocate(sources(i)%file_dependencies(n_depend)) - do j=1,n_include + do j=1,n_depend - do k=1,size(f_sources) + do k=1,size(sources) - if (index(f_sources(k)%file_name,f_sources(i)%include_dependencies(j)%s) > 0) then - f_sources(i)%file_dependencies(n_use+j)%ptr => f_sources(k) + if (sources(i)%module_dependencies(j)%s == sources(k)%unit_name) then + sources(i)%file_dependencies(j)%ptr => sources(k) exit end if end do - if (.not.associated(f_sources(i)%file_dependencies(n_use+j)%ptr)) then - write(*,*) '(!) Unable to find source for include dependency: ',f_sources(i)%include_dependencies(j)%s + if (.not.associated(sources(i)%file_dependencies(j)%ptr)) then + write(*,*) '(!) Unable to find source for module dependency: ',sources(i)%module_dependencies(j)%s stop end if @@ -264,7 +295,7 @@ subroutine resolve_f_dependencies(f_sources) end do -end subroutine resolve_f_dependencies +end subroutine resolve_dependencies |