-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathpathlib.F90
More file actions
145 lines (113 loc) · 3.32 KB
/
Copy pathpathlib.F90
File metadata and controls
145 lines (113 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
module pathlib
use, intrinsic:: iso_fortran_env, only: stderr=>error_unit
implicit none
private
public :: mkdir, copyfile, expanduser, home, realpath
interface
module function realpath(path)
character(*), intent(in) :: path
character(:), allocatable :: realpath
end function realpath
end interface
contains
integer function copyfile(source, dest) result(istat)
!! overwrites existing file in destination
character(*), intent(in) :: source, dest
character(len(source)) :: src
character(len(dest)) :: dst
logical :: exists
integer :: icstat
#if defined(_WIN32)
!! https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/copy
character(*), parameter :: CMD='copy /y '
src = filesep_swap(source)
dst = filesep_swap(dest)
#elif defined(__APPLE__)
!! https://ss64.com/osx/cp.html
character(*), parameter :: CMD='cp -rf '
src = source
dst = dest
#else
!! https://linux.die.net/man/1/cp
!! NOTE: some apple systems weren't defining __APPLE__ so keep this "cp -r "
character(*), parameter :: CMD='cp -rf '
src = source
dst = dest
#endif
call execute_command_line(CMD//src//' '//dst, exitstat=istat, cmdstat=icstat)
if (istat == 0 .and. icstat /= 0) istat = icstat
if (istat /= 0) write(stderr,*) 'ERROR: '//CMD//src//' '//dst
end function copyfile
integer function mkdir(path) result(istat)
!! create a directory, with parents if needed
character(*), intent(in) :: path
character(len(path)) :: p
integer :: icstat
#if defined(_WIN32)
!! https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/md
character(*), parameter :: CMD='mkdir '
p = filesep_swap(path)
#else
character(*), parameter :: CMD='mkdir -p '
p = path
#endif
call execute_command_line(CMD // p, exitstat=istat, cmdstat=icstat)
if (istat == 0 .and. icstat /= 0) istat = icstat
if (istat /= 0) write(stderr,*) 'ERROR: '//CMD//p
end function mkdir
function filesep_swap(path) result(swapped)
!! swaps '/' to '\' for Windows systems
character(*), intent(in) :: path
character(len(path)) :: swapped
integer :: i
swapped = path
do
i = index(swapped, '/')
if (i == 0) exit
swapped(i:i) = char(92)
end do
end function filesep_swap
function expanduser(indir)
!! resolve home directory as Fortran does not understand tilde
!! works for Linux, Mac, Windows, etc.
character(:), allocatable :: expanduser, homedir
character(*), intent(in) :: indir
if (len_trim(indir) < 1 .or. indir(1:1) /= '~') then
!! nothing to expand
expanduser = trim(adjustl(indir))
return
endif
homedir = home()
if (len_trim(homedir) == 0) then
!! could not determine the home directory
expanduser = trim(adjustl(indir))
return
endif
if (len_trim(indir) < 3) then
!! ~ or ~/
expanduser = homedir
else
!! ~/...
expanduser = homedir // trim(adjustl(indir(3:)))
endif
end function expanduser
function home()
!! https://en.wikipedia.org/wiki/Home_directory#Default_home_directory_per_operating_system
character(:), allocatable :: home, var
character(256) :: buf
integer :: L, istat
#if defined(_WIN32)
var = "USERPROFILE"
#else
var = "HOME"
#endif
call get_environment_variable(var, buf, length=L, status=istat)
if (L==0 .or. istat /= 0) then
write(stderr,*) 'ERROR: could not determine home directory from env var ',var
if (istat==1) write(stderr,*) 'env var ',var,' does not exist.'
home = ""
else
home = trim(buf) // '/'
endif
end function home
end module pathlib