scrrun: Add missing id value.
[wine] / 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 #include <string.h>
30 #include <ctype.h>
31
32 #include "widl.h"
33 #include "utils.h"
34 #include "parser.h"
35 #include "header.h"
36 #include "expr.h"
37 #include "typetree.h"
38
39 static int indentation = 0;
40 static int is_object_interface = 0;
41 user_type_list_t user_type_list = LIST_INIT(user_type_list);
42 context_handle_list_t context_handle_list = LIST_INIT(context_handle_list);
43 generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
44
45 static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name);
46
47 static void indent(FILE *h, int delta)
48 {
49   int c;
50   if (delta < 0) indentation += delta;
51   for (c=0; c<indentation; c++) fprintf(h, "    ");
52   if (delta > 0) indentation += delta;
53 }
54
55 int is_ptrchain_attr(const var_t *var, enum attr_type t)
56 {
57     if (is_attr(var->attrs, t))
58         return 1;
59     else
60     {
61         type_t *type = var->type;
62         for (;;)
63         {
64             if (is_attr(type->attrs, t))
65                 return 1;
66             else if (type_is_alias(type))
67                 type = type_alias_get_aliasee(type);
68             else if (is_ptr(type))
69                 type = type_pointer_get_ref(type);
70             else return 0;
71         }
72     }
73 }
74
75 int is_aliaschain_attr(const type_t *type, enum attr_type attr)
76 {
77     const type_t *t = type;
78     for (;;)
79     {
80         if (is_attr(t->attrs, attr))
81             return 1;
82         else if (type_is_alias(t))
83             t = type_alias_get_aliasee(t);
84         else return 0;
85     }
86 }
87
88 int is_attr(const attr_list_t *list, enum attr_type t)
89 {
90     const attr_t *attr;
91     if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
92         if (attr->type == t) return 1;
93     return 0;
94 }
95
96 void *get_attrp(const attr_list_t *list, enum attr_type t)
97 {
98     const attr_t *attr;
99     if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
100         if (attr->type == t) return attr->u.pval;
101     return NULL;
102 }
103
104 unsigned int get_attrv(const attr_list_t *list, enum attr_type t)
105 {
106     const attr_t *attr;
107     if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
108         if (attr->type == t) return attr->u.ival;
109     return 0;
110 }
111
112 int is_void(const type_t *t)
113 {
114     return type_get_type(t) == TYPE_VOID;
115 }
116
117 int is_conformant_array(const type_t *t)
118 {
119     return is_array(t) && type_array_has_conformance(t);
120 }
121
122 void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid)
123 {
124   if (!uuid) return;
125   fprintf(f, "DEFINE_GUID(%s_%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,"
126         "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n",
127         guid_prefix, name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0],
128         uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5],
129         uuid->Data4[6], uuid->Data4[7]);
130 }
131
132 static void write_uuid_decl(FILE *f, const char *name, const UUID *uuid)
133 {
134   fprintf(f, "#ifdef __CRT_UUID_DECL\n");
135   fprintf(f, "__CRT_UUID_DECL(%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,"
136         "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
137         name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
138         uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6],
139         uuid->Data4[7]);
140   fprintf(f, "#endif\n");
141 }
142
143 static const char *uuid_string(const UUID *uuid)
144 {
145   static char buf[37];
146
147   sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
148         uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], uuid->Data4[2],
149         uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
150
151   return buf;
152 }
153
154 const char *get_name(const var_t *v)
155 {
156     static char buffer[256];
157
158     if (is_attr( v->attrs, ATTR_PROPGET ))
159         strcpy( buffer, "get_" );
160     else if (is_attr( v->attrs, ATTR_PROPPUT ))
161         strcpy( buffer, "put_" );
162     else if (is_attr( v->attrs, ATTR_PROPPUTREF ))
163         strcpy( buffer, "putref_" );
164     else
165         buffer[0] = 0;
166     strcat( buffer, v->name );
167     return buffer;
168 }
169
170 static void write_fields(FILE *h, var_list_t *fields)
171 {
172     unsigned nameless_struct_cnt = 0, nameless_struct_i = 0, nameless_union_cnt = 0, nameless_union_i = 0;
173     const char *name;
174     char buf[32];
175     var_t *v;
176
177     if (!fields) return;
178
179     LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
180         if (!v || !v->type) continue;
181
182         switch(type_get_type_detect_alias(v->type)) {
183         case TYPE_STRUCT:
184         case TYPE_ENCAPSULATED_UNION:
185             nameless_struct_cnt++;
186             break;
187         case TYPE_UNION:
188             nameless_union_cnt++;
189             break;
190         default:
191             ;
192         }
193     }
194
195     LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
196         if (!v || !v->type) continue;
197
198         indent(h, 0);
199         name = v->name;
200
201         switch(type_get_type_detect_alias(v->type)) {
202         case TYPE_STRUCT:
203         case TYPE_ENCAPSULATED_UNION:
204             if(!v->name) {
205                 fprintf(h, "__C89_NAMELESS ");
206                 if(nameless_struct_cnt == 1) {
207                     name = "__C89_NAMELESSSTRUCTNAME";
208                 }else if(nameless_struct_i < 5 /* # of supporting macros */) {
209                     sprintf(buf, "__C89_NAMELESSSTRUCTNAME%d", ++nameless_struct_i);
210                     name = buf;
211                 }
212             }
213             break;
214         case TYPE_UNION:
215             if(!v->name) {
216                 fprintf(h, "__C89_NAMELESS ");
217                 if(nameless_union_cnt == 1) {
218                     name = "__C89_NAMELESSUNIONNAME";
219                 }else if(nameless_union_i < 8 /* # of supporting macros */ ) {
220                     sprintf(buf, "__C89_NAMELESSUNIONNAME%d", ++nameless_union_i);
221                     name = buf;
222                 }
223             }
224             break;
225         default:
226             ;
227         }
228         write_type_def_or_decl(h, v->type, TRUE, name);
229         fprintf(h, ";\n");
230     }
231 }
232
233 static void write_enums(FILE *h, var_list_t *enums)
234 {
235   var_t *v;
236   if (!enums) return;
237   LIST_FOR_EACH_ENTRY( v, enums, var_t, entry )
238   {
239     if (v->name) {
240       indent(h, 0);
241       fprintf(h, "%s", get_name(v));
242       if (v->eval) {
243         fprintf(h, " = ");
244         write_expr(h, v->eval, 0, 1, NULL, NULL, "");
245       }
246     }
247     if (list_next( enums, &v->entry )) fprintf(h, ",\n");
248   }
249   fprintf(h, "\n");
250 }
251
252 int needs_space_after(type_t *t)
253 {
254   return (type_is_alias(t) ||
255           (!is_ptr(t) && (!is_array(t) || !type_array_is_decl_as_ptr(t) || t->name)));
256 }
257
258 void write_type_left(FILE *h, type_t *t, int declonly)
259 {
260   if (!h) return;
261
262   if (is_attr(t->attrs, ATTR_CONST) &&
263       (type_is_alias(t) || !is_ptr(t)))
264     fprintf(h, "const ");
265
266   if (type_is_alias(t)) fprintf(h, "%s", t->name);
267   else {
268     switch (type_get_type_detect_alias(t)) {
269       case TYPE_ENUM:
270         if (!declonly && t->defined && !t->written) {
271           if (t->name) fprintf(h, "enum %s {\n", t->name);
272           else fprintf(h, "enum {\n");
273           t->written = TRUE;
274           indentation++;
275           write_enums(h, type_enum_get_values(t));
276           indent(h, -1);
277           fprintf(h, "}");
278         }
279         else fprintf(h, "enum %s", t->name ? t->name : "");
280         break;
281       case TYPE_STRUCT:
282       case TYPE_ENCAPSULATED_UNION:
283         if (!declonly && t->defined && !t->written) {
284           if (t->name) fprintf(h, "struct %s {\n", t->name);
285           else fprintf(h, "struct {\n");
286           t->written = TRUE;
287           indentation++;
288           if (type_get_type(t) != TYPE_STRUCT)
289             write_fields(h, type_encapsulated_union_get_fields(t));
290           else
291             write_fields(h, type_struct_get_fields(t));
292           indent(h, -1);
293           fprintf(h, "}");
294         }
295         else fprintf(h, "struct %s", t->name ? t->name : "");
296         break;
297       case TYPE_UNION:
298         if (!declonly && t->defined && !t->written) {
299           if (t->name) fprintf(h, "union %s {\n", t->name);
300           else fprintf(h, "union {\n");
301           t->written = TRUE;
302           indentation++;
303           write_fields(h, type_union_get_cases(t));
304           indent(h, -1);
305           fprintf(h, "}");
306         }
307         else fprintf(h, "union %s", t->name ? t->name : "");
308         break;
309       case TYPE_POINTER:
310         write_type_left(h, type_pointer_get_ref(t), declonly);
311         fprintf(h, "%s*", needs_space_after(type_pointer_get_ref(t)) ? " " : "");
312         if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
313         break;
314       case TYPE_ARRAY:
315         if (t->name && type_array_is_decl_as_ptr(t))
316           fprintf(h, "%s", t->name);
317         else
318         {
319           write_type_left(h, type_array_get_element(t), declonly);
320           if (type_array_is_decl_as_ptr(t))
321             fprintf(h, "%s*", needs_space_after(type_array_get_element(t)) ? " " : "");
322         }
323         break;
324       case TYPE_BASIC:
325         if (type_basic_get_type(t) != TYPE_BASIC_INT32 &&
326             type_basic_get_type(t) != TYPE_BASIC_INT64 &&
327             type_basic_get_type(t) != TYPE_BASIC_HYPER)
328         {
329           if (type_basic_get_sign(t) < 0) fprintf(h, "signed ");
330           else if (type_basic_get_sign(t) > 0) fprintf(h, "unsigned ");
331         }
332         switch (type_basic_get_type(t))
333         {
334         case TYPE_BASIC_INT8: fprintf(h, "small"); break;
335         case TYPE_BASIC_INT16: fprintf(h, "short"); break;
336         case TYPE_BASIC_INT: fprintf(h, "int"); break;
337         case TYPE_BASIC_INT3264: fprintf(h, "__int3264"); break;
338         case TYPE_BASIC_BYTE: fprintf(h, "byte"); break;
339         case TYPE_BASIC_CHAR: fprintf(h, "char"); break;
340         case TYPE_BASIC_WCHAR: fprintf(h, "wchar_t"); break;
341         case TYPE_BASIC_FLOAT: fprintf(h, "float"); break;
342         case TYPE_BASIC_DOUBLE: fprintf(h, "double"); break;
343         case TYPE_BASIC_ERROR_STATUS_T: fprintf(h, "error_status_t"); break;
344         case TYPE_BASIC_HANDLE: fprintf(h, "handle_t"); break;
345         case TYPE_BASIC_INT32:
346           if (type_basic_get_sign(t) > 0)
347             fprintf(h, "ULONG");
348           else
349             fprintf(h, "LONG");
350           break;
351         case TYPE_BASIC_INT64:
352           if (type_basic_get_sign(t) > 0)
353             fprintf(h, "UINT64");
354           else
355             fprintf(h, "INT64");
356           break;
357         case TYPE_BASIC_HYPER:
358           if (type_basic_get_sign(t) > 0)
359             fprintf(h, "MIDL_uhyper");
360           else
361             fprintf(h, "hyper");
362           break;
363         }
364         break;
365       case TYPE_INTERFACE:
366       case TYPE_MODULE:
367       case TYPE_COCLASS:
368         fprintf(h, "%s", t->name);
369         break;
370       case TYPE_VOID:
371         fprintf(h, "void");
372         break;
373       case TYPE_BITFIELD:
374         write_type_left(h, type_bitfield_get_field(t), declonly);
375         break;
376       case TYPE_ALIAS:
377       case TYPE_FUNCTION:
378         /* handled elsewhere */
379         assert(0);
380         break;
381     }
382   }
383 }
384
385 void write_type_right(FILE *h, type_t *t, int is_field)
386 {
387   if (!h) return;
388
389   switch (type_get_type(t))
390   {
391   case TYPE_ARRAY:
392     if (!type_array_is_decl_as_ptr(t))
393     {
394       if (is_conformant_array(t))
395       {
396         fprintf(h, "[%s]", is_field ? "1" : "");
397         t = type_array_get_element(t);
398       }
399       for ( ;
400            type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t);
401            t = type_array_get_element(t))
402         fprintf(h, "[%u]", type_array_get_dim(t));
403     }
404     break;
405   case TYPE_BITFIELD:
406     fprintf(h, " : %u", type_bitfield_get_bits(t)->cval);
407     break;
408   case TYPE_VOID:
409   case TYPE_BASIC:
410   case TYPE_ENUM:
411   case TYPE_STRUCT:
412   case TYPE_ENCAPSULATED_UNION:
413   case TYPE_UNION:
414   case TYPE_ALIAS:
415   case TYPE_MODULE:
416   case TYPE_COCLASS:
417   case TYPE_FUNCTION:
418   case TYPE_INTERFACE:
419   case TYPE_POINTER:
420     break;
421   }
422 }
423
424 static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
425 {
426   type_t *pt = NULL;
427   int ptr_level = 0;
428
429   if (!h) return;
430
431   if (t) {
432     for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
433       ;
434
435     if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
436       int i;
437       const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
438       if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE";
439       if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
440       write_type_left(h, type_function_get_rettype(pt), declonly);
441       fputc(' ', h);
442       if (ptr_level) fputc('(', h);
443       if (callconv) fprintf(h, "%s ", callconv);
444       for (i = 0; i < ptr_level; i++)
445         fputc('*', h);
446     } else
447       write_type_left(h, t, declonly);
448   }
449
450   if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
451
452   if (t) {
453     if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
454       const var_list_t *args = type_function_get_args(pt);
455
456       if (ptr_level) fputc(')', h);
457       fputc('(', h);
458       if (args)
459           write_args(h, args, NULL, 0, FALSE);
460       else
461           fprintf(h, "void");
462       fputc(')', h);
463     } else
464       write_type_right(h, t, is_field);
465   }
466 }
467
468 static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
469 {
470   write_type_v(f, t, field, FALSE, name);
471 }
472
473 void write_type_decl(FILE *f, type_t *t, const char *name)
474 {
475   write_type_v(f, t, FALSE, TRUE, name);
476 }
477
478 void write_type_decl_left(FILE *f, type_t *t)
479 {
480   write_type_left(f, t, TRUE);
481 }
482
483 static int user_type_registered(const char *name)
484 {
485   user_type_t *ut;
486   LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry)
487     if (!strcmp(name, ut->name))
488       return 1;
489   return 0;
490 }
491
492 static int context_handle_registered(const char *name)
493 {
494   context_handle_t *ch;
495   LIST_FOR_EACH_ENTRY(ch, &context_handle_list, context_handle_t, entry)
496     if (!strcmp(name, ch->name))
497       return 1;
498   return 0;
499 }
500
501 static int generic_handle_registered(const char *name)
502 {
503   generic_handle_t *gh;
504   LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry)
505     if (!strcmp(name, gh->name))
506       return 1;
507   return 0;
508 }
509
510 unsigned int get_context_handle_offset( const type_t *type )
511 {
512     context_handle_t *ch;
513     unsigned int index = 0;
514
515     while (!is_attr( type->attrs, ATTR_CONTEXTHANDLE ))
516     {
517         if (type_is_alias( type )) type = type_alias_get_aliasee( type );
518         else if (is_ptr( type )) type = type_pointer_get_ref( type );
519         else error( "internal error: %s is not a context handle\n", type->name );
520     }
521     LIST_FOR_EACH_ENTRY( ch, &context_handle_list, context_handle_t, entry )
522     {
523         if (!strcmp( type->name, ch->name )) return index;
524         index++;
525     }
526     error( "internal error: %s is not registered as a context handle\n", type->name );
527     return index;
528 }
529
530 unsigned int get_generic_handle_offset( const type_t *type )
531 {
532     generic_handle_t *gh;
533     unsigned int index = 0;
534
535     while (!is_attr( type->attrs, ATTR_HANDLE ))
536     {
537         if (type_is_alias( type )) type = type_alias_get_aliasee( type );
538         else if (is_ptr( type )) type = type_pointer_get_ref( type );
539         else error( "internal error: %s is not a generic handle\n", type->name );
540     }
541     LIST_FOR_EACH_ENTRY( gh, &generic_handle_list, generic_handle_t, entry )
542     {
543         if (!strcmp( type->name, gh->name )) return index;
544         index++;
545     }
546     error( "internal error: %s is not registered as a generic handle\n", type->name );
547     return index;
548 }
549
550 /* check for types which require additional prototypes to be generated in the
551  * header */
552 void check_for_additional_prototype_types(const var_list_t *list)
553 {
554   const var_t *v;
555
556   if (!list) return;
557   LIST_FOR_EACH_ENTRY( v, list, const var_t, entry )
558   {
559     type_t *type = v->type;
560     if (!type) continue;
561     for (;;) {
562       const char *name = type->name;
563       if (type->user_types_registered) break;
564       type->user_types_registered = 1;
565       if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
566         if (!context_handle_registered(name))
567         {
568           context_handle_t *ch = xmalloc(sizeof(*ch));
569           ch->name = xstrdup(name);
570           list_add_tail(&context_handle_list, &ch->entry);
571         }
572         /* don't carry on parsing fields within this type */
573         break;
574       }
575       if ((type_get_type(type) != TYPE_BASIC ||
576            type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
577           is_attr(type->attrs, ATTR_HANDLE)) {
578         if (!generic_handle_registered(name))
579         {
580           generic_handle_t *gh = xmalloc(sizeof(*gh));
581           gh->name = xstrdup(name);
582           list_add_tail(&generic_handle_list, &gh->entry);
583         }
584         /* don't carry on parsing fields within this type */
585         break;
586       }
587       if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
588         if (!user_type_registered(name))
589         {
590           user_type_t *ut = xmalloc(sizeof *ut);
591           ut->name = xstrdup(name);
592           list_add_tail(&user_type_list, &ut->entry);
593         }
594         /* don't carry on parsing fields within this type as we are already
595          * using a wire marshaled type */
596         break;
597       }
598       else if (type_is_complete(type))
599       {
600         var_list_t *vars;
601         switch (type_get_type_detect_alias(type))
602         {
603         case TYPE_ENUM:
604           vars = type_enum_get_values(type);
605           break;
606         case TYPE_STRUCT:
607           vars = type_struct_get_fields(type);
608           break;
609         case TYPE_UNION:
610           vars = type_union_get_cases(type);
611           break;
612         default:
613           vars = NULL;
614           break;
615         }
616         check_for_additional_prototype_types(vars);
617       }
618
619       if (type_is_alias(type))
620         type = type_alias_get_aliasee(type);
621       else if (is_ptr(type))
622         type = type_pointer_get_ref(type);
623       else if (is_array(type))
624         type = type_array_get_element(type);
625       else
626         break;
627     }
628   }
629 }
630
631 static void write_user_types(FILE *header)
632 {
633   user_type_t *ut;
634   LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry)
635   {
636     const char *name = ut->name;
637     fprintf(header, "ULONG           __RPC_USER %s_UserSize     (ULONG *, ULONG, %s *);\n", name, name);
638     fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal  (ULONG *, unsigned char *, %s *);\n", name, name);
639     fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(ULONG *, unsigned char *, %s *);\n", name, name);
640     fprintf(header, "void            __RPC_USER %s_UserFree     (ULONG *, %s *);\n", name, name);
641   }
642 }
643
644 static void write_context_handle_rundowns(FILE *header)
645 {
646   context_handle_t *ch;
647   LIST_FOR_EACH_ENTRY(ch, &context_handle_list, context_handle_t, entry)
648   {
649     const char *name = ch->name;
650     fprintf(header, "void __RPC_USER %s_rundown(%s);\n", name, name);
651   }
652 }
653
654 static void write_generic_handle_routines(FILE *header)
655 {
656   generic_handle_t *gh;
657   LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry)
658   {
659     const char *name = gh->name;
660     fprintf(header, "handle_t __RPC_USER %s_bind(%s);\n", name, name);
661     fprintf(header, "void __RPC_USER %s_unbind(%s, handle_t);\n", name, name);
662   }
663 }
664
665 static void write_typedef(FILE *header, type_t *type)
666 {
667   fprintf(header, "typedef ");
668   write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name);
669   fprintf(header, ";\n");
670 }
671
672 int is_const_decl(const var_t *var)
673 {
674   const type_t *t;
675   /* strangely, MIDL accepts a const attribute on any pointer in the
676   * declaration to mean that data isn't being instantiated. this appears
677   * to be a bug, but there is no benefit to being incompatible with MIDL,
678   * so we'll do the same thing */
679   for (t = var->type; ; )
680   {
681     if (is_attr(t->attrs, ATTR_CONST))
682       return TRUE;
683     else if (is_ptr(t))
684       t = type_pointer_get_ref(t);
685     else break;
686   }
687   return FALSE;
688 }
689
690 static void write_declaration(FILE *header, const var_t *v)
691 {
692   if (is_const_decl(v) && v->eval)
693   {
694     fprintf(header, "#define %s (", v->name);
695     write_expr(header, v->eval, 0, 1, NULL, NULL, "");
696     fprintf(header, ")\n\n");
697   }
698   else
699   {
700     switch (v->stgclass)
701     {
702       case STG_NONE:
703       case STG_REGISTER: /* ignored */
704         break;
705       case STG_STATIC:
706         fprintf(header, "static ");
707         break;
708       case STG_EXTERN:
709         fprintf(header, "extern ");
710         break;
711     }
712     write_type_def_or_decl(header, v->type, FALSE, v->name);
713     fprintf(header, ";\n\n");
714   }
715 }
716
717 static void write_library(FILE *header, const typelib_t *typelib)
718 {
719   const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID);
720   fprintf(header, "\n");
721   write_guid(header, "LIBID", typelib->name, uuid);
722   fprintf(header, "\n");
723 }
724
725
726 const type_t* get_explicit_generic_handle_type(const var_t* var)
727 {
728     const type_t *t;
729     for (t = var->type;
730          is_ptr(t) || type_is_alias(t);
731          t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
732         if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) &&
733             is_attr(t->attrs, ATTR_HANDLE))
734             return t;
735     return NULL;
736 }
737
738 const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
739                                   unsigned char *explicit_fc, unsigned char *implicit_fc )
740 {
741     const var_t *var;
742     const var_list_t *args = type_get_function_args( func->type );
743
744     *explicit_fc = *implicit_fc = 0;
745     if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
746     {
747         if (!is_attr( var->attrs, ATTR_IN ) && is_attr( var->attrs, ATTR_OUT )) continue;
748         if (type_get_type( var->type ) == TYPE_BASIC && type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
749         {
750             *explicit_fc = RPC_FC_BIND_PRIMITIVE;
751             return var;
752         }
753         if (get_explicit_generic_handle_type( var ))
754         {
755             *explicit_fc = RPC_FC_BIND_GENERIC;
756             return var;
757         }
758         if (is_context_handle( var->type ))
759         {
760             *explicit_fc = RPC_FC_BIND_CONTEXT;
761             return var;
762         }
763     }
764
765     if ((var = get_attrp( iface->attrs, ATTR_IMPLICIT_HANDLE )))
766     {
767         if (type_get_type( var->type ) == TYPE_BASIC &&
768             type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
769             *implicit_fc = RPC_FC_BIND_PRIMITIVE;
770         else
771             *implicit_fc = RPC_FC_BIND_GENERIC;
772         return var;
773     }
774
775     *implicit_fc = RPC_FC_AUTO_HANDLE;
776     return NULL;
777 }
778
779 int has_out_arg_or_return(const var_t *func)
780 {
781     const var_t *var;
782
783     if (!is_void(type_function_get_rettype(func->type)))
784         return 1;
785
786     if (!type_get_function_args(func->type))
787         return 0;
788
789     LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
790         if (is_attr(var->attrs, ATTR_OUT))
791             return 1;
792
793     return 0;
794 }
795
796
797 /********** INTERFACES **********/
798
799 int is_object(const type_t *iface)
800 {
801     const attr_t *attr;
802     if (type_is_defined(iface) && type_iface_get_inherit(iface))
803         return 1;
804     if (iface->attrs) LIST_FOR_EACH_ENTRY( attr, iface->attrs, const attr_t, entry )
805         if (attr->type == ATTR_OBJECT || attr->type == ATTR_ODL) return 1;
806     return 0;
807 }
808
809 int is_local(const attr_list_t *a)
810 {
811   return is_attr(a, ATTR_LOCAL);
812 }
813
814 const var_t *is_callas(const attr_list_t *a)
815 {
816   return get_attrp(a, ATTR_CALLAS);
817 }
818
819 static int is_inherited_method(const type_t *iface, const var_t *func)
820 {
821   while ((iface = type_iface_get_inherit(iface)))
822   {
823     const statement_t *stmt;
824     STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
825     {
826       const var_t *funccmp = stmt->u.var;
827
828       if (!is_callas(func->attrs))
829       {
830          char inherit_name[256];
831          /* compare full name including property prefix */
832          strcpy(inherit_name, get_name(funccmp));
833          if (!strcmp(inherit_name, get_name(func))) return 1;
834       }
835     }
836   }
837
838   return 0;
839 }
840
841 static void write_method_macro(FILE *header, const type_t *iface, const char *name)
842 {
843   const statement_t *stmt;
844   int first_iface = 1;
845
846   if (type_iface_get_inherit(iface))
847     write_method_macro(header, type_iface_get_inherit(iface), name);
848
849   STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
850   {
851     const var_t *func = stmt->u.var;
852
853     if (first_iface)
854     {
855       fprintf(header, "/*** %s methods ***/\n", iface->name);
856       first_iface = 0;
857     }
858
859     if (!is_callas(func->attrs) && !is_inherited_method(iface, func)) {
860       const var_t *arg;
861
862       fprintf(header, "#define %s_%s(This", name, get_name(func));
863       if (type_get_function_args(func->type))
864           LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
865               fprintf(header, ",%s", arg->name);
866       fprintf(header, ") ");
867
868       fprintf(header, "(This)->lpVtbl->%s(This", get_name(func));
869       if (type_get_function_args(func->type))
870           LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
871               fprintf(header, ",%s", arg->name);
872       fprintf(header, ")\n");
873     }
874   }
875 }
876
877 void write_args(FILE *h, const var_list_t *args, const char *name, int method, int do_indent)
878 {
879   const var_t *arg;
880   int count = 0;
881
882   if (do_indent)
883   {
884       indentation++;
885       indent(h, 0);
886   }
887   if (method == 1) {
888     fprintf(h, "%s* This", name);
889     count++;
890   }
891   if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) {
892     if (count) {
893         if (do_indent)
894         {
895             fprintf(h, ",\n");
896             indent(h, 0);
897         }
898         else fprintf(h, ",");
899     }
900     write_type_decl(h, arg->type, arg->name);
901     if (method == 2) {
902         const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE);
903         if (expr) {
904             fprintf(h, " = ");
905             write_expr( h, expr, 0, 1, NULL, NULL, "" );
906         }
907     }
908     count++;
909   }
910   if (do_indent) indentation--;
911 }
912
913 static void write_cpp_method_def(FILE *header, const type_t *iface)
914 {
915   const statement_t *stmt;
916
917   STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
918   {
919     const var_t *func = stmt->u.var;
920     if (!is_callas(func->attrs)) {
921       const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
922       if (!callconv) callconv = "STDMETHODCALLTYPE";
923       indent(header, 0);
924       fprintf(header, "virtual ");
925       write_type_decl_left(header, type_function_get_rettype(func->type));
926       fprintf(header, " %s %s(\n", callconv, get_name(func));
927       write_args(header, type_get_function_args(func->type), iface->name, 2, TRUE);
928       fprintf(header, ") = 0;\n");
929       fprintf(header, "\n");
930     }
931   }
932 }
933
934 static void write_inline_wrappers(FILE *header, const type_t *iface, const char *name)
935 {
936   const statement_t *stmt;
937   int first_iface = 1;
938
939   if (type_iface_get_inherit(iface))
940     write_inline_wrappers(header, type_iface_get_inherit(iface), name);
941
942   STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
943   {
944     const var_t *func = stmt->u.var;
945
946     if (first_iface)
947     {
948       fprintf(header, "/*** %s methods ***/\n", iface->name);
949       first_iface = 0;
950     }
951
952     if (!is_callas(func->attrs) && !is_inherited_method(iface, func)) {
953       const var_t *arg;
954
955       fprintf(header, "static FORCEINLINE ");
956       write_type_decl_left(header, type_function_get_rettype(func->type));
957       fprintf(header, " %s_%s(", name, get_name(func));
958       write_args(header, type_get_function_args(func->type), name, 1, FALSE);
959       fprintf(header, ") {\n");
960       fprintf(header, "    %s", is_void(type_function_get_rettype(func->type)) ? "" : "return ");
961       fprintf(header, "This->lpVtbl->%s(This", get_name(func));
962       if (type_get_function_args(func->type))
963           LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
964               fprintf(header, ",%s", arg->name);
965       fprintf(header, ");\n");
966       fprintf(header, "}\n");
967     }
968   }
969 }
970
971 static void do_write_c_method_def(FILE *header, const type_t *iface, const char *name)
972 {
973   const statement_t *stmt;
974   int first_iface = 1;
975
976   if (type_iface_get_inherit(iface))
977     do_write_c_method_def(header, type_iface_get_inherit(iface), name);
978
979   STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
980   {
981     const var_t *func = stmt->u.var;
982     if (first_iface) {
983       indent(header, 0);
984       fprintf(header, "/*** %s methods ***/\n", iface->name);
985       first_iface = 0;
986     }
987     if (!is_callas(func->attrs)) {
988       const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
989       if (!callconv) callconv = "STDMETHODCALLTYPE";
990       indent(header, 0);
991       write_type_decl_left(header, type_function_get_rettype(func->type));
992       if (is_inherited_method(iface, func))
993         fprintf(header, " (%s *%s_%s)(\n", callconv, iface->name, func->name);
994       else
995         fprintf(header, " (%s *%s)(\n", callconv, get_name(func));
996       write_args(header, type_get_function_args(func->type), name, 1, TRUE);
997       fprintf(header, ");\n");
998       fprintf(header, "\n");
999     }
1000   }
1001 }
1002
1003 static void write_c_method_def(FILE *header, const type_t *iface)
1004 {
1005   do_write_c_method_def(header, iface, iface->name);
1006 }
1007
1008 static void write_c_disp_method_def(FILE *header, const type_t *iface)
1009 {
1010   do_write_c_method_def(header, type_iface_get_inherit(iface), iface->name);
1011 }
1012
1013 static void write_method_proto(FILE *header, const type_t *iface)
1014 {
1015   const statement_t *stmt;
1016
1017   STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
1018   {
1019     const var_t *func = stmt->u.var;
1020
1021     if (!is_local(func->attrs)) {
1022       const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
1023       if (!callconv) callconv = "STDMETHODCALLTYPE";
1024       /* proxy prototype */
1025       write_type_decl_left(header, type_function_get_rettype(func->type));
1026       fprintf(header, " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
1027       write_args(header, type_get_function_args(func->type), iface->name, 1, TRUE);
1028       fprintf(header, ");\n");
1029       /* stub prototype */
1030       fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func));
1031       fprintf(header, "    IRpcStubBuffer* This,\n");
1032       fprintf(header, "    IRpcChannelBuffer* pRpcChannelBuffer,\n");
1033       fprintf(header, "    PRPC_MESSAGE pRpcMessage,\n");
1034       fprintf(header, "    DWORD* pdwStubPhase);\n");
1035     }
1036   }
1037 }
1038
1039 static void write_locals(FILE *fp, const type_t *iface, int body)
1040 {
1041   static const char comment[]
1042     = "/* WIDL-generated stub.  You must provide an implementation for this.  */";
1043   const statement_t *stmt;
1044
1045   if (!is_object(iface))
1046     return;
1047
1048   STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface)) {
1049     const var_t *func = stmt->u.var;
1050     const var_t *cas = is_callas(func->attrs);
1051
1052     if (cas) {
1053       const statement_t *stmt2 = NULL;
1054       STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface))
1055         if (!strcmp(stmt2->u.var->name, cas->name))
1056           break;
1057       if (&stmt2->entry != type_iface_get_stmts(iface)) {
1058         const var_t *m = stmt2->u.var;
1059         /* proxy prototype - use local prototype */
1060         write_type_decl_left(fp, type_function_get_rettype(m->type));
1061         fprintf(fp, " CALLBACK %s_%s_Proxy(\n", iface->name, get_name(m));
1062         write_args(fp, type_get_function_args(m->type), iface->name, 1, TRUE);
1063         fprintf(fp, ")");
1064         if (body) {
1065           type_t *rt = type_function_get_rettype(m->type);
1066           fprintf(fp, "\n{\n");
1067           fprintf(fp, "    %s\n", comment);
1068           if (rt->name && strcmp(rt->name, "HRESULT") == 0)
1069             fprintf(fp, "    return E_NOTIMPL;\n");
1070           else if (type_get_type(rt) != TYPE_VOID) {
1071             fprintf(fp, "    ");
1072             write_type_decl(fp, rt, "rv");
1073             fprintf(fp, ";\n");
1074             fprintf(fp, "    memset(&rv, 0, sizeof rv);\n");
1075             fprintf(fp, "    return rv;\n");
1076           }
1077           fprintf(fp, "}\n\n");
1078         }
1079         else
1080           fprintf(fp, ";\n");
1081         /* stub prototype - use remotable prototype */
1082         write_type_decl_left(fp, type_function_get_rettype(func->type));
1083         fprintf(fp, " __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(m));
1084         write_args(fp, type_get_function_args(func->type), iface->name, 1, TRUE);
1085         fprintf(fp, ")");
1086         if (body)
1087           /* Remotable methods must all return HRESULTs.  */
1088           fprintf(fp, "\n{\n    %s\n    return E_NOTIMPL;\n}\n\n", comment);
1089         else
1090           fprintf(fp, ";\n");
1091       }
1092       else
1093         error_loc("invalid call_as attribute (%s -> %s)\n", func->name, cas->name);
1094     }
1095   }
1096 }
1097
1098 static void write_local_stubs_stmts(FILE *local_stubs, const statement_list_t *stmts)
1099 {
1100   const statement_t *stmt;
1101   if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
1102   {
1103     if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
1104       write_locals(local_stubs, stmt->u.type, TRUE);
1105   }
1106 }
1107
1108 void write_local_stubs(const statement_list_t *stmts)
1109 {
1110   FILE *local_stubs;
1111
1112   if (!local_stubs_name) return;
1113
1114   local_stubs = fopen(local_stubs_name, "w");
1115   if (!local_stubs) {
1116     error("Could not open %s for output\n", local_stubs_name);
1117     return;
1118   }
1119   fprintf(local_stubs, "/* call_as/local stubs for %s */\n\n", input_name);
1120   fprintf(local_stubs, "#include <objbase.h>\n");
1121   fprintf(local_stubs, "#include \"%s\"\n\n", header_name);
1122
1123   write_local_stubs_stmts(local_stubs, stmts);
1124
1125   fclose(local_stubs);
1126 }
1127
1128 static void write_function_proto(FILE *header, const type_t *iface, const var_t *fun, const char *prefix)
1129 {
1130   const char *callconv = get_attrp(fun->type->attrs, ATTR_CALLCONV);
1131
1132   if (!callconv) callconv = "__cdecl";
1133   /* FIXME: do we need to handle call_as? */
1134   write_type_decl_left(header, type_function_get_rettype(fun->type));
1135   fprintf(header, " %s ", callconv);
1136   fprintf(header, "%s%s(\n", prefix, get_name(fun));
1137   if (type_get_function_args(fun->type))
1138     write_args(header, type_get_function_args(fun->type), iface->name, 0, TRUE);
1139   else
1140     fprintf(header, "    void");
1141   fprintf(header, ");\n\n");
1142 }
1143
1144 static void write_forward(FILE *header, type_t *iface)
1145 {
1146   fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->name);
1147   fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->name);
1148   fprintf(header, "typedef interface %s %s;\n", iface->name, iface->name);
1149   fprintf(header, "#endif\n\n" );
1150 }
1151
1152 static void write_com_interface_start(FILE *header, const type_t *iface)
1153 {
1154   int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
1155   fprintf(header, "/*****************************************************************************\n");
1156   fprintf(header, " * %s %sinterface\n", iface->name, dispinterface ? "disp" : "");
1157   fprintf(header, " */\n");
1158   fprintf(header,"#ifndef __%s_%sINTERFACE_DEFINED__\n", iface->name, dispinterface ? "DISP" : "");
1159   fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->name, dispinterface ? "DISP" : "");
1160 }
1161
1162 static void write_com_interface_end(FILE *header, type_t *iface)
1163 {
1164   int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
1165   const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
1166
1167   if (uuid)
1168       write_guid(header, dispinterface ? "DIID" : "IID", iface->name, uuid);
1169
1170   /* C++ interface */
1171   fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
1172   if (uuid)
1173       fprintf(header, "MIDL_INTERFACE(\"%s\")\n", uuid_string(uuid));
1174   else
1175       fprintf(header, "interface ");
1176   if (type_iface_get_inherit(iface))
1177   {
1178     fprintf(header, "%s : public %s\n", iface->name,
1179             type_iface_get_inherit(iface)->name);
1180     fprintf(header, "{\n");
1181   }
1182   else
1183   {
1184     fprintf(header, "%s\n", iface->name);
1185     fprintf(header, "{\n");
1186     fprintf(header, "    BEGIN_INTERFACE\n");
1187     fprintf(header, "\n");
1188   }
1189   /* dispinterfaces don't have real functions, so don't write C++ functions for
1190    * them */
1191   if (!dispinterface)
1192   {
1193     indentation++;
1194     write_cpp_method_def(header, iface);
1195     indentation--;
1196   }
1197   if (!type_iface_get_inherit(iface))
1198     fprintf(header, "    END_INTERFACE\n");
1199   fprintf(header, "};\n");
1200   if (uuid)
1201       write_uuid_decl(header, iface->name, uuid);
1202   fprintf(header, "#else\n");
1203   /* C interface */
1204   fprintf(header, "typedef struct %sVtbl {\n", iface->name);
1205   indentation++;
1206   fprintf(header, "    BEGIN_INTERFACE\n");
1207   fprintf(header, "\n");
1208   if (dispinterface)
1209     write_c_disp_method_def(header, iface);
1210   else
1211     write_c_method_def(header, iface);
1212   indentation--;
1213   fprintf(header, "    END_INTERFACE\n");
1214   fprintf(header, "} %sVtbl;\n", iface->name);
1215   fprintf(header, "interface %s {\n", iface->name);
1216   fprintf(header, "    CONST_VTBL %sVtbl* lpVtbl;\n", iface->name);
1217   fprintf(header, "};\n");
1218   fprintf(header, "\n");
1219   fprintf(header, "#ifdef COBJMACROS\n");
1220   /* dispinterfaces don't have real functions, so don't write macros for them,
1221    * only for the interface this interface inherits from, i.e. IDispatch */
1222   fprintf(header, "#ifndef WIDL_C_INLINE_WRAPPERS\n");
1223   write_method_macro(header, dispinterface ? type_iface_get_inherit(iface) : iface, iface->name);
1224   fprintf(header, "#else\n");
1225   write_inline_wrappers(header, dispinterface ? type_iface_get_inherit(iface) : iface, iface->name);
1226   fprintf(header, "#endif\n");
1227   fprintf(header, "#endif\n");
1228   fprintf(header, "\n");
1229   fprintf(header, "#endif\n");
1230   fprintf(header, "\n");
1231   /* dispinterfaces don't have real functions, so don't write prototypes for
1232    * them */
1233   if (!dispinterface)
1234   {
1235     write_method_proto(header, iface);
1236     write_locals(header, iface, FALSE);
1237     fprintf(header, "\n");
1238   }
1239   fprintf(header,"#endif  /* __%s_%sINTERFACE_DEFINED__ */\n\n", iface->name, dispinterface ? "DISP" : "");
1240 }
1241
1242 static void write_rpc_interface_start(FILE *header, const type_t *iface)
1243 {
1244   unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
1245   const var_t *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
1246
1247   fprintf(header, "/*****************************************************************************\n");
1248   fprintf(header, " * %s interface (v%d.%d)\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver));
1249   fprintf(header, " */\n");
1250   fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
1251   fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
1252   if (var)
1253   {
1254       fprintf(header, "extern ");
1255       write_type_decl( header, var->type, var->name );
1256       fprintf(header, ";\n");
1257   }
1258   if (old_names)
1259   {
1260       fprintf(header, "extern RPC_IF_HANDLE %s%s_ClientIfHandle;\n", prefix_client, iface->name);
1261       fprintf(header, "extern RPC_IF_HANDLE %s%s_ServerIfHandle;\n", prefix_server, iface->name);
1262   }
1263   else
1264   {
1265       fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec;\n",
1266               prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver));
1267       fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec;\n",
1268               prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver));
1269   }
1270 }
1271
1272 static void write_rpc_interface_end(FILE *header, const type_t *iface)
1273 {
1274   fprintf(header,"\n#endif  /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
1275 }
1276
1277 static void write_coclass(FILE *header, type_t *cocl)
1278 {
1279   const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID);
1280
1281   fprintf(header, "/*****************************************************************************\n");
1282   fprintf(header, " * %s coclass\n", cocl->name);
1283   fprintf(header, " */\n\n");
1284   if (uuid)
1285       write_guid(header, "CLSID", cocl->name, uuid);
1286   fprintf(header, "\n#ifdef __cplusplus\n");
1287   if (uuid)
1288   {
1289       fprintf(header, "class DECLSPEC_UUID(\"%s\") %s;\n", uuid_string(uuid), cocl->name);
1290       write_uuid_decl(header, cocl->name, uuid);
1291   }
1292   else
1293   {
1294       fprintf(header, "class %s;\n", cocl->name);
1295   }
1296   fprintf(header, "#endif\n");
1297   fprintf(header, "\n");
1298 }
1299
1300 static void write_coclass_forward(FILE *header, type_t *cocl)
1301 {
1302   fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", cocl->name);
1303   fprintf(header, "#define __%s_FWD_DEFINED__\n", cocl->name);
1304   fprintf(header, "typedef struct %s %s;\n", cocl->name, cocl->name);
1305   fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name );
1306 }
1307
1308 static void write_import(FILE *header, const char *fname)
1309 {
1310   char *hname, *p;
1311
1312   hname = dup_basename(fname, ".idl");
1313   p = hname + strlen(hname) - 2;
1314   if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h");
1315
1316   fprintf(header, "#include <%s>\n", hname);
1317   free(hname);
1318 }
1319
1320 static void write_imports(FILE *header, const statement_list_t *stmts)
1321 {
1322   const statement_t *stmt;
1323   if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
1324   {
1325     switch (stmt->type)
1326     {
1327       case STMT_TYPE:
1328         if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
1329           write_imports(header, type_iface_get_stmts(stmt->u.type));
1330         break;
1331       case STMT_TYPEREF:
1332       case STMT_IMPORTLIB:
1333         /* not included in header */
1334         break;
1335       case STMT_IMPORT:
1336         write_import(header, stmt->u.str);
1337         break;
1338       case STMT_TYPEDEF:
1339       case STMT_MODULE:
1340       case STMT_CPPQUOTE:
1341       case STMT_DECLARATION:
1342         /* not processed here */
1343         break;
1344       case STMT_LIBRARY:
1345         write_imports(header, stmt->u.lib->stmts);
1346         break;
1347     }
1348   }
1349 }
1350
1351 static void write_forward_decls(FILE *header, const statement_list_t *stmts)
1352 {
1353   const statement_t *stmt;
1354   if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
1355   {
1356     switch (stmt->type)
1357     {
1358       case STMT_TYPE:
1359         if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
1360         {
1361           if (is_object(stmt->u.type) || is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE))
1362             write_forward(header, stmt->u.type);
1363         }
1364         else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
1365           write_coclass_forward(header, stmt->u.type);
1366         break;
1367       case STMT_TYPEREF:
1368       case STMT_IMPORTLIB:
1369         /* not included in header */
1370         break;
1371       case STMT_IMPORT:
1372       case STMT_TYPEDEF:
1373       case STMT_MODULE:
1374       case STMT_CPPQUOTE:
1375       case STMT_DECLARATION:
1376         /* not processed here */
1377         break;
1378       case STMT_LIBRARY:
1379         write_forward_decls(header, stmt->u.lib->stmts);
1380         break;
1381     }
1382   }
1383 }
1384
1385 static void write_header_stmts(FILE *header, const statement_list_t *stmts, const type_t *iface, int ignore_funcs)
1386 {
1387   const statement_t *stmt;
1388   if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
1389   {
1390     switch (stmt->type)
1391     {
1392       case STMT_TYPE:
1393         if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
1394         {
1395           type_t *iface = stmt->u.type;
1396           if (is_object(iface)) is_object_interface++;
1397           if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
1398           {
1399             write_com_interface_start(header, iface);
1400             write_header_stmts(header, type_iface_get_stmts(iface), stmt->u.type, TRUE);
1401             write_com_interface_end(header, iface);
1402           }
1403           else
1404           {
1405             write_rpc_interface_start(header, iface);
1406             write_header_stmts(header, type_iface_get_stmts(iface), iface, FALSE);
1407             write_rpc_interface_end(header, iface);
1408           }
1409           if (is_object(iface)) is_object_interface--;
1410         }
1411         else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
1412           write_coclass(header, stmt->u.type);
1413         else
1414         {
1415           write_type_def_or_decl(header, stmt->u.type, FALSE, NULL);
1416           fprintf(header, ";\n\n");
1417         }
1418         break;
1419       case STMT_TYPEREF:
1420         /* FIXME: shouldn't write out forward declarations for undefined
1421         * interfaces but a number of our IDL files depend on this */
1422         if (type_get_type(stmt->u.type) == TYPE_INTERFACE && !stmt->u.type->written)
1423           write_forward(header, stmt->u.type);
1424         break;
1425       case STMT_IMPORTLIB:
1426       case STMT_MODULE:
1427         /* not included in header */
1428         break;
1429       case STMT_IMPORT:
1430         /* not processed here */
1431         break;
1432       case STMT_TYPEDEF:
1433       {
1434         const type_list_t *type_entry = stmt->u.type_list;
1435         for (; type_entry; type_entry = type_entry->next)
1436           write_typedef(header, type_entry->type);
1437         break;
1438       }
1439       case STMT_LIBRARY:
1440         write_library(header, stmt->u.lib);
1441         write_header_stmts(header, stmt->u.lib->stmts, NULL, FALSE);
1442         break;
1443       case STMT_CPPQUOTE:
1444         fprintf(header, "%s\n", stmt->u.str);
1445         break;
1446       case STMT_DECLARATION:
1447         if (iface && type_get_type(stmt->u.var->type) == TYPE_FUNCTION)
1448         {
1449           if (!ignore_funcs)
1450           {
1451             int prefixes_differ = strcmp(prefix_client, prefix_server);
1452
1453             if (prefixes_differ)
1454             {
1455               fprintf(header, "/* client prototype */\n");
1456               write_function_proto(header, iface, stmt->u.var, prefix_client);
1457               fprintf(header, "/* server prototype */\n");
1458             }
1459             write_function_proto(header, iface, stmt->u.var, prefix_server);
1460           }
1461         }
1462         else
1463           write_declaration(header, stmt->u.var);
1464         break;
1465     }
1466   }
1467 }
1468
1469 void write_header(const statement_list_t *stmts)
1470 {
1471   FILE *header;
1472
1473   if (!do_header) return;
1474
1475   if(!(header = fopen(header_name, "w"))) {
1476     error("Could not open %s for output\n", header_name);
1477     return;
1478   }
1479   fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name);
1480
1481   fprintf(header, "#ifndef __REQUIRED_RPCNDR_H_VERSION__\n");
1482   fprintf(header, "#define __REQUIRED_RPCNDR_H_VERSION__ 475\n");
1483   fprintf(header, "#endif\n\n");
1484
1485   fprintf(header, "#include <rpc.h>\n" );
1486   fprintf(header, "#include <rpcndr.h>\n\n" );
1487
1488   fprintf(header, "#ifndef COM_NO_WINDOWS_H\n");
1489   fprintf(header, "#include <windows.h>\n");
1490   fprintf(header, "#include <ole2.h>\n");
1491   fprintf(header, "#endif\n\n");
1492
1493   fprintf(header, "#ifndef __%s__\n", header_token);
1494   fprintf(header, "#define __%s__\n\n", header_token);
1495
1496   fprintf(header, "/* Forward declarations */\n\n");
1497   write_forward_decls(header, stmts);
1498
1499   fprintf(header, "/* Headers for imported files */\n\n");
1500   write_imports(header, stmts);
1501   fprintf(header, "\n");
1502   start_cplusplus_guard(header);
1503
1504   write_header_stmts(header, stmts, NULL, FALSE);
1505
1506   fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
1507   fprintf(header, "\n");
1508   write_user_types(header);
1509   write_generic_handle_routines(header);
1510   write_context_handle_rundowns(header);
1511   fprintf(header, "\n");
1512   fprintf(header, "/* End additional prototypes */\n");
1513   fprintf(header, "\n");
1514
1515   end_cplusplus_guard(header);
1516   fprintf(header, "#endif /* __%s__ */\n", header_token);
1517
1518   fclose(header);
1519 }