1 module LexingExt = struct
9 pos_lnum = lexbuf.lex_curr_p.pos_lnum + 1
14 module ListExt = struct
16 let inv_assoc l = List.map (fun (x, y) -> (y, x)) l
20 let last l = try List.hd (List.rev l) with _ -> raise EmptyList
23 let rec aux l = function
24 | [] -> raise EmptyList
25 | [ x ] -> (x, List.rev l)
26 | x :: xs -> aux (x :: l) xs
30 let multi_set_of_list l =
31 let h = Hashtbl.create 13 in
33 let o = try Hashtbl.find h x with Not_found -> 0 in
34 Hashtbl.replace h x (o + 1)
37 Hashtbl.fold (fun k v accu -> (k, v) :: accu) h []
39 let hashtbl_of_assoc l =
40 let h = Hashtbl.create 13 in
41 List.iter (fun (k, v) -> Hashtbl.add h k v) l;
45 let assoc_union l1 l2 =
46 let h1 = hashtbl_of_assoc l1 in
51 let v2 = Hashtbl.find h1 k in
52 if v1 <> v2 then raise Conflict;
56 let assoc_diff l1 l2 =
57 let h1 = hashtbl_of_assoc l1 in
58 let h2 = hashtbl_of_assoc l2 in
63 try Some (Hashtbl.find h2 k)
64 with Not_found -> None
68 (k, (Some v1, v2)) :: accu
70 (k, (v2, Some v1)) :: accu
75 let d1 = diff h1 h2 true in
76 let d2 = diff h2 h1 false in
78 with Conflict -> assert false
80 let transitive_forall2 p l =
81 let rec aux = function
84 | x1 :: ((x2 :: _) as xs) ->
85 if not (p x1 x2) then Some (x1, x2) else aux xs
91 module ArgExt = struct
93 let extra_doc s = "", Arg.Unit ignore, s
97 module SysExt = struct
99 let safe_remove name =
100 try Sys.remove name with Sys_error _ -> ()
102 let rec alternative name =
103 if not (Sys.file_exists name) then
106 let dirname = Filename.dirname name in
107 let filename = Filename.basename name in
108 let r = Str.regexp "\\([0-9]+\\)-\\(.*\\)" in
110 if Str.string_match r filename 0 then
111 let i = int_of_string (Str.matched_group 1 filename) in
112 Printf.sprintf "%02d-%s" (i + 1) (Str.matched_group 2 filename)
116 alternative (Filename.concat dirname filename)
121 let fresh_file prefix suffix =
122 let string_of_complement = function
124 | Some i -> string_of_int i in
125 let next_complement = function
127 | Some i -> Some (i+1) in
128 let rec aux complement =
129 let filename = prefix ^ (string_of_complement complement) ^ suffix in
130 if not (Sys.file_exists filename) then filename
131 else aux (next_complement complement) in
134 let exists_exts base exts =
135 let f res ext = res || (Sys.file_exists (base ^ ext)) in
136 List.fold_left f false exts
138 let fresh_base base exts =
139 let string_of_complement = function
141 | Some i -> string_of_int i in
142 let next_complement = function
144 | Some i -> Some (i+1) in
145 let rec aux complement =
146 let new_base = base ^ (string_of_complement complement) in
147 if not (exists_exts new_base exts) then new_base
148 else aux (next_complement complement) in
151 let rec repeat n f a =
153 else repeat (n-1) f (f a)