Jacek Caban : vbscript: Allow creating RegExp object by new expression.

Alexandre Julliard julliard at winehq.org
Tue Mar 18 14:15:06 CDT 2014


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Mar 18 15:52:13 2014 +0100

vbscript: Allow creating RegExp object by new expression.

---

 dlls/vbscript/interp.c         |   11 +++++++++++
 dlls/vbscript/tests/lang.vbs   |   12 ++++++++++++
 dlls/vbscript/tests/regexp.vbs |    6 ++++++
 dlls/vbscript/vbregexp.c       |   36 ++++++++++++++++++++++++------------
 dlls/vbscript/vbscript.h       |    2 ++
 5 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 066d675..bc3e940 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -975,8 +975,19 @@ static HRESULT interp_new(exec_ctx_t *ctx)
     VARIANT v;
     HRESULT hres;
 
+    static const WCHAR regexpW[] = {'r','e','g','e','x','p',0};
+
     TRACE("%s\n", debugstr_w(arg));
 
+    if(!strcmpiW(arg, regexpW)) {
+        V_VT(&v) = VT_DISPATCH;
+        hres = create_regexp(&V_DISPATCH(&v));
+        if(FAILED(hres))
+            return hres;
+
+        return stack_push(ctx, &v);
+    }
+
     for(class_desc = ctx->script->classes; class_desc; class_desc = class_desc->next) {
         if(!strcmpiW(class_desc->name, arg))
             break;
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 612c615..d3e8318 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -1132,4 +1132,16 @@ Call testarrarg(1, "VT_I2*")
 Call testarrarg(false, "VT_BOOL*")
 Call testarrarg(Empty, "VT_EMPTY*")
 
+' It's allowed to declare non-builtin RegExp class...
+class RegExp
+     public property get Global()
+         Call ok(false, "Global called")
+         Global = "fail"
+     end property
+end class
+
+' ...but there is no way to use it because builtin instance is always created
+set x = new RegExp
+Call ok(x.Global = false, "x.Global = " & x.Global)
+
 reportSuccess()
diff --git a/dlls/vbscript/tests/regexp.vbs b/dlls/vbscript/tests/regexp.vbs
index 72fa108..0354fb7 100644
--- a/dlls/vbscript/tests/regexp.vbs
+++ b/dlls/vbscript/tests/regexp.vbs
@@ -168,4 +168,10 @@ Call ok(submatch.Count = 2, "submatch.Count = " & submatch.Count)
 Call ok(submatch.Item(0) = "a", "submatch.Item(0) = " & submatch.Item(0))
 Call ok(submatch.Item(1) = "b", "submatch.Item(0) = " & submatch.Item(1))
 
+Set x = new regexp
+Call ok(x.Pattern = "", "RegExp.Pattern = " & x.Pattern)
+Call ok(x.IgnoreCase = false, "RegExp.IgnoreCase = " & x.IgnoreCase)
+Call ok(x.Global = false, "RegExp.Global = " & x.Global)
+Call ok(x.Multiline = false, "RegExp.Multiline = " & x.Multiline)
+
 Call reportSuccess()
diff --git a/dlls/vbscript/vbregexp.c b/dlls/vbscript/vbregexp.c
index ada364f..0a399b9 100644
--- a/dlls/vbscript/vbregexp.c
+++ b/dlls/vbscript/vbregexp.c
@@ -1599,29 +1599,41 @@ static IRegExpVtbl RegExpVtbl = {
     RegExp_Replace
 };
 
-HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppv)
+HRESULT create_regexp(IDispatch **ret)
 {
-    RegExp2 *ret;
+    RegExp2 *regexp;
     HRESULT hres;
 
-    TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppv);
-
     hres = init_regexp_typeinfo(RegExp2_tid);
     if(FAILED(hres))
         return hres;
 
-    ret = heap_alloc_zero(sizeof(*ret));
-    if(!ret)
+    regexp = heap_alloc_zero(sizeof(*regexp));
+    if(!regexp)
         return E_OUTOFMEMORY;
 
-    ret->IRegExp2_iface.lpVtbl = &RegExp2Vtbl;
-    ret->IRegExp_iface.lpVtbl = &RegExpVtbl;
+    regexp->IRegExp2_iface.lpVtbl = &RegExp2Vtbl;
+    regexp->IRegExp_iface.lpVtbl = &RegExpVtbl;
+    regexp->ref = 1;
+    heap_pool_init(&regexp->pool);
 
-    ret->ref = 1;
-    heap_pool_init(&ret->pool);
+    *ret = (IDispatch*)&regexp->IRegExp2_iface;
+    return S_OK;
+}
+
+HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppv)
+{
+    IDispatch *regexp;
+    HRESULT hres;
+
+    TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppv);
+
+    hres = create_regexp(&regexp);
+    if(FAILED(hres))
+        return hres;
 
-    hres = IRegExp2_QueryInterface(&ret->IRegExp2_iface, riid, ppv);
-    IRegExp2_Release(&ret->IRegExp2_iface);
+    hres = IDispatch_QueryInterface(regexp, riid, ppv);
+    IDispatch_Release(regexp);
     return hres;
 }
 
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 94139bb..bf7a17c 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -382,6 +382,8 @@ static inline BOOL is_int32(double d)
     return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d;
 }
 
+HRESULT create_regexp(IDispatch**) DECLSPEC_HIDDEN;
+
 HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
 HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
 




More information about the wine-cvs mailing list