Jacek Caban : jscript: Store match result in script context.

Alexandre Julliard julliard at winehq.org
Thu May 27 10:46:39 CDT 2010


Module: wine
Branch: master
Commit: 32c61c5092e76c9f50655b92880c4033fc78b3d6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=32c61c5092e76c9f50655b92880c4033fc78b3d6

Author: Jacek Caban <jacek at 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)




More information about the wine-cvs mailing list