From: Shuai Meng Subject: [PATCH] vbscript: Implemented String Message-Id: <5443DC66.1030309@gmail.com> Date: Sun, 19 Oct 2014 23:44:38 +0800 --- dlls/vbscript/global.c | 61 +++++++++++++++++++++++++++++++++++++++++++-- dlls/vbscript/tests/api.vbs | 30 ++++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c index bbbe22c..a32d563 100644 --- a/dlls/vbscript/global.c +++ b/dlls/vbscript/global.c @@ -156,6 +156,20 @@ static inline HRESULT return_date(VARIANT *res, double date) return S_OK; } +HRESULT to_short(VARIANT *v, short *ret) +{ + VARIANT r; + HRESULT hres; + + V_VT(&r) = VT_EMPTY; + hres = VariantChangeType(&r, v, 0, VT_I2); + if(FAILED(hres)) + return hres; + + *ret = V_I2(&r); + return S_OK; +} + HRESULT to_int(VARIANT *v, int *ret) { VARIANT r; @@ -1176,8 +1190,51 @@ static HRESULT Global_Space(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VAR static HRESULT Global_String(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) { - FIXME("\n"); - return E_NOTIMPL; + HRESULT hres; + short i, len, tmp; + BSTR str, newstr; + + TRACE("%s\n", debugstr_variant(arg)); + assert(args_cnt == 2); + + if(V_VT(arg) == VT_NULL) + return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE); + + str = SysAllocStringLen(NULL, 1023); + newstr = SysAllocStringLen(NULL, 1023); + if(!str || !newstr) + return E_OUTOFMEMORY; + + + switch(V_VT(arg + 1)) { + case VT_NULL: + return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE); + case VT_BSTR: + str = V_BSTR(arg + 1); + break; + case VT_ARRAY|VT_BYREF|VT_VARIANT: + return DISP_E_TYPEMISMATCH; + default: + hres = to_short(arg + 1, &tmp); + if(FAILED(hres)) + return hres; + str[0] = (char)tmp; + break; + } + + hres = to_short(arg, &len); + if(FAILED(hres)) + return hres; + if(len < 0) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL); + else if(len == 0) + newstr = '\0'; + else if(len > 1023) + len = 1023; + + for(i = 0; i < len; i++) + newstr[i] = str[0]; + return return_bstr(res, newstr); } static HRESULT Global_InStr(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res) diff --git a/dlls/vbscript/tests/api.vbs b/dlls/vbscript/tests/api.vbs index 1b68d2e..1cfcf6a 100644 --- a/dlls/vbscript/tests/api.vbs +++ b/dlls/vbscript/tests/api.vbs @@ -1266,4 +1266,34 @@ Call testRGBError(&h4d&, -2, &h2f&, 5) Call ok(getVT(Timer) = "VT_R4", "getVT(Timer) = " & getVT(Timer)) +Sub testStringError(arg1, arg2, error_num) + on error resume next + Dim x + + Call Err.clear() + x = String(arg1, arg2) + Call ok(Err.number = error_num, "Err.number1 = " & Err.number) + + Call Err.clear() + Call String(arg1, arg2) + Call ok(Err.number = error_num, "Err.number2 = " & Err.number) +End Sub +Dim iarray(2,3) +Call ok(String(3, "abcd") = "aaa", "String(3, ""abcd"") = " & String(3, "abcd")) +Call ok(getVT(String(3, "abcd")) = "VT_BSTR", "getVT(String(3, ""abcd"")) = " & getVT(String(3, "abcd"))) +Call ok(String(0, "abcd") = "", "String(0, ""abcd"") = " & String(0, "abcd")) +Call ok(getVT(String(0, "abcd")) = "VT_BSTR", "getVT(String(0, ""abcd"")) = " & getVT(String(0, "abcd"))) +Call ok(String(1, 65) = "A", "String(1, 65) = " & String(1, 65)) +Call ok(getVT(String(1, 65)) = "VT_BSTR", "getVT(String(1, 65)) = " & getVT(String(1, 65))) +Call ok(String(1, 65.49) = "A", "String(1, 65.49) = " & String(1, 65.49)) +Call ok(getVT(String(1, 65.49)) = "VT_BSTR", "getVT(String(1, 65.49)) = " & getVT(String(1, 65.49))) +Call ok(String(1, 65.5) = "B", "String(1, 65.5) = " & String(1, 65.5)) +Call ok(getVT(String(1, 65.5)) = "VT_BSTR", "getVT(String(1, 65.5)) = " & getVT(String(1, 65.5))) +Call ok(String(1, 66.5) = "B", "String(1, 66.5) = " & String(1, 66.5)) +Call ok(getVT(String(1, 66.5)) = "VT_BSTR", "getVT(String(1, 66.5)) = " & getVT(String(1, 66.5))) +Call testStringError(2, iarray, 13) +Call testStringError(-1, "w", 5) +Call testStringError(2, Null, 94) +Call testStringError(Null, "f", 94) + Call reportSuccess()