@@ -7,8 +7,7 @@ module fpm_filesystem
7
7
OS_CYGWIN, OS_SOLARIS, OS_FREEBSD, OS_OPENBSD
8
8
use fpm_environment, only: separator, get_env
9
9
use fpm_strings, only: f_string, replace, string_t, split
10
- use iso_c_binding, only: c_int8_t, c_int16_t, c_int32_t, c_int64_t, c_int128_t, c_char, c_ptr, c_int, c_loc, c_long, c_short, &
11
- c_null_char, c_associated, c_f_pointer
10
+ use iso_c_binding, only: c_char, c_ptr, c_int, c_null_char, c_associated, c_f_pointer
12
11
implicit none
13
12
private
14
13
public :: basename, canon_path, dirname, is_dir, join_path, number_of_rows, read_lines, list_files, env_variable, &
@@ -18,124 +17,8 @@ module fpm_filesystem
18
17
19
18
integer , parameter :: LINE_BUFFER_LEN = 1000
20
19
21
- #if (defined(MINGW64))
22
- type, bind(c) :: stat_t
23
- integer (kind= c_int32_t) :: st_dev
24
- integer (kind= c_int16_t) :: st_ino
25
- integer (kind= c_int16_t) :: st_mode
26
- integer (kind= c_int16_t) :: st_nlink
27
-
28
- integer (kind= c_int16_t) :: st_uid
29
- integer (kind= c_int16_t) :: st_gid
30
-
31
- integer (kind= c_int32_t) :: st_rdev
32
- integer (kind= c_int32_t) :: st_size
33
-
34
- integer (kind= c_int64_t) :: st_atime
35
- integer (kind= c_int64_t) :: st_mtime
36
- integer (kind= c_int64_t) :: st_ctime
37
- end type
38
- #elif (defined(MINGW32))
39
- type, bind(c) :: stat_t
40
- integer (kind= c_int32_t) :: st_dev
41
- integer (kind= c_int16_t) :: st_ino
42
- integer (kind= c_int16_t) :: st_mode
43
- integer (kind= c_int16_t) :: st_nlink
44
-
45
- integer (kind= c_int16_t) :: st_uid
46
- integer (kind= c_int16_t) :: st_gid
47
-
48
- integer (kind= c_int32_t) :: st_rdev
49
- integer (kind= c_int32_t) :: st_size
50
-
51
- integer (kind= c_int32_t) :: st_atime
52
- integer (kind= c_int32_t) :: st_mtime
53
- integer (kind= c_int32_t) :: st_ctime
54
- end type
55
- #elif (defined(LINUX64))
56
- type, bind(c) :: stat_t
57
- integer (kind= c_int64_t) :: st_dev
58
- integer (kind= c_int64_t) :: st_ino
59
- integer (kind= c_int64_t) :: st_nlink
60
- integer (kind= c_int32_t) :: st_mode
61
-
62
- integer (kind= c_int32_t) :: st_uid
63
- integer (kind= c_int32_t) :: st_gid
64
- integer (kind= c_int32_t) :: pad0
65
-
66
- integer (kind= c_int64_t) :: st_rdev
67
- integer (kind= c_int64_t) :: st_size
68
- integer (kind= c_int64_t) :: st_blksize
69
- integer (kind= c_int64_t) :: st_blocks
70
-
71
- integer (kind= c_int128_t) :: st_atime
72
- integer (kind= c_int128_t) :: st_mtime
73
- integer (kind= c_int128_t) :: st_ctime
74
-
75
- integer (kind= c_int64_t) :: glibc_reserved4
76
- integer (kind= c_int64_t) :: glibc_reserved5
77
- integer (kind= c_int64_t) :: glibc_reserved6
78
- end type
79
- #elif (defined(LINUX32))
80
- type, bind(c) :: stat_t
81
- integer (kind= c_int64_t) :: st_dev
82
- integer (kind= c_int16_t) :: pad1
83
- integer (kind= c_int32_t) :: st_ino
84
- integer (kind= c_int32_t) :: st_mode
85
- integer (kind= c_int32_t) :: st_nlink
86
-
87
- integer (kind= c_int32_t) :: st_uid
88
- integer (kind= c_int32_t) :: st_gid
89
- integer (kind= c_int64_t) :: st_rdev
90
- integer (kind= c_int16_t) :: pad2
91
-
92
- integer (kind= c_int32_t) :: st_size
93
- integer (kind= c_int32_t) :: st_blksize
94
- integer (kind= c_int32_t) :: st_blocks
95
-
96
- integer (kind= c_int64_t) :: st_atime
97
- integer (kind= c_int64_t) :: st_mtime
98
- integer (kind= c_int64_t) :: st_ctime
99
-
100
- integer (kind= c_int32_t) :: glibc_reserved4
101
- integer (kind= c_int32_t) :: glibc_reserved5
102
- end type
103
- #endif
104
-
105
- #if (defined(MINGW64) || defined(MINGW32))
106
- type, bind(c) :: dirent
107
- integer (kind= c_long) :: d_ino
108
- integer (kind= c_short) :: d_reclen
109
- integer (kind= c_short) :: d_namlen
110
- character (len= 1 ,kind= c_char) :: d_name(260 )
111
- end type
112
- #elif (defined(LINUX64))
113
- type, bind(c) :: dirent
114
- integer (kind= c_int64_t) :: d_ino
115
- integer (kind= c_int64_t) :: d_off
116
- integer (kind= c_int16_t) :: d_reclen
117
- integer (kind= c_int8_t) :: d_type
118
- character (len= 1 ,kind= c_char) :: d_name(256 )
119
- end type
120
- #elif (defined(LINUX32))
121
- type, bind(c) :: dirent
122
- integer (kind= c_int32_t) :: d_ino
123
- integer (kind= c_int32_t) :: d_off
124
- integer (kind= c_int16_t) :: d_reclen
125
- integer (kind= c_int8_t) :: d_type
126
- character (len= 1 ,kind= c_char) :: d_name(256 )
127
- end type
128
- #endif
129
-
130
- #if (defined(MINGW64) || defined(MINGW32) || defined(LINUX64) || defined(LINUX32))
20
+ #ifdef ENABLE_C_WRAPPER
131
21
interface
132
- function c_stat (path , buf ) result(r) bind(c, name= " stat" )
133
- import c_char, c_ptr, c_int
134
- character (kind= c_char), intent (in ) :: path(* )
135
- type (c_ptr), value :: buf
136
- integer (kind= c_int) :: r
137
- end function c_stat
138
-
139
22
function c_opendir (dir ) result(r) bind(c, name= " opendir" )
140
23
import c_char, c_ptr
141
24
character (kind= c_char), intent (in ) :: dir(* )
@@ -153,6 +36,18 @@ function c_closedir(dir) result(r) bind(c, name="closedir")
153
36
type (c_ptr), intent (in ), value :: dir
154
37
integer (kind= c_int) :: r
155
38
end function c_closedir
39
+
40
+ function c_get_d_name (dir ) result(r) bind(c, name= " get_d_name" )
41
+ import c_ptr
42
+ type (c_ptr), intent (in ), value :: dir
43
+ type (c_ptr) :: r
44
+ end function c_get_d_name
45
+
46
+ function c_is_dir (path ) result(r) bind(c, name= " is_dir" )
47
+ import c_char, c_int
48
+ character (kind= c_char), intent (in ) :: path(* )
49
+ integer (kind= c_int) :: r
50
+ end function c_is_dir
156
51
end interface
157
52
#endif
158
53
@@ -450,31 +345,43 @@ subroutine mkdir(dir)
450
345
end if
451
346
end subroutine mkdir
452
347
453
-
454
- #if (defined(MINGW64) || defined(MINGW32) || defined(LINUX64) || defined(LINUX32))
348
+ #ifdef ENABLE_C_WRAPPER
455
349
! > Get file & directory names in directory `dir` using iso_c_binding.
456
350
! !
457
351
! ! - File/directory names return are relative to cwd, ie. preprended with `dir`
458
352
! ! - Includes files starting with `.` except current directory and parent directory
459
353
! !
460
- recursive subroutine list_files (dir , files , recurse )
354
+ recursive subroutine list_files (dir , files , recurse , separator )
461
355
character (len=* ), intent (in ) :: dir
462
356
type (string_t), allocatable , intent (out ) :: files(:)
463
357
logical , intent (in ), optional :: recurse
358
+ character (len= 1 ), optional :: separator
464
359
465
360
integer :: i
466
361
type (string_t), allocatable :: dir_files(:)
467
362
type (string_t), allocatable :: sub_dir_files(:)
468
363
469
364
type (c_ptr) :: dir_handle
470
365
type (c_ptr) :: dir_entry_c
471
- type (dirent ), pointer :: dir_entry_fortran
366
+ character (len = :,kind = c_char ), allocatable :: fortran_name
472
367
character (len= :), allocatable :: string_fortran
473
368
integer , parameter :: N_MAX = 256
474
369
type (string_t) :: files_tmp(N_MAX)
475
370
integer (kind= c_int) :: r
371
+ character (len= 1 ) :: filesep
372
+
373
+ if (present (separator)) then
374
+ filesep = separator
375
+ else
376
+ select case (get_os_type())
377
+ case default
378
+ filesep = ' /'
379
+ case (OS_WINDOWS)
380
+ filesep = ' \'
381
+ end select
382
+ end if
476
383
477
- if (.not. is_dir_c (dir(1 :len_trim (dir))// c_null_char)) then
384
+ if (c_is_dir (dir(1 :len_trim (dir))// c_null_char) .eq. 0 ) then
478
385
allocate (files(0 ))
479
386
return
480
387
end if
@@ -493,8 +400,7 @@ recursive subroutine list_files(dir, files, recurse)
493
400
if (.not. c_associated(dir_entry_c)) then
494
401
exit
495
402
else
496
- call c_f_pointer(dir_entry_c, dir_entry_fortran)
497
- string_fortran = f_string(dir_entry_fortran% d_name)
403
+ string_fortran = f_string(c_get_d_name(dir_entry_c))
498
404
499
405
if ((string_fortran .eq. ' .' .or. string_fortran .eq. ' ..' )) then
500
406
cycle
@@ -507,7 +413,7 @@ recursive subroutine list_files(dir, files, recurse)
507
413
i = 1
508
414
end if
509
415
510
- files_tmp(i)% s = join_path( dir, string_fortran)
416
+ files_tmp(i)% s = dir // filesep // string_fortran
511
417
end if
512
418
end do
513
419
@@ -528,8 +434,8 @@ recursive subroutine list_files(dir, files, recurse)
528
434
allocate (sub_dir_files(0 ))
529
435
530
436
do i= 1 ,size (files)
531
- if (is_dir_c (files(i)% s// c_null_char)) then
532
- call list_files(files(i)% s, dir_files, recurse= .true. )
437
+ if (c_is_dir (files(i)% s// c_null_char) .ne. 0 ) then
438
+ call list_files(files(i)% s, dir_files, recurse= .true. , separator = filesep )
533
439
sub_dir_files = [sub_dir_files, dir_files]
534
440
end if
535
441
end do
@@ -539,18 +445,6 @@ recursive subroutine list_files(dir, files, recurse)
539
445
end if
540
446
end subroutine list_files
541
447
542
- function is_dir_c (path ) result(r)
543
- character (kind= c_char), intent (in ) :: path(* )
544
- logical :: r
545
- type (stat_t), target :: buf
546
- integer (kind= c_int) :: exists
547
- integer (kind= c_int), parameter :: S_IFMT = 61440
548
- integer (kind= c_int), parameter :: S_IFDIR = 16384
549
-
550
- exists = c_stat(path, c_loc(buf))
551
- r = exists .eq. 0 .and. iand (int (buf% st_mode, kind= c_int), S_IFMT) .eq. S_IFDIR
552
- end function is_dir_c
553
-
554
448
#else
555
449
! > Get file & directory names in directory `dir`.
556
450
! !
@@ -616,8 +510,10 @@ recursive subroutine list_files(dir, files, recurse)
616
510
end if
617
511
618
512
end subroutine list_files
513
+
619
514
#endif
620
515
516
+
621
517
! > test if pathname already exists
622
518
logical function exists (filename ) result(r)
623
519
character (len=* ), intent (in ) :: filename
0 commit comments