Fix English progman resources by translating French bits.
[wine.git] / tools / widl / header.c
blobc910a9ab42008ab6bb6eceba12951b5eab092a3d
1 /*
2 * IDL Compiler
4 * Copyright 2002 Ove Kaaven
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif
28 #include <string.h>
29 #include <assert.h>
30 #include <ctype.h>
31 #include <signal.h>
33 #include "widl.h"
34 #include "utils.h"
35 #include "parser.h"
36 #include "header.h"
37 #include "proxy.h"
39 static int indentation = 0;
41 static void indent(int delta)
43 int c;
44 if (delta < 0) indentation += delta;
45 for (c=0; c<indentation; c++) fprintf(header, " ");
46 if (delta > 0) indentation += delta;
49 int is_void(type_t *t, var_t *v)
51 if (v && v->ptr_level) return 0;
52 if (!t->type && !t->ref) return 1;
53 return 0;
56 static void write_pident(var_t *v)
58 int c;
59 for (c=0; c<v->ptr_level; c++) {
60 fprintf(header, "*");
62 if (v->name) fprintf(header, "%s", v->name);
65 void write_name(FILE *h, var_t *v)
67 fprintf(h, "%s", v->name);
70 char* get_name(var_t *v)
72 return v->name;
75 static void write_fields(FILE *h, var_t *v)
77 if (!v) return;
78 while (NEXT_LINK(v)) v = NEXT_LINK(v);
79 while (v) {
80 if (v->type) {
81 indent(0);
82 write_type(h, v->type, NULL, v->tname);
83 if (get_name(v)) {
84 fprintf(header, " ");
85 write_pident(v);
87 fprintf(header, ";\n");
89 v = PREV_LINK(v);
93 void write_type(FILE *h, type_t *t, var_t *v, char *n)
95 int c;
97 if (n) fprintf(h, "%s", n);
98 else {
99 if (t->is_const) fprintf(h, "const ");
100 if (t->type) {
101 switch (t->type) {
102 case RPC_FC_BYTE:
103 fprintf(h, "byte");
104 break;
105 case RPC_FC_CHAR:
106 fprintf(h, "char");
107 break;
108 case RPC_FC_USHORT:
109 fprintf(h, "unsigned ");
110 case RPC_FC_SHORT:
111 if (t->ref) fprintf(h, t->ref->name);
112 fprintf(h, "short");
113 break;
114 case RPC_FC_ULONG:
115 fprintf(h, "unsigned ");
116 case RPC_FC_LONG:
117 if (t->ref) fprintf(h, t->ref->name);
118 else fprintf(h, "long");
119 break;
120 case RPC_FC_STRUCT:
121 if (t->defined && !t->written) {
122 if (t->name) fprintf(h, "struct %s {\n", t->name);
123 else fprintf(h, "struct {\n");
124 indentation++;
125 write_fields(h, t->fields);
126 indent(-1);
127 fprintf(h, "}");
129 else fprintf(h, "struct %s", t->name);
130 break;
131 case RPC_FC_NON_ENCAPSULATED_UNION:
132 if (t->defined && !t->written) {
133 if (t->name) fprintf(h, "union %s {\n", t->name);
134 else fprintf(h, "union {\n");
135 indentation++;
136 write_fields(h, t->fields);
137 indent(-1);
138 fprintf(h, "}");
140 else fprintf(h, "union %s", t->name);
141 break;
142 default:
143 fprintf(h, "(unknown-type:%d)", t->type);
146 else {
147 if (t->ref) {
148 write_type(h, t->ref, NULL, t->name);
150 else fprintf(h, "void");
153 if (v) {
154 for (c=0; c<v->ptr_level; c++) {
155 fprintf(h, "*");
160 void write_typedef(type_t *type, var_t *names)
162 char *tname = names->tname;
163 while (NEXT_LINK(names)) names = NEXT_LINK(names);
164 fprintf(header, "typedef ");
165 write_type(header, type, NULL, tname);
166 fprintf(header, " ");
167 while (names) {
168 write_pident(names);
169 if (PREV_LINK(names))
170 fprintf(header, ", ");
171 names = PREV_LINK(names);
173 fprintf(header, ";\n");
176 /********** INTERFACES **********/
178 int is_object(attr_t *a)
180 while (a) {
181 if (a->type == ATTR_OBJECT) return 1;
182 a = NEXT_LINK(a);
184 return 0;
187 int is_local(attr_t *a)
189 while (a) {
190 if (a->type == ATTR_LOCAL) return 1;
191 a = NEXT_LINK(a);
193 return 0;
196 var_t *is_callas(attr_t *a)
198 while (a) {
199 if (a->type == ATTR_CALLAS) return a->u.pval;
200 a = NEXT_LINK(a);
202 return NULL;
205 static void write_method_def(type_t *iface)
207 func_t *cur = iface->funcs;
208 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
209 fprintf(header, "#define %s_METHODS", iface->name);
210 while (cur) {
211 var_t *def = cur->def;
212 if (!is_callas(def->attrs)) {
213 var_t *arg = cur->args;
214 int argc = 0;
215 if (arg) {
216 argc++;
217 while (NEXT_LINK(arg)) {
218 arg = NEXT_LINK(arg);
219 argc++;
222 fprintf(header, " \\\n");
223 if (!is_void(def->type, def)) {
224 if (argc)
225 fprintf(header, " ICOM_METHOD%d (", argc);
226 else
227 fprintf(header, " ICOM_METHOD (");
228 write_type(header, def->type, def, def->tname);
229 fprintf(header, ",");
230 } else
231 if (argc)
232 fprintf(header, " ICOM_VMETHOD%d(", argc);
233 else
234 fprintf(header, " ICOM_VMETHOD (");
235 write_name(header, def);
236 while (arg) {
237 fprintf(header, ",");
238 write_type(header, arg->type, arg, arg->tname);
239 fprintf(header, ",");
240 write_name(header,arg);
241 arg = PREV_LINK(arg);
243 fprintf(header, ")");
245 cur = PREV_LINK(cur);
247 fprintf(header, "\n");
250 static int write_method_macro(type_t *iface, char *name)
252 int idx;
253 func_t *cur = iface->funcs;
254 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
256 if (iface->ref) idx = write_method_macro(iface->ref, name);
257 else idx = 0;
258 fprintf(header, "/*** %s methods ***/\n", iface->name);
259 while (cur) {
260 var_t *def = cur->def;
261 if (!is_callas(def->attrs)) {
262 var_t *arg = cur->args;
263 int argc = 0;
264 int c;
265 while (arg) {
266 arg = NEXT_LINK(arg);
267 argc++;
270 fprintf(header, "#define %s_", name);
271 write_name(header,def);
272 fprintf(header, "(p");
273 for (c=0; c<argc; c++)
274 fprintf(header, ",%c", c+'a');
275 fprintf(header, ") ");
277 if (argc)
278 fprintf(header, "ICOM_CALL%d(", argc);
279 else
280 fprintf(header, "ICOM_CALL(");
281 write_name(header,def);
282 fprintf(header, ",p");
283 for (c=0; c<argc; c++)
284 fprintf(header, ",%c", c+'a');
285 fprintf(header, ")\n");
286 if (cur->idx == -1) cur->idx = idx;
287 else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro");
288 idx++;
290 cur = PREV_LINK(cur);
292 return idx;
295 void write_method_args(FILE *h, var_t *arg, char *name)
297 if (arg) {
298 while (NEXT_LINK(arg))
299 arg = NEXT_LINK(arg);
301 fprintf(h, " %s* This", name);
302 while (arg) {
303 fprintf(h, ",\n ");
304 write_type(h, arg->type, arg, arg->tname);
305 fprintf(h, " ");
306 write_name(h,arg);
307 arg = PREV_LINK(arg);
311 static void write_method_proto(type_t *iface)
313 func_t *cur = iface->funcs;
314 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
315 while (cur) {
316 var_t *def = cur->def;
317 var_t *cas = is_callas(def->attrs);
318 if (!is_local(def->attrs)) {
319 /* proxy prototype */
320 write_type(header, def->type, def, def->tname);
321 fprintf(header, " CALLBACK %s_", iface->name);
322 write_name(header,def);
323 fprintf(header, "_Proxy(\n");
324 write_method_args(header, cur->args, iface->name);
325 fprintf(header, ");\n");
326 /* stub prototype */
327 fprintf(header, "void __RPC_STUB %s_", iface->name);
328 write_name(header,def);
329 fprintf(header, "_Stub(\n");
330 fprintf(header, " IRpcStubBuffer* This,\n");
331 fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
332 fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
333 fprintf(header, " DWORD* pdwStubPhase);\n");
335 if (cas) {
336 func_t *m = iface->funcs;
337 while (m && strcmp(get_name(m->def), cas->name))
338 m = NEXT_LINK(m);
339 if (m) {
340 var_t *mdef = m->def;
341 /* proxy prototype - use local prototype */
342 write_type(header, mdef->type, mdef, mdef->tname);
343 fprintf(header, " CALLBACK %s_", iface->name);
344 write_name(header, mdef);
345 fprintf(header, "_Proxy(\n");
346 write_method_args(header, m->args, iface->name);
347 fprintf(header, ");\n");
348 /* stub prototype - use remotable prototype */
349 write_type(header, def->type, def, def->tname);
350 fprintf(header, " __RPC_STUB %s_", iface->name);
351 write_name(header, mdef);
352 fprintf(header, "_Stub(\n");
353 write_method_args(header, cur->args, iface->name);
354 fprintf(header, ");\n");
356 else {
357 yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name);
361 cur = PREV_LINK(cur);
365 void write_forward(type_t *iface)
367 if (!iface->written) {
368 fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
369 iface->written = TRUE;
373 void write_interface(type_t *iface)
375 if (!is_object(iface->attrs)) {
376 if (!iface->funcs) return;
377 yywarning("RPC interfaces not supported yet\n");
378 return;
381 if (!iface->funcs) {
382 yywarning("%s has no methods", iface->name);
383 return;
386 fprintf(header, "/*****************************************************************************\n");
387 fprintf(header, " * %s interface\n", iface->name);
388 fprintf(header, " */\n");
389 write_forward(iface);
390 if (iface->ref)
391 fprintf(header, "#define ICOM_INTERFACE %s\n", iface->name);
392 write_method_def(iface);
393 fprintf(header, "#define %s_IMETHODS \\\n", iface->name);
394 if (iface->ref)
395 fprintf(header, " %s_IMETHODS \\\n", iface->ref->name);
396 fprintf(header, " %s_METHODS \\\n", iface->name);
397 if (iface->ref) {
398 fprintf(header, "ICOM_DEFINE(%s,%s)\n", iface->name, iface->ref->name);
399 fprintf(header, "#undef ICOM_INTERFACE\n");
401 fprintf(header, "\n");
402 write_method_macro(iface, iface->name);
403 fprintf(header, "\n");
404 write_method_proto(iface);
405 fprintf(header, "\n");
407 if (!is_local(iface->attrs))
408 write_proxy(iface);