widl: Marshal and unmarshal basic types.
[wine.git] / tools / widl / typegen.c
blob8883b3f712a4781bfb85aa5855c23bf893ccd495
1 /*
2 * Format String Generator for IDL Compiler
4 * Copyright 2005 Eric Kohl
5 * Copyright 2005 Robert Shearman
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
23 #include "wine/port.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #ifdef HAVE_UNISTD_H
28 # include <unistd.h>
29 #endif
30 #include <string.h>
31 #include <assert.h>
32 #include <ctype.h>
33 #include <signal.h>
35 #include "widl.h"
36 #include "utils.h"
37 #include "parser.h"
38 #include "header.h"
39 #include "windef.h"
41 #include "widl.h"
43 static int print_file(FILE *file, int indent, const char *format, ...)
45 va_list va;
46 int i, r;
48 va_start(va, format);
49 for (i = 0; i < indent; i++)
50 fprintf(file, " ");
51 r = vfprintf(file, format, va);
52 va_end(va);
53 return r;
56 static void write_procformatstring_var(FILE *file, int indent, var_t *var)
58 switch(var->type->type)
60 #define CASE_BASETYPE(fctype) \
61 case RPC_##fctype: \
62 print_file(file, indent, "0x%02x, /* " #fctype " */\n", var->type->type); \
63 break
65 CASE_BASETYPE(FC_BYTE);
66 CASE_BASETYPE(FC_CHAR);
67 CASE_BASETYPE(FC_WCHAR);
68 CASE_BASETYPE(FC_USHORT);
69 CASE_BASETYPE(FC_SHORT);
70 CASE_BASETYPE(FC_ULONG);
71 CASE_BASETYPE(FC_LONG);
72 CASE_BASETYPE(FC_HYPER);
73 CASE_BASETYPE(FC_IGNORE);
74 CASE_BASETYPE(FC_SMALL);
75 CASE_BASETYPE(FC_FLOAT);
76 CASE_BASETYPE(FC_DOUBLE);
77 #undef CASE_BASETYPE
78 default:
79 error("Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
83 void write_procformatstring(FILE *file, type_t *iface)
85 int indent = 0;
86 func_t *func = iface->funcs;
87 var_t *var;
89 print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
90 print_file(file, indent, "{\n");
91 indent++;
92 print_file(file, indent, "0,\n");
93 print_file(file, indent, "{\n");
94 indent++;
96 while (NEXT_LINK(func)) func = NEXT_LINK(func);
97 while (func)
99 /* emit argument data */
100 if (func->args)
102 var = func->args;
103 while (NEXT_LINK(var)) var = NEXT_LINK(var);
104 while (var)
106 print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
107 write_procformatstring_var(file, indent, var);
108 var = PREV_LINK(var);
112 /* emit return value data */
113 var = func->def;
114 if (is_void(var->type, NULL))
116 print_file(file, indent, "0x5b, /* FC_END */\n");
117 print_file(file, indent, "0x5c, /* FC_PAD */\n");
119 else
121 print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
122 write_procformatstring_var(file, indent, var);
125 func = PREV_LINK(func);
128 print_file(file, indent, "0x0\n");
129 indent--;
130 print_file(file, indent, "}\n");
131 indent--;
132 print_file(file, indent, "};\n");
133 print_file(file, indent, "\n");
137 void write_typeformatstring(FILE *file)
139 int indent = 0;
140 print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
141 print_file(file, indent, "{\n");
142 indent++;
143 print_file(file, indent, "0,\n");
144 print_file(file, indent, "{\n");
145 indent++;
146 print_file(file, indent, "NdrFcShort(0x0),\n");
147 print_file(file, indent, "0x0\n");
148 indent--;
149 print_file(file, indent, "}\n");
150 indent--;
151 print_file(file, indent, "};\n");
152 print_file(file, indent, "\n");
156 unsigned int get_required_buffer_size(type_t *type)
158 switch(type->type)
160 case RPC_FC_BYTE:
161 case RPC_FC_CHAR:
162 case RPC_FC_WCHAR:
163 case RPC_FC_USHORT:
164 case RPC_FC_SHORT:
165 case RPC_FC_ULONG:
166 case RPC_FC_LONG:
167 case RPC_FC_FLOAT:
168 case RPC_FC_IGNORE:
169 case RPC_FC_ERROR_STATUS_T:
170 return 4;
172 case RPC_FC_HYPER:
173 case RPC_FC_DOUBLE:
174 return 8;
176 default:
177 error("Unknown/unsupported type: %s (0x%02x)\n", type->name, type->type);
178 return 0;
182 void marshall_arguments(FILE *file, int indent, func_t *func)
184 unsigned int alignment;
185 unsigned int size;
186 unsigned int last_size = 0;
187 var_t *var;
189 if (!func->args)
190 return;
192 var = func->args;
193 while (NEXT_LINK(var)) var = NEXT_LINK(var);
194 while (var)
196 alignment = 0;
197 switch (var->type->type)
199 case RPC_FC_BYTE:
200 case RPC_FC_CHAR:
201 size = 1;
202 alignment = 0;
203 break;
205 case RPC_FC_WCHAR:
206 case RPC_FC_USHORT:
207 case RPC_FC_SHORT:
208 size = 2;
209 if (last_size != 0 && last_size < 2)
210 alignment = (2 - last_size);
211 break;
213 case RPC_FC_ULONG:
214 case RPC_FC_LONG:
215 case RPC_FC_FLOAT:
216 case RPC_FC_ERROR_STATUS_T:
217 size = 4;
218 if (last_size != 0 && last_size < 4)
219 alignment = (4 - last_size);
220 break;
222 case RPC_FC_HYPER:
223 case RPC_FC_DOUBLE:
224 size = 8;
225 if (last_size != 0 && last_size < 4)
226 alignment = (4 - last_size);
227 break;
229 default:
230 size = 0;
231 error("Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
234 if (alignment != 0)
235 print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment);
237 print_file(file, indent, "*((");
238 write_type(file, var->type, var, var->tname);
239 fprintf(file, " __RPC_FAR*)_StubMsg.Buffer)++ = ");
240 write_name(file, var);
241 fprintf(file, ";\n");
242 fprintf(file, "\n");
244 last_size = size;
246 var = PREV_LINK(var);
250 void unmarshall_arguments(FILE *file, int indent, func_t *func)
252 unsigned int alignment;
253 unsigned int size;
254 unsigned int last_size = 0;
255 var_t *var;
257 if (!func->args)
258 return;
260 var = func->args;
261 while (NEXT_LINK(var)) var = NEXT_LINK(var);
262 while (var)
264 alignment = 0;
265 switch (var->type->type)
267 case RPC_FC_BYTE:
268 case RPC_FC_CHAR:
269 size = 1;
270 alignment = 0;
271 break;
273 case RPC_FC_WCHAR:
274 case RPC_FC_USHORT:
275 case RPC_FC_SHORT:
276 size = 2;
277 if (last_size != 0 && last_size < 2)
278 alignment = (2 - last_size);
279 break;
281 case RPC_FC_ULONG:
282 case RPC_FC_LONG:
283 case RPC_FC_FLOAT:
284 case RPC_FC_ERROR_STATUS_T:
285 size = 4;
286 if (last_size != 0 && last_size < 4)
287 alignment = (4 - last_size);
288 break;
290 case RPC_FC_HYPER:
291 case RPC_FC_DOUBLE:
292 size = 8;
293 if (last_size != 0 && last_size < 4)
294 alignment = (4 - last_size);
295 break;
297 default:
298 size = 0;
299 error("Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
302 if (alignment != 0)
303 print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment);
305 print_file(file, indent, "");
306 write_name(file, var);
307 fprintf(file, " = *((");
308 write_type(file, var->type, var, var->tname);
309 fprintf(file, " __RPC_FAR*)_StubMsg.Buffer)++;\n");
310 fprintf(file, "\n");
312 last_size = size;
314 var = PREV_LINK(var);