Change oldnames option from '-o' to '--oldnames'.
[reactos.git] / reactos / tools / widl / header.c
1 /*
2 * IDL Compiler
3 *
4 * Copyright 2002 Ove Kaaven
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include "config.h"
22
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>
32
33 #include "widl.h"
34 #include "utils.h"
35 #include "parser.h"
36 #include "header.h"
37
38 static int indentation = 0;
39
40 static void indent(int delta)
41 {
42 int c;
43 if (delta < 0) indentation += delta;
44 for (c=0; c<indentation; c++) fprintf(header, " ");
45 if (delta > 0) indentation += delta;
46 }
47
48 int is_base_type(type_t *t)
49 {
50 return (t->type == RPC_FC_BYTE || t->type == RPC_FC_CHAR ||
51 t->type == RPC_FC_SMALL || t->type == RPC_FC_USMALL ||
52 t->type == RPC_FC_WCHAR || t->type == RPC_FC_SHORT ||
53 t->type == RPC_FC_USHORT || t->type == RPC_FC_LONG ||
54 t->type == RPC_FC_ULONG || t->type == RPC_FC_FLOAT ||
55 t->type == RPC_FC_HYPER || t->type == RPC_FC_DOUBLE ||
56 t->type == RPC_FC_ENUM16 || t->type == RPC_FC_ENUM32 ||
57 t->type == RPC_FC_IGNORE);
58 }
59
60 int is_attr(attr_t *a, enum attr_type t)
61 {
62 while (a) {
63 if (a->type == t) return 1;
64 a = NEXT_LINK(a);
65 }
66 return 0;
67 }
68
69 void *get_attrp(attr_t *a, enum attr_type t)
70 {
71 while (a) {
72 if (a->type == t) return a->u.pval;
73 a = NEXT_LINK(a);
74 }
75 return NULL;
76 }
77
78 unsigned long get_attrv(attr_t *a, enum attr_type t)
79 {
80 while (a) {
81 if (a->type == t) return a->u.ival;
82 a = NEXT_LINK(a);
83 }
84 return 0;
85 }
86
87 int is_void(type_t *t, var_t *v)
88 {
89 if (v && v->ptr_level) return 0;
90 if (!t->type && !t->ref) return 1;
91 return 0;
92 }
93
94 static void write_pident(FILE *h, var_t *v)
95 {
96 int c;
97 for (c=0; c<v->ptr_level; c++) {
98 fprintf(h, "*");
99 }
100 if (v->name) fprintf(h, "%s", v->name);
101 }
102
103 void write_name(FILE *h, var_t *v)
104 {
105 if (is_attr( v->attrs, ATTR_PROPGET ))
106 fprintf(h, "get_" );
107 else if (is_attr( v->attrs, ATTR_PROPPUT ))
108 fprintf(h, "put_" );
109 fprintf(h, "%s", v->name);
110 }
111
112 char* get_name(var_t *v)
113 {
114 return v->name;
115 }
116
117 static void write_array(FILE *h, expr_t *v, int field)
118 {
119 if (!v) return;
120 while (NEXT_LINK(v)) v = NEXT_LINK(v);
121 fprintf(h, "[");
122 while (v) {
123 if (v->is_const)
124 fprintf(h, "%ld", v->cval); /* statically sized array */
125 else
126 if (field) fprintf(h, "1"); /* dynamically sized array */
127 if (PREV_LINK(v))
128 fprintf(h, ", ");
129 v = PREV_LINK(v);
130 }
131 fprintf(h, "]");
132 }
133
134 static void write_field(FILE *h, var_t *v)
135 {
136 if (!v) return;
137 if (v->type) {
138 indent(0);
139 write_type(h, v->type, NULL, v->tname);
140 if (get_name(v)) {
141 fprintf(h, " ");
142 write_pident(h, v);
143 }
144 else {
145 /* not all C/C++ compilers support anonymous structs and unions */
146 switch (v->type->type) {
147 case RPC_FC_STRUCT:
148 case RPC_FC_CVSTRUCT:
149 case RPC_FC_CPSTRUCT:
150 case RPC_FC_CSTRUCT:
151 case RPC_FC_PSTRUCT:
152 case RPC_FC_BOGUS_STRUCT:
153 case RPC_FC_ENCAPSULATED_UNION:
154 fprintf(h, " DUMMYSTRUCTNAME");
155 break;
156 case RPC_FC_NON_ENCAPSULATED_UNION:
157 fprintf(h, " DUMMYUNIONNAME");
158 break;
159 default:
160 /* ? */
161 break;
162 }
163 }
164 write_array(h, v->array, 1);
165 fprintf(h, ";\n");
166 }
167 }
168
169 static void write_fields(FILE *h, var_t *v)
170 {
171 var_t *first = v;
172 if (!v) return;
173 while (NEXT_LINK(v)) v = NEXT_LINK(v);
174 while (v) {
175 write_field(h, v);
176 if (v == first) break;
177 v = PREV_LINK(v);
178 }
179 }
180
181 static void write_enums(FILE *h, var_t *v)
182 {
183 if (!v) return;
184 while (NEXT_LINK(v)) v = NEXT_LINK(v);
185 while (v) {
186 if (get_name(v)) {
187 indent(0);
188 write_name(h, v);
189 if (v->eval) {
190 fprintf(h, " = ");
191 write_expr(h, v->eval);
192 }
193 }
194 if (PREV_LINK(v))
195 fprintf(h, ",\n");
196 v = PREV_LINK(v);
197 }
198 fprintf(h, "\n");
199 }
200
201 void write_type(FILE *h, type_t *t, var_t *v, char *n)
202 {
203 int c;
204
205 if (n) fprintf(h, "%s", n);
206 else {
207 if (t->is_const) fprintf(h, "const ");
208 if (t->type) {
209 if (t->sign > 0) fprintf(h, "signed ");
210 else if (t->sign < 0) fprintf(h, "unsigned ");
211 switch (t->type) {
212 case RPC_FC_BYTE:
213 if (t->ref) fprintf(h, t->ref->name);
214 else fprintf(h, "byte");
215 break;
216 case RPC_FC_CHAR:
217 if (t->ref) fprintf(h, t->ref->name);
218 else fprintf(h, "char");
219 break;
220 case RPC_FC_WCHAR:
221 fprintf(h, "wchar_t");
222 break;
223 case RPC_FC_USHORT:
224 case RPC_FC_SHORT:
225 if (t->ref) fprintf(h, t->ref->name);
226 else fprintf(h, "short");
227 break;
228 case RPC_FC_ULONG:
229 case RPC_FC_LONG:
230 if (t->ref) fprintf(h, t->ref->name);
231 else fprintf(h, "long");
232 break;
233 case RPC_FC_HYPER:
234 if (t->ref) fprintf(h, t->ref->name);
235 else fprintf(h, "hyper");
236 break;
237 case RPC_FC_FLOAT:
238 fprintf(h, "float");
239 break;
240 case RPC_FC_DOUBLE:
241 fprintf(h, "double");
242 break;
243 case RPC_FC_ENUM16:
244 case RPC_FC_ENUM32:
245 if (t->defined && !t->written) {
246 if (t->name) fprintf(h, "enum %s {\n", t->name);
247 else fprintf(h, "enum {\n");
248 t->written = TRUE;
249 indentation++;
250 write_enums(h, t->fields);
251 indent(-1);
252 fprintf(h, "}");
253 }
254 else fprintf(h, "enum %s", t->name);
255 break;
256 case RPC_FC_ERROR_STATUS_T:
257 if (t->ref) fprintf(h, t->ref->name);
258 else fprintf(h, "error_status_t");
259 break;
260 case RPC_FC_IGNORE:
261 if (t->ref) fprintf(h, t->ref->name);
262 else fprintf(h, "handle_t");
263 break;
264 case RPC_FC_STRUCT:
265 case RPC_FC_CVSTRUCT:
266 case RPC_FC_CPSTRUCT:
267 case RPC_FC_CSTRUCT:
268 case RPC_FC_PSTRUCT:
269 case RPC_FC_BOGUS_STRUCT:
270 case RPC_FC_ENCAPSULATED_UNION:
271 if (t->defined && !t->written) {
272 if (t->name) fprintf(h, "struct %s {\n", t->name);
273 else fprintf(h, "struct {\n");
274 t->written = TRUE;
275 indentation++;
276 write_fields(h, t->fields);
277 indent(-1);
278 fprintf(h, "}");
279 }
280 else fprintf(h, "struct %s", t->name);
281 break;
282 case RPC_FC_NON_ENCAPSULATED_UNION:
283 if (t->defined && !t->written) {
284 if (t->name) fprintf(h, "union %s {\n", t->name);
285 else fprintf(h, "union {\n");
286 t->written = TRUE;
287 indentation++;
288 write_fields(h, t->fields);
289 indent(-1);
290 fprintf(h, "}");
291 }
292 else fprintf(h, "union %s", t->name);
293 break;
294 default:
295 fprintf(h, "(unknown-type:%d)", t->type);
296 }
297 }
298 else {
299 if (t->ref) {
300 write_type(h, t->ref, NULL, t->name);
301 }
302 else fprintf(h, "void");
303 }
304 }
305 if (v) {
306 for (c=0; c<v->ptr_level; c++) {
307 fprintf(h, "*");
308 }
309 }
310 }
311
312 void write_typedef(type_t *type, var_t *names)
313 {
314 char *tname = names->tname;
315 var_t *lname;
316 while (NEXT_LINK(names)) names = NEXT_LINK(names);
317 lname = names;
318 fprintf(header, "typedef ");
319 write_type(header, type, NULL, tname);
320 fprintf(header, " ");
321 while (names) {
322 write_pident(header, names);
323 if (PREV_LINK(names))
324 fprintf(header, ", ");
325 names = PREV_LINK(names);
326 }
327 fprintf(header, ";\n");
328
329 if (get_attrp(type->attrs, ATTR_WIREMARSHAL)) {
330 names = lname;
331 while (names) {
332 char *name = get_name(names);
333 fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name);
334 fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name);
335 fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name);
336 fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name);
337 if (PREV_LINK(names))
338 fprintf(header, ", ");
339 names = PREV_LINK(names);
340 }
341 }
342
343 fprintf(header, "\n");
344 }
345
346 static void do_write_expr(FILE *h, expr_t *e, int p)
347 {
348 switch (e->type) {
349 case EXPR_VOID:
350 break;
351 case EXPR_NUM:
352 fprintf(h, "%ld", e->u.lval);
353 break;
354 case EXPR_HEXNUM:
355 fprintf(h, "0x%lx", e->u.lval);
356 break;
357 case EXPR_IDENTIFIER:
358 fprintf(h, "%s", e->u.sval);
359 break;
360 case EXPR_NEG:
361 fprintf(h, "-");
362 do_write_expr(h, e->ref, 1);
363 break;
364 case EXPR_NOT:
365 fprintf(h, "~");
366 do_write_expr(h, e->ref, 1);
367 break;
368 case EXPR_PPTR:
369 fprintf(h, "*");
370 do_write_expr(h, e->ref, 1);
371 break;
372 case EXPR_CAST:
373 fprintf(h, "(");
374 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
375 fprintf(h, ")");
376 do_write_expr(h, e->ref, 1);
377 break;
378 case EXPR_SIZEOF:
379 fprintf(h, "sizeof(");
380 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
381 fprintf(h, ")");
382 break;
383 case EXPR_SHL:
384 case EXPR_SHR:
385 case EXPR_MUL:
386 case EXPR_DIV:
387 case EXPR_ADD:
388 case EXPR_SUB:
389 case EXPR_AND:
390 case EXPR_OR:
391 if (p) fprintf(h, "(");
392 do_write_expr(h, e->ref, 1);
393 switch (e->type) {
394 case EXPR_SHL: fprintf(h, " << "); break;
395 case EXPR_SHR: fprintf(h, " >> "); break;
396 case EXPR_MUL: fprintf(h, " * "); break;
397 case EXPR_DIV: fprintf(h, " / "); break;
398 case EXPR_ADD: fprintf(h, " + "); break;
399 case EXPR_SUB: fprintf(h, " - "); break;
400 case EXPR_AND: fprintf(h, " & "); break;
401 case EXPR_OR: fprintf(h, " | "); break;
402 default: break;
403 }
404 do_write_expr(h, e->u.ext, 1);
405 if (p) fprintf(h, ")");
406 break;
407 case EXPR_COND:
408 if (p) fprintf(h, "(");
409 do_write_expr(h, e->ref, 1);
410 fprintf(h, " ? ");
411 do_write_expr(h, e->u.ext, 1);
412 fprintf(h, " : ");
413 do_write_expr(h, e->ext2, 1);
414 if (p) fprintf(h, ")");
415 break;
416 }
417 }
418
419 void write_expr(FILE *h, expr_t *e)
420 {
421 do_write_expr(h, e, 0);
422 }
423
424 void write_constdef(var_t *v)
425 {
426 fprintf(header, "#define %s (", get_name(v));
427 write_expr(header, v->eval);
428 fprintf(header, ")\n\n");
429 }
430
431 void write_externdef(var_t *v)
432 {
433 fprintf(header, "extern const ");
434 write_type(header, v->type, NULL, v->tname);
435 if (get_name(v)) {
436 fprintf(header, " ");
437 write_pident(header, v);
438 }
439 fprintf(header, ";\n\n");
440 }
441
442
443 var_t* get_explicit_handle_var(func_t* func)
444 {
445 var_t* var;
446
447 if (!func->args)
448 return NULL;
449
450 var = func->args;
451 while (NEXT_LINK(var)) var = NEXT_LINK(var);
452 while (var)
453 {
454 if (var->type->type == RPC_FC_IGNORE)
455 return var;
456
457 var = PREV_LINK(var);
458 }
459
460 return NULL;
461 }
462
463
464 /********** INTERFACES **********/
465
466 int is_object(attr_t *a)
467 {
468 while (a) {
469 if (a->type == ATTR_OBJECT || a->type == ATTR_ODL) return 1;
470 a = NEXT_LINK(a);
471 }
472 return 0;
473 }
474
475 int is_local(attr_t *a)
476 {
477 return is_attr(a, ATTR_LOCAL);
478 }
479
480 var_t *is_callas(attr_t *a)
481 {
482 return get_attrp(a, ATTR_CALLAS);
483 }
484
485 static int write_method_macro(type_t *iface, char *name)
486 {
487 int idx;
488 func_t *cur = iface->funcs;
489
490 if (iface->ref) idx = write_method_macro(iface->ref, name);
491 else idx = 0;
492
493 if (!cur) return idx;
494 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
495
496 fprintf(header, "/*** %s methods ***/\n", iface->name);
497 while (cur) {
498 var_t *def = cur->def;
499 if (!is_callas(def->attrs)) {
500 var_t *arg = cur->args;
501 int argc = 0;
502 int c;
503 while (arg) {
504 arg = NEXT_LINK(arg);
505 argc++;
506 }
507
508 fprintf(header, "#define %s_", name);
509 write_name(header,def);
510 fprintf(header, "(p");
511 for (c=0; c<argc; c++)
512 fprintf(header, ",%c", c+'a');
513 fprintf(header, ") ");
514
515 fprintf(header, "(p)->lpVtbl->");
516 write_name(header, def);
517 fprintf(header, "(p");
518 for (c=0; c<argc; c++)
519 fprintf(header, ",%c", c+'a');
520 fprintf(header, ")\n");
521 if (cur->idx == -1) cur->idx = idx;
522 else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro");
523 idx++;
524 }
525 cur = PREV_LINK(cur);
526 }
527 return idx;
528 }
529
530 void write_args(FILE *h, var_t *arg, char *name, int method, int do_indent)
531 {
532 int count = 0;
533 if (arg) {
534 while (NEXT_LINK(arg))
535 arg = NEXT_LINK(arg);
536 }
537 if (do_indent)
538 {
539 if (h == header) {
540 indentation++;
541 indent(0);
542 } else fprintf(h, " ");
543 }
544 if (method == 1) {
545 fprintf(h, "%s* This", name);
546 count++;
547 }
548 if (arg == NULL && method == 0) {
549 fprintf(h, "void");
550 return;
551 }
552 while (arg) {
553 if (count) {
554 if (do_indent)
555 {
556 fprintf(h, ",\n");
557 if (h == header) indent(0);
558 else fprintf(h, " ");
559 }
560 else fprintf(h, ",");
561 }
562 write_type(h, arg->type, arg, arg->tname);
563 if (arg->args)
564 {
565 fprintf(h, " (STDMETHODCALLTYPE *");
566 write_name(h,arg);
567 fprintf(h, ")(");
568 write_args(h, arg->args, NULL, 0, FALSE);
569 fprintf(h, ")");
570 }
571 else
572 {
573 fprintf(h, " ");
574 write_name(h, arg);
575 }
576 write_array(h, arg->array, 0);
577 arg = PREV_LINK(arg);
578 count++;
579 }
580 if (do_indent && h == header) indentation--;
581 }
582
583 static void write_cpp_method_def(type_t *iface)
584 {
585 func_t *cur = iface->funcs;
586
587 if (!cur) return;
588 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
589 while (cur) {
590 var_t *def = cur->def;
591 if (!is_callas(def->attrs)) {
592 indent(0);
593 fprintf(header, "virtual ");
594 write_type(header, def->type, def, def->tname);
595 fprintf(header, " STDMETHODCALLTYPE ");
596 write_name(header, def);
597 fprintf(header, "(\n");
598 write_args(header, cur->args, iface->name, 2, TRUE);
599 fprintf(header, ") = 0;\n");
600 fprintf(header, "\n");
601 }
602 cur = PREV_LINK(cur);
603 }
604 }
605
606 static void do_write_c_method_def(type_t *iface, char *name)
607 {
608 func_t *cur = iface->funcs;
609
610 if (iface->ref) do_write_c_method_def(iface->ref, name);
611
612 if (!cur) return;
613 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
614 indent(0);
615 fprintf(header, "/*** %s methods ***/\n", iface->name);
616 while (cur) {
617 var_t *def = cur->def;
618 if (!is_callas(def->attrs)) {
619 indent(0);
620 write_type(header, def->type, def, def->tname);
621 fprintf(header, " (STDMETHODCALLTYPE *");
622 write_name(header, def);
623 fprintf(header, ")(\n");
624 write_args(header, cur->args, name, 1, TRUE);
625 fprintf(header, ");\n");
626 fprintf(header, "\n");
627 }
628 cur = PREV_LINK(cur);
629 }
630 }
631
632 static void write_c_method_def(type_t *iface)
633 {
634 do_write_c_method_def(iface, iface->name);
635 }
636
637 static void write_c_disp_method_def(type_t *iface)
638 {
639 do_write_c_method_def(iface->ref, iface->name);
640 }
641
642 static void write_method_proto(type_t *iface)
643 {
644 func_t *cur = iface->funcs;
645
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");
667 }
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");
688 }
689 else {
690 yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name);
691 }
692 }
693
694 cur = PREV_LINK(cur);
695 }
696 }
697
698 static void write_function_proto(type_t *iface)
699 {
700 int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
701 var_t* explicit_handle_var;
702
703 func_t *cur = iface->funcs;
704 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
705 while (cur) {
706 var_t *def = cur->def;
707
708 /* check for a defined binding handle */
709 explicit_handle_var = get_explicit_handle_var(cur);
710 if (explicit_handle) {
711 if (!explicit_handle_var) {
712 error("%s() does not define an explicit binding handle!\n", def->name);
713 return;
714 }
715 } else {
716 if (explicit_handle_var) {
717 error("%s() must not define a binding handle!\n", def->name);
718 return;
719 }
720 }
721
722 /* FIXME: do we need to handle call_as? */
723 write_type(header, def->type, def, def->tname);
724 fprintf(header, " ");
725 write_name(header, def);
726 fprintf(header, "(\n");
727 write_args(header, cur->args, iface->name, 0, TRUE);
728 fprintf(header, ");\n");
729
730 cur = PREV_LINK(cur);
731 }
732 }
733
734 void write_forward(type_t *iface)
735 {
736 /* C/C++ forwards should only be written for object interfaces, so if we
737 * have a full definition we only write one if we find [object] among the
738 * attributes - however, if we don't have a full definition at this point
739 * (i.e. this is an IDL forward), then we also assume that it is an object
740 * interface, since non-object interfaces shouldn't need forwards */
741 if ((!iface->defined || is_object(iface->attrs) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
742 && !iface->written) {
743 fprintf(header,"#ifndef __%s_FWD_DEFINED__\n", iface->name);
744 fprintf(header,"#define __%s_FWD_DEFINED__\n", iface->name);
745 fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
746 fprintf(header, "#endif\n\n" );
747 iface->written = TRUE;
748 }
749 }
750
751 static void write_guid(const char *guid_prefix, const char *name, UUID *uuid)
752 {
753 if (!uuid) return;
754 fprintf(header, "DEFINE_GUID(%s_%s, 0x%08lx, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n",
755 guid_prefix, name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
756 uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
757 }
758
759 static void write_iface_guid(type_t *iface)
760 {
761 UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
762 write_guid("IID", iface->name, uuid);
763 }
764
765 static void write_dispiface_guid(type_t *iface)
766 {
767 UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
768 write_guid("DIID", iface->name, uuid);
769 }
770
771 static void write_coclass_guid(class_t *cocl)
772 {
773 UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID);
774 write_guid("CLSID", cocl->name, uuid);
775 }
776
777 static void write_com_interface(type_t *iface)
778 {
779 if (!iface->funcs && !iface->ref) {
780 yywarning("%s has no methods", iface->name);
781 return;
782 }
783
784 fprintf(header, "/*****************************************************************************\n");
785 fprintf(header, " * %s interface\n", iface->name);
786 fprintf(header, " */\n");
787 fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
788 fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
789 write_iface_guid(iface);
790 write_forward(iface);
791 /* C++ interface */
792 fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
793 if (iface->ref)
794 {
795 fprintf(header, "struct %s : public %s\n", iface->name, iface->ref->name);
796 fprintf(header, "{\n");
797 indentation++;
798 write_cpp_method_def(iface);
799 indentation--;
800 fprintf(header, "};\n");
801 }
802 else
803 {
804 fprintf(header, "struct %s\n", iface->name);
805 fprintf(header, "{\n");
806 fprintf(header, " BEGIN_INTERFACE\n");
807 fprintf(header, "\n");
808 indentation++;
809 write_cpp_method_def(iface);
810 indentation--;
811 fprintf(header, " END_INTERFACE\n");
812 fprintf(header, "};\n");
813 }
814 fprintf(header, "#else\n");
815 /* C interface */
816 fprintf(header, "typedef struct %sVtbl %sVtbl;\n", iface->name, iface->name);
817 fprintf(header, "struct %s {\n", iface->name);
818 fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name);
819 fprintf(header, "};\n");
820 fprintf(header, "struct %sVtbl {\n", iface->name);
821 indentation++;
822 fprintf(header, " BEGIN_INTERFACE\n");
823 fprintf(header, "\n");
824 write_c_method_def(iface);
825 indentation--;
826 fprintf(header, " END_INTERFACE\n");
827 fprintf(header, "};\n");
828 fprintf(header, "\n");
829 fprintf(header, "#ifdef COBJMACROS\n");
830 write_method_macro(iface, iface->name);
831 fprintf(header, "#endif\n");
832 fprintf(header, "\n");
833 fprintf(header, "#endif\n");
834 fprintf(header, "\n");
835 write_method_proto(iface);
836 fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
837 }
838
839 static void write_rpc_interface(type_t *iface)
840 {
841 unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
842 char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
843
844 if (!iface->funcs) return;
845
846 fprintf(header, "/*****************************************************************************\n");
847 fprintf(header, " * %s interface (v%d.%d)\n", iface->name, LOWORD(ver), HIWORD(ver));
848 fprintf(header, " */\n");
849 write_iface_guid(iface);
850 if (var)
851 {
852 fprintf(header, "extern handle_t %s;\n", var);
853 }
854 if (old_names)
855 {
856 fprintf(header, "extern RPC_IF_HANDLE %s_ClientIfHandle;\n", iface->name);
857 fprintf(header, "extern RPC_IF_HANDLE %s_ServerIfHandle;\n", iface->name);
858 }
859 else
860 {
861 fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
862 fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
863 }
864 write_function_proto(iface);
865 fprintf(header, "\n");
866
867 /* FIXME: server/client code */
868 }
869
870 void write_interface(type_t *iface)
871 {
872 if (is_object(iface->attrs))
873 write_com_interface(iface);
874 else
875 write_rpc_interface(iface);
876 }
877
878 void write_dispinterface(type_t *iface)
879 {
880 fprintf(header, "/*****************************************************************************\n");
881 fprintf(header, " * %s dispinterface\n", iface->name);
882 fprintf(header, " */\n");
883 fprintf(header,"#ifndef __%s_DISPINTERFACE_DEFINED__\n", iface->name);
884 fprintf(header,"#define __%s_DISPINTERFACE_DEFINED__\n\n", iface->name);
885 write_dispiface_guid(iface);
886 write_forward(iface);
887 /* C++ interface */
888 fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
889 fprintf(header, "struct %s : public %s\n", iface->name, iface->ref->name);
890 fprintf(header, "{\n");
891 fprintf(header, "};\n");
892 fprintf(header, "#else\n");
893 /* C interface */
894 fprintf(header, "typedef struct %sVtbl %sVtbl;\n", iface->name, iface->name);
895 fprintf(header, "struct %s {\n", iface->name);
896 fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name);
897 fprintf(header, "};\n");
898 fprintf(header, "struct %sVtbl {\n", iface->name);
899 indentation++;
900 fprintf(header, " BEGIN_INTERFACE\n");
901 fprintf(header, "\n");
902 write_c_disp_method_def(iface);
903 indentation--;
904 fprintf(header, " END_INTERFACE\n");
905 fprintf(header, "};\n");
906 fprintf(header, "\n");
907 fprintf(header, "#ifdef COBJMACROS\n");
908 write_method_macro(iface->ref, iface->name);
909 fprintf(header, "#endif\n");
910 fprintf(header, "\n");
911 fprintf(header, "#endif\n");
912 fprintf(header, "\n");
913 fprintf(header,"#endif /* __%s_DISPINTERFACE_DEFINED__ */\n\n", iface->name);
914 }
915
916 void write_coclass(class_t *cocl)
917 {
918 fprintf(header, "/*****************************************************************************\n");
919 fprintf(header, " * %s coclass\n", cocl->name);
920 fprintf(header, " */\n\n");
921 write_coclass_guid(cocl);
922 fprintf(header, "\n");
923 }