Output intermediate variables for the method to write into in stubs.
[wine.git] / tools / widl / proxy.c
blobe45ef3f415fec1e37f966c6dee52f7a477a6b0dc
1 /*
2 * IDL Compiler
4 * Copyright 2002 Ove Kaaven
5 * Copyright 2004 Mike McCormack
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.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 <assert.h>
31 #include <ctype.h>
32 #include <signal.h>
34 #include "widl.h"
35 #include "utils.h"
36 #include "parser.h"
37 #include "header.h"
39 static FILE* proxy;
40 static int indent = 0;
42 /* FIXME: support generation of stubless proxies */
44 int print_proxy( char *format, ... )
46 va_list va;
47 int i, r;
49 va_start( va, format );
50 for( i=0; i<indent; i++ )
51 fprintf( proxy, " " );
52 r = vfprintf( proxy, format, va );
53 va_end( va );
54 return r;
57 static type_t *get_base_type( type_t *type )
59 while( type->ref )
60 type = type->ref;
61 return type;
64 static void write_stubdescproto(void)
66 print_proxy( "extern const MIDL_STUB_DESC Object_StubDesc;\n");
67 print_proxy( "\n");
70 static void write_stubdesc(void)
72 print_proxy( "const MIDL_STUB_DESC Object_StubDesc = {\n");
73 print_proxy( " 0,\n");
74 print_proxy( " NdrOleAllocate,\n");
75 print_proxy( " NdrOleFree,\n");
76 print_proxy( " {0}, 0, 0, 0, 0,\n");
77 print_proxy( " 0 /* __MIDL_TypeFormatString.Format */\n");
78 print_proxy( "};\n");
79 print_proxy( "\n");
82 static void write_formatdesc( char *str )
84 print_proxy( "typedef struct _MIDL_%s_FORMAT_STRING {\n", str );
85 print_proxy( " short Pad;\n");
86 print_proxy( " unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str);
87 print_proxy( "} MIDL_%s_FORMAT_STRING;\n", str);
88 print_proxy( "\n");
91 static void write_formatstringsdecl(void)
93 print_proxy( "#define TYPE_FORMAT_STRING_SIZE %d\n",1); /* FIXME */
94 print_proxy( "#define PROC_FORMAT_STRING_SIZE %d\n",1); /* FIXME */
95 print_proxy( "\n");
96 write_formatdesc( "TYPE" );
97 write_formatdesc( "PROC" );
98 print_proxy( "extern const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n");
99 print_proxy( "extern const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n");
100 print_proxy( "\n");
103 static void write_formatstring( int proc )
105 const char *t, *n;
106 if( !proc )
108 t = "TYPE";
109 n = "Type";
111 else
113 t = "PROC";
114 n = "Proc";
116 print_proxy( "static const MIDL_%s_FORMAT_STRING __MIDL_%sFormatString =\n", t, n);
117 print_proxy( "{\n");
118 indent++;
119 print_proxy( "0,\n");
120 print_proxy( "{\n");
121 indent++;
122 print_proxy( "0\n");
123 indent--;
124 print_proxy( "}\n");
125 indent--;
126 print_proxy( "};\n");
127 print_proxy( "\n");
130 static void init_proxy(void)
132 if (proxy) return;
133 proxy = fopen(proxy_name, "w");
134 print_proxy( "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION);
135 print_proxy( "\n");
136 print_proxy( "#ifndef __REDQ_RPCPROXY_H_VERSION__\n");
137 print_proxy( "#define __REQUIRED_RPCPROXY_H_VERSION__ 440\n");
138 print_proxy( "#endif /* __REDQ_RPCPROXY_H_VERSION__ */\n");
139 print_proxy( "\n");
140 print_proxy( "#include \"rpcproxy.h\"\n");
141 print_proxy( "\n");
142 print_proxy( "#ifndef __RPCPROXY_H_VERSION__\n");
143 print_proxy( "#error This code needs a newer version of rpcproxy.h\n");
144 print_proxy( "#endif /* __RPCPROXY_H_VERSION__ */\n");
145 print_proxy( "\n");
146 print_proxy( "#include \"%s\"\n", header_name);
147 print_proxy( "\n");
148 write_formatstringsdecl();
149 write_stubdescproto();
152 static void clear_output_vars( var_t *arg )
154 if (arg) {
155 while (NEXT_LINK(arg))
156 arg = NEXT_LINK(arg);
158 while (arg) {
159 if (is_attr(arg->attrs, ATTR_OUT) && !is_attr(arg->attrs, ATTR_IN)) {
160 print_proxy( "if(%s)\n", arg->name );
161 indent++;
162 print_proxy( "MIDL_memset( %s, 0, sizeof( ", arg->name );
163 indent--;
164 write_type(proxy, arg->type, arg, arg->tname);
165 fprintf( proxy, " ));\n" );
167 arg = PREV_LINK(arg);
171 static void proxy_gen_marshall_size( var_t *arg )
173 print_proxy( "_StubMsg.BufferLength = 0U;\n" );
175 if (arg) {
176 while (NEXT_LINK(arg))
177 arg = NEXT_LINK(arg);
179 while (arg) {
180 if (is_attr(arg->attrs, ATTR_IN)) {
181 int index = 0;
182 type_t *type = get_base_type(arg->type);
184 switch( type->type )
186 case RPC_FC_BYTE:
187 case RPC_FC_CHAR:
188 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 1, arg->name );
189 break;
191 case RPC_FC_SHORT:
192 case RPC_FC_USHORT:
193 case RPC_FC_ENUM16:
194 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 2, arg->name );
195 break;
197 case RPC_FC_LONG:
198 case RPC_FC_ULONG:
199 case RPC_FC_ENUM32:
200 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 4, arg->name );
201 break;
203 case RPC_FC_STRUCT:
204 print_proxy( "NdrSimpleStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name );
205 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index );
206 break;
208 case RPC_FC_IP:
209 print_proxy( "NdrPointerBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name );
210 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
211 break;
213 default:
214 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
217 arg = PREV_LINK(arg);
221 static void gen_marshall_copydata( var_t *arg )
223 if (arg) {
224 while (NEXT_LINK(arg))
225 arg = NEXT_LINK(arg);
227 while (arg) {
228 if (is_attr(arg->attrs, ATTR_IN)) {
229 int index = 0;
230 type_t *type = get_base_type(arg->type);
232 switch( type->type )
234 case RPC_FC_BYTE:
235 case RPC_FC_CHAR:
236 case RPC_FC_SHORT:
237 case RPC_FC_USHORT:
238 case RPC_FC_ENUM16:
239 case RPC_FC_LONG:
240 case RPC_FC_ULONG:
241 case RPC_FC_ENUM32:
242 print_proxy( "*((");
243 write_type(proxy, arg->type, arg, arg->tname);
244 fprintf(proxy,"*)_StubMsg.Buffer)++ = %s;\n", arg->name );
245 break;
247 case RPC_FC_STRUCT:
248 /* FIXME: add the format string, and set the index below */
249 print_proxy( "NdrSimpleStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name );
250 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
251 break;
253 case RPC_FC_IP:
254 print_proxy( "NdrPointerMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name );
255 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
256 break;
258 default:
259 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
262 arg = PREV_LINK(arg);
266 static void gen_marshall( var_t *arg )
268 /* generated code to determine the size of the buffer required */
269 proxy_gen_marshall_size( arg );
271 /* generated code to allocate the buffer */
272 print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" );
274 /* generated code to copy the args into the buffer */
275 gen_marshall_copydata( arg );
277 print_proxy( "\n");
280 static void gen_unmarshall( var_t *arg )
282 if (arg) {
283 while (NEXT_LINK(arg))
284 arg = NEXT_LINK(arg);
286 while (arg) {
287 if (is_attr(arg->attrs, ATTR_IN)) {
288 int index = 0;
289 print_proxy( "NdrPointerUnmarshall(&_StubMsg, (unsigned char**)&%s, ", arg->name );
290 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index );
292 arg = PREV_LINK(arg);
296 static void gen_proxy(type_t *iface, func_t *cur, int idx)
298 var_t *def = cur->def;
299 int has_ret = !is_void(def->type, def);
301 indent = 0;
302 write_type(proxy, def->type, def, def->tname);
303 print_proxy( " CALLBACK %s_", iface->name);
304 write_name(proxy, def);
305 print_proxy( "_Proxy(\n");
306 write_args(proxy, cur->args, iface->name, 1, TRUE);
307 print_proxy( ")\n");
308 print_proxy( "{\n");
309 indent ++;
310 /* local variables */
311 if (has_ret) {
312 print_proxy( "" );
313 write_type(proxy, def->type, def, def->tname);
314 print_proxy( " _Ret;\n");
316 print_proxy( "RPC_MESSAGE _Msg;\n" );
317 print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" );
318 print_proxy( "\n");
320 /* FIXME: trace */
321 clear_output_vars( cur->args );
323 print_proxy( "RpcTryExcept\n" );
324 print_proxy( "{\n" );
325 indent++;
326 print_proxy( "NdrProxyInitialize(This, &_Msg, &_StubMsg, &Object_StubDesc, %d);\n", idx);
328 print_proxy( "RpcTryFinally\n" );
329 print_proxy( "{\n" );
330 indent++;
332 gen_marshall( cur->args );
334 print_proxy( "NdrProxySendReceive(This, &_StubMsg);\n" );
335 print_proxy( "\n");
337 gen_unmarshall( cur->args );
338 if (has_ret) {
340 * FIXME: We only need to round the buffer up if it could be unaligned...
341 * We should calculate how much buffer we used and output the following
342 * line only if necessary.
344 print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n");
346 print_proxy( "_Ret = *((" );
347 write_type(proxy, def->type, def, def->tname);
348 fprintf(proxy, "*)_StubMsg.Buffer)++;\n");
351 indent--;
352 print_proxy( "}\n");
353 print_proxy( "RpcFinally\n" );
354 print_proxy( "{\n" );
355 indent++;
356 print_proxy( "NdrProxyFreeBuffer(This, &_StubMsg);\n" );
357 indent--;
358 print_proxy( "}\n");
359 print_proxy( "RpcEndFinally\n" );
360 indent--;
361 print_proxy( "}\n" );
362 print_proxy( "RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE)\n" );
363 print_proxy( "{\n" );
364 if (has_ret) {
365 indent++;
366 print_proxy( "_Ret = NdrProxyErrorHandler(RpcExceptionCode());\n" );
367 indent--;
369 print_proxy( "}\n" );
370 print_proxy( "RpcEndExcept\n" );
372 if (has_ret) {
373 print_proxy( "return _Ret;\n" );
375 indent--;
376 print_proxy( "}\n");
377 print_proxy( "\n");
380 static void stub_write_locals( var_t *arg )
382 int n = 0;
383 while (arg) {
384 int outptr = is_attr(arg->attrs, ATTR_OUT);
386 /* create a temporary variable to store the output */
387 if (outptr) {
388 var_t temp;
389 memset( &temp, 0, sizeof temp );
390 temp.ptr_level = arg->ptr_level - 1; /* dereference once */
391 print_proxy("");
392 write_type(proxy, arg->type, &temp, arg->tname);
393 fprintf(proxy, " _M%d;\n",n++);
395 print_proxy("");
396 write_type(proxy, arg->type, arg, arg->tname);
397 fprintf(proxy, " ");
398 write_name(proxy, arg);
399 /* if (outptr) fprintf(proxy, " = &_M%d;\n",n++); */
400 fprintf(proxy, ";\n");
401 arg = NEXT_LINK(arg);
405 static void stub_unmarshall( var_t *arg )
407 int n = 0;
408 if (arg) {
409 while (NEXT_LINK(arg))
410 arg = NEXT_LINK(arg);
412 while (arg) {
413 if (is_attr(arg->attrs, ATTR_IN)) {
414 int index = 0;
415 type_t *type = get_base_type(arg->type);
417 switch( type->type )
419 case RPC_FC_BYTE:
420 case RPC_FC_CHAR:
421 case RPC_FC_SHORT:
422 case RPC_FC_USHORT:
423 case RPC_FC_ENUM16:
424 case RPC_FC_LONG:
425 case RPC_FC_ULONG:
426 case RPC_FC_ENUM32:
427 print_proxy( "%s = *((", arg->name);
428 write_type(proxy, arg->type, arg, arg->tname);
429 fprintf(proxy,"*)_StubMsg.Buffer)++;\n");
430 break;
432 case RPC_FC_STRUCT:
433 /* FIXME: add the format string, and set the index below */
434 print_proxy( "NdrSimpleStructUnmarshall(&_StubMsg, (unsigned char**)&%s, ", arg->name );
435 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d],0);\n", index );
436 break;
438 default:
439 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
442 else if (is_attr(arg->attrs, ATTR_OUT)) {
443 print_proxy("");
444 write_name(proxy, arg);
445 fprintf(proxy," = &_M%d;\n", n);
446 print_proxy("_M%d = 0;\n", n++);
448 arg = PREV_LINK(arg);
452 static void stub_gen_marshall_size( var_t *arg )
454 print_proxy( "_StubMsg.BufferLength = 0U;\n" );
456 if (arg) {
457 while (NEXT_LINK(arg))
458 arg = NEXT_LINK(arg);
460 while (arg) {
461 if (is_attr(arg->attrs, ATTR_OUT)) {
462 int index = 0;
463 type_t *type = get_base_type(arg->type);
465 switch( type->type )
467 case RPC_FC_BYTE:
468 case RPC_FC_CHAR:
469 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 1, arg->name );
470 break;
472 case RPC_FC_SHORT:
473 case RPC_FC_USHORT:
474 case RPC_FC_ENUM16:
475 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 2, arg->name );
476 break;
478 case RPC_FC_LONG:
479 case RPC_FC_ULONG:
480 case RPC_FC_ENUM32:
481 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 4, arg->name );
482 break;
484 case RPC_FC_STRUCT:
485 print_proxy( "NdrSimpleStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name );
486 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index );
487 break;
489 case RPC_FC_IP:
490 print_proxy( "NdrPointerBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name );
491 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
492 break;
494 default:
495 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
498 arg = PREV_LINK(arg);
502 static void stub_gen_marshall_copydata( var_t *arg )
504 if (arg) {
505 while (NEXT_LINK(arg))
506 arg = NEXT_LINK(arg);
508 while (arg) {
509 if (is_attr(arg->attrs, ATTR_OUT)) {
510 int index = 0;
511 type_t *type = get_base_type(arg->type);
513 switch( type->type )
515 case RPC_FC_BYTE:
516 case RPC_FC_CHAR:
517 case RPC_FC_SHORT:
518 case RPC_FC_USHORT:
519 case RPC_FC_ENUM16:
520 case RPC_FC_LONG:
521 case RPC_FC_ULONG:
522 case RPC_FC_ENUM32:
523 print_proxy( "*((");
524 write_type(proxy, arg->type, arg, arg->tname);
525 fprintf(proxy,"*)_StubMsg.Buffer)++ = %s;\n", arg->name );
526 break;
528 case RPC_FC_STRUCT:
529 /* FIXME: add the format string, and set the index below */
530 print_proxy( "NdrSimpleStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name );
531 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
532 break;
534 case RPC_FC_IP:
535 print_proxy( "NdrPointerMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name );
536 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
537 break;
539 default:
540 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
543 arg = PREV_LINK(arg);
547 static void stub_genmarshall( var_t *args )
549 /* FIXME: size buffer */
550 stub_gen_marshall_size( args );
552 print_proxy("NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n");
554 stub_gen_marshall_copydata( args );
557 static void gen_stub(type_t *iface, func_t *cur, char *cas)
559 var_t *def = cur->def;
560 var_t *arg;
561 int has_ret = !is_void(def->type, def);
563 indent = 0;
564 print_proxy( "void __RPC_STUB %s_", iface->name);
565 write_name(proxy, def);
566 print_proxy( "_Stub(\n");
567 indent++;
568 print_proxy( "IRpcStubBuffer* This,\n");
569 print_proxy( "IRpcChannelBuffer* pRpcChannelBuffer,\n");
570 print_proxy( "PRPC_MESSAGE pRpcMessage,\n");
571 print_proxy( "DWORD* _pdwStubPhase)\n");
572 indent--;
573 print_proxy( "{\n");
574 indent++;
575 /* local variables */
576 if (has_ret) {
577 print_proxy("");
578 write_type(proxy, def->type, def, def->tname);
579 fprintf(proxy, " _Ret;\n");
581 print_proxy("%s* _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name);
582 print_proxy("MIDL_STUB_MESSAGE _StubMsg;\n");
583 stub_write_locals( cur->args );
584 fprintf(proxy, "\n");
586 /* FIXME: trace */
588 print_proxy("NdrStubInitialize(pRpcMessage, &_StubMsg, &Object_StubDesc, pRpcChannelBuffer);\n");
589 fprintf(proxy, "\n");
591 print_proxy("RpcTryFinally\n");
592 print_proxy("{\n");
593 indent++;
595 stub_unmarshall( cur->args );
596 fprintf(proxy, "\n");
598 print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n");
599 fprintf(proxy, "\n");
600 print_proxy("");
601 if (has_ret) fprintf(proxy, "_Ret = ");
602 fprintf(proxy, "%s_", iface->name);
603 if (cas) fprintf(proxy, "%s_Stub", cas);
604 else write_name(proxy, def);
605 fprintf(proxy, "(_This");
606 arg = cur->args;
607 if (arg) {
608 while (NEXT_LINK(arg)) arg = NEXT_LINK(arg);
609 while (arg) {
610 fprintf(proxy, ", ");
611 write_name(proxy, arg);
612 arg = PREV_LINK(arg);
615 fprintf(proxy, ");\n");
616 fprintf(proxy, "\n");
617 print_proxy("*_pdwStubPhase = STUB_MARSHAL;\n");
618 fprintf(proxy, "\n");
620 stub_genmarshall( cur->args );
621 fprintf(proxy, "\n");
623 if (has_ret) {
625 * FIXME: We only need to round the buffer up if it could be unaligned...
626 * We should calculate how much buffer we used and output the following
627 * line only if necessary.
629 print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n");
631 print_proxy( "*((" );
632 write_type(proxy, def->type, def, def->tname);
633 fprintf(proxy, "*)_StubMsg.Buffer)++ = _Ret;\n");
636 indent--;
637 print_proxy("}\n");
638 print_proxy("RpcFinally\n");
639 print_proxy("{\n");
640 print_proxy("}\n");
641 print_proxy("RpcEndFinally\n");
643 /* FIXME: marshall */
644 indent--;
646 print_proxy("}\n");
647 print_proxy("\n");
650 static int write_proxy_methods(type_t *iface)
652 func_t *cur = iface->funcs;
653 int i = 0;
654 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
656 if (iface->ref) i = write_proxy_methods(iface->ref);
657 while (cur) {
658 var_t *def = cur->def;
659 if (!is_callas(def->attrs)) {
660 if (i) fprintf(proxy, ",\n ");
661 fprintf(proxy, "%s_", iface->name);
662 write_name(proxy, def);
663 fprintf(proxy, "_Proxy");
664 i++;
666 cur = PREV_LINK(cur);
668 return i;
671 static int write_stub_methods(type_t *iface)
673 func_t *cur = iface->funcs;
674 int i = 0;
675 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
677 if (iface->ref) i = write_stub_methods(iface->ref);
678 else return i; /* skip IUnknown */
679 while (cur) {
680 var_t *def = cur->def;
681 if (!is_local(def->attrs)) {
682 if (i) fprintf(proxy, ",\n");
683 fprintf(proxy, " %s_", iface->name);
684 write_name(proxy, def);
685 fprintf(proxy, "_Stub");
686 i++;
688 cur = PREV_LINK(cur);
690 return i;
693 static void write_proxy(type_t *iface)
695 int midx = -1, stubs;
696 func_t *cur = iface->funcs;
698 if (!cur) return;
699 if (!do_everything) return;
701 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
703 /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */
705 init_proxy();
707 fprintf(proxy, "/*****************************************************************************\n");
708 fprintf(proxy, " * %s interface\n", iface->name);
709 fprintf(proxy, " */\n");
710 while (cur) {
711 var_t *def = cur->def;
712 if (!is_local(def->attrs)) {
713 var_t *cas = is_callas(def->attrs);
714 char *cname = cas ? cas->name : NULL;
715 int idx = cur->idx;
716 if (cname) {
717 func_t *m = iface->funcs;
718 while (m && strcmp(get_name(m->def), cname))
719 m = NEXT_LINK(m);
720 idx = m->idx;
722 gen_proxy(iface, cur, idx);
723 gen_stub(iface, cur, cname);
724 if (midx == -1) midx = idx;
725 else if (midx != idx) yyerror("method index mismatch in write_proxy");
726 midx++;
728 cur = PREV_LINK(cur);
731 write_stubdesc();
733 /* proxy vtable */
734 fprintf(proxy, "const CINTERFACE_PROXY_VTABLE(%d) %sProxyVtbl =\n", midx, iface->name);
735 fprintf(proxy, "{\n");
736 fprintf(proxy, " {&IID_%s},\n", iface->name);
737 fprintf(proxy, " {");
738 write_proxy_methods(iface);
739 fprintf(proxy, "}\n");
740 fprintf(proxy, "};\n");
741 fprintf(proxy, "\n");
743 /* stub vtable */
744 fprintf(proxy, "static const PRPC_STUB_FUNCTION %s_table[] =\n", iface->name);
745 fprintf(proxy, "{\n");
746 stubs = write_stub_methods(iface);
747 fprintf(proxy, "\n");
748 fprintf(proxy, "};\n");
749 fprintf(proxy, "\n");
750 fprintf(proxy, "const CInterfaceStubVtbl %sStubVtbl = {\n", iface->name);
751 fprintf(proxy, " {&IID_%s,\n", iface->name);
752 fprintf(proxy, " 0,\n");
753 fprintf(proxy, " %d,\n", stubs+3);
754 fprintf(proxy, " &%s_table[-3]},\n", iface->name);
755 fprintf(proxy, " {CStdStubBuffer_METHODS}\n");
756 fprintf(proxy, "};\n");
757 fprintf(proxy, "\n");
758 write_formatstring( 1 );
759 write_formatstring( 0 );
762 void write_proxies(ifref_t *ifaces)
764 ifref_t *lcur = ifaces;
765 ifref_t *cur;
766 char *file_id = proxy_token;
767 int c;
769 if (!lcur) return;
770 while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur);
772 cur = lcur;
773 while (cur) {
774 if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs))
775 write_proxy(cur->iface);
776 cur = PREV_LINK(cur);
779 if (!proxy) return;
781 fprintf(proxy, "const CInterfaceProxyVtbl* _%s_ProxyVtblList[] =\n", file_id);
782 fprintf(proxy, "{\n");
783 cur = lcur;
784 while (cur) {
785 if(cur->iface->ref)
786 fprintf(proxy, " (CInterfaceProxyVtbl*)&%sProxyVtbl,\n", cur->iface->name);
787 cur = PREV_LINK(cur);
789 fprintf(proxy, " 0\n");
790 fprintf(proxy, "};\n");
791 fprintf(proxy, "\n");
793 fprintf(proxy, "const CInterfaceStubVtbl* _%s_StubVtblList[] =\n", file_id);
794 fprintf(proxy, "{\n");
795 cur = lcur;
796 while (cur) {
797 if(cur->iface->ref)
798 fprintf(proxy, " (CInterfaceStubVtbl*)&%sStubVtbl,\n", cur->iface->name);
799 cur = PREV_LINK(cur);
801 fprintf(proxy, " 0\n");
802 fprintf(proxy, "};\n");
803 fprintf(proxy, "\n");
805 fprintf(proxy, "const PCInterfaceName _%s_InterfaceNamesList[] =\n", file_id);
806 fprintf(proxy, "{\n");
807 cur = lcur;
808 while (cur) {
809 if(cur->iface->ref)
810 fprintf(proxy, " \"%s\",\n", cur->iface->name);
811 cur = PREV_LINK(cur);
813 fprintf(proxy, " 0\n");
814 fprintf(proxy, "};\n");
815 fprintf(proxy, "\n");
817 fprintf(proxy, "#define _%s_CHECK_IID(n) IID_GENERIC_CHECK_IID(_%s, pIID, n)\n", file_id, file_id);
818 fprintf(proxy, "\n");
819 fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id);
820 fprintf(proxy, "{\n");
821 cur = lcur;
822 c = 0;
823 while (cur) {
824 if(cur->iface->ref)
826 fprintf(proxy, " if (!_%s_CHECK_IID(%d)) {\n", file_id, c);
827 fprintf(proxy, " *pIndex = %d;\n", c);
828 fprintf(proxy, " return 1;\n");
829 fprintf(proxy, " }\n");
830 c++;
832 cur = PREV_LINK(cur);
834 fprintf(proxy, " return 0;\n");
835 fprintf(proxy, "}\n");
836 fprintf(proxy, "\n");
838 fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo =\n", file_id);
839 fprintf(proxy, "{\n");
840 fprintf(proxy, " (PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id);
841 fprintf(proxy, " (PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id);
842 fprintf(proxy, " (const PCInterfaceName*)&_%s_InterfaceNamesList,\n", file_id);
843 fprintf(proxy, " 0,\n");
844 fprintf(proxy, " &_%s_IID_Lookup,\n", file_id);
845 fprintf(proxy, " %d,\n", c);
846 fprintf(proxy, " 1,\n");
847 fprintf(proxy, " 0,\n");
848 fprintf(proxy, " 0,\n");
849 fprintf(proxy, " 0,\n");
850 fprintf(proxy, " 0\n");
851 fprintf(proxy, "};\n");
853 fclose(proxy);