X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Focaml%2Fregistry%2Fhelm_registry.ml;h=0c7b437238d1e57c23a9d5bcf73d83d6e4fde2b1;hb=5325734bc2e4927ed7ec146e35a6f0f2b49f50c1;hp=969644b01a2f381c6c28a55439c392cc26c045d8;hpb=cd9181526a9d57eadeb4e7c1f6b7b440946fd432;p=helm.git diff --git a/helm/ocaml/registry/helm_registry.ml b/helm/ocaml/registry/helm_registry.ml index 969644b01..0c7b43723 100644 --- a/helm/ocaml/registry/helm_registry.ml +++ b/helm/ocaml/registry/helm_registry.ml @@ -69,6 +69,11 @@ let dot_rex = Str.regexp "\\." let spaces_rex = Str.regexp "[ \t\n\r]+" let heading_spaces_rex = Str.regexp "^[ \t\n\r]+" +let split s = + (* trailing blanks are removed per default by split *) + Str.split spaces_rex (Str.global_replace heading_spaces_rex "" s) +let merge l = String.concat " " l + (* escapes for xml configuration file *) let (escape, unescape) = let (in_enc, out_enc) = (`Enc_utf8, `Enc_utf8) in @@ -93,6 +98,8 @@ let set' registry ~key ~value = value_is_valid ~key ~value; Hashtbl.replace 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) @@ -135,12 +142,6 @@ let get key = let set = set' registry -let string_list_of_string s = - (* trailing blanks are removed per default by split *) -(* Pcre.split ~res:spaces_rex (Pcre.replace ~rex:heading_spaces_rex s) *) - Str.split spaces_rex (Str.global_replace heading_spaces_rex "" s) -let string_of_string_list l = String.concat " " l - let mk_get_set type_name (from_string: string -> 'a) (to_string: 'a -> string) = let getter key = let value = get key in @@ -155,44 +156,101 @@ let mk_get_set type_name (from_string: string -> 'a) (to_string: 'a -> string) = let (get_string, set_string) = (get, set) let (get_int, set_int) = mk_get_set "int" int_of_string string_of_int let (get_float, set_float) = mk_get_set "float" float_of_string string_of_float -let (get_string_list, set_string_list) = - mk_get_set "string list" string_list_of_string string_of_string_list - -(* -let save_to = - let dtd = new dtd default_config.warner `Enc_utf8 in - let rec create_key node sections key value = - match sections with - | [] -> create_element_node ~valcheck:false default_spec dtd -*) +let (get_bool, set_bool) = mk_get_set "bool" bool_of_string string_of_bool +let (get_string_list, set_string_list) = mk_get_set "string list" split merge -let save_to fname = - debug_print ("Saving configuration to " ^ fname); - let oc = open_out fname in - output_string oc "\n"; - output_string oc "\n"; +let get_opt getter key = try - Hashtbl.iter - (fun key value -> - fprintf oc " %s\n" key (escape value)) - registry; - output_string oc ""; - close_out oc - with e -> - close_out oc; - raise e + Some (getter key) + with Key_not_found _ -> None +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 Hashtbl.add validators key (validator, descr); id +open Pxp_dtd open Pxp_document open Pxp_types open Pxp_yacc +let save_to = + 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 value *) + let element = + create_element_node ~valcheck:false PxpHelmConf.pxp_spec dtd "key" ["name", key] + in + let data = create_data_node PxpHelmConf.pxp_spec dtd value in + element#append_node data; + element + in + let is_section name = + fun node -> + match node#node_type with + | T_element "section" -> + (try node#attribute "name" = Value name with Not_found -> false) + | _ -> false + in + let add_key_node root sections key value = + let rec aux node = function + | [] -> + let key_node = create_key_node key value in + node#append_node key_node + | section :: tl -> + let next_node = + try + find ~deeply:false (is_section section) node + with Not_found -> + let section_node = + create_element_node ~valcheck:false PxpHelmConf.pxp_spec dtd + "section" ["name", section] + in + node#append_node section_node; + section_node + in + aux next_node tl + in + aux root sections + in + fun fname -> + let xml_root = + create_element_node ~valcheck:false PxpHelmConf.pxp_spec dtd "helm_registry" [] + in + Hashtbl.iter + (fun key value -> + let sections, key = + let hd, tl = + match List.rev (Str.split dot_RE key) with + | hd :: tl -> hd, tl + | _ -> assert false + in + List.rev tl, hd + in + add_key_node xml_root sections key value) + registry; + let outchan = (* let's write xml output to fname *) + if Unix.system "xmllint --version &> /dev/null" = Unix.WEXITED 0 then + (* xmllint available, use it! *) + Unix.open_process_out (sprintf + "xmllint --format --encode utf8 -o '%s' -" fname) + else + (* xmllint not available, write pxp ugly output directly to fname *) + open_out fname + in + xml_root#write (`Out_channel outchan) `Enc_utf8; + 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 @@ -202,7 +260,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 ->