let compare_substring (a, idxa, lena) (b, idxb, lenb) =
let module With_exns = struct
exception Left
exception Right
let rec drop_until ~exn idx l =
match idx, l with
| 0, l -> l
| more, [] -> raise exn
| more, h :: t -> drop_until ~exn (more - 1) t
let f () =
begin try
let rec cmp l1 l2 len1 len2 =
if len1 < 0 then raise Left;
if len2 < 0 then raise Right;
match l1, l2 with
| _, _ when len1 = 0 && len2 = 0 -> 0
| _, _ when len1 = 0 -> -1
| _, _ when len2 = 0 -> 1
| [], [] when len1 = 0 || len2 = 0 -> Pervasives.compare lena lenb
| [], _ when len1 > 0 -> raise Left
| _, [] when len2 > 0 -> raise Right
| h1 :: t1, h2 :: t2 when Char.compare h1 h2 = 0 ->
cmp t1 t2 (len1 - 1) (len2 - 1)
| h1 :: _, h2 :: _ -> Char.compare h1 h2
| _, _ -> assert false
in
if lena = 0 && lenb = 0 then 0
else (
let aa = drop_until ~exn:Left idxa a in
let bb = drop_until ~exn:Right idxb b in
(cmp aa bb lena lenb)
)
with
| Left -> -1
| Right -> 1
| Failure s -> 1
end
end in
With_exns.f ()