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