forked from xavierleroy/coq2html
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcommon.ml
69 lines (61 loc) · 1.72 KB
/
common.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
let shell cmd =
Printf.eprintf " $ %s\n" cmd;
let status = Sys.command cmd in
if status <> 0 then begin
prerr_endline ("Common.shell Error: " ^ cmd);
exit status
end
let wrap_result f x =
try Ok (f x) with
| exn -> Error exn
let unwrap_result = function
| Ok x -> x
| Error exn -> raise exn
let file_using_r filename f =
let read_ch = open_in filename in
let result = wrap_result f read_ch in
close_in read_ch;
unwrap_result result
let file_using_w filename f =
let write_ch = open_out filename in
let result = wrap_result f write_ch in
close_out write_ch;
unwrap_result result
let read_lines filename =
file_using_r filename begin fun read_ch ->
let rec iter store =
try iter (input_line read_ch :: store) with
| End_of_file -> List.rev store
in
iter []
end
let write_lines filename lines =
file_using_w filename begin fun out_ch ->
List.iter (Printf.fprintf out_ch "%s\n") lines
end
(* very naive brute force algorith *)
let strstr ~haystack ~needle =
assert (needle <> "");
let hlen = String.length haystack in
let nlen = String.length needle in
(* [has_prefix hpos npos] checks
haystack.[hpos-npos+i] = needle.[i] for 0 <= i <= npos
*)
let rec has_prefix hpos npos =
if haystack.[hpos] <> needle.[npos] then false
else if npos = 0 then true
else has_prefix (hpos - 1) (npos - 1)
in
let npos_init = nlen - 1 in
let hlen_nlen = hlen - nlen in
(* check from 0 to hlen - nlen *)
let rec loop hstart =
if hstart > hlen_nlen then None
else
if has_prefix (hstart + npos_init) npos_init then Some hstart
else loop (hstart + 1)
in
loop 0
let grep word contents =
strstr ~haystack:contents ~needle:word
|> Option.is_some