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