Remote protocol working.
[wrappi.git] / generator / wrappi_enums.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 Camlp4.PreCast
20
21 open Wrappi_types
22 open Wrappi_utils
23
24 open Printf
25
26 let extend_api api =
27   let eps = ref api.api_entry_points in
28
29   iter_enums api (
30     fun en ->
31       let name = en.en_name in
32
33       (* Add an entry point wrap_<name>_enum_to_string. *)
34       let fname = sprintf "%s_enum_to_string" name in
35       let code =
36         let b = Buffer.create 512 in
37         bprintf b "  switch (v) {\n";
38         Array.iter (
39           fun id ->
40             bprintf b "  case WRAP_%s_%s: return \"%s\";\n"
41               (String.uppercase name) (String.uppercase id) id;
42         ) en.en_identifiers;
43         bprintf b "  default:\n";
44         bprintf b "    set_error (\"unknown enum case %%d\", v);\n";
45         bprintf b "    return NULL;\n";
46         bprintf b "  }\n";
47         Buffer.contents b in
48       let c_code = {
49         cc_loc = Loc.ghost;
50         cc_code = code;
51       } in
52       let ep = {
53         ep_loc = Loc.ghost;
54         ep_local = true;
55         ep_name = fname;
56         ep_ftype = RStaticString, ["v", TEnum name, None], [];
57         ep_code = Some c_code;
58         ep_includes = []
59       } in
60
61       eps := StringMap.add fname ep !eps;
62
63       (* Add an entry point wrap_<name>_string_to_enum. *)
64       let fname = sprintf "%s_string_to_enum" name in
65       let code =
66         let b = Buffer.create 512 in
67         Array.iter (
68           fun id ->
69             bprintf b "  if (STREQ (v, \"%s\"))\n" id;
70             bprintf b "    return WRAP_%s_%s;\n"
71               (String.uppercase name) (String.uppercase id);
72         ) en.en_identifiers;
73         bprintf b "  set_error (\"unknown enum case %%s\", v);\n";
74         bprintf b "  return -1;\n";
75         Buffer.contents b in
76       let c_code = {
77         cc_loc = Loc.ghost;
78         cc_code = code;
79       } in
80       let ep = {
81         ep_loc = Loc.ghost;
82         ep_local = true;
83         ep_name = fname;
84         ep_ftype = Return (TEnum name), ["v", TString, None], [];
85         ep_code = Some c_code;
86         ep_includes = []
87       } in
88
89       eps := StringMap.add fname ep !eps;
90
91       (* Add an entry point wrap_<name>_enum_nr. *)
92       let fname = sprintf "%s_enum_nr" name in
93       let code = sprintf "  return %d;\n" (Array.length en.en_identifiers) in
94       let c_code = {
95         cc_loc = Loc.ghost;
96         cc_code = code;
97       } in
98       let ep = {
99         ep_loc = Loc.ghost;
100         ep_local = true;
101         ep_name = fname;
102         ep_ftype = Return TInt, [], [];
103         ep_code = Some c_code;
104         ep_includes = []
105       } in
106
107       eps := StringMap.add fname ep !eps;
108   );
109
110   { api with api_entry_points = !eps }