| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 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> |
| Dmitry Timoshkov | c63d980 | 2002-08-17 18:28:43 +0000 | [diff] [blame] | 25 | #ifdef HAVE_UNISTD_H |
| 26 | # include <unistd.h> |
| 27 | #endif |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 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 | #include "proxy.h" |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 38 | |
| 39 | static int indentation = 0; |
| 40 | |
| 41 | static void indent(int delta) |
| 42 | { |
| 43 | int c; |
| 44 | if (delta < 0) indentation += delta; |
| 45 | for (c=0; c<indentation; c++) fprintf(header, " "); |
| 46 | if (delta > 0) indentation += delta; |
| 47 | } |
| 48 | |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 49 | int is_attr(attr_t *a, enum attr_type t) |
| 50 | { |
| 51 | while (a) { |
| 52 | if (a->type == t) return 1; |
| 53 | a = NEXT_LINK(a); |
| 54 | } |
| 55 | return 0; |
| 56 | } |
| 57 | |
| 58 | void *get_attrp(attr_t *a, enum attr_type t) |
| 59 | { |
| 60 | while (a) { |
| 61 | if (a->type == t) return a->u.pval; |
| 62 | a = NEXT_LINK(a); |
| 63 | } |
| 64 | return NULL; |
| 65 | } |
| 66 | |
| 67 | DWORD get_attrv(attr_t *a, enum attr_type t) |
| 68 | { |
| 69 | while (a) { |
| 70 | if (a->type == t) return a->u.ival; |
| 71 | a = NEXT_LINK(a); |
| 72 | } |
| 73 | return 0; |
| 74 | } |
| 75 | |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 76 | int is_void(type_t *t, var_t *v) |
| 77 | { |
| 78 | if (v && v->ptr_level) return 0; |
| 79 | if (!t->type && !t->ref) return 1; |
| 80 | return 0; |
| 81 | } |
| 82 | |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 83 | static void write_pident(FILE *h, var_t *v) |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 84 | { |
| 85 | int c; |
| 86 | for (c=0; c<v->ptr_level; c++) { |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 87 | fprintf(h, "*"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 88 | } |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 89 | if (v->name) fprintf(h, "%s", v->name); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 90 | } |
| 91 | |
| 92 | void write_name(FILE *h, var_t *v) |
| 93 | { |
| 94 | fprintf(h, "%s", v->name); |
| 95 | } |
| 96 | |
| 97 | char* get_name(var_t *v) |
| 98 | { |
| 99 | return v->name; |
| 100 | } |
| 101 | |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 102 | static void write_array(FILE *h, expr_t *v, int field) |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 103 | { |
| 104 | if (!v) return; |
| 105 | while (NEXT_LINK(v)) v = NEXT_LINK(v); |
| 106 | fprintf(h, "["); |
| 107 | while (v) { |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 108 | if (v->is_const) |
| 109 | fprintf(h, "%ld", v->cval); /* statically sized array */ |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 110 | else |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 111 | if (field) fprintf(h, "1"); /* dynamically sized array */ |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 112 | if (PREV_LINK(v)) |
| 113 | fprintf(h, ", "); |
| 114 | v = PREV_LINK(v); |
| 115 | } |
| 116 | fprintf(h, "]"); |
| 117 | } |
| 118 | |
| 119 | static void write_field(FILE *h, var_t *v) |
| 120 | { |
| 121 | if (!v) return; |
| 122 | if (v->type) { |
| 123 | indent(0); |
| 124 | write_type(h, v->type, NULL, v->tname); |
| 125 | if (get_name(v)) { |
| 126 | fprintf(h, " "); |
| 127 | write_pident(h, v); |
| 128 | } |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 129 | else { |
| 130 | /* not all C/C++ compilers support anonymous structs and unions */ |
| 131 | switch (v->type->type) { |
| 132 | case RPC_FC_STRUCT: |
| 133 | case RPC_FC_ENCAPSULATED_UNION: |
| 134 | fprintf(h, " DUMMYSTRUCTNAME"); |
| 135 | break; |
| 136 | case RPC_FC_NON_ENCAPSULATED_UNION: |
| 137 | fprintf(h, " DUMMYUNIONNAME"); |
| 138 | break; |
| 139 | default: |
| 140 | /* ? */ |
| 141 | break; |
| 142 | } |
| 143 | } |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 144 | write_array(h, v->array, 1); |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 145 | fprintf(h, ";\n"); |
| 146 | } |
| 147 | } |
| 148 | |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 149 | static void write_fields(FILE *h, var_t *v) |
| 150 | { |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 151 | var_t *first = v; |
| 152 | if (!v) return; |
| 153 | while (NEXT_LINK(v)) v = NEXT_LINK(v); |
| 154 | while (v) { |
| 155 | write_field(h, v); |
| 156 | if (v == first) break; |
| 157 | v = PREV_LINK(v); |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | static void write_enums(FILE *h, var_t *v) |
| 162 | { |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 163 | if (!v) return; |
| 164 | while (NEXT_LINK(v)) v = NEXT_LINK(v); |
| 165 | while (v) { |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 166 | if (get_name(v)) { |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 167 | indent(0); |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 168 | write_name(h, v); |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 169 | if (v->eval) { |
| 170 | fprintf(h, " = "); |
| 171 | write_expr(h, v->eval); |
| 172 | } |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 173 | } |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 174 | if (PREV_LINK(v)) |
| 175 | fprintf(h, ",\n"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 176 | v = PREV_LINK(v); |
| 177 | } |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 178 | fprintf(h, "\n"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 179 | } |
| 180 | |
| 181 | void write_type(FILE *h, type_t *t, var_t *v, char *n) |
| 182 | { |
| 183 | int c; |
| 184 | |
| 185 | if (n) fprintf(h, "%s", n); |
| 186 | else { |
| 187 | if (t->is_const) fprintf(h, "const "); |
| 188 | if (t->type) { |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 189 | if (t->sign > 0) fprintf(h, "signed "); |
| 190 | else if (t->sign < 0) fprintf(h, "unsigned "); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 191 | switch (t->type) { |
| 192 | case RPC_FC_BYTE: |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 193 | if (t->ref) fprintf(h, t->ref->name); |
| 194 | else fprintf(h, "byte"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 195 | break; |
| 196 | case RPC_FC_CHAR: |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 197 | if (t->ref) fprintf(h, t->ref->name); |
| 198 | else fprintf(h, "char"); |
| 199 | break; |
| 200 | case RPC_FC_WCHAR: |
| 201 | fprintf(h, "wchar_t"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 202 | break; |
| 203 | case RPC_FC_USHORT: |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 204 | case RPC_FC_SHORT: |
| 205 | if (t->ref) fprintf(h, t->ref->name); |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 206 | else fprintf(h, "short"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 207 | break; |
| 208 | case RPC_FC_ULONG: |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 209 | case RPC_FC_LONG: |
| 210 | if (t->ref) fprintf(h, t->ref->name); |
| 211 | else fprintf(h, "long"); |
| 212 | break; |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 213 | case RPC_FC_HYPER: |
| 214 | if (t->ref) fprintf(h, t->ref->name); |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 215 | else fprintf(h, "hyper"); |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 216 | break; |
| 217 | case RPC_FC_FLOAT: |
| 218 | fprintf(h, "float"); |
| 219 | break; |
| 220 | case RPC_FC_DOUBLE: |
| 221 | fprintf(h, "double"); |
| 222 | break; |
| 223 | case RPC_FC_ENUM16: |
| 224 | case RPC_FC_ENUM32: |
| 225 | if (t->defined && !t->written) { |
| 226 | if (t->name) fprintf(h, "enum %s {\n", t->name); |
| 227 | else fprintf(h, "enum {\n"); |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 228 | t->written = TRUE; |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 229 | indentation++; |
| 230 | write_enums(h, t->fields); |
| 231 | indent(-1); |
| 232 | fprintf(h, "}"); |
| 233 | } |
| 234 | else fprintf(h, "enum %s", t->name); |
| 235 | break; |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 236 | case RPC_FC_ERROR_STATUS_T: |
| 237 | if (t->ref) fprintf(h, t->ref->name); |
| 238 | else fprintf(h, "error_status_t"); |
| 239 | break; |
| 240 | case RPC_FC_BIND_PRIMITIVE: |
| 241 | if (t->ref) fprintf(h, t->ref->name); |
| 242 | else fprintf(h, "handle_t"); |
| 243 | break; |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 244 | case RPC_FC_STRUCT: |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 245 | case RPC_FC_ENCAPSULATED_UNION: |
| 246 | if (t->defined && !t->written) { |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 247 | if (t->name) fprintf(h, "struct %s {\n", t->name); |
| 248 | else fprintf(h, "struct {\n"); |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 249 | t->written = TRUE; |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 250 | indentation++; |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 251 | write_fields(h, t->fields); |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 252 | indent(-1); |
| 253 | fprintf(h, "}"); |
| 254 | } |
| 255 | else fprintf(h, "struct %s", t->name); |
| 256 | break; |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 257 | case RPC_FC_NON_ENCAPSULATED_UNION: |
| 258 | if (t->defined && !t->written) { |
| 259 | if (t->name) fprintf(h, "union %s {\n", t->name); |
| 260 | else fprintf(h, "union {\n"); |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 261 | t->written = TRUE; |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 262 | indentation++; |
| 263 | write_fields(h, t->fields); |
| 264 | indent(-1); |
| 265 | fprintf(h, "}"); |
| 266 | } |
| 267 | else fprintf(h, "union %s", t->name); |
| 268 | break; |
| 269 | default: |
| 270 | fprintf(h, "(unknown-type:%d)", t->type); |
| 271 | } |
| 272 | } |
| 273 | else { |
| 274 | if (t->ref) { |
| 275 | write_type(h, t->ref, NULL, t->name); |
| 276 | } |
| 277 | else fprintf(h, "void"); |
| 278 | } |
| 279 | } |
| 280 | if (v) { |
| 281 | for (c=0; c<v->ptr_level; c++) { |
| 282 | fprintf(h, "*"); |
| 283 | } |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | void write_typedef(type_t *type, var_t *names) |
| 288 | { |
| 289 | char *tname = names->tname; |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 290 | var_t *lname; |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 291 | while (NEXT_LINK(names)) names = NEXT_LINK(names); |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 292 | lname = names; |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 293 | fprintf(header, "typedef "); |
| 294 | write_type(header, type, NULL, tname); |
| 295 | fprintf(header, " "); |
| 296 | while (names) { |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 297 | write_pident(header, names); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 298 | if (PREV_LINK(names)) |
| 299 | fprintf(header, ", "); |
| 300 | names = PREV_LINK(names); |
| 301 | } |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 302 | fprintf(header, ";\n"); |
| 303 | |
| 304 | if (get_attrp(type->attrs, ATTR_WIREMARSHAL)) { |
| 305 | names = lname; |
| 306 | while (names) { |
| 307 | char *name = get_name(names); |
| 308 | fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name); |
| 309 | fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name); |
| 310 | fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name); |
| 311 | fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name); |
| 312 | if (PREV_LINK(names)) |
| 313 | fprintf(header, ", "); |
| 314 | names = PREV_LINK(names); |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | fprintf(header, "\n"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 319 | } |
| 320 | |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 321 | static void do_write_expr(FILE *h, expr_t *e, int p) |
| 322 | { |
| 323 | switch (e->type) { |
| 324 | case EXPR_VOID: |
| 325 | break; |
| 326 | case EXPR_NUM: |
| 327 | fprintf(h, "%ld", e->u.lval); |
| 328 | break; |
| 329 | case EXPR_HEXNUM: |
| 330 | fprintf(h, "0x%lx", e->u.lval); |
| 331 | break; |
| 332 | case EXPR_IDENTIFIER: |
| 333 | fprintf(h, "%s", e->u.sval); |
| 334 | break; |
| 335 | case EXPR_NEG: |
| 336 | fprintf(h, "-"); |
| 337 | do_write_expr(h, e->ref, 1); |
| 338 | break; |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 339 | case EXPR_NOT: |
| 340 | fprintf(h, "~"); |
| 341 | do_write_expr(h, e->ref, 1); |
| 342 | break; |
| Ove Kaaven | 34e2f87 | 2002-11-30 01:49:46 +0000 | [diff] [blame] | 343 | case EXPR_PPTR: |
| 344 | fprintf(h, "*"); |
| 345 | do_write_expr(h, e->ref, 1); |
| 346 | break; |
| 347 | case EXPR_CAST: |
| 348 | fprintf(h, "("); |
| 349 | write_type(h, e->u.tref->ref, NULL, e->u.tref->name); |
| 350 | fprintf(h, ")"); |
| 351 | do_write_expr(h, e->ref, 1); |
| 352 | break; |
| 353 | case EXPR_SIZEOF: |
| 354 | fprintf(h, "sizeof("); |
| 355 | write_type(h, e->u.tref->ref, NULL, e->u.tref->name); |
| 356 | fprintf(h, ")"); |
| 357 | break; |
| 358 | case EXPR_SHL: |
| 359 | case EXPR_SHR: |
| 360 | case EXPR_MUL: |
| 361 | case EXPR_DIV: |
| 362 | case EXPR_ADD: |
| 363 | case EXPR_SUB: |
| 364 | case EXPR_AND: |
| 365 | case EXPR_OR: |
| 366 | if (p) fprintf(h, "("); |
| 367 | do_write_expr(h, e->ref, 1); |
| 368 | switch (e->type) { |
| 369 | case EXPR_SHL: fprintf(h, " << "); break; |
| 370 | case EXPR_SHR: fprintf(h, " >> "); break; |
| 371 | case EXPR_MUL: fprintf(h, " * "); break; |
| 372 | case EXPR_DIV: fprintf(h, " / "); break; |
| 373 | case EXPR_ADD: fprintf(h, " + "); break; |
| 374 | case EXPR_SUB: fprintf(h, " - "); break; |
| 375 | case EXPR_AND: fprintf(h, " & "); break; |
| 376 | case EXPR_OR: fprintf(h, " | "); break; |
| 377 | default: break; |
| 378 | } |
| 379 | do_write_expr(h, e->u.ext, 1); |
| 380 | if (p) fprintf(h, ")"); |
| 381 | break; |
| 382 | } |
| 383 | } |
| 384 | |
| 385 | void write_expr(FILE *h, expr_t *e) |
| 386 | { |
| 387 | do_write_expr(h, e, 0); |
| 388 | } |
| 389 | |
| 390 | void write_constdef(var_t *v) |
| 391 | { |
| 392 | fprintf(header, "#define %s (", get_name(v)); |
| 393 | write_expr(header, v->eval); |
| 394 | fprintf(header, ")\n\n"); |
| 395 | } |
| 396 | |
| 397 | void write_externdef(var_t *v) |
| 398 | { |
| 399 | fprintf(header, "extern const "); |
| 400 | write_type(header, v->type, NULL, v->tname); |
| 401 | if (get_name(v)) { |
| 402 | fprintf(header, " "); |
| 403 | write_pident(header, v); |
| 404 | } |
| 405 | fprintf(header, ";\n\n"); |
| 406 | } |
| 407 | |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 408 | /********** INTERFACES **********/ |
| 409 | |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 410 | int is_object(attr_t *a) |
| 411 | { |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 412 | return is_attr(a, ATTR_OBJECT); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 413 | } |
| 414 | |
| 415 | int is_local(attr_t *a) |
| 416 | { |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 417 | return is_attr(a, ATTR_LOCAL); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 418 | } |
| 419 | |
| 420 | var_t *is_callas(attr_t *a) |
| 421 | { |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 422 | return get_attrp(a, ATTR_CALLAS); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 423 | } |
| 424 | |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 425 | static void write_icom_method_def(type_t *iface) |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 426 | { |
| 427 | func_t *cur = iface->funcs; |
| 428 | while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 429 | while (cur) { |
| 430 | var_t *def = cur->def; |
| 431 | if (!is_callas(def->attrs)) { |
| 432 | var_t *arg = cur->args; |
| 433 | int argc = 0; |
| 434 | if (arg) { |
| 435 | argc++; |
| 436 | while (NEXT_LINK(arg)) { |
| 437 | arg = NEXT_LINK(arg); |
| 438 | argc++; |
| 439 | } |
| 440 | } |
| 441 | fprintf(header, " \\\n"); |
| 442 | if (!is_void(def->type, def)) { |
| 443 | if (argc) |
| 444 | fprintf(header, " ICOM_METHOD%d (", argc); |
| 445 | else |
| 446 | fprintf(header, " ICOM_METHOD ("); |
| 447 | write_type(header, def->type, def, def->tname); |
| 448 | fprintf(header, ","); |
| 449 | } else |
| 450 | if (argc) |
| 451 | fprintf(header, " ICOM_VMETHOD%d(", argc); |
| 452 | else |
| 453 | fprintf(header, " ICOM_VMETHOD ("); |
| 454 | write_name(header, def); |
| 455 | while (arg) { |
| 456 | fprintf(header, ","); |
| 457 | write_type(header, arg->type, arg, arg->tname); |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 458 | /* since the ICOM macros can't express arrays, |
| 459 | * we have to pretend they're pointers instead */ |
| 460 | if (arg->array) fprintf(header, "*"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 461 | fprintf(header, ","); |
| 462 | write_name(header,arg); |
| 463 | arg = PREV_LINK(arg); |
| 464 | } |
| 465 | fprintf(header, ")"); |
| 466 | } |
| 467 | cur = PREV_LINK(cur); |
| 468 | } |
| 469 | fprintf(header, "\n"); |
| 470 | } |
| 471 | |
| 472 | static int write_method_macro(type_t *iface, char *name) |
| 473 | { |
| 474 | int idx; |
| 475 | func_t *cur = iface->funcs; |
| 476 | while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); |
| 477 | |
| 478 | if (iface->ref) idx = write_method_macro(iface->ref, name); |
| 479 | else idx = 0; |
| 480 | fprintf(header, "/*** %s methods ***/\n", iface->name); |
| 481 | while (cur) { |
| 482 | var_t *def = cur->def; |
| 483 | if (!is_callas(def->attrs)) { |
| 484 | var_t *arg = cur->args; |
| 485 | int argc = 0; |
| 486 | int c; |
| 487 | while (arg) { |
| 488 | arg = NEXT_LINK(arg); |
| 489 | argc++; |
| 490 | } |
| 491 | |
| 492 | fprintf(header, "#define %s_", name); |
| 493 | write_name(header,def); |
| 494 | fprintf(header, "(p"); |
| 495 | for (c=0; c<argc; c++) |
| 496 | fprintf(header, ",%c", c+'a'); |
| 497 | fprintf(header, ") "); |
| 498 | |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 499 | if (use_icom) { |
| 500 | if (argc) |
| 501 | fprintf(header, "ICOM_CALL%d(", argc); |
| 502 | else |
| 503 | fprintf(header, "ICOM_CALL("); |
| 504 | write_name(header, def); |
| 505 | fprintf(header, ",p"); |
| 506 | } |
| 507 | else { |
| 508 | fprintf(header, "(p)->lpVtbl->"); |
| 509 | write_name(header, def); |
| 510 | fprintf(header, "(p"); |
| 511 | } |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 512 | for (c=0; c<argc; c++) |
| 513 | fprintf(header, ",%c", c+'a'); |
| 514 | fprintf(header, ")\n"); |
| 515 | if (cur->idx == -1) cur->idx = idx; |
| 516 | else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro"); |
| 517 | idx++; |
| 518 | } |
| 519 | cur = PREV_LINK(cur); |
| 520 | } |
| 521 | return idx; |
| 522 | } |
| 523 | |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 524 | void write_args(FILE *h, var_t *arg, char *name, int method) |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 525 | { |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 526 | int count = 0; |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 527 | if (arg) { |
| 528 | while (NEXT_LINK(arg)) |
| 529 | arg = NEXT_LINK(arg); |
| 530 | } |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 531 | if (h == header) { |
| 532 | indentation++; |
| 533 | indent(0); |
| 534 | } else fprintf(h, " "); |
| 535 | if (method == 1) { |
| 536 | fprintf(h, "%s* This", name); |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 537 | count++; |
| 538 | } |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 539 | while (arg) { |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 540 | if (count) { |
| 541 | fprintf(h, ",\n"); |
| 542 | if (h == header) indent(0); |
| 543 | else fprintf(h, " "); |
| 544 | } |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 545 | write_type(h, arg->type, arg, arg->tname); |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 546 | if (method && use_icom && arg->array) fprintf(h, "*"); /* as write_icom_method_def */ |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 547 | fprintf(h, " "); |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 548 | write_name(h, arg); |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 549 | if (!(method && use_icom)) write_array(h, arg->array, 0); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 550 | arg = PREV_LINK(arg); |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 551 | count++; |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 552 | } |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 553 | if (h == header) indentation--; |
| 554 | } |
| 555 | |
| 556 | static void write_cpp_method_def(type_t *iface) |
| 557 | { |
| 558 | func_t *cur = iface->funcs; |
| 559 | while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); |
| 560 | while (cur) { |
| 561 | var_t *def = cur->def; |
| 562 | if (!is_callas(def->attrs)) { |
| 563 | indent(0); |
| 564 | fprintf(header, "virtual "); |
| 565 | write_type(header, def->type, def, def->tname); |
| 566 | fprintf(header, " CALLBACK "); |
| 567 | write_name(header, def); |
| 568 | fprintf(header, "(\n"); |
| 569 | write_args(header, cur->args, iface->name, 2); |
| 570 | fprintf(header, ") = 0;\n"); |
| 571 | fprintf(header, "\n"); |
| 572 | } |
| 573 | cur = PREV_LINK(cur); |
| 574 | } |
| 575 | } |
| 576 | |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 577 | static void do_write_c_method_def(type_t *iface, char *name) |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 578 | { |
| 579 | func_t *cur = iface->funcs; |
| 580 | while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); |
| 581 | |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 582 | if (iface->ref) do_write_c_method_def(iface->ref, name); |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 583 | indent(0); |
| 584 | fprintf(header, "/*** %s methods ***/\n", iface->name); |
| 585 | while (cur) { |
| 586 | var_t *def = cur->def; |
| 587 | if (!is_callas(def->attrs)) { |
| 588 | indent(0); |
| 589 | write_type(header, def->type, def, def->tname); |
| 590 | fprintf(header, " (CALLBACK *"); |
| 591 | write_name(header, def); |
| 592 | fprintf(header, ")(\n"); |
| Alexandre Julliard | ea118ec | 2002-12-17 21:05:16 +0000 | [diff] [blame] | 593 | write_args(header, cur->args, name, 1); |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 594 | fprintf(header, ");\n"); |
| 595 | fprintf(header, "\n"); |
| 596 | } |
| 597 | cur = PREV_LINK(cur); |
| 598 | } |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 599 | } |
| 600 | |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 601 | static void write_c_method_def(type_t *iface) |
| 602 | { |
| 603 | do_write_c_method_def(iface, iface->name); |
| 604 | } |
| 605 | |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 606 | static void write_method_proto(type_t *iface) |
| 607 | { |
| 608 | func_t *cur = iface->funcs; |
| 609 | while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); |
| 610 | while (cur) { |
| 611 | var_t *def = cur->def; |
| 612 | var_t *cas = is_callas(def->attrs); |
| 613 | if (!is_local(def->attrs)) { |
| 614 | /* proxy prototype */ |
| 615 | write_type(header, def->type, def, def->tname); |
| 616 | fprintf(header, " CALLBACK %s_", iface->name); |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 617 | write_name(header, def); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 618 | fprintf(header, "_Proxy(\n"); |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 619 | write_args(header, cur->args, iface->name, 1); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 620 | fprintf(header, ");\n"); |
| 621 | /* stub prototype */ |
| 622 | fprintf(header, "void __RPC_STUB %s_", iface->name); |
| 623 | write_name(header,def); |
| 624 | fprintf(header, "_Stub(\n"); |
| Ove Kaaven | 1893977 | 2002-11-21 00:02:38 +0000 | [diff] [blame] | 625 | fprintf(header, " struct IRpcStubBuffer* This,\n"); |
| 626 | fprintf(header, " struct IRpcChannelBuffer* pRpcChannelBuffer,\n"); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 627 | fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); |
| 628 | fprintf(header, " DWORD* pdwStubPhase);\n"); |
| 629 | } |
| 630 | if (cas) { |
| 631 | func_t *m = iface->funcs; |
| 632 | while (m && strcmp(get_name(m->def), cas->name)) |
| 633 | m = NEXT_LINK(m); |
| 634 | if (m) { |
| 635 | var_t *mdef = m->def; |
| 636 | /* proxy prototype - use local prototype */ |
| 637 | write_type(header, mdef->type, mdef, mdef->tname); |
| 638 | fprintf(header, " CALLBACK %s_", iface->name); |
| 639 | write_name(header, mdef); |
| 640 | fprintf(header, "_Proxy(\n"); |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 641 | write_args(header, m->args, iface->name, 1); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 642 | fprintf(header, ");\n"); |
| 643 | /* stub prototype - use remotable prototype */ |
| 644 | write_type(header, def->type, def, def->tname); |
| 645 | fprintf(header, " __RPC_STUB %s_", iface->name); |
| 646 | write_name(header, mdef); |
| 647 | fprintf(header, "_Stub(\n"); |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 648 | write_args(header, cur->args, iface->name, 1); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 649 | fprintf(header, ");\n"); |
| 650 | } |
| 651 | else { |
| 652 | yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name); |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | cur = PREV_LINK(cur); |
| 657 | } |
| 658 | } |
| 659 | |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 660 | static void write_function_proto(type_t *iface) |
| 661 | { |
| 662 | func_t *cur = iface->funcs; |
| 663 | while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); |
| 664 | while (cur) { |
| 665 | var_t *def = cur->def; |
| 666 | /* FIXME: do we need to handle call_as? */ |
| 667 | write_type(header, def->type, def, def->tname); |
| 668 | fprintf(header, " "); |
| 669 | write_name(header, def); |
| 670 | fprintf(header, "(\n"); |
| 671 | write_args(header, cur->args, iface->name, 0); |
| 672 | fprintf(header, ");\n"); |
| 673 | |
| 674 | cur = PREV_LINK(cur); |
| 675 | } |
| 676 | } |
| 677 | |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 678 | void write_forward(type_t *iface) |
| 679 | { |
| Ove Kaaven | 1893977 | 2002-11-21 00:02:38 +0000 | [diff] [blame] | 680 | /* C/C++ forwards should only be written for object interfaces, so if we |
| 681 | * have a full definition we only write one if we find [object] among the |
| 682 | * attributes - however, if we don't have a full definition at this point |
| 683 | * (i.e. this is an IDL forward), then we also assume that it is an object |
| 684 | * interface, since non-object interfaces shouldn't need forwards */ |
| 685 | if ((!iface->defined || is_object(iface->attrs)) && !iface->written) { |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 686 | fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name); |
| 687 | iface->written = TRUE; |
| 688 | } |
| 689 | } |
| 690 | |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 691 | void write_guid(type_t *iface) |
| 692 | { |
| Ove Kaaven | 064c48a | 2002-12-15 01:13:18 +0000 | [diff] [blame] | 693 | UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 694 | if (!uuid) return; |
| 695 | 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", |
| 696 | iface->name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], |
| 697 | uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]); |
| 698 | } |
| 699 | |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 700 | void write_com_interface(type_t *iface) |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 701 | { |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 702 | if (!iface->funcs) { |
| 703 | yywarning("%s has no methods", iface->name); |
| 704 | return; |
| 705 | } |
| 706 | |
| 707 | fprintf(header, "/*****************************************************************************\n"); |
| 708 | fprintf(header, " * %s interface\n", iface->name); |
| 709 | fprintf(header, " */\n"); |
| Ove Kaaven | 03c7d46 | 2002-11-12 02:12:35 +0000 | [diff] [blame] | 710 | write_guid(iface); |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 711 | write_forward(iface); |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 712 | if (use_icom) { |
| 713 | fprintf(header, "#define ICOM_INTERFACE %s\n", iface->name); |
| 714 | fprintf(header, "#define %s_METHODS", iface->name); |
| 715 | write_icom_method_def(iface); |
| 716 | fprintf(header, "#define %s_IMETHODS \\\n", iface->name); |
| 717 | if (iface->ref) |
| 718 | fprintf(header, " %s_IMETHODS \\\n", iface->ref->name); |
| 719 | fprintf(header, " %s_METHODS\n", iface->name); |
| 720 | if (iface->ref) |
| 721 | fprintf(header, "ICOM_DEFINE(%s,%s)\n", iface->name, iface->ref->name); |
| 722 | else |
| 723 | fprintf(header, "ICOM_DEFINE1(%s)\n", iface->name); |
| 724 | fprintf(header, "#undef ICOM_INTERFACE\n"); |
| 725 | fprintf(header, "\n"); |
| 726 | write_method_macro(iface, iface->name); |
| 727 | } |
| 728 | else { |
| 729 | /* C++ interface */ |
| 730 | fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n"); |
| 731 | fprintf(header, "struct %s", iface->name); |
| 732 | if (iface->ref) |
| 733 | fprintf(header, ": %s", iface->ref->name); |
| 734 | fprintf(header, " {\n"); |
| 735 | indentation++; |
| 736 | fprintf(header, "\n"); |
| 737 | write_cpp_method_def(iface); |
| 738 | indentation--; |
| 739 | fprintf(header, "} ICOM_COM_INTERFACE_ATTRIBUTE;\n"); |
| 740 | fprintf(header, "#else\n"); |
| 741 | /* C interface */ |
| 742 | fprintf(header, "typedef struct %sVtbl %sVtbl;\n", iface->name, iface->name); |
| 743 | fprintf(header, "struct %s {\n", iface->name); |
| 744 | fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name); |
| 745 | fprintf(header, "};\n"); |
| 746 | fprintf(header, "struct %sVtbl {\n", iface->name); |
| 747 | indentation++; |
| 748 | fprintf(header, " ICOM_MSVTABLE_COMPAT_FIELDS\n"); |
| 749 | fprintf(header, "\n"); |
| Ove Kaaven | be3c114 | 2003-01-09 01:05:54 +0000 | [diff] [blame] | 750 | write_c_method_def(iface); |
| Ove Kaaven | 998236b | 2002-12-15 03:01:20 +0000 | [diff] [blame] | 751 | indentation--; |
| 752 | fprintf(header, "};\n"); |
| 753 | fprintf(header, "\n"); |
| 754 | if (compat_icom) { |
| 755 | fprintf(header, "#define %s_IMETHODS", iface->name); |
| 756 | if (iface->ref) |
| 757 | fprintf(header, " \\\n %s_IMETHODS", iface->ref->name); |
| 758 | write_icom_method_def(iface); |
| 759 | fprintf(header, "\n"); |
| 760 | } |
| 761 | write_method_macro(iface, iface->name); |
| 762 | fprintf(header, "\n"); |
| 763 | fprintf(header, "#endif\n"); |
| 764 | } |
| Alexandre Julliard | 7d4ee77 | 2002-07-16 03:20:45 +0000 | [diff] [blame] | 765 | fprintf(header, "\n"); |
| 766 | write_method_proto(iface); |
| 767 | fprintf(header, "\n"); |
| 768 | |
| 769 | if (!is_local(iface->attrs)) |
| 770 | write_proxy(iface); |
| 771 | } |
| Ove Kaaven | e30a967 | 2002-12-03 19:12:07 +0000 | [diff] [blame] | 772 | |
| 773 | void write_rpc_interface(type_t *iface) |
| 774 | { |
| 775 | DWORD ver = get_attrv(iface->attrs, ATTR_VERSION); |
| 776 | |
| 777 | if (!iface->funcs) return; |
| 778 | |
| 779 | fprintf(header, "/*****************************************************************************\n"); |
| 780 | fprintf(header, " * %s interface (v%d.%d)\n", iface->name, LOWORD(ver), HIWORD(ver)); |
| 781 | fprintf(header, " */\n"); |
| 782 | write_guid(iface); |
| 783 | fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver)); |
| 784 | fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver)); |
| 785 | write_function_proto(iface); |
| 786 | fprintf(header, "\n"); |
| 787 | |
| 788 | /* FIXME: server/client code */ |
| 789 | } |
| 790 | |
| 791 | void write_interface(type_t *iface) |
| 792 | { |
| 793 | if (is_object(iface->attrs)) |
| 794 | write_com_interface(iface); |
| 795 | else |
| 796 | write_rpc_interface(iface); |
| 797 | } |