X-Git-Url: http://git.nguyen.vg/gitweb/?a=blobdiff_plain;f=tag.ml;fp=tag.ml;h=e5c382091f1fe6837ecb2a9be5046a1da3613be6;hb=c10ce35cd399aff15a49f3b24a31b38cb2191da0;hp=8c7769107e400eaee858205d0bfee9b7a613959c;hpb=6c60812f1f494f273d6074fcccf2707a6097cfaa;p=SXSI%2Fxpathcomp.git diff --git a/tag.ml b/tag.ml index 8c77691..e5c3820 100644 --- a/tag.ml +++ b/tag.ml @@ -5,93 +5,35 @@ (* Distributed under the terms of the LGPL (see LICENCE) *) (******************************************************************************) (* maybe utf8 string... *) -module T = -struct - type t = string - - (* special tag which denotes attribute nodes, should not be a valid - xml tag name *) - let attribute = "<@>" - (* Likewise for strings *) - let pcdata = "<$>" - - let compare : t -> t -> int = String.compare - - let hash (s:t) = - let rec loop acc = function - | -1 -> acc - | n -> loop (( acc lsl 6 ) + (acc lsl 16) - acc + (Char.code s.[n])) (n-1) - - in - loop 0 ((String.length s)-1) - - let equal x y = compare x y == 0 -end -module HMap = Map.Make (struct type t = int let compare x y = x - y end) -module HTag = -struct type t = int -let attribute = T.hash T.attribute -let pcdata = T.hash T.pcdata +type pool -let pool = ref HMap.empty +external null_pool : unit -> pool = "caml_xml_tree_nullt" +external null_tag : unit -> t = "caml_xml_tree_nullt" +external register_tag : pool -> string -> t = "caml_xml_tree_register_tag" +external tag_name : pool -> t -> string = "caml_xml_tree_tag_name" +let nullt = null_tag () +let pcdata = max_int +let attribute = max_int - 1 -let add_pool s = - let hash = T.hash s in - pool := HMap.add hash s !pool - -let clear_pool () = - pool := HMap.empty; - add_pool ""; - add_pool T.attribute; - add_pool T.pcdata - -let _ = clear_pool () +let pool = ref (null_pool ()) -let init l = - clear_pool () +let init p = pool := p -let tag s = - let hash = T.hash s in - try - let s' = HMap.find hash !pool - in - if s <> s' then - failwith (Printf.sprintf "hash conflict s1=%s, s2=%s, %i" s s' hash) - else hash - with - Not_found -> - add_pool s; - hash +let tag s = match s with + | "<$>" -> pcdata + | "<@>" -> attribute + | _ -> register_tag !pool s -let compare x y = x - y +let compare = (-) let equal = (==) -let hash t = T.hash t -let print fmt t = - Format.fprintf fmt "%s" ( - try - HMap.find t !pool - with - Not_found -> failwith (Printf.sprintf "%i not found!" t)) -let to_string x = HMap.find x !pool +let to_string t = + if t = pcdata then "<$>" + else if t = attribute then "<@>" + else tag_name !pool t -end -module STag = -struct - type t = string - let attribute = T.attribute - let pcdata = T.pcdata - external tag : string -> t = "%identity" - external clear_pool : unit -> unit = "%identity" - let init _ = () - let compare = String.compare - let equal = (=) - let print fmt s = Format.fprintf fmt "%s" s - external to_string : t -> string = "%identity" -end - -include STag +let print ppf t = Format.fprintf ppf "%s" (to_string t)