]> matita.cs.unibo.it Git - helm.git/blob - components/library/librarian.ml
modifications to make matita behave reasonably, removed some useless windows
[helm.git] / components / library / librarian.ml
1 exception NoRootFor of string
2
3 let find_root path =
4   let paths = List.rev (Str.split (Str.regexp "/") path) in
5   let rec build = function
6     | he::tl as l -> ("/" ^ String.concat "/" (List.rev l) ^ "/") :: build tl
7     | [] -> ["/"]
8   in
9   let paths = List.map HExtlib.normalize_path (build paths) in
10   try HExtlib.find_in paths "root"
11   with Failure "find_in" -> raise (NoRootFor path)
12 ;;
13   
14 let ensure_trailing_slash s = 
15   if s = "" then "/" else
16   if s.[String.length s-1] <> '/' then s^"/" else s
17 ;;
18
19 let remove_trailing_slash s = 
20   if s = "" then "" else
21   let len = String.length s in
22   if s.[len-1] = '/' then String.sub s 0 (len-1) else s
23 ;;
24
25 let find_root_for ~include_paths file = 
26  let include_paths = "" :: Sys.getcwd () :: include_paths in
27  let path = HExtlib.find_in include_paths file in
28  (* HLog.debug ("file "^file^" resolved as "^path); *)
29  let rootpath, root, buri = 
30    try
31      let mburi = Helm_registry.get "matita.baseuri" in
32      match Str.split (Str.regexp " ") mburi with
33      | [root; buri] when HExtlib.is_prefix_of root path -> 
34          ":registry:", root, buri
35      | _ -> raise (Helm_registry.Key_not_found "matita.baseuri")
36    with Helm_registry.Key_not_found "matita.baseuri" -> 
37      let rootpath = find_root path in
38      let data = HExtlib.input_file rootpath in
39      let buri = 
40        let lines = Str.split (Str.regexp "\n") data in
41        let lines = 
42          List.map (fun l -> 
43            match Str.split (Str.regexp "=") l with
44            | [k;v] -> Pcre.replace ~pat:" " k, Pcre.replace ~pat:" " v
45            | _ -> raise (Failure ("Malformed root file: " ^ rootpath)))
46            lines
47        in
48        List.assoc "baseuri" lines
49      in
50      rootpath, Filename.dirname rootpath, buri
51  in
52  (* HLog.debug ("file "^file^" rooted by "^rootpath^""); *)
53  let uri = Http_getter_misc.strip_trailing_slash buri in
54  if String.length uri < 5 || String.sub uri 0 5 <> "cic:/" then
55    HLog.error (rootpath ^ " sets an incorrect baseuri: " ^ buri);
56  ensure_trailing_slash root, remove_trailing_slash uri, path
57 ;;
58   
59 let baseuri_of_script ?(include_paths=[]) file = 
60   let root, buri, path = find_root_for ~include_paths file in
61   let path = HExtlib.normalize_path path in
62   let root = HExtlib.normalize_path root in
63   let lpath = Str.split (Str.regexp "/") path in
64   let lroot = Str.split (Str.regexp "/") root in
65   let rec substract l1 l2 =
66     match l1, l2 with
67     | h1::tl1,h2::tl2 when h1 = h2 -> substract tl1 tl2
68     | l,[] -> l
69     | _ -> raise (NoRootFor file)
70   in
71   let extra_buri = substract lpath lroot in
72   let chop name = 
73     assert(Filename.check_suffix name ".ma");
74     try Filename.chop_extension name
75     with Invalid_argument "Filename.chop_extension" -> name
76   in
77    root,
78    remove_trailing_slash (HExtlib.normalize_path 
79     (buri ^ "/" ^ chop (String.concat "/" extra_buri))),
80    path
81 ;;
82
83 let find_roots_in_dir dir =
84   HExtlib.find ~test:(fun f ->
85     Filename.basename f = "root" &&
86     try (Unix.stat f).Unix.st_kind = Unix.S_REG 
87     with Unix.Unix_error _ -> false)
88     dir
89 ;;
90