]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/registry/helm_registry.ml
ported to latest ocaml-http API
[helm.git] / helm / ocaml / registry / helm_registry.ml
index 5569165a3591c96821da3377140bcc8ee2966967..10639e0899d82a6daf702f8623bb2dec5743e931 100644 (file)
@@ -29,6 +29,34 @@ let debug = false
 let debug_print s =
   if debug then prerr_endline ("Helm_registry debugging: " ^ s)
 
+  (** <helpers> *)
+
+let list_uniq l =
+  let rec aux last_element = function
+    | [] -> []
+    | hd :: tl ->
+        (match last_element with
+        | Some elt when elt = hd -> aux last_element tl
+        | _ -> hd :: aux (Some hd) tl)
+  in
+  aux None l
+
+let starts_with prefix =
+(*
+  let rex = Str.regexp (Str.quote prefix) in
+  fun s -> Str.string_match rex s 0
+*)
+  let prefix_len = String.length prefix in
+  fun s ->
+    try
+      String.sub s 0 prefix_len = prefix
+    with Invalid_argument _ -> false
+
+let hashtbl_keys tbl = Hashtbl.fold (fun k _ acc -> k :: acc) tbl []
+let hashtbl_pairs tbl = Hashtbl.fold (fun k v acc -> (k,v) :: acc) tbl []
+
+  (** </helpers> *)
+
 exception Malformed_key of string
 exception Key_not_found of string
 exception Cyclic_definition of string
@@ -81,7 +109,6 @@ let (escape, unescape) =
    Netencoding.Html.decode ~in_enc ~out_enc ~entity_base:`Xml ())
 
 let key_is_valid key =
-(*   if not (Pcre.pmatch ~rex:valid_key_rex key) then *)
   if not (Str.string_match valid_key_rex key 0) then
     raise (Malformed_key key)
 
@@ -101,7 +128,6 @@ let set' registry ~key ~value =
 let unset = Hashtbl.remove registry
 
 let env_var_of_key key =
-(*   Pcre.replace ~rex:dot_rex ~templ:"__" (String.uppercase key) *)
   Str.global_replace dot_rex "__" (String.uppercase key)
 
 let get key =
@@ -142,6 +168,8 @@ let get key =
 
 let set = set' registry
 
+let has key = Hashtbl.mem registry key
+
 let mk_get_set type_name (from_string: string -> 'a) (to_string: 'a -> string) =
   let getter key =
     let value = get key in
@@ -167,6 +195,10 @@ let set_opt setter ~key ~value =
   match value with
   | None -> unset key
   | Some value -> setter ~key ~value
+let get_opt_default getter default key =
+  match get_opt getter key with
+  | None -> default
+  | Some v -> v
 
 let add_validator ~key ~validator ~descr =
   let id = get_next_validator_id () in
@@ -179,13 +211,14 @@ open Pxp_types
 open Pxp_yacc
 
 let save_to =
-  let dtd = new dtd default_config.warner `Enc_utf8 in
+  let dtd = new dtd PxpHelmConf.pxp_config.warner `Enc_utf8 in
   let dot_RE = Str.regexp "\\." in
   let create_key_node key value = (* create a <key name="foo">value</key> *)
     let element =
-      create_element_node ~valcheck:false default_spec dtd "key" ["name", key]
+      create_element_node ~valcheck:false PxpHelmConf.pxp_spec dtd
+        "key" ["name", key]
     in
-    let data = create_data_node default_spec dtd value in
+    let data = create_data_node PxpHelmConf.pxp_spec dtd value in
     element#append_node data;
     element
   in
@@ -207,7 +240,7 @@ let save_to =
               find ~deeply:false (is_section section) node
             with Not_found ->
               let section_node =
-                create_element_node ~valcheck:false default_spec dtd
+                create_element_node ~valcheck:false PxpHelmConf.pxp_spec dtd
                   "section" ["name", section]
               in
               node#append_node section_node;
@@ -219,7 +252,7 @@ let save_to =
   in
   fun fname ->
     let xml_root =
-      create_element_node ~valcheck:false default_spec dtd "helm_registry" []
+      create_element_node ~valcheck:false PxpHelmConf.pxp_spec dtd "helm_registry" []
     in
     Hashtbl.iter
       (fun key value ->
@@ -246,7 +279,7 @@ let save_to =
       close_out outchan
 
 let load_from_absolute =
-  let config = default_config in
+  let config = PxpHelmConf.pxp_config in
   let entry = `Entry_document [ `Extend_dtd_fully; `Parse_xml_decl ] in
   let fold_key key_stack key =
     match key_stack with
@@ -256,7 +289,7 @@ let load_from_absolute =
   fun fname ->
     debug_print ("Loading configuration from " ^ fname);
     let document =
-      parse_wfdocument_entity config (from_file fname) default_spec
+      parse_wfdocument_entity config (from_file fname) PxpHelmConf.pxp_spec
     in
     let rec aux key_stack node =
       node#iter_nodes (fun n ->
@@ -306,6 +339,46 @@ let load_from ?path fname =
   end else
     load_from_absolute fname
 
+let fold ?prefix f init =
+  match prefix with
+  | None -> Hashtbl.fold (fun k v acc -> f acc k v) registry init
+  | Some s ->
+      let key_matches = starts_with (s ^ ".") in
+      let rec fold_filter acc = function
+        | [] -> acc
+        | (k,v) :: tl when key_matches k -> fold_filter (f acc k v) tl
+        | _ :: tl -> fold_filter acc tl
+      in
+      fold_filter init (hashtbl_pairs registry)
+
+let iter ?prefix f = fold ?prefix (fun _ k v -> f k v) ()
+let to_list ?prefix () = fold ?prefix (fun acc k v -> (k, v) :: acc) []
+
+let ls prefix =
+  let prefix = prefix ^ "." in
+  let prefix_len = String.length prefix in
+  let key_matches = starts_with prefix in
+  let matching_keys = (* collect matching keys' _postfixes_ *)
+    fold
+      (fun acc key _ ->
+        if key_matches key then
+          String.sub key prefix_len (String.length key - prefix_len) :: acc
+        else
+          acc)
+      []
+  in
+  let (sections, keys) =
+    List.fold_left
+      (fun (sections, keys) postfix ->
+        match Str.split dot_rex postfix with
+        | [key] -> (sections, key :: keys)
+        | hd_key :: _ ->  (* length > 1 => nested section found *)
+            (hd_key :: sections, keys)
+        | _ -> assert false)
+      ([], []) matching_keys
+  in
+  (list_uniq (List.sort Pervasives.compare sections), keys)
+
   (* DEBUGGING ONLY *)
 
 let dump () = Hashtbl.iter (fun k v -> printf "%s = %s\n" k v) registry