Begin generating C implementation code.
[wrappi.git] / generator / wrappi_c_impl.ml
diff --git a/generator/wrappi_c_impl.ml b/generator/wrappi_c_impl.ml
new file mode 100644 (file)
index 0000000..50673fc
--- /dev/null
@@ -0,0 +1,98 @@
+(* wrappi
+ * Copyright (C) 2011 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Camlp4.PreCast
+
+open Wrappi_utils
+open Wrappi_types
+open Wrappi_boilerplate
+open Wrappi_pr
+
+open Printf
+
+let generate_implementation ep =
+  generate_header CStyle LGPLv2plus;
+
+  pr "\
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include \"wrappi.h\"
+
+#include \"internal.h\"
+
+"
+
+  (* Depending on whether this is a local or remote function, include
+   * different definitions here.
+   *)
+  (*if ep.ep_local then ... *)
+
+(* Make a unique, reproducible filename for each entry point. *)
+let filename_of_ep ep =
+  let filename = Loc.file_name ep.ep_loc in
+  let filename = Filename.basename filename in
+  let filename =
+    try Filename.chop_extension filename
+    with Invalid_argument _ -> filename in
+  let filename = sprintf "%s-%s.c" filename ep.ep_name in
+  filename
+
+let generate_lib_implementation_files_mk api =
+  generate_header HashStyle GPLv2plus;
+
+  let eps = StringMap.bindings api.api_entry_points in
+  let cmp (a, _) (b, _) = compare a b in
+  let eps = List.sort cmp eps in
+  let eps = List.map snd eps in
+
+  let rec loop = function
+    | [] -> ()
+    | [ep] -> pr "\t%s\n" (filename_of_ep ep)
+    | ep :: eps -> pr "\t%s \\\n" (filename_of_ep ep); loop eps
+  in
+
+  pr "local_implementation_files := \\\n";
+
+  loop (List.filter (fun ep -> ep.ep_local) eps);
+
+  pr "\n";
+  pr "remote_implementation_files := \\\n";
+
+  loop (List.filter (fun ep -> not ep.ep_local) eps)
+
+let generate api =
+  let gitignores = ref [] in
+
+  iter_entry_points api (
+    fun ep ->
+      let filename = filename_of_ep ep in
+
+      gitignores := ("/" ^ filename) :: !gitignores;
+
+      output_to ("lib/" ^ filename) generate_implementation ep
+  );
+
+  let gitignores = List.rev !gitignores in
+  output_to "lib/.gitignore"
+    (fun () -> List.iter (pr "%s\n") gitignores) ();
+
+  output_to "lib/implementation_files.mk"
+    generate_lib_implementation_files_mk api