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:
parent
9b7311e709
commit
b900567f04
|
@ -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);
|
||||
|
||||
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(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);
|
||||
}
|
||||
|
||||
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(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(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(FAILED(hres)) {
|
||||
if(V_VT(args) != VT_BSTR)
|
||||
SysFreeString(str1);
|
||||
SysFreeString(str2);
|
||||
if(FAILED(hres))
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue