Dan Hipschman : widl: Implement complex arrays.
Alexandre Julliard
julliard at winehq.org
Wed Sep 19 08:16:14 CDT 2007
Module: wine
Branch: master
Commit: 132f06cd48c7ebd176649a5e00795e7a7fc67adb
URL: http://source.winehq.org/git/wine.git/?a=commit;h=132f06cd48c7ebd176649a5e00795e7a7fc67adb
Author: Dan Hipschman <dsh at linux.ucla.edu>
Date: Tue Sep 18 15:29:59 2007 -0700
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 2ed6de7..40f9a81 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 44bb945..23ca779 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 fbaf9a7..46fb439 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 d821065..6625bda 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 448e503..fc17c19 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);
More information about the wine-cvs
mailing list