diff options
Diffstat (limited to 'perl_checker.src/common.ml')
-rw-r--r-- | perl_checker.src/common.ml | 1005 |
1 files changed, 0 insertions, 1005 deletions
diff --git a/perl_checker.src/common.ml b/perl_checker.src/common.ml deleted file mode 100644 index dd2f6b1..0000000 --- a/perl_checker.src/common.ml +++ /dev/null @@ -1,1005 +0,0 @@ -open Stack -open List - -exception Found -exception Not_comparable -exception GraphSort_circular_deps - -type ('a, 'b) either = Left of 'a | Right of 'b -type ('a, 'b) or_option = Or_some of 'a | Or_error of 'b - -(**********************************************************************************) - -let internal_error s = failwith ("internal error: " ^ s) - -let id x = x -let double a = a,a -let swap (x,y) = (y,x) -let safe_tl l = try tl l with _ -> [] -let fstfst ((e, _), _) = e -let sndfst ((_, e), _) = e -let fstsnd (_, (e, _)) = e -let sndsnd (_, (_, e)) = e - -let fst3 (e, _, _) = e -let snd3 (_, e, _) = e -let ter3 (_, _, e) = e -let sndter3 (_, a, b) = (a, b) - -let o f g x = f (g x) -let curry f x y = f (x,y) -let uncurry f (x, y) = f x y - -let is_int n = ceil n = n - -let uncons = function - | [] -> failwith "uncons" - | e::l -> e,l - -let has_env var = - try - let _ = Sys.getenv var in true - with Not_found -> false - -let some = function - | Some e -> e - | None -> failwith "some" - -let some_or = function - | None -> id - | Some e -> fun _ -> e - -let option2l = function - | None -> [] - | Some e -> [e] - -let prefer_some f a b = - match a, b with - | Some a, Some b -> Some (f a b) - | None, _ -> b - | _, None -> a - -let rec collect_accu f accu = function - | [] -> accu - | e::l -> collect_accu f (rev_append (f e) accu) l - -let collect f l = rev (collect_accu f [] l) - -let merge_some merge a b = - match a,b with - | None, None -> None - | _, None -> a - | None, _ -> b - | Some(a), Some(b) -> Some(merge a b) - -let rec uniq = function - | [] -> [] - | e::l -> if mem e l then uniq l else e :: uniq l - -let rec uniq_ eq = function - | [] -> [] - | e::l -> - try - let _ = find (eq e) l in - uniq_ eq l - with Not_found -> e :: uniq_ eq l - -let rec non_uniq = function - | [] -> [] - | e::l -> if mem e l then e :: non_uniq l else non_uniq l - -let rec member_ eq e = function - | [] -> false - | e'::l -> if eq e e' then true else member_ eq e l - -let rec find_some p = function - | [] -> raise Not_found - | x :: l -> - match p x with - | Some v -> v - | None -> find_some p l - -let fold_left1 f = function - | [] -> failwith "fold_left1" - | e :: l -> fold_left f e l - -let find_index e l = - let rec find_index_ i = function - | [] -> raise Not_found - | e'::l -> if e=e' then i else find_index_ (i+1) l - in - find_index_ 0 l - -let rec find_some_ p = function - | [] -> None - | x :: l -> - match p x with - | Some v -> Some v - | None -> find_some_ p l - -let rec fpartition p l = - let rec part yes no = function - | [] -> (rev yes, rev no) - | x :: l -> - (match p x with - | None -> part yes (x :: no) l - | Some v -> part (v :: yes) no l) in - part [] [] l - -let partition_either f l = - let rec part_either left right = function - | [] -> (rev left, rev right) - | x :: l -> - (match f x with - | Left e -> part_either (e :: left) right l - | Right e -> part_either left (e :: right) l) in - part_either [] [] l - -let rec keep_best f = - let rec partition e = function - | [] -> e, [] - | e' :: l -> - match f(e,e') with - | None -> let (e'', l') = partition e l in e'', e' :: l' - | Some e'' -> partition e'' l - in function - | [] -> [] - | e::l -> - let (e', l') = partition e l in - e' :: keep_best f l' - -let rec keep_bests f l = - let rec once e unchanged = function - | [] -> None - | e' :: l -> - match f(e,e') with - | None -> once e (e' :: unchanged) l - | Some e'' -> Some(e'', unchanged @ l) - in - let rec as_many_as_possible e l = - match once e [] l with - | None -> None - | Some(e', l') -> Some(some_or (as_many_as_possible e' l') (e', l')) - in - let rec try_with e l_done l_next = - match as_many_as_possible e l_next with - | None -> try_with_next (e :: l_done) l_next - | Some(e2, l_next2) -> - match as_many_as_possible e2 l_done with - | None -> try_with_next (e2 :: l_done) l_next2 - | Some(e3, l_done2) -> try_with e3 l_done2 l_next2 - and try_with_next l_done = function - | [] -> rev l_done - | e::l_next -> try_with e l_done l_next - in - try_with_next [] l - -let rec fold_right1 f = function - | [] -> failwith "fold_right1" - | [e] -> e - | e::l -> f e (fold_right1 f l) - -let rec for_all2_ p l1 l2 = - match (l1, l2) with - ([], []) -> true - | (a1::l1, a2::l2) -> p a1 a2 && for_all2_ p l1 l2 - | (_, _) -> false - -let rec for_all2_true p l1 l2 = - match (l1, l2) with - | (a1::l1, a2::l2) -> p a1 a2 && for_all2_true p l1 l2 - | (_, _) -> true - -let maxl l = fold_right1 max l - -let rec stack2list s = - let l = ref [] in - Stack.iter (fun e -> l := e :: !l) s ; - !l - -let rec stack_exists f s = - try - Stack.iter (fun e -> if f e then raise Found) s ; - false - with Found -> true - -let rec queue2list q = rev (Queue.fold (fun b a -> a :: b) [] q) - -let rec fix_point f p = - let p' = f p in - if p = p' then p else fix_point f p' - -let rec fix_point_withenv f env p = - let p', env' = f env p in - if p = p' then (p, env') else fix_point_withenv f env' p' - -let rec fix_point_ nb f p = - let p' = f p in - if p = p' then p, nb else fix_point_ (nb+1) f p' - -let rec group_by_2 = function - | [] -> [] - | a :: b :: l -> (a, b) :: group_by_2 l - | _ -> failwith "group_by_2" - -(* -let rec lfix_point f e = - let e' = f(e) in - if e = e' then e :: lfix_point f e' else [e] -*) - -let fluid_let ref value f = - let previous_val = !ref in - ref := value ; - let v = f() in - ref := previous_val ; - v - -let do0_withenv doit f env l = - let r_env = ref env in - doit (fun e -> r_env := f !r_env e) l ; - !r_env - -let do0_withenv2 doit f env l = - let r_env = ref env in - doit (fun e e' -> r_env := f !r_env e e') l ; - !r_env - -let do_withenv doit f env l = - let r_env = ref env in - let l' = doit (fun e -> - let e', env' = f !r_env e in - r_env := env' ; e' - ) l in - l', !r_env - -let do2_withenv doit f env l1 l2 = - let r_env = ref env in - let l' = doit (fun e1 e2 -> - let e', env' = f !r_env e1 e2 in - r_env := env' ; e' - ) l1 l2 in - l', !r_env - -let do_collect doit f l1 = - let l = ref [] in - doit (fun i t -> l := f i t @ !l) l1 ; - !l - -let map_withitself f l = - let rec map_withitself_ done_ = function - | [] -> done_ - | e :: l -> - let e' = f (done_ @ e :: l) e in - map_withitself_ (done_ @ [ e' ]) l - in map_withitself_ [] l - -let map_t2 f (x,y) = f x, f y -let map_t3 f (x,y,z) = f x, f y, f z -let map_option f = function - | Some e -> Some (f e) - | None -> None -let map_optionoption f = function - | Some e -> f e - | None -> None -let t2_option2option_t2 = function - | (Some x, Some y) -> Some(x,y) - | _ -> None -let rec l_option2option_l = function - | [] -> Some [] - | None :: _l -> None - | Some e :: l -> map_option (fun l -> e :: l) (l_option2option_l l) -let map_option_env f (e, env) = map_option f e, env - -let t2_to_list (a,b) = [ a ; b ] -let t3_to_list (a,b,c) = [ a ; b ; c ] - -let if_some bool val_ = if bool then Some val_ else None - -let rec fold_left_option f val_ = function - | [] -> Some val_ - | e::l -> - match f val_ e with - | None -> None - | Some val_' -> fold_left_option f val_' l - -let collect_some_withenv f env l = - let rec collect accu env = function - | [] -> rev accu, env - | e::l -> - let e', env' = f env e in - let accu' = - match e' with - | Some e' -> e'::accu - | None -> accu in - collect accu' env' l - in collect [] env l - -let for_all_option_withenv remap f env l = - let rec for_all env accu = function - | [] -> Some(remap (rev accu)), env - | e::l -> - (match f env e with - | None, env' -> None, env' - | Some e', env' -> for_all env' (e' :: accu) l) - in - for_all env [] l - -let for_all2_option_withenv remap f env la lb = - let rec for_all env accu = function - | [], [] -> Some(remap (rev accu)), env - | a::la, b::lb -> - (match f env a b with - | None, env' -> None, env' - | Some ab, env' -> for_all env' (ab :: accu) (la, lb)) - | _ -> None, env - in - for_all env [] (la, lb) - -let map_or_option f = function - | Or_some e -> Or_some (f e) - | Or_error err -> Or_error err - -let map_index f l = - let rec map_ n = function - | [] -> [] - | e::l -> f e n :: map_ (n+1) l - in map_ 0 l - -let filter_index f l = - let rec filter_ n = function - | [] -> [] - | e::l -> - let l' = filter_ (n+1) l in - if f e n then e :: l' else l' - in filter_ 0 l - -let iter_index f l = - let rec iter_ n = function - | [] -> () - | e::l -> f e n ; iter_ (n+1) l - in iter_ 0 l - -let map_fst f (x, y) = f x, y -let map_snd f (x, y) = x, f y - -let map_withenv f env e = do_withenv map f env e -let find_withenv f env e = do_withenv find f env e -let filter_withenv f env e = do_withenv filter f env e -let exists_withenv f env e = do_withenv exists f env e -let map_t2_withenv f env e = do_withenv map_t2 f env e -let for_all_withenv f env e = do_withenv for_all f env e -let collect_withenv f env e = do_withenv collect f env e -let partition_either_withenv f env e = do_withenv partition_either f env e - -let map2_withenv f env l1 l2 = do2_withenv map2 f env l1 l2 -let for_all2_withenv f env l1 l2 = do2_withenv for_all2 f env l1 l2 - -let rec take n l = - if n = 0 then [] - else match l with - | [] -> raise Not_found - | e::l -> e :: take (n-1) l -let last_n n l = rev (take n (rev l)) -let last l = hd (last_n 1 l) - -let rec skipfirst e = function - | [] -> [] - | e'::l when e = e' -> skipfirst e l - | l -> l - -let rec removelast = function - | [] -> failwith "removelast" - | [_] -> [] - | e::l -> e :: removelast l - -let rec split_last l = - let rec spl accu = function - | [] -> failwith "split_last" - | [e] -> rev accu, e - | e::l -> spl (e :: accu) l - in spl [] l - -let iter_assoc_val f l = iter (fun (_,v) -> f v) l -let map_assoc_val f l = map (fun (k,v) -> k, f v) l - -let assoc_or_fail e l = - try assoc e l with Not_found -> failwith "assoc failed" - -let assoc_by is_same e l = - find_some (fun (a,b) -> if is_same e a then Some b else None) l - -let rec update_assoc_by is_same f e = function - | [] -> raise Not_found - | (a,b) :: l when is_same e a -> (a, f b) :: l - | (a,b) :: l -> (a,b) :: update_assoc_by is_same f e l - -let update_assoc f e = update_assoc_by (=) f e - -let rec update_assoc_by_with_default default is_same f e = function - | [] -> [ e, f default ] - | (a,b) :: l when is_same e a -> (a, f b) :: l - | (a,b) :: l -> (a,b) :: update_assoc_by_with_default default is_same f e l - -let update_all_assoc_by is_same f e l = - map (fun (a,b) -> a, if is_same e a then f b else b) l - -let rec rassoc e = function - | [] -> raise Not_found - | (k,v) :: l -> if e = v then k else rassoc e l - -let rec all_assoc e = function - | [] -> [] - | (e',v) :: l when e=e' -> v :: all_assoc e l - | _ :: l -> all_assoc e l - -let rec all_assoc_by is_same e = function - | [] -> [] - | (e',v) :: l when is_same e e' -> v :: all_assoc_by is_same e l - | _ :: l -> all_assoc_by is_same e l - -let prepare_want_all_assoc l = - map (fun n -> n, uniq (all_assoc n l)) (uniq (map fst l)) - -let prepare_want_all_assoc_by is_same l = - map (fun n -> n, uniq_ is_same (all_assoc_by is_same n l)) (uniq_ is_same (map fst l)) - -let prepare_want_all_assoc_by_ is_same_a is_same_b l = - map (fun n -> n, uniq_ is_same_b (all_assoc_by is_same_a n l)) (uniq_ is_same_a (map fst l)) - -let rec count_uniq = function - | [] -> [] - | e::l -> - let has, l' = partition ((=) e) l in - (e, length has + 1) :: count_uniq l' - -let rec repeat e = function - | 0 -> [] - | n -> e :: repeat e (n-1) - -let rec inits = function - | [] -> [[]] - | e::l -> [] :: map (fun l -> e::l) (inits l) -let rec tails = function - | [] -> [[]] - | (_::xs) as xxs -> xxs :: tails xs - -let apply f x = f x;; - -let rec map3 f l1 l2 l3 = - match (l1, l2, l3) with - ([], [], []) -> [] - | (a1::l1, a2::l2, a3::l3) -> let r = f a1 a2 a3 in r :: map3 f l1 l2 l3 - | (_, _, _) -> invalid_arg "map3" - -let filter2 f l1 l2 = - split (filter f (combine l1 l2)) - -let break_at f l = - let rec b l1 = function - | [] -> l1, [] - | e::l2 -> if f e then (l1, e :: l2) else b (l1 @ [e]) l2 - in b [] l -let break v l = break_at ((=) v) l - -let drop_while f l = snd (break_at (fun e -> not (f e)) l) - -(* break_at_indice 0 [1;2] gives [], [1;2] - break_at_indice 1 [1;2] gives [1], [2] - *) -let rec break_at_indice i l = - if i = 0 then [], l else - match l with - | [] -> raise Not_found - | e::l2 -> - let a, b = break_at_indice (i-1) l2 in - e::a, b - -let rev_nth e l = - let rec rev_nth' i = function - | [] -> raise Not_found - | e'::_ when e'=e -> i - | _::l -> rev_nth' (i+1) l - in rev_nth' 0 l - -let rec getset_nth l i f = - match l, i with - | e::l', 0 -> f e :: l' - | [], _ -> failwith "getset_nth" - | e::l', _ -> e :: getset_nth l' (i - 1) f - -let set_nth l i v = getset_nth l i (fun _ -> v) - -let adjustModDown m n = n - (n mod m) -let adjustModUp m n = adjustModDown m (n + m - 1) - - -let hashtbl_find f h = - let r = ref None in - Hashtbl.iter (fun v c -> if f v c then r := Some v) h ; - match !r with - | Some v -> v - | None -> raise Not_found - -let hashtbl_map f h = Hashtbl.iter (fun v c -> Hashtbl.replace h v (f v c)) h - -let hashtbl_values h = Hashtbl.fold (fun _ v l -> v :: l) h [] -let hashtbl_keys h = Hashtbl.fold (fun k _ l -> k :: l) h [] -let hashtbl_to_list h = Hashtbl.fold (fun k v l -> (k,v) :: l) h [] - -let hashtbl_collect f h = - rev (Hashtbl.fold (fun k v l -> rev_append (f k v) l) h []) - -let hashtbl_exists f h = - try - Hashtbl.iter (fun v c -> if f v c then raise Found) h ; - false - with Found -> true - -let memoize f = - let hash = Hashtbl.create 16 in - fun k -> - try Hashtbl.find hash k - with Not_found -> - let v = f k in - Hashtbl.add hash k v ; v - -let array_shift a = Array.sub a 1 (Array.length a - 1) -let array_last_n n a = - let len = Array.length a in - Array.sub a (len - n) n - -let array_collect f a = Array.fold_left (fun l e -> f e @ l) [] a - -let rec lvector_product = - let rec vector_product a b = match a with - | [] -> [] - | e::l -> map (fun e' -> e :: e') b :: vector_product l b - in function - | [] -> [] - | [e] -> map (fun e -> [e]) e - | e::l -> flatten (vector_product e (lvector_product l)) - -let vector_product2 a b = - map (function - | [a;b] -> a,b - | _ -> failwith "vector_product2" - ) (lvector_product [ a ; b ]) - -let rec transpose = function - | [] :: _ -> [] - | ll -> - let l, ll' = split (map (function e::l -> e,l | _ -> raise Not_found) ll) in - l :: transpose ll' - -let rec range min max = - if min >= max then [] else min :: range (min + 1) max - -let sum l = List.fold_left (+) 0 l - -let rec filter_some_with f = function - | [] -> [] - | e :: l -> - match f e with - | None -> filter_some_with f l - | Some e' -> e' :: filter_some_with f l - -let rec filter_some = function - | [] -> [] - | None :: l -> filter_some l - | Some e :: l -> e :: filter_some l - -let rec difference l = function - | [] -> l - | e::l' -> difference (filter ((<>) e) l) l' - -let rec difference_ eq l = function - | [] -> l - | e::l' -> - let l2 = filter (fun e' -> not (eq e e')) l in - difference_ eq l2 l' - -let intersection_by is_same l1 l2 = filter (fun e -> exists (is_same e) l2) l1 - -let intersection_and_differences eq l1 l2 = - let rec both inter l2_only = function - | [], l2 -> inter, [], rev l2_only @ l2 - | l1, [] -> inter, l1, rev l2_only - | l1, e2 :: l2' -> - match partition (eq e2) l1 with - | [], _ -> both inter (e2 :: l2_only) (l1, l2') - | _, l1' -> both (e2 :: inter) l2_only (l1', l2') - in both [] [] (l1, l2) - -let rec triangularize = function - | [] -> [] - | e::l -> (e,l) :: triangularize l - -let diagonalize l = - map_index (fun a i -> - a, filter_index (fun _ j -> i <> j) l - ) l - -let rec list_of_nonempty_sublists = function - | [] -> [] - | e :: l -> - let l' = list_of_nonempty_sublists l in - [e] :: l' @ map (fun l -> e :: l) l' - -let rec graph_is_sorted_by eq = function - | [] -> true - | (_,deps) :: l -> - for_all (fun e -> try let _ = assoc_by eq e l in false with Not_found -> true) deps && graph_is_sorted_by eq l - -let graph_closure_by eq graph = - let err = ref None in - try - let graph_rev = collect (fun (i, l) -> map (fun e -> (e, i)) l) graph in - let bothway = map (fun (i,l) -> i, (l, all_assoc_by eq i graph_rev)) graph in - let closed = fold_left (fun graph j -> - let next, prev = assoc_by eq j graph in - let graph2 = fold_left (fun graph i -> - if member_ eq i next then (err := Some(j,i); raise GraphSort_circular_deps) else - update_assoc_by eq (fun (i_next,i_prev) -> i_next @ next, i_prev) i graph - ) graph (filter (fun a -> not (eq a j)) prev) in - let graph3 = fold_left (fun graph k -> - if member_ eq k prev then (err := Some(j,k); raise GraphSort_circular_deps) else - update_assoc_by eq (fun (k_next,k_prev) -> k_next, k_prev @ prev) k graph - ) graph2 (filter (fun a -> not (eq a j)) next) in - graph3 - ) bothway (map fst bothway) in - Or_some (map (fun (e,(next,_)) -> e, uniq_ eq next) closed) - with GraphSort_circular_deps -> - Or_error (some !err) - -let rec graph_sort_by eq l = - let cmp (_, deps_a) (b, _) = if member_ eq b deps_a then 1 else -1 in - let rec sort_it = function - | [] -> [] - | [e] -> [e] - | e::l -> - let l' = sort_it l in - let gt, lt = break_at (fun ((_, deps) as e') -> deps = [] or cmp e e' = 1) l' in - gt @ [e] @ lt - in - map_or_option (fun l' -> - let l_sorted = rev (sort_it l') in - if not (graph_is_sorted_by eq l_sorted) then internal_error "graph_sort failed" else - l_sorted - ) (graph_closure_by eq l) - -let int_sort l = sort (fun a b -> a - b) l - -let str_begins_with prefix s = - String.sub s 0 (min (String.length s) (String.length prefix)) = prefix - -let rec strstr s subs = - let len_s, len_subs = String.length s, String.length subs in - let rec rec_ i = - let i' = String.index_from s i subs.[0] in - if i' + len_subs <= len_s then - if String.sub s i' len_subs = subs then - i' - else - rec_ (i' + 1) - else - raise Not_found - in - rec_ 0 - -let str_contains s subs = - try - let _ = strstr s subs in true - with Not_found -> false - -let str_ends_with s suffix = - let len = min (String.length s) (String.length suffix) in - String.sub s (String.length s - len) len = suffix - -let chop = function - | "" -> "" - | s -> String.sub s 0 (String.length s - 1) - -let chomps s = - let i = ref (String.length s - 1) in - while !i >= 0 && (s.[!i] = ' ' || s.[!i] = '\t') do decr i done ; - String.sub s 0 (!i+1) - -let rec times e = function - | 0 -> [] - | n -> e :: times e (n-1) - -let skip_n_char_ beg end_ s = - let full_len = String.length s in - if beg < full_len && full_len - beg - end_ > 0 - then String.sub s beg (full_len - beg - end_) - else "" -let skip_n_char n s = skip_n_char_ n 0 s - -let rec non_index_from s beg c = - if s.[beg] = c then non_index_from s (beg+1) c else beg -let non_index s c = non_index_from s 0 c - -let rec non_rindex_from s beg c = - if s.[beg] = c then non_rindex_from s (beg-1) c else beg -let non_rindex s c = non_rindex_from s (String.length s - 1) c - -let rec explode_string = function - | "" -> [] - | s -> (String.get s 0) :: explode_string (String.sub s 1 (String.length s - 1)) - -let count_matching_char s c = - let rec count_matching_char_ nb i = - try - let i' = String.index_from s i c in - count_matching_char_ (nb+1) (i'+1) - with Not_found -> nb - in - count_matching_char_ 0 0 - -let is_uppercase c = Char.lowercase c <> c -let is_lowercase c = Char.uppercase c <> c - -let char_is_alphanumerical c = - let i = Char.code c in - Char.code 'a' <= i && i <= Char.code 'z' || - Char.code 'A' <= i && i <= Char.code 'Z' || - Char.code '0' <= i && i <= Char.code '9' - -let char_is_alphanumerical_ c = - let i = Char.code c in - Char.code 'a' <= i && i <= Char.code 'z' || - Char.code 'A' <= i && i <= Char.code 'Z' || - Char.code '0' <= i && i <= Char.code '9' || c = '_' - -let char_is_alpha c = - let i = Char.code c in - Char.code 'a' <= i && i <= Char.code 'z' || - Char.code 'A' <= i && i <= Char.code 'Z' - -let char_is_number c = - let i = Char.code c in - Char.code '0' <= i && i <= Char.code '9' - -let count_chars_in_string s c = - let rec rec_count_chars_in_string from = - try - let from' = String.index_from s from c in - 1 + rec_count_chars_in_string (from' + 1) - with - Not_found -> 0 - in rec_count_chars_in_string 0 - -let rec string_fold_left f val_ s = - let val_ = ref val_ in - for i = 0 to String.length s - 1 do - val_ := f !val_ s.[i] - done ; - !val_ - -(* -let rec string_forall_with f i s = - try - f s.[i] && string_forall_with f (i+1) s - with Invalid_argument _ -> true -*) -let string_forall_with f i s = - let len = String.length s in - let rec string_forall_with_ i = - i >= len || f s.[i] && string_forall_with_ (i+1) - in string_forall_with_ i - -let starts_with_non_lowercase s = s <> "" && s.[0] <> '_' && not (is_lowercase s.[0]) - -let rec fold_lines f init chan = - try - let line = input_line chan in - fold_lines f (f init line) chan - with End_of_file -> init -let readlines chan = List.rev (fold_lines (fun l e -> e::l) [] chan) - -let split_at c s = - let rec split_at_ accu i = - try - let i' = String.index_from s i c in - split_at_ (String.sub s i (i' - i) :: accu) (i'+1) - with Not_found -> rev (skip_n_char i s :: accu) - in - split_at_ [] 0 - -let split_at2 c1 c2 s = - let rec split_at2_ accu i i2 = - try - let i3 = String.index_from s i2 c1 in - if s.[i3+1] = c2 then split_at2_ (String.sub s i (i3 - i) :: accu) (i3+2) (i3+2) else - split_at2_ accu i i3 - with Not_found | Invalid_argument _ -> rev (skip_n_char i s :: accu) - in - split_at2_ [] 0 0 - -let words s = - let rec words_ accu i s = - try - let i2 = non_index_from s i ' ' in - try - let i3 = String.index_from s i2 ' ' in - words_ (String.sub s i2 (i3 - i2) :: accu) (i3+1) s - with Not_found -> rev (skip_n_char i2 s :: accu) - with Invalid_argument _ -> rev accu - in - collect (words_ [] 0) (split_at '\n' s) - -let to_CamelCase s_ = - let l = ref [] in - let s = String.copy s_ in - for i = 1 to String.length s - 1 do - if is_uppercase (String.unsafe_get s i) && is_lowercase (String.unsafe_get s (i-1)) then ( - String.set s i (Char.lowercase (String.get s i)) ; - l := i :: !l - ) - done ; - if !l = [] then None else - let offset, s' = fold_left (fun (offset, s') i -> - i, s' ^ String.sub s offset (i-offset) ^ "_" - ) (0, "") (rev !l) in - Some (s' ^ String.sub s offset (String.length s - offset)) - -let concat_symlink file link = - if str_begins_with "..//" link then (* ..//foo => /foo *) - skip_n_char 3 link - else - let file = if str_ends_with file "/" then chop file else file in (* s|/$|| *) - let rec reduce file link = - if str_begins_with "../" link then - let file = String.sub file 0 (String.rindex file '/') in (* s|/[^/]+$|| *) - reduce file (skip_n_char 3 link) - else - file ^ "/" ^ link - in - reduce file link - -let expand_symlinks file = - match split_at '/' file with - | "" :: l -> - let rec remove_dotdot accu nb = function - | [] -> if nb = 0 then accu else failwith "remove_dotdot" - | ".." :: l -> remove_dotdot accu (nb + 1) l - | e :: l -> if nb > 0 then remove_dotdot accu (nb - 1) l else remove_dotdot (e :: accu) nb l - in - let l = remove_dotdot [] 0 (List.rev l) in - List.fold_left (fun file piece -> - fix_point (fun file -> - try concat_symlink file ("../" ^ Unix.readlink file) - with _ -> file - ) (file ^ "/" ^ piece)) "" l - | _ -> internal_error (Printf.sprintf "expand_symlinks: %s is relative\n" file) - -let mtime f = (Unix.stat f).Unix.st_mtime - -let rec updir dir nb = - if nb = 0 then dir else - match dir with - | "." -> String.concat "/" (times ".." nb) - | _ -> - if Filename.basename dir = ".." then - dir ^ "/" ^ String.concat "/" (times ".." nb) - else - updir (Filename.dirname dir) (nb-1) - -let (string_of_ref : 'a ref -> string) = fun r -> - Printf.sprintf "0x%x" (Obj.magic r : int) - -let print_endline_flush s = print_endline s ; flush stdout - -let is_int n = n = floor n - -(* total order *) -let rec compare_lists cmp l1 l2 = - match l1, l2 with - | [], [] -> 0 - | [], _ -> -1 - | _, [] -> 1 - | e1::l1, e2::l2 -> - match cmp e1 e2 with - | 0 -> compare_lists cmp l1 l2 - | v -> v - -let compare_best a b = - match a, b with - | 0, 0 -> 0 - | 1, 1 | 1, 0 | 0, 1 -> 1 - | -1, -1 | -1, 0 | 0, -1 -> -1 - | 1, -1 | -1, 1 -> raise Not_comparable - | _ -> failwith "uh?" - -(* partial order *) -let combine_comparison_list l = - fold_left compare_best 0 l - -let min_with_cmp less_than a b = - if less_than a b then a - else if less_than b a then b - else raise Not_comparable - -let max_with_cmp less_than a b = - if less_than a b then b - else if less_than b a then a - else raise Not_comparable - -let rec fold_left2_compare f e l1 l2 = - match l1, l2 with - | [], [] -> e - | e1::l1, e2::l2 -> fold_left2_compare f (f e e1 e2) l1 l2 - | _ -> raise Not_comparable - -let rec exists_compare cmp = function - | [] -> raise Not_comparable - | e :: l -> try cmp e with Not_comparable -> exists_compare cmp l - -let forall_compare cmp = fold_left (fun n e -> compare_best n (cmp e)) 0 -let forall2_compare cmp = fold_left2_compare (fun n e1 e2 -> compare_best n (cmp e1 e2)) 0 - -let exists2_compare left_dropping cmp l1 l2 = - let rec forall_compare_ n = function - | [], [] -> n - | _, [] -> compare_best n left_dropping - | [], _ -> compare_best n (-left_dropping) - | e1::l1, e2::l2 -> - match try Some (cmp e1 e2) with Not_comparable -> None with - | Some n' -> forall_compare_ (compare_best n n') (l1, l2) - | None -> - if n = left_dropping then - forall_compare_ left_dropping (l1, e2::l2) - else if n = -left_dropping then - forall_compare_ (-left_dropping) (e1::l1, l2) - else - (* need to try both *) - try forall_compare_ left_dropping (l1, e2::l2) - with Not_comparable -> forall_compare_ (-left_dropping) (e1::l1, l2) - in forall_compare_ 0 (l1, l2) - - -let rec compare_sorted_sets is_same l1 l2 = - match l1, l2 with - | [], [] -> 0 - | [], _ -> -1 - | _, [] -> 1 - | e1::l1, e2::l2 -> if is_same e1 e2 then compare_sorted_sets is_same l1 l2 else raise Not_found - -let scan_list_while_modifying f l = - let rec scan_list_while_modifying_ prev = function - | [] -> prev - | e :: next -> - let prev', next' = some_or (f prev next e) (prev @ [e], next) in - scan_list_while_modifying_ prev' next' - in scan_list_while_modifying_ [] l - -let bools2compare = function - | true, true -> 0 - | true, false -> -1 - | false, true -> 1 - | _ -> raise Not_comparable - -let lpush l e = l := e :: !l - -(* -let is_greater2compare is_greater a b = - match is_greater a b, is_greater b a with - - *) - -module OrderedString = - struct - type t = string - let compare = compare - end;; - -module StringSet = Set.Make(OrderedString);; - -let stringSet_to_list = StringSet.elements -let stringSet_add set e = StringSet.add e set -let stringSet_difference = StringSet.diff -let list_to_StringSet l = fold_left stringSet_add StringSet.empty l - -(* this character messes emacs caml mode *) -let char_quote = '"' |