2 * Copyright 2008 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(jscript
);
34 jsval_t last_index_val
;
37 static inline RegExpInstance
*regexp_from_jsdisp(jsdisp_t
*jsdisp
)
39 return CONTAINING_RECORD(jsdisp
, RegExpInstance
, dispex
);
42 static inline RegExpInstance
*regexp_this(jsval_t vthis
)
44 jsdisp_t
*jsdisp
= is_object_instance(vthis
) ? to_jsdisp(get_object(vthis
)) : NULL
;
45 return (jsdisp
&& is_class(jsdisp
, JSCLASS_REGEXP
)) ? regexp_from_jsdisp(jsdisp
) : NULL
;
48 static void set_last_index(RegExpInstance
*This
, DWORD last_index
)
50 This
->last_index
= last_index
;
51 jsval_release(This
->last_index_val
);
52 This
->last_index_val
= jsval_number(last_index
);
55 static HRESULT
do_regexp_match_next(script_ctx_t
*ctx
, RegExpInstance
*regexp
,
56 DWORD rem_flags
, jsstr_t
*jsstr
, const WCHAR
*str
, match_state_t
*ret
)
60 hres
= regexp_execute(regexp
->jsregexp
, ctx
, &ctx
->tmp_heap
,
61 str
, jsstr_length(jsstr
), ret
);
65 if(rem_flags
& REM_RESET_INDEX
)
66 set_last_index(regexp
, 0);
70 if(!(rem_flags
& REM_NO_CTX_UPDATE
) && ctx
->last_match
!= jsstr
) {
71 jsstr_release(ctx
->last_match
);
72 ctx
->last_match
= jsstr_addref(jsstr
);
75 if(!(rem_flags
& REM_NO_CTX_UPDATE
)) {
76 DWORD i
, n
= min(ARRAY_SIZE(ctx
->match_parens
), ret
->paren_count
);
78 for(i
=0; i
< n
; i
++) {
79 if(ret
->parens
[i
].index
== -1) {
80 ctx
->match_parens
[i
].index
= 0;
81 ctx
->match_parens
[i
].length
= 0;
83 ctx
->match_parens
[i
].index
= ret
->parens
[i
].index
;
84 ctx
->match_parens
[i
].length
= ret
->parens
[i
].length
;
88 if(n
< ARRAY_SIZE(ctx
->match_parens
))
89 memset(ctx
->match_parens
+n
, 0, sizeof(ctx
->match_parens
) - n
*sizeof(ctx
->match_parens
[0]));
92 set_last_index(regexp
, ret
->cp
-str
);
94 if(!(rem_flags
& REM_NO_CTX_UPDATE
)) {
95 ctx
->last_match_index
= ret
->cp
-str
-ret
->match_len
;
96 ctx
->last_match_length
= ret
->match_len
;
102 HRESULT
regexp_match_next(script_ctx_t
*ctx
, jsdisp_t
*dispex
,
103 DWORD rem_flags
, jsstr_t
*jsstr
, match_state_t
**ret
)
105 RegExpInstance
*regexp
= regexp_from_jsdisp(dispex
);
106 match_state_t
*match
;
111 if((rem_flags
& REM_CHECK_GLOBAL
) && !(regexp
->jsregexp
->flags
& REG_GLOB
)) {
112 if(rem_flags
& REM_ALLOC_RESULT
)
117 str
= jsstr_flatten(jsstr
);
119 return E_OUTOFMEMORY
;
121 if(rem_flags
& REM_ALLOC_RESULT
) {
122 match
= alloc_match_state(regexp
->jsregexp
, NULL
, str
);
124 return E_OUTOFMEMORY
;
128 mark
= heap_pool_mark(&ctx
->tmp_heap
);
130 if(rem_flags
& REM_NO_PARENS
) {
131 match
= alloc_match_state(regexp
->jsregexp
, &ctx
->tmp_heap
, NULL
);
133 heap_pool_clear(mark
);
134 return E_OUTOFMEMORY
;
136 match
->cp
= (*ret
)->cp
;
137 match
->match_len
= (*ret
)->match_len
;
142 hres
= do_regexp_match_next(ctx
, regexp
, rem_flags
, jsstr
, str
, match
);
144 if(rem_flags
& REM_NO_PARENS
) {
145 (*ret
)->cp
= match
->cp
;
146 (*ret
)->match_len
= match
->match_len
;
149 heap_pool_clear(mark
);
151 if(hres
!= S_OK
&& (rem_flags
& REM_ALLOC_RESULT
)) {
159 static HRESULT
regexp_match(script_ctx_t
*ctx
, jsdisp_t
*dispex
, jsstr_t
*jsstr
, BOOL gflag
,
160 match_result_t
**match_result
, DWORD
*result_cnt
)
162 RegExpInstance
*This
= regexp_from_jsdisp(dispex
);
163 match_result_t
*ret
= NULL
;
164 match_state_t
*result
;
165 DWORD i
=0, ret_size
= 0;
170 mark
= heap_pool_mark(&ctx
->tmp_heap
);
172 str
= jsstr_flatten(jsstr
);
174 return E_OUTOFMEMORY
;
176 result
= alloc_match_state(This
->jsregexp
, &ctx
->tmp_heap
, str
);
178 heap_pool_clear(mark
);
179 return E_OUTOFMEMORY
;
183 hres
= do_regexp_match_next(ctx
, This
, 0, jsstr
, str
, result
);
184 if(hres
== S_FALSE
) {
194 match_result_t
*old_ret
= ret
;
196 ret
= realloc(old_ret
, (ret_size
<<= 1) * sizeof(match_result_t
));
200 ret
= malloc((ret_size
=4) * sizeof(match_result_t
));
203 hres
= E_OUTOFMEMORY
;
208 ret
[i
].index
= result
->cp
- str
- result
->match_len
;
209 ret
[i
++].length
= result
->match_len
;
211 if(!gflag
&& !(This
->jsregexp
->flags
& REG_GLOB
)) {
217 heap_pool_clear(mark
);
228 static HRESULT
RegExp_get_source(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
232 *r
= jsval_string(jsstr_addref(regexp_from_jsdisp(jsthis
)->str
));
236 static HRESULT
RegExp_get_global(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
240 *r
= jsval_bool(!!(regexp_from_jsdisp(jsthis
)->jsregexp
->flags
& REG_GLOB
));
244 static HRESULT
RegExp_get_ignoreCase(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
248 *r
= jsval_bool(!!(regexp_from_jsdisp(jsthis
)->jsregexp
->flags
& REG_FOLD
));
252 static HRESULT
RegExp_get_multiline(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
256 *r
= jsval_bool(!!(regexp_from_jsdisp(jsthis
)->jsregexp
->flags
& REG_MULTILINE
));
260 static INT
index_from_val(script_ctx_t
*ctx
, jsval_t v
)
265 hres
= to_number(ctx
, v
, &n
);
270 return is_int32(n
) ? n
: 0;
273 static HRESULT
RegExp_get_lastIndex(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
275 RegExpInstance
*regexp
= regexp_from_jsdisp(jsthis
);
279 return jsval_copy(regexp
->last_index_val
, r
);
282 static HRESULT
RegExp_set_lastIndex(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t value
)
284 RegExpInstance
*regexp
= regexp_from_jsdisp(jsthis
);
289 jsval_release(regexp
->last_index_val
);
290 hres
= jsval_copy(value
, ®exp
->last_index_val
);
294 regexp
->last_index
= index_from_val(ctx
, value
);
298 static HRESULT
RegExp_toString(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
301 RegExpInstance
*regexp
;
308 if(!(regexp
= regexp_this(vthis
))) {
309 WARN("Not a RegExp\n");
310 return JS_E_REGEXP_EXPECTED
;
317 len
= jsstr_length(regexp
->str
) + 2;
319 f
= regexp
->jsregexp
->flags
;
324 if(f
& REG_MULTILINE
)
327 ret
= jsstr_alloc_buf(len
, &ptr
);
329 return E_OUTOFMEMORY
;
332 ptr
+= jsstr_flush(regexp
->str
, ptr
);
339 if(f
& REG_MULTILINE
)
342 *r
= jsval_string(ret
);
346 static HRESULT
create_match_array(script_ctx_t
*ctx
, jsstr_t
*input_str
,
347 const match_state_t
*result
, IDispatch
**ret
)
355 input
= jsstr_flatten(input_str
);
357 return E_OUTOFMEMORY
;
359 hres
= create_array(ctx
, result
->paren_count
+1, &array
);
363 for(i
=0; i
< result
->paren_count
; i
++) {
366 if(result
->parens
[i
].index
!= -1) {
367 if(!(str
= jsstr_substr(input_str
, result
->parens
[i
].index
, result
->parens
[i
].length
))) {
368 hres
= E_OUTOFMEMORY
;
371 val
= jsval_string(str
);
372 }else if(ctx
->version
< SCRIPTLANGUAGEVERSION_ES5
) {
373 val
= jsval_string(jsstr_empty());
375 val
= jsval_undefined();
378 hres
= jsdisp_propput_idx(array
, i
+1, val
);
384 while(SUCCEEDED(hres
)) {
385 hres
= jsdisp_propput_name(array
, L
"index", jsval_number(result
->cp
-input
-result
->match_len
));
389 hres
= jsdisp_propput_name(array
, L
"lastIndex", jsval_number(result
->cp
-input
));
393 hres
= jsdisp_propput_name(array
, L
"input", jsval_string(input_str
));
397 str
= jsstr_alloc_len(result
->cp
-result
->match_len
, result
->match_len
);
399 hres
= E_OUTOFMEMORY
;
402 hres
= jsdisp_propput_name(array
, L
"0", jsval_string(str
));
408 jsdisp_release(array
);
412 *ret
= to_disp(array
);
416 static HRESULT
run_exec(script_ctx_t
*ctx
, jsval_t vthis
, jsval_t arg
,
417 jsstr_t
**input
, match_state_t
**result
, BOOL
*ret
)
419 RegExpInstance
*regexp
;
420 match_state_t
*match
;
421 DWORD last_index
= 0;
426 if(!(regexp
= regexp_this(vthis
))) {
427 WARN("Not a RegExp\n");
428 return JS_E_REGEXP_EXPECTED
;
431 hres
= to_flat_string(ctx
, arg
, &jsstr
, &string
);
435 if(regexp
->jsregexp
->flags
& REG_GLOB
) {
436 if(regexp
->last_index
< 0) {
437 jsstr_release(jsstr
);
438 set_last_index(regexp
, 0);
441 *input
= jsstr_empty();
445 last_index
= regexp
->last_index
;
448 match
= alloc_match_state(regexp
->jsregexp
, &ctx
->tmp_heap
, string
+last_index
);
450 jsstr_release(jsstr
);
451 return E_OUTOFMEMORY
;
454 hres
= regexp_match_next(ctx
, ®exp
->dispex
, REM_RESET_INDEX
, jsstr
, &match
);
456 jsstr_release(jsstr
);
465 jsstr_release(jsstr
);
469 static HRESULT
RegExp_exec(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
472 match_state_t
*match
;
480 mark
= heap_pool_mark(&ctx
->tmp_heap
);
482 hres
= run_exec(ctx
, vthis
, argc
? argv
[0] : jsval_string(jsstr_empty()), &string
, &match
, &b
);
484 heap_pool_clear(mark
);
492 hres
= create_match_array(ctx
, string
, match
, &ret
);
494 *r
= jsval_disp(ret
);
500 heap_pool_clear(mark
);
501 jsstr_release(string
);
505 static HRESULT
RegExp_test(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
508 match_state_t
*match
;
516 mark
= heap_pool_mark(&ctx
->tmp_heap
);
517 hres
= run_exec(ctx
, vthis
, argc
? argv
[0] : jsval_string(undef_str
= jsstr_undefined()), NULL
, &match
, &b
);
518 heap_pool_clear(mark
);
520 jsstr_release(undef_str
);
529 static HRESULT
RegExp_value(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
536 return JS_E_FUNCTION_EXPECTED
;
538 FIXME("unimplemented flags %x\n", flags
);
545 static void RegExp_destructor(jsdisp_t
*dispex
)
547 RegExpInstance
*This
= regexp_from_jsdisp(dispex
);
550 regexp_destroy(This
->jsregexp
);
551 jsval_release(This
->last_index_val
);
552 jsstr_release(This
->str
);
555 static HRESULT
RegExp_gc_traverse(struct gc_ctx
*gc_ctx
, enum gc_traverse_op op
, jsdisp_t
*dispex
)
557 return gc_process_linked_val(gc_ctx
, op
, dispex
, ®exp_from_jsdisp(dispex
)->last_index_val
);
560 static const builtin_prop_t RegExp_props
[] = {
561 {L
"exec", RegExp_exec
, PROPF_METHOD
|1},
562 {L
"global", NULL
,0, RegExp_get_global
},
563 {L
"ignoreCase", NULL
,0, RegExp_get_ignoreCase
},
564 {L
"lastIndex", NULL
,0, RegExp_get_lastIndex
, RegExp_set_lastIndex
},
565 {L
"multiline", NULL
,0, RegExp_get_multiline
},
566 {L
"source", NULL
,0, RegExp_get_source
},
567 {L
"test", RegExp_test
, PROPF_METHOD
|1},
568 {L
"toString", RegExp_toString
, PROPF_METHOD
}
571 static const builtin_info_t RegExp_info
= {
572 .class = JSCLASS_REGEXP
,
573 .call
= RegExp_value
,
574 .props_cnt
= ARRAY_SIZE(RegExp_props
),
575 .props
= RegExp_props
,
576 .destructor
= RegExp_destructor
,
577 .gc_traverse
= RegExp_gc_traverse
580 static const builtin_prop_t RegExpInst_props
[] = {
581 {L
"global", NULL
,0, RegExp_get_global
},
582 {L
"ignoreCase", NULL
,0, RegExp_get_ignoreCase
},
583 {L
"lastIndex", NULL
,0, RegExp_get_lastIndex
, RegExp_set_lastIndex
},
584 {L
"multiline", NULL
,0, RegExp_get_multiline
},
585 {L
"source", NULL
,0, RegExp_get_source
}
588 static const builtin_info_t RegExpInst_info
= {
589 .class = JSCLASS_REGEXP
,
590 .call
= RegExp_value
,
591 .props_cnt
= ARRAY_SIZE(RegExpInst_props
),
592 .props
= RegExpInst_props
,
593 .destructor
= RegExp_destructor
,
594 .gc_traverse
= RegExp_gc_traverse
597 static HRESULT
alloc_regexp(script_ctx_t
*ctx
, jsstr_t
*str
, jsdisp_t
*object_prototype
, RegExpInstance
**ret
)
599 RegExpInstance
*regexp
;
602 regexp
= calloc(1, sizeof(RegExpInstance
));
604 return E_OUTOFMEMORY
;
607 hres
= init_dispex(®exp
->dispex
, ctx
, &RegExp_info
, object_prototype
);
609 hres
= init_dispex_from_constr(®exp
->dispex
, ctx
, &RegExpInst_info
, ctx
->regexp_constr
);
616 regexp
->str
= jsstr_addref(str
);
617 regexp
->last_index_val
= jsval_number(0);
623 HRESULT
create_regexp(script_ctx_t
*ctx
, jsstr_t
*src
, DWORD flags
, jsdisp_t
**ret
)
625 RegExpInstance
*regexp
;
629 str
= jsstr_flatten(src
);
631 return E_OUTOFMEMORY
;
633 TRACE("%s %lx\n", debugstr_wn(str
, jsstr_length(src
)), flags
);
635 hres
= alloc_regexp(ctx
, src
, NULL
, ®exp
);
639 regexp
->jsregexp
= regexp_new(ctx
, &ctx
->tmp_heap
, str
, jsstr_length(regexp
->str
), flags
, FALSE
);
640 if(!regexp
->jsregexp
) {
641 WARN("regexp_new failed\n");
642 jsdisp_release(®exp
->dispex
);
643 return DISP_E_EXCEPTION
;
646 *ret
= ®exp
->dispex
;
650 HRESULT
create_regexp_var(script_ctx_t
*ctx
, jsval_t src_arg
, jsval_t
*flags_arg
, jsdisp_t
**ret
)
653 const WCHAR
*opt
= NULL
;
657 if(is_object_instance(src_arg
)) {
660 obj
= to_jsdisp(get_object(src_arg
));
662 if(is_class(obj
, JSCLASS_REGEXP
)) {
663 RegExpInstance
*regexp
= regexp_from_jsdisp(obj
);
665 hres
= create_regexp(ctx
, regexp
->str
, regexp
->jsregexp
->flags
, ret
);
671 if(is_undefined(src_arg
))
674 hres
= to_string(ctx
, src_arg
, &src
);
678 if(flags_arg
&& !is_undefined(*flags_arg
)) {
681 hres
= to_string(ctx
, *flags_arg
, &opt_str
);
682 if(SUCCEEDED(hres
)) {
683 opt
= jsstr_flatten(opt_str
);
685 hres
= parse_regexp_flags(opt
, jsstr_length(opt_str
), &flags
);
687 hres
= E_OUTOFMEMORY
;
688 jsstr_release(opt_str
);
693 hres
= create_regexp(ctx
, src
, flags
, ret
);
698 HRESULT
regexp_string_match(script_ctx_t
*ctx
, jsdisp_t
*re
, jsstr_t
*jsstr
, jsval_t
*r
)
700 RegExpInstance
*regexp
= regexp_from_jsdisp(re
);
701 match_result_t
*match_result
;
707 str
= jsstr_flatten(jsstr
);
709 return E_OUTOFMEMORY
;
711 if(!(regexp
->jsregexp
->flags
& REG_GLOB
)) {
712 match_state_t
*match
;
715 mark
= heap_pool_mark(&ctx
->tmp_heap
);
716 match
= alloc_match_state(regexp
->jsregexp
, &ctx
->tmp_heap
, str
);
718 heap_pool_clear(mark
);
719 return E_OUTOFMEMORY
;
722 hres
= regexp_match_next(ctx
, ®exp
->dispex
, 0, jsstr
, &match
);
724 heap_pool_clear(mark
);
732 hres
= create_match_array(ctx
, jsstr
, match
, &ret
);
734 *r
= jsval_disp(ret
);
740 heap_pool_clear(mark
);
744 hres
= regexp_match(ctx
, ®exp
->dispex
, jsstr
, FALSE
, &match_result
, &match_cnt
);
756 hres
= create_array(ctx
, match_cnt
, &array
);
762 for(i
=0; i
< match_cnt
; i
++) {
765 tmp_str
= jsstr_substr(jsstr
, match_result
[i
].index
, match_result
[i
].length
);
767 hres
= E_OUTOFMEMORY
;
771 hres
= jsdisp_propput_idx(array
, i
, jsval_string(tmp_str
));
772 jsstr_release(tmp_str
);
777 while(SUCCEEDED(hres
)) {
778 hres
= jsdisp_propput_name(array
, L
"index", jsval_number(match_result
[match_cnt
-1].index
));
782 hres
= jsdisp_propput_name(array
, L
"lastIndex",
783 jsval_number(match_result
[match_cnt
-1].index
+ match_result
[match_cnt
-1].length
));
787 hres
= jsdisp_propput_name(array
, L
"input", jsval_string(jsstr
));
793 if(SUCCEEDED(hres
) && r
)
794 *r
= jsval_obj(array
);
796 jsdisp_release(array
);
800 static HRESULT
global_idx(script_ctx_t
*ctx
, DWORD idx
, jsval_t
*r
)
804 ret
= jsstr_substr(ctx
->last_match
, ctx
->match_parens
[idx
].index
, ctx
->match_parens
[idx
].length
);
806 return E_OUTOFMEMORY
;
808 *r
= jsval_string(ret
);
812 static HRESULT
RegExpConstr_get_idx1(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
815 return global_idx(ctx
, 0, r
);
818 static HRESULT
RegExpConstr_get_idx2(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
821 return global_idx(ctx
, 1, r
);
824 static HRESULT
RegExpConstr_get_idx3(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
827 return global_idx(ctx
, 2, r
);
830 static HRESULT
RegExpConstr_get_idx4(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
833 return global_idx(ctx
, 3, r
);
836 static HRESULT
RegExpConstr_get_idx5(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
839 return global_idx(ctx
, 4, r
);
842 static HRESULT
RegExpConstr_get_idx6(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
845 return global_idx(ctx
, 5, r
);
848 static HRESULT
RegExpConstr_get_idx7(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
851 return global_idx(ctx
, 6, r
);
854 static HRESULT
RegExpConstr_get_idx8(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
857 return global_idx(ctx
, 7, r
);
860 static HRESULT
RegExpConstr_get_idx9(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
863 return global_idx(ctx
, 8, r
);
866 static HRESULT
RegExpConstr_get_leftContext(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
872 ret
= jsstr_substr(ctx
->last_match
, 0, ctx
->last_match_index
);
874 return E_OUTOFMEMORY
;
876 *r
= jsval_string(ret
);
880 static HRESULT
RegExpConstr_get_rightContext(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
886 ret
= jsstr_substr(ctx
->last_match
, ctx
->last_match_index
+ctx
->last_match_length
,
887 jsstr_length(ctx
->last_match
) - ctx
->last_match_index
- ctx
->last_match_length
);
889 return E_OUTOFMEMORY
;
891 *r
= jsval_string(ret
);
895 static HRESULT
RegExpConstr_value(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
901 case DISPATCH_METHOD
:
903 if(is_object_instance(argv
[0])) {
904 jsdisp_t
*jsdisp
= to_jsdisp(get_object(argv
[0]));
906 if(is_class(jsdisp
, JSCLASS_REGEXP
)) {
907 if(argc
> 1 && !is_undefined(argv
[1]))
908 return JS_E_REGEXP_SYNTAX
;
911 *r
= jsval_obj(jsdisp_addref(jsdisp
));
918 case DISPATCH_CONSTRUCT
: {
922 hres
= create_regexp_var(ctx
, argc
? argv
[0] : jsval_undefined(), argc
> 1 ? argv
+1 : NULL
, &ret
);
933 FIXME("unimplemented flags: %x\n", flags
);
940 static const builtin_prop_t RegExpConstr_props
[] = {
941 {L
"$1", NULL
,0, RegExpConstr_get_idx1
, builtin_set_const
},
942 {L
"$2", NULL
,0, RegExpConstr_get_idx2
, builtin_set_const
},
943 {L
"$3", NULL
,0, RegExpConstr_get_idx3
, builtin_set_const
},
944 {L
"$4", NULL
,0, RegExpConstr_get_idx4
, builtin_set_const
},
945 {L
"$5", NULL
,0, RegExpConstr_get_idx5
, builtin_set_const
},
946 {L
"$6", NULL
,0, RegExpConstr_get_idx6
, builtin_set_const
},
947 {L
"$7", NULL
,0, RegExpConstr_get_idx7
, builtin_set_const
},
948 {L
"$8", NULL
,0, RegExpConstr_get_idx8
, builtin_set_const
},
949 {L
"$9", NULL
,0, RegExpConstr_get_idx9
, builtin_set_const
},
950 {L
"leftContext", NULL
,0, RegExpConstr_get_leftContext
, builtin_set_const
},
951 {L
"rightContext", NULL
,0, RegExpConstr_get_rightContext
, builtin_set_const
}
954 static const builtin_info_t RegExpConstr_info
= {
955 .class = JSCLASS_FUNCTION
,
956 .call
= Function_value
,
957 .props_cnt
= ARRAY_SIZE(RegExpConstr_props
),
958 .props
= RegExpConstr_props
,
961 HRESULT
create_regexp_constr(script_ctx_t
*ctx
, jsdisp_t
*object_prototype
, jsdisp_t
**ret
)
963 jsstr_t
*str
= jsstr_empty();
964 RegExpInstance
*regexp
;
967 hres
= alloc_regexp(ctx
, str
, object_prototype
, ®exp
);
972 hres
= create_builtin_constructor(ctx
, RegExpConstr_value
, L
"RegExp", &RegExpConstr_info
,
973 PROPF_CONSTR
|2, ®exp
->dispex
, ret
);
975 jsdisp_release(®exp
->dispex
);
979 HRESULT
parse_regexp_flags(const WCHAR
*str
, DWORD str_len
, DWORD
*ret
)
984 for (p
= str
; p
< str
+str_len
; p
++) {
993 flags
|= REG_MULTILINE
;
999 WARN("wrong flag %c\n", *p
);