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"
45 static const func_t
*current_func
;
46 static const var_t
*current_fields
;
48 static size_t type_memsize(const type_t
*t
, int ptr_level
, const expr_t
*array
);
50 static int print_file(FILE *file
, int indent
, const char *format
, ...)
58 for (i
= 0; i
< indent
; i
++)
60 r
= vfprintf(file
, format
, va
);
65 static inline int type_has_ref(const type_t
*type
)
67 return (type
->type
== 0 && type
->ref
);
70 static inline int is_base_type(unsigned char type
)
89 case RPC_FC_ERROR_STATUS_T
:
97 static size_t write_procformatstring_var(FILE *file
, int indent
,
98 const var_t
*var
, int is_return
, unsigned int *type_offset
)
101 int ptr_level
= var
->ptr_level
;
102 const type_t
*type
= var
->type
;
104 int is_in
= is_attr(var
->attrs
, ATTR_IN
);
105 int is_out
= is_attr(var
->attrs
, ATTR_OUT
);
107 if (!is_in
&& !is_out
) is_in
= TRUE
;
109 if (ptr_level
== 0 && type_has_ref(type
))
112 if (ptr_level
== 0 && !var
->array
&& is_base_type(type
->type
))
115 print_file(file
, indent
, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
117 print_file(file
, indent
, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
121 #define CASE_BASETYPE(fctype) \
123 print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
124 size = 2; /* includes param type prefix */ \
127 CASE_BASETYPE(FC_BYTE
);
128 CASE_BASETYPE(FC_CHAR
);
129 CASE_BASETYPE(FC_WCHAR
);
130 CASE_BASETYPE(FC_USHORT
);
131 CASE_BASETYPE(FC_SHORT
);
132 CASE_BASETYPE(FC_ULONG
);
133 CASE_BASETYPE(FC_LONG
);
134 CASE_BASETYPE(FC_HYPER
);
135 CASE_BASETYPE(FC_IGNORE
);
136 CASE_BASETYPE(FC_USMALL
);
137 CASE_BASETYPE(FC_SMALL
);
138 CASE_BASETYPE(FC_FLOAT
);
139 CASE_BASETYPE(FC_DOUBLE
);
140 CASE_BASETYPE(FC_ERROR_STATUS_T
);
143 error("Unknown/unsupported type: %s (0x%02x)\n", var
->name
, type
->type
);
150 print_file(file
, indent
, "0x52, /* FC_RETURN_PARAM */\n");
151 else if (is_in
&& is_out
)
152 print_file(file
, indent
, "0x50, /* FC_IN_OUT_PARAM */\n");
154 print_file(file
, indent
, "0x51, /* FC_OUT_PARAM */\n");
156 print_file(file
, indent
, "0x4d, /* FC_IN_PARAM */\n");
158 print_file(file
, indent
, "0x01,\n");
159 print_file(file
, indent
, "NdrFcShort(0x%x),\n", *type_offset
);
160 size
= 4; /* includes param type prefix */
162 *type_offset
+= get_size_typeformatstring_var(var
);
166 void write_procformatstring(FILE *file
, type_t
*iface
)
170 unsigned int type_offset
= 2;
172 print_file(file
, indent
, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
173 print_file(file
, indent
, "{\n");
175 print_file(file
, indent
, "0,\n");
176 print_file(file
, indent
, "{\n");
181 func_t
*func
= iface
->funcs
;
182 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
183 for (; func
; func
= PREV_LINK(func
))
185 /* emit argument data */
189 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
192 write_procformatstring_var(file
, indent
, var
, FALSE
,
195 var
= PREV_LINK(var
);
199 /* emit return value data */
201 if (is_void(var
->type
, NULL
))
203 print_file(file
, indent
, "0x5b, /* FC_END */\n");
204 print_file(file
, indent
, "0x5c, /* FC_PAD */\n");
207 write_procformatstring_var(file
, indent
, var
, TRUE
,
212 print_file(file
, indent
, "0x0\n");
214 print_file(file
, indent
, "}\n");
216 print_file(file
, indent
, "};\n");
217 print_file(file
, indent
, "\n");
220 /* write conformance / variance descriptor */
221 static size_t write_conf_or_var_desc(FILE *file
, const func_t
*func
, const var_t
*fields
, const expr_t
*expr
)
223 unsigned char operator_type
= 0;
224 const char *operator_string
= "no operators";
225 const expr_t
*subexpr
= expr
;
227 if (!file
) return 4; /* optimisation for sizing pass */
229 switch (subexpr
->type
)
232 subexpr
= subexpr
->ref
;
233 operator_type
= RPC_FC_DEREFERENCE
;
234 operator_string
= "FC_DEREFERENCE";
237 if (subexpr
->u
.ext
->is_const
&& (subexpr
->u
.ext
->cval
== 2))
239 subexpr
= subexpr
->ref
;
240 operator_type
= RPC_FC_DIV_2
;
241 operator_string
= "FC_DIV_2";
245 if (subexpr
->u
.ext
->is_const
&& (subexpr
->u
.ext
->cval
== 2))
247 subexpr
= subexpr
->ref
;
248 operator_type
= RPC_FC_MULT_2
;
249 operator_string
= "FC_MULT_2";
253 if (subexpr
->u
.ext
->is_const
&& (subexpr
->u
.ext
->cval
== 1))
255 subexpr
= subexpr
->ref
;
256 operator_type
= RPC_FC_SUB_1
;
257 operator_string
= "FC_SUB_1";
261 if (subexpr
->u
.ext
->is_const
&& (subexpr
->u
.ext
->cval
== 1))
263 subexpr
= subexpr
->ref
;
264 operator_type
= RPC_FC_ADD_1
;
265 operator_string
= "FC_ADD_1";
272 if (subexpr
->type
== EXPR_IDENTIFIER
)
274 unsigned char correlation_type
;
275 const type_t
*correlation_variable
= NULL
;
276 unsigned char param_type
= 0;
277 const char *param_type_string
= NULL
;
284 for (offset
= 0, var
= fields
; var
; var
= NEXT_LINK(var
))
286 offset
-= type_memsize(var
->type
, var
->ptr_level
, var
->array
);
287 if (!strcmp(var
->name
, subexpr
->u
.sval
))
289 correlation_variable
= var
->type
;
293 if (!correlation_variable
)
294 error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
297 correlation_type
= RPC_FC_NORMAL_CONFORMANCE
;
301 const var_t
*var
= func
->args
;
303 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
304 /* FIXME: not all stack variables are sizeof(void *) */
305 for (offset
= 0; var
; offset
+= sizeof(void *), var
= PREV_LINK(var
))
307 if (!strcmp(var
->name
, subexpr
->u
.sval
))
309 correlation_variable
= var
->type
;
313 if (!correlation_variable
)
314 error("write_conf_or_var_desc: couldn't find variable %s in function\n",
317 correlation_type
= RPC_FC_TOP_LEVEL_CONFORMANCE
;
320 while (type_has_ref(correlation_variable
))
321 correlation_variable
= correlation_variable
->ref
;
323 switch (correlation_variable
->type
)
327 param_type
= RPC_FC_SMALL
;
328 param_type_string
= "FC_SMALL";
332 param_type
= RPC_FC_USMALL
;
333 param_type_string
= "FC_USMALL";
337 param_type
= RPC_FC_SHORT
;
338 param_type_string
= "FC_SHORT";
341 param_type
= RPC_FC_USHORT
;
342 param_type_string
= "FC_USHORT";
345 param_type
= RPC_FC_LONG
;
346 param_type_string
= "FC_LONG";
349 param_type
= RPC_FC_ULONG
;
350 param_type_string
= "FC_ULONG";
353 error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n",
354 correlation_variable
->type
);
357 print_file(file
, 2, "0x%x, /* Corr desc: %s%s */\n",
358 correlation_type
| param_type
,
359 correlation_type
== RPC_FC_TOP_LEVEL_CONFORMANCE
? "parameter, " : "",
361 print_file(file
, 2, "0x%x, /* %s */\n", operator_type
, operator_string
);
362 print_file(file
, 2, "0x%x, /* %soffset = %d */\n",
364 correlation_type
== RPC_FC_TOP_LEVEL_CONFORMANCE
? "x86 stack size / " : "",
368 error("write_conf_or_var_desc: expression type %d\n", subexpr
->type
);
372 static size_t fields_memsize(const var_t
*v
)
375 const var_t
*first
= v
;
377 while (NEXT_LINK(v
)) v
= NEXT_LINK(v
);
379 size
+= type_memsize(v
->type
, v
->ptr_level
, v
->array
);
380 if (v
== first
) break;
386 static size_t type_memsize(const type_t
*t
, int ptr_level
, const expr_t
*array
)
391 return sizeof(void *);
409 case RPC_FC_ERROR_STATUS_T
:
419 case RPC_FC_CVSTRUCT
:
420 case RPC_FC_CPSTRUCT
:
423 case RPC_FC_BOGUS_STRUCT
:
424 case RPC_FC_ENCAPSULATED_UNION
:
425 case RPC_FC_NON_ENCAPSULATED_UNION
:
426 size
= fields_memsize(t
->fields
);
429 error("type_memsize: Unknown type %d", t
->type
);
444 static size_t write_string_tfs(FILE *file
, const attr_t
*attrs
,
445 const type_t
*type
, const expr_t
*array
,
448 const expr_t
*size_is
= get_attrp(attrs
, ATTR_SIZEIS
);
449 int has_size
= size_is
&& (size_is
->type
!= EXPR_VOID
);
451 if ((type
->type
!= RPC_FC_CHAR
) && (type
->type
!= RPC_FC_WCHAR
))
453 error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", type
->type
, name
);
457 if (array
&& array
->is_const
)
459 size_t typestring_size
;
461 if (array
->cval
> USHRT_MAX
)
462 error("array size for parameter %s exceeds %d bytes by %ld bytes\n",
463 name
, USHRT_MAX
, array
->cval
- USHRT_MAX
);
465 if (type
->type
== RPC_FC_CHAR
)
466 print_file(file
, 2, "0x%x, /* FC_CSTRING */\n", RPC_FC_C_CSTRING
);
468 print_file(file
, 2, "0x%x, /* FC_WSTRING */\n", RPC_FC_C_WSTRING
);
469 print_file(file
, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD
);
472 print_file(file
, 2, "NdrFcShort(0x%x), /* %d */\n", array
->cval
, array
->cval
);
473 typestring_size
+= 2;
475 return typestring_size
;
479 size_t typestring_size
;
481 if (type
->type
== RPC_FC_CHAR
)
482 print_file(file
, 2, "0x%x, /* FC_C_CSTRING */\n", RPC_FC_C_CSTRING
);
484 print_file(file
, 2, "0x%x, /* FC_C_WSTRING */\n", RPC_FC_C_WSTRING
);
485 print_file(file
, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED
);
488 typestring_size
+= write_conf_or_var_desc(file
, current_func
, NULL
, size_is
);
490 return typestring_size
;
494 size_t typestring_size
;
496 if (type
->type
== RPC_FC_CHAR
)
497 print_file(file
, 2, "0x%x, /* FC_C_CSTRING */\n", RPC_FC_C_CSTRING
);
499 print_file(file
, 2, "0x%x, /* FC_C_WSTRING */\n", RPC_FC_C_WSTRING
);
500 print_file(file
, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD
);
503 return typestring_size
;
507 static size_t write_array_tfs(FILE *file
, const attr_t
*attrs
,
508 const type_t
*type
, const expr_t
*array
,
511 const expr_t
*length_is
= get_attrp(attrs
, ATTR_LENGTHIS
);
512 const expr_t
*size_is
= get_attrp(attrs
, ATTR_SIZEIS
);
513 int has_length
= length_is
&& (length_is
->type
!= EXPR_VOID
);
514 int has_size
= size_is
&& (size_is
->type
!= EXPR_VOID
) && !array
->is_const
;
516 /* FIXME: need to analyse type for pointers */
518 if (NEXT_LINK(array
)) /* multi-dimensional array */
520 error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name
);
525 if (!has_length
&& !has_size
)
528 size_t typestring_size
;
529 size_t size
= type_memsize(type
, 0, array
);
530 if (size
< USHRT_MAX
)
532 print_file(file
, 2, "0x%x, /* FC_SMFARRAY */\n", RPC_FC_SMFARRAY
);
534 print_file(file
, 2, "0x%x, /* 0 */\n", 0);
536 print_file(file
, 2, "NdrFcShort(0x%x), /* %d */\n", size
, size
);
541 print_file(file
, 2, "0x%x, /* FC_LGFARRAY */\n", RPC_FC_LGFARRAY
);
543 print_file(file
, 2, "0x%x, /* 0 */\n", 0);
545 print_file(file
, 2, "NdrFcLong(0x%x), /* %d */\n", size
, size
);
549 /* FIXME: write out pointer descriptor if necessary */
551 print_file(file
, 2, "0x0, /* FIXME: write out conversion data */\n");
552 print_file(file
, 2, "FC_END,\n");
553 typestring_size
+= 2;
555 return typestring_size
;
557 else if (has_length
&& !has_size
)
560 size_t typestring_size
;
561 size_t element_size
= type_memsize(type
, 0, NULL
);
562 size_t elements
= array
->cval
;
563 size_t total_size
= element_size
* elements
;
565 if (total_size
< USHRT_MAX
)
567 print_file(file
, 2, "0x%x, /* FC_SMVARRAY */\n", RPC_FC_SMVARRAY
);
569 print_file(file
, 2, "0x%x, /* 0 */\n", 0);
571 print_file(file
, 2, "NdrFcShort(0x%x), /* %d */\n", total_size
, total_size
);
572 /* number of elements */
573 print_file(file
, 2, "NdrFcShort(0x%x), /* %d */\n", elements
, elements
);
578 print_file(file
, 2, "0x%x, /* FC_LGVARRAY */\n", RPC_FC_LGVARRAY
);
580 print_file(file
, 2, "0x%x, /* 0 */\n", 0);
582 print_file(file
, 2, "NdrFcLong(0x%x), /* %d */\n", total_size
, total_size
);
583 /* number of elements */
584 print_file(file
, 2, "NdrFcLong(0x%x), /* %d */\n", elements
, elements
);
585 typestring_size
= 10;
588 print_file(file
, 2, "NdrFcShort(0x%x), /* %d */\n", element_size
, element_size
);
589 typestring_size
+= 2;
591 typestring_size
+= write_conf_or_var_desc(file
, current_func
,
595 /* FIXME: write out pointer descriptor if necessary */
597 print_file(file
, 2, "0x0, /* FIXME: write out conversion data */\n");
598 print_file(file
, 2, "FC_END,\n");
599 typestring_size
+= 2;
601 return typestring_size
;
603 else if (!has_length
&& has_size
)
605 /* conformant array */
606 size_t typestring_size
;
607 size_t element_size
= type_memsize(type
, 0, NULL
);
609 print_file(file
, 2, "0x%x, /* FC_CARRAY */\n", RPC_FC_CARRAY
);
611 print_file(file
, 2, "0x%x, /* 0 */\n", 0);
613 print_file(file
, 2, "NdrFcShort(0x%x), /* %d */\n", element_size
, element_size
);
616 typestring_size
+= write_conf_or_var_desc(file
, current_func
,
617 current_fields
, size_is
);
619 /* FIXME: write out pointer descriptor if necessary */
621 print_file(file
, 2, "0x0, /* FIXME: write out conversion data */\n");
622 print_file(file
, 2, "FC_END,\n");
623 typestring_size
+= 2;
625 return typestring_size
;
629 /* conformant varying array */
630 size_t typestring_size
;
631 size_t element_size
= type_memsize(type
, 0, NULL
);
633 print_file(file
, 2, "0x%x, /* FC_CARRAY */\n", RPC_FC_CARRAY
);
635 print_file(file
, 2, "0x%x, /* 0 */\n", 0);
637 print_file(file
, 2, "NdrFcShort(0x%x), /* %d */\n", element_size
, element_size
);
640 typestring_size
+= write_conf_or_var_desc(file
, current_func
,
641 current_fields
, size_is
);
642 typestring_size
+= write_conf_or_var_desc(file
, current_func
,
646 /* FIXME: write out pointer descriptor if necessary */
648 print_file(file
, 2, "0x0, /* FIXME: write out conversion data */\n");
649 print_file(file
, 2, "FC_END,\n");
650 typestring_size
+= 2;
652 return typestring_size
;
657 static size_t write_struct_tfs(FILE *file
, const type_t
*type
, const char *name
)
660 size_t typestring_size
;
664 total_size
= type_memsize(type
, 0, NULL
);
666 if (total_size
> USHRT_MAX
)
667 error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
668 name
, USHRT_MAX
, total_size
- USHRT_MAX
);
670 print_file(file
, 2, "0x%x, /* %s */\n", RPC_FC_STRUCT
, "FC_STRUCT");
672 print_file(file
, 2, "0x0,\n");
674 print_file(file
, 2, "NdrShort(0x%x), /* %u */\n", total_size
, total_size
);
678 print_file(file
, 2, "0x0, /* FIXME: write out conversion data */\n");
679 print_file(file
, 2, "FC_END,\n");
681 typestring_size
+= 2;
682 return typestring_size
;
684 error("write_struct_tfs: Unimplemented for type 0x%x\n", type
->type
);
689 static size_t write_union_tfs(FILE *file
, const attr_t
*attrs
, const type_t
*type
, const char *name
)
691 error("write_union_tfs: Unimplemented\n");
695 static size_t write_typeformatstring_var(FILE *file
, int indent
,
698 const type_t
*type
= var
->type
;
699 int ptr_level
= var
->ptr_level
;
704 size_t typeformat_size
= 0;
706 if (is_string_type(var
->attrs
, ptr_level
, var
->array
))
708 typeformat_size
+= write_string_tfs(file
, var
->attrs
, type
, var
->array
, var
->name
);
709 return typeformat_size
;
712 if (is_array_type(var
->attrs
, ptr_level
, var
->array
))
714 typeformat_size
+= write_array_tfs(file
, var
->attrs
, type
, var
->array
, var
->name
);
715 return typeformat_size
;
720 /* follow reference if the type has one */
721 if (type_has_ref(type
))
724 /* FIXME: get new ptr_level from type */
728 /* basic types don't need a type format string */
729 if (is_base_type(type
->type
))
730 return typeformat_size
;
737 case RPC_FC_CPSTRUCT
:
738 case RPC_FC_CVSTRUCT
:
739 case RPC_FC_BOGUS_STRUCT
:
740 typeformat_size
+= write_struct_tfs(file
, type
, var
->name
);
741 return typeformat_size
;
742 case RPC_FC_ENCAPSULATED_UNION
:
743 case RPC_FC_NON_ENCAPSULATED_UNION
:
744 typeformat_size
+= write_union_tfs(file
, var
->attrs
, type
, var
->name
);
745 return typeformat_size
;
747 error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type
->type
, var
->name
);
750 else if (ptr_level
== 1 && !type_has_ref(type
))
752 pointer_type
= get_attrv(var
->attrs
, ATTR_POINTERTYPE
);
753 if (!pointer_type
) pointer_type
= RPC_FC_RP
;
755 /* special case for pointers to base types */
758 #define CASE_BASETYPE(fctype) \
760 print_file(file, indent, "0x%x, 0x08, /* %s [simple_pointer] */\n", \
762 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP")); \
763 print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
764 print_file(file, indent, "0x5c, /* FC_PAD */\n"); \
765 typeformat_size += 4; \
766 return typeformat_size
767 CASE_BASETYPE(FC_BYTE
);
768 CASE_BASETYPE(FC_CHAR
);
769 CASE_BASETYPE(FC_SMALL
);
770 CASE_BASETYPE(FC_USMALL
);
771 CASE_BASETYPE(FC_WCHAR
);
772 CASE_BASETYPE(FC_SHORT
);
773 CASE_BASETYPE(FC_USHORT
);
774 CASE_BASETYPE(FC_LONG
);
775 CASE_BASETYPE(FC_ULONG
);
776 CASE_BASETYPE(FC_FLOAT
);
777 CASE_BASETYPE(FC_HYPER
);
778 CASE_BASETYPE(FC_DOUBLE
);
779 CASE_BASETYPE(FC_ENUM16
);
780 CASE_BASETYPE(FC_ENUM32
);
781 CASE_BASETYPE(FC_IGNORE
);
782 CASE_BASETYPE(FC_ERROR_STATUS_T
);
788 assert(ptr_level
> 0);
790 pointer_type
= get_attrv(var
->attrs
, ATTR_POINTERTYPE
);
791 if (!pointer_type
) pointer_type
= RPC_FC_RP
;
793 print_file(file
, indent
, "0x%x, 0x00, /* %s */\n",
795 pointer_type
== RPC_FC_FP
? "FC_FP" : (pointer_type
== RPC_FC_UP
? "FC_UP" : "FC_RP"));
796 print_file(file
, indent
, "NdrShort(0x2), /* 2 */\n");
803 void write_typeformatstring(FILE *file
, type_t
*iface
)
808 print_file(file
, indent
, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
809 print_file(file
, indent
, "{\n");
811 print_file(file
, indent
, "0,\n");
812 print_file(file
, indent
, "{\n");
814 print_file(file
, indent
, "NdrFcShort(0x0),\n");
818 func_t
*func
= iface
->funcs
;
819 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
820 for (; func
; func
= PREV_LINK(func
))
826 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
829 write_typeformatstring_var(file
, indent
, var
);
830 var
= PREV_LINK(var
);
836 print_file(file
, indent
, "0x0\n");
838 print_file(file
, indent
, "}\n");
840 print_file(file
, indent
, "};\n");
841 print_file(file
, indent
, "\n");
844 static unsigned int get_required_buffer_size_type(
845 const type_t
*type
, int ptr_level
, const expr_t
*array
,
846 const char *name
, unsigned int *alignment
)
849 if (ptr_level
== 0 && !array
&& !type_has_ref(type
))
868 case RPC_FC_ERROR_STATUS_T
:
881 for (field
= type
->fields
; field
; field
= NEXT_LINK(field
))
883 unsigned int alignment
;
884 size
+= get_required_buffer_size_type(
885 field
->type
, field
->ptr_level
, field
->array
, field
->name
,
892 error("get_required_buffer_size: Unknown/unsupported type: %s (0x%02x)\n", name
, type
->type
);
896 if (ptr_level
== 0 && type_has_ref(type
))
897 return get_required_buffer_size_type(type
->ref
, 0 /* FIXME */, array
, name
, alignment
);
901 unsigned int get_required_buffer_size(const var_t
*var
, unsigned int *alignment
)
903 return get_required_buffer_size_type(var
->type
, var
->ptr_level
, var
->array
, var
->name
, alignment
);
906 void marshall_arguments(FILE *file
, int indent
, func_t
*func
,
907 unsigned int *type_offset
, enum pass pass
)
909 unsigned int last_size
= 0;
916 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
917 for (; var
; *type_offset
+= get_size_typeformatstring_var(var
), var
= PREV_LINK(var
))
919 int in_attr
= is_attr(var
->attrs
, ATTR_IN
);
920 int out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
922 if (!in_attr
&& !out_attr
)
939 if (is_string_type(var
->attrs
, var
->ptr_level
, var
->array
))
941 if (var
->array
&& var
->array
->is_const
)
942 print_file(file
, indent
,
943 "NdrNonConformantStringMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
944 var
->name
, *type_offset
);
946 print_file(file
, indent
,
947 "NdrConformantStringMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
948 var
->name
, *type_offset
);
951 else if (is_array_type(var
->attrs
, var
->ptr_level
, var
->array
))
953 const expr_t
*length_is
= get_attrp(var
->attrs
, ATTR_LENGTHIS
);
954 const expr_t
*size_is
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
955 const char *array_type
;
956 int has_length
= length_is
&& (length_is
->type
!= EXPR_VOID
);
957 int has_size
= size_is
&& (size_is
->type
!= EXPR_VOID
) && !var
->array
->is_const
;
959 if (NEXT_LINK(var
->array
)) /* multi-dimensional array */
960 array_type
= "ComplexArray";
963 if (!has_length
&& !has_size
)
964 array_type
= "FixedArray";
965 else if (has_length
&& !has_size
)
967 print_file(file
, indent
, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
968 print_file(file
, indent
, "_StubMsg.ActualCount = (unsigned long)");
969 write_expr(file
, length_is
, 1);
970 fprintf(file
, ";\n\n");
971 array_type
= "VaryingArray";
973 else if (!has_length
&& has_size
)
975 print_file(file
, indent
, "_StubMsg.MaxCount = (unsigned long)");
976 write_expr(file
, size_is
? size_is
: var
->array
, 1);
977 fprintf(file
, ";\n\n");
978 array_type
= "ConformantArray";
982 print_file(file
, indent
, "_StubMsg.MaxCount = (unsigned long)");
983 write_expr(file
, size_is
? size_is
: var
->array
, 1);
984 fprintf(file
, ";\n");
985 print_file(file
, indent
, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
986 print_file(file
, indent
, "_StubMsg.ActualCount = (unsigned long)");
987 write_expr(file
, length_is
, 1);
988 fprintf(file
, ";\n\n");
989 array_type
= "ConformantVaryingArray";
993 print_file(file
, indent
,
994 "Ndr%sMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
995 array_type
, var
->name
, *type_offset
);
998 else if (var
->ptr_level
== 0 && is_base_type(var
->type
->type
))
1001 unsigned int alignment
= 0;
1002 switch (var
->type
->type
)
1016 if (last_size
!= 0 && last_size
< 2)
1017 alignment
= (2 - last_size
);
1023 case RPC_FC_ERROR_STATUS_T
:
1025 if (last_size
!= 0 && last_size
< 4)
1026 alignment
= (4 - last_size
);
1032 if (last_size
!= 0 && last_size
< 4)
1033 alignment
= (4 - last_size
);
1037 error("marshall_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var
->name
, var
->type
->type
);
1042 print_file(file
, indent
, "_StubMsg.Buffer += %u;\n", alignment
);
1044 print_file(file
, indent
, "*(");
1045 write_type(file
, var
->type
, var
, var
->tname
);
1046 fprintf(file
, " *)_StubMsg.Buffer = ");
1047 write_name(file
, var
);
1048 fprintf(file
, ";\n");
1049 fprintf(file
, "_StubMsg.Buffer += sizeof(");
1050 write_type(file
, var
->type
, var
, var
->tname
);
1051 fprintf(file
, ");\n");
1055 else if (var
->ptr_level
== 0)
1057 const char *ndrtype
;
1059 switch (var
->type
->type
)
1062 ndrtype
= "SimpleStruct";
1064 case RPC_FC_CSTRUCT
:
1065 case RPC_FC_CPSTRUCT
:
1066 ndrtype
= "ConformantStruct";
1068 case RPC_FC_CVSTRUCT
:
1069 ndrtype
= "ConformantVaryingStruct";
1071 case RPC_FC_BOGUS_STRUCT
:
1072 ndrtype
= "ComplexStruct";
1075 error("marshall_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
1076 var
->name
, var
->type
->type
, var
->ptr_level
);
1080 print_file(file
, indent
,
1081 "Ndr%sMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
1082 ndrtype
, var
->name
, *type_offset
);
1087 print_file(file
, indent
,
1088 "NdrPointerMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
1089 var
->name
, *type_offset
);
1092 fprintf(file
, "\n");
1096 void unmarshall_arguments(FILE *file
, int indent
, func_t
*func
,
1097 unsigned int *type_offset
, enum pass pass
)
1099 unsigned int last_size
= 0;
1106 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
1107 for (; var
; *type_offset
+= get_size_typeformatstring_var(var
), var
= PREV_LINK(var
))
1109 int in_attr
= is_attr(var
->attrs
, ATTR_IN
);
1110 int out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
1112 if (!in_attr
&& !out_attr
)
1129 if (is_string_type(var
->attrs
, var
->ptr_level
, var
->array
))
1131 if (var
->array
&& var
->array
->is_const
)
1132 print_file(file
, indent
,
1133 "NdrNonConformantStringUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
1134 var
->name
, *type_offset
);
1136 print_file(file
, indent
,
1137 "NdrConformantStringUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
1138 var
->name
, *type_offset
);
1141 else if (is_array_type(var
->attrs
, var
->ptr_level
, var
->array
))
1143 const expr_t
*length_is
= get_attrp(var
->attrs
, ATTR_LENGTHIS
);
1144 const expr_t
*size_is
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
1145 const char *array_type
;
1146 int has_length
= length_is
&& (length_is
->type
!= EXPR_VOID
);
1147 int has_size
= size_is
&& (size_is
->type
!= EXPR_VOID
) && !var
->array
->is_const
;
1149 if (NEXT_LINK(var
->array
)) /* multi-dimensional array */
1150 array_type
= "ComplexArray";
1153 if (!has_length
&& !has_size
)
1154 array_type
= "FixedArray";
1155 else if (has_length
&& !has_size
)
1156 array_type
= "VaryingArray";
1157 else if (!has_length
&& has_size
)
1158 array_type
= "ConformantArray";
1160 array_type
= "ConformantVaryingArray";
1163 print_file(file
, indent
,
1164 "Ndr%sUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
1165 array_type
, var
->name
, *type_offset
);
1168 else if (var
->ptr_level
== 0 && is_base_type(var
->type
->type
))
1171 unsigned int alignment
= 0;
1173 switch (var
->type
->type
)
1187 if (last_size
!= 0 && last_size
< 2)
1188 alignment
= (2 - last_size
);
1194 case RPC_FC_ERROR_STATUS_T
:
1196 if (last_size
!= 0 && last_size
< 4)
1197 alignment
= (4 - last_size
);
1203 if (last_size
!= 0 && last_size
< 4)
1204 alignment
= (4 - last_size
);
1208 error("unmarshall_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var
->name
, var
->type
->type
);
1213 print_file(file
, indent
, "_StubMsg.Buffer += %u;\n", alignment
);
1215 print_file(file
, indent
, "");
1216 write_name(file
, var
);
1217 fprintf(file
, " = *(");
1218 write_type(file
, var
->type
, var
, var
->tname
);
1219 fprintf(file
, " *)_StubMsg.Buffer;\n");
1220 fprintf(file
, "_StubMsg.Buffer += sizeof(");
1221 write_type(file
, var
->type
, var
, var
->tname
);
1222 fprintf(file
, ");\n");
1226 else if (var
->ptr_level
== 0)
1228 const char *ndrtype
;
1230 switch (var
->type
->type
)
1233 ndrtype
= "SimpleStruct";
1235 case RPC_FC_CSTRUCT
:
1236 case RPC_FC_CPSTRUCT
:
1237 ndrtype
= "ConformantStruct";
1239 case RPC_FC_CVSTRUCT
:
1240 ndrtype
= "ConformantVaryingStruct";
1242 case RPC_FC_BOGUS_STRUCT
:
1243 ndrtype
= "ComplexStruct";
1246 error("unmarshall_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
1247 var
->name
, var
->type
->type
, var
->ptr_level
);
1251 print_file(file
, indent
,
1252 "Ndr%sUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
1253 ndrtype
, var
->name
, *type_offset
);
1258 print_file(file
, indent
,
1259 "NdrPointerUnmarshall(&_StubMsg, (unsigned char **)&%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
1260 var
->name
, *type_offset
);
1263 fprintf(file
, "\n");
1268 size_t get_size_procformatstring_var(const var_t
*var
)
1270 unsigned int type_offset
= 2;
1271 return write_procformatstring_var(NULL
, 0, var
, FALSE
, &type_offset
);
1275 size_t get_size_typeformatstring_var(const var_t
*var
)
1277 return write_typeformatstring_var(NULL
, 0, var
);