Module: wine Branch: master Commit: 1d0f9378bc855652bf45db0e29b07fa85724dbd1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1d0f9378bc855652bf45db0e29...
Author: Dan Hipschman dsh@linux.ucla.edu Date: Wed Oct 17 18:06:26 2007 -0700
widl: Detect conformant arrays of user types correctly.
---
dlls/rpcrt4/tests/server.c | 54 ++++++++++++++++++++++++++++++++++++++++++ dlls/rpcrt4/tests/server.idl | 16 ++++++++++++ tools/widl/header.c | 4 ++- tools/widl/parser.y | 41 ++++++++++++++------------------ tools/widl/typegen.c | 16 ++++++++++++ 5 files changed, 107 insertions(+), 24 deletions(-)
diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index d8ecff0..97f2e23 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -48,6 +48,14 @@ midl_user_free(void __RPC_FAR *p) free(p); }
+static char * +xstrdup(const char *s) +{ + char *d = HeapAlloc(GetProcessHeap(), 0, strlen(s) + 1); + strcpy(d, s); + return d; +} + int s_int_return(void) { @@ -264,6 +272,26 @@ s_square_puint(puint_t p) }
int +s_sum_puints(puints_t *p) +{ + int sum = 0; + int i; + for (i = 0; i < p->n; ++i) + sum += atoi(p->ps[i]); + return sum; +} + +int +s_sum_cpuints(cpuints_t *p) +{ + int sum = 0; + int i; + for (i = 0; i < p->n; ++i) + sum += atoi(p->ps[i]); + return sum; +} + +int s_dot_copy_vectors(vector_t u, vector_t v) { return u.x * v.x + u.y * v.y + u.z * v.z; @@ -724,9 +752,35 @@ pointer_tests(void) test_list_t *list = make_list(make_list(make_list(null_list()))); test_us_t tus = {{p1}}; int *pa[4]; + puints_t pus; + cpuints_t cpus;
ok(test_list_length(list) == 3, "RPC test_list_length\n"); ok(square_puint(p1) == 121, "RPC square_puint\n"); + pus.n = 4; + pus.ps = HeapAlloc(GetProcessHeap(), 0, pus.n * sizeof pus.ps[0]); + pus.ps[0] = xstrdup("5"); + pus.ps[1] = xstrdup("6"); + pus.ps[2] = xstrdup("7"); + pus.ps[3] = xstrdup("8"); + ok(sum_puints(&pus) == 26, "RPC sum_puints\n"); + HeapFree(GetProcessHeap(), 0, pus.ps[0]); + HeapFree(GetProcessHeap(), 0, pus.ps[1]); + HeapFree(GetProcessHeap(), 0, pus.ps[2]); + HeapFree(GetProcessHeap(), 0, pus.ps[3]); + HeapFree(GetProcessHeap(), 0, pus.ps); + cpus.n = 4; + cpus.ps = HeapAlloc(GetProcessHeap(), 0, cpus.n * sizeof cpus.ps[0]); + cpus.ps[0] = xstrdup("5"); + cpus.ps[1] = xstrdup("6"); + cpus.ps[2] = xstrdup("7"); + cpus.ps[3] = xstrdup("8"); + ok(sum_cpuints(&cpus) == 26, "RPC sum_puints\n"); + HeapFree(GetProcessHeap(), 0, cpus.ps[0]); + HeapFree(GetProcessHeap(), 0, cpus.ps[1]); + HeapFree(GetProcessHeap(), 0, cpus.ps[2]); + HeapFree(GetProcessHeap(), 0, cpus.ps[3]); + HeapFree(GetProcessHeap(), 0, cpus.ps); ok(square_test_us(&tus) == 121, "RPC square_test_us\n");
pa[0] = &a[0]; diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index 6233a1f..807bf44 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -153,6 +153,22 @@ cpp_quote("#endif")
typedef [wire_marshal(int)] void *puint_t; int square_puint(puint_t p); + + typedef struct + { + [size_is(n)] puint_t *ps; + int n; + } puints_t; + + /* Same thing as puints_t, but make it complex (needs padding). */ + typedef struct + { + [size_is(n)] puint_t *ps; + char n; + } cpuints_t; + + int sum_puints(puints_t *p); + int sum_cpuints(cpuints_t *p); int dot_copy_vectors(vector_t u, vector_t v);
typedef struct wire_us *wire_us_t; diff --git a/tools/widl/header.c b/tools/widl/header.c index 2643f49..8de9b9f 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -101,7 +101,9 @@ int is_void(const type_t *t)
int is_conformant_array(const type_t *t) { - return t->type == RPC_FC_CARRAY || t->type == RPC_FC_CVARRAY; + return t->type == RPC_FC_CARRAY + || t->type == RPC_FC_CVARRAY + || (t->type == RPC_FC_BOGUS_ARRAY && t->size_is); }
void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid) diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 96e9891..6a93995 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1434,24 +1434,24 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, 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: + if (is_user_type(rt)) 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; - } + else + 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; + } } }
@@ -1859,6 +1859,7 @@ static int get_struct_type(var_list_t *fields) case RPC_FC_OP: case RPC_FC_CARRAY: case RPC_FC_CVARRAY: + case RPC_FC_BOGUS_ARRAY: has_pointer = 1; break;
@@ -1897,15 +1898,9 @@ static int get_struct_type(var_list_t *fields) /* fallthru - treat it as complex */
/* as soon as we see one of these these members, it's bogus... */ - case RPC_FC_IP: case RPC_FC_ENCAPSULATED_UNION: case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_TRANSMIT_AS: - case RPC_FC_REPRESENT_AS: - case RPC_FC_PAD: - case RPC_FC_EMBEDDED_COMPLEX: case RPC_FC_BOGUS_STRUCT: - case RPC_FC_BOGUS_ARRAY: return RPC_FC_BOGUS_STRUCT; } } diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 53ec78c..2245524 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -1744,6 +1744,22 @@ static size_t write_struct_tfs(FILE *file, type_t *type, type_t *ft = f->type; if (is_ptr(ft)) write_pointer_tfs(file, ft, tfsoff); + else if (!ft->declarray && is_conformant_array(ft)) + { + unsigned int absoff = ft->typestring_offset; + short reloff = absoff - (*tfsoff + 2); + int ptr_type = get_attrv(f->attrs, ATTR_POINTERTYPE); + /* FIXME: We need to store pointer attributes for arrays + so we don't lose pointer_default info. */ + if (ptr_type == 0) + ptr_type = RPC_FC_UP; + print_file(file, 0, "/* %d */\n", *tfsoff); + print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type, + string_of_type(ptr_type)); + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", + reloff, reloff, absoff); + *tfsoff += 4; + } } if (type->ptrdesc == *tfsoff) type->ptrdesc = 0;