From 00b64430e82fd1234f64d39a4bb2b4d44e47cfb7 Mon Sep 17 00:00:00 2001 From: Dmitry Kislyuk Date: Wed, 29 Jul 2020 14:36:35 -0500 Subject: [PATCH] vbscript: Implement case insensitive comparison. Signed-off-by: Dmitry Kislyuk Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/vbscript/global.c | 42 +++++++++++++++++++++---------------- dlls/vbscript/tests/api.vbs | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c index a4442960d9e..e41c2ff7b31 100644 --- a/dlls/vbscript/global.c +++ b/dlls/vbscript/global.c @@ -1624,10 +1624,10 @@ static HRESULT Global_InStr(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, { VARIANT *startv, *str1v, *str2v; BSTR str1, str2; - int start, ret; + int ret, start = 0, mode = 0; HRESULT hres; - TRACE("\n"); + TRACE("args_cnt=%u\n", args_cnt); assert(2 <= args_cnt && args_cnt <= 4); @@ -1643,8 +1643,21 @@ static HRESULT Global_InStr(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, str2v = args+2; break; case 4: - FIXME("unsupported compare argument %s\n", debugstr_variant(args)); - return E_NOTIMPL; + startv = args; + str1v = args+1; + str2v = args+2; + + if(V_VT(args+3) == VT_NULL) + return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE); + + hres = to_int(args+3, &mode); + if(FAILED(hres)) + return hres; + + if (mode != 0 && mode != 1) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL); + + break; DEFAULT_UNREACHABLE; } @@ -1652,12 +1665,8 @@ static HRESULT Global_InStr(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, hres = to_int(startv, &start); if(FAILED(hres)) return hres; - if(--start < 0) { - FIXME("start %d\n", start); - return E_FAIL; - } - }else { - start = 0; + if(--start < 0) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL); } if(V_VT(str1v) == VT_NULL || V_VT(str2v) == VT_NULL) @@ -1675,16 +1684,13 @@ static HRESULT Global_InStr(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, } str2 = V_BSTR(str2v); - if(start < SysStringLen(str1)) { - WCHAR *ptr; + if(start >= SysStringLen(str1)) + return return_int(res, 0); - ptr = wcsstr(str1+start, str2); - ret = ptr ? ptr-str1+1 : 0; - }else { - ret = 0; - } + ret = FindStringOrdinal(FIND_FROMSTART, str1 + start, SysStringLen(str1)-start, + str2, SysStringLen(str2), mode); - return return_int(res, ret); + return return_int(res, ++ret ? ret+start : 0); } static HRESULT Global_InStrB(BuiltinDisp *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) diff --git a/dlls/vbscript/tests/api.vbs b/dlls/vbscript/tests/api.vbs index 0a65984483f..3f50195bdc3 100644 --- a/dlls/vbscript/tests/api.vbs +++ b/dlls/vbscript/tests/api.vbs @@ -390,6 +390,45 @@ Call ok(x = 2, "InStr returned " & x) x = InStr(2.6, "abcd", "bc") Call ok(x = 0, "InStr returned " & x) +x = InStr(3, "abcdefgh", "fg", 0) +Call ok(x = 6, "InStr returned " & x) + +x = InStr(3, "abcdefgh", "FG", 0) +Call ok(x = 0, "InStr returned " & x) + +x = InStr(3, "abcdefgh", "FG", 1) +Call ok(x = 6, "InStr returned " & x) + +x = InStr(3, "abcdefgh", "FG", 1.4) +Call ok(x = 6, "InStr returned " & x) + +x = InStr(3, "abcdefgh", "FG", -0.3) +Call ok(x = 0, "InStr returned " & x) + +x = InStr(1, "abcABC", "aB", 0) +Call ok(x = 0, "InStr returned " & x) + +x = InStr(1, "abcABC", "aB", 1) +Call ok(x = 1, "InStr returned " & x) + +x = InStr(2, "abcABC", "aB", 1) +Call ok(x = 4, "InStr returned " & x) + +x = InStr(5, "abcABC", "aB", 1) +Call ok(x = 0, "InStr returned " & x) + +x = InStr(2, "abcABC", "ab", 1) +Call ok(x = 4, "InStr returned " & x) + +x = InStr(6, "abcABC", "c", 1) +Call ok(x = 6, "InStr returned " & x) + +x = InStr(2, "abc" & Chr(0) & "A" & Chr(0) & "BC", "C", 0) +Call ok(x = 8, "InStr returned " & x) + +x = InStr(1, "abc" & Chr(0) & "ABC", Chr(0) & "a", 1) +Call ok(x = 4, "InStr returned " & x) + x = InStrRev("bcabcd", "bc") Call ok(x = 4, "InStrRev returned " & x)