Determine RPC struct types more exactly.
[wine/multimedia.git] / tools / widl / header.c
blob5332d5fe292bf4222b5bf845349ba3773d8c4f3d
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"
38 static int indentation = 0;
40 static void indent(int delta)
42 int c;
43 if (delta < 0) indentation += delta;
44 for (c=0; c<indentation; c++) fprintf(header, " ");
45 if (delta > 0) indentation += delta;
48 int is_attr(attr_t *a, enum attr_type t)
50 while (a) {
51 if (a->type == t) return 1;
52 a = NEXT_LINK(a);
54 return 0;
57 void *get_attrp(attr_t *a, enum attr_type t)
59 while (a) {
60 if (a->type == t) return a->u.pval;
61 a = NEXT_LINK(a);
63 return NULL;
66 unsigned long get_attrv(attr_t *a, enum attr_type t)
68 while (a) {
69 if (a->type == t) return a->u.ival;
70 a = NEXT_LINK(a);
72 return 0;
75 int is_void(type_t *t, var_t *v)
77 if (v && v->ptr_level) return 0;
78 if (!t->type && !t->ref) return 1;
79 return 0;
82 static void write_pident(FILE *h, var_t *v)
84 int c;
85 for (c=0; c<v->ptr_level; c++) {
86 fprintf(h, "*");
88 if (v->name) fprintf(h, "%s", v->name);
91 void write_name(FILE *h, var_t *v)
93 fprintf(h, "%s", v->name);
96 char* get_name(var_t *v)
98 return v->name;
101 static void write_array(FILE *h, expr_t *v, int field)
103 if (!v) return;
104 while (NEXT_LINK(v)) v = NEXT_LINK(v);
105 fprintf(h, "[");
106 while (v) {
107 if (v->is_const)
108 fprintf(h, "%ld", v->cval); /* statically sized array */
109 else
110 if (field) fprintf(h, "1"); /* dynamically sized array */
111 if (PREV_LINK(v))
112 fprintf(h, ", ");
113 v = PREV_LINK(v);
115 fprintf(h, "]");
118 static void write_field(FILE *h, var_t *v)
120 if (!v) return;
121 if (v->type) {
122 indent(0);
123 write_type(h, v->type, NULL, v->tname);
124 if (get_name(v)) {
125 fprintf(h, " ");
126 write_pident(h, v);
128 else {
129 /* not all C/C++ compilers support anonymous structs and unions */
130 switch (v->type->type) {
131 case RPC_FC_STRUCT:
132 case RPC_FC_CVSTRUCT:
133 case RPC_FC_CPSTRUCT:
134 case RPC_FC_CSTRUCT:
135 case RPC_FC_PSTRUCT:
136 case RPC_FC_BOGUS_STRUCT:
137 case RPC_FC_ENCAPSULATED_UNION:
138 fprintf(h, " DUMMYSTRUCTNAME");
139 break;
140 case RPC_FC_NON_ENCAPSULATED_UNION:
141 fprintf(h, " DUMMYUNIONNAME");
142 break;
143 default:
144 /* ? */
145 break;
148 write_array(h, v->array, 1);
149 fprintf(h, ";\n");
153 static void write_fields(FILE *h, var_t *v)
155 var_t *first = v;
156 if (!v) return;
157 while (NEXT_LINK(v)) v = NEXT_LINK(v);
158 while (v) {
159 write_field(h, v);
160 if (v == first) break;
161 v = PREV_LINK(v);
165 static void write_enums(FILE *h, var_t *v)
167 if (!v) return;
168 while (NEXT_LINK(v)) v = NEXT_LINK(v);
169 while (v) {
170 if (get_name(v)) {
171 indent(0);
172 write_name(h, v);
173 if (v->eval) {
174 fprintf(h, " = ");
175 write_expr(h, v->eval);
178 if (PREV_LINK(v))
179 fprintf(h, ",\n");
180 v = PREV_LINK(v);
182 fprintf(h, "\n");
185 void write_type(FILE *h, type_t *t, var_t *v, char *n)
187 int c;
189 if (n) fprintf(h, "%s", n);
190 else {
191 if (t->is_const) fprintf(h, "const ");
192 if (t->type) {
193 if (t->sign > 0) fprintf(h, "signed ");
194 else if (t->sign < 0) fprintf(h, "unsigned ");
195 switch (t->type) {
196 case RPC_FC_BYTE:
197 if (t->ref) fprintf(h, t->ref->name);
198 else fprintf(h, "byte");
199 break;
200 case RPC_FC_CHAR:
201 if (t->ref) fprintf(h, t->ref->name);
202 else fprintf(h, "char");
203 break;
204 case RPC_FC_WCHAR:
205 fprintf(h, "wchar_t");
206 break;
207 case RPC_FC_USHORT:
208 case RPC_FC_SHORT:
209 if (t->ref) fprintf(h, t->ref->name);
210 else fprintf(h, "short");
211 break;
212 case RPC_FC_ULONG:
213 case RPC_FC_LONG:
214 if (t->ref) fprintf(h, t->ref->name);
215 else fprintf(h, "long");
216 break;
217 case RPC_FC_HYPER:
218 if (t->ref) fprintf(h, t->ref->name);
219 else fprintf(h, "hyper");
220 break;
221 case RPC_FC_FLOAT:
222 fprintf(h, "float");
223 break;
224 case RPC_FC_DOUBLE:
225 fprintf(h, "double");
226 break;
227 case RPC_FC_ENUM16:
228 case RPC_FC_ENUM32:
229 if (t->defined && !t->written) {
230 if (t->name) fprintf(h, "enum %s {\n", t->name);
231 else fprintf(h, "enum {\n");
232 t->written = TRUE;
233 indentation++;
234 write_enums(h, t->fields);
235 indent(-1);
236 fprintf(h, "}");
238 else fprintf(h, "enum %s", t->name);
239 break;
240 case RPC_FC_ERROR_STATUS_T:
241 if (t->ref) fprintf(h, t->ref->name);
242 else fprintf(h, "error_status_t");
243 break;
244 case RPC_FC_BIND_PRIMITIVE:
245 if (t->ref) fprintf(h, t->ref->name);
246 else fprintf(h, "handle_t");
247 break;
248 case RPC_FC_STRUCT:
249 case RPC_FC_CVSTRUCT:
250 case RPC_FC_CPSTRUCT:
251 case RPC_FC_CSTRUCT:
252 case RPC_FC_PSTRUCT:
253 case RPC_FC_BOGUS_STRUCT:
254 case RPC_FC_ENCAPSULATED_UNION:
255 if (t->defined && !t->written) {
256 if (t->name) fprintf(h, "struct %s {\n", t->name);
257 else fprintf(h, "struct {\n");
258 t->written = TRUE;
259 indentation++;
260 write_fields(h, t->fields);
261 indent(-1);
262 fprintf(h, "}");
264 else fprintf(h, "struct %s", t->name);
265 break;
266 case RPC_FC_NON_ENCAPSULATED_UNION:
267 if (t->defined && !t->written) {
268 if (t->name) fprintf(h, "union %s {\n", t->name);
269 else fprintf(h, "union {\n");
270 t->written = TRUE;
271 indentation++;
272 write_fields(h, t->fields);
273 indent(-1);
274 fprintf(h, "}");
276 else fprintf(h, "union %s", t->name);
277 break;
278 default:
279 fprintf(h, "(unknown-type:%d)", t->type);
282 else {
283 if (t->ref) {
284 write_type(h, t->ref, NULL, t->name);
286 else fprintf(h, "void");
289 if (v) {
290 for (c=0; c<v->ptr_level; c++) {
291 fprintf(h, "*");
296 void write_typedef(type_t *type, var_t *names)
298 char *tname = names->tname;
299 var_t *lname;
300 while (NEXT_LINK(names)) names = NEXT_LINK(names);
301 lname = names;
302 fprintf(header, "typedef ");
303 write_type(header, type, NULL, tname);
304 fprintf(header, " ");
305 while (names) {
306 write_pident(header, names);
307 if (PREV_LINK(names))
308 fprintf(header, ", ");
309 names = PREV_LINK(names);
311 fprintf(header, ";\n");
313 if (get_attrp(type->attrs, ATTR_WIREMARSHAL)) {
314 names = lname;
315 while (names) {
316 char *name = get_name(names);
317 fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name);
318 fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name);
319 fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name);
320 fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name);
321 if (PREV_LINK(names))
322 fprintf(header, ", ");
323 names = PREV_LINK(names);
327 fprintf(header, "\n");
330 static void do_write_expr(FILE *h, expr_t *e, int p)
332 switch (e->type) {
333 case EXPR_VOID:
334 break;
335 case EXPR_NUM:
336 fprintf(h, "%ld", e->u.lval);
337 break;
338 case EXPR_HEXNUM:
339 fprintf(h, "0x%lx", e->u.lval);
340 break;
341 case EXPR_IDENTIFIER:
342 fprintf(h, "%s", e->u.sval);
343 break;
344 case EXPR_NEG:
345 fprintf(h, "-");
346 do_write_expr(h, e->ref, 1);
347 break;
348 case EXPR_NOT:
349 fprintf(h, "~");
350 do_write_expr(h, e->ref, 1);
351 break;
352 case EXPR_PPTR:
353 fprintf(h, "*");
354 do_write_expr(h, e->ref, 1);
355 break;
356 case EXPR_CAST:
357 fprintf(h, "(");
358 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
359 fprintf(h, ")");
360 do_write_expr(h, e->ref, 1);
361 break;
362 case EXPR_SIZEOF:
363 fprintf(h, "sizeof(");
364 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
365 fprintf(h, ")");
366 break;
367 case EXPR_SHL:
368 case EXPR_SHR:
369 case EXPR_MUL:
370 case EXPR_DIV:
371 case EXPR_ADD:
372 case EXPR_SUB:
373 case EXPR_AND:
374 case EXPR_OR:
375 if (p) fprintf(h, "(");
376 do_write_expr(h, e->ref, 1);
377 switch (e->type) {
378 case EXPR_SHL: fprintf(h, " << "); break;
379 case EXPR_SHR: fprintf(h, " >> "); break;
380 case EXPR_MUL: fprintf(h, " * "); break;
381 case EXPR_DIV: fprintf(h, " / "); break;
382 case EXPR_ADD: fprintf(h, " + "); break;
383 case EXPR_SUB: fprintf(h, " - "); break;
384 case EXPR_AND: fprintf(h, " & "); break;
385 case EXPR_OR: fprintf(h, " | "); break;
386 default: break;
388 do_write_expr(h, e->u.ext, 1);
389 if (p) fprintf(h, ")");
390 break;
391 case EXPR_COND:
392 if (p) fprintf(h, "(");
393 do_write_expr(h, e->ref, 1);
394 fprintf(h, " ? ");
395 do_write_expr(h, e->u.ext, 1);
396 fprintf(h, " : ");
397 do_write_expr(h, e->ext2, 1);
398 if (p) fprintf(h, ")");
399 break;
403 void write_expr(FILE *h, expr_t *e)
405 do_write_expr(h, e, 0);
408 void write_constdef(var_t *v)
410 fprintf(header, "#define %s (", get_name(v));
411 write_expr(header, v->eval);
412 fprintf(header, ")\n\n");
415 void write_externdef(var_t *v)
417 fprintf(header, "extern const ");
418 write_type(header, v->type, NULL, v->tname);
419 if (get_name(v)) {
420 fprintf(header, " ");
421 write_pident(header, v);
423 fprintf(header, ";\n\n");
426 /********** INTERFACES **********/
428 int is_object(attr_t *a)
430 while (a) {
431 if (a->type == ATTR_OBJECT || a->type == ATTR_ODL) return 1;
432 a = NEXT_LINK(a);
434 return 0;
437 int is_local(attr_t *a)
439 return is_attr(a, ATTR_LOCAL);
442 var_t *is_callas(attr_t *a)
444 return get_attrp(a, ATTR_CALLAS);
447 static void write_icom_method_def(type_t *iface)
449 func_t *cur = iface->funcs;
450 if (iface->ref) write_icom_method_def( iface->ref );
451 if (!cur) return;
452 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
453 if (cur) fprintf( header, " \\\n /*** %s methods ***/", iface->name );
454 while (cur) {
455 var_t *def = cur->def;
456 if (!is_callas(def->attrs)) {
457 var_t *arg = cur->args;
459 if (arg) {
460 while (NEXT_LINK(arg)) {
461 arg = NEXT_LINK(arg);
464 fprintf(header, " \\\n STDMETHOD_(");
465 write_type(header, def->type, def, def->tname);
466 fprintf(header, ",");
467 write_name(header, def);
468 fprintf(header, ")(%s", arg ? "THIS_ " : "THIS" );
469 while (arg) {
470 write_type(header, arg->type, arg, arg->tname);
471 if (arg->args)
473 fprintf(header, " (STDMETHODCALLTYPE *");
474 write_name(header,arg);
475 fprintf( header,")(");
476 write_args(header, arg->args, NULL, 0, FALSE);
477 fprintf(header,")");
479 else
481 fprintf(header, " ");
482 write_name(header,arg);
484 write_array(header, arg->array, 0);
485 arg = PREV_LINK(arg);
486 if (arg) fprintf(header, ", ");
488 fprintf(header, ") PURE;");
490 cur = PREV_LINK(cur);
494 static int write_method_macro(type_t *iface, char *name)
496 int idx;
497 func_t *cur = iface->funcs;
499 if (iface->ref) idx = write_method_macro(iface->ref, name);
500 else idx = 0;
502 if (!cur) return idx;
503 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
505 fprintf(header, "/*** %s methods ***/\n", iface->name);
506 while (cur) {
507 var_t *def = cur->def;
508 if (!is_callas(def->attrs)) {
509 var_t *arg = cur->args;
510 int argc = 0;
511 int c;
512 while (arg) {
513 arg = NEXT_LINK(arg);
514 argc++;
517 fprintf(header, "#define %s_", name);
518 write_name(header,def);
519 fprintf(header, "(p");
520 for (c=0; c<argc; c++)
521 fprintf(header, ",%c", c+'a');
522 fprintf(header, ") ");
524 fprintf(header, "(p)->lpVtbl->");
525 write_name(header, def);
526 fprintf(header, "(p");
527 for (c=0; c<argc; c++)
528 fprintf(header, ",%c", c+'a');
529 fprintf(header, ")\n");
530 if (cur->idx == -1) cur->idx = idx;
531 else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro");
532 idx++;
534 cur = PREV_LINK(cur);
536 return idx;
539 void write_args(FILE *h, var_t *arg, char *name, int method, int do_indent)
541 int count = 0;
542 if (arg) {
543 while (NEXT_LINK(arg))
544 arg = NEXT_LINK(arg);
546 if (do_indent)
548 if (h == header) {
549 indentation++;
550 indent(0);
551 } else fprintf(h, " ");
553 if (method == 1) {
554 fprintf(h, "%s* This", name);
555 count++;
557 while (arg) {
558 if (count) {
559 if (do_indent)
561 fprintf(h, ",\n");
562 if (h == header) indent(0);
563 else fprintf(h, " ");
565 else fprintf(h, ",");
567 write_type(h, arg->type, arg, arg->tname);
568 if (arg->args)
570 fprintf(h, " (STDMETHODCALLTYPE *");
571 write_name(h,arg);
572 fprintf(h, ")(");
573 write_args(h, arg->args, NULL, 0, FALSE);
574 fprintf(h, ")");
576 else
578 fprintf(h, " ");
579 write_name(h, arg);
581 write_array(h, arg->array, 0);
582 arg = PREV_LINK(arg);
583 count++;
585 if (do_indent && h == header) indentation--;
588 static void write_cpp_method_def(type_t *iface)
590 func_t *cur = iface->funcs;
592 if (!cur) return;
593 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
594 while (cur) {
595 var_t *def = cur->def;
596 if (!is_callas(def->attrs)) {
597 indent(0);
598 fprintf(header, "virtual ");
599 write_type(header, def->type, def, def->tname);
600 fprintf(header, " STDMETHODCALLTYPE ");
601 write_name(header, def);
602 fprintf(header, "(\n");
603 write_args(header, cur->args, iface->name, 2, TRUE);
604 fprintf(header, ") = 0;\n");
605 fprintf(header, "\n");
607 cur = PREV_LINK(cur);
611 static void do_write_c_method_def(type_t *iface, char *name)
613 func_t *cur = iface->funcs;
615 if (iface->ref) do_write_c_method_def(iface->ref, name);
617 if (!cur) return;
618 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
619 indent(0);
620 fprintf(header, "/*** %s methods ***/\n", iface->name);
621 while (cur) {
622 var_t *def = cur->def;
623 if (!is_callas(def->attrs)) {
624 indent(0);
625 write_type(header, def->type, def, def->tname);
626 fprintf(header, " (STDMETHODCALLTYPE *");
627 write_name(header, def);
628 fprintf(header, ")(\n");
629 write_args(header, cur->args, name, 1, TRUE);
630 fprintf(header, ");\n");
631 fprintf(header, "\n");
633 cur = PREV_LINK(cur);
637 static void write_c_method_def(type_t *iface)
639 do_write_c_method_def(iface, iface->name);
642 static void write_method_proto(type_t *iface)
644 func_t *cur = iface->funcs;
646 if (!cur) return;
647 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
648 while (cur) {
649 var_t *def = cur->def;
650 var_t *cas = is_callas(def->attrs);
651 if (!is_local(def->attrs)) {
652 /* proxy prototype */
653 write_type(header, def->type, def, def->tname);
654 fprintf(header, " CALLBACK %s_", iface->name);
655 write_name(header, def);
656 fprintf(header, "_Proxy(\n");
657 write_args(header, cur->args, iface->name, 1, TRUE);
658 fprintf(header, ");\n");
659 /* stub prototype */
660 fprintf(header, "void __RPC_STUB %s_", iface->name);
661 write_name(header,def);
662 fprintf(header, "_Stub(\n");
663 fprintf(header, " struct IRpcStubBuffer* This,\n");
664 fprintf(header, " struct IRpcChannelBuffer* pRpcChannelBuffer,\n");
665 fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
666 fprintf(header, " DWORD* pdwStubPhase);\n");
668 if (cas) {
669 func_t *m = iface->funcs;
670 while (m && strcmp(get_name(m->def), cas->name))
671 m = NEXT_LINK(m);
672 if (m) {
673 var_t *mdef = m->def;
674 /* proxy prototype - use local prototype */
675 write_type(header, mdef->type, mdef, mdef->tname);
676 fprintf(header, " CALLBACK %s_", iface->name);
677 write_name(header, mdef);
678 fprintf(header, "_Proxy(\n");
679 write_args(header, m->args, iface->name, 1, TRUE);
680 fprintf(header, ");\n");
681 /* stub prototype - use remotable prototype */
682 write_type(header, def->type, def, def->tname);
683 fprintf(header, " __RPC_STUB %s_", iface->name);
684 write_name(header, mdef);
685 fprintf(header, "_Stub(\n");
686 write_args(header, cur->args, iface->name, 1, TRUE);
687 fprintf(header, ");\n");
689 else {
690 yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name);
694 cur = PREV_LINK(cur);
698 static void write_function_proto(type_t *iface)
700 func_t *cur = iface->funcs;
701 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
702 while (cur) {
703 var_t *def = cur->def;
704 /* FIXME: do we need to handle call_as? */
705 write_type(header, def->type, def, def->tname);
706 fprintf(header, " ");
707 write_name(header, def);
708 fprintf(header, "(\n");
709 write_args(header, cur->args, iface->name, 0, TRUE);
710 fprintf(header, ");\n");
712 cur = PREV_LINK(cur);
716 void write_forward(type_t *iface)
718 /* C/C++ forwards should only be written for object interfaces, so if we
719 * have a full definition we only write one if we find [object] among the
720 * attributes - however, if we don't have a full definition at this point
721 * (i.e. this is an IDL forward), then we also assume that it is an object
722 * interface, since non-object interfaces shouldn't need forwards */
723 if ((!iface->defined || is_object(iface->attrs)) && !iface->written) {
724 fprintf(header,"#ifndef __%s_FWD_DEFINED__\n", iface->name);
725 fprintf(header,"#define __%s_FWD_DEFINED__\n", iface->name);
726 fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
727 fprintf(header, "#endif\n\n" );
728 iface->written = TRUE;
732 void write_guid(type_t *iface)
734 UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
735 if (!uuid) return;
736 fprintf(header, "DEFINE_GUID(IID_%s, 0x%08lx, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n",
737 iface->name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
738 uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
741 void write_com_interface(type_t *iface)
743 if (!iface->funcs && !iface->ref) {
744 yywarning("%s has no methods", iface->name);
745 return;
748 fprintf(header, "/*****************************************************************************\n");
749 fprintf(header, " * %s interface\n", iface->name);
750 fprintf(header, " */\n");
751 fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
752 fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
753 write_guid(iface);
754 write_forward(iface);
755 /* C++ interface */
756 fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
757 if (iface->ref)
759 fprintf(header, "struct %s : public %s\n", iface->name, iface->ref->name);
760 fprintf(header, "{\n");
761 indentation++;
762 write_cpp_method_def(iface);
763 indentation--;
764 fprintf(header, "};\n");
766 else
768 fprintf(header, "struct %s\n", iface->name);
769 fprintf(header, "{\n");
770 fprintf(header, " BEGIN_INTERFACE\n");
771 fprintf(header, "\n");
772 indentation++;
773 write_cpp_method_def(iface);
774 indentation--;
775 fprintf(header, " END_INTERFACE\n");
776 fprintf(header, "};\n");
778 fprintf(header, "#else\n");
779 /* C interface */
780 fprintf(header, "typedef struct %sVtbl %sVtbl;\n", iface->name, iface->name);
781 fprintf(header, "struct %s {\n", iface->name);
782 fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name);
783 fprintf(header, "};\n");
784 fprintf(header, "struct %sVtbl {\n", iface->name);
785 indentation++;
786 fprintf(header, " BEGIN_INTERFACE\n");
787 fprintf(header, "\n");
788 write_c_method_def(iface);
789 indentation--;
790 fprintf(header, " END_INTERFACE\n");
791 fprintf(header, "};\n");
792 fprintf(header, "\n");
793 fprintf(header, "#ifdef COBJMACROS\n");
794 write_method_macro(iface, iface->name);
795 fprintf(header, "#endif\n");
796 fprintf(header, "\n");
797 fprintf(header, "#endif\n");
798 fprintf(header, "\n");
799 if (compat_icom) {
800 fprintf(header, "#define %s_METHODS", iface->name);
801 write_icom_method_def(iface);
802 fprintf(header, "\n\n");
804 write_method_proto(iface);
805 fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
808 void write_rpc_interface(type_t *iface)
810 unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
812 if (!iface->funcs) return;
814 fprintf(header, "/*****************************************************************************\n");
815 fprintf(header, " * %s interface (v%d.%d)\n", iface->name, LOWORD(ver), HIWORD(ver));
816 fprintf(header, " */\n");
817 write_guid(iface);
818 fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
819 fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
820 write_function_proto(iface);
821 fprintf(header, "\n");
823 /* FIXME: server/client code */
826 void write_interface(type_t *iface)
828 if (is_object(iface->attrs))
829 write_com_interface(iface);
830 else
831 write_rpc_interface(iface);