static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { match_state_t *match; heap_pool_t *mark; BOOL b; jsstr_t *string; HRESULT hres; TRACE("\n"); mark = heap_pool_mark(&ctx->tmp_heap); hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(jsstr_empty()), &string, &match, &b); if(FAILED(hres)) { heap_pool_clear(mark); return hres; } if(r) { if(b) { IDispatch *ret; hres = create_match_array(ctx, string, match, &ret); if(SUCCEEDED(hres)) *r = jsval_disp(ret); }else { *r = jsval_null(); } } heap_pool_clear(mark); jsstr_release(string); return hres; }
HRESULT regexp_match_next(script_ctx_t *ctx, jsdisp_t *dispex, DWORD rem_flags, jsstr_t *jsstr, match_state_t **ret) { RegExpInstance *regexp = (RegExpInstance*)dispex; match_state_t *match; heap_pool_t *mark; const WCHAR *str; HRESULT hres; if((rem_flags & REM_CHECK_GLOBAL) && !(regexp->jsregexp->flags & REG_GLOB)) { if(rem_flags & REM_ALLOC_RESULT) *ret = NULL; return S_FALSE; } str = jsstr_flatten(jsstr); if(!str) return E_OUTOFMEMORY; if(rem_flags & REM_ALLOC_RESULT) { match = alloc_match_state(regexp->jsregexp, NULL, str); if(!match) return E_OUTOFMEMORY; *ret = match; } mark = heap_pool_mark(&ctx->tmp_heap); if(rem_flags & REM_NO_PARENS) { match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, NULL); if(!match) { heap_pool_clear(mark); return E_OUTOFMEMORY; } match->cp = (*ret)->cp; match->match_len = (*ret)->match_len; }else { match = *ret; } hres = do_regexp_match_next(ctx, regexp, rem_flags, jsstr, str, match); if(rem_flags & REM_NO_PARENS) { (*ret)->cp = match->cp; (*ret)->match_len = match->match_len; } heap_pool_clear(mark); if(hres != S_OK && (rem_flags & REM_ALLOC_RESULT)) { heap_free(match); *ret = NULL; } return hres; }
static HRESULT WINAPI RegExp2_Test(IRegExp2 *iface, BSTR sourceString, VARIANT_BOOL *pMatch) { RegExp2 *This = impl_from_IRegExp2(iface); match_state_t *result; heap_pool_t *mark; HRESULT hres; TRACE("(%p)->(%s %p)\n", This, debugstr_w(sourceString), pMatch); if(!This->pattern) { *pMatch = VARIANT_TRUE; return S_OK; } if(!This->regexp) { This->regexp = regexp_new(NULL, &This->pool, This->pattern, strlenW(This->pattern), This->flags, FALSE); if(!This->regexp) return E_FAIL; }else { hres = regexp_set_flags(&This->regexp, NULL, &This->pool, This->flags); if(FAILED(hres)) return hres; } mark = heap_pool_mark(&This->pool); result = alloc_match_state(This->regexp, &This->pool, sourceString); if(!result) { heap_pool_clear(mark); return E_OUTOFMEMORY; } hres = regexp_execute(This->regexp, NULL, &This->pool, sourceString, SysStringLen(sourceString), result); heap_pool_clear(mark); if(hres == S_OK) { *pMatch = VARIANT_TRUE; }else if(hres == S_FALSE) { *pMatch = VARIANT_FALSE; hres = S_OK; } return hres; }
static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { match_state_t *match; jsstr_t *undef_str; heap_pool_t *mark; BOOL b; HRESULT hres; TRACE("\n"); mark = heap_pool_mark(&ctx->tmp_heap); hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(undef_str = jsstr_undefined()), NULL, &match, &b); heap_pool_clear(mark); if(!argc) jsstr_release(undef_str); if(FAILED(hres)) return hres; if(r) *r = jsval_bool(b); return S_OK; }
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval_t *r) { static const WCHAR indexW[] = {'i','n','d','e','x',0}; static const WCHAR inputW[] = {'i','n','p','u','t',0}; static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0}; RegExpInstance *regexp = (RegExpInstance*)re; match_result_t *match_result; unsigned match_cnt, i; jsdisp_t *array; HRESULT hres; if(!(regexp->jsregexp->flags & REG_GLOB)) { match_state_t *match; heap_pool_t *mark; mark = heap_pool_mark(&ctx->tmp_heap); match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, str->str); if(!match) { heap_pool_clear(mark); return E_OUTOFMEMORY; } hres = regexp_match_next(ctx, ®exp->dispex, 0, str, &match); if(FAILED(hres)) { heap_pool_clear(mark); return hres; } if(r) { if(hres == S_OK) { IDispatch *ret; hres = create_match_array(ctx, str, match, &ret); if(SUCCEEDED(hres)) *r = jsval_disp(ret); }else { *r = jsval_null(); } } heap_pool_clear(mark); return S_OK; } hres = regexp_match(ctx, ®exp->dispex, str, FALSE, &match_result, &match_cnt); if(FAILED(hres)) return hres; if(!match_cnt) { TRACE("no match\n"); if(r) *r = jsval_null(); return S_OK; } hres = create_array(ctx, match_cnt, &array); if(FAILED(hres)) return hres; for(i=0; i < match_cnt; i++) { jsstr_t *tmp_str; tmp_str = jsstr_substr(str, match_result[i].index, match_result[i].length); if(!tmp_str) { hres = E_OUTOFMEMORY; break; } hres = jsdisp_propput_idx(array, i, jsval_string(tmp_str)); jsstr_release(tmp_str); if(FAILED(hres)) break; } while(SUCCEEDED(hres)) { hres = jsdisp_propput_name(array, indexW, jsval_number(match_result[match_cnt-1].index)); if(FAILED(hres)) break; hres = jsdisp_propput_name(array, lastIndexW, jsval_number(match_result[match_cnt-1].index + match_result[match_cnt-1].length)); if(FAILED(hres)) break; hres = jsdisp_propput_name(array, inputW, jsval_string(str)); break; } heap_free(match_result); if(SUCCEEDED(hres) && r) *r = jsval_obj(array); else jsdisp_release(array); return hres; }
static HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, jsstr_t *str, BOOL gflag, match_result_t **match_result, DWORD *result_cnt) { RegExpInstance *This = (RegExpInstance*)dispex; match_result_t *ret = NULL; match_state_t *result; DWORD i=0, ret_size = 0; heap_pool_t *mark; HRESULT hres; mark = heap_pool_mark(&ctx->tmp_heap); result = alloc_match_state(This->jsregexp, &ctx->tmp_heap, str->str); if(!result) { heap_pool_clear(mark); return E_OUTOFMEMORY; } while(1) { hres = do_regexp_match_next(ctx, This, 0, str, result); if(hres == S_FALSE) { hres = S_OK; break; } if(FAILED(hres)) break; if(ret_size == i) { if(ret) { match_result_t *old_ret = ret; ret = heap_realloc(old_ret, (ret_size <<= 1) * sizeof(match_result_t)); if(!ret) heap_free(old_ret); }else { ret = heap_alloc((ret_size=4) * sizeof(match_result_t)); } if(!ret) { hres = E_OUTOFMEMORY; break; } } ret[i].index = result->cp - str->str - result->match_len; ret[i++].length = result->match_len; if(!gflag && !(This->jsregexp->flags & REG_GLOB)) { hres = S_OK; break; } } heap_pool_clear(mark); if(FAILED(hres)) { heap_free(ret); return hres; } *match_result = ret; *result_cnt = i; return S_OK; }