Rob Shearman : widl:
Implement writing of SAFEARRAY type descriptions in typelibs.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Mar 7 15:02:31 CST 2007
Module: wine
Branch: master
Commit: 1c2a717b59ed563511ca44fbbef8ea1e9f60c1c2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1c2a717b59ed563511ca44fbbef8ea1e9f60c1c2
Author: Rob Shearman <rob at codeweavers.com>
Date: Wed Mar 7 13:32:22 2007 +0000
widl: Implement writing of SAFEARRAY type descriptions in typelibs.
---
tools/widl/parser.y | 18 ++++++++++++++----
tools/widl/typelib.c | 4 ++++
tools/widl/write_msft.c | 23 +++++++++++++++--------
3 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 0d03b03..b757c5c 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -90,7 +90,7 @@ static var_t *make_var(char *name);
static func_list_t *append_func(func_list_t *list, func_t *func);
static func_t *make_func(var_t *def, var_list_t *args);
static type_t *make_class(char *name);
-static type_t *make_safearray(void);
+static type_t *make_safearray(typeref_t *tref);
static type_t *make_builtin(char *name);
static type_t *make_int(int sign);
@@ -833,7 +833,7 @@ type: tVOID { $$ = make_tref(NULL, duptype(find_type("void", 0), 1)); }
| tSTRUCT aIDENTIFIER { $$ = make_tref(NULL, get_type(RPC_FC_STRUCT, $2, tsSTRUCT)); }
| uniondef { $$ = make_tref(NULL, $1); }
| tUNION aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsUNION)); }
- | tSAFEARRAY '(' type ')' { $$ = make_tref(NULL, make_safearray()); }
+ | tSAFEARRAY '(' type ')' { $$ = make_tref(NULL, make_safearray($3)); }
;
typedef: tTYPEDEF m_attributes type pident_list { reg_typedefs(type_ref($3), $4, $2);
@@ -1321,9 +1321,19 @@ static type_t *make_class(char *name)
return c;
}
-static type_t *make_safearray(void)
+static type_t *make_safearray(typeref_t *tref)
{
- return make_type(RPC_FC_FP, find_type("SAFEARRAY", 0));
+ const type_t *sa_orig = find_type("SAFEARRAY", 0);
+ type_t *sa = make_type(sa_orig->type, sa_orig->ref);
+ type_t *ptr;
+
+ if (sa_orig->name)
+ sa->name = strdup(sa_orig->name);
+ sa->ref = type_ref(tref);
+ ptr = make_type(RPC_FC_FP, sa);
+ ptr->name = strdup("SAFEARRAY");
+
+ return ptr;
}
#define HASHMAX 64
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
index 4e66c7b..2f8708b 100644
--- a/tools/widl/typelib.c
+++ b/tools/widl/typelib.c
@@ -181,7 +181,11 @@ unsigned short get_type_vt(type_t *t)
case RPC_FC_OP:
case RPC_FC_FP:
if(t->ref)
+ {
+ if (match(t->ref->name, "SAFEARRAY"))
+ return VT_SAFEARRAY;
return VT_PTR;
+ }
error("get_type_vt: unknown-deref-type: %d\n", t->ref->type);
break;
diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c
index 0017bd9..d3a5bf4 100644
--- a/tools/widl/write_msft.c
+++ b/tools/widl/write_msft.c
@@ -903,14 +903,22 @@ static int encode_type(
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
break;
}
-#if 0
case VT_SAFEARRAY:
- /* FIXME: Make with the error checking. */
- FIXME("SAFEARRAY vartype, may not work correctly.\n");
+ {
+ int next_vt;
+
+ /* skip over SAFEARRAY type straight to element type */
+ type = type->ref;
- ctl2_encode_typedesc(typelib, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);
+ for(next_vt = 0; type->ref; type = type->ref) {
+ next_vt = get_type_vt(type->ref);
+ if (next_vt != 0)
+ break;
+ }
+
+ encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size);
for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
@@ -934,16 +942,15 @@ static int encode_type(
typedata[1] = target_type;
}
- *encoded_tdesc = typeoffset;
+ *encoded_type = typeoffset;
*width = 4;
*alignment = 4;
- *decoded_size = sizeof(TYPEDESC) + child_size;
+ *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
break;
+ }
-#endif
-
case VT_USERDEFINED:
{
int typeinfo_offset;
More information about the wine-cvs
mailing list