2 * Format String Generator for IDL Compiler
4 * Copyright 2005 Eric Kohl
5 * Copyright 2005 Robert Shearman
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
23 #include "wine/port.h"
44 static int print_file(FILE *file
, int indent
, const char *format
, ...)
52 for (i
= 0; i
< indent
; i
++)
54 r
= vfprintf(file
, format
, va
);
59 static size_t write_procformatstring_var(FILE *file
, int indent
, var_t
*var
, int is_return
, unsigned int *type_offset
)
62 if (var
->ptr_level
== 0 && !var
->array
)
65 print_file(file
, indent
, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
67 print_file(file
, indent
, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
69 switch(var
->type
->type
)
71 #define CASE_BASETYPE(fctype) \
73 print_file(file, indent, "0x%02x, /* " #fctype " */\n", var->type->type); \
74 size = 2; /* includes param type prefix */ \
77 CASE_BASETYPE(FC_BYTE
);
78 CASE_BASETYPE(FC_CHAR
);
79 CASE_BASETYPE(FC_WCHAR
);
80 CASE_BASETYPE(FC_USHORT
);
81 CASE_BASETYPE(FC_SHORT
);
82 CASE_BASETYPE(FC_ULONG
);
83 CASE_BASETYPE(FC_LONG
);
84 CASE_BASETYPE(FC_HYPER
);
85 CASE_BASETYPE(FC_IGNORE
);
86 CASE_BASETYPE(FC_USMALL
);
87 CASE_BASETYPE(FC_SMALL
);
88 CASE_BASETYPE(FC_FLOAT
);
89 CASE_BASETYPE(FC_DOUBLE
);
90 CASE_BASETYPE(FC_ERROR_STATUS_T
);
93 error("Unknown/unsupported type: %s (0x%02x)\n", var
->name
, var
->type
->type
);
99 int in_attr
= is_attr(var
->attrs
, ATTR_IN
);
100 int out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
103 print_file(file
, indent
, "0x52, /* FC_RETURN_PARAM */\n");
104 else if (in_attr
&& out_attr
)
105 print_file(file
, indent
, "0x50, /* FC_IN_OUT_PARAM */\n");
107 print_file(file
, indent
, "0x51, /* FC_OUT_PARAM */\n");
109 print_file(file
, indent
, "0x4d, /* FC_IN_PARAM */\n");
111 print_file(file
, indent
, "0x01,\n");
112 print_file(file
, indent
, "NdrFcShort(0x%x),\n", *type_offset
);
113 size
= 4; /* includes param type prefix */
115 *type_offset
+= get_size_typeformatstring_var(var
);
119 void write_procformatstring(FILE *file
, type_t
*iface
)
123 unsigned int type_offset
= 2;
125 print_file(file
, indent
, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
126 print_file(file
, indent
, "{\n");
128 print_file(file
, indent
, "0,\n");
129 print_file(file
, indent
, "{\n");
134 func_t
*func
= iface
->funcs
;
135 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
136 for (; func
; func
= PREV_LINK(func
))
138 /* emit argument data */
142 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
145 write_procformatstring_var(file
, indent
, var
, FALSE
, &type_offset
);
146 var
= PREV_LINK(var
);
150 /* emit return value data */
152 if (is_void(var
->type
, NULL
))
154 print_file(file
, indent
, "0x5b, /* FC_END */\n");
155 print_file(file
, indent
, "0x5c, /* FC_PAD */\n");
158 write_procformatstring_var(file
, indent
, var
, TRUE
, &type_offset
);
162 print_file(file
, indent
, "0x0\n");
164 print_file(file
, indent
, "}\n");
166 print_file(file
, indent
, "};\n");
167 print_file(file
, indent
, "\n");
171 static size_t write_typeformatstring_var(FILE *file
, int indent
, var_t
*var
)
173 int ptr_level
= var
->ptr_level
;
175 /* basic types don't need a type format string */
176 if (ptr_level
== 0 && !var
->array
)
179 if (ptr_level
== 1 ||
180 (var
->ptr_level
== 0 && var
->array
&& !NEXT_LINK(var
->array
)))
182 switch (var
->type
->type
)
184 #define CASE_BASETYPE(fctype) \
186 print_file(file, indent, "0x11, 0x08, /* FC_RP [simple_pointer] */\n"); \
187 print_file(file, indent, "0x%02x, /* " #fctype " */\n", var->type->type); \
188 print_file(file, indent, "0x5c, /* FC_PAD */\n"); \
190 CASE_BASETYPE(FC_BYTE
);
191 CASE_BASETYPE(FC_CHAR
);
192 CASE_BASETYPE(FC_SMALL
);
193 CASE_BASETYPE(FC_USMALL
);
194 CASE_BASETYPE(FC_WCHAR
);
195 CASE_BASETYPE(FC_SHORT
);
196 CASE_BASETYPE(FC_USHORT
);
197 CASE_BASETYPE(FC_LONG
);
198 CASE_BASETYPE(FC_ULONG
);
199 CASE_BASETYPE(FC_FLOAT
);
200 CASE_BASETYPE(FC_HYPER
);
201 CASE_BASETYPE(FC_DOUBLE
);
202 CASE_BASETYPE(FC_ENUM16
);
203 CASE_BASETYPE(FC_ENUM32
);
204 CASE_BASETYPE(FC_IGNORE
);
205 CASE_BASETYPE(FC_ERROR_STATUS_T
);
207 error("write_typeformatstring_var: Unknown/unsupported type: %s (0x%02x)\n", var
->name
, var
->type
->type
);
210 error("write_typeformatstring_var: Pointer level %d not supported for variable %s\n", ptr_level
, var
->name
);
215 void write_typeformatstring(FILE *file
, type_t
*iface
)
220 print_file(file
, indent
, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
221 print_file(file
, indent
, "{\n");
223 print_file(file
, indent
, "0,\n");
224 print_file(file
, indent
, "{\n");
226 print_file(file
, indent
, "NdrFcShort(0x0),\n");
230 func_t
*func
= iface
->funcs
;
231 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
232 for (; func
; func
= PREV_LINK(func
))
237 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
240 write_typeformatstring_var(file
, indent
, var
);
241 var
= PREV_LINK(var
);
247 print_file(file
, indent
, "0x0\n");
249 print_file(file
, indent
, "}\n");
251 print_file(file
, indent
, "};\n");
252 print_file(file
, indent
, "\n");
256 unsigned int get_required_buffer_size(const var_t
*var
, unsigned int *alignment
)
259 if (var
->ptr_level
== 0 && !var
->array
)
261 switch (var
->type
->type
)
278 case RPC_FC_ERROR_STATUS_T
:
288 error("get_required_buffer_size: Unknown/unsupported type: %s (0x%02x)\n", var
->name
, var
->type
->type
);
295 void marshall_arguments(FILE *file
, int indent
, func_t
*func
,
296 unsigned int *type_offset
, enum pass pass
)
298 unsigned int last_size
= 0;
305 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
306 for (; var
; *type_offset
+= get_size_typeformatstring_var(var
), var
= PREV_LINK(var
))
308 int in_attr
= is_attr(var
->attrs
, ATTR_IN
);
309 int out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
311 if (!in_attr
&& !out_attr
)
328 if (var
->ptr_level
== 0 && !var
->array
)
331 unsigned int alignment
= 0;
332 switch (var
->type
->type
)
346 if (last_size
!= 0 && last_size
< 2)
347 alignment
= (2 - last_size
);
353 case RPC_FC_ERROR_STATUS_T
:
355 if (last_size
!= 0 && last_size
< 4)
356 alignment
= (4 - last_size
);
362 if (last_size
!= 0 && last_size
< 4)
363 alignment
= (4 - last_size
);
367 error("marshall_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var
->name
, var
->type
->type
);
372 print_file(file
, indent
, "_StubMsg.Buffer += %u;\n", alignment
);
374 print_file(file
, indent
, "*(");
375 write_type(file
, var
->type
, var
, var
->tname
);
376 fprintf(file
, " *)_StubMsg.Buffer = ");
377 write_name(file
, var
);
378 fprintf(file
, ";\n");
379 fprintf(file
, "_StubMsg.Buffer += sizeof(");
380 write_type(file
, var
->type
, var
, var
->tname
);
381 fprintf(file
, ");\n");
386 else if ((var
->ptr_level
== 1 && !var
->array
) ||
387 (var
->ptr_level
== 0 && var
->array
))
389 if (is_attr(var
->attrs
, ATTR_STRING
))
391 switch (var
->type
->type
)
395 print_file(file
, indent
,
396 "NdrConformantStringMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
397 var
->name
, *type_offset
);
400 error("marshall_arguments: Unsupported [string] type: %s (0x%02x, ptr_level: 1)\n", var
->name
, var
->type
->type
);
405 const expr_t
*length_is
= get_attrp(var
->attrs
, ATTR_LENGTHIS
);
406 const expr_t
*size_is
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
407 const char *array_type
;
408 int has_length
= length_is
&& (length_is
->type
!= EXPR_VOID
);
409 int has_size
= size_is
&& (size_is
->type
!= EXPR_VOID
) && !var
->array
->is_const
;
411 if (NEXT_LINK(var
->array
)) /* multi-dimensional array */
412 array_type
= "ComplexArray";
415 if (!has_length
&& !has_size
)
416 array_type
= "FixedArray";
417 else if (has_length
&& !has_size
)
418 array_type
= "VaryingArray";
419 else if (!has_length
&& has_size
)
420 array_type
= "ConformantArray";
422 array_type
= "ConformantVaryingArray";
425 print_file(file
, indent
,
426 "Ndr%sMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
427 array_type
, var
->name
, *type_offset
);
433 switch (var
->type
->type
)
436 ndrtype
= "SimpleStruct";
439 case RPC_FC_CPSTRUCT
:
440 ndrtype
= "ConformantStruct";
442 case RPC_FC_CVSTRUCT
:
443 ndrtype
= "ConformantVaryingStruct";
445 case RPC_FC_BOGUS_STRUCT
:
446 ndrtype
= "ComplexStruct";
449 error("marshall_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
450 var
->name
, var
->type
->type
, var
->ptr_level
);
454 print_file(file
, indent
,
455 "Ndr%sMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
456 ndrtype
, var
->name
, *type_offset
);
462 error("marshall_arguments: Pointer level %d not supported for variable %s\n", var
->ptr_level
, var
->name
);
469 void unmarshall_arguments(FILE *file
, int indent
, func_t
*func
,
470 unsigned int *type_offset
, enum pass pass
)
472 unsigned int last_size
= 0;
479 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
480 for (; var
; *type_offset
+= get_size_typeformatstring_var(var
), var
= PREV_LINK(var
))
482 int in_attr
= is_attr(var
->attrs
, ATTR_IN
);
483 int out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
485 if (!in_attr
&& !out_attr
)
502 if (var
->ptr_level
== 0 && !var
->array
)
505 unsigned int alignment
= 0;
507 switch (var
->type
->type
)
521 if (last_size
!= 0 && last_size
< 2)
522 alignment
= (2 - last_size
);
528 case RPC_FC_ERROR_STATUS_T
:
530 if (last_size
!= 0 && last_size
< 4)
531 alignment
= (4 - last_size
);
537 if (last_size
!= 0 && last_size
< 4)
538 alignment
= (4 - last_size
);
542 error("unmarshall_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var
->name
, var
->type
->type
);
547 print_file(file
, indent
, "_StubMsg.Buffer += %u;\n", alignment
);
549 print_file(file
, indent
, "");
550 write_name(file
, var
);
551 fprintf(file
, " = *(");
552 write_type(file
, var
->type
, var
, var
->tname
);
553 fprintf(file
, " *)_StubMsg.Buffer;\n");
554 fprintf(file
, "_StubMsg.Buffer += sizeof(");
555 write_type(file
, var
->type
, var
, var
->tname
);
556 fprintf(file
, ");\n");
561 else if ((var
->ptr_level
== 1 && !var
->array
) ||
562 (var
->ptr_level
== 0 && var
->array
))
564 if (is_attr(var
->attrs
, ATTR_STRING
))
566 switch (var
->type
->type
)
570 print_file(file
, indent
,
571 "NdrConformantStringUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
572 var
->name
, *type_offset
);
575 error("unmarshall_arguments: Unsupported [string] type: %s (0x%02x, ptr_level: %d)\n",
576 var
->name
, var
->type
->type
, var
->ptr_level
);
581 const expr_t
*length_is
= get_attrp(var
->attrs
, ATTR_LENGTHIS
);
582 const expr_t
*size_is
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
583 const char *array_type
;
584 int has_length
= length_is
&& (length_is
->type
!= EXPR_VOID
);
585 int has_size
= size_is
&& (size_is
->type
!= EXPR_VOID
) && !var
->array
->is_const
;
587 if (NEXT_LINK(var
->array
)) /* multi-dimensional array */
588 array_type
= "ComplexArray";
591 if (!has_length
&& !has_size
)
592 array_type
= "FixedArray";
593 else if (has_length
&& !has_size
)
594 array_type
= "VaryingArray";
595 else if (!has_length
&& has_size
)
596 array_type
= "ConformantArray";
598 array_type
= "ConformantVaryingArray";
601 print_file(file
, indent
,
602 "Ndr%sUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
603 array_type
, var
->name
, *type_offset
);
609 switch (var
->type
->type
)
612 ndrtype
= "SimpleStruct";
615 case RPC_FC_CPSTRUCT
:
616 ndrtype
= "ConformantStruct";
618 case RPC_FC_CVSTRUCT
:
619 ndrtype
= "ConformantVaryingStruct";
621 case RPC_FC_BOGUS_STRUCT
:
622 ndrtype
= "ComplexStruct";
625 error("unmarshall_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
626 var
->name
, var
->type
->type
, var
->ptr_level
);
630 print_file(file
, indent
,
631 "Ndr%sUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
632 ndrtype
, var
->name
, *type_offset
);
638 error("unmarshall_arguments: Pointer level %d not supported for variable %s\n", var
->ptr_level
, var
->name
);
646 size_t get_size_procformatstring_var(var_t
*var
)
648 unsigned int type_offset
= 2;
649 return write_procformatstring_var(NULL
, 0, var
, FALSE
, &type_offset
);
653 size_t get_size_typeformatstring_var(var_t
*var
)
655 return write_typeformatstring_var(NULL
, 0, var
);