More implementation.
[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 -> "int" (* XXX not int, correct type 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   | RVoid -> "void"
47   | RStaticString -> "const char *"
48   | Return t -> c_of_ptype ~param:false t
49
50 (* Print the extern... declaration of a single entry point. *)
51 let pr_extern_decl ep =
52   let ret, req, opt = ep.ep_ftype in
53   pr "extern %s wrap_%s (wrap_h *w" (c_of_rtype ret) ep.ep_name;
54
55   (* Required parameters. *)
56   List.iter (
57     fun (name, t, _) ->
58       let t = c_of_ptype ~param:true t in
59       let sep = (* "const char *" - omit space after asterisk *)
60         let len = String.length t in
61         if isalnum t.[len-1] then " " else "" in
62       pr ", %s%s%s" t sep name
63   ) req;
64
65   (* Optional parameters. *)
66   if opt <> [] then
67     pr ", ...";
68
69   pr ");\n"
70
71 let generate_lib_wrappi_h api =
72   generate_header CStyle LGPLv2plus;
73
74   pr "\
75 /* Please read the wrappi(1) man page for full documentation.  If you
76  * are not familiar with man pages or don't have the documentation
77  * installed, it is also available online at http://wrappi.org/
78  */
79
80 #ifndef WRAPPI_H_
81 #define WRAPPI_H_
82
83 #ifdef __cplusplus
84 extern \"C\" {
85 #endif
86
87 #include <stdint.h>
88
89 /* The handle. */
90 typedef struct wrap_h wrap_h;
91
92 /* Connection management. */
93 extern wrap_h *wrap_create (void);
94 extern void wrap_close (wrap_h *w);
95
96 ";
97
98   (* Separate the local and remote functions. *)
99   pr "\
100 /* Handle functions. */
101 ";
102   iter_entry_points api (fun ep -> if ep.ep_local then pr_extern_decl ep);
103
104   pr "\
105
106 /* API entry points. */
107 ";
108   iter_entry_points api (fun ep -> if not ep.ep_local then pr_extern_decl ep);
109
110   pr "\
111
112 #ifdef __cplusplus
113 }
114 #endif
115
116 #endif /* WRAPPI_H_ */
117 "
118
119 let generate api =
120   output_to "lib/wrappi.h" generate_lib_wrappi_h api