Jacek Caban : jscript: Added support for RegExp.$* properties.

Alexandre Julliard julliard at winehq.org
Thu Sep 20 15:05:37 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Sep 20 15:02:55 2012 +0200

jscript: Added support for RegExp.$* properties.

---

 dlls/jscript/jscript.h       |   11 ++--
 dlls/jscript/regexp.c        |  122 ++++++++++++++++++++++++++++++++++++++++++
 dlls/jscript/tests/regexp.js |   23 ++++++++
 3 files changed, 151 insertions(+), 5 deletions(-)

diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 87d43e8..99d3863 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -299,6 +299,11 @@ typedef struct {
     jsval_t val;
 } jsexcept_t;
 
+typedef struct {
+    const WCHAR *str;
+    DWORD len;
+} match_result_t;
+
 struct _script_ctx_t {
     LONG ref;
 
@@ -321,6 +326,7 @@ struct _script_ctx_t {
     IDispatch *host_global;
 
     BSTR last_match;
+    match_result_t match_parens[9];
     DWORD last_match_index;
     DWORD last_match_length;
 
@@ -371,11 +377,6 @@ HRESULT create_vbarray_constr(script_ctx_t*,jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDE
 IUnknown *create_ax_site(script_ctx_t*) DECLSPEC_HIDDEN;
 HRESULT create_jscaller(script_ctx_t*) DECLSPEC_HIDDEN;
 
-typedef struct {
-    const WCHAR *str;
-    DWORD len;
-} match_result_t;
-
 #define REM_CHECK_GLOBAL   0x0001
 #define REM_RESET_INDEX    0x0002
 #define REM_NO_CTX_UPDATE  0x0004
diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c
index fc4be4f..b53b848 100644
--- a/dlls/jscript/regexp.c
+++ b/dlls/jscript/regexp.c
@@ -101,6 +101,16 @@ static const WCHAR leftContextW[] =
 static const WCHAR rightContextW[] =
     {'r','i','g','h','t','C','o','n','t','e','x','t',0};
 
+static const WCHAR idx1W[] = {'$','1',0};
+static const WCHAR idx2W[] = {'$','2',0};
+static const WCHAR idx3W[] = {'$','3',0};
+static const WCHAR idx4W[] = {'$','4',0};
+static const WCHAR idx5W[] = {'$','5',0};
+static const WCHAR idx6W[] = {'$','6',0};
+static const WCHAR idx7W[] = {'$','7',0};
+static const WCHAR idx8W[] = {'$','8',0};
+static const WCHAR idx9W[] = {'$','9',0};
+
 static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
 static const WCHAR emptyW[] = {0};
 
@@ -3388,6 +3398,23 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D
         }
     }
 
+    if(!(rem_flags & REM_NO_CTX_UPDATE)) {
+        DWORD i, n = min(sizeof(ctx->match_parens)/sizeof(ctx->match_parens[0]), regexp->jsregexp->parenCount);
+
+        for(i=0; i < n; i++) {
+            if(result->parens[i].index == -1) {
+                ctx->match_parens[i].str = NULL;
+                ctx->match_parens[i].len = 0;
+            }else {
+                ctx->match_parens[i].str = ctx->last_match + result->parens[i].index;
+                ctx->match_parens[i].len = result->parens[i].length;
+            }
+        }
+
+        if(n < sizeof(ctx->match_parens)/sizeof(ctx->match_parens[0]))
+            memset(ctx->match_parens+n, 0, sizeof(ctx->match_parens) - n*sizeof(ctx->match_parens[0]));
+    }
+
     matchlen = (result->cp-*cp) - gData.skipped;
     *cp = result->cp;
     ret->str = result->cp-matchlen;
@@ -4000,6 +4027,92 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str, jsval_t *
     return hres;
 }
 
