4 * Copyright 2005 Eric Kohl
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
34 #define END_OF_LIST(list) \
37 while (NEXT_LINK(list)) \
38 list = NEXT_LINK(list); \
43 static int indent
= 0;
45 static int print_client( const char *format
, ... )
51 for (i
= 0; i
< indent
; i
++)
53 r
= vfprintf(client
, format
, va
);
59 static void write_procformatstring(type_t
*iface
)
61 func_t
*func
= iface
->funcs
;
64 print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
71 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
74 /* emit argument data */
78 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
81 switch(var
->type
->type
)
84 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
85 print_client("0x%02x, /* FC_BYTE */\n", RPC_FC_BYTE
);
88 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
89 print_client("0x%02x, /* FC_CHAR */\n", RPC_FC_CHAR
);
92 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
93 print_client("0x%02x, /* FC_WCHAR */\n", RPC_FC_WCHAR
);
97 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
98 print_client("0x%02x, /* FC_USHORT */\n", RPC_FC_SHORT
);
102 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
103 print_client("0x%02x, /* FC_LONG */\n", RPC_FC_LONG
);
106 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
107 print_client("0x%02x, /* FC_HYPER */\n", RPC_FC_HYPER
);
110 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
111 print_client("0x%02x, /* FC_IGNORE */\n", RPC_FC_IGNORE
);
114 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
115 print_client("0x%02x, /* FC_SMALL */\n", RPC_FC_SMALL
);
118 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
119 print_client("0x%02x, /* FC_FLOAT */\n", RPC_FC_FLOAT
);
122 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
123 print_client("0x%02x, /* FC_DOUBLE */\n", RPC_FC_DOUBLE
);
126 error("Unknown/unsupported type\n");
130 var
= PREV_LINK(var
);
134 /* emit return value data */
136 if (is_void(var
->type
, NULL
))
138 print_client("0x5b, /* FC_END */\n");
139 print_client("0x5c, /* FC_PAD */\n");
143 switch(var
->type
->type
)
146 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
147 print_client("0x%02x, /* FC_BYTE */\n", var
->type
->type
);
150 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
151 print_client("0x%02x, /* FC_CHAR */\n", var
->type
->type
);
154 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
155 print_client("0x%02x, /* FC_WCHAR */\n", var
->type
->type
);
158 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
159 print_client("0x%02x, /* FC_USHORT */\n", var
->type
->type
);
162 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
163 print_client("0x%02x, /* FC_SHORT */\n", var
->type
->type
);
166 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
167 print_client("0x%02x, /* FC_ULONG */\n", var
->type
->type
);
170 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
171 print_client("0x%02x, /* FC_LONG */\n", var
->type
->type
);
174 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
175 print_client("0x%02x, /* FC_HYPER */\n", var
->type
->type
);
178 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
179 print_client("0x%02x, /* FC_SMALL */\n", RPC_FC_SMALL
);
182 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
183 print_client("0x%02x, /* FC_FLOAT */\n", RPC_FC_FLOAT
);
186 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
187 print_client("0x%02x, /* FC_DOUBLE */\n", RPC_FC_DOUBLE
);
190 error("Unknown/unsupported type\n");
195 func
= PREV_LINK(func
);
198 print_client("0x0\n");
202 print_client("};\n");
207 static void write_typeformatstring(void)
209 print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
212 print_client("0,\n");
215 print_client("NdrFcShort(0x0),\n");
216 print_client("0x0\n");
220 print_client("};\n");
225 static void print_message_buffer_size(func_t
*func
)
227 unsigned int alignment
;
234 fprintf(client
, " 0U");
239 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
243 switch (var
->type
->type
)
256 if (last_size
!= -1 && last_size
< 2)
257 alignment
+= (2 - last_size
);
264 if (last_size
!= -1 && last_size
< 4)
265 alignment
+= (4 - last_size
);
271 if (last_size
!= -1 && last_size
< 4)
272 alignment
+= (4 - last_size
);
280 error("Unknown/unsupported type!");
284 fprintf(client
, " +");
285 fprintf(client
, " %dU", (size
== 0) ? 0 : size
+ alignment
);
289 var
= PREV_LINK(var
);
294 static void marshall_arguments(func_t
*func
)
296 unsigned int alignment
;
298 unsigned int last_size
= 0;
305 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
309 switch (var
->type
->type
)
322 if (last_size
!= 0 && last_size
< 2)
323 alignment
= (2 - last_size
);
330 if (last_size
!= 0 && last_size
< 4)
331 alignment
= (4 - last_size
);
337 if (last_size
!= 0 && last_size
< 4)
338 alignment
= (4 - last_size
);
346 error("Unknown/unsupported type!");
352 print_client("_StubMsg.Buffer += %u;\n", alignment
);
355 write_type(client
, var
->type
, var
, var
->tname
);
356 fprintf(client
, " __RPC_FAR*)_StubMsg.Buffer)++ = ");
357 write_name(client
, var
);
358 fprintf(client
, ";\n");
359 fprintf(client
, "\n");
364 var
= PREV_LINK(var
);
369 static void write_function_stubs(type_t
*iface
)
371 char *implicit_handle
= get_attrp(iface
->attrs
, ATTR_IMPLICIT_HANDLE
);
372 int explicit_handle
= is_attr(iface
->attrs
, ATTR_EXPLICIT_HANDLE
);
373 func_t
*func
= iface
->funcs
;
375 var_t
* explicit_handle_var
;
376 int method_count
= 0;
377 unsigned int proc_offset
= 0;
379 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
382 var_t
*def
= func
->def
;
384 /* check for a defined binding handle */
385 explicit_handle_var
= get_explicit_handle_var(func
);
388 if (!explicit_handle_var
)
390 error("%s() does not define an explicit binding handle!\n", def
->name
);
396 if (explicit_handle_var
)
398 error("%s() must not define a binding handle!\n", def
->name
);
403 write_type(client
, def
->type
, def
, def
->tname
);
404 fprintf(client
, " ");
405 write_name(client
, def
);
406 fprintf(client
, "(\n");
408 write_args(client
, func
->args
, iface
->name
, 0, TRUE
);
409 fprintf(client
, ")\n");
412 /* write the functions body */
413 fprintf(client
, "{\n");
416 /* declare return value '_RetVal' */
417 if (!is_void(def
->type
, NULL
))
420 write_type(client
, def
->type
, def
, def
->tname
);
421 fprintf(client
, " _RetVal;\n");
424 if (implicit_handle
|| explicit_handle
)
425 print_client("RPC_BINDING_HANDLE _Handle = 0;\n");
426 print_client("RPC_MESSAGE _RpcMessage;\n");
427 print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
428 fprintf(client
, "\n");
429 print_client("RpcTryFinally\n");
433 print_client("NdrClientInitializeNew(\n");
435 print_client("(PRPC_MESSAGE)&_RpcMessage,\n");
436 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
437 print_client("(PMIDL_STUB_DESC)&%s_StubDesc,\n", iface
->name
);
438 print_client("%d);\n", method_count
);
440 fprintf(client
, "\n");
444 print_client("_Handle = %s;\n", implicit_handle
);
445 fprintf(client
, "\n");
447 else if (explicit_handle
)
449 print_client("_Handle = %s;\n", explicit_handle_var
->name
);
450 fprintf(client
, "\n");
453 /* emit the message buffer size */
454 print_client("_StubMsg.BufferLength =");
455 print_message_buffer_size(func
);
456 fprintf(client
, ";\n");
459 print_client("NdrGetBuffer(\n");
461 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
462 print_client("_StubMsg.BufferLength,\n");
463 if (implicit_handle
|| explicit_handle
)
464 print_client("%_Handle);\n");
466 print_client("%s__MIDL_AutoBindHandle);\n", iface
->name
);
468 fprintf(client
, "\n");
470 /* marshal arguments */
471 marshall_arguments(func
);
473 /* send/recieve message */
474 print_client("NdrSendReceive(\n");
476 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
477 print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n");
480 /* unmarshal return value */
481 if (!is_void(def
->type
, NULL
))
483 fprintf(client
, "\n");
485 print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
487 print_client("NdrConvert(\n");
489 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
490 print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset
);
492 fprintf(client
, "\n");
494 print_client("_RetVal = *((");
495 write_type(client
, def
->type
, def
, def
->tname
);
496 fprintf(client
, " __RPC_FAR *)_StubMsg.Buffer)++;\n");
499 /* update proc_offset */
503 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
506 proc_offset
+= 2; /* FIXME */
507 var
= PREV_LINK(var
);
510 proc_offset
+= 2; /* FIXME */
514 print_client("RpcFinally\n");
519 /* FIXME: emit client finally code */
521 print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n");
525 print_client("RpcEndFinally\n");
528 /* emit return code */
529 if (!is_void(def
->type
, NULL
))
531 fprintf(client
, "\n");
532 print_client("return _RetVal;\n");
536 fprintf(client
, "}\n");
537 fprintf(client
, "\n");
540 func
= PREV_LINK(func
);
545 static void write_bindinghandledecl(type_t
*iface
)
547 print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n", iface
->name
);
548 fprintf(client
, "\n");
552 static void write_stubdescdecl(type_t
*iface
)
554 print_client("extern const MIDL_STUB_DESC %s_StubDesc;\n", iface
->name
);
555 fprintf(client
, "\n");
559 static void write_stubdescriptor(type_t
*iface
)
561 char *implicit_handle
= get_attrp(iface
->attrs
, ATTR_IMPLICIT_HANDLE
);
563 print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface
->name
);
566 print_client("(void __RPC_FAR *)& %s___RpcClientInterface,\n", iface
->name
);
567 print_client("MIDL_user_allocate,\n");
568 print_client("MIDL_user_free,\n");
570 print_client("&%s,\n", implicit_handle
);
572 print_client("&%s__MIDL_AutoBindHandle,\n", iface
->name
);
573 print_client("0,\n");
574 print_client("0,\n");
575 print_client("0,\n");
576 print_client("0,\n");
577 print_client("__MIDL_TypeFormatString.Format,\n");
578 print_client("1, /* -error bounds_check flag */\n");
579 print_client("0x10001, /* Ndr library version */\n");
580 print_client("0,\n");
581 print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
582 print_client("0,\n");
583 print_client("0,\n");
584 print_client("0, /* notify & notify_flag routine table */\n");
585 print_client("1, /* Flags */\n");
586 print_client("0, /* Reserved3 */\n");
587 print_client("0, /* Reserved4 */\n");
588 print_client("0 /* Reserved5 */\n");
590 print_client("};\n");
591 fprintf(client
, "\n");
595 static void write_clientinterfacedecl(type_t
*iface
)
597 unsigned long ver
= get_attrv(iface
->attrs
, ATTR_VERSION
);
598 UUID
*uuid
= get_attrp(iface
->attrs
, ATTR_UUID
);
600 print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface
->name
);
603 print_client("sizeof(RPC_CLIENT_INTERFACE),\n");
604 print_client("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n",
605 uuid
->Data1
, uuid
->Data2
, uuid
->Data3
, uuid
->Data4
[0], uuid
->Data4
[1],
606 uuid
->Data4
[2], uuid
->Data4
[3], uuid
->Data4
[4], uuid
->Data4
[5], uuid
->Data4
[6],
607 uuid
->Data4
[7], LOWORD(ver
), HIWORD(ver
));
608 print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */
609 print_client("0,\n");
610 print_client("0,\n");
611 print_client("0,\n");
612 print_client("0,\n");
613 print_client("0,\n");
614 print_client("0,\n");
616 print_client("};\n");
617 print_client("RPC_IF_HANDLE %s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
618 iface
->name
, LOWORD(ver
), HIWORD(ver
), iface
->name
);
619 fprintf(client
, "\n");
623 static void write_formatdesc( const char *str
)
625 print_client("typedef struct _MIDL_%s_FORMAT_STRING\n", str
);
628 print_client("short Pad;\n");
629 print_client("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str
);
631 print_client("} MIDL_%s_FORMAT_STRING;\n", str
);
636 static void write_formatstringsdecl(type_t
*iface
)
642 print_client("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */
644 /* determine the proc format string size */
646 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
649 /* argument list size */
653 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
656 byte_count
+= 2; /* FIXME: determine real size */
657 var
= PREV_LINK(var
);
661 /* return value size */
662 byte_count
+= 2; /* FIXME: determine real size */
663 func
= PREV_LINK(func
);
666 print_client("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count
);
668 fprintf(client
, "\n");
669 write_formatdesc("TYPE");
670 write_formatdesc("PROC");
671 fprintf(client
, "\n");
672 print_client("extern const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n");
673 print_client("extern const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n");
678 static void write_implicithandledecl(type_t
*iface
)
680 char *implicit_handle
= get_attrp(iface
->attrs
, ATTR_IMPLICIT_HANDLE
);
684 fprintf(client
, "handle_t %s;\n", implicit_handle
);
685 fprintf(client
, "\n");
690 static void init_client(void)
693 if (!(client
= fopen(client_name
, "w")))
694 error("Could not open %s for output\n", client_name
);
696 print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION
, input_name
);
697 print_client("#include<string.h>\n");
698 print_client("#ifdef _ALPHA_\n");
699 print_client("#include<stdarg.h>\n");
700 print_client("#endif\n");
701 fprintf(client
, "\n");
702 print_client("#include\"%s\"\n", header_name
);
703 fprintf(client
, "\n");
707 void write_client(ifref_t
*ifaces
)
709 ifref_t
*iface
= ifaces
;
723 fprintf(client
, "/*****************************************************************************\n");
724 fprintf(client
, " * %s interface\n", iface
->iface
->name
);
725 fprintf(client
, " */\n");
726 fprintf(client
, "\n");
728 write_formatstringsdecl(iface
->iface
);
729 write_implicithandledecl(iface
->iface
);
731 write_clientinterfacedecl(iface
->iface
);
732 write_stubdescdecl(iface
->iface
);
733 write_bindinghandledecl(iface
->iface
);
735 write_function_stubs(iface
->iface
);
736 write_stubdescriptor(iface
->iface
);
738 print_client("#if !defined(__RPC_WIN32__)\n");
739 print_client("#error Invalid build platform for this stub.\n");
740 print_client("#endif\n");
741 fprintf(client
, "\n");
743 write_procformatstring(iface
->iface
);
744 write_typeformatstring();
746 fprintf(client
, "\n");
748 iface
= PREV_LINK(iface
);