@@ -5,7 +5,7 @@ module fpm_filesystem
5
5
use fpm_strings, only: f_string, string_t, split
6
6
implicit none
7
7
private
8
- public :: basename, dirname, is_dir, join_path, number_of_rows, read_lines, list_files,&
8
+ public :: basename, canon_path, dirname, is_dir, join_path, number_of_rows, read_lines, list_files,&
9
9
mkdir, exists, get_temp_filename, windows_path
10
10
11
11
integer , parameter :: LINE_BUFFER_LEN = 1000
@@ -40,6 +40,76 @@ function basename(path,suffix) result (base)
40
40
end function basename
41
41
42
42
43
+ function canon_path (path ) result(canon)
44
+ ! Canonicalize path for comparison
45
+ ! Handles path string redundancies
46
+ ! Does not test existence of path
47
+ !
48
+ ! To be replaced by realpath/_fullname in stdlib_os
49
+ !
50
+ character (* ), intent (in ) :: path
51
+ character (:), allocatable :: canon
52
+
53
+ integer :: i, j
54
+ integer :: iback
55
+ character (len (path)) :: nixpath
56
+ character (len (path)) :: temp
57
+
58
+ nixpath = unix_path(path)
59
+
60
+ j = 1
61
+ do i= 1 ,len (nixpath)
62
+
63
+ ! Skip back to last directory for '/../'
64
+ if (i > 4 ) then
65
+
66
+ if (nixpath(i-3 :i) == ' /../' ) then
67
+
68
+ iback = scan (nixpath(1 :i-4 ),' /' ,back= .true. )
69
+ if (iback > 0 ) then
70
+ j = iback + 1
71
+ cycle
72
+ end if
73
+
74
+ end if
75
+
76
+ end if
77
+
78
+ if (i > 1 .and. j > 1 ) then
79
+
80
+ ! Ignore current directory reference
81
+ if (nixpath(i-1 :i) == ' ./' ) then
82
+
83
+ j = j - 1
84
+ cycle
85
+
86
+ end if
87
+
88
+ ! Ignore repeated separators
89
+ if (nixpath(i-1 :i) == ' //' ) then
90
+
91
+ cycle
92
+
93
+ end if
94
+
95
+ ! Do NOT include trailing slash
96
+ if (i == len (nixpath) .and. nixpath(i:i) == ' /' ) then
97
+ cycle
98
+ end if
99
+
100
+ end if
101
+
102
+
103
+ temp(j:j) = nixpath(i:i)
104
+ j = j + 1
105
+
106
+ end do
107
+
108
+ canon = temp(1 :j-1 )
109
+
110
+ end function canon_path
111
+
112
+
43
113
function dirname (path ) result (dir)
44
114
! Extract dirname from path
45
115
!
@@ -287,4 +357,23 @@ function windows_path(path) result(winpath)
287
357
288
358
end function windows_path
289
359
360
+
361
+ function unix_path (path ) result(nixpath)
362
+ ! Replace file system separators for unix
363
+ !
364
+ character (* ), intent (in ) :: path
365
+ character (:), allocatable :: nixpath
366
+
367
+ integer :: idx
368
+
369
+ nixpath = path
370
+
371
+ idx = index (nixpath,' \' )
372
+ do while (idx > 0 )
373
+ nixpath(idx:idx) = ' /'
374
+ idx = index (nixpath,' \' )
375
+ end do
376
+
377
+ end function unix_path
378
+
290
379
end module fpm_filesystem
0 commit comments