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;
77 return a->u.lval - b->u.lval;
79 return strcmp(a->u.sval, b->u.sval);
81 ret = compare_expr(a->ref, b->ref);
84 ret = compare_expr(a->u.ext, b->u.ext);
87 return compare_expr(a->ext2, b->ext2);
96 ret = compare_expr(a->ref, b->ref);
99 return compare_expr(a->u.ext, b->u.ext);
105 return compare_expr(a->ref, b->ref);
112 #define WRITE_FCTYPE(file, fctype, typestring_offset) \
115 fprintf(file, "/* %2u */\n", typestring_offset); \
116 print_file((file), 2, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
120 static int print_file(FILE *file, int indent, const char *format, ...)
127 va_start(va, format);
128 for (i = 0; i < indent; i++)
130 r = vfprintf(file, format, va);
135 static inline int type_has_ref(const type_t *type)
137 return (type->type == 0 && type->ref);
140 static inline int is_base_type(unsigned char type)
159 case RPC_FC_ERROR_STATUS_T:
160 case RPC_FC_BIND_PRIMITIVE:
168 unsigned char ref_type(const type_t *type)
170 while (type_has_ref(type))
176 static size_t write_procformatstring_var(FILE *file, int indent,
177 const var_t *var, int is_return, unsigned int *type_offset)
180 int ptr_level = var->ptr_level;
181 const type_t *type = var->type;
183 int is_in = is_attr(var->attrs, ATTR_IN);
184 int is_out = is_attr(var->attrs, ATTR_OUT);
186 if (!is_in && !is_out) is_in = TRUE;
188 if (ptr_level == 0 && type_has_ref(type))
191 if (ptr_level == 0 && !var->array && is_base_type(type->type))
194 print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
196 print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
200 #define CASE_BASETYPE(fctype) \
202 print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
203 size = 2; /* includes param type prefix */ \
206 CASE_BASETYPE(FC_BYTE);
207 CASE_BASETYPE(FC_CHAR);
208 CASE_BASETYPE(FC_WCHAR);
209 CASE_BASETYPE(FC_USHORT);
210 CASE_BASETYPE(FC_SHORT);
211 CASE_BASETYPE(FC_ULONG);
212 CASE_BASETYPE(FC_LONG);
213 CASE_BASETYPE(FC_HYPER);
214 CASE_BASETYPE(FC_IGNORE);
215 CASE_BASETYPE(FC_USMALL);
216 CASE_BASETYPE(FC_SMALL);
217 CASE_BASETYPE(FC_FLOAT);
218 CASE_BASETYPE(FC_DOUBLE);
219 CASE_BASETYPE(FC_ERROR_STATUS_T);
222 case RPC_FC_BIND_PRIMITIVE:
223 print_file(file, indent, "0x%02x, /* FC_IGNORE */\n", RPC_FC_IGNORE);
224 size = 2; /* includes param type prefix */
228 error("Unknown/unsupported type: %s (0x%02x)\n", var->name, type->type);
235 print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n");
236 else if (is_in && is_out)
237 print_file(file, indent, "0x50, /* FC_IN_OUT_PARAM */\n");
239 print_file(file, indent, "0x51, /* FC_OUT_PARAM */\n");
241 print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n");
243 print_file(file, indent, "0x01,\n");
244 print_file(file, indent, "NdrFcShort(0x%x),\n", *type_offset);
245 size = 4; /* includes param type prefix */
247 *type_offset += get_size_typeformatstring_var(var);
251 void write_procformatstring(FILE *file, const ifref_t *ifaces)
253 const ifref_t *iface = ifaces;
256 unsigned int type_offset = 2;
258 print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
259 print_file(file, indent, "{\n");
261 print_file(file, indent, "0,\n");
262 print_file(file, indent, "{\n");
267 for (; iface; iface = PREV_LINK(iface))
269 if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
272 if (iface->iface->funcs)
274 func_t *func = iface->iface->funcs;
275 while (NEXT_LINK(func)) func = NEXT_LINK(func);
276 for (; func; func = PREV_LINK(func))
278 /* emit argument data */
282 while (NEXT_LINK(var)) var = NEXT_LINK(var);
285 write_procformatstring_var(file, indent, var, FALSE,
288 var = PREV_LINK(var);
292 /* emit return value data */
294 if (is_void(var->type, NULL))
296 print_file(file, indent, "0x5b, /* FC_END */\n");
297 print_file(file, indent, "0x5c, /* FC_PAD */\n");
300 write_procformatstring_var(file, indent, var, TRUE,
306 print_file(file, indent, "0x0\n");
308 print_file(file, indent, "}\n");
310 print_file(file, indent, "};\n");
311 print_file(file, indent, "\n");
314 /* write conformance / variance descriptor */
315 static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_t *structure, const expr_t *expr)
317 unsigned char operator_type = 0;
318 const char *operator_string = "no operators";
319 const expr_t *subexpr = expr;
320 unsigned char correlation_type;
322 if (!file) return 4; /* optimisation for sizing pass */
326 if (expr->cval > UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX)
327 error("write_conf_or_var_desc: constant value %ld is greater than "
328 "the maximum constant size of %d\n", expr->cval,
329 UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX);
331 print_file(file, 2, "0x%x, /* Corr desc: constant, val = %ld */\n",
332 RPC_FC_CONSTANT_CONFORMANCE, expr->cval);
333 print_file(file, 2, "0x%x,\n", expr->cval & ~USHRT_MAX);
334 print_file(file, 2, "NdrFcShort(0x%x),\n", expr->cval & USHRT_MAX);
339 switch (subexpr->type)
342 subexpr = subexpr->ref;
343 operator_type = RPC_FC_DEREFERENCE;
344 operator_string = "FC_DEREFERENCE";
347 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2))
349 subexpr = subexpr->ref;
350 operator_type = RPC_FC_DIV_2;
351 operator_string = "FC_DIV_2";
355 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2))
357 subexpr = subexpr->ref;
358 operator_type = RPC_FC_MULT_2;
359 operator_string = "FC_MULT_2";
363 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1))
365 subexpr = subexpr->ref;
366 operator_type = RPC_FC_SUB_1;
367 operator_string = "FC_SUB_1";
371 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1))
373 subexpr = subexpr->ref;
374 operator_type = RPC_FC_ADD_1;
375 operator_string = "FC_ADD_1";
382 if (subexpr->type == EXPR_IDENTIFIER)
384 const type_t *correlation_variable = NULL;
385 unsigned char correlation_variable_type;
386 unsigned char param_type = 0;
387 const char *param_type_string = NULL;
394 for (offset = 0, var = structure->fields; var; var = NEXT_LINK(var))
396 offset -= type_memsize(var->type, var->ptr_level, var->array);
397 if (!strcmp(var->name, subexpr->u.sval))
399 correlation_variable = var->type;
403 if (!correlation_variable)
404 error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
407 correlation_type = RPC_FC_NORMAL_CONFORMANCE;
411 const var_t *var = func->args;
413 while (NEXT_LINK(var)) var = NEXT_LINK(var);
414 /* FIXME: not all stack variables are sizeof(void *) */
415 for (offset = 0; var; offset += sizeof(void *), var = PREV_LINK(var))
417 if (!strcmp(var->name, subexpr->u.sval))
419 correlation_variable = var->type;
423 if (!correlation_variable)
424 error("write_conf_or_var_desc: couldn't find variable %s in function\n",
427 correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE;
430 correlation_variable_type = ref_type(correlation_variable);
432 switch (correlation_variable_type)
436 param_type = RPC_FC_SMALL;
437 param_type_string = "FC_SMALL";
441 param_type = RPC_FC_USMALL;
442 param_type_string = "FC_USMALL";
446 param_type = RPC_FC_SHORT;
447 param_type_string = "FC_SHORT";
450 param_type = RPC_FC_USHORT;
451 param_type_string = "FC_USHORT";
454 param_type = RPC_FC_LONG;
455 param_type_string = "FC_LONG";
458 param_type = RPC_FC_ULONG;
459 param_type_string = "FC_ULONG";
462 error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n",
463 correlation_variable_type);
466 print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n",
467 correlation_type | param_type,
468 correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter, " : "",
470 print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string);
471 print_file(file, 2, "NdrFcShort(0x%x), /* %soffset = %d */\n",
473 correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "x86 stack size / " : "",
478 unsigned int callback_offset = 0;
482 struct expr_eval_routine *eval;
485 LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
487 if (!strcmp(eval->structure->name, structure->name) &&
488 !compare_expr(eval->expr, expr))
498 eval = xmalloc(sizeof(*eval));
499 eval->structure = structure;
500 eval->structure_size = fields_memsize(structure->fields);
502 list_add_tail(&expr_eval_routines, &eval->entry);
505 correlation_type = RPC_FC_NORMAL_CONFORMANCE;
509 error("write_conf_or_var_desc: top-level callback conformance unimplemented\n");
510 correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE;
513 if (callback_offset > USHRT_MAX)
514 error("Maximum number of callback routines reached\n");
516 print_file(file, 2, "0x%x, /* Corr desc: %s */\n",
518 correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter" : "");
519 print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK");
520 print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", callback_offset, callback_offset);
525 static size_t fields_memsize(const var_t *v)
528 const var_t *first = v;
530 while (NEXT_LINK(v)) v = NEXT_LINK(v);
532 size += type_memsize(v->type, v->ptr_level, v->array);
533 if (v == first) break;
539 static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array)
544 return sizeof(void *);
547 return type_memsize(t->ref, 0 /* FIXME */, NULL);
565 case RPC_FC_ERROR_STATUS_T:
575 case RPC_FC_CVSTRUCT:
576 case RPC_FC_CPSTRUCT:
579 case RPC_FC_BOGUS_STRUCT:
580 case RPC_FC_ENCAPSULATED_UNION:
581 case RPC_FC_NON_ENCAPSULATED_UNION:
582 size = fields_memsize(t->fields);
585 error("type_memsize: Unknown type %d\n", t->type);
600 size_t get_type_memsize(const type_t *type)
602 return type_memsize(type, 0, NULL);
605 static int write_pointers(FILE *file, const attr_t *attrs,
606 const type_t *type, int ptr_level,
607 const expr_t *array, int level,
608 unsigned int *typestring_offset)
610 int pointers_written = 0;
613 /* don't generate a pointer for first-level arrays since we want to
614 * descend into them to write their pointers, not stop here */
615 if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array))
617 return write_pointers(file, NULL, type, 0, NULL, level + 1, typestring_offset);
622 /* FIXME: only general algorithm implemented, not the actual writing */
623 error("write_pointers: Writing type format string for pointer is unimplemented\n");
627 /* FIXME: search through all refs for pointers too */
628 while(type_has_ref(type))
633 /* note: don't descend into complex structures or unions since these
634 * will always be generated as a separate type */
636 case RPC_FC_CVSTRUCT:
637 case RPC_FC_CPSTRUCT:
642 while (NEXT_LINK(v)) v = NEXT_LINK(v);
643 for (; v; v = PREV_LINK(v))
644 pointers_written += write_pointers(file, v->attrs, v->type,
645 v->ptr_level, v->array,
656 return pointers_written;
659 static size_t write_pointer_description(FILE *file, const attr_t *attrs,
660 const type_t *type, int ptr_level,
661 const expr_t *array, int level,
662 size_t typestring_offset)
667 /* don't generate a pointer for first-level arrays since we want to
668 * descend into them to write their pointers, not stop here */
669 if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array))
671 return write_pointer_description(file, NULL, type, 0, NULL,
672 level + 1, typestring_offset);
677 /* FIXME: only general algorithm implemented, not the actual writing */
678 error("write_pointer_description: Writing pointer description is unimplemented\n");
682 /* FIXME: search through all refs for pointers too */
686 /* note: don't descend into complex structures or unions since these
687 * will always be generated as a separate type */
689 case RPC_FC_CVSTRUCT:
690 case RPC_FC_CPSTRUCT:
695 while (NEXT_LINK(v)) v = NEXT_LINK(v);
696 for (; v; v = PREV_LINK(v))
697 size += write_pointer_description(file, v->attrs, v->type,
698 v->ptr_level, v->array,
712 static size_t write_string_tfs(FILE *file, const attr_t *attrs,
713 const type_t *type, const expr_t *array,
714 const char *name, unsigned int *typestring_offset)
716 const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS);
717 int has_size = size_is && (size_is->type != EXPR_VOID);
718 size_t start_offset = *typestring_offset;
719 unsigned char flags = 0;
720 int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
724 pointer_type = RPC_FC_RP;
726 if (!get_attrp(attrs, ATTR_SIZEIS))
727 flags |= RPC_FC_P_SIMPLEPOINTER;
729 rtype = ref_type(type);
731 if ((rtype != RPC_FC_BYTE) && (rtype != RPC_FC_CHAR) && (rtype != RPC_FC_WCHAR))
733 error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", rtype, name);
737 print_file(file, 2,"0x%x, 0x%x, /* %s%s */\n",
739 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"),
740 (flags & RPC_FC_P_SIMPLEPOINTER) ? " [simple_pointer]" : "");
741 *typestring_offset += 2;
743 if (!(flags & RPC_FC_P_SIMPLEPOINTER))
745 print_file(file, 2, "NdrFcShort(0x2),\n");
746 *typestring_offset += 2;
749 if (array && array->is_const)
751 if (array->cval > USHRT_MAX)
752 error("array size for parameter %s exceeds %d bytes by %ld bytes\n",
753 name, USHRT_MAX, array->cval - USHRT_MAX);
755 if (rtype == RPC_FC_CHAR)
756 WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset);
758 WRITE_FCTYPE(file, FC_WSTRING, *typestring_offset);
759 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
760 *typestring_offset += 2;
762 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", array->cval, array->cval);
763 *typestring_offset += 2;
769 if (rtype == RPC_FC_CHAR)
770 WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
772 WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset);
773 print_file(file, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED);
774 *typestring_offset += 2;
776 *typestring_offset += write_conf_or_var_desc(file, current_func, NULL, size_is);
782 if (rtype == RPC_FC_CHAR)
783 WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
785 WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset);
786 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
787 *typestring_offset += 2;
793 static size_t write_array_tfs(FILE *file, const attr_t *attrs,
794 const type_t *type, const expr_t *array,
795 const char *name, unsigned int *typestring_offset)
797 const expr_t *length_is = get_attrp(attrs, ATTR_LENGTHIS);
798 const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS);
799 int has_length = length_is && (length_is->type != EXPR_VOID);
800 int has_size = (size_is && (size_is->type != EXPR_VOID)) || !array->is_const;
802 int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
804 pointer_type = RPC_FC_RP;
806 print_file(file, 2, "0x%x, 0x00, /* %s */\n",
808 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"));
809 print_file(file, 2, "NdrFcShort(0x2),\n");
810 *typestring_offset += 4;
812 if (array && NEXT_LINK(array)) /* multi-dimensional array */
814 error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name);
819 size_t pointer_start_offset = *typestring_offset;
822 if (write_pointers(file, attrs, type, 0, array, 0, typestring_offset) > 0)
825 start_offset = *typestring_offset;
827 if (!has_length && !has_size)
830 size_t size = type_memsize(type, 0, array);
831 if (size < USHRT_MAX)
833 WRITE_FCTYPE(file, FC_SMFARRAY, *typestring_offset);
835 print_file(file, 2, "0x%x, /* 0 */\n", 0);
837 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", size, size);
838 *typestring_offset += 4;
842 WRITE_FCTYPE(file, FC_LGFARRAY, *typestring_offset);
844 print_file(file, 2, "0x%x, /* 0 */\n", 0);
846 print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", size, size);
847 *typestring_offset += 6;
852 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
853 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
854 *typestring_offset += 2;
855 *typestring_offset = write_pointer_description(file, attrs,
856 type, 0, array, 0, pointer_start_offset);
857 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
858 *typestring_offset += 1;
861 print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
862 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
863 *typestring_offset += 2;
867 else if (has_length && !has_size)
870 size_t element_size = type_memsize(type, 0, NULL);
871 size_t elements = array->cval;
872 size_t total_size = element_size * elements;
874 if (total_size < USHRT_MAX)
876 WRITE_FCTYPE(file, FC_SMVARRAY, *typestring_offset);
878 print_file(file, 2, "0x%x, /* 0 */\n", 0);
880 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", total_size, total_size);
881 /* number of elements */
882 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", elements, elements);
883 *typestring_offset += 6;
887 WRITE_FCTYPE(file, FC_LGVARRAY, *typestring_offset);
889 print_file(file, 2, "0x%x, /* 0 */\n", 0);
891 print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", total_size, total_size);
892 /* number of elements */
893 print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", elements, elements);
894 *typestring_offset += 10;
897 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
898 *typestring_offset += 2;
900 *typestring_offset += write_conf_or_var_desc(file, current_func,
906 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
907 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
908 *typestring_offset += 2;
909 *typestring_offset += write_pointer_description(file, attrs,
910 type, 0, array, 0, pointer_start_offset);
911 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
912 *typestring_offset += 1;
915 print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
916 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
917 *typestring_offset += 2;
921 else if (!has_length && has_size)
923 /* conformant array */
924 size_t element_size = type_memsize(type, 0, NULL);
926 WRITE_FCTYPE(file, FC_CARRAY, *typestring_offset);
928 print_file(file, 2, "0x%x, /* 0 */\n", 0);
930 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
931 *typestring_offset += 4;
933 *typestring_offset += write_conf_or_var_desc(file, current_func,
935 size_is ? size_is : array);
939 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
940 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
941 *typestring_offset += 2;
942 *typestring_offset += write_pointer_description(file, attrs,
943 type, 0, array, 0, pointer_start_offset);
944 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
945 *typestring_offset += 1;
948 print_file(file, 2, "0x%x, /* FIXME: write out conversion data */\n", type->type);
949 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
950 *typestring_offset += 2;
956 /* conformant varying array */
957 size_t element_size = type_memsize(type, 0, NULL);
959 WRITE_FCTYPE(file, FC_CVARRAY, *typestring_offset);
961 print_file(file, 2, "0x%x, /* 0 */\n", 0);
963 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
964 *typestring_offset += 4;
966 *typestring_offset += write_conf_or_var_desc(file, current_func,
968 size_is ? size_is : array);
969 *typestring_offset += write_conf_or_var_desc(file, current_func,
975 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
976 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
977 *typestring_offset += 2;
978 *typestring_offset += write_pointer_description(file, attrs,
979 type, 0, array, 0, pointer_start_offset);
980 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
981 *typestring_offset += 1;
984 print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
985 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
986 *typestring_offset += 2;
993 static const var_t *find_array_or_string_in_struct(const type_t *type)
995 /* last field is the first in the fields linked list */
996 const var_t *last_field = type->fields;
997 if (is_array_type(last_field->attrs, last_field->ptr_level, last_field->array))
1000 assert((last_field->type->type == RPC_FC_CSTRUCT) ||
1001 (last_field->type->type == RPC_FC_CPSTRUCT) ||
1002 (last_field->type->type == RPC_FC_CVSTRUCT));
1004 return find_array_or_string_in_struct(last_field->type);
1007 static size_t write_struct_members(FILE *file, const type_t *type)
1009 size_t typestring_size = 0;
1012 field = type->fields;
1013 while (NEXT_LINK(field)) field = NEXT_LINK(field);
1014 for (; field; field = PREV_LINK(field))
1016 unsigned char rtype = ref_type(field->type);
1018 if (is_base_type(rtype))
1022 #define CASE_BASETYPE(fctype) \
1023 case RPC_##fctype: \
1024 print_file(file, 2, "0x%02x,\t\t/* " #fctype " */\n", RPC_##fctype); \
1025 typestring_size++; \
1027 CASE_BASETYPE(FC_BYTE);
1028 CASE_BASETYPE(FC_CHAR);
1029 CASE_BASETYPE(FC_SMALL);
1030 CASE_BASETYPE(FC_USMALL);
1031 CASE_BASETYPE(FC_WCHAR);
1032 CASE_BASETYPE(FC_SHORT);
1033 CASE_BASETYPE(FC_USHORT);
1034 CASE_BASETYPE(FC_LONG);
1035 CASE_BASETYPE(FC_ULONG);
1036 CASE_BASETYPE(FC_FLOAT);
1037 CASE_BASETYPE(FC_HYPER);
1038 CASE_BASETYPE(FC_DOUBLE);
1039 CASE_BASETYPE(FC_ENUM16);
1040 CASE_BASETYPE(FC_ENUM32);
1041 CASE_BASETYPE(FC_IGNORE);
1042 CASE_BASETYPE(FC_ERROR_STATUS_T);
1045 #undef CASE_BASETYPE
1049 error("Unsupported member type 0x%x\n", rtype);
1052 if (typestring_size % 1)
1054 print_file(file, 2, "0x%x,\t\t/* FC_PAD */\n", RPC_FC_PAD);
1058 print_file(file, 2, "0x%x,\t\t/* FC_END */\n", RPC_FC_END);
1061 return typestring_size;
1064 static size_t write_struct_tfs(FILE *file, const type_t *type,
1065 const char *name, unsigned int *typestring_offset)
1067 unsigned int total_size;
1069 size_t start_offset;
1070 size_t array_offset;
1071 size_t pointer_offset;
1076 case RPC_FC_PSTRUCT:
1077 total_size = type_memsize(type, 0, NULL);
1079 if (total_size > USHRT_MAX)
1080 error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
1081 name, USHRT_MAX, total_size - USHRT_MAX);
1083 if (type->type == RPC_FC_PSTRUCT)
1085 pointer_offset = *typestring_offset;
1086 write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset);
1088 else pointer_offset = 0; /* silence warning */
1090 start_offset = *typestring_offset;
1091 if (type->type == RPC_FC_STRUCT)
1092 WRITE_FCTYPE(file, FC_STRUCT, *typestring_offset);
1094 WRITE_FCTYPE(file, FC_PSTRUCT, *typestring_offset);
1096 print_file(file, 2, "0x3,\n"); /* FIXME */
1098 print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size);
1099 *typestring_offset += 4;
1101 if (type->type == RPC_FC_PSTRUCT)
1103 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
1104 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
1105 *typestring_offset += 2;
1106 *typestring_offset += write_pointer_description(file, NULL,
1107 type, 0, NULL, 0, pointer_offset);
1108 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1109 *typestring_offset += 1;
1113 *typestring_offset += write_struct_members(file, type);
1114 return start_offset;
1115 case RPC_FC_CSTRUCT:
1116 case RPC_FC_CPSTRUCT:
1117 total_size = type_memsize(type, 0, NULL);
1119 if (total_size > USHRT_MAX)
1120 error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
1121 name, USHRT_MAX, total_size - USHRT_MAX);
1123 array = find_array_or_string_in_struct(type);
1124 current_structure = type;
1125 array_offset = write_array_tfs(file, array->attrs, array->type,
1126 array->array, array->name,
1128 current_structure = NULL;
1130 if (type->type == RPC_FC_CPSTRUCT)
1132 pointer_offset = *typestring_offset;
1133 write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset);
1135 else pointer_offset = 0; /* silence warning */
1137 start_offset = *typestring_offset;
1138 if (type->type == RPC_FC_CSTRUCT)
1139 WRITE_FCTYPE(file, FC_CSTRUCT, *typestring_offset);
1141 WRITE_FCTYPE(file, FC_CPSTRUCT, *typestring_offset);
1143 print_file(file, 2, "0x0,\n");
1145 print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size);
1146 *typestring_offset += 4;
1147 print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d (%u) */\n",
1148 array_offset - *typestring_offset,
1149 array_offset - *typestring_offset,
1151 *typestring_offset += 2;
1153 if (type->type == RPC_FC_CPSTRUCT)
1155 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
1156 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
1157 *typestring_offset += 2;
1158 *typestring_offset += write_pointer_description(file, NULL,
1159 type, 0, NULL, 0, pointer_offset);
1160 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1161 *typestring_offset += 1;
1164 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1165 *typestring_offset += 1;
1167 return start_offset;
1168 case RPC_FC_CVSTRUCT:
1169 total_size = type_memsize(type, 0, NULL);
1171 if (total_size > USHRT_MAX)
1172 error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
1173 name, USHRT_MAX, total_size - USHRT_MAX);
1175 array = find_array_or_string_in_struct(type);
1176 current_structure = type;
1177 if (is_attr(array->attrs, ATTR_STRING))
1178 array_offset = write_string_tfs(file, array->attrs, array->type,
1179 array->array, array->name,
1182 array_offset = write_array_tfs(file, array->attrs, array->type,
1183 array->array, array->name,
1185 current_structure = NULL;
1187 pointer_offset = *typestring_offset;
1188 if (!write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset))
1191 start_offset = *typestring_offset;
1192 WRITE_FCTYPE(file, FC_CVSTRUCT, *typestring_offset);
1194 print_file(file, 2, "0x0,\n");
1196 print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size);
1197 *typestring_offset += 4;
1198 print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d (%u) */\n",
1199 array_offset - *typestring_offset,
1200 array_offset - *typestring_offset,
1202 *typestring_offset += 2;
1204 if (pointer_offset != 0)
1206 print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
1207 print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
1208 *typestring_offset += 2;
1209 *typestring_offset += write_pointer_description(file, NULL,
1210 type, 0, NULL, 0, pointer_offset);
1211 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1212 *typestring_offset += 1;
1215 print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
1216 *typestring_offset += 1;
1218 return start_offset;
1220 error("write_struct_tfs: Unimplemented for type 0x%x\n", type->type);
1221 return *typestring_offset;
1225 static void write_pointer_only_tfs(FILE *file, const attr_t *attrs, size_t offset, unsigned int *typeformat_offset)
1227 int in_attr, out_attr;
1228 unsigned char flags = 0;
1229 int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
1230 if (!pointer_type) pointer_type = RPC_FC_RP;
1231 in_attr = is_attr(attrs, ATTR_IN);
1232 out_attr = is_attr(attrs, ATTR_OUT);
1233 if (!in_attr && !out_attr) in_attr = 1;
1235 if (out_attr && !in_attr && pointer_type == RPC_FC_RP)
1238 print_file(file, 2, "0x%x, 0x%x,\t\t/* %s%s */\n",
1241 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"),
1242 (flags & 0x04) ? " [allocated_on_stack]" : "");
1243 print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", offset, offset);
1244 *typeformat_offset += 4;
1247 static size_t write_union_tfs(FILE *file, const attr_t *attrs,
1248 const type_t *type, const char *name,
1249 unsigned int *typeformat_offset)
1251 error("write_union_tfs: Unimplemented\n");
1252 return *typeformat_offset;
1255 static size_t write_typeformatstring_var(FILE *file, int indent,
1256 const var_t *var, unsigned int *typeformat_offset)
1258 const type_t *type = var->type;
1259 int ptr_level = var->ptr_level;
1261 chat("write_typeformatstring_var: %s\n", var->name);
1265 chat("write_typeformatstring: type->type = 0x%x, type->name = %s, ptr_level = %d\n", type->type, type->name, ptr_level);
1267 if (is_string_type(var->attrs, ptr_level, var->array))
1268 return write_string_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
1270 if (is_array_type(var->attrs, ptr_level, var->array))
1271 return write_array_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
1275 /* follow reference if the type has one */
1276 if (type_has_ref(type))
1279 /* FIXME: get new ptr_level from type */
1283 /* basic types don't need a type format string */
1284 if (is_base_type(type->type))
1290 case RPC_FC_PSTRUCT:
1291 case RPC_FC_CSTRUCT:
1292 case RPC_FC_CPSTRUCT:
1293 case RPC_FC_CVSTRUCT:
1294 case RPC_FC_BOGUS_STRUCT:
1295 return write_struct_tfs(file, type, var->name, typeformat_offset);
1296 case RPC_FC_ENCAPSULATED_UNION:
1297 case RPC_FC_NON_ENCAPSULATED_UNION:
1298 return write_union_tfs(file, var->attrs, type, var->name, typeformat_offset);
1300 case RPC_FC_BIND_PRIMITIVE:
1304 error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name);
1307 else if (ptr_level == 1 && !type_has_ref(type))
1309 size_t start_offset = *typeformat_offset;
1310 int in_attr = is_attr(var->attrs, ATTR_IN);
1311 int out_attr = is_attr(var->attrs, ATTR_OUT);
1312 int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
1313 if (!pointer_type) pointer_type = RPC_FC_RP;
1315 /* special case for pointers to base types */
1318 #define CASE_BASETYPE(fctype) \
1319 case RPC_##fctype: \
1320 print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", \
1322 (!in_attr && out_attr) ? 0x0C : 0x08, \
1323 pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), \
1324 (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); \
1325 print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
1326 print_file(file, indent, "0x5c, /* FC_PAD */\n"); \
1327 *typeformat_offset += 4; \
1329 CASE_BASETYPE(FC_BYTE);
1330 CASE_BASETYPE(FC_CHAR);
1331 CASE_BASETYPE(FC_SMALL);
1332 CASE_BASETYPE(FC_USMALL);
1333 CASE_BASETYPE(FC_WCHAR);
1334 CASE_BASETYPE(FC_SHORT);
1335 CASE_BASETYPE(FC_USHORT);
1336 CASE_BASETYPE(FC_LONG);
1337 CASE_BASETYPE(FC_ULONG);
1338 CASE_BASETYPE(FC_FLOAT);
1339 CASE_BASETYPE(FC_HYPER);
1340 CASE_BASETYPE(FC_DOUBLE);
1341 CASE_BASETYPE(FC_ENUM16);
1342 CASE_BASETYPE(FC_ENUM32);
1343 CASE_BASETYPE(FC_IGNORE);
1344 CASE_BASETYPE(FC_ERROR_STATUS_T);
1350 assert(ptr_level > 0);
1353 fprintf(file, "/* %2u */\n", *typeformat_offset);
1354 write_pointer_only_tfs(file, var->attrs, 2, typeformat_offset);
1361 void write_typeformatstring(FILE *file, const ifref_t *ifaces)
1365 unsigned int typeformat_offset;
1366 const ifref_t *iface = ifaces;
1368 print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
1369 print_file(file, indent, "{\n");
1371 print_file(file, indent, "0,\n");
1372 print_file(file, indent, "{\n");
1374 print_file(file, indent, "NdrFcShort(0x0),\n");
1375 typeformat_offset = 2;
1379 for (; iface; iface = PREV_LINK(iface))
1381 if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
1384 if (iface->iface->funcs)
1386 func_t *func = iface->iface->funcs;
1387 while (NEXT_LINK(func)) func = NEXT_LINK(func);
1388 for (; func; func = PREV_LINK(func))
1390 current_func = func;
1394 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1397 write_typeformatstring_var(file, indent, var,
1398 &typeformat_offset);
1399 var = PREV_LINK(var);
1406 print_file(file, indent, "0x0\n");
1408 print_file(file, indent, "}\n");
1410 print_file(file, indent, "};\n");
1411 print_file(file, indent, "\n");
1414 static unsigned int get_required_buffer_size_type(
1415 const type_t *type, int ptr_level, const expr_t *array,
1416 const char *name, unsigned int *alignment)
1419 if (ptr_level == 0 && !array && !type_has_ref(type))
1439 case RPC_FC_ERROR_STATUS_T:
1449 case RPC_FC_BIND_PRIMITIVE:
1456 for (field = type->fields; field; field = NEXT_LINK(field))
1458 unsigned int alignment;
1459 size += get_required_buffer_size_type(
1460 field->type, field->ptr_level, field->array, field->name,
1467 error("get_required_buffer_size: Unknown/unsupported type: %s (0x%02x)\n", name, type->type);
1471 if (ptr_level == 0 && type_has_ref(type))
1472 return get_required_buffer_size_type(type->ref, 0 /* FIXME */, array, name, alignment);
1476 unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass)
1478 expr_t *size_is = get_attrp(var->attrs, ATTR_SIZEIS);
1479 int has_size = (size_is && (size_is->type != EXPR_VOID));
1480 int in_attr = is_attr(var->attrs, ATTR_IN);
1481 int out_attr = is_attr(var->attrs, ATTR_OUT);
1483 if (!in_attr && !out_attr)
1488 if (pass == PASS_OUT)
1490 if (out_attr && var->ptr_level > 0)
1492 type_t *type = var->type;
1493 while (type->type == 0 && type->ref)
1496 if (type->type == RPC_FC_STRUCT)
1499 unsigned int size = 36;
1500 for (field = type->fields; field; field = NEXT_LINK(field))
1503 size += get_required_buffer_size_type(
1504 field->type, field->ptr_level, field->array, field->name,
1514 if ((!out_attr || in_attr) && !has_size && !is_attr(var->attrs, ATTR_STRING) && !var->array)
1516 if (var->ptr_level > 0 || (var->ptr_level == 0 && type_has_ref(var->type)))
1518 type_t *type = var->type;
1519 while (type->type == 0 && type->ref)
1522 if (is_base_type(type->type))
1526 else if (type->type == RPC_FC_STRUCT)
1528 unsigned int size = 36;
1530 for (field = type->fields; field; field = NEXT_LINK(field))
1533 size += get_required_buffer_size_type(
1534 field->type, field->ptr_level, field->array, field->name,
1542 return get_required_buffer_size_type(var->type, var->ptr_level, var->array, var->name, alignment);
1546 static void print_phase_function(FILE *file, int indent, const char *type,
1547 enum remoting_phase phase,
1548 const char *varname, unsigned int type_offset)
1550 const char *function;
1553 case PHASE_BUFFERSIZE:
1554 function = "BufferSize";
1557 function = "Marshall";
1559 case PHASE_UNMARSHAL:
1560 function = "Unmarshall";
1570 print_file(file, indent, "Ndr%s%s(\n", type, function);
1572 print_file(file, indent, "&_StubMsg,\n");
1573 print_file(file, indent, "%s%s,\n",
1574 (phase == PHASE_UNMARSHAL) ? "(unsigned char **)&" : "(unsigned char *)",
1576 print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
1577 type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");");
1578 if (phase == PHASE_UNMARSHAL)
1579 print_file(file, indent, "0);\n");
1583 void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase,
1584 enum pass pass, const var_t *var,
1585 const char *varname)
1587 const type_t *type = var->type;
1589 unsigned int alignment = 0;
1590 unsigned char rtype;
1592 /* no work to do for other phases, buffer sizing is done elsewhere */
1593 if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL)
1596 rtype = ref_type(type);
1618 case RPC_FC_ERROR_STATUS_T:
1630 case RPC_FC_BIND_PRIMITIVE:
1631 /* no marshalling needed */
1635 error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, rtype);
1639 print_file(file, indent, "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + %u) & ~0x%x);\n",
1640 alignment - 1, alignment - 1);
1642 if (phase == PHASE_MARSHAL)
1644 print_file(file, indent, "*(");
1645 write_type(file, var->type, NULL, var->tname);
1647 fprintf(file, " *)_StubMsg.Buffer = *");
1649 fprintf(file, " *)_StubMsg.Buffer = ");
1650 fprintf(file, varname);
1651 fprintf(file, ";\n");
1653 else if (phase == PHASE_UNMARSHAL)
1655 if (pass == PASS_IN || pass == PASS_RETURN)
1656 print_file(file, indent, "");
1658 print_file(file, indent, "*");
1659 fprintf(file, varname);
1660 if (pass == PASS_IN && var->ptr_level)
1661 fprintf(file, " = (");
1663 fprintf(file, " = *(");
1664 write_type(file, var->type, NULL, var->tname);
1665 fprintf(file, " *)_StubMsg.Buffer;\n");
1668 print_file(file, indent, "_StubMsg.Buffer += sizeof(");
1669 write_type(file, var->type, NULL, var->tname);
1670 fprintf(file, ");\n");
1673 /* returns whether the MaxCount, Offset or ActualCount members need to be
1674 * filled in for the specified phase */
1675 static inline int is_size_needed_for_phase(enum remoting_phase phase)
1677 return (phase != PHASE_UNMARSHAL);
1680 void write_remoting_arguments(FILE *file, int indent, const func_t *func,
1681 unsigned int *type_offset, enum pass pass,
1682 enum remoting_phase phase)
1684 const expr_t *length_is;
1685 const expr_t *size_is;
1686 int in_attr, out_attr, has_length, has_size, pointer_type;
1693 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1694 for (; var; *type_offset += get_size_typeformatstring_var(var), var = PREV_LINK(var))
1696 const type_t *type = var->type;
1697 unsigned char rtype;
1699 length_is = get_attrp(var->attrs, ATTR_LENGTHIS);
1700 size_is = get_attrp(var->attrs, ATTR_SIZEIS);
1701 has_length = length_is && (length_is->type != EXPR_VOID);
1702 has_size = (size_is && (size_is->type != EXPR_VOID)) || (var->array && !var->array->is_const);
1704 pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
1706 pointer_type = RPC_FC_RP;
1708 in_attr = is_attr(var->attrs, ATTR_IN);
1709 out_attr = is_attr(var->attrs, ATTR_OUT);
1710 if (!in_attr && !out_attr)
1727 rtype = ref_type(type);
1729 if (is_string_type(var->attrs, var->ptr_level, var->array))
1731 if (var->array && var->array->is_const)
1732 print_phase_function(file, indent, "NonConformantString", phase, var->name, *type_offset);
1735 if (size_is && is_size_needed_for_phase(phase))
1737 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
1738 write_expr(file, size_is, 1);
1739 fprintf(file, ";\n");
1742 if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP))
1743 print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
1745 print_phase_function(file, indent, "ConformantString", phase, var->name,
1746 *type_offset + (has_size ? 4 : 2));
1749 else if (is_array_type(var->attrs, var->ptr_level, var->array))
1751 const char *array_type;
1753 if (var->array && NEXT_LINK(var->array)) /* multi-dimensional array */
1754 array_type = "ComplexArray";
1757 if (!has_length && !has_size)
1758 array_type = "FixedArray";
1759 else if (has_length && !has_size)
1761 if (is_size_needed_for_phase(phase))
1763 print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
1764 print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
1765 write_expr(file, length_is, 1);
1766 fprintf(file, ";\n\n");
1768 array_type = "VaryingArray";
1770 else if (!has_length && has_size)
1772 if (is_size_needed_for_phase(phase) && phase != PHASE_FREE)
1774 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
1775 write_expr(file, size_is ? size_is : var->array, 1);
1776 fprintf(file, ";\n\n");
1778 array_type = "ConformantArray";
1782 if (is_size_needed_for_phase(phase))
1784 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
1785 write_expr(file, size_is ? size_is : var->array, 1);
1786 fprintf(file, ";\n");
1787 print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
1788 print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
1789 write_expr(file, length_is, 1);
1790 fprintf(file, ";\n\n");
1792 array_type = "ConformantVaryingArray";
1796 if (!in_attr && phase == PHASE_FREE)
1798 print_file(file, indent, "if (%s)\n", var->name);
1800 print_file(file, indent, "_StubMsg.pfnFree(%s);\n", var->name);
1802 else if (phase != PHASE_FREE)
1804 if (pointer_type == RPC_FC_UP)
1805 print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
1807 print_phase_function(file, indent, array_type, phase, var->name, *type_offset + 4);
1810 else if (var->ptr_level == 0 && is_base_type(rtype))
1812 print_phase_basetype(file, indent, phase, pass, var, var->name);
1814 else if (var->ptr_level == 0)
1816 const char *ndrtype;
1821 ndrtype = "SimpleStruct";
1823 case RPC_FC_CSTRUCT:
1824 case RPC_FC_CPSTRUCT:
1825 ndrtype = "ConformantStruct";
1827 case RPC_FC_CVSTRUCT:
1828 ndrtype = "ConformantVaryingStruct";
1830 case RPC_FC_BOGUS_STRUCT:
1831 ndrtype = "ComplexStruct";
1834 error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
1835 var->name, rtype, var->ptr_level);
1839 print_phase_function(file, indent, ndrtype, phase, var->name, *type_offset);
1843 if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && is_base_type(rtype))
1845 print_phase_basetype(file, indent, phase, pass, var, var->name);
1847 else if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && (rtype == RPC_FC_STRUCT))
1849 if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE)
1850 print_phase_function(file, indent, "SimpleStruct", phase, var->name, *type_offset + 4);
1854 print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
1857 fprintf(file, "\n");
1862 size_t get_size_procformatstring_var(const var_t *var)
1864 unsigned int type_offset = 2;
1865 return write_procformatstring_var(NULL, 0, var, FALSE, &type_offset);
1869 size_t get_size_typeformatstring_var(const var_t *var)
1871 unsigned int type_offset = 0;
1872 write_typeformatstring_var(NULL, 0, var, &type_offset);
1876 size_t get_size_procformatstring(const ifref_t *ifaces)
1878 const ifref_t *iface = ifaces;
1885 for (; iface; iface = PREV_LINK(iface))
1887 if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
1890 if (iface->iface->funcs)
1892 func = iface->iface->funcs;
1893 while (NEXT_LINK(func)) func = NEXT_LINK(func);
1896 /* argument list size */
1900 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1903 size += get_size_procformatstring_var(var);
1904 var = PREV_LINK(var);
1909 /* return value size */
1910 if (is_void(var->type, NULL))
1913 size += get_size_procformatstring_var(var);
1915 func = PREV_LINK(func);
1922 size_t get_size_typeformatstring(const ifref_t *ifaces)
1924 const ifref_t *iface = ifaces;
1931 for (; iface; iface = PREV_LINK(iface))
1933 if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
1936 if (iface->iface->funcs)
1938 func = iface->iface->funcs;
1939 while (NEXT_LINK(func)) func = NEXT_LINK(func);
1942 /* argument list size */
1946 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1949 size += get_size_typeformatstring_var(var);
1950 var = PREV_LINK(var);
1954 func = PREV_LINK(func);
1961 static void write_struct_expr(FILE *h, const expr_t *e, int brackets,
1962 const var_t *fields, const char *structvar)
1968 fprintf(h, "%ld", e->u.lval);
1971 fprintf(h, "0x%lx", e->u.lval);
1973 case EXPR_TRUEFALSE:
1975 fprintf(h, "FALSE");
1979 case EXPR_IDENTIFIER:
1982 for (field = fields; field; field = NEXT_LINK(field))
1984 if (!strcmp(e->u.sval, field->name))
1986 fprintf(h, "%s->%s", structvar, e->u.sval);
1990 if (!field) error("no field found for identifier %s\n", e->u.sval);
1995 write_struct_expr(h, e->ref, 1, fields, structvar);
1999 write_struct_expr(h, e->ref, 1, fields, structvar);
2003 write_struct_expr(h, e->ref, 1, fields, structvar);
2007 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
2009 write_struct_expr(h, e->ref, 1, fields, structvar);
2012 fprintf(h, "sizeof(");
2013 write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
2024 if (brackets) fprintf(h, "(");
2025 write_struct_expr(h, e->ref, 1, fields, structvar);
2027 case EXPR_SHL: fprintf(h, " << "); break;
2028 case EXPR_SHR: fprintf(h, " >> "); break;
2029 case EXPR_MUL: fprintf(h, " * "); break;
2030 case EXPR_DIV: fprintf(h, " / "); break;
2031 case EXPR_ADD: fprintf(h, " + "); break;
2032 case EXPR_SUB: fprintf(h, " - "); break;
2033 case EXPR_AND: fprintf(h, " & "); break;
2034 case EXPR_OR: fprintf(h, " | "); break;
2037 write_struct_expr(h, e->u.ext, 1, fields, structvar);
2038 if (brackets) fprintf(h, ")");
2041 if (brackets) fprintf(h, "(");
2042 write_struct_expr(h, e->ref, 1, fields, structvar);
2044 write_struct_expr(h, e->u.ext, 1, fields, structvar);
2046 write_struct_expr(h, e->ext2, 1, fields, structvar);
2047 if (brackets) fprintf(h, ")");
2052 int write_expr_eval_routines(FILE *file, const char *iface)
2055 struct expr_eval_routine *eval;
2056 unsigned short callback_offset = 0;
2058 LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
2062 print_file(file, indent, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
2063 iface, eval->structure->name, callback_offset);
2064 print_file(file, indent, "{\n");
2066 print_file(file, indent, "struct %s *" STRUCT_EXPR_EVAL_VAR " = (struct %s *)(pStubMsg->StackTop - %u);\n",
2067 eval->structure->name, eval->structure->name, eval->structure_size);
2068 fprintf(file, "\n");
2069 print_file(file, indent, "pStubMsg->Offset = 0;\n"); /* FIXME */
2070 print_file(file, indent, "pStubMsg->MaxCount = (unsigned long)");
2071 write_struct_expr(file, eval->expr, 1, eval->structure->fields, STRUCT_EXPR_EVAL_VAR);
2072 fprintf(file, ";\n");
2074 print_file(file, indent, "}\n\n");
2080 void write_expr_eval_routine_list(FILE *file, const char *iface)
2082 struct expr_eval_routine *eval;
2083 struct expr_eval_routine *cursor;
2084 unsigned short callback_offset = 0;
2086 fprintf(file, "static const EXPR_EVAL ExprEvalRoutines[] =\n");
2087 fprintf(file, "{\n");
2089 LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry)
2091 print_file(file, 1, "%s_%sExprEval_%04u,\n",
2092 iface, eval->structure->name, callback_offset);
2095 list_remove(&eval->entry);
2099 fprintf(file, "};\n\n");