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