aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fpm/src/FPM_Filesystem.f9073
-rw-r--r--fpm/src/FPM_Strings.f9020
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