vbscript: Implement case insensitive search in InStrRev function.

Signed-off-by: Dmitry Kislyuk <dimaki@rocketmail.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Dmitry Kislyuk 2020-08-07 02:41:15 -05:00 committed by Alexandre Julliard
parent 9b7311e709
commit b900567f04
2 changed files with 104 additions and 46 deletions

View File

@ -2398,61 +2398,80 @@ static HRESULT Global_StrReverse(BuiltinDisp *This, VARIANT *arg, unsigned args_
static HRESULT Global_InStrRev(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
int start, ret = 0;
int start = -1, ret = -1, mode = 0;
BSTR str1, str2;
size_t len1, len2;
HRESULT hres;
TRACE("%s %s arg_cnt=%u\n", debugstr_variant(args), debugstr_variant(args+1), args_cnt);
if(args_cnt > 3) {
FIXME("Unsupported args\n");
return E_NOTIMPL;
}
assert(2 <= args_cnt && args_cnt <= 4);
if(V_VT(args) == VT_NULL || V_VT(args+1) == VT_NULL || (args_cnt > 2 && V_VT(args+2) == VT_NULL))
if(V_VT(args) == VT_NULL || V_VT(args+1) == VT_NULL || (args_cnt > 2 && V_VT(args+2) == VT_NULL)
|| (args_cnt == 4 && V_VT(args+3) == VT_NULL))
return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
hres = to_string(args, &str1);
if(FAILED(hres))
return hres;
hres = to_string(args+1, &str2);
if(SUCCEEDED(hres)) {
if(args_cnt > 2) {
hres = to_int(args+2, &start);
if(SUCCEEDED(hres) && start <= 0) {
FIXME("Unsupported start %d\n", start);
hres = E_NOTIMPL;
}
}else {
start = SysStringLen(str1);
}
} else {
str2 = NULL;
if(args_cnt == 4) {
hres = to_int(args+3, &mode);
if(FAILED(hres))
return hres;
if (mode != 0 && mode != 1)
return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
}
if(SUCCEEDED(hres)) {
const WCHAR *ptr;
size_t len;
len = SysStringLen(str2);
if(start >= len && start <= SysStringLen(str1)) {
for(ptr = str1+start-SysStringLen(str2); ptr >= str1; ptr--) {
if(!memcmp(ptr, str2, len*sizeof(WCHAR))) {
ret = ptr-str1+1;
break;
}
}
}
if(args_cnt >= 3) {
hres = to_int(args+2, &start);
if(FAILED(hres))
return hres;
if(!start || start < -1)
return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
}
SysFreeString(str1);
SysFreeString(str2);
if(FAILED(hres))
return hres;
if(V_VT(args) != VT_BSTR) {
hres = to_string(args, &str1);
if(FAILED(hres))
return hres;
}
else
str1 = V_BSTR(args);
if(V_VT(args+1) != VT_BSTR) {
hres = to_string(args+1, &str2);
if(FAILED(hres)) {
if(V_VT(args) != VT_BSTR)
SysFreeString(str1);
return hres;
}
}
else
str2 = V_BSTR(args+1);
len1 = SysStringLen(str1);
if(!len1) {
ret = 0;
goto end;
}
if(start == -1)
start = len1;
len2 = SysStringLen(str2);
if(!len2) {
ret = start;
goto end;
}
if(start >= len2 && start <= len1) {
ret = FindStringOrdinal(FIND_FROMEND, str1, start,
str2, len2, mode);
}
ret++;
end:
if(V_VT(args) != VT_BSTR)
SysFreeString(str1);
if(V_VT(args+1) != VT_BSTR)
SysFreeString(str2);
return return_int(res, ret);
}

View File

@ -508,18 +508,57 @@ Call ok(x = 3, "InStrRev returned " & x)
x = InStrRev(1234, 34)
Call ok(x = 3, "InStrRev returned " & x)
Sub testInStrRevError(arg1, arg2, arg3, error_num)
x = InStrRev("abcd", "A", 1, 0)
Call ok(x = 0, "InStrRev returned " & x)
x = InStrRev("abcd", "A", 1, 1)
Call ok(x = 1, "InStrRev returned " & x)
x = InStrRev("abcd", "Ab", 1, 1)
Call ok(x = 0, "InStrRev returned " & x)
x = InStrRev("abcd", "Ab", -1, 1)
Call ok(x = 1, "InStrRev returned " & x)
x = InStrRev("abcd", "cd", 3, 1)
Call ok(x = 0, "InStrRev returned " & x)
x = InStrRev("abcd", "cd", 4, 1)
Call ok(x = 3, "InStrRev returned " & x)
x = InStrRev("abcd", "cd", 5, 1)
Call ok(x = 0, "InStrRev returned " & x)
x = InStrRev("abc" & Chr(0) & "A" & Chr(0) & "BC", "c", 8, 0)
Call ok(x = 3, "InStrRev returned " & x)
x = InStrRev("abc" & Chr(0) & "ABC", Chr(0) & "a", 6, 1)
Call ok(x = 4, "InStrRev returned " & x)
x = InStrRev("", "hi", 1, 0)
Call ok(x = 0, "InStrRev returned " & x)
x = InStrRev("abcd", "", 3, 1)
Call ok(x = 3, "InStrRev returned " & x)
x = InStrRev("", "", 3, 0)
Call ok(x = 0, "InStrRev returned " & x)
Sub testInStrRevError(arg1, arg2, arg3, arg4, error_num)
on error resume next
Dim x
Call Err.clear()
x = InStrRev(arg1, arg2, arg3)
x = InStrRev(arg1, arg2, arg3, arg4)
Call ok(Err.number = error_num, "Err.number = " & Err.number)
End Sub
call testInStrRevError("abcd", null, 2, 94)
call testInStrRevError(null, "abcd", 2, 94)
call testInStrRevError("abcd", "abcd", null, 94)
call testInStrRevError("abcd", null, 2, 0, 94)
call testInStrRevError(null, "abcd", 2, 0, 94)
call testInStrRevError("abcd", "abcd", null, 0, 94)
call testInStrRevError("abcd", "abcd", 2, null, 94)
call testInStrRevError("abcd", "abcd", -20, 1, 5)
Call testInStrRevError("abcd", "abcd", 2, 10, 5)
Sub TestMid(str, start, len, ex)
x = Mid(str, start, len)