exception NoRootFor of string let find_root path = let paths = List.rev (Str.split (Str.regexp "/") path) in let rec build = function | he::tl as l -> ("/" ^ String.concat "/" (List.rev l) ^ "/") :: build tl | [] -> ["/"] in let paths = List.map HExtlib.normalize_path (build paths) in try HExtlib.find_in paths "root" with Failure "find_in" -> raise (NoRootFor path) ;; let ensure_trailing_slash s = if s = "" then "/" else if s.[String.length s-1] <> '/' then s^"/" else s ;; let remove_trailing_slash s = if s = "" then "" else let len = String.length s in if s.[len-1] = '/' then String.sub s 0 (len-1) else s ;; let find_root_for ~include_paths file = let include_paths = "" :: Sys.getcwd () :: include_paths in let path = HExtlib.find_in include_paths file in (* HLog.debug ("file "^file^" resolved as "^path); *) let rootpath, root, buri = try let mburi = Helm_registry.get "matita.baseuri" in match Str.split (Str.regexp " ") mburi with | [root; buri] when HExtlib.is_prefix_of root path -> ":registry:", root, buri | _ -> raise (Helm_registry.Key_not_found "matita.baseuri") with Helm_registry.Key_not_found "matita.baseuri" -> let rootpath = find_root path in let data = HExtlib.input_file rootpath in let buri = let lines = Str.split (Str.regexp "\n") data in let lines = List.map (fun l -> match Str.split (Str.regexp "=") l with | [k;v] -> Pcre.replace ~pat:" " k, Pcre.replace ~pat:" " v | _ -> raise (Failure ("Malformed root file: " ^ rootpath))) lines in List.assoc "baseuri" lines in rootpath, Filename.dirname rootpath, buri in (* HLog.debug ("file "^file^" rooted by "^rootpath^""); *) let uri = Http_getter_misc.strip_trailing_slash buri in if String.length uri < 5 || String.sub uri 0 5 <> "cic:/" then HLog.error (rootpath ^ " sets an incorrect baseuri: " ^ buri); ensure_trailing_slash root, remove_trailing_slash uri, path ;; let baseuri_of_script ?(include_paths=[]) file = let root, buri, path = find_root_for ~include_paths file in let path = HExtlib.normalize_path path in let root = HExtlib.normalize_path root in let lpath = Str.split (Str.regexp "/") path in let lroot = Str.split (Str.regexp "/") root in let rec substract l1 l2 = match l1, l2 with | h1::tl1,h2::tl2 when h1 = h2 -> substract tl1 tl2 | l,[] -> l | _ -> raise (NoRootFor file) in let extra_buri = substract lpath lroot in let chop name = assert(Filename.check_suffix name ".ma"); try Filename.chop_extension name with Invalid_argument "Filename.chop_extension" -> name in root, remove_trailing_slash (HExtlib.normalize_path (buri ^ "/" ^ chop (String.concat "/" extra_buri))), path ;; let find_roots_in_dir dir = HExtlib.find ~test:(fun f -> Filename.basename f = "root" && try (Unix.stat f).Unix.st_kind = Unix.S_REG with Unix.Unix_error _ -> false) dir ;;