1
1
module fpm_filesystem
2
+ use ,intrinsic :: iso_fortran_env, only : stdin= >input_unit, stdout= >output_unit, stderr= >error_unit
2
3
use fpm_environment, only: get_os_type, &
3
4
OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_WINDOWS, &
4
5
OS_CYGWIN, OS_SOLARIS, OS_FREEBSD
@@ -7,6 +8,7 @@ module fpm_filesystem
7
8
private
8
9
public :: basename, canon_path, dirname, is_dir, join_path, number_of_rows, read_lines, list_files, env_variable, &
9
10
mkdir, exists, get_temp_filename, windows_path, unix_path, getline, delete_file, to_fortran_name
11
+ public :: fileopen, fileclose, filewrite, warnwrite
10
12
11
13
integer , parameter :: LINE_BUFFER_LEN = 1000
12
14
@@ -73,7 +75,7 @@ function canon_path(path) result(canon)
73
75
! Canonicalize path for comparison
74
76
! Handles path string redundancies
75
77
! Does not test existence of path
76
- !
78
+ !
77
79
! To be replaced by realpath/_fullname in stdlib_os
78
80
!
79
81
character (* ), intent (in ) :: path
@@ -127,7 +129,7 @@ function canon_path(path) result(canon)
127
129
end if
128
130
129
131
end if
130
-
132
+
131
133
132
134
temp(j:j) = nixpath(i:i)
133
135
j = j + 1
@@ -145,30 +147,28 @@ function dirname(path) result (dir)
145
147
character (* ), intent (in ) :: path
146
148
character (:), allocatable :: dir
147
149
148
- character (:), allocatable :: file_parts(:)
149
-
150
150
dir = path(1 :scan (path,' /\' ,back= .true. ))
151
151
152
152
end function dirname
153
153
154
154
155
- logical function is_dir (dir )
156
- character (* ), intent (in ) :: dir
157
- integer :: stat
155
+ logical function is_dir (dir )
156
+ character (* ), intent (in ) :: dir
157
+ integer :: stat
158
158
159
- select case (get_os_type())
159
+ select case (get_os_type())
160
160
161
161
case (OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_CYGWIN, OS_SOLARIS, OS_FREEBSD)
162
- call execute_command_line(" test -d " // dir , exitstat= stat)
162
+ call execute_command_line(" test -d " // dir , exitstat= stat)
163
163
164
- case (OS_WINDOWS)
165
- call execute_command_line(' cmd /c "if not exist ' // windows_path(dir) // ' \ exit /B 1"' , exitstat= stat)
164
+ case (OS_WINDOWS)
165
+ call execute_command_line(' cmd /c "if not exist ' // windows_path(dir) // ' \ exit /B 1"' , exitstat= stat)
166
166
167
- end select
167
+ end select
168
168
169
- is_dir = (stat == 0 )
169
+ is_dir = (stat == 0 )
170
170
171
- end function is_dir
171
+ end function is_dir
172
172
173
173
174
174
function join_path (a1 ,a2 ,a3 ,a4 ,a5 ) result(path)
@@ -315,7 +315,7 @@ recursive subroutine list_files(dir, files, recurse)
315
315
do i= 1 ,size (files)
316
316
if (is_dir(files(i)% s)) then
317
317
318
- call list_files(files(i)% s, dir_files, recurse= .true. )
318
+ call list_files(files(i)% s, dir_files, recurse= .true. )
319
319
sub_dir_files = [sub_dir_files, dir_files]
320
320
321
321
end if
@@ -347,7 +347,7 @@ function get_temp_filename() result(tempfile)
347
347
348
348
type (c_ptr) :: c_tempfile_ptr
349
349
character (len= 1 ), pointer :: c_tempfile(:)
350
-
350
+
351
351
interface
352
352
353
353
function c_tempnam (dir ,pfx ) result(tmp) bind(c,name= " tempnam" )
@@ -389,7 +389,7 @@ function windows_path(path) result(winpath)
389
389
winpath(idx:idx) = ' \'
390
390
idx = index (winpath,' /' )
391
391
end do
392
-
392
+
393
393
end function windows_path
394
394
395
395
@@ -408,7 +408,7 @@ function unix_path(path) result(nixpath)
408
408
nixpath(idx:idx) = ' /'
409
409
idx = index (nixpath,' \' )
410
410
end do
411
-
411
+
412
412
end function unix_path
413
413
414
414
@@ -464,6 +464,101 @@ subroutine delete_file(file)
464
464
end if
465
465
end subroutine delete_file
466
466
467
+ subroutine warnwrite (fname ,data )
468
+ ! > write trimmed character data to a file if it does not exist
469
+ character (len=* ),intent (in ) :: fname
470
+ character (len=* ),intent (in ) :: data (:)
471
+
472
+ if (.not. exists(fname))then
473
+ call filewrite(fname,data )
474
+ else
475
+ write (stderr,' (*(g0,1x))' )' <INFO> ' ,fname,&
476
+ & ' already exists. Not overwriting'
477
+ endif
478
+
479
+ end subroutine warnwrite
480
+
481
+ subroutine fileopen (filename ,lun ,ier )
482
+ ! procedure to open filename as a sequential "text" file
483
+
484
+ character (len=* ),intent (in ) :: filename
485
+ integer ,intent (out ) :: lun
486
+ integer ,intent (out ),optional :: ier
487
+ integer :: ios
488
+ character (len= 256 ) :: message
489
+
490
+ message= ' '
491
+ ios= 0
492
+ if (filename.ne. ' ' )then
493
+ open (file= filename, &
494
+ & newunit= lun, &
495
+ & form= ' formatted' , & ! FORM = FORMATTED | UNFORMATTED
496
+ & access= ' sequential' , & ! ACCESS = SEQUENTIAL| DIRECT | STREAM
497
+ & action= ' write' , & ! ACTION = READ|WRITE| READWRITE
498
+ & position= ' rewind' , & ! POSITION= ASIS | REWIND | APPEND
499
+ & status= ' new' , & ! STATUS = NEW| REPLACE| OLD| SCRATCH| UNKNOWN
500
+ & iostat= ios, &
501
+ & iomsg= message)
502
+ else
503
+ lun= stdout
504
+ ios= 0
505
+ endif
506
+ if (ios.ne. 0 )then
507
+ write (stderr,' (*(a:,1x))' )&
508
+ & ' <ERROR> *filewrite*:' ,filename,trim (message)
509
+ lun=- 1
510
+ if (present (ier))then
511
+ ier= ios
512
+ else
513
+ stop 1
514
+ endif
515
+ endif
516
+
517
+ end subroutine fileopen
518
+
519
+ subroutine fileclose (lun ,ier )
520
+ ! simple close of a LUN. On error show message and stop (by default)
521
+ integer ,intent (in ) :: lun
522
+ integer ,intent (out ),optional :: ier
523
+ character (len= 256 ) :: message
524
+ integer :: ios
525
+ if (lun.ne. - 1 )then
526
+ close (unit= lun,iostat= ios,iomsg= message)
527
+ if (ios.ne. 0 )then
528
+ write (stderr,' (*(a:,1x))' )' <ERROR> *filewrite*:' ,trim (message)
529
+ if (present (ier))then
530
+ ier= ios
531
+ else
532
+ stop 2
533
+ endif
534
+ endif
535
+ endif
536
+ end subroutine fileclose
537
+
538
+ subroutine filewrite (filename ,filedata )
539
+ ! procedure to write filedata to file filename
540
+
541
+ character (len=* ),intent (in ) :: filename
542
+ character (len=* ),intent (in ) :: filedata(:)
543
+ integer :: lun, i, ios
544
+ character (len= 256 ) :: message
545
+ call fileopen(filename,lun)
546
+ if (lun.ne. - 1 )then ! program currently stops on error on open, but might
547
+ ! want it to continue so -1 (unallowed LUN) indicates error
548
+ ! write file
549
+ do i= 1 ,size (filedata)
550
+ write (lun,' (a)' ,iostat= ios,iomsg= message)trim (filedata(i))
551
+ if (ios.ne. 0 )then
552
+ write (stderr,' (*(a:,1x))' )&
553
+ & ' <ERROR> *filewrite*:' ,filename,trim (message)
554
+ stop 4
555
+ endif
556
+ enddo
557
+ endif
558
+ ! close file
559
+ call fileclose(lun)
560
+
561
+ end subroutine filewrite
467
562
468
563
pure function to_fortran_name (string ) result(res)
469
564
! Returns string with special characters replaced with an underscore.
@@ -475,5 +570,4 @@ pure function to_fortran_name(string) result(res)
475
570
res = replace (string, SPECIAL_CHARACTERS, ' _' )
476
571
end function to_fortran_name
477
572
478
-
479
573
end module fpm_filesystem
0 commit comments