jscript: Added $ handling to String.replace.

This commit is contained in:
Piotr Caban 2009-08-11 14:06:52 +02:00 committed by Alexandre Julliard
parent 01128fa35b
commit 59cf9c449e
2 changed files with 95 additions and 7 deletions

View File

@ -802,7 +802,7 @@ static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
DWORD parens_cnt = 0, parens_size=0, rep_len=0, length;
BSTR rep_str = NULL, match_str = NULL, ret_str, val_str = NULL;
DispatchEx *rep_func = NULL, *regexp = NULL;
match_result_t *parens = NULL, match;
match_result_t *parens = NULL, match, **parens_ptr = &parens;
strbuf_t ret = {NULL,0,0};
BOOL gcheck = FALSE;
VARIANT *arg_var;
@ -884,12 +884,9 @@ static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
if(FAILED(hres))
break;
if(strchrW(rep_str, '$')) {
FIXME("unsupported $ in replace string\n");
hres = E_NOTIMPL;
}
rep_len = SysStringLen(rep_str);
if(!strchrW(rep_str, '$'))
parens_ptr = NULL;
}
}
@ -900,7 +897,7 @@ static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
while(1) {
if(regexp) {
hres = regexp_match_next(regexp, gcheck, str, length, &cp, rep_func ? &parens : NULL,
hres = regexp_match_next(regexp, gcheck, str, length, &cp, parens_ptr,
&parens_size, &parens_cnt, &match);
gcheck = TRUE;
@ -934,6 +931,64 @@ static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
SysFreeString(cstr);
if(FAILED(hres))
break;
}else if(rep_str && regexp) {
const WCHAR *ptr = rep_str, *ptr2;
while((ptr2 = strchrW(ptr, '$'))) {
hres = strbuf_append(&ret, ptr, ptr2-ptr);
if(FAILED(hres))
break;
switch(ptr2[1]) {
case '$':
hres = strbuf_append(&ret, ptr2, 1);
ptr = ptr2+2;
break;
case '&':
hres = strbuf_append(&ret, match.str, match.len);
ptr = ptr2+2;
break;
case '`':
hres = strbuf_append(&ret, str, match.str-str);
ptr = ptr2+2;
break;
case '\'':
hres = strbuf_append(&ret, ecp, (str+length)-ecp);
ptr = ptr2+2;
break;
default: {
DWORD idx;
if(!isdigitW(ptr2[1])) {
hres = strbuf_append(&ret, ptr2, 1);
ptr = ptr2+1;
break;
}
idx = ptr2[1] - '0';
if(isdigitW(ptr[3]) && idx*10 + (ptr[2]-'0') <= parens_cnt) {
idx = idx*10 + (ptr[2]-'0');
ptr = ptr2+3;
}else if(idx && idx <= parens_cnt) {
ptr = ptr2+2;
}else {
hres = strbuf_append(&ret, ptr2, 1);
ptr = ptr2+1;
break;
}
hres = strbuf_append(&ret, parens[idx-1].str, parens[idx-1].len);
}
}
if(FAILED(hres))
break;
}
if(SUCCEEDED(hres))
hres = strbuf_append(&ret, ptr, (rep_str+rep_len)-ptr);
if(FAILED(hres))
break;
}else if(rep_str) {
hres = strbuf_append(&ret, rep_str, rep_len);
if(FAILED(hres))

View File

@ -158,6 +158,39 @@ function replaceFunc2(m, subm, off, str) {
r = "[test1] [test2]".replace(/\[([^\[]+)\]/g, replaceFunc2);
ok(r === "r0 r1", "r = '" + r + "' expected 'r0 r1'");
r = "$1,$2".replace(/(\$(\d))/g, "$$1-$1$2");
ok(r === "$1-$11,$1-$22", "r = '" + r + "' expected '$1-$11,$1-$22'");
r = "abc &1 123".replace(/(\&(\d))/g, "$&");
ok(r === "abc &1 123", "r = '" + r + "' expected 'abc &1 123'");
r = "abc &1 123".replace(/(\&(\d))/g, "$'");
ok(r === "abc 123 123", "r = '" + r + "' expected 'abc 123 123'");
r = "abc &1 123".replace(/(\&(\d))/g, "$`");
ok(r === "abc abc 123", "r = '" + r + "' expected 'abc abc 123'");
r = "abc &1 123".replace(/(\&(\d))/g, "$3");
ok(r === "abc $3 123", "r = '" + r + "' expected 'abc $3 123'");
r = "abc &1 123".replace(/(\&(\d))/g, "$");
ok(r === "abc $ 123", "r = '" + r + "' expected 'abc $ 123'");
r = "abc &1 123".replace(/(\&(\d))/g, "$a");
ok(r === "abc $a 123", "r = '" + r + "' expected 'abc $a 123'");
r = "abc &1 123".replace(/(\&(\d))/g, "$11");
ok(r === "abc &11 123", "r = '" + r + "' expected 'abc &11 123'");
r = "abc &1 123".replace(/(\&(\d))/g, "$0");
ok(r === "abc $0 123", "r = '" + r + "' expected 'abc $0 123'");
r = "1 2 3".replace("2", "$&");
ok(r === "1 $& 3", "r = '" + r + "' expected '1 $& 3'");
r = "1 2 3".replace("2", "$'");
ok(r === "1 $' 3", "r = '" + r + "' expected '1 $' 3'");
r = "1,,2,3".split(/,+/g);
ok(r.length === 3, "r.length = " + r.length);
ok(r[0] === "1", "r[0] = " + r[0]);