+type typedef = {
+ td_loc : Camlp4.PreCast.Loc.t;
+ td_name : string;
+ td_type : ptype;
+}
+
+type enum = {
+ en_loc : Camlp4.PreCast.Loc.t;
+ en_name : string;
+ en_identifiers : string array;
+}
+
+type struct_decl = {
+ sd_loc : Camlp4.PreCast.Loc.t;
+ sd_name : string;
+ sd_identifiers : string array;
+ sd_fields : ptype array;
+}
+
+type union = {
+ un_loc : Camlp4.PreCast.Loc.t;
+ un_name : string;
+ un_identifiers : string array;
+ un_fields : ptype array;
+}
+
+type api = {
+ api_typedefs : typedef StringMap.t;
+ api_enums : enum StringMap.t;
+ api_structs : struct_decl StringMap.t;
+ api_unions : union StringMap.t;
+ api_entry_points : entry_point StringMap.t;
+}
+
+let iter xs f =
+ let xs = StringMap.bindings xs in
+ let cmp (a, _) (b, _) = compare a b in
+ let xs = List.sort cmp xs in
+ List.iter (fun (_, x) -> f x) xs
+
+let iter_typedefs { api_typedefs = tds } f = iter tds f
+let iter_enums { api_enums = ens } f = iter ens f
+let iter_structs { api_structs = sds } f = iter sds f
+let iter_unions { api_unions = uns } f = iter uns f
+let iter_entry_points { api_entry_points = eps } f = iter eps f
+
+let rec string_of_ptype = function
+ | TBool -> "bool"
+ | TBuffer -> "buffer"
+ | TEnum name -> sprintf "enum %s" name
+ | TFile -> "file"
+ | THash t -> sprintf "hash(%s)" (string_of_ptype t)
+ | TInt -> "int"