Add more realistic type system.
[wrappi.git] / generator / wrappi_c.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 Wrappi_types
20 open Wrappi_utils
21 open Wrappi_pr
22 open Wrappi_boilerplate
23
24 open Printf
25
26 let c_of_ptype ~param = function
27   | TBool -> "int"
28   | TBuffer -> assert false (* XXX not implemented *)
29   | TEnum name -> sprintf "enum wrap_%s" name
30   | TFile -> if param then "const char *" else "char *"
31   | THash t -> if param then "char * const *" else "char **"
32   | TInt -> "intXXX" (* XXX depends on preconditions *)
33   | TInt32 -> "int32_t"
34   | TInt64 -> "int64_t"
35   | TList t -> assert false (* XXX not implemented *)
36   | TNullable TString -> if param then "const char *" else "char *"
37   | TNullable _ -> assert false (* XXX may be implemented in future *)
38   | TString -> if param then "const char *" else "char *"
39   | TStruct name -> sprintf "struct wrap_%s" name
40   | TTypedef name -> assert false (* should never happen *)
41   | TUInt32 -> "uint32_t"
42   | TUInt64 -> "uint64_t"
43   | TUnion name -> sprintf "union wrap_%s" name
44
45 let c_of_rtype = function
46   | RErr -> "int"
47   | Return t -> c_of_ptype ~param:false t
48
49 let generate_lib_wrappi_h api =
50   generate_header CStyle LGPLv2plus;
51
52   pr "\
53 /* Please read the wrappi(1) man page for full documentation.  If you
54  * are not familiar with man pages or don't have the documentation
55  * installed, it is also available online at http://wrappi.org/
56  */
57
58 #ifndef WRAPPI_H_
59 #define WRAPPI_H_
60
61 #ifdef __cplusplus
62 extern \"C\" {
63 #endif
64
65 #include <stdint.h>
66
67 /* The handle. */
68 typedef struct wrap_h wrap_h;
69
70 /* Connection management. */
71 extern wrap_h *wrap_create (void);
72 extern void wrap_close (wrap_h *w);
73
74 /* API entry points. */
75 ";
76
77   iter_entry_points api (
78     fun ep ->
79       let ret, req, opt = ep.ep_ftype in
80       pr "extern %s wrap_%s (wrap_h *w" (c_of_rtype ret) ep.ep_name;
81
82       (* Required parameters. *)
83       List.iter (
84         fun (name, t, _) ->
85           let t = c_of_ptype ~param:true t in
86           let sep = (* "const char *" - omit space after asterisk *)
87             let len = String.length t in
88             if isalnum t.[len-1] then " " else "" in
89           pr ", %s%s%s" t sep name
90       ) req;
91
92       (* Optional parameters. *)
93       if opt <> [] then
94         pr ", ...";
95
96       pr ");\n"
97
98   );
99
100   pr "\
101
102 #ifdef __cplusplus
103 }
104 #endif
105
106 #endif /* WRAPPI_H_ */
107 "
108
109 let generate api =
110   output_to "lib/wrappi.h" generate_lib_wrappi_h api