From 07b542cc08d85144db1a6baa9f913a825d096982 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 13 Sep 2011 11:37:08 +0200 Subject: [PATCH] vbscript: Added variable value expression support. --- dlls/vbscript/interp.c | 42 ++++++++++++++++++++++++++++++++++-- dlls/vbscript/tests/lang.vbs | 1 + 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 45a7504a0a3..9dd74be2209 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -40,7 +40,8 @@ typedef HRESULT (*instr_func_t)(exec_ctx_t*); typedef enum { REF_NONE, - REF_DISP + REF_DISP, + REF_VAR } ref_type_t; typedef struct { @@ -50,6 +51,7 @@ typedef struct { IDispatch *disp; DISPID id; } d; + VARIANT *v; } u; } ref_t; @@ -59,12 +61,30 @@ typedef struct { BOOL owned; } variant_val_t; +static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *ref) +{ + while(var) { + if(!strcmpiW(var->name, name)) { + ref->type = REF_VAR; + ref->u.v = &var->v; + return TRUE; + } + + var = var->next; + } + + return FALSE; +} + static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, ref_t *ref) { named_item_t *item; DISPID id; HRESULT hres; + if(lookup_dynamic_vars(ctx->script->global_vars, name, ref)) + return S_OK; + LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) { if(item->flags & SCRIPTITEM_GLOBALMEMBERS) { hres = disp_get_id(item->disp, name, &id); @@ -210,12 +230,26 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res) vbstack_to_dp(ctx, arg_cnt, &dp); switch(ref.type) { + case REF_VAR: + if(!res) { + FIXME("REF_VAR no res\n"); + return E_NOTIMPL; + } + + if(arg_cnt) { + FIXME("arguments not implemented\n"); + return E_NOTIMPL; + } + + V_VT(res) = VT_BYREF|VT_VARIANT; + V_BYREF(res) = V_VT(ref.u.v) == (VT_VARIANT|VT_BYREF) ? V_VARIANTREF(ref.u.v) : ref.u.v; + break; case REF_DISP: hres = disp_call(ctx->script, ref.u.d.disp, ref.u.d.id, &dp, res); if(FAILED(hres)) return hres; break; - default: + case REF_NONE: FIXME("%s not found\n", debugstr_w(identifier)); return DISP_E_UNKNOWNNAME; } @@ -254,6 +288,10 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, VARIANT *val, BOOL own_v return hres; switch(ref.type) { + case REF_VAR: + FIXME("REF_VAR not implemented\n"); + hres = E_NOTIMPL; + break; case REF_DISP: hres = disp_propput(ctx->script, ref.u.d.disp, ref.u.d.id, val); if(own_val) diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 94dc3eb37ba..61a59d0cb56 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -66,6 +66,7 @@ Call ok(getVT(&hffFFffFF&) = "VT_I2", "getVT(&hffFFffFF&) is not VT_I2") Call ok(getVT(1 & 100000) = "VT_BSTR", "getVT(1 & 100000) is not VT_BSTR") Call ok(getVT(-empty) = "VT_I2", "getVT(-empty) = " & getVT(-empty)) Call ok(getVT(-null) = "VT_NULL", "getVT(-null) = " & getVT(-null)) +Call ok(getVT(y) = "VT_EMPTY*", "getVT(y) = " & getVT(y)) Call ok("ab" & "cd" = "abcd", """ab"" & ""cd"" <> ""abcd""") Call ok("ab " & null = "ab ", """ab"" & null = " & ("ab " & null))