widl: Avoid lvalue casts in generated code.
[wine/winequartzdrv.git] / tools / widl / typegen.c
blobcb6e87ba6873623a3c6116b7527903fe6c1d6027
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"
42 #include "typegen.h"
44 static int print_file(FILE *file, int indent, const char *format, ...)
46 va_list va;
47 int i, r;
49 va_start(va, format);
50 for (i = 0; i < indent; i++)
51 fprintf(file, " ");
52 r = vfprintf(file, format, va);
53 va_end(va);
54 return r;
57 static void write_procformatstring_var(FILE *file, int indent, var_t *var)
59 switch(var->type->type)
61 #define CASE_BASETYPE(fctype) \
62 case RPC_##fctype: \
63 print_file(file, indent, "0x%02x, /* " #fctype " */\n", var->type->type); \
64 break
66 CASE_BASETYPE(FC_BYTE);
67 CASE_BASETYPE(FC_CHAR);
68 CASE_BASETYPE(FC_WCHAR);
69 CASE_BASETYPE(FC_USHORT);
70 CASE_BASETYPE(FC_SHORT);
71 CASE_BASETYPE(FC_ULONG);
72 CASE_BASETYPE(FC_LONG);
73 CASE_BASETYPE(FC_HYPER);
74 CASE_BASETYPE(FC_IGNORE);
75 CASE_BASETYPE(FC_USMALL);
76 CASE_BASETYPE(FC_SMALL);
77 CASE_BASETYPE(FC_FLOAT);
78 CASE_BASETYPE(FC_DOUBLE);
79 CASE_BASETYPE(FC_ERROR_STATUS_T);
80 #undef CASE_BASETYPE
81 default:
82 error("Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
86 void write_procformatstring(FILE *file, type_t *iface)
88 int indent = 0;
89 func_t *func = iface->funcs;
90 var_t *var;
92 print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
93 print_file(file, indent, "{\n");
94 indent++;
95 print_file(file, indent, "0,\n");
96 print_file(file, indent, "{\n");
97 indent++;
99 while (NEXT_LINK(func)) func = NEXT_LINK(func);
100 while (func)
102 /* emit argument data */
103 if (func->args)
105 var = func->args;
106 while (NEXT_LINK(var)) var = NEXT_LINK(var);
107 while (var)
109 print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
110 write_procformatstring_var(file, indent, var);
111 var = PREV_LINK(var);
115 /* emit return value data */
116 var = func->def;
117 if (is_void(var->type, NULL))
119 print_file(file, indent, "0x5b, /* FC_END */\n");
120 print_file(file, indent, "0x5c, /* FC_PAD */\n");
122 else
124 print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
125 write_procformatstring_var(file, indent, var);
128 func = PREV_LINK(func);
131 print_file(file, indent, "0x0\n");
132 indent--;
133 print_file(file, indent, "}\n");
134 indent--;
135 print_file(file, indent, "};\n");
136 print_file(file, indent, "\n");
140 static void write_typeformatstring_var(FILE *file, int indent, var_t *var)
142 int ptr_level = var->ptr_level;
144 /* basic types don't need a type format string */
145 if (ptr_level == 0)
146 return;
148 if (ptr_level == 1)
150 switch (var->type->type)
152 #define CASE_BASETYPE(fctype) \
153 case RPC_##fctype: \
154 print_file(file, indent, "0x11, 0x08, /* FC_RP [simple_pointer] */\n"); \
155 print_file(file, indent, "0x%02x, /* " #fctype " */\n", var->type->type); \
156 print_file(file, indent, "0x5c, /* FC_PAD */\n"); \
157 break
158 CASE_BASETYPE(FC_BYTE);
159 CASE_BASETYPE(FC_CHAR);
160 CASE_BASETYPE(FC_SMALL);
161 CASE_BASETYPE(FC_USMALL);
162 CASE_BASETYPE(FC_WCHAR);
163 CASE_BASETYPE(FC_SHORT);
164 CASE_BASETYPE(FC_USHORT);
165 CASE_BASETYPE(FC_LONG);
166 CASE_BASETYPE(FC_ULONG);
167 CASE_BASETYPE(FC_FLOAT);
168 CASE_BASETYPE(FC_HYPER);
169 CASE_BASETYPE(FC_DOUBLE);
170 CASE_BASETYPE(FC_ENUM16);
171 CASE_BASETYPE(FC_ENUM32);
172 CASE_BASETYPE(FC_IGNORE);
173 CASE_BASETYPE(FC_ERROR_STATUS_T);
174 default:
175 error("write_typeformatstring_var: Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
180 void write_typeformatstring(FILE *file, type_t *iface)
182 int indent = 0;
183 func_t *func = iface->funcs;
184 var_t *var;
186 print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
187 print_file(file, indent, "{\n");
188 indent++;
189 print_file(file, indent, "0,\n");
190 print_file(file, indent, "{\n");
191 indent++;
192 print_file(file, indent, "NdrFcShort(0x0),\n");
194 while (NEXT_LINK(func)) func = NEXT_LINK(func);
195 while (func)
197 if (func->args)
199 var = func->args;
200 while (NEXT_LINK(var)) var = NEXT_LINK(var);
201 while (var)
203 write_typeformatstring_var(file, indent, var);
204 var = PREV_LINK(var);
207 func = PREV_LINK(func);
210 print_file(file, indent, "0x0\n");
211 indent--;
212 print_file(file, indent, "}\n");
213 indent--;
214 print_file(file, indent, "};\n");
215 print_file(file, indent, "\n");
219 unsigned int get_required_buffer_size(type_t *type)
221 switch(type->type)
223 case RPC_FC_BYTE:
224 case RPC_FC_CHAR:
225 case RPC_FC_WCHAR:
226 case RPC_FC_USHORT:
227 case RPC_FC_SHORT:
228 case RPC_FC_USMALL:
229 case RPC_FC_SMALL:
230 case RPC_FC_ULONG:
231 case RPC_FC_LONG:
232 case RPC_FC_FLOAT:
233 case RPC_FC_IGNORE:
234 case RPC_FC_ERROR_STATUS_T:
235 return 4;
237 case RPC_FC_HYPER:
238 case RPC_FC_DOUBLE:
239 return 8;
241 default:
242 error("Unknown/unsupported type: %s (0x%02x)\n", type->name, type->type);
243 return 0;
247 void marshall_arguments(FILE *file, int indent, func_t *func)
249 unsigned int alignment;
250 unsigned int size;
251 unsigned int last_size = 0;
252 var_t *var;
254 if (!func->args)
255 return;
257 var = func->args;
258 while (NEXT_LINK(var)) var = NEXT_LINK(var);
259 while (var)
261 alignment = 0;
262 switch (var->type->type)
264 case RPC_FC_BYTE:
265 case RPC_FC_CHAR:
266 case RPC_FC_SMALL:
267 case RPC_FC_USMALL:
268 size = 1;
269 alignment = 0;
270 break;
272 case RPC_FC_WCHAR:
273 case RPC_FC_USHORT:
274 case RPC_FC_SHORT:
275 size = 2;
276 if (last_size != 0 && last_size < 2)
277 alignment = (2 - last_size);
278 break;
280 case RPC_FC_ULONG:
281 case RPC_FC_LONG:
282 case RPC_FC_FLOAT:
283 case RPC_FC_ERROR_STATUS_T:
284 size = 4;
285 if (last_size != 0 && last_size < 4)
286 alignment = (4 - last_size);
287 break;
289 case RPC_FC_HYPER:
290 case RPC_FC_DOUBLE:
291 size = 8;
292 if (last_size != 0 && last_size < 4)
293 alignment = (4 - last_size);
294 break;
296 default:
297 size = 0;
298 error("Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
301 if (alignment != 0)
302 print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment);
304 print_file(file, indent, "*(");
305 write_type(file, var->type, var, var->tname);
306 fprintf(file, " *)_StubMsg.Buffer = ");
307 write_name(file, var);
308 fprintf(file, ";\n");
309 fprintf(file, "_StubMsg.Buffer += sizeof(");
310 write_type(file, var->type, var, var->tname);
311 fprintf(file, ");\n");
312 fprintf(file, "\n");
314 last_size = size;
316 var = PREV_LINK(var);
320 void unmarshall_arguments(FILE *file, int indent, func_t *func)
322 unsigned int alignment;
323 unsigned int size;
324 unsigned int last_size = 0;
325 var_t *var;
327 if (!func->args)
328 return;
330 var = func->args;
331 while (NEXT_LINK(var)) var = NEXT_LINK(var);
332 while (var)
334 alignment = 0;
335 switch (var->type->type)
337 case RPC_FC_BYTE:
338 case RPC_FC_CHAR:
339 case RPC_FC_SMALL:
340 case RPC_FC_USMALL:
341 size = 1;
342 alignment = 0;
343 break;
345 case RPC_FC_WCHAR:
346 case RPC_FC_USHORT:
347 case RPC_FC_SHORT:
348 size = 2;
349 if (last_size != 0 && last_size < 2)
350 alignment = (2 - last_size);
351 break;
353 case RPC_FC_ULONG:
354 case RPC_FC_LONG:
355 case RPC_FC_FLOAT:
356 case RPC_FC_ERROR_STATUS_T:
357 size = 4;
358 if (last_size != 0 && last_size < 4)
359 alignment = (4 - last_size);
360 break;
362 case RPC_FC_HYPER:
363 case RPC_FC_DOUBLE:
364 size = 8;
365 if (last_size != 0 && last_size < 4)
366 alignment = (4 - last_size);
367 break;
369 default:
370 size = 0;
371 error("Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
374 if (alignment != 0)
375 print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment);
377 print_file(file, indent, "");
378 write_name(file, var);
379 fprintf(file, " = *(");
380 write_type(file, var->type, var, var->tname);
381 fprintf(file, " *)_StubMsg.Buffer;\n");
382 fprintf(file, "_StubMsg.Buffer += sizeof(");
383 write_type(file, var->type, var, var->tname);
384 fprintf(file, ");\n");
385 fprintf(file, "\n");
387 last_size = size;
389 var = PREV_LINK(var);