Module: wine Branch: master Commit: 32c61c5092e76c9f50655b92880c4033fc78b3d6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=32c61c5092e76c9f50655b9288...
Author: Jacek Caban jacek@codeweavers.com Date: Wed May 26 19:18:18 2010 +0200
jscript: Store match result in script context.
---
dlls/jscript/jscript.c | 1 + dlls/jscript/jscript.h | 4 ++++ dlls/jscript/regexp.c | 23 +++++++++++++++++++++-- dlls/jscript/string.c | 27 +++++++++++++++++++++------ 4 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 9a516aa..c7c77e3 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -71,6 +71,7 @@ void script_release(script_ctx_t *ctx) return;
jsheap_free(&ctx->tmp_heap); + SysFreeString(ctx->last_match); heap_free(ctx); }
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index c58c05d..901f25d 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -272,6 +272,10 @@ struct _script_ctx_t {
IDispatch *host_global;
+ BSTR last_match; + DWORD last_match_index; + DWORD last_match_length; + DispatchEx *global; DispatchEx *function_constr; DispatchEx *activex_constr; diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c index da23f5c..c4c7225 100644 --- a/dlls/jscript/regexp.c +++ b/dlls/jscript/regexp.c @@ -3348,8 +3348,6 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D }
if(parens) { - DWORD i; - if(regexp->jsregexp->parenCount > *parens_size) { match_result_t *new_parens;
@@ -3362,6 +3360,22 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D
*parens = new_parens; } + } + + /* FIXME: We often already have a copy of input string that we could use to store last match */ + if(!(rem_flags & REM_NO_CTX_UPDATE) && + (!ctx->last_match || len != SysStringLen(ctx->last_match) || strncmpW(ctx->last_match, str, len))) { + BSTR last_match; + + last_match = SysAllocStringLen(str, len); + if(!last_match) + return E_OUTOFMEMORY; + SysFreeString(ctx->last_match); + ctx->last_match = last_match; + } + + if(parens) { + DWORD i;
*parens_cnt = regexp->jsregexp->parenCount;
@@ -3382,6 +3396,11 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D ret->len = matchlen; set_last_index(regexp, result->cp-str);
+ if(!(rem_flags & REM_NO_CTX_UPDATE)) { + ctx->last_match_index = ret->str-str; + ctx->last_match_length = matchlen; + } + return S_OK; }
diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c index 510dcc2..05b9eba 100644 --- a/dlls/jscript/string.c +++ b/dlls/jscript/string.c @@ -779,9 +779,9 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI DWORD parens_cnt = 0, parens_size=0, rep_len=0, length; BSTR rep_str = NULL, match_str = NULL, ret_str, val_str; DispatchEx *rep_func = NULL, *regexp = NULL; - match_result_t *parens = NULL, match, **parens_ptr = &parens; + match_result_t *parens = NULL, match = {NULL,0}, **parens_ptr = &parens; strbuf_t ret = {NULL,0,0}; - DWORD re_flags = 0; + DWORD re_flags = REM_NO_CTX_UPDATE; VARIANT *arg_var; HRESULT hres = S_OK;
@@ -860,7 +860,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI if(regexp) { hres = regexp_match_next(ctx, regexp, re_flags, str, length, &cp, parens_ptr, &parens_size, &parens_cnt, &match); - re_flags = REM_CHECK_GLOBAL; + re_flags |= REM_CHECK_GLOBAL;
if(hres == S_FALSE) { hres = S_OK; @@ -969,13 +969,28 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
if(rep_func) jsdisp_release(rep_func); - if(regexp) - jsdisp_release(regexp); - SysFreeString(val_str); SysFreeString(rep_str); SysFreeString(match_str); heap_free(parens);
+ if(SUCCEEDED(hres) && match.str && regexp) { + if(!val_str) + val_str = SysAllocStringLen(str, length); + if(val_str) { + SysFreeString(ctx->last_match); + ctx->last_match = val_str; + val_str = NULL; + ctx->last_match_index = match.str-str; + ctx->last_match_length = match.len; + }else { + hres = E_OUTOFMEMORY; + } + } + + if(regexp) + jsdisp_release(regexp); + SysFreeString(val_str); + if(SUCCEEDED(hres) && retv) { ret_str = SysAllocStringLen(ret.buf, ret.len); if(!ret_str)