Jacek Caban : jscript: Added RegExp.exec implementation.
Alexandre Julliard
julliard at winehq.org
Fri Aug 28 10:17:46 CDT 2009
Module: wine
Branch: master
Commit: 132009469c4f7f275b1b5deb1b48a11ace46373e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=132009469c4f7f275b1b5deb1b48a11ace46373e
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Aug 27 21:34:01 2009 +0200
jscript: Added RegExp.exec implementation.
---
dlls/jscript/regexp.c | 144 +++++++++++++++++++++++++++++++++++++++++-
dlls/jscript/tests/regexp.js | 51 +++++++++++++++-
2 files changed, 192 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c
index 754de36..5c473d4 100644
--- a/dlls/jscript/regexp.c
+++ b/dlls/jscript/regexp.c
@@ -3496,11 +3496,151 @@ static HRESULT RegExp_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA
return E_NOTIMPL;
}
+static HRESULT create_match_array(script_ctx_t *ctx, BSTR input, const match_result_t *result,
+ const match_result_t *parens, DWORD parens_cnt, LCID lcid, jsexcept_t *ei, IDispatch **ret)
+{
+ DispatchEx *array;
+ VARIANT var;
+ int i;
+ HRESULT hres = S_OK;
+
+ static const WCHAR indexW[] = {'i','n','d','e','x',0};
+ static const WCHAR inputW[] = {'i','n','p','u','t',0};
+ static const WCHAR zeroW[] = {'0',0};
+
+ hres = create_array(ctx, parens_cnt+1, &array);
+ if(FAILED(hres))
+ return hres;
+
+ for(i=0; i < parens_cnt; i++) {
+ V_VT(&var) = VT_BSTR;
+ V_BSTR(&var) = SysAllocStringLen(parens[i].str, parens[i].len);
+ if(!V_BSTR(&var)) {
+ hres = E_OUTOFMEMORY;
+ break;
+ }
+
+ hres = jsdisp_propput_idx(array, i+1, lcid, &var, ei, NULL/*FIXME*/);
+ SysFreeString(V_BSTR(&var));
+ if(FAILED(hres))
+ break;
+ }
+
+ while(SUCCEEDED(hres)) {
+ V_VT(&var) = VT_I4;
+ V_I4(&var) = result->str-input;
+ hres = jsdisp_propput_name(array, indexW, lcid, &var, ei, NULL/*FIXME*/);
+ if(FAILED(hres))
+ break;
+
+ V_VT(&var) = VT_BSTR;
+ V_BSTR(&var) = input;
+ hres = jsdisp_propput_name(array, inputW, lcid, &var, ei, NULL/*FIXME*/);
+ if(FAILED(hres))
+ break;
+
+ V_BSTR(&var) = SysAllocStringLen(result->str, result->len);
+ if(!V_BSTR(&var)) {
+ hres = E_OUTOFMEMORY;
+ break;
+ }
+ hres = jsdisp_propput_name(array, zeroW, lcid, &var, ei, NULL/*FIXME*/);
+ SysFreeString(V_BSTR(&var));
+ break;
+ }
+
+ if(FAILED(hres)) {
+ jsdisp_release(array);
+ return hres;
+ }
+
+ *ret = (IDispatch*)_IDispatchEx_(array);
+ return S_OK;
+}
+
+static HRESULT run_exec(DispatchEx *dispex, VARIANT *arg, LCID lcid, jsexcept_t *ei, BSTR *input,
+ match_result_t *match, match_result_t **parens, DWORD *parens_cnt, VARIANT_BOOL *ret)
+{
+ RegExpInstance *regexp;
+ DWORD parens_size = 0, last_index = 0, length;
+ const WCHAR *cp;
+ BSTR string;
+ HRESULT hres;
+
+ if(!is_class(dispex, JSCLASS_REGEXP)) {
+ FIXME("Not a RegExp\n");
+ return E_NOTIMPL;
+ }
+
+ regexp = (RegExpInstance*)dispex;
+
+ if(arg) {
+ hres = to_string(regexp->dispex.ctx, arg, ei, &string);
+ if(FAILED(hres))
+ return hres;
+ }else {
+ string = SysAllocStringLen(NULL, 0);
+ if(!string)
+ return E_OUTOFMEMORY;
+ }
+
+ length = SysStringLen(string);
+ if(regexp->jsregexp->flags & JSREG_GLOB)
+ last_index = regexp->last_index;
+
+ cp = string + last_index;
+ hres = regexp_match_next(®exp->dispex, FALSE, string, length, &cp, parens, parens ? &parens_size : NULL,
+ parens_cnt, match);
+ if(FAILED(hres)) {
+ SysFreeString(string);
+ return hres;
+ }
+
+ if(hres == S_OK) {
+ regexp->last_index = cp-string;
+ *ret = VARIANT_TRUE;
+ }else {
+ regexp->last_index = 0;
+ *ret = VARIANT_FALSE;
+ }
+
+ if(input)
+ *input = string;
+ return S_OK;
+}
+
static HRESULT RegExp_exec(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
- FIXME("\n");
- return E_NOTIMPL;
+ match_result_t *parens = NULL, match;
+ DWORD parens_cnt = 0;
+ VARIANT_BOOL b;
+ BSTR string;
+ HRESULT hres;
+
+ TRACE("\n");
+
+ hres = run_exec(dispex, arg_cnt(dp) ? get_arg(dp,0) : NULL, lcid, ei, &string, &match, &parens, &parens_cnt, &b);
+ if(FAILED(hres))
+ return hres;
+
+ if(retv) {
+ if(b) {
+ IDispatch *ret;
+
+ hres = create_match_array(dispex->ctx, string, &match, parens, parens_cnt, lcid, ei, &ret);
+ if(SUCCEEDED(hres)) {
+ V_VT(retv) = VT_DISPATCH;
+ V_DISPATCH(retv) = ret;
+ }
+ }else {
+ V_VT(retv) = VT_NULL;
+ }
+ }
+
+ heap_free(parens);
+ SysFreeString(string);
+ return hres;
}
static HRESULT RegExp_test(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js
index b246284..27c1afb 100644
--- a/dlls/jscript/tests/regexp.js
+++ b/dlls/jscript/tests/regexp.js
@@ -17,11 +17,60 @@
*/
-var m, re;
+var m, re, b;
re = /a+/;
ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
+m = re.exec(" aabaaa");
+ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
+ok(m.index === 1, "m.index = " + m.index);
+ok(m.input === " aabaaa", "m.input = " + m.input);
+ok(m.length === 1, "m.length = " + m.length);
+ok(m[0] === "aa", "m[0] = " + m[0]);
+
+m = re.exec(" aabaaa");
+ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
+ok(m.index === 1, "m.index = " + m.index);
+ok(m.input === " aabaaa", "m.input = " + m.input);
+ok(m.length === 1, "m.length = " + m.length);
+ok(m[0] === "aa", "m[0] = " + m[0]);
+
+re = /a+/g;
+ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
+
+m = re.exec(" aabaaa");
+ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
+ok(m.index === 1, "m.index = " + m.index);
+ok(m.input === " aabaaa", "m.input = " + m.input);
+ok(m.length === 1, "m.length = " + m.length);
+ok(m[0] === "aa", "m[0] = " + m[0]);
+
+m = re.exec(" aabaaa");
+ok(re.lastIndex === 7, "re.lastIndex = " + re.lastIndex);
+ok(m.index === 4, "m.index = " + m.index);
+ok(m.input === " aabaaa", "m.input = " + m.input);
+ok(m.length === 1, "m.length = " + m.length);
+ok(m[0] === "aaa", "m[0] = " + m[0]);
+
+m = re.exec(" aabaaa");
+ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
+ok(m === null, "m is not null");
+
+re.exec(" a");
+ok(re.lastIndex === 16, "re.lastIndex = " + re.lastIndex);
+
+m = re.exec(" a");
+ok(m === null, "m is not null");
+ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
+
+m = re.exec(" a");
+ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex);
+
+m = re.exec();
+ok(m === null, "m is not null");
+ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
+
m = "abcabc".match(/ca/);
ok(typeof(m) === "object", "typeof m is not object");
ok(m.length === 1, "m.length is not 1");
More information about the wine-cvs
mailing list