Separate local and remote functions.
[wrappi.git] / generator / wrappi_c.ml
index f6e9afc..3011ab1 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *)
 
+open Wrappi_types
+open Wrappi_utils
 open Wrappi_pr
 open Wrappi_boilerplate
 
+open Printf
+
+let c_of_ptype ~param = function
+  | TBool -> "int"
+  | TBuffer -> assert false (* XXX not implemented *)
+  | TEnum name -> sprintf "enum wrap_%s" name
+  | TFile -> if param then "const char *" else "char *"
+  | THash t -> if param then "char * const *" else "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 -> 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
+  | TTypedef name -> assert false (* should never happen *)
+  | TUInt32 -> "uint32_t"
+  | TUInt64 -> "uint64_t"
+  | TUnion name -> sprintf "union wrap_%s" name
+
+let c_of_rtype = function
+  | RVoid -> "void"
+  | Return t -> c_of_ptype ~param:false t
+
+(* Print the extern... declaration of a single entry point. *)
+let pr_extern_decl ep =
+  let ret, req, opt = ep.ep_ftype in
+  pr "extern %s wrap_%s (wrap_h *w" (c_of_rtype ret) ep.ep_name;
+
+  (* Required parameters. *)
+  List.iter (
+    fun (name, 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" t sep name
+  ) req;
+
+  (* Optional parameters. *)
+  if opt <> [] then
+    pr ", ...";
+
+  pr ");\n"
+
 let generate_lib_wrappi_h api =
   generate_header CStyle LGPLv2plus;
 
   pr "\
+/* Please read the wrappi(1) man page for full documentation.  If you
+ * are not familiar with man pages or don't have the documentation
+ * installed, it is also available online at http://wrappi.org/
+ */
+
 #ifndef WRAPPI_H_
 #define WRAPPI_H_
 
@@ -30,10 +83,28 @@ let generate_lib_wrappi_h api =
 extern \"C\" {
 #endif
 
+#include <stdint.h>
+
+/* The handle. */
+typedef struct wrap_h wrap_h;
+
+/* Connection management. */
+extern wrap_h *wrap_create (void);
+extern void wrap_close (wrap_h *w);
+
 ";
 
+  (* Separate the local and remote functions. *)
+  pr "\
+/* Handle functions. */
+";
+  iter_entry_points api (fun ep -> if ep.ep_local then pr_extern_decl ep);
 
+  pr "\
 
+/* API entry points. */
+";
+  iter_entry_points api (fun ep -> if not ep.ep_local then pr_extern_decl ep);
 
   pr "\