widl: Don't output __RPC_FAR in generated code.
[wine] / tools / widl / typegen.c
1 /*
2  * Format String Generator for IDL Compiler
3  *
4  * Copyright 2005 Eric Kohl
5  * Copyright 2005 Robert Shearman
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
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>
34
35 #include "widl.h"
36 #include "utils.h"
37 #include "parser.h"
38 #include "header.h"
39 #include "windef.h"
40
41 #include "widl.h"
42
43 static int print_file(FILE *file, int indent, const char *format, ...)
44 {
45     va_list va;
46     int i, r;
47
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;
54 }
55
56 static void write_procformatstring_var(FILE *file, int indent, var_t *var)
57 {
58     switch(var->type->type)
59     {
60 #define CASE_BASETYPE(fctype) \
61     case RPC_##fctype: \
62         print_file(file, indent, "0x%02x,    /* " #fctype " */\n", var->type->type); \
63         break
64
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);
80     }
81 }
82
83 void write_procformatstring(FILE *file, type_t *iface)
84 {
85     int indent = 0;
86     func_t *func = iface->funcs;
87     var_t *var;
88
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++;
95
96     while (NEXT_LINK(func)) func = NEXT_LINK(func);
97     while (func)
98     {
99         /* emit argument data */
100         if (func->args)
101         {
102             var = func->args;
103             while (NEXT_LINK(var)) var = NEXT_LINK(var);
104             while (var)
105             {
106                 print_file(file, indent, "0x4e,    /* FC_IN_PARAM_BASETYPE */\n");
107                 write_procformatstring_var(file, indent, var);
108                 var = PREV_LINK(var);
109             }
110         }
111
112         /* emit return value data */
113         var = func->def;
114         if (is_void(var->type, NULL))
115         {
116             print_file(file, indent, "0x5b,    /* FC_END */\n");
117             print_file(file, indent, "0x5c,    /* FC_PAD */\n");
118         }
119         else
120         {
121             print_file(file, indent, "0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");
122             write_procformatstring_var(file, indent, var);
123         }
124
125         func = PREV_LINK(func);
126     }
127
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");
134 }
135
136
137 void write_typeformatstring(FILE *file)
138 {
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");
153 }
154
155
156 unsigned int get_required_buffer_size(type_t *type)
157 {
158     switch(type->type)
159     {
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;
171
172         case RPC_FC_HYPER:
173         case RPC_FC_DOUBLE:
174             return 8;
175
176         default:
177             error("Unknown/unsupported type: %s (0x%02x)\n", type->name, type->type);
178             return 0;
179     }
180 }
181
182 void marshall_arguments(FILE *file, int indent, func_t *func)
183 {
184     unsigned int alignment;
185     unsigned int size;
186     unsigned int last_size = 0;
187     var_t *var;
188
189     if (!func->args)
190         return;
191
192     var = func->args;
193     while (NEXT_LINK(var)) var = NEXT_LINK(var);
194     while (var)
195     {
196         alignment = 0;
197         switch (var->type->type)
198         {
199         case RPC_FC_BYTE:
200         case RPC_FC_CHAR:
201             size = 1;
202             alignment = 0;
203             break;
204
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;
212
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;
221
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;
228
229         default:
230             size = 0;
231             error("Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
232         }
233
234         if (alignment != 0)
235             print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment);
236
237         print_file(file, indent, "*((");
238         write_type(file, var->type, var, var->tname);
239         fprintf(file, " *)_StubMsg.Buffer)++ = ");
240         write_name(file, var);
241         fprintf(file, ";\n");
242         fprintf(file, "\n");
243
244         last_size = size;
245
246         var = PREV_LINK(var);
247     }
248 }
249
250 void unmarshall_arguments(FILE *file, int indent, func_t *func)
251 {
252     unsigned int alignment;
253     unsigned int size;
254     unsigned int last_size = 0;
255     var_t *var;
256
257     if (!func->args)
258         return;
259
260     var = func->args;
261     while (NEXT_LINK(var)) var = NEXT_LINK(var);
262     while (var)
263     {
264         alignment = 0;
265         switch (var->type->type)
266         {
267         case RPC_FC_BYTE:
268         case RPC_FC_CHAR:
269             size = 1;
270             alignment = 0;
271             break;
272
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;
280
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;
289
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;
296
297         default:
298             size = 0;
299             error("Unknown/unsupported type: %s (0x%02x)\n", var->name, var->type->type);
300         }
301
302         if (alignment != 0)
303             print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment);
304
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, " *)_StubMsg.Buffer)++;\n");
310         fprintf(file, "\n");
311
312         last_size = size;
313
314         var = PREV_LINK(var);
315     }
316 }