jscript: Store match result in script context.

This commit is contained in:
Jacek Caban 2010-05-26 19:18:18 +02:00 committed by Alexandre Julliard
parent fe86330d7e
commit 32c61c5092
4 changed files with 47 additions and 8 deletions

View File

@ -71,6 +71,7 @@ void script_release(script_ctx_t *ctx)
return;
jsheap_free(&ctx->tmp_heap);
SysFreeString(ctx->last_match);
heap_free(ctx);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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)