Robert Wilhelm : vbscript: Support properties with parameters.
Alexandre Julliard
julliard at winehq.org
Wed Nov 18 15:48:01 CST 2020
Module: wine
Branch: master
Commit: a839ac952a8d5673b0aff6307cc7ecc0eabb3d99
URL: https://source.winehq.org/git/wine.git/?a=commit;h=a839ac952a8d5673b0aff6307cc7ecc0eabb3d99
Author: Robert Wilhelm <robert.wilhelm at gmx.net>
Date: Tue Nov 17 21:11:32 2020 +0100
vbscript: Support properties with parameters.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=33996
Signed-off-by: Robert Wilhelm <robert.wilhelm at gmx.net>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/vbscript/parser.y | 2 +-
dlls/vbscript/tests/lang.vbs | 21 +++++++++++++++++++++
dlls/vbscript/vbdisp.c | 35 +++++++++++++++++++++++++----------
3 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index a9f4c540fcb..8f1c1307794 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -454,7 +454,7 @@ ClassBody
PropertyDecl
: Storage_opt tPROPERTY tGET Identifier ArgumentsDecl_opt StSep BodyStatements tEND tPROPERTY
{ $$ = new_function_decl(ctx, $4, FUNC_PROPGET, $1, $5, $7); CHECK_ERROR; }
- | Storage_opt tPROPERTY tLET Identifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
+ | Storage_opt tPROPERTY tLET Identifier '(' ArgumentDeclList ')' StSep BodyStatements tEND tPROPERTY
{ $$ = new_function_decl(ctx, $4, FUNC_PROPLET, $1, $6, $9); CHECK_ERROR; }
| Storage_opt tPROPERTY tSET Identifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
{ $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; }
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 53f36b6e710..ed89906c9cf 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -1770,6 +1770,27 @@ class TestPropSyntax
end property
end class
+Class TestPropParam
+ Public oDict
+ Public Property Let Key(oldKey,newKey)
+ oDict = oldKey & newKey
+ End Property
+ Public Property Let three(uno,due,tre)
+ oDict = uno & due & tre
+ End Property
+ Public Property Let ten(a,b,c,d,e,f,g,h,i,j)
+ oDict = a & b & c & d & e & f & g & h & i & j
+ End Property
+End Class
+
+Set x = new TestPropParam
+x.key("old") = "new"
+call ok(x.oDict = "oldnew","x.oDict = " & x.oDict & " expected oldnew")
+x.three(1,2) = 3
+call ok(x.oDict = "123","x.oDict = " & x.oDict & " expected 123")
+x.ten(1,2,3,4,5,6,7,8,9) = 0
+call ok(x.oDict = "1234567890","x.oDict = " & x.oDict & " expected 1234567890")
+
set x = new TestPropSyntax
set x.prop = new TestPropSyntax
set x.prop.prop = new TestPropSyntax
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 5f493d420bd..ee4875f4e01 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -197,28 +197,43 @@ static HRESULT invoke_vbdisp(vbdisp_t *This, DISPID id, DWORD flags, BOOL extern
case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: {
DISPPARAMS dp = {NULL, NULL, 1, 0};
BOOL needs_release;
- VARIANT put_val;
+ VARIANT buf[6];
HRESULT hres;
-
- if(arg_cnt(params)) {
- FIXME("arguments not implemented\n");
- return E_NOTIMPL;
+ INT i;
+
+ dp.cArgs = arg_cnt(params) + 1;
+ if(dp.cArgs > ARRAY_SIZE(buf)) {
+ dp.rgvarg = heap_alloc(dp.cArgs*sizeof(VARIANT));
+ if(!dp.rgvarg)
+ return E_OUTOFMEMORY;
+ }else {
+ dp.rgvarg = buf;
}
- hres = get_propput_arg(This->desc->ctx, params, flags, &put_val, &needs_release);
- if(FAILED(hres))
+ hres = get_propput_arg(This->desc->ctx, params, flags, dp.rgvarg, &needs_release);
+ if(FAILED(hres)) {
+ if(dp.rgvarg != buf)
+ heap_free(dp.rgvarg);
return hres;
+ }
- dp.rgvarg = &put_val;
- func = This->desc->funcs[id].entries[V_VT(&put_val) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
+ func = This->desc->funcs[id].entries[V_VT(dp.rgvarg) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
if(!func) {
FIXME("no letter/setter\n");
+ if(dp.rgvarg != buf)
+ heap_free(dp.rgvarg);
return DISP_E_MEMBERNOTFOUND;
}
+ for(i=1; i < dp.cArgs; i++) {
+ dp.rgvarg[i]=params->rgvarg[params->cNamedArgs+i-1];
+ }
+
hres = exec_script(This->desc->ctx, extern_caller, func, This, &dp, NULL);
if(needs_release)
- VariantClear(&put_val);
+ VariantClear(dp.rgvarg);
+ if(dp.rgvarg != buf)
+ heap_free(dp.rgvarg);
return hres;
}
default:
More information about the wine-cvs
mailing list