Source file fileString.ml
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
open EzCompat
let cut_extension file =
let basename = Filename.basename file in
let basename, extensions = EzString.cut_at basename '.' in
let extensions = String.lowercase extensions in
( basename, extensions )
let cut_extensions file =
let (basename, extensions) = cut_extension file in
let extensions = EzString.split extensions '.' in
( basename, extensions )
let is_absolute file = not (Filename.is_relative file)
let is_relative = Filename.is_relative
let is_implicit = Filename.is_implicit
let concat = Filename.concat
let add_path = Filename.concat
let add_basename = Filename.concat
let add_basenames = List.fold_left Filename.concat
let dirname = Filename.dirname
let basename = Filename.basename
let check_suffix = Filename.check_suffix
let add_suffix = (^)
let open_in = open_in
let open_in_bin = open_in_bin
let open_out = open_out
let open_out_bin = open_out_bin
let open_fd file mode perm = MinUnix.openfile file mode perm
let temp_file prefix suffix = Filename.temp_file prefix suffix
let current_dir_name = Filename.current_dir_name
let with_open open_channel close_channel filename f =
let ic = open_channel filename in
try
let x = f ic in
close_channel ic;
x
with exn ->
close_channel ic;
raise exn
let with_in filename f = with_open open_in close_in filename f
let with_in_bin filename f = with_open open_in_bin close_in filename f
let with_out = with_open open_out close_out
let with_out_bin = with_open open_out_bin close_out
let copy_file f1 f2 =
with_in_bin f1 (fun ic ->
with_out_bin f2 (fun oc ->
FileChannel.copy_file ic oc))
let iter_blocks f filename =
with_in_bin filename (fun ic ->
FileChannel.iter_blocks f ic)
let write_file filename str =
with_out_bin filename (fun oc ->
output_string oc str)
let file_of_string = write_file
let read_file filename =
with_in_bin filename FileChannel.read_file
let string_of_file = read_file
let read_lines filename =
with_in filename FileChannel.read_lines
let read_lines_to_revlist filename =
with_in filename FileChannel.read_lines_to_revlist
let read_lines_to_list filename =
with_in filename FileChannel.read_lines_to_list
let write_lines filename lines =
with_out filename (fun oc -> FileChannel.write_lines oc lines)
let write_lines_of_list filename lines =
with_out filename (fun oc -> FileChannel.write_lines_of_list oc lines)
let lines_of_file = read_lines
let file_of_lines = write_lines
let iter_lines f filename =
with_in filename (fun ic ->
FileChannel.iter_lines f ic)
let iteri_lines f filename =
with_in filename (fun ic ->
FileChannel.iteri_lines f ic)
let read_sublines filename off len =
with_in filename (fun ic ->
FileChannel.read_sublines ic off len)
let read_sublines_to_list filename off len =
with_in filename (fun ic ->
FileChannel.read_sublines_to_list ic off len)
let read_subfile filename pos len =
with_in filename (fun ic ->
FileChannel.read_subfile ic pos len)
let string_of_subfile = read_subfile
let is_directory = Sys.is_directory
let is_link filename =
try let s = MinUnix.lstat filename in
s.MinUnix.st_kind = MinUnix.S_LNK with _ -> false
let rename = Sys.rename
let remove = Sys.remove
let getcwd = Sys.getcwd
let exists = Sys.file_exists
let stat filename = MinUnix.stat filename
let lstat filename = MinUnix.lstat filename
let to_string s = s
let size filename =
let s = MinUnix.stat filename in
s.MinUnix.st_size
module OP = struct
let (//) = Filename.concat
end
module Directory_operations = FileDirMaker.Make(struct
type path = string
let add_basename = add_basename
let dirname = dirname
let basename = basename
let rmdir = MinUnix.rmdir
let lstat = MinUnix.lstat
let stat = MinUnix.stat
let mkdir = MinUnix.mkdir
let remove = Sys.remove
let readdir = Sys.readdir
let to_string = to_string
end)
include Directory_operations
let rec copy_rec src dst =
match (MinUnix.stat src).MinUnix.st_kind with
| MinUnix.S_DIR ->
make_dir ~p:true dst;
iter_dir ~f:(fun file ->
copy_rec (Filename.concat src file)
(Filename.concat dst file)) src
| MinUnix.S_REG ->
copy_file src dst
| _ ->
failwith (Printf.sprintf
"File.copy_rec: cannot copy unknown kind file %S"
src)
let rec uncopy_rec src dst =
match
(try Some (MinUnix.stat src).MinUnix.st_kind with _ -> None),
(try Some (MinUnix.stat dst).MinUnix.st_kind with _ -> None)
with
| _, None -> ()
| Some MinUnix.S_DIR, Some MinUnix.S_DIR ->
iter_dir ~f:(fun file ->
uncopy_rec (Filename.concat src file)
(Filename.concat dst file)) src;
(try MinUnix.rmdir dst with _ -> ())
| Some MinUnix.S_REG, Some MinUnix.S_REG ->
Sys.remove dst
| _ ->
failwith (Printf.sprintf
"File.uncopy_rec: inconsistent kinds between %S and %S"
src dst)
let find_in_path path name =
if not (Filename.is_implicit name) then
if Sys.file_exists name then name else raise Not_found
else begin
let rec try_dir = function
[] -> raise Not_found
| dir::rem ->
let fullname = Filename.concat dir name in
if Sys.file_exists fullname then fullname else try_dir rem
in try_dir path
end