Remote protocol working.
[wrappi.git] / generator / wrappi_main.ml
1 (* wrappi
2  * Copyright (C) 2011 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *)
18
19 open Unix
20 open Printf
21
22 open Wrappi_utils
23 open Wrappi_types
24 open Wrappi_pr
25
26 let api = Wrappi_accumulator.get_api ()
27 let nr_tds = StringMap.cardinal api.api_typedefs
28 let nr_ens = StringMap.cardinal api.api_enums
29 let nr_sds = StringMap.cardinal api.api_structs
30 let nr_uns = StringMap.cardinal api.api_unions
31 let nr_eps = StringMap.cardinal api.api_entry_points
32
33 (* Extend the API with some entry points which are purely
34  * generated from other things, eg. from enums.
35  *)
36 let api = Wrappi_enums.extend_api api
37 let api = Wrappi_structs.extend_api api
38
39 let dump_and_exit () =
40   printf "typedefs (%d):\n" nr_tds;
41   iter_typedefs api (fun td -> printf "  %s\n" (string_of_typedef td));
42
43   printf "enums (%d):\n" nr_ens;
44   iter_enums api (fun en -> printf "  %s\n" (string_of_enum en));
45
46   printf "structs (%d):\n" nr_sds;
47   iter_structs api (fun sd -> printf "  %s\n" (string_of_struct sd));
48
49   printf "unions (%d):\n" nr_uns;
50   iter_unions api (fun un -> printf "  %s\n" (string_of_union un));
51
52   printf "entry points (%d):\n" nr_eps;
53   iter_entry_points api (fun ep -> printf "  %s\n" (string_of_entry_point ep));
54
55   exit 0
56
57 (* Parse command line arguments. *)
58 let () =
59   let display_version () =
60     printf "%s %s\n" Config.package_name Config.package_version;
61     exit 0
62   in
63
64   let argspec = Arg.align [
65     "--dump", Arg.Unit dump_and_exit, " Dump API data and exit";
66     "--version", Arg.Unit display_version, " Display version number and exit";
67   ] in
68   let anon_fun str = raise (Arg.Bad "generator: unknown parameter") in
69   let usage_msg = "
70 NAME
71   wrappi generator - generate a lot of code
72
73 SYNOPSIS
74
75 To run the generator normally (note it MUST be run from the top
76 level SOURCE directory):
77
78   ./generator/generator
79
80 Options are for debugging only:
81
82   ./generator/generator [--options]
83
84 OPTIONS" in
85   Arg.parse argspec anon_fun usage_msg
86
87 let perror msg = function
88   | Unix_error (err, _, _) ->
89       eprintf "%s: %s\n" msg (error_message err)
90   | exn ->
91       eprintf "%s: %s\n" msg (Printexc.to_string exn)
92
93 let () =
94   printf "generator, %d typedefs, %d enums, %d structs, %d unions, %d entry points\n"
95     nr_tds nr_ens nr_sds nr_uns nr_eps;
96
97   (* Acquire a lock so parallel builds won't run the generator
98    * simultaneously.  It's assumed that ./configure.ac only exists in
99    * the top level source directory.  Note the lock is released
100    * implicitly when the program exits.
101    *)
102   let lock_fd =
103     try openfile "configure.ac" [O_RDWR] 0
104     with
105     | Unix_error (ENOENT, _, _) ->
106       eprintf "\
107 You are probably running this from the wrong directory.
108 Run it from the top source directory using the command
109   make -C generator stamp-generator
110 ";
111       exit 1
112     | exn ->
113       perror "open: configure.ac" exn;
114       exit 1 in
115
116   (try lockf lock_fd F_LOCK 1
117    with exn ->
118      perror "lock: configure.ac" exn;
119      exit 1);
120
121   (* Generate code. *)
122   Wrappi_c_impl.generate api;
123   Wrappi_c_xdr.generate api;
124   Wrappi_c.generate api;
125
126   printf "generated %d lines of code in %d files\n"
127     (get_lines_generated ()) (List.length (get_files_generated ()));
128
129   (* Create the stamp file last and unconditionally.  This is used
130    * by the Makefile to know when we must rerun the generator.
131    *)
132   let chan = open_out "generator/stamp-generator" in
133   fprintf chan "1\n";
134   close_out chan