X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=generator%2Fwrappi_c.ml;h=5a7366058b44a467db602a813ca756afa2892d76;hb=2c2b03cd99c55606d16e02b014a8a63055874867;hp=099a7c2c35d5594b3e5d3acf1ce02996965dbee9;hpb=0571e7d0a290a9c3e0f3880363d0f2dbe93fc616;p=wrappi.git diff --git a/generator/wrappi_c.ml b/generator/wrappi_c.ml index 099a7c2..5a73660 100644 --- a/generator/wrappi_c.ml +++ b/generator/wrappi_c.ml @@ -173,6 +173,50 @@ extern void wrap_close (wrap_h *w); pr "\ +/* C API introspection. */ +"; + iter_entry_points api ( + fun ep -> + let name = ep.ep_name in + let ret, req, opt = ep.ep_ftype in + + pr "struct wrap_%s_args {\n" name; + List.iter ( + fun (n, t, _) -> + let t = c_of_ptype ~param:true t in + let sep = (* "const char *" - omit space after asterisk *) + let len = String.length t in + if isalnum t.[len-1] then " " else "" in + pr " %s%s%s;\n" t sep n + ) req; + pr "};\n"; + pr "\n"; + + if opt <> [] then assert false; (* XXX not implemented *) + + pr "struct wrap_%s_ret {\n" name; + (match ret with + | RVoid -> () + | RStaticString -> pr " const char *r;\n"; + | Return t -> + let t = c_of_ptype ~param:false t in + let sep = (* "const char *" - omit space after asterisk *) + let len = String.length t in + if isalnum t.[len-1] then " " else "" in + pr " %s%sr;\n" t sep + ); + + pr "};\n"; + pr "\n"; + ); + + pr "\ +extern void wrap_call (wrap_h *w, const char *name, const void *args, void *ret); +extern size_t wrap_call_get_args_struct_size (wrap_h *w, const char *name); +extern size_t wrap_call_get_ret_struct_size (wrap_h *w, const char *name); +extern /* xdrproc_t */ void *wrap_call_get_args_xdrproc (wrap_h *w, const char *name); +extern /* xdrproc_t */ void *wrap_call_get_ret_xdrproc (wrap_h *w, const char *name); + #ifdef __cplusplus } #endif @@ -180,6 +224,126 @@ extern void wrap_close (wrap_h *w); #endif /* WRAPPI_H_ */ " +let generate_lib_call_c api = + generate_header inputs CStyle LGPLv2plus; + + pr "\ +#include + +#include + +#include \"wrappi.h\" +#include \"internal.h\" + +void +wrap_call (wrap_h *w, const char *name, const void *args, void *ret) +{ + int proc; + + proc = wrap_int_lookup_proc_entry (name); + if (proc == -1) { + set_error (\"procedure not found: %%s\", name); + return; + } + + /* This ends up calling wrap_int_call_. */ + wrap_int_proc_table[proc].call (w, args, ret); +} + +size_t +wrap_call_get_args_struct_size (wrap_h *w, const char *name) +{ + int proc; + + proc = wrap_int_lookup_proc_entry (name); + if (proc == -1) { + set_error (\"procedure not found: %%s\", name); + return 0; + } + + return wrap_int_proc_table[proc].args_struct_size; +} + +size_t +wrap_call_get_ret_struct_size (wrap_h *w, const char *name) +{ + int proc; + + proc = wrap_int_lookup_proc_entry (name); + if (proc == -1) { + set_error (\"procedure not found: %%s\", name); + return 0; + } + + return wrap_int_proc_table[proc].ret_struct_size; +} + +/* Really this returns xdrproc_t but we don't want to have to include + * XDR headers in the public API. + */ +void * +wrap_call_get_args_xdrproc (wrap_h *w, const char *name) +{ + int proc; + + proc = wrap_int_lookup_proc_entry (name); + if (proc == -1) { + set_error (\"procedure not found: %%s\", name); + return 0; + } + + return wrap_int_proc_table[proc].args_xdrproc; +} + +/* Really this returns xdrproc_t but we don't want to have to include + * XDR headers in the public API. + */ +void * +wrap_call_get_ret_xdrproc (wrap_h *w, const char *name) +{ + int proc; + + proc = wrap_int_lookup_proc_entry (name); + if (proc == -1) { + set_error (\"procedure not found: %%s\", name); + return 0; + } + + return wrap_int_proc_table[proc].ret_xdrproc; +} +"; + + iter_entry_points api ( + fun ep -> + pr "\n"; + + let name = ep.ep_name in + let ret, req, opt = ep.ep_ftype in + + pr "void\n"; + pr "wrap_int_call_%s (wrap_h *w, const void *argsv, void *retv)\n" name; + pr "{\n"; + if req <> [] || opt <> [] then + pr " const struct wrap_%s_args *args = argsv;\n" name; + if ret <> RVoid then + pr " struct wrap_%s_ret *ret = retv;\n" name; + pr "\n"; + + pr " "; + (match ret with + | RVoid -> () + | _ -> pr "ret->r = " + ); + + pr "wrap_%s (w" name; + List.iter (fun (n, _, _) -> pr ", args->%s" n) req; + + if opt <> [] then assert false; (* XXX not implemented *) + + pr ");\n"; + pr "}\n"; + ) + (* 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. @@ -188,6 +352,8 @@ let generate_lib_free_structs_c api = generate_header inputs CStyle LGPLv2plus; pr "\ +#include + #include #include \"wrappi.h\" @@ -226,4 +392,5 @@ let generate_lib_free_structs_c api = let generate api = output_to "lib/wrappi.h" generate_lib_wrappi_h api; + output_to "lib/call.c" generate_lib_call_c api; output_to "lib/free_structs.c" generate_lib_free_structs_c api