2 * Format String Generator for IDL Compiler
4 * Copyright 2005-2006 Eric Kohl
5 * Copyright 2005-2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/port.h"
41 #include "wine/list.h"
46 static const func_t *current_func;
47 static const type_t *current_structure;
49 /* name of the structure variable for structure callbacks */
50 #define STRUCT_EXPR_EVAL_VAR "pS"
52 static struct list expr_eval_routines = LIST_INIT(expr_eval_routines);
54 struct expr_eval_routine
57 const type_t *structure;
58 size_t structure_size;
62 static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array);
63 static size_t fields_memsize(const var_t *v);
65 static int compare_expr(const expr_t *a, const expr_t *b)
69 if (a->type != b->type)
70 return a->type - b->type;
76 return a->u.lval - b->u.lval;
78 return strcmp(a->u.sval, b->u.sval);
80 ret = compare_expr(a->ref, b->ref);
83 ret = compare_expr(a->u.ext, b->u.ext);
86 return compare_expr(a->ext2, b->ext2);
95 ret = compare_expr(a->ref, b->ref);
98 return compare_expr(a->u.ext, b->u.ext);
104 return compare_expr(a->ref, b->ref);
111 #define WRITE_FCTYPE(file, fctype, typestring_offset) \
114 fprintf(file, "/* %2u */\n", typestring_offset); \
115 print_file((file), 2, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
119 static int print_file(FILE *file, int indent, const char *format, ...)
126 va_start(va, format);
127 for (i = 0; i < indent; i++)
129 r = vfprintf(file, format, va);
134 static inline int type_has_ref(const type_t *type)
136 return (type->type == 0 && type->ref);
139 static inline int is_base_type(unsigned char type)
158 case RPC_FC_ERROR_STATUS_T:
159 case RPC_FC_BIND_PRIMITIVE:
167 static size_t write_procformatstring_var(FILE *file, int indent,
168 const var_t *var, int is_return, unsigned int *type_offset)
171 int ptr_level = var->ptr_level;
172 const type_t *type = var->type;
174 int is_in = is_attr(var->attrs, ATTR_IN);
175 int is_out = is_attr(var->attrs, ATTR_OUT);
177 if (!is_in && !is_out) is_in = TRUE;
179 if (ptr_level == 0 && type_has_ref(type))
182 if (ptr_level == 0 && !var->array && is_base_type(type->type))
185 print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
187 print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
191 #define CASE_BASETYPE(fctype) \
193 print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
194 size = 2; /* includes param type prefix */ \
197 CASE_BASETYPE(FC_BYTE);
198 CASE_BASETYPE(FC_CHAR);
199 CASE_BASETYPE(FC_WCHAR);
200 CASE_BASETYPE(FC_USHORT);
201 CASE_BASETYPE(FC_SHORT);
202 CASE_BASETYPE(FC_ULONG);
203 CASE_BASETYPE(FC_LONG);
204 CASE_BASETYPE(FC_HYPER);
205 CASE_BASETYPE(FC_IGNORE);
206 CASE_BASETYPE(FC_USMALL);
207 CASE_BASETYPE(FC_SMALL);
208 CASE_BASETYPE(FC_FLOAT);
209 CASE_BASETYPE(FC_DOUBLE);
210 CASE_BASETYPE(FC_ERROR_STATUS_T);
213 case RPC_FC_BIND_PRIMITIVE:
214 print_file(file, indent, "0x%02x, /* FC_IGNORE */\n", RPC_FC_IGNORE);
215 size = 2; /* includes param type prefix */
219 error("Unknown/unsupported type: %s (0x%02x)\n", var->name, type->type);
226 print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n");
227 else if (is_in && is_out)
228 print_file(file, indent, "0x50, /* FC_IN_OUT_PARAM */\n");
230 print_file(file, indent, "0x51, /* FC_OUT_PARAM */\n");
232 print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n");
234 print_file(file, indent, "0x01,\n");
235 print_file(file, indent, "NdrFcShort(0x%x),\n", *type_offset);
236 size = 4; /* includes param type prefix */
238 *type_offset += get_size_typeformatstring_var(var);
242 void write_procformatstring(FILE *file, const ifref_t *ifaces)
244 const ifref_t *iface = ifaces;
247 unsigned int type_offset = 2;
249 print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
250 print_file(file, indent, "{\n");
252 print_file(file, indent, "0,\n");
253 print_file(file, indent, "{\n");
258 for (; iface; iface = PREV_LINK(iface))
260 if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
263 if (iface->iface->funcs)
265 func_t *func = iface->iface->funcs;
266 while (NEXT_LINK(func)) func = NEXT_LINK(func);
267 for (; func; func = PREV_LINK(func))
269 /* emit argument data */
273 while (NEXT_LINK(var)) var = NEXT_LINK(var);
276 write_procformatstring_var(file, indent, var, FALSE,
279 var = PREV_LINK(var);
283 /* emit return value data */
285 if (is_void(var->type, NULL))
287 print_file(file, indent, "0x5b, /* FC_END */\n");
288 print_file(file, indent, "0x5c, /* FC_PAD */\n");
291 write_procformatstring_var(file, indent, var, TRUE,
297 print_file(file, indent, "0x0\n");
299 print_file(file, indent, "}\n");
301 print_file(file, indent, "};\n");
302 print_file(file, indent, "\n");
305 /* write conformance / variance descriptor */
306 static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_t *structure, const expr_t *expr)
308 unsigned char operator_type = 0;
309 const char *operator_string = "no operators";
310 const expr_t *subexpr = expr;
311 unsigned char correlation_type;
313 if (!file) return 4; /* optimisation for sizing pass */
317 if (expr->cval > UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX)
318 error("write_conf_or_var_desc: constant value %ld is greater than "
319 "the maximum constant size of %d\n", expr->cval,
320 UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX);
322 print_file(file, 2, "0x%x, /* Corr desc: constant, val = %ld */\n",
323 RPC_FC_CONSTANT_CONFORMANCE, expr->cval);
324 print_file(file, 2, "0x%x,\n", expr->cval & ~USHRT_MAX);
325 print_file(file, 2, "NdrFcShort(0x%x),\n", expr->cval & USHRT_MAX);
330 switch (subexpr->type)
333 subexpr = subexpr->ref;
334 operator_type = RPC_FC_DEREFERENCE;
335 operator_string = "FC_DEREFERENCE";
338 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2))
340 subexpr = subexpr->ref;
341 operator_type = RPC_FC_DIV_2;
342 operator_string = "FC_DIV_2";
346 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2))
348 subexpr = subexpr->ref;
349 operator_type = RPC_FC_MULT_2;
350 operator_string = "FC_MULT_2";
354 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1))
356 subexpr = subexpr->ref;
357 operator_type = RPC_FC_SUB_1;
358 operator_string = "FC_SUB_1";
362 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1))
364 subexpr = subexpr->ref;
365 operator_type = RPC_FC_ADD_1;
366 operator_string = "FC_ADD_1";
373 if (subexpr->type == EXPR_IDENTIFIER)
375 const type_t *correlation_variable = NULL;
376 unsigned char param_type = 0;
377 const char *param_type_string = NULL;
384 for (offset = 0, var = structure->fields; var; var = NEXT_LINK(var))
386 offset -= type_memsize(var->type, var->ptr_level, var->array);
387 if (!strcmp(var->name, subexpr->u.sval))
389 correlation_variable = var->type;
393 if (!correlation_variable)
394 error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
397 correlation_type = RPC_FC_NORMAL_CONFORMANCE;
401 const var_t *var = func->args;
403 while (NEXT_LINK(var)) var = NEXT_LINK(var);
404 /* FIXME: not all stack variables are sizeof(void *) */
405 for (offset = 0; var; offset += sizeof(void *), var = PREV_LINK(var))
407 if (!strcmp(var->name, subexpr->u.sval))
409 correlation_variable = var->type;
413 if (!correlation_variable)
414 error("write_conf_or_var_desc: couldn't find variable %s in function\n",
417 correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE;
420 while (type_has_ref(correlation_variable))
421 correlation_variable = correlation_variable->ref;
423 switch (correlation_variable->type)
427 param_type = RPC_FC_SMALL;
428 param_type_string = "FC_SMALL";
432 param_type = RPC_FC_USMALL;
433 param_type_string = "FC_USMALL";
437 param_type = RPC_FC_SHORT;
438 param_type_string = "FC_SHORT";
441 param_type = RPC_FC_USHORT;
442 param_type_string = "FC_USHORT";
445 param_type = RPC_FC_LONG;
446 param_type_string = "FC_LONG";
449 param_type = RPC_FC_ULONG;
450 param_type_string = "FC_ULONG";
453 error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n",
454 correlation_variable->type);
457 print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n",
458 correlation_type | param_type,
459 correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter, " : "",
461 print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string);
462 print_file(file, 2, "NdrFcShort(0x%x), /* %soffset = %d */\n",
464 correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "x86 stack size / " : "",
469 unsigned int callback_offset = 0;
473 struct expr_eval_routine *eval;
476 LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
478 if (!strcmp(eval->structure->name, structure->name) &&
479 !compare_expr(eval->expr, expr))
489 eval = xmalloc(sizeof(*eval));
490 eval->structure = structure;
491 eval->structure_size = fields_memsize(structure->fields);
493 list_add_tail(&expr_eval_routines, &eval->entry);
496 correlation_type = RPC_FC_NORMAL_CONFORMANCE;
500 error("write_conf_or_var_desc: top-level callback conformance unimplemented\n");
501 correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE;
504 if (callback_offset > USHRT_MAX)
505 error("Maximum number of callback routines reached\n");
507 print_file(file, 2, "0x%x, /* Corr desc: %s */\n",
509 correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter" : "");
510 print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK");
511 print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", callback_offset, callback_offset);
516 static size_t fields_memsize(const var_t *v)
519 const var_t *first = v;
521 while (NEXT_LINK(v)) v = NEXT_LINK(v);
523 size += type_memsize(v->type, v->ptr_level, v->array);
524 if (v == first) break;
530 static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array)
535 return sizeof(void *);
538 return type_memsize(t->ref, 0 /* FIXME */, NULL);
556 case RPC_FC_ERROR_STATUS_T:
566 case RPC_FC_CVSTRUCT:
567 case RPC_FC_CPSTRUCT:
570 case RPC_FC_BOGUS_STRUCT:
571 case RPC_FC_ENCAPSULATED_UNION:
572 case RPC_FC_NON_ENCAPSULATED_UNION:
573 size = fields_memsize(t->fields);
576 error("type_memsize: Unknown type %d\n", t->type);
591 size_t get_type_memsize(const type_t *type)
593 return type_memsize(type, 0, NULL);
596 static int write_pointers(FILE *file, const attr_t *attrs,
597 const type_t *type, int ptr_level,
598 const expr_t *array, int level,
599 unsigned int *typestring_offset)
601 int pointers_written = 0;
604 /* don't generate a pointer for first-level arrays since we want to
605 * descend into them to write their pointers, not stop here */
606 if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array))
608 return write_pointers(file, NULL, type, 0, NULL, level + 1, typestring_offset);
613 /* FIXME: only general algorithm implemented, not the actual writing */
614 error("write_pointers: Writing type format string for pointer is unimplemented\n");
618 /* FIXME: search through all refs for pointers too */
619 while(type_has_ref(type))
624 /* note: don't descend into complex structures or unions since these
625 * will always be generated as a separate type */
627 case RPC_FC_CVSTRUCT:
628 case RPC_FC_CPSTRUCT:
633 while (NEXT_LINK(v)) v = NEXT_LINK(v);
634 for (; v; v = PREV_LINK(v))
635 pointers_written += write_pointers(file, v->attrs, v->type,
636 v->ptr_level, v->array,
647 return pointers_written;
650 static size_t write_pointer_description(FILE *file, const attr_t *attrs,
651 const type_t *type, int ptr_level,
652 const expr_t *array, int level,
653 size_t typestring_offset)
658 /* don't generate a pointer for first-level arrays since we want to
659 * descend into them to write their pointers, not stop here */
660 if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array))
662 return write_pointer_description(file, NULL, type, 0, NULL,
663 level + 1, typestring_offset);
668 /* FIXME: only general algorithm implemented, not the actual writing */
669 error("write_pointer_description: Writing pointer description is unimplemented\n");
673 /* FIXME: search through all refs for pointers too */
677 /* note: don't descend into complex structures or unions since these
678 * will always be generated as a separate type */
680 case RPC_FC_CVSTRUCT:
681 case RPC_FC_CPSTRUCT:
686 while (NEXT_LINK(v)) v = NEXT_LINK(v);
687 for (; v; v = PREV_LINK(v))
688 size += write_pointer_description(file, v->attrs, v->type,
689 v->ptr_level, v->array,
703 static size_t write_string_tfs(FILE *file, const attr_t *attrs,
704 const type_t *type, const expr_t *array,
705 const char *name, unsigned int *typestring_offset)
707 const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS);
708 int has_size = size_is && (size_is->type != EXPR_VOID);
709 size_t start_offset = *typestring_offset;
710 unsigned char flags = 0;
711 int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
713 pointer_type = RPC_FC_RP;
715 if (!get_attrp(attrs, ATTR_SIZEIS))
716 flags |= RPC_FC_P_SIMPLEPOINTER;
718 while (type_has_ref(type))
721 if ((type->type != RPC_FC_BYTE) && (type->type != RPC_FC_CHAR) && (type->type != RPC_FC_WCHAR))
723 error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", type->type, name);
727 print_file(file, 2,"0x%x, 0x%x, /* %s%s */\n",
729 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"),
730 (flags & RPC_FC_P_SIMPLEPOINTER) ? " [simple_pointer]" : "");
731 *typestring_offset += 2;
733 if (!(flags & RPC_FC_P_SIMPLEPOINTER))
735 print_file(file, 2, "NdrFcShort(0x2),\n");
736 *typestring_offset += 2;
739 if (array && array->is_const)
741 if (array->cval > USHRT_MAX)
742 error("array size for parameter %s exceeds %d bytes by %ld bytes\n",
743 name, USHRT_MAX, array->cval - USHRT_MAX);
745 if (type->type == RPC_FC_CHAR)
746 WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset);
748 WRITE_FCTYPE(file, FC_WSTRING, *typestring_offset);
749 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
750 *typestring_offset += 2;
752 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", array->cval, array->cval);
753 *typestring_offset += 2;
759 if (type->type == RPC_FC_CHAR)
760 WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
762 WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset);
763 print_file(file, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED);
764 *typestring_offset += 2;
766 *typestring_offset += write_conf_or_var_desc(file, current_func, NULL, size_is);
772 if (type->type == RPC_FC_CHAR)
773 WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
775 WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset);
776 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
777 *typestring_offset += 2;
783 static size_t write_array_tfs(FILE *file, const attr_t *attrs,
784 const type_t *type, const expr_t *array,
785 const char *name, unsigned int *typestring_offset)
787 const expr_t *length_is = get_attrp(attrs, ATTR_LENGTHIS);
788 const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS);
789 int has_length = length_is && (length_is->type != EXPR_VOID);
790 int has_size = (size_is && (size_is->type != EXPR_VOID)) || !array->is_const;
792 int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
794 pointer_type = RPC_FC_RP;
796 print_file(file, 2, "0x%x, 0x00, /* %s */\n",
798 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"));
799 print_file(file, 2, "NdrFcShort(0x2),\n");
800 *typestring_offset += 4;
802 if (array && NEXT_LINK(array)) /* multi-dimensional array */
804 error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name);
809 size_t pointer_start_offset = *typestring_offset;
812 if (write_pointers(file, attrs, type, 0, array, 0, typestring_offset) > 0)
815 start_offset = *typestring_offset;
817 if (!has_length && !has_size)
820 size_t size = type_memsize(type, 0, array);
821 if (size < USHRT_MAX)
823 WRITE_FCTYPE(file, FC_SMFARRAY, *typestring_offset);
825 print_file(file, 2, "0x%x, /* 0 */\n", 0);
827 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", size, size);
828 *typestring_offset += 4;
832 WRITE_FCTYPE(file, FC_LGFARRAY, *typestring_offset);
834 print_file(file, 2, "0x%x, /* 0 */\n", 0);
836 print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", size, size);
837 *typestring_offset += 6;
842 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
843 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
844 *typestring_offset += 2;
845 *typestring_offset = write_pointer_description(file, attrs,
846 type, 0, array, 0, pointer_start_offset);
847 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
848 *typestring_offset += 1;
851 print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
852 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
853 *typestring_offset += 2;
857 else if (has_length && !has_size)
860 size_t element_size = type_memsize(type, 0, NULL);
861 size_t elements = array->cval;
862 size_t total_size = element_size * elements;
864 if (total_size < USHRT_MAX)
866 WRITE_FCTYPE(file, FC_SMVARRAY, *typestring_offset);
868 print_file(file, 2, "0x%x, /* 0 */\n", 0);
870 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", total_size, total_size);
871 /* number of elements */
872 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", elements, elements);
873 *typestring_offset += 6;
877 WRITE_FCTYPE(file, FC_LGVARRAY, *typestring_offset);
879 print_file(file, 2, "0x%x, /* 0 */\n", 0);
881 print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", total_size, total_size);
882 /* number of elements */
883 print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", elements, elements);
884 *typestring_offset += 10;
887 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
888 *typestring_offset += 2;
890 *typestring_offset += write_conf_or_var_desc(file, current_func,
896 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
897 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
898 *typestring_offset += 2;
899 *typestring_offset += write_pointer_description(file, attrs,
900 type, 0, array, 0, pointer_start_offset);
901 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
902 *typestring_offset += 1;
905 print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
906 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
907 *typestring_offset += 2;
911 else if (!has_length && has_size)
913 /* conformant array */
914 size_t element_size = type_memsize(type, 0, NULL);
916 WRITE_FCTYPE(file, FC_CARRAY, *typestring_offset);
918 print_file(file, 2, "0x%x, /* 0 */\n", 0);
920 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
921 *typestring_offset += 4;
923 *typestring_offset += write_conf_or_var_desc(file, current_func,
925 size_is ? size_is : array);
929 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
930 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
931 *typestring_offset += 2;
932 *typestring_offset += write_pointer_description(file, attrs,
933 type, 0, array, 0, pointer_start_offset);
934 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
935 *typestring_offset += 1;
938 print_file(file, 2, "0x%x, /* FIXME: write out conversion data */\n", type->type);
939 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
940 *typestring_offset += 2;
946 /* conformant varying array */
947 size_t element_size = type_memsize(type, 0, NULL);
949 WRITE_FCTYPE(file, FC_CVARRAY, *typestring_offset);
951 print_file(file, 2, "0x%x, /* 0 */\n", 0);
953 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
954 *typestring_offset += 4;
956 *typestring_offset += write_conf_or_var_desc(file, current_func,
958 size_is ? size_is : array);
959 *typestring_offset += write_conf_or_var_desc(file, current_func,
965 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
966 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
967 *typestring_offset += 2;
968 *typestring_offset += write_pointer_description(file, attrs,
969 type, 0, array, 0, pointer_start_offset);
970 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
971 *typestring_offset += 1;
974 print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
975 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
976 *typestring_offset += 2;
983 static const var_t *find_array_or_string_in_struct(const type_t *type)
985 /* last field is the first in the fields linked list */
986 const var_t *last_field = type->fields;
987 if (is_array_type(last_field->attrs, last_field->ptr_level, last_field->array))
990 assert((last_field->type->type == RPC_FC_CSTRUCT) ||
991 (last_field->type->type == RPC_FC_CPSTRUCT) ||
992 (last_field->type->type == RPC_FC_CVSTRUCT));
994 return find_array_or_string_in_struct(last_field->type);
997 static size_t write_struct_members(FILE *file, const type_t *type)
999 size_t typestring_size = 0;
1002 field = type->fields;
1003 while (NEXT_LINK(field)) field = NEXT_LINK(field);
1004 for (; field; field = PREV_LINK(field))
1006 if (is_base_type(field->type->type))
1008 switch (field->type->type)
1010 #define CASE_BASETYPE(fctype) \
1011 case RPC_##fctype: \
1012 print_file(file, 2, "0x%02x,\t\t/* " #fctype " */\n", RPC_##fctype); \
1013 typestring_size++; \
1015 CASE_BASETYPE(FC_BYTE);
1016 CASE_BASETYPE(FC_CHAR);
1017 CASE_BASETYPE(FC_SMALL);
1018 CASE_BASETYPE(FC_USMALL);
1019 CASE_BASETYPE(FC_WCHAR);
1020 CASE_BASETYPE(FC_SHORT);
1021 CASE_BASETYPE(FC_USHORT);
1022 CASE_BASETYPE(FC_LONG);
1023 CASE_BASETYPE(FC_ULONG);
1024 CASE_BASETYPE(FC_FLOAT);
1025 CASE_BASETYPE(FC_HYPER);
1026 CASE_BASETYPE(FC_DOUBLE);
1027 CASE_BASETYPE(FC_ENUM16);
1028 CASE_BASETYPE(FC_ENUM32);
1029 CASE_BASETYPE(FC_IGNORE);
1030 CASE_BASETYPE(FC_ERROR_STATUS_T);
1033 #undef CASE_BASETYPE
1037 error("Unsupported member type 0x%x\n", field->type->type);
1040 if (typestring_size % 1)
1042 print_file(file, 2, "0x%x,\t\t/* FC_PAD */\n", RPC_FC_PAD);
1046 print_file(file, 2, "0x%x,\t\t/* FC_END */\n", RPC_FC_END);
1049 return typestring_size;
1052 static size_t write_struct_tfs(FILE *file, const type_t *type,
1053 const char *name, unsigned int *typestring_offset)
1055 unsigned int total_size;
1057 size_t start_offset;
1058 size_t array_offset;
1059 size_t pointer_offset;
1064 case RPC_FC_PSTRUCT:
1065 total_size = type_memsize(type, 0, NULL);
1067 if (total_size > USHRT_MAX)
1068 error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
1069 name, USHRT_MAX, total_size - USHRT_MAX);
1071 if (type->type == RPC_FC_PSTRUCT)
1073 pointer_offset = *typestring_offset;
1074 write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset);
1076 else pointer_offset = 0; /* silence warning */
1078 start_offset = *typestring_offset;
1079 if (type->type == RPC_FC_STRUCT)
1080 WRITE_FCTYPE(file, FC_STRUCT, *typestring_offset);
1082 WRITE_FCTYPE(file, FC_PSTRUCT, *typestring_offset);
1084 print_file(file, 2, "0x3,\n"); /* FIXME */
1086 print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size);
1087 *typestring_offset += 4;
1089 if (type->type == RPC_FC_PSTRUCT)
1091 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
1092 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
1093 *typestring_offset += 2;
1094 *typestring_offset += write_pointer_description(file, NULL,
1095 type, 0, NULL, 0, pointer_offset);
1096 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1097 *typestring_offset += 1;
1101 *typestring_offset += write_struct_members(file, type);
1102 return start_offset;
1103 case RPC_FC_CSTRUCT:
1104 case RPC_FC_CPSTRUCT:
1105 total_size = type_memsize(type, 0, NULL);
1107 if (total_size > USHRT_MAX)
1108 error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
1109 name, USHRT_MAX, total_size - USHRT_MAX);
1111 array = find_array_or_string_in_struct(type);
1112 current_structure = type;
1113 array_offset = write_array_tfs(file, array->attrs, array->type,
1114 array->array, array->name,
1116 current_structure = NULL;
1118 if (type->type == RPC_FC_CPSTRUCT)
1120 pointer_offset = *typestring_offset;
1121 write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset);
1123 else pointer_offset = 0; /* silence warning */
1125 start_offset = *typestring_offset;
1126 if (type->type == RPC_FC_CSTRUCT)
1127 WRITE_FCTYPE(file, FC_CSTRUCT, *typestring_offset);
1129 WRITE_FCTYPE(file, FC_CPSTRUCT, *typestring_offset);
1131 print_file(file, 2, "0x0,\n");
1133 print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size);
1134 *typestring_offset += 4;
1135 print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d (%u) */\n",
1136 array_offset - *typestring_offset,
1137 array_offset - *typestring_offset,
1139 *typestring_offset += 2;
1141 if (type->type == RPC_FC_CPSTRUCT)
1143 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
1144 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
1145 *typestring_offset += 2;
1146 *typestring_offset += write_pointer_description(file, NULL,
1147 type, 0, NULL, 0, pointer_offset);
1148 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1149 *typestring_offset += 1;
1152 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1153 *typestring_offset += 1;
1155 return start_offset;
1156 case RPC_FC_CVSTRUCT:
1157 total_size = type_memsize(type, 0, NULL);
1159 if (total_size > USHRT_MAX)
1160 error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
1161 name, USHRT_MAX, total_size - USHRT_MAX);
1163 array = find_array_or_string_in_struct(type);
1164 current_structure = type;
1165 if (is_attr(array->attrs, ATTR_STRING))
1166 array_offset = write_string_tfs(file, array->attrs, array->type,
1167 array->array, array->name,
1170 array_offset = write_array_tfs(file, array->attrs, array->type,
1171 array->array, array->name,
1173 current_structure = NULL;
1175 pointer_offset = *typestring_offset;
1176 if (!write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset))
1179 start_offset = *typestring_offset;
1180 WRITE_FCTYPE(file, FC_CVSTRUCT, *typestring_offset);
1182 print_file(file, 2, "0x0,\n");
1184 print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size);
1185 *typestring_offset += 4;
1186 print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d (%u) */\n",
1187 array_offset - *typestring_offset,
1188 array_offset - *typestring_offset,
1190 *typestring_offset += 2;
1192 if (pointer_offset != 0)
1194 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
1195 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
1196 *typestring_offset += 2;
1197 *typestring_offset += write_pointer_description(file, NULL,
1198 type, 0, NULL, 0, pointer_offset);
1199 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1200 *typestring_offset += 1;
1203 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1204 *typestring_offset += 1;
1206 return start_offset;
1208 error("write_struct_tfs: Unimplemented for type 0x%x\n", type->type);
1209 return *typestring_offset;
1213 static void write_pointer_only_tfs(FILE *file, const attr_t *attrs, size_t offset, unsigned int *typeformat_offset)
1215 int in_attr, out_attr;
1216 unsigned char flags = 0;
1217 int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
1218 if (!pointer_type) pointer_type = RPC_FC_RP;
1219 in_attr = is_attr(attrs, ATTR_IN);
1220 out_attr = is_attr(attrs, ATTR_OUT);
1221 if (!in_attr && !out_attr) in_attr = 1;
1223 if (out_attr && !in_attr && pointer_type == RPC_FC_RP)
1226 print_file(file, 2, "0x%x, 0x%x,\t\t/* %s%s */\n",
1229 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"),
1230 (flags & 0x04) ? " [allocated_on_stack]" : "");
1231 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", offset, offset);
1232 *typeformat_offset += 4;
1235 static size_t write_union_tfs(FILE *file, const attr_t *attrs,
1236 const type_t *type, const char *name,
1237 unsigned int *typeformat_offset)
1239 error("write_union_tfs: Unimplemented\n");
1240 return *typeformat_offset;
1243 static size_t write_typeformatstring_var(FILE *file, int indent,
1244 const var_t *var, unsigned int *typeformat_offset)
1246 const type_t *type = var->type;
1247 int ptr_level = var->ptr_level;
1249 chat("write_typeformatstring_var: %s\n", var->name);
1253 chat("write_typeformatstring: type->type = 0x%x, type->name = %s, ptr_level = %d\n", type->type, type->name, ptr_level);
1255 if (is_string_type(var->attrs, ptr_level, var->array))
1256 return write_string_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
1258 if (is_array_type(var->attrs, ptr_level, var->array))
1259 return write_array_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
1263 /* follow reference if the type has one */
1264 if (type_has_ref(type))
1267 /* FIXME: get new ptr_level from type */
1271 /* basic types don't need a type format string */
1272 if (is_base_type(type->type))
1278 case RPC_FC_PSTRUCT:
1279 case RPC_FC_CSTRUCT:
1280 case RPC_FC_CPSTRUCT:
1281 case RPC_FC_CVSTRUCT:
1282 case RPC_FC_BOGUS_STRUCT:
1283 return write_struct_tfs(file, type, var->name, typeformat_offset);
1284 case RPC_FC_ENCAPSULATED_UNION:
1285 case RPC_FC_NON_ENCAPSULATED_UNION:
1286 return write_union_tfs(file, var->attrs, type, var->name, typeformat_offset);
1288 case RPC_FC_BIND_PRIMITIVE:
1292 error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name);
1295 else if (ptr_level == 1 && !type_has_ref(type))
1297 size_t start_offset = *typeformat_offset;
1298 int in_attr = is_attr(var->attrs, ATTR_IN);
1299 int out_attr = is_attr(var->attrs, ATTR_OUT);
1300 int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
1301 if (!pointer_type) pointer_type = RPC_FC_RP;
1303 /* special case for pointers to base types */
1306 #define CASE_BASETYPE(fctype) \
1307 case RPC_##fctype: \
1308 print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", \
1310 (!in_attr && out_attr) ? 0x0C : 0x08, \
1311 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), \
1312 (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); \
1313 print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
1314 print_file(file, indent, "0x5c, /* FC_PAD */\n"); \
1315 *typeformat_offset += 4; \
1317 CASE_BASETYPE(FC_BYTE);
1318 CASE_BASETYPE(FC_CHAR);
1319 CASE_BASETYPE(FC_SMALL);
1320 CASE_BASETYPE(FC_USMALL);
1321 CASE_BASETYPE(FC_WCHAR);
1322 CASE_BASETYPE(FC_SHORT);
1323 CASE_BASETYPE(FC_USHORT);
1324 CASE_BASETYPE(FC_LONG);
1325 CASE_BASETYPE(FC_ULONG);
1326 CASE_BASETYPE(FC_FLOAT);
1327 CASE_BASETYPE(FC_HYPER);
1328 CASE_BASETYPE(FC_DOUBLE);
1329 CASE_BASETYPE(FC_ENUM16);
1330 CASE_BASETYPE(FC_ENUM32);
1331 CASE_BASETYPE(FC_IGNORE);
1332 CASE_BASETYPE(FC_ERROR_STATUS_T);
1338 assert(ptr_level > 0);
1341 fprintf(file, "/* %2u */\n", *typeformat_offset);
1342 write_pointer_only_tfs(file, var->attrs, 2, typeformat_offset);
1349 void write_typeformatstring(FILE *file, const ifref_t *ifaces)
1353 unsigned int typeformat_offset;
1354 const ifref_t *iface = ifaces;
1356 print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
1357 print_file(file, indent, "{\n");
1359 print_file(file, indent, "0,\n");
1360 print_file(file, indent, "{\n");
1362 print_file(file, indent, "NdrFcShort(0x0),\n");
1363 typeformat_offset = 2;
1367 for (; iface; iface = PREV_LINK(iface))
1369 if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
1372 if (iface->iface->funcs)
1374 func_t *func = iface->iface->funcs;
1375 while (NEXT_LINK(func)) func = NEXT_LINK(func);
1376 for (; func; func = PREV_LINK(func))
1378 current_func = func;
1382 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1385 write_typeformatstring_var(file, indent, var,
1386 &typeformat_offset);
1387 var = PREV_LINK(var);
1394 print_file(file, indent, "0x0\n");
1396 print_file(file, indent, "}\n");
1398 print_file(file, indent, "};\n");
1399 print_file(file, indent, "\n");
1402 static unsigned int get_required_buffer_size_type(
1403 const type_t *type, int ptr_level, const expr_t *array,
1404 const char *name, unsigned int *alignment)
1407 if (ptr_level == 0 && !array && !type_has_ref(type))
1427 case RPC_FC_ERROR_STATUS_T:
1437 case RPC_FC_BIND_PRIMITIVE:
1444 for (field = type->fields; field; field = NEXT_LINK(field))
1446 unsigned int alignment;
1447 size += get_required_buffer_size_type(
1448 field->type, field->ptr_level, field->array, field->name,
1455 error("get_required_buffer_size: Unknown/unsupported type: %s (0x%02x)\n", name, type->type);
1459 if (ptr_level == 0 && type_has_ref(type))
1460 return get_required_buffer_size_type(type->ref, 0 /* FIXME */, array, name, alignment);
1464 unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass)
1466 expr_t *size_is = get_attrp(var->attrs, ATTR_SIZEIS);
1467 int has_size = (size_is && (size_is->type != EXPR_VOID));
1468 int in_attr = is_attr(var->attrs, ATTR_IN);
1469 int out_attr = is_attr(var->attrs, ATTR_OUT);
1471 if (!in_attr && !out_attr)
1476 if (pass == PASS_OUT)
1478 if (out_attr && var->ptr_level > 0)
1480 type_t *type = var->type;
1481 while (type->type == 0 && type->ref)
1484 if (type->type == RPC_FC_STRUCT)
1487 unsigned int size = 36;
1488 for (field = type->fields; field; field = NEXT_LINK(field))
1491 size += get_required_buffer_size_type(
1492 field->type, field->ptr_level, field->array, field->name,
1502 if ((!out_attr || in_attr) && !has_size && !is_attr(var->attrs, ATTR_STRING) && !var->array)
1504 if (var->ptr_level > 0 || (var->ptr_level == 0 && type_has_ref(var->type)))
1506 type_t *type = var->type;
1507 while (type->type == 0 && type->ref)
1510 if (is_base_type(type->type))
1514 else if (type->type == RPC_FC_STRUCT)
1516 unsigned int size = 36;
1518 for (field = type->fields; field; field = NEXT_LINK(field))
1521 size += get_required_buffer_size_type(
1522 field->type, field->ptr_level, field->array, field->name,
1530 return get_required_buffer_size_type(var->type, var->ptr_level, var->array, var->name, alignment);
1534 static void print_phase_function(FILE *file, int indent, const char *type,
1535 enum remoting_phase phase,
1536 const char *varname, unsigned int type_offset)
1538 const char *function;
1541 case PHASE_BUFFERSIZE:
1542 function = "BufferSize";
1545 function = "Marshall";
1547 case PHASE_UNMARSHAL:
1548 function = "Unmarshall";
1558 print_file(file, indent, "Ndr%s%s(\n", type, function);
1560 print_file(file, indent, "&_StubMsg,\n");
1561 print_file(file, indent, "%s%s,\n",
1562 (phase == PHASE_UNMARSHAL) ? "(unsigned char **)&" : "(unsigned char *)",
1564 print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
1565 type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");");
1566 if (phase == PHASE_UNMARSHAL)
1567 print_file(file, indent, "0);\n");
1571 void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase,
1572 enum pass pass, const var_t *var,
1573 const char *varname)
1575 const type_t *type = var->type;
1577 unsigned int alignment = 0;
1579 /* no work to do for other phases, buffer sizing is done elsewhere */
1580 if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL)
1583 while (type_has_ref(type))
1606 case RPC_FC_ERROR_STATUS_T:
1618 case RPC_FC_BIND_PRIMITIVE:
1619 /* no marshalling needed */
1623 error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, type->type);
1627 print_file(file, indent, "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + %u) & ~0x%x);\n",
1628 alignment - 1, alignment - 1);
1630 if (phase == PHASE_MARSHAL)
1632 print_file(file, indent, "*(");
1633 write_type(file, var->type, NULL, var->tname);
1635 fprintf(file, " *)_StubMsg.Buffer = *");
1637 fprintf(file, " *)_StubMsg.Buffer = ");
1638 fprintf(file, varname);
1639 fprintf(file, ";\n");
1641 else if (phase == PHASE_UNMARSHAL)
1643 if (pass == PASS_IN || pass == PASS_RETURN)
1644 print_file(file, indent, "");
1646 print_file(file, indent, "*");
1647 fprintf(file, varname);
1648 if (pass == PASS_IN && var->ptr_level)
1649 fprintf(file, " = (");
1651 fprintf(file, " = *(");
1652 write_type(file, var->type, NULL, var->tname);
1653 fprintf(file, " *)_StubMsg.Buffer;\n");
1656 print_file(file, indent, "_StubMsg.Buffer += sizeof(");
1657 write_type(file, var->type, NULL, var->tname);
1658 fprintf(file, ");\n");
1661 /* returns whether the MaxCount, Offset or ActualCount members need to be
1662 * filled in for the specified phase */
1663 static inline int is_size_needed_for_phase(enum remoting_phase phase)
1665 return (phase != PHASE_UNMARSHAL);
1668 void write_remoting_arguments(FILE *file, int indent, const func_t *func,
1669 unsigned int *type_offset, enum pass pass,
1670 enum remoting_phase phase)
1672 const expr_t *length_is;
1673 const expr_t *size_is;
1674 int in_attr, out_attr, has_length, has_size, pointer_type;
1681 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1682 for (; var; *type_offset += get_size_typeformatstring_var(var), var = PREV_LINK(var))
1684 const type_t *type = var->type;
1685 length_is = get_attrp(var->attrs, ATTR_LENGTHIS);
1686 size_is = get_attrp(var->attrs, ATTR_SIZEIS);
1687 has_length = length_is && (length_is->type != EXPR_VOID);
1688 has_size = (size_is && (size_is->type != EXPR_VOID)) || (var->array && !var->array->is_const);
1690 pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
1692 pointer_type = RPC_FC_RP;
1694 in_attr = is_attr(var->attrs, ATTR_IN);
1695 out_attr = is_attr(var->attrs, ATTR_OUT);
1696 if (!in_attr && !out_attr)
1713 while (type_has_ref(type))
1716 if (is_string_type(var->attrs, var->ptr_level, var->array))
1718 if (var->array && var->array->is_const)
1719 print_phase_function(file, indent, "NonConformantString", phase, var->name, *type_offset);
1722 if (size_is && is_size_needed_for_phase(phase))
1724 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
1725 write_expr(file, size_is, 1);
1726 fprintf(file, ";\n");
1729 if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP))
1730 print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
1732 print_phase_function(file, indent, "ConformantString", phase, var->name,
1733 *type_offset + (has_size ? 4 : 2));
1736 else if (is_array_type(var->attrs, var->ptr_level, var->array))
1738 const char *array_type;
1740 if (var->array && NEXT_LINK(var->array)) /* multi-dimensional array */
1741 array_type = "ComplexArray";
1744 if (!has_length && !has_size)
1745 array_type = "FixedArray";
1746 else if (has_length && !has_size)
1748 if (is_size_needed_for_phase(phase))
1750 print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
1751 print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
1752 write_expr(file, length_is, 1);
1753 fprintf(file, ";\n\n");
1755 array_type = "VaryingArray";
1757 else if (!has_length && has_size)
1759 if (is_size_needed_for_phase(phase) && phase != PHASE_FREE)
1761 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
1762 write_expr(file, size_is ? size_is : var->array, 1);
1763 fprintf(file, ";\n\n");
1765 array_type = "ConformantArray";
1769 if (is_size_needed_for_phase(phase))
1771 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
1772 write_expr(file, size_is ? size_is : var->array, 1);
1773 fprintf(file, ";\n");
1774 print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
1775 print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
1776 write_expr(file, length_is, 1);
1777 fprintf(file, ";\n\n");
1779 array_type = "ConformantVaryingArray";
1783 if (!in_attr && phase == PHASE_FREE)
1785 print_file(file, indent, "if (%s)\n", var->name);
1787 print_file(file, indent, "_StubMsg.pfnFree(%s);\n", var->name);
1789 else if (phase != PHASE_FREE)
1791 if (pointer_type == RPC_FC_UP)
1792 print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
1794 print_phase_function(file, indent, array_type, phase, var->name, *type_offset + 4);
1797 else if (var->ptr_level == 0 && is_base_type(type->type))
1799 print_phase_basetype(file, indent, phase, pass, var, var->name);
1801 else if (var->ptr_level == 0)
1803 const char *ndrtype;
1808 ndrtype = "SimpleStruct";
1810 case RPC_FC_CSTRUCT:
1811 case RPC_FC_CPSTRUCT:
1812 ndrtype = "ConformantStruct";
1814 case RPC_FC_CVSTRUCT:
1815 ndrtype = "ConformantVaryingStruct";
1817 case RPC_FC_BOGUS_STRUCT:
1818 ndrtype = "ComplexStruct";
1821 error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
1822 var->name, type->type, var->ptr_level);
1826 print_phase_function(file, indent, ndrtype, phase, var->name, *type_offset);
1830 if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && is_base_type(type->type))
1832 print_phase_basetype(file, indent, phase, pass, var, var->name);
1834 else if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && (type->type == RPC_FC_STRUCT))
1836 if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE)
1837 print_phase_function(file, indent, "SimpleStruct", phase, var->name, *type_offset + 4);
1841 print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
1844 fprintf(file, "\n");
1849 size_t get_size_procformatstring_var(const var_t *var)
1851 unsigned int type_offset = 2;
1852 return write_procformatstring_var(NULL, 0, var, FALSE, &type_offset);
1856 size_t get_size_typeformatstring_var(const var_t *var)
1858 unsigned int type_offset = 0;
1859 write_typeformatstring_var(NULL, 0, var, &type_offset);
1863 size_t get_size_procformatstring(const ifref_t *ifaces)
1865 const ifref_t *iface = ifaces;
1872 for (; iface; iface = PREV_LINK(iface))
1874 if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
1877 if (iface->iface->funcs)
1879 func = iface->iface->funcs;
1880 while (NEXT_LINK(func)) func = NEXT_LINK(func);
1883 /* argument list size */
1887 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1890 size += get_size_procformatstring_var(var);
1891 var = PREV_LINK(var);
1896 /* return value size */
1897 if (is_void(var->type, NULL))
1900 size += get_size_procformatstring_var(var);
1902 func = PREV_LINK(func);
1909 size_t get_size_typeformatstring(const ifref_t *ifaces)
1911 const ifref_t *iface = ifaces;
1918 for (; iface; iface = PREV_LINK(iface))
1920 if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
1923 if (iface->iface->funcs)
1925 func = iface->iface->funcs;
1926 while (NEXT_LINK(func)) func = NEXT_LINK(func);
1929 /* argument list size */
1933 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1936 size += get_size_typeformatstring_var(var);
1937 var = PREV_LINK(var);
1941 func = PREV_LINK(func);
1948 static void write_struct_expr(FILE *h, const expr_t *e, int brackets,
1949 const var_t *fields, const char *structvar)
1955 fprintf(h, "%ld", e->u.lval);
1958 fprintf(h, "0x%lx", e->u.lval);
1960 case EXPR_IDENTIFIER:
1963 for (field = fields; field; field = NEXT_LINK(field))
1965 if (!strcmp(e->u.sval, field->name))
1967 fprintf(h, "%s->%s", structvar, e->u.sval);
1971 if (!field) error("no field found for identifier %s\n", e->u.sval);
1976 write_struct_expr(h, e->ref, 1, fields, structvar);
1980 write_struct_expr(h, e->ref, 1, fields, structvar);
1984 write_struct_expr(h, e->ref, 1, fields, structvar);
1988 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
1990 write_struct_expr(h, e->ref, 1, fields, structvar);
1993 fprintf(h, "sizeof(");
1994 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
2005 if (brackets) fprintf(h, "(");
2006 write_struct_expr(h, e->ref, 1, fields, structvar);
2008 case EXPR_SHL: fprintf(h, " << "); break;
2009 case EXPR_SHR: fprintf(h, " >> "); break;
2010 case EXPR_MUL: fprintf(h, " * "); break;
2011 case EXPR_DIV: fprintf(h, " / "); break;
2012 case EXPR_ADD: fprintf(h, " + "); break;
2013 case EXPR_SUB: fprintf(h, " - "); break;
2014 case EXPR_AND: fprintf(h, " & "); break;
2015 case EXPR_OR: fprintf(h, " | "); break;
2018 write_struct_expr(h, e->u.ext, 1, fields, structvar);
2019 if (brackets) fprintf(h, ")");
2022 if (brackets) fprintf(h, "(");
2023 write_struct_expr(h, e->ref, 1, fields, structvar);
2025 write_struct_expr(h, e->u.ext, 1, fields, structvar);
2027 write_struct_expr(h, e->ext2, 1, fields, structvar);
2028 if (brackets) fprintf(h, ")");
2033 int write_expr_eval_routines(FILE *file, const char *iface)
2036 struct expr_eval_routine *eval;
2037 unsigned short callback_offset = 0;
2039 LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
2043 print_file(file, indent, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
2044 iface, eval->structure->name, callback_offset);
2045 print_file(file, indent, "{\n");
2047 print_file(file, indent, "struct %s *" STRUCT_EXPR_EVAL_VAR " = (struct %s *)(pStubMsg->StackTop - %u);\n",
2048 eval->structure->name, eval->structure->name, eval->structure_size);
2049 fprintf(file, "\n");
2050 print_file(file, indent, "pStubMsg->Offset = 0;\n"); /* FIXME */
2051 print_file(file, indent, "pStubMsg->MaxCount = (unsigned long)");
2052 write_struct_expr(file, eval->expr, 1, eval->structure->fields, STRUCT_EXPR_EVAL_VAR);
2053 fprintf(file, ";\n");
2055 print_file(file, indent, "}\n\n");
2061 void write_expr_eval_routine_list(FILE *file, const char *iface)
2063 struct expr_eval_routine *eval;
2064 struct expr_eval_routine *cursor;
2065 unsigned short callback_offset = 0;
2067 fprintf(file, "static const EXPR_EVAL ExprEvalRoutines[] =\n");
2068 fprintf(file, "{\n");
2070 LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry)
2072 print_file(file, 1, "%s_%sExprEval_%04u,\n",
2073 iface, eval->structure->name, callback_offset);
2076 list_remove(&eval->entry);
2080 fprintf(file, "};\n\n");