Source file opamCompat.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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
module String = struct
[@@@warning "-32"]
(** NOTE: OCaml >= 4.13 *)
let exists p s =
let n = String.length s in
let rec loop i =
if i = n then false
else if p (String.unsafe_get s i) then true
else loop (succ i) in
loop 0
(** NOTE: OCaml >= 4.13 *)
let starts_with ~prefix s =
let x = String.length prefix in
let n = String.length s in
n >= x &&
let rec chk i = i >= x || prefix.[i] = s.[i] && chk (i+1) in
chk 0
(** NOTE: OCaml >= 4.13 *)
let ends_with ~suffix s =
let x = String.length suffix in
let n = String.length s in
n >= x &&
let rec chk i = i >= x || suffix.[i] = s.[i+n-x] && chk (i+1) in
chk 0
(** NOTE: OCaml >= 4.13 *)
let for_all f s =
let len = String.length s in
let rec aux i = i >= len || f s.[i] && aux (i+1) in
aux 0
(** NOTE: OCaml >= 4.13 *)
let fold_left f acc s =
let acc = ref acc in
for i = 0 to String.length s - 1 do acc := f !acc s.[i] done;
!acc
include Stdlib.String
end
module Seq = struct
[@@@warning "-32"]
(** NOTE: OCaml >= 4.14 *)
let rec find_map f xs =
match xs() with
| Seq.Nil ->
None
| Seq.Cons (x, xs) ->
match f x with
| None ->
find_map f xs
| Some _ as result ->
result
include Seq
end
module Either = struct
(** NOTE: OCaml >= 4.12 *)
type ('a, 'b) t =
| Left of 'a
| Right of 'b
end
module Unix = struct
[@@@warning "-32"]
(** NOTE: OCaml >= 4.13 *)
let realpath s =
let getchdir s =
let p =
try Sys.getcwd ()
with Sys_error _ -> Filename.get_temp_dir_name ()
in
Unix.chdir s;
p
in
try getchdir (getchdir s) with Unix.Unix_error _ -> s
include Unix
end
module Lazy = struct
[@@@warning "-32"]
(** NOTE: OCaml >= 4.13 *)
let map f x =
lazy (f (Lazy.force x))
(** NOTE: OCaml >= 4.13 *)
let map_val f x =
if Lazy.is_val x
then Lazy.from_val (f (Lazy.force x))
else lazy (f (Lazy.force x))
include Stdlib.Lazy
end
module Filename = struct
[@@@warning "-32"]
let quote s =
let l = String.length s in
let b = Buffer.create (l + 20) in
Buffer.add_char b '\"';
let rec loop i =
if i = l then Buffer.add_char b '\"' else
match s.[i] with
| '\"' -> loop_bs 0 i;
| '\\' -> loop_bs 0 i;
| c -> Buffer.add_char b c; loop (i+1);
and loop_bs n i =
if i = l then begin
Buffer.add_char b '\"';
add_bs n;
end else begin
match s.[i] with
| '\"' -> add_bs (2*n+1); Buffer.add_char b '\"'; loop (i+1);
| '\\' -> loop_bs (n+1) (i+1);
| _ -> add_bs n; loop i
end
and add_bs n = for _j = 1 to n do Buffer.add_char b '\\'; done
in
loop 0;
Buffer.contents b
let quote_cmd s =
let b = Buffer.create (String.length s + 20) in
String.iter
(fun c ->
match c with
| '(' | ')' | '!' | '^' | '%' | '\"' | '<' | '>' | '&' | '|' ->
Buffer.add_char b '^'; Buffer.add_char b c
| _ ->
Buffer.add_char b c)
s;
Buffer.contents b
let quote_cmd_filename f =
if String.contains f '\"' || String.contains f '%' then
failwith ("Filename.quote_command: bad file name " ^ f)
else if String.contains f ' ' then
"\"" ^ f ^ "\""
else
f
(** NOTE: OCaml >= 4.10 *)
let quote_command cmd ?stdin ?stdout ?stderr args =
String.concat "" [
"\"";
quote_cmd_filename cmd;
" ";
quote_cmd (String.concat " " (List.map quote args));
(match stdin with None -> "" | Some f -> " <" ^ quote_cmd_filename f);
(match stdout with None -> "" | Some f -> " >" ^ quote_cmd_filename f);
(match stderr with None -> "" | Some f ->
if stderr = stdout
then " 2>&1"
else " 2>" ^ quote_cmd_filename f);
"\""
]
include Stdlib.Filename
end
module List = struct
[@@@warning "-32"]
(** NOTE: OCaml >= 4.11 *)
let fold_left_map f s l =
let s, l_rev =
List.fold_left (fun (s, l_rev) x ->
let s, y = f s x in
s, y :: l_rev)
(s, []) l
in
s, List.rev l_rev
let rec equal eq x y = match x, y with
| [], [] -> true
| [], _::_ | _::_, [] -> false
| x::_, y::_ when eq x y -> true
| _::xs, _::ys -> equal eq xs ys
include Stdlib.List
end
module type MAP = sig
include Stdlib.Map.S
(** NOTE: OCaml >= 4.11 *)
val filter_map: (key -> 'a -> 'b option) -> 'a t -> 'b t
end
module Map(Ord : Stdlib.Map.OrderedType) = struct
[@@@warning "-32"]
module M = Stdlib.Map.Make(Ord)
(** NOTE: OCaml >= 4.11 *)
let filter_map f map =
M.fold (fun key value map ->
match f key value with
| Some value -> M.add key value map
| None -> map
) map M.empty
include M
end
module Pair = struct
(** NOTE: OCaml >= 5.4 *)
let equal eq1 eq2 (x1, y1) (x2, y2) =
eq1 x1 x2 && eq2 y1 y2
end