+static HRESULT global_idx(script_ctx_t *ctx, DWORD flags, DWORD idx, jsval_t *r)
+{
+    switch(flags) {
+    case DISPATCH_PROPERTYGET: {
+        BSTR ret = NULL;
+
+        ret = SysAllocStringLen(ctx->match_parens[idx].str, ctx->match_parens[idx].len);
+        if(!ret)
+            return E_OUTOFMEMORY;
+
+        *r = jsval_string(ret);
+        break;
+    }
+    case DISPATCH_PROPERTYPUT:
+        break;
+    default:
+        FIXME("unsupported flags\n");
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
+static HRESULT RegExpConstr_idx1(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 0, r);
+}
+
+static HRESULT RegExpConstr_idx2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 1, r);
+}
+
+static HRESULT RegExpConstr_idx3(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 2, r);
+}
+
+static HRESULT RegExpConstr_idx4(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 3, r);
+}
+
+static HRESULT RegExpConstr_idx5(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 4, r);
+}
+
+static HRESULT RegExpConstr_idx6(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 5, r);
+}
+
+static HRESULT RegExpConstr_idx7(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 6, r);
+}
+
+static HRESULT RegExpConstr_idx8(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 7, r);
+}
+
+static HRESULT RegExpConstr_idx9(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         unsigned argc, jsval_t *argv, jsval_t *r)
+{
+    TRACE("\n");
+    return global_idx(ctx, flags, 8, r);
+}
+
 static HRESULT RegExpConstr_leftContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
          unsigned argc, jsval_t *argv, jsval_t *r)
 {
@@ -4108,6 +4221,15 @@ static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 }
 
 static const builtin_prop_t RegExpConstr_props[] = {
+    {idx1W,           RegExpConstr_idx1,           0},
+    {idx2W,           RegExpConstr_idx2,           0},
+    {idx3W,           RegExpConstr_idx3,           0},
+    {idx4W,           RegExpConstr_idx4,           0},
+    {idx5W,           RegExpConstr_idx5,           0},
+    {idx6W,           RegExpConstr_idx6,           0},
+    {idx7W,           RegExpConstr_idx7,           0},
+    {idx8W,           RegExpConstr_idx8,           0},
+    {idx9W,           RegExpConstr_idx9,           0},
     {leftContextW,    RegExpConstr_leftContext,    0},
     {rightContextW,   RegExpConstr_rightContext,   0}
 };
diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js
index 7b363dd..38d5377 100644
--- a/dlls/jscript/tests/regexp.js
+++ b/dlls/jscript/tests/regexp.js
@@ -598,4 +598,27 @@ ok(tmp === "x*y", '"x/y".replace(/[/]/, "*") = ' + tmp);
 tmp = "x/y".replace(/[xy/]/g, "*");
 ok(tmp === "***", '"x/y".replace(/[xy/]/, "*") = ' + tmp);
 
+/(b)/.exec("abc");
+ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
+ok("$2" in RegExp, "RegExp.$2 doesn't exist");
+ok(RegExp.$2 === "", "RegExp.$2 = " + RegExp.$2);
+ok(RegExp.$9 === "", "RegExp.$9 = " + RegExp.$9);
+ok(!("$10" in RegExp), "RegExp.$10 exists");
+
+/(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)/.exec("abbbbbbbbbbbc");
+ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
+ok(RegExp.$2 === "b", "[2] RegExp.$2 = " + RegExp.$2);
+ok(RegExp.$9 === "b", "RegExp.$9 = " + RegExp.$9);
+ok(!("$10" in RegExp), "RegExp.$10 exists");
+
+/(b)/.exec("abc");
+ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
+ok("$2" in RegExp, "RegExp.$2 doesn't exist");
+ok(RegExp.$2 === "", "RegExp.$2 = " + RegExp.$2);
+ok(RegExp.$9 === "", "RegExp.$9 = " + RegExp.$9);
+ok(!("$10" in RegExp), "RegExp.$10 exists");
+
+RegExp.$1 = "a";
+ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
+
 reportSuccess();




More information about the wine-cvs mailing list