vbscript: Implement case-insensitive search in Replace 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
65c37cee24
commit
3be18bb757
|
@ -2449,12 +2449,19 @@ error:
|
|||
static HRESULT Global_Replace(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
|
||||
{
|
||||
BSTR string, find = NULL, replace = NULL, ret;
|
||||
int from = 1, cnt = -1;
|
||||
int from = 1, cnt = -1, mode = 0;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
TRACE("%s %s %s %u...\n", debugstr_variant(args), debugstr_variant(args+1), debugstr_variant(args+2), args_cnt);
|
||||
|
||||
assert(3 <= args_cnt && args_cnt <= 6);
|
||||
|
||||
if(V_VT(args) == VT_NULL || V_VT(args+1) == VT_NULL || (V_VT(args+2) == VT_NULL)
|
||||
|| (args_cnt >= 4 && V_VT(args+3) == VT_NULL) || (args_cnt >= 5 && V_VT(args+4) == VT_NULL)
|
||||
|| (args_cnt == 6 && V_VT(args+5) == VT_NULL))
|
||||
return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE);
|
||||
|
||||
|
||||
if(V_VT(args) != VT_BSTR) {
|
||||
hres = to_string(args, &string);
|
||||
if(FAILED(hres))
|
||||
|
@ -2499,10 +2506,17 @@ static HRESULT Global_Replace(BuiltinDisp *This, VARIANT *args, unsigned args_cn
|
|||
}
|
||||
}
|
||||
|
||||
if(args_cnt == 6)
|
||||
FIXME("copare argument not supported\n");
|
||||
if(args_cnt == 6) {
|
||||
hres = to_int(args+5, &mode);
|
||||
if(FAILED(hres))
|
||||
goto error;
|
||||
if (mode != 0 && mode != 1) {
|
||||
hres = MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
ret = string_replace(string, find, replace, from - 1, cnt);
|
||||
ret = string_replace(string, find, replace, from - 1, cnt, mode);
|
||||
if(!ret) {
|
||||
hres = E_OUTOFMEMORY;
|
||||
}else if(res) {
|
||||
|
|
|
@ -844,6 +844,7 @@ TestRTrim "", ""
|
|||
TestRTrim 123, "123"
|
||||
if isEnglishLang then TestRTrim true, "True"
|
||||
|
||||
|
||||
sub test_replace(str, find, rep, exp)
|
||||
dim r
|
||||
r = Replace(str, find, rep)
|
||||
|
@ -865,8 +866,17 @@ sub test_replace_cnt(str, find, rep, from, cnt, exp)
|
|||
r & """ expected """ & exp & """"
|
||||
end sub
|
||||
|
||||
sub test_replace_mode(str, find, rep, from, cnt, mode, exp)
|
||||
dim r
|
||||
r = Replace(str, find, rep, from, cnt, mode)
|
||||
ok r = exp, "Replace(""" & str & """, """ & find & """, """ & rep & """, " & from & ", " & cnt & ", " & mode _
|
||||
& ") = """ & r & """ expected """ & exp & """"
|
||||
end sub
|
||||
|
||||
test_replace "xx testxx(xx)", "xx", "!", "! test!(!)"
|
||||
test_replace "", "x", "y", ""
|
||||
test_replace "xxx", "", "y", "xxx"
|
||||
test_replace "yxxy", "x", "", "yy"
|
||||
test_replace "xxxxx", "xx", "y", "yyx"
|
||||
test_replace 123, 2, 6, "163"
|
||||
test_replace "xyz" & Chr(0) & "xyz", "y", "Y", "xYz" & Chr(0) & "xYz"
|
||||
|
@ -884,6 +894,12 @@ test_replace_cnt "xx testxx(xx)", "xx", "!", 2, 1, "x test!(xx)"
|
|||
test_replace_cnt "xx testxx(xx)", "xx", "!", 1, -1, "! test!(!)"
|
||||
test_replace_cnt "xx testxx(xx)", "xx", "!", 1, 0, "xx testxx(xx)"
|
||||
|
||||
test_replace_mode "Aa testAAa(aa)", "aa", "!", 1, 2, 1, "! test!a(aa)"
|
||||
test_replace_mode "aA testaa(aa)", "AA", "!", 1, 1, 1, "! testaa(aa)"
|
||||
test_replace_mode "aa testAa(aa)", "aa", "!", 2, 2, 0, "a testAa(!)"
|
||||
test_replace_mode "aa testAA(aA)", "Aa", "!", 1, -1, 1, "! test!(!)"
|
||||
test_replace_mode "aa testaa(aa)", "A", "!", 1, -1, 1, "!! test!!(!!)"
|
||||
|
||||
on error resume next
|
||||
Replace "xx", "x", "y", -1
|
||||
x = err.number
|
||||
|
@ -902,6 +918,24 @@ x = err.number
|
|||
on error goto 0
|
||||
ok x = 5, "err = " & x
|
||||
|
||||
Sub testReplaceError(arg1, arg2, arg3, arg4, arg5, arg6, error_num)
|
||||
on error resume next
|
||||
Dim x
|
||||
|
||||
Call Err.clear()
|
||||
x = Replace(arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
Call ok(Err.number = error_num, "Err.number = " & Err.number)
|
||||
End Sub
|
||||
|
||||
Call testReplaceError(Null, "x", "y", 1, 1, 0, 94)
|
||||
Call testReplaceError("xx", null, "y", 1, 1, 0, 94)
|
||||
Call testReplaceError("xx", "x", null, 1, 1, 0, 94)
|
||||
Call testReplaceError("xx", "x", "y", null, 1, 0, 94)
|
||||
Call testReplaceError("xx", "x", "y", 1, null, 0, 94)
|
||||
Call testReplaceError("xx", "x", "y", 1, 1, null, 94)
|
||||
Call testReplaceError("xx", "x", "y", 1, 1, 8, 5)
|
||||
|
||||
|
||||
Sub TestRound(val, exval, vt)
|
||||
Call ok(Round(val) = exval, "Round(" & val & ") = " & Round(val))
|
||||
Call ok(getVT(Round(val)) = vt, "getVT(Round(" & val & ")) = " & getVT(Round(val)))
|
||||
|
|
|
@ -1629,33 +1629,36 @@ static const IRegExp2Vtbl RegExp2Vtbl = {
|
|||
RegExp2_Replace
|
||||
};
|
||||
|
||||
BSTR string_replace(BSTR string, BSTR find, BSTR replace, int from, int cnt)
|
||||
BSTR string_replace(BSTR string, BSTR find, BSTR replace, int from, int cnt, int mode)
|
||||
{
|
||||
const WCHAR *ptr, *string_end;
|
||||
strbuf_t buf = { NULL, 0, 0 };
|
||||
size_t replace_len, find_len;
|
||||
BSTR ret = NULL;
|
||||
HRESULT hres = S_OK;
|
||||
int pos;
|
||||
|
||||
string_end = string + SysStringLen(string);
|
||||
ptr = from > SysStringLen(string) ? string_end : string + from;
|
||||
|
||||
find_len = SysStringLen(find);
|
||||
replace_len = SysStringLen(replace);
|
||||
if(!replace_len)
|
||||
cnt = 0;
|
||||
|
||||
while(string_end - ptr >= find_len && cnt && find_len) {
|
||||
if(memcmp(ptr, find, find_len * sizeof(WCHAR))) {
|
||||
hres = strbuf_append(&buf, ptr, 1);
|
||||
pos = FindStringOrdinal(FIND_FROMSTART, ptr, string_end - ptr,
|
||||
find, find_len, mode);
|
||||
|
||||
if(pos == -1)
|
||||
break;
|
||||
else {
|
||||
hres = strbuf_append(&buf, ptr, pos);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
ptr++;
|
||||
}else {
|
||||
hres = strbuf_append(&buf, replace, replace_len);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
ptr += find_len;
|
||||
|
||||
ptr = ptr + pos + find_len;
|
||||
if(cnt != -1)
|
||||
cnt--;
|
||||
}
|
||||
|
|
|
@ -393,7 +393,7 @@ static inline BOOL is_digit(WCHAR c)
|
|||
}
|
||||
|
||||
HRESULT create_regexp(IDispatch**) DECLSPEC_HIDDEN;
|
||||
BSTR string_replace(BSTR,BSTR,BSTR,int,int) DECLSPEC_HIDDEN;
|
||||
BSTR string_replace(BSTR,BSTR,BSTR,int,int,int) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT map_hres(HRESULT) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
Loading…
Reference in New Issue