Jacek Caban : widl: Allow defaultvalue() attribute on any pointer type.

Alexandre Julliard julliard at winehq.org
Fri Aug 24 13:59:16 CDT 2018


Module: wine
Branch: master
Commit: bc6c2eb907e90cf29abcedb77f4bb840abea0231
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=bc6c2eb907e90cf29abcedb77f4bb840abea0231

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Aug 24 12:12:02 2018 +0200

widl: Allow defaultvalue() attribute on any pointer type.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 tools/widl/write_msft.c | 130 +++++++++++++++++++++---------------------------
 1 file changed, 56 insertions(+), 74 deletions(-)

diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c
index 98a788c..913e1a6 100644
--- a/tools/widl/write_msft.c
+++ b/tools/widl/write_msft.c
@@ -1160,39 +1160,17 @@ static unsigned int get_ulong_val(unsigned int val, int vt)
 
 static void write_int_value(msft_typelib_t *typelib, int *out, int vt, int value)
 {
-    switch(vt) {
-    case VT_I2:
-    case VT_I4:
-    case VT_R4:
-    case VT_BOOL:
-    case VT_I1:
-    case VT_UI1:
-    case VT_UI2:
-    case VT_UI4:
-    case VT_INT:
-    case VT_UINT:
-    case VT_HRESULT:
-    case VT_PTR:
-    case VT_UNKNOWN:
-    case VT_DISPATCH:
-      {
-        const unsigned int lv = get_ulong_val(value, vt);
-        if((lv & 0x3ffffff) == lv) {
-            *out = 0x80000000;
-            *out |= vt << 26;
-            *out |= lv;
-        } else {
-            int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0);
-            *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
-            memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &value, 4);
-            *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757;
-            *out = offset;
-        }
-        return;
-      }
-
-    default:
-        warning("can't write value of type %d yet\n", vt);
+    const unsigned int lv = get_ulong_val(value, vt);
+    if ((lv & 0x3ffffff) == lv) {
+        *out = 0x80000000;
+        *out |= vt << 26;
+        *out |= lv;
+    } else {
+        int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0);
+        *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
+        memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &value, 4);
+        *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757;
+        *out = offset;
     }
 }
 
@@ -1211,6 +1189,50 @@ static void write_string_value(msft_typelib_t *typelib, int *out, const char *va
     *out = offset;
 }
 
+static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *expr, int *out)
+{
+    int vt;
+
+    if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT) {
+        if (get_type_vt(type) != VT_BSTR)
+            error("string default value applied to non-string type\n");
+        chat("default value '%s'\n", expr->u.sval);
+        write_string_value(typelib, out, expr->u.sval);
+        return;
+    }
+
+    if (type_get_type(type) == TYPE_ENUM) {
+        vt = VT_I4;
+    } else if (is_ptr(type)) {
+        vt = get_type_vt(type_pointer_get_ref(type));
+        if (vt == VT_USERDEFINED)
+            vt = VT_I4;
+        if (expr->cval)
+            warning("non-null pointer default value\n");
+    } else {
+        vt = get_type_vt(type);
+        switch(vt) {
+        case VT_I2:
+        case VT_I4:
+        case VT_R4:
+        case VT_BOOL:
+        case VT_I1:
+        case VT_UI1:
+        case VT_UI2:
+        case VT_UI4:
+        case VT_INT:
+        case VT_UINT:
+        case VT_HRESULT:
+            break;
+        default:
+            warning("can't write value of type %d yet\n", vt);
+            return;
+        }
+    }
+
+    write_int_value(typelib, out, vt, expr->cval);
+}
+
 static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
                             int vt, const void *value, int *offset)
 {
@@ -1242,33 +1264,6 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
     return S_OK;
 }
 
-/* It's possible to have a default value for pointer arguments too.
-   In this case default value has a referenced type, e.g.
-   'LONG*' argument gets VT_I4, 'DOUBLE*' - VT_R8. IUnknown* and IDispatch*
-   are recognised too and stored as VT_UNKNOWN and VT_DISPATCH.
-   But IUnknown/IDispatch arguments can only have default value of 0
-   (or expression that resolves to zero) while other pointers can have
-   any default value. */
-static int get_defaultvalue_vt(type_t *type)
-{
-    int vt;
-    if (type_get_type(type) == TYPE_ENUM)
-        vt = VT_I4;
-    else
-   {
-        vt = get_type_vt(type);
-        if (vt == VT_PTR && is_ptr(type)) {
-            vt = get_type_vt(type_pointer_get_ref(type));
-            /* The only acceptable value for pointers to non-basic types
-               is NULL, it's stored as VT_I4 for both 32 and 64 bit typelibs. */
-            if (vt == VT_USERDEFINED)
-                vt = VT_I4;
-        }
-    }
-
-    return vt;
-}
-
 static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
 {
     int offset, name_offset;
@@ -1492,21 +1487,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
             switch(attr->type) {
             case ATTR_DEFAULTVALUE:
               {
-                int vt;
-                expr_t *expr = (expr_t *)attr->u.pval;
-                vt = get_defaultvalue_vt(arg->type);
                 paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
-                if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT)
-                {
-                  if (vt != VT_BSTR) error("string default value applied to non-string type\n");
-                  chat("default value '%s'\n", expr->u.sval);
-                  write_string_value(typeinfo->typelib, defaultdata, expr->u.sval);
-                }
-                else
-                {
-                  chat("default value %d\n", expr->cval);
-                  write_int_value(typeinfo->typelib, defaultdata, vt, expr->cval);
-                }
+                write_default_value(typeinfo->typelib, arg->type, (expr_t *)attr->u.pval, defaultdata);
                 break;
               }
             case ATTR_IN:




More information about the wine-cvs mailing list