4 * Copyright 2002 Ove Kaaven
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 static int indentation
= 0;
41 static void indent(int delta
)
44 if (delta
< 0) indentation
+= delta
;
45 for (c
=0; c
<indentation
; c
++) fprintf(header
, " ");
46 if (delta
> 0) indentation
+= delta
;
49 int is_void(type_t
*t
, var_t
*v
)
51 if (v
&& v
->ptr_level
) return 0;
52 if (!t
->type
&& !t
->ref
) return 1;
56 static void write_pident(var_t
*v
)
59 for (c
=0; c
<v
->ptr_level
; c
++) {
62 if (v
->name
) fprintf(header
, "%s", v
->name
);
65 void write_name(FILE *h
, var_t
*v
)
67 fprintf(h
, "%s", v
->name
);
70 char* get_name(var_t
*v
)
75 static void write_fields(FILE *h
, var_t
*v
)
78 while (NEXT_LINK(v
)) v
= NEXT_LINK(v
);
82 write_type(h
, v
->type
, NULL
, v
->tname
);
87 fprintf(header
, ";\n");
93 void write_type(FILE *h
, type_t
*t
, var_t
*v
, char *n
)
97 if (n
) fprintf(h
, "%s", n
);
99 if (t
->is_const
) fprintf(h
, "const ");
109 fprintf(h
, "unsigned ");
111 if (t
->ref
) fprintf(h
, t
->ref
->name
);
115 fprintf(h
, "unsigned ");
117 if (t
->ref
) fprintf(h
, t
->ref
->name
);
118 else fprintf(h
, "long");
121 if (t
->defined
&& !t
->written
) {
122 if (t
->name
) fprintf(h
, "struct %s {\n", t
->name
);
123 else fprintf(h
, "struct {\n");
125 write_fields(h
, t
->fields
);
129 else fprintf(h
, "struct %s", t
->name
);
131 case RPC_FC_NON_ENCAPSULATED_UNION
:
132 if (t
->defined
&& !t
->written
) {
133 if (t
->name
) fprintf(h
, "union %s {\n", t
->name
);
134 else fprintf(h
, "union {\n");
136 write_fields(h
, t
->fields
);
140 else fprintf(h
, "union %s", t
->name
);
143 fprintf(h
, "(unknown-type:%d)", t
->type
);
148 write_type(h
, t
->ref
, NULL
, t
->name
);
150 else fprintf(h
, "void");
154 for (c
=0; c
<v
->ptr_level
; c
++) {
160 void write_typedef(type_t
*type
, var_t
*names
)
162 char *tname
= names
->tname
;
163 while (NEXT_LINK(names
)) names
= NEXT_LINK(names
);
164 fprintf(header
, "typedef ");
165 write_type(header
, type
, NULL
, tname
);
166 fprintf(header
, " ");
169 if (PREV_LINK(names
))
170 fprintf(header
, ", ");
171 names
= PREV_LINK(names
);
173 fprintf(header
, ";\n");
176 /********** INTERFACES **********/
178 int is_object(attr_t
*a
)
181 if (a
->type
== ATTR_OBJECT
) return 1;
187 int is_local(attr_t
*a
)
190 if (a
->type
== ATTR_LOCAL
) return 1;
196 var_t
*is_callas(attr_t
*a
)
199 if (a
->type
== ATTR_CALLAS
) return a
->u
.pval
;
205 static void write_method_def(type_t
*iface
)
207 func_t
*cur
= iface
->funcs
;
208 while (NEXT_LINK(cur
)) cur
= NEXT_LINK(cur
);
209 fprintf(header
, "#define %s_METHODS", iface
->name
);
211 var_t
*def
= cur
->def
;
212 if (!is_callas(def
->attrs
)) {
213 var_t
*arg
= cur
->args
;
217 while (NEXT_LINK(arg
)) {
218 arg
= NEXT_LINK(arg
);
222 fprintf(header
, " \\\n");
223 if (!is_void(def
->type
, def
)) {
225 fprintf(header
, " ICOM_METHOD%d (", argc
);
227 fprintf(header
, " ICOM_METHOD (");
228 write_type(header
, def
->type
, def
, def
->tname
);
229 fprintf(header
, ",");
232 fprintf(header
, " ICOM_VMETHOD%d(", argc
);
234 fprintf(header
, " ICOM_VMETHOD (");
235 write_name(header
, def
);
237 fprintf(header
, ",");
238 write_type(header
, arg
->type
, arg
, arg
->tname
);
239 fprintf(header
, ",");
240 write_name(header
,arg
);
241 arg
= PREV_LINK(arg
);
243 fprintf(header
, ")");
245 cur
= PREV_LINK(cur
);
247 fprintf(header
, "\n");
250 static int write_method_macro(type_t
*iface
, char *name
)
253 func_t
*cur
= iface
->funcs
;
254 while (NEXT_LINK(cur
)) cur
= NEXT_LINK(cur
);
256 if (iface
->ref
) idx
= write_method_macro(iface
->ref
, name
);
258 fprintf(header
, "/*** %s methods ***/\n", iface
->name
);
260 var_t
*def
= cur
->def
;
261 if (!is_callas(def
->attrs
)) {
262 var_t
*arg
= cur
->args
;
266 arg
= NEXT_LINK(arg
);
270 fprintf(header
, "#define %s_", name
);
271 write_name(header
,def
);
272 fprintf(header
, "(p");
273 for (c
=0; c
<argc
; c
++)
274 fprintf(header
, ",%c", c
+'a');
275 fprintf(header
, ") ");
278 fprintf(header
, "ICOM_CALL%d(", argc
);
280 fprintf(header
, "ICOM_CALL(");
281 write_name(header
,def
);
282 fprintf(header
, ",p");
283 for (c
=0; c
<argc
; c
++)
284 fprintf(header
, ",%c", c
+'a');
285 fprintf(header
, ")\n");
286 if (cur
->idx
== -1) cur
->idx
= idx
;
287 else if (cur
->idx
!= idx
) yyerror("BUG: method index mismatch in write_method_macro");
290 cur
= PREV_LINK(cur
);
295 void write_method_args(FILE *h
, var_t
*arg
, char *name
)
298 while (NEXT_LINK(arg
))
299 arg
= NEXT_LINK(arg
);
301 fprintf(h
, " %s* This", name
);
304 write_type(h
, arg
->type
, arg
, arg
->tname
);
307 arg
= PREV_LINK(arg
);
311 static void write_method_proto(type_t
*iface
)
313 func_t
*cur
= iface
->funcs
;
314 while (NEXT_LINK(cur
)) cur
= NEXT_LINK(cur
);
316 var_t
*def
= cur
->def
;
317 var_t
*cas
= is_callas(def
->attrs
);
318 if (!is_local(def
->attrs
)) {
319 /* proxy prototype */
320 write_type(header
, def
->type
, def
, def
->tname
);
321 fprintf(header
, " CALLBACK %s_", iface
->name
);
322 write_name(header
,def
);
323 fprintf(header
, "_Proxy(\n");
324 write_method_args(header
, cur
->args
, iface
->name
);
325 fprintf(header
, ");\n");
327 fprintf(header
, "void __RPC_STUB %s_", iface
->name
);
328 write_name(header
,def
);
329 fprintf(header
, "_Stub(\n");
330 fprintf(header
, " IRpcStubBuffer* This,\n");
331 fprintf(header
, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
332 fprintf(header
, " PRPC_MESSAGE pRpcMessage,\n");
333 fprintf(header
, " DWORD* pdwStubPhase);\n");
336 func_t
*m
= iface
->funcs
;
337 while (m
&& strcmp(get_name(m
->def
), cas
->name
))
340 var_t
*mdef
= m
->def
;
341 /* proxy prototype - use local prototype */
342 write_type(header
, mdef
->type
, mdef
, mdef
->tname
);
343 fprintf(header
, " CALLBACK %s_", iface
->name
);
344 write_name(header
, mdef
);
345 fprintf(header
, "_Proxy(\n");
346 write_method_args(header
, m
->args
, iface
->name
);
347 fprintf(header
, ");\n");
348 /* stub prototype - use remotable prototype */
349 write_type(header
, def
->type
, def
, def
->tname
);
350 fprintf(header
, " __RPC_STUB %s_", iface
->name
);
351 write_name(header
, mdef
);
352 fprintf(header
, "_Stub(\n");
353 write_method_args(header
, cur
->args
, iface
->name
);
354 fprintf(header
, ");\n");
357 yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def
), cas
->name
);
361 cur
= PREV_LINK(cur
);
365 void write_forward(type_t
*iface
)
367 if (!iface
->written
) {
368 fprintf(header
, "typedef struct %s %s;\n", iface
->name
, iface
->name
);
369 iface
->written
= TRUE
;
373 void write_interface(type_t
*iface
)
375 if (!is_object(iface
->attrs
)) {
376 if (!iface
->funcs
) return;
377 yywarning("RPC interfaces not supported yet\n");
382 yywarning("%s has no methods", iface
->name
);
386 fprintf(header
, "/*****************************************************************************\n");
387 fprintf(header
, " * %s interface\n", iface
->name
);
388 fprintf(header
, " */\n");
389 write_forward(iface
);
391 fprintf(header
, "#define ICOM_INTERFACE %s\n", iface
->name
);
392 write_method_def(iface
);
393 fprintf(header
, "#define %s_IMETHODS \\\n", iface
->name
);
395 fprintf(header
, " %s_IMETHODS \\\n", iface
->ref
->name
);
396 fprintf(header
, " %s_METHODS \\\n", iface
->name
);
398 fprintf(header
, "ICOM_DEFINE(%s,%s)\n", iface
->name
, iface
->ref
->name
);
399 fprintf(header
, "#undef ICOM_INTERFACE\n");
401 fprintf(header
, "\n");
402 write_method_macro(iface
, iface
->name
);
403 fprintf(header
, "\n");
404 write_method_proto(iface
);
405 fprintf(header
, "\n");
407 if (!is_local(iface
->attrs
))