Piotr Caban : jscript: Added $ handling to String.replace.
Alexandre Julliard
julliard at winehq.org
Tue Aug 11 10:47:37 CDT 2009
Module: wine
Branch: master
Commit: 59cf9c449ed04e7a8226ef66dec929a4021c2bd8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=59cf9c449ed04e7a8226ef66dec929a4021c2bd8
Author: Piotr Caban <piotr.caban at gmail.com>
Date: Tue Aug 11 14:06:52 2009 +0200
jscript: Added $ handling to String.replace.
---
dlls/jscript/string.c | 69 +++++++++++++++++++++++++++++++++++++----
dlls/jscript/tests/regexp.js | 33 ++++++++++++++++++++
2 files changed, 95 insertions(+), 7 deletions(-)
diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c
index 6695bf8..4cf3783 100644
--- a/dlls/jscript/string.c
+++ b/dlls/jscript/string.c
@@ -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))
diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js
index 3e4db68..4344dfe 100644
--- a/dlls/jscript/tests/regexp.js
+++ b/dlls/jscript/tests/regexp.js
@@ -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]);
More information about the wine-cvs
mailing list