diff options
-rw-r--r-- | fpm/src/FPM_Filesystem.f90 | 73 | ||||
-rw-r--r-- | fpm/src/FPM_Strings.f90 | 20 |
2 files changed, 81 insertions, 12 deletions
diff --git a/fpm/src/FPM_Filesystem.f90 b/fpm/src/FPM_Filesystem.f90 index fe35066..6729632 100644 --- a/fpm/src/FPM_Filesystem.f90 +++ b/fpm/src/FPM_Filesystem.f90 @@ -4,13 +4,12 @@ use environment, only: get_os_type, OS_LINUX, OS_MACOS, OS_WINDOWS implicit none private -public :: number_of_rows, list_files, exists +public :: number_of_rows, read_lines, list_files, exists, get_temp_filename integer, parameter :: LINE_BUFFER_LEN = 1000 contains - integer function number_of_rows(s) result(nrows) ! determine number or rows integer,intent(in)::s @@ -26,20 +25,19 @@ integer function number_of_rows(s) result(nrows) rewind(s) end function -function read_lines(filename) result(lines) - character(*), intent(in) :: filename + +function read_lines(fh) result(lines) + integer, intent(in) :: fh type(string_t), allocatable :: lines(:) - integer :: fh, i + integer :: i character(LINE_BUFFER_LEN) :: line_buffer - open(newunit=fh, file=filename, status="old") allocate(lines(number_of_rows(fh))) do i = 1, size(lines) read(fh, *) line_buffer lines(i)%s = trim(line_buffer) end do - close(fh) end function read_lines @@ -47,30 +45,81 @@ end function read_lines subroutine list_files(dir, files) character(len=*), intent(in) :: dir type(string_t), allocatable, intent(out) :: files(:) - integer :: stat + + integer :: stat, fh + character(:), allocatable :: temp_file + ! Using `inquire` / exists on directories works with gfortran, but not ifort if (.not. exists(dir)) then allocate(files(0)) return end if + + allocate(temp_file, source = get_temp_filename() ) + select case (get_os_type()) case (OS_LINUX) - call execute_command_line("ls " // dir // " > fpm_ls.out", exitstat=stat) + call execute_command_line("ls " // dir // " > "//temp_file, exitstat=stat) case (OS_MACOS) - call execute_command_line("ls " // dir // " > fpm_ls.out", exitstat=stat) + call execute_command_line("ls " // dir // " > "//temp_file, exitstat=stat) case (OS_WINDOWS) - call execute_command_line("dir /b " // dir // " > fpm_ls.out", exitstat=stat) + call execute_command_line("dir /b " // dir // " > "//temp_file, exitstat=stat) end select if (stat /= 0) then print *, "execute_command_line() failed" error stop end if - files = read_lines("fpm_ls.out") + + open(newunit=fh, file=temp_file, status="old") + files = read_lines(fh) + close(fh,status="delete") + end subroutine + logical function exists(filename) result(r) character(len=*), intent(in) :: filename inquire(file=filename, exist=r) end function + +function get_temp_filename() result(tempfile) + ! Get a unused temporary filename + ! Calls posix 'tempnam' - not recommended, but + ! we have no security concerns for this application + ! and use here is temporary. + ! Works with MinGW + ! + use iso_c_binding, only: c_ptr, C_NULL_PTR, c_f_pointer + character(:), allocatable :: tempfile + + type(c_ptr) :: c_tempfile_ptr + character(len=1), pointer :: c_tempfile(:) + + interface + + function c_tempnam(dir,pfx) result(tmp) BIND(C,name="tempnam") + import + type(c_ptr), intent(in), value :: dir + type(c_ptr), intent(in), value :: pfx + type(c_ptr) :: tmp + end function c_tempnam + + subroutine c_free(ptr) BIND(C,name="free") + import + type(c_ptr), value :: ptr + end subroutine c_free + + end interface + + c_tempfile_ptr = c_tempnam(C_NULL_PTR, C_NULL_PTR) + call c_f_pointer(c_tempfile_ptr,c_tempfile,[LINE_BUFFER_LEN]) + + tempfile = f_string(c_tempfile) + + call c_free(c_tempfile_ptr) + +end function get_temp_filename + + end module FPM_Filesystem
\ No newline at end of file diff --git a/fpm/src/FPM_Strings.f90 b/fpm/src/FPM_Strings.f90 index 33ae0c4..9a8869d 100644 --- a/fpm/src/FPM_Strings.f90 +++ b/fpm/src/FPM_Strings.f90 @@ -19,5 +19,25 @@ logical function str_ends_with(s, e) result(r) end if end function +function f_string(c_string) + use iso_c_binding + character(len=1), intent(in) :: c_string(:) + character(:), allocatable :: f_string + + integer :: i, n + + i = 0 + do while(c_string(i+1) /= C_NULL_CHAR) + i = i + 1 + end do + n = i + + allocate(character(n) :: f_string) + do i=1,n + f_string(i:i) = c_string(i) + end do + + end function f_string + end module FPM_Strings
\ No newline at end of file |