From 132f06cd48c7ebd176649a5e00795e7a7fc67adb Mon Sep 17 00:00:00 2001 From: Dan Hipschman Date: Tue, 18 Sep 2007 15:29:59 -0700 Subject: [PATCH] widl: Implement complex arrays. --- dlls/rpcrt4/tests/server.c | 12 ++++++++++++ dlls/rpcrt4/tests/server.idl | 1 + tools/widl/parser.y | 25 ++++++++++++++++++++++--- tools/widl/typegen.c | 25 +++++++++++++++++++------ tools/widl/typegen.h | 1 + 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 2ed6de7d726..40f9a81e7f9 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -351,6 +351,12 @@ s_sum_padded(padded_t *p) } int +s_sum_padded2(padded_t ps[2]) +{ + return s_sum_padded(&ps[0]) + s_sum_padded(&ps[1]); +} + +int s_sum_bogus(bogus_t *b) { return *b->h.p1 + *b->p2 + *b->p3 + b->c; @@ -405,6 +411,7 @@ basic_tests(void) pints_t pints; ptypes_t ptypes; padded_t padded; + padded_t padded2[2]; bogus_t bogus; int i1, i2, i3, *pi2, *pi3, **ppi3; double u, v; @@ -483,6 +490,11 @@ basic_tests(void) padded.i = -3; padded.c = 8; ok(sum_padded(&padded) == 5, "RPC sum_padded\n"); + padded2[0].i = -5; + padded2[0].c = 1; + padded2[1].i = 3; + padded2[1].c = 7; + ok(sum_padded2(padded2) == 6, "RPC sum_padded2\n"); i1 = 14; i2 = -7; diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index 44bb94531f5..23ca779f528 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -207,6 +207,7 @@ interface IServer } padded_t; int sum_padded(padded_t *p); + int sum_padded2(padded_t ps[2]); typedef struct { diff --git a/tools/widl/parser.y b/tools/widl/parser.y index fbaf9a77137..46fb4390b96 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1365,9 +1365,28 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr) } } - /* if the structure is complex, then so must be the encompassing array */ - if (is_array(v->type) && (v->type->ref->type == RPC_FC_BOGUS_STRUCT)) - v->type->type = RPC_FC_BOGUS_ARRAY; + if (is_array(v->type)) + { + const type_t *rt = v->type->ref; + switch (rt->type) + { + case RPC_FC_BOGUS_STRUCT: + case RPC_FC_NON_ENCAPSULATED_UNION: + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_ENUM16: + v->type->type = RPC_FC_BOGUS_ARRAY; + break; + /* FC_RP should be above, but widl overuses these, and will break things. */ + case RPC_FC_UP: + case RPC_FC_RP: + if (rt->ref->type == RPC_FC_IP) + v->type->type = RPC_FC_BOGUS_ARRAY; + break; + default: + if (is_user_type(rt)) + v->type->type = RPC_FC_BOGUS_ARRAY; + } + } } static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface) diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index d8210658ac2..6625bda55bb 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -200,7 +200,7 @@ static type_t *get_user_type(const type_t *t, const char **pname) } } -static int is_user_type(const type_t *t) +int is_user_type(const type_t *t) { return get_user_type(t, NULL) != NULL; } @@ -1448,6 +1448,11 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type size_t start_offset; int has_pointer; int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); + unsigned int baseoff + = type->declarray && current_structure + ? type_memsize(current_structure, &align) + : 0; + if (!pointer_type) pointer_type = RPC_FC_RP; @@ -1470,10 +1475,6 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type if (type->type != RPC_FC_BOGUS_ARRAY) { unsigned char tc = type->type; - unsigned int baseoff - = type->declarray && current_structure - ? type_memsize(current_structure, &align) - : 0; if (tc == RPC_FC_LGFARRAY || tc == RPC_FC_LGVARRAY) { @@ -1530,7 +1531,19 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type write_end(file, typestring_offset); } else - error("%s: complex arrays unimplemented\n", name); + { + unsigned int dim = size_is ? 0 : type->dim; + print_file(file, 2, "NdrFcShort(0x%x),\t/* %u */\n", dim, dim); + *typestring_offset += 2; + *typestring_offset + += write_conf_or_var_desc(file, current_structure, baseoff, + size_is); + *typestring_offset + += write_conf_or_var_desc(file, current_structure, baseoff, + length_is); + write_member_type(file, type, NULL, type->ref, NULL, typestring_offset); + write_end(file, typestring_offset); + } return start_offset; } diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h index 448e5035180..fc17c19ad87 100644 --- a/tools/widl/typegen.h +++ b/tools/widl/typegen.h @@ -56,3 +56,4 @@ int decl_indirect(const type_t *t); void write_parameters_init(FILE *file, int indent, const func_t *func); void print(FILE *file, int indent, const char *format, va_list ap); int get_padding(const var_list_t *fields); +int is_user_type(const type_t *t); -- 2.11.4.GIT