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)
|
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;
|
BSTR str1, str2;
|
||||||
|
size_t len1, len2;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("%s %s arg_cnt=%u\n", debugstr_variant(args), debugstr_variant(args+1), args_cnt);
|
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);
|
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);
|
return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
|
||||||
|
|
||||||
hres = to_string(args, &str1);
|
if(args_cnt == 4) {
|
||||||
if(FAILED(hres))
|
hres = to_int(args+3, &mode);
|
||||||
return hres;
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
hres = to_string(args+1, &str2);
|
if (mode != 0 && mode != 1)
|
||||||
if(SUCCEEDED(hres)) {
|
return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
|
||||||
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)) {
|
if(args_cnt >= 3) {
|
||||||
const WCHAR *ptr;
|
hres = to_int(args+2, &start);
|
||||||
size_t len;
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
len = SysStringLen(str2);
|
if(!start || start < -1)
|
||||||
if(start >= len && start <= SysStringLen(str1)) {
|
return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
|
||||||
for(ptr = str1+start-SysStringLen(str2); ptr >= str1; ptr--) {
|
|
||||||
if(!memcmp(ptr, str2, len*sizeof(WCHAR))) {
|
|
||||||
ret = ptr-str1+1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SysFreeString(str1);
|
if(V_VT(args) != VT_BSTR) {
|
||||||
SysFreeString(str2);
|
hres = to_string(args, &str1);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return 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);
|
return return_int(res, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -508,18 +508,57 @@ Call ok(x = 3, "InStrRev returned " & x)
|
||||||
x = InStrRev(1234, 34)
|
x = InStrRev(1234, 34)
|
||||||
Call ok(x = 3, "InStrRev returned " & x)
|
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
|
on error resume next
|
||||||
Dim x
|
Dim x
|
||||||
|
|
||||||
Call Err.clear()
|
Call Err.clear()
|
||||||
x = InStrRev(arg1, arg2, arg3)
|
x = InStrRev(arg1, arg2, arg3, arg4)
|
||||||
Call ok(Err.number = error_num, "Err.number = " & Err.number)
|
Call ok(Err.number = error_num, "Err.number = " & Err.number)
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
call testInStrRevError("abcd", null, 2, 94)
|
call testInStrRevError("abcd", null, 2, 0, 94)
|
||||||
call testInStrRevError(null, "abcd", 2, 94)
|
call testInStrRevError(null, "abcd", 2, 0, 94)
|
||||||
call testInStrRevError("abcd", "abcd", null, 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)
|
Sub TestMid(str, start, len, ex)
|
||||||
x = Mid(str, start, len)
|
x = Mid(str, start, len)
|
||||||
|
|
Loading…
Reference in New Issue