forked from camlspotter/ocamloscope
-
Notifications
You must be signed in to change notification settings - Fork 0
/
source.ml
41 lines (36 loc) · 1.18 KB
/
source.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
(* local source service *)
open Spotlib.Spot
open List
let tbl = Hashtbl.create 1023
let scan ds =
Unix.Find.find ds ~follow_symlink:true ~f:(fun path ->
let is_source =
match Filename.split_extension path#base with
| _, ".eliom" -> true
| _, s when String.length s >= 3 && String.take 3 s = ".ml" -> true
| _ -> false
in
if is_source then
Hashtbl.add (* not replace *)
tbl path#base (path#path, ref None)) (* digest is got lazily *)
let find base ~digest =
let cands = Hashtbl.find_all tbl base in
flip find_map_opt cands & function
| (p, ({contents = Some (Some d)} as r)) when digest = d ->
begin match Digest.file p with
| exception _ ->
r := Some None; None
| d ->
if digest <> d then begin
r := Some None; None
end else Some p
end
| (_, {contents = Some (Some _)}) (* different digest *) -> None
| (_, {contents = Some None (* err *) }) -> None
| (p, r) ->
match Digest.file p with
| exception _ ->
r := Some None; None
| d ->
r := Some (Some d);
if digest = d then Some p else None