Remote protocol working.
[wrappi.git] / generator / wrappi_c_impl.ml
index 2b08eb4..0b4b3a3 100644 (file)
@@ -182,8 +182,8 @@ pr "\
 
     pr "  } else {\n";
     pr "    /* Remote connection. */\n";
-    pr "    struct wrap_int_%s_args args;\n" name;
-    pr "    struct wrap_int_%s_ret ret;\n" name;
+    pr "    struct wrap_%s_args args;\n" name;
+    pr "    struct wrap_%s_ret ret;\n" name;
     pr "\n";
     List.iter (fun (n, _, _) -> pr "    args.%s = %s;\n" n n) req;
 
@@ -236,89 +236,84 @@ enum {
   pr "#define wrap_int_nr_procs %d\n" (StringMap.cardinal api.api_entry_points);
 
   pr "\n";
+  pr "#endif /* WRAPPI_INTERNAL_PROCS_H_ */\n"
+
+let generate_lib_internal_procs_c api =
+  generate_header inputs CStyle LGPLv2plus;
 
   pr "\
-/* These structures are used as the first stage of marshalling
- * arguments and return types of entry points.  It is much more
- * convenient to be able to pass around one of these structs,
- * than to have to pass a variable list of arguments.  They must
- * not be exposed externally.
- */
+#include <config.h>
+
+#include <stdlib.h>
+
+#include \"wrappi.h\"
+#include \"internal.h\"
+
+/* Defined in lib/call.c */
 ";
 
   iter_entry_points api (
     fun ep ->
-      let name = ep.ep_name in
-      let ret, req, opt = ep.ep_ftype in
-
-      pr "struct wrap_int_%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";
+      pr "extern void wrap_int_call_%s (wrap_h *w, const void *args, void *ret);\n" ep.ep_name
+  );
+  pr "\n";
 
-      if opt <> [] then assert false; (* XXX not implemented *)
-
-      pr "struct wrap_int_%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 "/* Defined in lib/xdr.c */\n";
+
+  iter_entry_points api (
+    fun ep ->
+      let name = ep.ep_name in
+      pr "extern bool_t wrap_int_xdr_%s_args (XDR *, struct wrap_%s_args *);\n" name name;
+      pr "extern bool_t wrap_int_xdr_%s_ret (XDR *, struct wrap_%s_ret *);\n" name name
   );
+  pr "\n";
+
+  pr "const struct proc_table wrap_int_proc_table[] = {\n";
 
   iter_entry_points api (
     fun ep ->
-      if not ep.ep_local then (
-        let name = ep.ep_name in
-        pr "extern bool_t wrap_int_xdr_%s_args (XDR *, struct wrap_int_%s_args *);\n" name name;
-        pr "extern bool_t wrap_int_xdr_%s_ret (XDR *, struct wrap_int_%s_ret *);\n" name name
-      )
+      let name = ep.ep_name in
+      pr "  [wrap_int_%s_num] = {\n" name;
+      pr "    .name = \"%s\",\n" name;
+      pr "    .args_struct_size = sizeof (struct wrap_%s_args),\n" name;
+      pr "    .ret_struct_size = sizeof (struct wrap_%s_ret),\n" name;
+      pr "    .call = &wrap_int_call_%s,\n" name;
+      pr "    .args_xdrproc = (xdrproc_t) &wrap_int_xdr_%s_args,\n" name;
+      pr "    .ret_xdrproc = (xdrproc_t) &wrap_int_xdr_%s_ret,\n" name;
+      pr "  },\n"
   );
 
-  pr "\n";
-  pr "#endif /* WRAPPI_INTERNAL_PROCS_H_ */\n"
+  pr "};\n"
 
-let generate_lib_internal_procs_c api =
+let generate_lib_internal_procs_lookup_gperf api =
   generate_header inputs CStyle LGPLv2plus;
 
   pr "\
+%%language=ANSI-C
+%%define lookup-function-name wrap_int_gperf_lookup_proc_entry
+%%readonly-tables
+%%null-strings
+
+%%{
+#include <config.h>
+
 #include <stdlib.h>
+#include <string.h>
 
 #include \"wrappi.h\"
 #include \"internal.h\"
+%%}
 
-";
+struct proc_entry;
 
-  pr "const struct proc_table wrap_int_proc_table[] = {\n";
+%%%%
+";
 
   iter_entry_points api (
     fun ep ->
       let name = ep.ep_name in
-      pr "  [wrap_int_%s_num] = {\n" name;
-      pr "    .name = \"%s\",\n" name;
-      if not ep.ep_local then (
-        pr "    .xdr_args = (xdrproc_t) &wrap_int_xdr_%s_args,\n" name;
-        pr "    .xdr_ret = (xdrproc_t) &wrap_int_xdr_%s_ret,\n" name;
-      );
-      pr "  },\n"
-  );
-
-  pr "};\n"
+      pr "%s, wrap_int_%s_num\n" name name
+  )
 
 (* Make a unique, reproducible filename for each entry point. *)
 let filename_of_ep ep =
@@ -377,6 +372,9 @@ let generate api =
   output_to "lib/internal-procs.c"
     generate_lib_internal_procs_c api;
 
+  output_to "lib/internal-procs-lookup.gperf"
+    generate_lib_internal_procs_lookup_gperf api;
+
   output_to "lib/implementation_files.mk"
     generate_lib_implementation_files_mk api;