* 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
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):
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