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
38 /* FIXME: support generation of stubless proxies */
40 static void write_stubdesc(void)
42 fprintf(proxy
, "const MIDL_STUB_DESC Object_StubDesc = {\n");
43 fprintf(proxy
, " 0,\n");
44 fprintf(proxy
, " NdrOleAllocate,\n");
45 fprintf(proxy
, " NdrOleFree,\n");
46 fprintf(proxy
, " {0}, 0, 0, 0, 0,\n");
47 fprintf(proxy
, " 0 /* __MIDL_TypeFormatString.Format */\n");
48 fprintf(proxy
, "};\n");
52 static void init_proxy(void)
55 proxy
= fopen(proxy_name
, "w");
56 fprintf(proxy
, "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION
);
57 fprintf(proxy
, "#include \"rpcproxy.h\"\n");
58 fprintf(proxy
, "#include \"%s\"\n", header_name
);
63 static void gen_proxy(type_t
*iface
, func_t
*cur
, int idx
)
65 var_t
*def
= cur
->def
;
66 int has_ret
= !is_void(def
->type
, def
);
68 write_type(proxy
, def
->type
, def
, def
->tname
);
69 fprintf(proxy
, " CALLBACK %s_", iface
->name
);
70 write_name(proxy
, def
);
71 fprintf(proxy
, "_Proxy(\n");
72 write_args(proxy
, cur
->args
, iface
->name
, 1);
73 fprintf(proxy
, ")\n");
74 fprintf(proxy
, "{\n");
78 write_type(proxy
, def
->type
, def
, def
->tname
);
79 fprintf(proxy
, " _Ret;\n");
81 fprintf(proxy
, " RPC_MESSAGE _Msg;\n");
82 fprintf(proxy
, " MIDL_STUB_MESSAGE _StubMsg;\n");
86 /* FIXME: clear output vars? */
88 fprintf(proxy
, " NdrProxyInitialize(This, &_Msg, &_StubMsg, &Object_StubDesc, %d);\n", idx
);
90 /* FIXME: size buffer */
92 fprintf(proxy
, " NdrProxyGetBuffer(This, &_StubMsg);\n");
96 fprintf(proxy
, " NdrProxySendReceive(This, &_StubMsg);\n");
98 /* FIXME: unmarshall */
100 fprintf(proxy
, " NdrProxyFreeBuffer(This, &_StubMsg);\n");
103 fprintf(proxy
, " return _Ret;\n");
105 fprintf(proxy
, "}\n");
106 fprintf(proxy
, "\n");
109 static void gen_stub(type_t
*iface
, func_t
*cur
, char *cas
)
111 var_t
*def
= cur
->def
;
113 int has_ret
= !is_void(def
->type
, def
);
115 fprintf(proxy
, "void __RPC_STUB %s_", iface
->name
);
116 write_name(proxy
, def
);
117 fprintf(proxy
, "_Stub(\n");
118 fprintf(proxy
, " IRpcStubBuffer* This,\n");
119 fprintf(proxy
, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
120 fprintf(proxy
, " PRPC_MESSAGE pRpcMessage,\n");
121 fprintf(proxy
, " DWORD* pdwStubPhase)\n");
122 fprintf(proxy
, "{\n");
123 /* local variables */
126 write_type(proxy
, def
->type
, def
, def
->tname
);
127 fprintf(proxy
, " _Ret;\n");
129 fprintf(proxy
, " %s* _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface
->name
, iface
->name
);
130 fprintf(proxy
, " MIDL_STUB_MESSAGE _StubMsg;\n");
134 write_type(proxy
, arg
->type
, arg
, arg
->tname
);
136 write_name(proxy
, arg
);
137 fprintf(proxy
, ";\n");
138 arg
= NEXT_LINK(arg
);
140 fprintf(proxy
, "\n");
143 /* FIXME: clear output vars? */
145 fprintf(proxy
, " NdrStubInitialize(pRpcMessage, &_StubMsg, &Object_StubDesc, pRpcChannelBuffer);\n");
147 /* FIXME: unmarshall */
149 fprintf(proxy
, " *pdwStubPhase = STUB_CALL_SERVER;\n");
151 if (has_ret
) fprintf(proxy
, "_Ret = ");
152 fprintf(proxy
, "%s_", iface
->name
);
153 if (cas
) fprintf(proxy
, "%s_Stub", cas
);
154 else write_name(proxy
, def
);
155 fprintf(proxy
, "(_This");
158 while (NEXT_LINK(arg
)) arg
= NEXT_LINK(arg
);
160 fprintf(proxy
, ", ");
161 write_name(proxy
, arg
);
162 arg
= PREV_LINK(arg
);
165 fprintf(proxy
, ");\n");
166 fprintf(proxy
, " *pdwStubPhase = STUB_MARSHAL;\n");
168 /* FIXME: size buffer */
170 fprintf(proxy
, " NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n");
172 /* FIXME: marshall */
174 fprintf(proxy
, "}\n");
175 fprintf(proxy
, "\n");
178 static int write_proxy_methods(type_t
*iface
)
180 func_t
*cur
= iface
->funcs
;
182 while (NEXT_LINK(cur
)) cur
= NEXT_LINK(cur
);
184 if (iface
->ref
) i
= write_proxy_methods(iface
->ref
);
186 var_t
*def
= cur
->def
;
187 if (!is_callas(def
->attrs
)) {
188 if (i
) fprintf(proxy
, ",\n ");
189 fprintf(proxy
, "%s_", iface
->name
);
190 write_name(proxy
, def
);
191 fprintf(proxy
, "_Proxy");
194 cur
= PREV_LINK(cur
);
199 static int write_stub_methods(type_t
*iface
)
201 func_t
*cur
= iface
->funcs
;
203 while (NEXT_LINK(cur
)) cur
= NEXT_LINK(cur
);
205 if (iface
->ref
) i
= write_stub_methods(iface
->ref
);
206 else return i
; /* skip IUnknown */
208 var_t
*def
= cur
->def
;
209 if (!is_local(def
->attrs
)) {
210 if (i
) fprintf(proxy
, ",\n");
211 fprintf(proxy
, " %s_", iface
->name
);
212 write_name(proxy
, def
);
213 fprintf(proxy
, "_Stub");
216 cur
= PREV_LINK(cur
);
221 typedef struct _if_list if_list
;
229 void write_proxy(type_t
*iface
)
231 int midx
= -1, stubs
;
232 func_t
*cur
= iface
->funcs
;
236 yywarning("%s has no methods", iface
->name
);
240 if (header_only
) return;
242 while (NEXT_LINK(cur
)) cur
= NEXT_LINK(cur
);
244 /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */
248 if_cur
= xmalloc(sizeof(if_list
));
249 if_cur
->iface
= iface
;
251 LINK(if_cur
, if_first
);
254 fprintf(proxy
, "/*****************************************************************************\n");
255 fprintf(proxy
, " * %s interface\n", iface
->name
);
256 fprintf(proxy
, " */\n");
258 var_t
*def
= cur
->def
;
259 if (!is_local(def
->attrs
)) {
260 var_t
*cas
= is_callas(def
->attrs
);
261 char *cname
= cas
? cas
->name
: NULL
;
264 func_t
*m
= iface
->funcs
;
265 while (m
&& strcmp(get_name(m
->def
), cname
))
269 gen_proxy(iface
, cur
, idx
);
270 gen_stub(iface
, cur
, cname
);
271 if (midx
== -1) midx
= idx
;
272 else if (midx
!= idx
) yyerror("method index mismatch in write_proxy");
275 cur
= PREV_LINK(cur
);
279 fprintf(proxy
, "const CINTERFACE_PROXY_VTABLE(%d) %sProxyVtbl = {\n", midx
, iface
->name
);
280 fprintf(proxy
, " {&IID_%s},\n", iface
->name
);
281 fprintf(proxy
, " {");
282 write_proxy_methods(iface
);
283 fprintf(proxy
, "}\n");
284 fprintf(proxy
, "};\n");
285 fprintf(proxy
, "\n");
288 fprintf(proxy
, "static const PRPC_STUB_FUNCTION %s_table[] = {\n", iface
->name
);
289 stubs
= write_stub_methods(iface
);
290 fprintf(proxy
, "\n");
291 fprintf(proxy
, "};\n");
292 fprintf(proxy
, "\n");
293 fprintf(proxy
, "const CInterfaceStubVtbl %sStubVtbl = {\n", iface
->name
);
294 fprintf(proxy
, " {&IID_%s,\n", iface
->name
);
295 fprintf(proxy
, " 0,\n");
296 fprintf(proxy
, " %d,\n", stubs
+3);
297 fprintf(proxy
, " &%s_table[-3]},\n", iface
->name
);
298 fprintf(proxy
, " {CStdStubBuffer_METHODS}\n");
299 fprintf(proxy
, "};\n");
300 fprintf(proxy
, "\n");
303 void finish_proxy(void)
305 if_list
*lcur
= if_first
;
307 char *file_id
= proxy_token
;
311 while (NEXT_LINK(lcur
)) lcur
= NEXT_LINK(lcur
);
313 fprintf(proxy
, "const CInterfaceProxyVtbl* _%s_ProxyVtblList[] = {\n", file_id
);
316 fprintf(proxy
, " (CInterfaceProxyVtbl*)&%sProxyVtbl,\n", cur
->iface
->name
);
317 cur
= PREV_LINK(cur
);
319 fprintf(proxy
, " 0\n");
320 fprintf(proxy
, "};\n");
321 fprintf(proxy
, "\n");
323 fprintf(proxy
, "const CInterfaceStubVtbl* _%s_StubVtblList[] = {\n", file_id
);
326 fprintf(proxy
, " (CInterfaceStubVtbl*)&%sStubVtbl,\n", cur
->iface
->name
);
327 cur
= PREV_LINK(cur
);
329 fprintf(proxy
, " 0\n");
330 fprintf(proxy
, "};\n");
331 fprintf(proxy
, "\n");
333 fprintf(proxy
, "const PCInterfaceName _%s_InterfaceNamesList[] = {\n", file_id
);
336 fprintf(proxy
, " \"%s\",\n", cur
->iface
->name
);
337 cur
= PREV_LINK(cur
);
339 fprintf(proxy
, " 0\n");
340 fprintf(proxy
, "};\n");
341 fprintf(proxy
, "\n");
343 fprintf(proxy
, "#define _%s_CHECK_IID(n) IID_GENERIC_CHECK_IID(_XXX, pIID, n)\n", file_id
);
344 fprintf(proxy
, "\n");
345 fprintf(proxy
, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id
);
346 fprintf(proxy
, "{\n");
350 fprintf(proxy
, " if (!_%s_CHECK_IID(%d)) {\n", file_id
, c
);
351 fprintf(proxy
, " *pIndex = %d\n", c
);
352 fprintf(proxy
, " return 1;\n");
353 fprintf(proxy
, " }\n");
354 cur
= PREV_LINK(cur
);
357 fprintf(proxy
, " return 0;\n");
358 fprintf(proxy
, "}\n");
359 fprintf(proxy
, "\n");
361 fprintf(proxy
, "const ExtendedProxyFileInfo %s_ProxyFileInfo = {\n", file_id
);
362 fprintf(proxy
, " (PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id
);
363 fprintf(proxy
, " (PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id
);
364 fprintf(proxy
, " (const PCInterfaceName*)&_%s_InterfaceNamesList,\n", file_id
);
365 fprintf(proxy
, " 0,\n");
366 fprintf(proxy
, " &_%s_IID_Lookup,\n", file_id
);
367 fprintf(proxy
, " %d,\n", c
);
368 fprintf(proxy
, " 1\n");
369 fprintf(proxy
, "};\n");