1 type intel_mesa_quirks
= bool;;
9 type platform
= | Punknown
| Plinux
| Posx
| Psun
| Pbsd
| Pcygwin
;;
11 let tempfailureretry f
a =
13 try f
a with Unix.Unix_error
(Unix.EINTR
, _
, _
) -> g ()
17 external cloexec
: Unix.file_descr
-> unit = "ml_cloexec";;
18 external hasdata
: Unix.file_descr
-> bool = "ml_hasdata";;
19 external toutf8
: int -> string = "ml_keysymtoutf8";;
20 external mbtoutf8
: string -> string = "ml_mbtoutf8";;
21 external spawn
: string -> (Unix.file_descr
* int) list
-> int = "ml_spawn";;
22 external platform
: unit -> (platform
* string array
) = "ml_platform";;
24 let now = Unix.gettimeofday
;;
25 let platform, uname
= platform ();;
26 let dolog fmt
= Format.ksprintf prerr_endline fmt
;;
29 | Unix.Unix_error
(e
, s, a) -> Printf.sprintf
"%s(%s) : %s (%d)"
30 s a (Unix.error_message e
) (Obj.magic e
)
31 | exn
-> Printexc.to_string exn
34 let error fmt
= Printf.kprintf failwith fmt
;;
36 module IntSet
= Set.Make
(struct type t
= int let compare = (-) end);;
38 let emptystr s = String.length
s = 0;;
39 let nonemptystr s = String.length
s > 0;;
40 let bound v minv maxv
= max minv
(min maxv v
);;
44 then failwith
"spawn not implemented under cygwin yet"
50 type t
= private string
51 val of_string
: string -> t
52 val to_string
: t
-> string
62 let (~
<) = Opaque.of_string;;
63 let (~
>) = Opaque.to_string;;
65 let int_of_string_with_suffix s =
66 let l = String.length
s in
70 let suffix = Char.lowercase
s.[l-1] in
72 | 'k'
-> String.sub
s 0 (l-1), 10
73 | 'm'
-> String.sub
s 0 (l-1), 20
74 | '
g'
-> String.sub
s 0 (l-1), 30
78 let n = int_of_string
s1 in
79 let m = n lsl shift
in
81 then error "value too large"
85 let string_with_suffix_of_int n =
89 let units = [(30, "G"); (20, "M"); (10, "K")] in
95 then string_of_int
h ^
s
97 let s = Printf.sprintf
"_%03d%s" h s in
103 let rec find = function
105 | (shift
, suffix) :: rest
->
106 if (n land ((1 lsl shift
) - 1)) = 0
107 then prettyint (n lsr shift
) ^
suffix
113 let color_of_string s =
114 Scanf.sscanf
s "%d/%d/%d" (fun r
g b ->
115 (float r
/. 256.0, float g /. 256.0, float b /. 256.0)
119 let color_to_string (r
, g, b) =
120 let r = truncate
(r *. 256.0)
121 and g = truncate
(g *. 256.0)
122 and b = truncate
(b *. 256.0) in
123 Printf.sprintf
"%d/%d/%d" r g b
127 if Filename.is_relative path
129 let cwd = Sys.getcwd
() in
130 if Filename.is_implicit path
131 then Filename.concat
cwd path
132 else Filename.concat
cwd (Filename.basename path
)
144 try tempfailureretry Unix.close fd
145 with exn
-> f
@@ exntos exn
149 let getenvwithdef name def
=
150 match Sys.getenv name
with
152 | exception Not_found
-> def
155 let newlinere = Str.regexp
"[\r\n]";;
156 let percentsre = Str.regexp
"%s";;
157 let whitere = Str.regexp
"[ \t]";;
162 let b = Buffer.create
(String.length
s + 1) in
163 Buffer.add_string
b s;
168 let btod b = if b then 1 else 0;;
170 let splitatspace s = let open String
in
171 match index
s ' '
with
172 | pos
-> sub
s 0 pos
:: sub
s (pos
+1) (length
s - pos
- 1) :: []
173 | exception Not_found
-> [s]
176 let boundastep h step
=
178 then bound step ~
-h 0
182 let withoutlastutf8 s =
183 let len = String.length
s in
191 let b = Char.code
s.[pos
] in
192 if b land 0b11000000 = 0b11000000
197 if Char.code
s.[len-1] land 0x80 = 0
201 String.sub
s 0 first;
206 let b = Buffer.create
l in
207 let s = Bytes.create
l in
209 let n = tempfailureretry (Unix.read fd
s 0) l in
211 then Buffer.contents
b
213 Buffer.add_subbytes
b s 0 n;
220 let filecontents path
=
221 let fd = Unix.openfile path
[Unix.O_RDONLY
] 0o0
in
222 match fdcontents fd with
224 error "failed to read contents of %s: %s" path
@@ exntos exn
226 Ne.clo fd @@ error "failed to close descriptor for %s: %s" path
;
230 let getcmdoutput errfun cmd
=
231 let reperror fmt
= Printf.kprintf errfun fmt
in
232 let clofail s e
= error "failed to close %s: %s" s e
in
233 match Unix.pipe
() with
235 reperror "pipe failed: %s" @@ exntos exn
;
238 match spawn cmd
[r, -1; w
, 1] with
240 reperror "failed to execute %S: %s" cmd
@@ exntos exn
;
243 Ne.clo w
@@ clofail "write end of the pipe";
245 match Unix.waitpid
[] pid
with
247 reperror "waitpid on %S %d failed: %s" cmd pid
@@ exntos exn
;
249 | _pid
, Unix.WEXITED
0 ->
251 match fdcontents r with
253 reperror "failed to read output of %S: %s" cmd
@@ exntos exn
;
256 let l = String.length
s in
257 if l > 0 && s.[l-1] = '
\n'
258 then String.sub
s 0 (l-1)
261 | _pid
, Unix.WEXITED
n ->
262 reperror "%S exited with error code %d" cmd
n;
264 | _pid
, Unix.WSIGNALED
n ->
265 reperror "%S was killed with signal %d" cmd
n;
267 | _pid
, Unix.WSTOPPED
n ->
268 reperror "%S was stopped by signal %d" cmd
n;
271 Ne.clo r @@ clofail "read end of the pipe";
276 let re = Str.regexp
{|.*\
(\
(https?\
|ftp\
|mailto\
|file\
)://[^
]+\
).*|} in
278 if Str.string_match
re s 0
279 then Str.matched_group
1 s