diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 066d675fd1b..bc3e940e11c 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 612c615fb69..d3e83183b50 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 72fa108a7e0..0354fb77f44 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 ada364f34cc..0a399b98525 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(®exp->pool); - ret->ref = 1; - heap_pool_init(&ret->pool); + *ret = (IDispatch*)®exp->IRegExp2_iface; + return S_OK; +} - hres = IRegExp2_QueryInterface(&ret->IRegExp2_iface, riid, ppv); - IRegExp2_Release(&ret->IRegExp2_iface); +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(®exp); + if(FAILED(hres)) + return hres; + + hres = IDispatch_QueryInterface(regexp, riid, ppv); + IDispatch_Release(regexp); return hres; } diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 94139bb34d5..bf7a17c0364 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;