Get rid of the ICOM_MSVTABLE_COMPAT support, g++ no longer requires
[wine/multimedia.git] / tools / widl / header.c
blob597d76d4ed1465f8e0b5cdc891cc1087e3121567
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_ENCAPSULATED_UNION:
133 fprintf(h, " DUMMYSTRUCTNAME");
134 break;
135 case RPC_FC_NON_ENCAPSULATED_UNION:
136 fprintf(h, " DUMMYUNIONNAME");
137 break;
138 default:
139 /* ? */
140 break;
143 write_array(h, v->array, 1);
144 fprintf(h, ";\n");
148 static void write_fields(FILE *h, var_t *v)
150 var_t *first = v;
151 if (!v) return;
152 while (NEXT_LINK(v)) v = NEXT_LINK(v);
153 while (v) {
154 write_field(h, v);
155 if (v == first) break;
156 v = PREV_LINK(v);
160 static void write_enums(FILE *h, var_t *v)
162 if (!v) return;
163 while (NEXT_LINK(v)) v = NEXT_LINK(v);
164 while (v) {
165 if (get_name(v)) {
166 indent(0);
167 write_name(h, v);
168 if (v->eval) {
169 fprintf(h, " = ");
170 write_expr(h, v->eval);
173 if (PREV_LINK(v))
174 fprintf(h, ",\n");
175 v = PREV_LINK(v);
177 fprintf(h, "\n");
180 void write_type(FILE *h, type_t *t, var_t *v, char *n)
182 int c;
184 if (n) fprintf(h, "%s", n);
185 else {
186 if (t->is_const) fprintf(h, "const ");
187 if (t->type) {
188 if (t->sign > 0) fprintf(h, "signed ");
189 else if (t->sign < 0) fprintf(h, "unsigned ");
190 switch (t->type) {
191 case RPC_FC_BYTE:
192 if (t->ref) fprintf(h, t->ref->name);
193 else fprintf(h, "byte");
194 break;
195 case RPC_FC_CHAR:
196 if (t->ref) fprintf(h, t->ref->name);
197 else fprintf(h, "char");
198 break;
199 case RPC_FC_WCHAR:
200 fprintf(h, "wchar_t");
201 break;
202 case RPC_FC_USHORT:
203 case RPC_FC_SHORT:
204 if (t->ref) fprintf(h, t->ref->name);
205 else fprintf(h, "short");
206 break;
207 case RPC_FC_ULONG:
208 case RPC_FC_LONG:
209 if (t->ref) fprintf(h, t->ref->name);
210 else fprintf(h, "long");
211 break;
212 case RPC_FC_HYPER:
213 if (t->ref) fprintf(h, t->ref->name);
214 else fprintf(h, "hyper");
215 break;
216 case RPC_FC_FLOAT:
217 fprintf(h, "float");
218 break;
219 case RPC_FC_DOUBLE:
220 fprintf(h, "double");
221 break;
222 case RPC_FC_ENUM16:
223 case RPC_FC_ENUM32:
224 if (t->defined && !t->written) {
225 if (t->name) fprintf(h, "enum %s {\n", t->name);
226 else fprintf(h, "enum {\n");
227 t->written = TRUE;
228 indentation++;
229 write_enums(h, t->fields);
230 indent(-1);
231 fprintf(h, "}");
233 else fprintf(h, "enum %s", t->name);
234 break;
235 case RPC_FC_ERROR_STATUS_T:
236 if (t->ref) fprintf(h, t->ref->name);
237 else fprintf(h, "error_status_t");
238 break;
239 case RPC_FC_BIND_PRIMITIVE:
240 if (t->ref) fprintf(h, t->ref->name);
241 else fprintf(h, "handle_t");
242 break;
243 case RPC_FC_STRUCT:
244 case RPC_FC_ENCAPSULATED_UNION:
245 if (t->defined && !t->written) {
246 if (t->name) fprintf(h, "struct %s {\n", t->name);
247 else fprintf(h, "struct {\n");
248 t->written = TRUE;
249 indentation++;
250 write_fields(h, t->fields);
251 indent(-1);
252 fprintf(h, "}");
254 else fprintf(h, "struct %s", t->name);
255 break;
256 case RPC_FC_NON_ENCAPSULATED_UNION:
257 if (t->defined && !t->written) {
258 if (t->name) fprintf(h, "union %s {\n", t->name);
259 else fprintf(h, "union {\n");
260 t->written = TRUE;
261 indentation++;
262 write_fields(h, t->fields);
263 indent(-1);
264 fprintf(h, "}");
266 else fprintf(h, "union %s", t->name);
267 break;
268 default:
269 fprintf(h, "(unknown-type:%d)", t->type);
272 else {
273 if (t->ref) {
274 write_type(h, t->ref, NULL, t->name);
276 else fprintf(h, "void");
279 if (v) {
280 for (c=0; c<v->ptr_level; c++) {
281 fprintf(h, "*");
286 void write_typedef(type_t *type, var_t *names)
288 char *tname = names->tname;
289 var_t *lname;
290 while (NEXT_LINK(names)) names = NEXT_LINK(names);
291 lname = names;
292 fprintf(header, "typedef ");
293 write_type(header, type, NULL, tname);
294 fprintf(header, " ");
295 while (names) {
296 write_pident(header, names);
297 if (PREV_LINK(names))
298 fprintf(header, ", ");
299 names = PREV_LINK(names);
301 fprintf(header, ";\n");
303 if (get_attrp(type->attrs, ATTR_WIREMARSHAL)) {
304 names = lname;
305 while (names) {
306 char *name = get_name(names);
307 fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name);
308 fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name);
309 fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name);
310 fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name);
311 if (PREV_LINK(names))
312 fprintf(header, ", ");
313 names = PREV_LINK(names);
317 fprintf(header, "\n");
320 static void do_write_expr(FILE *h, expr_t *e, int p)
322 switch (e->type) {
323 case EXPR_VOID:
324 break;
325 case EXPR_NUM:
326 fprintf(h, "%ld", e->u.lval);
327 break;
328 case EXPR_HEXNUM:
329 fprintf(h, "0x%lx", e->u.lval);
330 break;
331 case EXPR_IDENTIFIER:
332 fprintf(h, "%s", e->u.sval);
333 break;
334 case EXPR_NEG:
335 fprintf(h, "-");
336 do_write_expr(h, e->ref, 1);
337 break;
338 case EXPR_NOT:
339 fprintf(h, "~");
340 do_write_expr(h, e->ref, 1);
341 break;
342 case EXPR_PPTR:
343 fprintf(h, "*");
344 do_write_expr(h, e->ref, 1);
345 break;
346 case EXPR_CAST:
347 fprintf(h, "(");
348 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
349 fprintf(h, ")");
350 do_write_expr(h, e->ref, 1);
351 break;
352 case EXPR_SIZEOF:
353 fprintf(h, "sizeof(");
354 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
355 fprintf(h, ")");
356 break;
357 case EXPR_SHL:
358 case EXPR_SHR:
359 case EXPR_MUL:
360 case EXPR_DIV:
361 case EXPR_ADD:
362 case EXPR_SUB:
363 case EXPR_AND:
364 case EXPR_OR:
365 if (p) fprintf(h, "(");
366 do_write_expr(h, e->ref, 1);
367 switch (e->type) {
368 case EXPR_SHL: fprintf(h, " << "); break;
369 case EXPR_SHR: fprintf(h, " >> "); break;
370 case EXPR_MUL: fprintf(h, " * "); break;
371 case EXPR_DIV: fprintf(h, " / "); break;
372 case EXPR_ADD: fprintf(h, " + "); break;
373 case EXPR_SUB: fprintf(h, " - "); break;
374 case EXPR_AND: fprintf(h, " & "); break;
375 case EXPR_OR: fprintf(h, " | "); break;
376 default: break;
378 do_write_expr(h, e->u.ext, 1);
379 if (p) fprintf(h, ")");
380 break;
381 case EXPR_COND:
382 if (p) fprintf(h, "(");
383 do_write_expr(h, e->ref, 1);
384 fprintf(h, " ? ");
385 do_write_expr(h, e->u.ext, 1);
386 fprintf(h, " : ");
387 do_write_expr(h, e->ext2, 1);
388 if (p) fprintf(h, ")");
389 break;
393 void write_expr(FILE *h, expr_t *e)
395 do_write_expr(h, e, 0);
398 void write_constdef(var_t *v)
400 fprintf(header, "#define %s (", get_name(v));
401 write_expr(header, v->eval);
402 fprintf(header, ")\n\n");
405 void write_externdef(var_t *v)
407 fprintf(header, "extern const ");
408 write_type(header, v->type, NULL, v->tname);
409 if (get_name(v)) {
410 fprintf(header, " ");
411 write_pident(header, v);
413 fprintf(header, ";\n\n");
416 /********** INTERFACES **********/
418 int is_object(attr_t *a)
420 while (a) {
421 if (a->type == ATTR_OBJECT || a->type == ATTR_ODL) return 1;
422 a = NEXT_LINK(a);
424 return 0;
427 int is_local(attr_t *a)
429 return is_attr(a, ATTR_LOCAL);
432 var_t *is_callas(attr_t *a)
434 return get_attrp(a, ATTR_CALLAS);
437 static void write_icom_method_def(type_t *iface)
439 func_t *cur = iface->funcs;
440 if (iface->ref) write_icom_method_def( iface->ref );
441 if (!cur) return;
442 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
443 if (cur) fprintf( header, " \\\n /*** %s methods ***/", iface->name );
444 while (cur) {
445 var_t *def = cur->def;
446 if (!is_callas(def->attrs)) {
447 var_t *arg = cur->args;
449 if (arg) {
450 while (NEXT_LINK(arg)) {
451 arg = NEXT_LINK(arg);
454 fprintf(header, " \\\n STDMETHOD_(");
455 write_type(header, def->type, def, def->tname);
456 fprintf(header, ",");
457 write_name(header, def);
458 fprintf(header, ")(%s", arg ? "THIS_ " : "THIS" );
459 while (arg) {
460 write_type(header, arg->type, arg, arg->tname);
461 if (arg->args)
463 fprintf(header, " (STDMETHODCALLTYPE *");
464 write_name(header,arg);
465 fprintf( header,")(");
466 write_args(header, arg->args, NULL, 0, FALSE);
467 fprintf(header,")");
469 else
471 fprintf(header, " ");
472 write_name(header,arg);
474 write_array(header, arg->array, 0);
475 arg = PREV_LINK(arg);
476 if (arg) fprintf(header, ", ");
478 fprintf(header, ") PURE;");
480 cur = PREV_LINK(cur);
484 static int write_method_macro(type_t *iface, char *name)
486 int idx;
487 func_t *cur = iface->funcs;
489 if (iface->ref) idx = write_method_macro(iface->ref, name);
490 else idx = 0;
492 if (!cur) return idx;
493 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
495 fprintf(header, "/*** %s methods ***/\n", iface->name);
496 while (cur) {
497 var_t *def = cur->def;
498 if (!is_callas(def->attrs)) {
499 var_t *arg = cur->args;
500 int argc = 0;
501 int c;
502 while (arg) {
503 arg = NEXT_LINK(arg);
504 argc++;
507 fprintf(header, "#define %s_", name);
508 write_name(header,def);
509 fprintf(header, "(p");
510 for (c=0; c<argc; c++)
511 fprintf(header, ",%c", c+'a');
512 fprintf(header, ") ");
514 fprintf(header, "(p)->lpVtbl->");
515 write_name(header, def);
516 fprintf(header, "(p");
517 for (c=0; c<argc; c++)
518 fprintf(header, ",%c", c+'a');
519 fprintf(header, ")\n");
520 if (cur->idx == -1) cur->idx = idx;
521 else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro");
522 idx++;
524 cur = PREV_LINK(cur);
526 return idx;
529 void write_args(FILE *h, var_t *arg, char *name, int method, int do_indent)
531 int count = 0;
532 if (arg) {
533 while (NEXT_LINK(arg))
534 arg = NEXT_LINK(arg);
536 if (do_indent)
538 if (h == header) {
539 indentation++;
540 indent(0);
541 } else fprintf(h, " ");
543 if (method == 1) {
544 fprintf(h, "%s* This", name);
545 count++;
547 while (arg) {
548 if (count) {
549 if (do_indent)
551 fprintf(h, ",\n");
552 if (h == header) indent(0);
553 else fprintf(h, " ");
555 else fprintf(h, ",");
557 write_type(h, arg->type, arg, arg->tname);
558 if (arg->args)
560 fprintf(h, " (STDMETHODCALLTYPE *");
561 write_name(h,arg);
562 fprintf(h, ")(");
563 write_args(h, arg->args, NULL, 0, FALSE);
564 fprintf(h, ")");
566 else
568 fprintf(h, " ");
569 write_name(h, arg);
571 write_array(h, arg->array, 0);
572 arg = PREV_LINK(arg);
573 count++;
575 if (do_indent && h == header) indentation--;
578 static void write_cpp_method_def(type_t *iface)
580 func_t *cur = iface->funcs;
582 if (!cur) return;
583 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
584 while (cur) {
585 var_t *def = cur->def;
586 if (!is_callas(def->attrs)) {
587 indent(0);
588 fprintf(header, "virtual ");
589 write_type(header, def->type, def, def->tname);
590 fprintf(header, " STDMETHODCALLTYPE ");
591 write_name(header, def);
592 fprintf(header, "(\n");
593 write_args(header, cur->args, iface->name, 2, TRUE);
594 fprintf(header, ") = 0;\n");
595 fprintf(header, "\n");
597 cur = PREV_LINK(cur);
601 static void do_write_c_method_def(type_t *iface, char *name)
603 func_t *cur = iface->funcs;
605 if (iface->ref) do_write_c_method_def(iface->ref, name);
607 if (!cur) return;
608 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
609 indent(0);
610 fprintf(header, "/*** %s methods ***/\n", iface->name);
611 while (cur) {
612 var_t *def = cur->def;
613 if (!is_callas(def->attrs)) {
614 indent(0);
615 write_type(header, def->type, def, def->tname);
616 fprintf(header, " (STDMETHODCALLTYPE *");
617 write_name(header, def);
618 fprintf(header, ")(\n");
619 write_args(header, cur->args, name, 1, TRUE);
620 fprintf(header, ");\n");
621 fprintf(header, "\n");
623 cur = PREV_LINK(cur);
627 static void write_c_method_def(type_t *iface)
629 do_write_c_method_def(iface, iface->name);
632 static void write_method_proto(type_t *iface)
634 func_t *cur = iface->funcs;
636 if (!cur) return;
637 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
638 while (cur) {
639 var_t *def = cur->def;
640 var_t *cas = is_callas(def->attrs);
641 if (!is_local(def->attrs)) {
642 /* proxy prototype */
643 write_type(header, def->type, def, def->tname);
644 fprintf(header, " CALLBACK %s_", iface->name);
645 write_name(header, def);
646 fprintf(header, "_Proxy(\n");
647 write_args(header, cur->args, iface->name, 1, TRUE);
648 fprintf(header, ");\n");
649 /* stub prototype */
650 fprintf(header, "void __RPC_STUB %s_", iface->name);
651 write_name(header,def);
652 fprintf(header, "_Stub(\n");
653 fprintf(header, " struct IRpcStubBuffer* This,\n");
654 fprintf(header, " struct IRpcChannelBuffer* pRpcChannelBuffer,\n");
655 fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
656 fprintf(header, " DWORD* pdwStubPhase);\n");
658 if (cas) {
659 func_t *m = iface->funcs;
660 while (m && strcmp(get_name(m->def), cas->name))
661 m = NEXT_LINK(m);
662 if (m) {
663 var_t *mdef = m->def;
664 /* proxy prototype - use local prototype */
665 write_type(header, mdef->type, mdef, mdef->tname);
666 fprintf(header, " CALLBACK %s_", iface->name);
667 write_name(header, mdef);
668 fprintf(header, "_Proxy(\n");
669 write_args(header, m->args, iface->name, 1, TRUE);
670 fprintf(header, ");\n");
671 /* stub prototype - use remotable prototype */
672 write_type(header, def->type, def, def->tname);
673 fprintf(header, " __RPC_STUB %s_", iface->name);
674 write_name(header, mdef);
675 fprintf(header, "_Stub(\n");
676 write_args(header, cur->args, iface->name, 1, TRUE);
677 fprintf(header, ");\n");
679 else {
680 yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name);
684 cur = PREV_LINK(cur);
688 static void write_function_proto(type_t *iface)
690 func_t *cur = iface->funcs;
691 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
692 while (cur) {
693 var_t *def = cur->def;
694 /* FIXME: do we need to handle call_as? */
695 write_type(header, def->type, def, def->tname);
696 fprintf(header, " ");
697 write_name(header, def);
698 fprintf(header, "(\n");
699 write_args(header, cur->args, iface->name, 0, TRUE);
700 fprintf(header, ");\n");
702 cur = PREV_LINK(cur);
706 void write_forward(type_t *iface)
708 /* C/C++ forwards should only be written for object interfaces, so if we
709 * have a full definition we only write one if we find [object] among the
710 * attributes - however, if we don't have a full definition at this point
711 * (i.e. this is an IDL forward), then we also assume that it is an object
712 * interface, since non-object interfaces shouldn't need forwards */
713 if ((!iface->defined || is_object(iface->attrs)) && !iface->written) {
714 fprintf(header,"#ifndef __%s_FWD_DEFINED__\n", iface->name);
715 fprintf(header,"#define __%s_FWD_DEFINED__\n", iface->name);
716 fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
717 fprintf(header, "#endif\n\n" );
718 iface->written = TRUE;
722 void write_guid(type_t *iface)
724 UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
725 if (!uuid) return;
726 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",
727 iface->name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
728 uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
731 void write_com_interface(type_t *iface)
733 if (!iface->funcs && !iface->ref) {
734 yywarning("%s has no methods", iface->name);
735 return;
738 fprintf(header, "/*****************************************************************************\n");
739 fprintf(header, " * %s interface\n", iface->name);
740 fprintf(header, " */\n");
741 fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
742 fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
743 write_guid(iface);
744 write_forward(iface);
745 /* C++ interface */
746 fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
747 if (iface->ref)
749 fprintf(header, "struct %s : public %s\n", iface->name, iface->ref->name);
750 fprintf(header, "{\n");
751 indentation++;
752 write_cpp_method_def(iface);
753 indentation--;
754 fprintf(header, "};\n");
756 else
758 fprintf(header, "struct %s\n", iface->name);
759 fprintf(header, "{\n");
760 fprintf(header, " BEGIN_INTERFACE\n");
761 fprintf(header, "\n");
762 indentation++;
763 write_cpp_method_def(iface);
764 indentation--;
765 fprintf(header, " END_INTERFACE\n");
766 fprintf(header, "};\n");
768 fprintf(header, "#else\n");
769 /* C interface */
770 fprintf(header, "typedef struct %sVtbl %sVtbl;\n", iface->name, iface->name);
771 fprintf(header, "struct %s {\n", iface->name);
772 fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name);
773 fprintf(header, "};\n");
774 fprintf(header, "struct %sVtbl {\n", iface->name);
775 indentation++;
776 fprintf(header, " BEGIN_INTERFACE\n");
777 fprintf(header, "\n");
778 write_c_method_def(iface);
779 indentation--;
780 fprintf(header, " END_INTERFACE\n");
781 fprintf(header, "};\n");
782 fprintf(header, "\n");
783 fprintf(header, "#ifdef COBJMACROS\n");
784 write_method_macro(iface, iface->name);
785 fprintf(header, "#endif\n");
786 fprintf(header, "\n");
787 fprintf(header, "#endif\n");
788 fprintf(header, "\n");
789 if (compat_icom) {
790 fprintf(header, "#define %s_METHODS", iface->name);
791 write_icom_method_def(iface);
792 fprintf(header, "\n\n");
794 write_method_proto(iface);
795 fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
798 void write_rpc_interface(type_t *iface)
800 unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
802 if (!iface->funcs) return;
804 fprintf(header, "/*****************************************************************************\n");
805 fprintf(header, " * %s interface (v%d.%d)\n", iface->name, LOWORD(ver), HIWORD(ver));
806 fprintf(header, " */\n");
807 write_guid(iface);
808 fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
809 fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
810 write_function_proto(iface);
811 fprintf(header, "\n");
813 /* FIXME: server/client code */
816 void write_interface(type_t *iface)
818 if (is_object(iface->attrs))
819 write_com_interface(iface);
820 else
821 write_rpc_interface(iface);