| TNullable TString -> if param then "const char *" else "char *"
| TNullable _ -> assert false (* XXX may be implemented in future *)
| TString -> if param then "const char *" else "char *"
- | TStruct name -> sprintf "struct wrap_%s" name
+ | TStruct name ->
+ if param then sprintf "const struct wrap_%s *" name
+ else sprintf "struct wrap_%s *" name
| TTypedef name -> assert false (* should never happen *)
| TUInt32 -> "uint32_t"
| TUInt64 -> "uint64_t"
| RStaticString -> "const char *"
| Return t -> c_of_ptype ~param:false t
+let field_of_ptype = function
+ | TBool -> "int"
+ | TBuffer -> assert false (* XXX not implemented *)
+ | TEnum name -> sprintf "wrap_%s_enum" name
+ | TFile -> assert false (* cannot occur in a struct *)
+ | THash t -> "char **"
+ | TInt -> "int" (* XXX not int, correct type depends on preconditions *)
+ | TInt32 -> "int32_t"
+ | TInt64 -> "int64_t"
+ | TList t -> assert false (* XXX not implemented *)
+ | TNullable TString -> "char *"
+ | TNullable _ -> assert false (* XXX may be implemented in future *)
+ | TString -> "char *"
+ | TStruct name -> assert false (* we don't allow struct/union here *)
+ | TTypedef name -> assert false (* should never happen *)
+ | TUInt32 -> "uint32_t"
+ | TUInt64 -> "uint64_t"
+ | TUnion name -> assert false (* we don't allow struct/union here *)
+
(* Print the extern... declaration of a single entry point. *)
let pr_extern_decl ep =
let ret, req, opt = ep.ep_ftype in
pr "\n";
);
+ iter_structs api (
+ fun sd ->
+ let name = sd.sd_name in
+
+ pr "struct wrap_%s {\n" name;
+
+ Array.iter (
+ fun (name, t) ->
+ pr " %s %s;\n" (field_of_ptype t) name
+ ) sd.sd_fields;
+ pr "};\n";
+ pr "void wrap_free_%s (struct wrap_%s *);\n" name name;
+ pr "\n"
+ );
+
pr "\
/* Connection management. */
extern wrap_h *wrap_create (void);
#endif /* WRAPPI_H_ */
"
+(* Functions for freeing structs are part of the C bindings. We don't
+ * want them to be exposed in other languages, although they will be
+ * used by other bindings.
+ *)
+let generate_lib_free_structs_c api =
+ generate_header inputs CStyle LGPLv2plus;
+
+ pr "\
+#include <stdlib.h>
+
+#include \"wrappi.h\"
+";
+
+ iter_structs api (
+ fun sd ->
+ pr "\n";
+
+ let name = sd.sd_name in
+
+ pr "void\n";
+ pr "wrap_free_%s (struct wrap_%s *v)\n" name name;
+ pr "{\n";
+
+ Array.iter (
+ fun (n, t) ->
+ match t with
+ | TBool | TEnum _ | TInt | TInt32 | TInt64 | TUInt32 | TUInt64 ->
+ () (* these don't need to be freed *)
+ | TBuffer -> assert false (* XXX not implemented *)
+ | TFile
+ | TNullable TString
+ | TString ->
+ pr " free (v->%s);\n" n
+ | THash t -> assert false (* XXX not implemented *)
+ | TList t -> assert false (* XXX not implemented *)
+ | TNullable _ -> assert false (* XXX may be implemented in future *)
+ | TStruct name -> assert false (* cannot occur in structs *)
+ | TTypedef name -> assert false (* should never happen *)
+ | TUnion name -> assert false (* cannot occur in structs *)
+ ) sd.sd_fields;
+ pr " free (v);\n";
+ pr "}\n"
+ )
+
let generate api =
- output_to "lib/wrappi.h" generate_lib_wrappi_h api
+ output_to "lib/wrappi.h" generate_lib_wrappi_h api;
+ output_to "lib/free_structs.c" generate_lib_free_structs_c api