Remote protocol working.
[wrappi.git] / generator / wrappi_main.ml
index aaf3719..2b40ec2 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *)
 
+open Unix
 open Printf
 
-let eps = Wrappi_globals.get_entry_points ()
+open Wrappi_utils
+open Wrappi_types
+open Wrappi_pr
+
+let api = Wrappi_accumulator.get_api ()
+let nr_tds = StringMap.cardinal api.api_typedefs
+let nr_ens = StringMap.cardinal api.api_enums
+let nr_sds = StringMap.cardinal api.api_structs
+let nr_uns = StringMap.cardinal api.api_unions
+let nr_eps = StringMap.cardinal api.api_entry_points
+
+(* Extend the API with some entry points which are purely
+ * generated from other things, eg. from enums.
+ *)
+let api = Wrappi_enums.extend_api api
+let api = Wrappi_structs.extend_api api
 
 let dump_and_exit () =
-  printf "entry points:\n";
+  printf "typedefs (%d):\n" nr_tds;
+  iter_typedefs api (fun td -> printf "  %s\n" (string_of_typedef td));
+
+  printf "enums (%d):\n" nr_ens;
+  iter_enums api (fun en -> printf "  %s\n" (string_of_enum en));
 
-  List.iter (fun ep ->
-    printf "  %s\n" (Wrappi_types.string_of_entry_point ep)
-  ) eps;
+  printf "structs (%d):\n" nr_sds;
+  iter_structs api (fun sd -> printf "  %s\n" (string_of_struct sd));
+
+  printf "unions (%d):\n" nr_uns;
+  iter_unions api (fun un -> printf "  %s\n" (string_of_union un));
+
+  printf "entry points (%d):\n" nr_eps;
+  iter_entry_points api (fun ep -> printf "  %s\n" (string_of_entry_point ep));
 
   exit 0
 
@@ -37,11 +62,15 @@ let () =
   in
 
   let argspec = Arg.align [
-    "--dump", Arg.Unit dump_and_exit, " Dump API data and exit.";
-    "--version", Arg.Unit display_version, " Display version number and exit.";
+    "--dump", Arg.Unit dump_and_exit, " Dump API data and exit";
+    "--version", Arg.Unit display_version, " Display version number and exit";
   ] in
   let anon_fun str = raise (Arg.Bad "generator: unknown parameter") in
-  let usage_msg = "wrappi generator: generates lots of code
+  let usage_msg = "
+NAME
+  wrappi generator - generate a lot of code
+
+SYNOPSIS
 
 To run the generator normally (note it MUST be run from the top
 level SOURCE directory):
@@ -55,5 +84,51 @@ Options are for debugging only:
 OPTIONS" in
   Arg.parse argspec anon_fun usage_msg
 
+let perror msg = function
+  | Unix_error (err, _, _) ->
+      eprintf "%s: %s\n" msg (error_message err)
+  | exn ->
+      eprintf "%s: %s\n" msg (Printexc.to_string exn)
+
 let () =
-  printf "generator, %d entry points\n" (List.length eps)
+  printf "generator, %d typedefs, %d enums, %d structs, %d unions, %d entry points\n"
+    nr_tds nr_ens nr_sds nr_uns nr_eps;
+
+  (* Acquire a lock so parallel builds won't run the generator
+   * simultaneously.  It's assumed that ./configure.ac only exists in
+   * the top level source directory.  Note the lock is released
+   * implicitly when the program exits.
+   *)
+  let lock_fd =
+    try openfile "configure.ac" [O_RDWR] 0
+    with
+    | Unix_error (ENOENT, _, _) ->
+      eprintf "\
+You are probably running this from the wrong directory.
+Run it from the top source directory using the command
+  make -C generator stamp-generator
+";
+      exit 1
+    | exn ->
+      perror "open: configure.ac" exn;
+      exit 1 in
+
+  (try lockf lock_fd F_LOCK 1
+   with exn ->
+     perror "lock: configure.ac" exn;
+     exit 1);
+
+  (* Generate code. *)
+  Wrappi_c_impl.generate api;
+  Wrappi_c_xdr.generate api;
+  Wrappi_c.generate api;
+
+  printf "generated %d lines of code in %d files\n"
+    (get_lines_generated ()) (List.length (get_files_generated ()));
+
+  (* Create the stamp file last and unconditionally.  This is used
+   * by the Makefile to know when we must rerun the generator.
+   *)
+  let chan = open_out "generator/stamp-generator" in
+  fprintf chan "1\n";
+  close_out chan