From 59cf9c449ed04e7a8226ef66dec929a4021c2bd8 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 11 Aug 2009 14:06:52 +0200 Subject: [PATCH] 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 6695bf893cb..4cf3783b0fc 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 3e4db68c4af..4344dfe0ce1 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]);