ReactOS 0.4.15-dev-7953-g1f49173
jsregexp.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Jacek Caban for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include <math.h>
20
21#include "jscript.h"
22#include "regexp.h"
23
24#include "wine/debug.h"
25
27
28typedef struct {
30
36
37static const WCHAR sourceW[] = {'s','o','u','r','c','e',0};
38static const WCHAR globalW[] = {'g','l','o','b','a','l',0};
39static const WCHAR ignoreCaseW[] = {'i','g','n','o','r','e','C','a','s','e',0};
40static const WCHAR multilineW[] = {'m','u','l','t','i','l','i','n','e',0};
41static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0};
42static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
43static const WCHAR execW[] = {'e','x','e','c',0};
44static const WCHAR testW[] = {'t','e','s','t',0};
45
46static const WCHAR leftContextW[] =
47 {'l','e','f','t','C','o','n','t','e','x','t',0};
48static const WCHAR rightContextW[] =
49 {'r','i','g','h','t','C','o','n','t','e','x','t',0};
50
51static const WCHAR idx1W[] = {'$','1',0};
52static const WCHAR idx2W[] = {'$','2',0};
53static const WCHAR idx3W[] = {'$','3',0};
54static const WCHAR idx4W[] = {'$','4',0};
55static const WCHAR idx5W[] = {'$','5',0};
56static const WCHAR idx6W[] = {'$','6',0};
57static const WCHAR idx7W[] = {'$','7',0};
58static const WCHAR idx8W[] = {'$','8',0};
59static const WCHAR idx9W[] = {'$','9',0};
60
62{
63 return CONTAINING_RECORD(jsdisp, RegExpInstance, dispex);
64}
65
67{
68 return regexp_from_jsdisp(vdisp->u.jsdisp);
69}
70
71static void set_last_index(RegExpInstance *This, DWORD last_index)
72{
73 This->last_index = last_index;
74 jsval_release(This->last_index_val);
75 This->last_index_val = jsval_number(last_index);
76}
77
79 DWORD rem_flags, jsstr_t *jsstr, const WCHAR *str, match_state_t *ret)
80{
82
83 hres = regexp_execute(regexp->jsregexp, ctx, &ctx->tmp_heap,
84 str, jsstr_length(jsstr), ret);
85 if(FAILED(hres))
86 return hres;
87 if(hres == S_FALSE) {
88 if(rem_flags & REM_RESET_INDEX)
89 set_last_index(regexp, 0);
90 return S_FALSE;
91 }
92
93 if(!(rem_flags & REM_NO_CTX_UPDATE) && ctx->last_match != jsstr) {
94 jsstr_release(ctx->last_match);
95 ctx->last_match = jsstr_addref(jsstr);
96 }
97
98 if(!(rem_flags & REM_NO_CTX_UPDATE)) {
99 DWORD i, n = min(ARRAY_SIZE(ctx->match_parens), ret->paren_count);
100
101 for(i=0; i < n; i++) {
102 if(ret->parens[i].index == -1) {
103 ctx->match_parens[i].index = 0;
104 ctx->match_parens[i].length = 0;
105 }else {
106 ctx->match_parens[i].index = ret->parens[i].index;
107 ctx->match_parens[i].length = ret->parens[i].length;
108 }
109 }
110
111 if(n < ARRAY_SIZE(ctx->match_parens))
112 memset(ctx->match_parens+n, 0, sizeof(ctx->match_parens) - n*sizeof(ctx->match_parens[0]));
113 }
114
115 set_last_index(regexp, ret->cp-str);
116
117 if(!(rem_flags & REM_NO_CTX_UPDATE)) {
118 ctx->last_match_index = ret->cp-str-ret->match_len;
119 ctx->last_match_length = ret->match_len;
120 }
121
122 return S_OK;
123}
124
126 DWORD rem_flags, jsstr_t *jsstr, match_state_t **ret)
127{
128 RegExpInstance *regexp = regexp_from_jsdisp(dispex);
130 heap_pool_t *mark;
131 const WCHAR *str;
133
134 if((rem_flags & REM_CHECK_GLOBAL) && !(regexp->jsregexp->flags & REG_GLOB)) {
135 if(rem_flags & REM_ALLOC_RESULT)
136 *ret = NULL;
137 return S_FALSE;
138 }
139
140 str = jsstr_flatten(jsstr);
141 if(!str)
142 return E_OUTOFMEMORY;
143
144 if(rem_flags & REM_ALLOC_RESULT) {
146 if(!match)
147 return E_OUTOFMEMORY;
148 *ret = match;
149 }
150
151 mark = heap_pool_mark(&ctx->tmp_heap);
152
153 if(rem_flags & REM_NO_PARENS) {
154 match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, NULL);
155 if(!match) {
156 heap_pool_clear(mark);
157 return E_OUTOFMEMORY;
158 }
159 match->cp = (*ret)->cp;
160 match->match_len = (*ret)->match_len;
161 }else {
162 match = *ret;
163 }
164
165 hres = do_regexp_match_next(ctx, regexp, rem_flags, jsstr, str, match);
166
167 if(rem_flags & REM_NO_PARENS) {
168 (*ret)->cp = match->cp;
169 (*ret)->match_len = match->match_len;
170 }
171
172 heap_pool_clear(mark);
173
174 if(hres != S_OK && (rem_flags & REM_ALLOC_RESULT)) {
176 *ret = NULL;
177 }
178
179 return hres;
180}
181
182static HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, jsstr_t *jsstr, BOOL gflag,
183 match_result_t **match_result, DWORD *result_cnt)
184{
188 DWORD i=0, ret_size = 0;
189 heap_pool_t *mark;
190 const WCHAR *str;
192
193 mark = heap_pool_mark(&ctx->tmp_heap);
194
195 str = jsstr_flatten(jsstr);
196 if(!str)
197 return E_OUTOFMEMORY;
198
199 result = alloc_match_state(This->jsregexp, &ctx->tmp_heap, str);
200 if(!result) {
201 heap_pool_clear(mark);
202 return E_OUTOFMEMORY;
203 }
204
205 while(1) {
206 hres = do_regexp_match_next(ctx, This, 0, jsstr, str, result);
207 if(hres == S_FALSE) {
208 hres = S_OK;
209 break;
210 }
211
212 if(FAILED(hres))
213 break;
214
215 if(ret_size == i) {
216 if(ret) {
217 match_result_t *old_ret = ret;
218
219 ret = heap_realloc(old_ret, (ret_size <<= 1) * sizeof(match_result_t));
220 if(!ret)
221 heap_free(old_ret);
222 }else {
223 ret = heap_alloc((ret_size=4) * sizeof(match_result_t));
224 }
225 if(!ret) {
227 break;
228 }
229 }
230
231 ret[i].index = result->cp - str - result->match_len;
232 ret[i++].length = result->match_len;
233
234 if(!gflag && !(This->jsregexp->flags & REG_GLOB)) {
235 hres = S_OK;
236 break;
237 }
238 }
239
240 heap_pool_clear(mark);
241 if(FAILED(hres)) {
242 heap_free(ret);
243 return hres;
244 }
245
246 *match_result = ret;
247 *result_cnt = i;
248 return S_OK;
249}
250
252{
253 TRACE("\n");
254
256 return S_OK;
257}
258
260{
261 TRACE("\n");
262
263 *r = jsval_bool(!!(regexp_from_jsdisp(jsthis)->jsregexp->flags & REG_GLOB));
264 return S_OK;
265}
266
268{
269 TRACE("\n");
270
271 *r = jsval_bool(!!(regexp_from_jsdisp(jsthis)->jsregexp->flags & REG_FOLD));
272 return S_OK;
273}
274
276{
277 TRACE("\n");
278
279 *r = jsval_bool(!!(regexp_from_jsdisp(jsthis)->jsregexp->flags & REG_MULTILINE));
280 return S_OK;
281}
282
284{
285 double n;
287
288 hres = to_number(ctx, v, &n);
289 if(FAILED(hres)) {
290 clear_ei(ctx); /* FIXME: Move ignoring exceptions to to_primitive */
291 return 0;
292 }
293
294 n = floor(n);
295 return is_int32(n) ? n : 0;
296}
297
299{
300 RegExpInstance *regexp = regexp_from_jsdisp(jsthis);
301
302 TRACE("\n");
303
304 return jsval_copy(regexp->last_index_val, r);
305}
306
308{
309 RegExpInstance *regexp = regexp_from_jsdisp(jsthis);
311
312 TRACE("\n");
313
315 hres = jsval_copy(value, &regexp->last_index_val);
316 if(FAILED(hres))
317 return hres;
318
320 return S_OK;
321}
322
324 jsval_t *r)
325{
326 RegExpInstance *regexp;
327 unsigned len, f;
328 jsstr_t *ret;
329 WCHAR *ptr;
330
331 TRACE("\n");
332
333 if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
334 FIXME("Not a RegExp\n");
335 return E_NOTIMPL;
336 }
337
338 regexp = regexp_from_vdisp(jsthis);
339
340 if(!r)
341 return S_OK;
342
343 len = jsstr_length(regexp->str) + 2;
344
345 f = regexp->jsregexp->flags;
346 if(f & REG_FOLD)
347 len++;
348 if(f & REG_GLOB)
349 len++;
350 if(f & REG_MULTILINE)
351 len++;
352
354 if(!ret)
355 return E_OUTOFMEMORY;
356
357 *ptr++ = '/';
358 ptr += jsstr_flush(regexp->str, ptr);
359 *ptr++ = '/';
360
361 if(f & REG_FOLD)
362 *ptr++ = 'i';
363 if(f & REG_GLOB)
364 *ptr++ = 'g';
365 if(f & REG_MULTILINE)
366 *ptr++ = 'm';
367
368 *r = jsval_string(ret);
369 return S_OK;
370}
371
374{
375 const WCHAR *input;
377 jsstr_t *str;
378 DWORD i;
379 HRESULT hres = S_OK;
380
381 static const WCHAR indexW[] = {'i','n','d','e','x',0};
382 static const WCHAR inputW[] = {'i','n','p','u','t',0};
383 static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0};
384 static const WCHAR zeroW[] = {'0',0};
385
386 input = jsstr_flatten(input_str);
387 if(!input)
388 return E_OUTOFMEMORY;
389
390 hres = create_array(ctx, result->paren_count+1, &array);
391 if(FAILED(hres))
392 return hres;
393
394 for(i=0; i < result->paren_count; i++) {
395 if(result->parens[i].index != -1)
396 str = jsstr_substr(input_str, result->parens[i].index, result->parens[i].length);
397 else
398 str = jsstr_empty();
399 if(!str) {
401 break;
402 }
403
406 if(FAILED(hres))
407 break;
408 }
409
410 while(SUCCEEDED(hres)) {
411 hres = jsdisp_propput_name(array, indexW, jsval_number(result->cp-input-result->match_len));
412 if(FAILED(hres))
413 break;
414
416 if(FAILED(hres))
417 break;
418
420 if(FAILED(hres))
421 break;
422
423 str = jsstr_alloc_len(result->cp-result->match_len, result->match_len);
424 if(!str) {
426 break;
427 }
430 break;
431 }
432
433 if(FAILED(hres)) {
435 return hres;
436 }
437
438 *ret = to_disp(array);
439 return S_OK;
440}
441
444{
445 RegExpInstance *regexp;
447 DWORD last_index = 0;
448 const WCHAR *string;
449 jsstr_t *jsstr;
451
452 if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
453 FIXME("Not a RegExp\n");
454 return E_NOTIMPL;
455 }
456
457 regexp = regexp_from_vdisp(jsthis);
458
459 hres = to_flat_string(ctx, arg, &jsstr, &string);
460 if(FAILED(hres))
461 return hres;
462
463 if(regexp->jsregexp->flags & REG_GLOB) {
464 if(regexp->last_index < 0) {
465 jsstr_release(jsstr);
466 set_last_index(regexp, 0);
467 *ret = FALSE;
468 if(input)
469 *input = jsstr_empty();
470 return S_OK;
471 }
472
473 last_index = regexp->last_index;
474 }
475
476 match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, string+last_index);
477 if(!match) {
478 jsstr_release(jsstr);
479 return E_OUTOFMEMORY;
480 }
481
482 hres = regexp_match_next(ctx, &regexp->dispex, REM_RESET_INDEX, jsstr, &match);
483 if(FAILED(hres)) {
484 jsstr_release(jsstr);
485 return hres;
486 }
487
488 *result = match;
489 *ret = hres == S_OK;
490 if(input)
491 *input = jsstr;
492 else
493 jsstr_release(jsstr);
494 return S_OK;
495}
496
498 jsval_t *r)
499{
501 heap_pool_t *mark;
502 BOOL b;
505
506 TRACE("\n");
507
508 mark = heap_pool_mark(&ctx->tmp_heap);
509
510 hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(jsstr_empty()), &string, &match, &b);
511 if(FAILED(hres)) {
512 heap_pool_clear(mark);
513 return hres;
514 }
515
516 if(r) {
517 if(b) {
518 IDispatch *ret;
519
520 hres = create_match_array(ctx, string, match, &ret);
521 if(SUCCEEDED(hres))
522 *r = jsval_disp(ret);
523 }else {
524 *r = jsval_null();
525 }
526 }
527
528 heap_pool_clear(mark);
529 jsstr_release(string);
530 return hres;
531}
532
534 jsval_t *r)
535{
537 jsstr_t *undef_str;
538 heap_pool_t *mark;
539 BOOL b;
541
542 TRACE("\n");
543
544 mark = heap_pool_mark(&ctx->tmp_heap);
545 hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(undef_str = jsstr_undefined()), NULL, &match, &b);
546 heap_pool_clear(mark);
547 if(!argc)
548 jsstr_release(undef_str);
549 if(FAILED(hres))
550 return hres;
551
552 if(r)
553 *r = jsval_bool(b);
554 return S_OK;
555}
556
558 jsval_t *r)
559{
560 TRACE("\n");
561
562 switch(flags) {
563 case INVOKE_FUNC:
565 default:
566 FIXME("unimplemented flags %x\n", flags);
567 return E_NOTIMPL;
568 }
569
570 return S_OK;
571}
572
573static void RegExp_destructor(jsdisp_t *dispex)
574{
576
577 if(This->jsregexp)
578 regexp_destroy(This->jsregexp);
579 jsval_release(This->last_index_val);
580 jsstr_release(This->str);
582}
583
584static const builtin_prop_t RegExp_props[] = {
593};
594
597 {NULL, RegExp_value, 0},
601 NULL
602};
603
610};
611
614 {NULL, RegExp_value, 0},
618 NULL
619};
620
622{
623 RegExpInstance *regexp;
625
626 regexp = heap_alloc_zero(sizeof(RegExpInstance));
627 if(!regexp)
628 return E_OUTOFMEMORY;
629
630 if(object_prototype)
631 hres = init_dispex(&regexp->dispex, ctx, &RegExp_info, object_prototype);
632 else
633 hres = init_dispex_from_constr(&regexp->dispex, ctx, &RegExpInst_info, ctx->regexp_constr);
634
635 if(FAILED(hres)) {
636 heap_free(regexp);
637 return hres;
638 }
639
640 *ret = regexp;
641 return S_OK;
642}
643
645{
646 RegExpInstance *regexp;
647 const WCHAR *str;
649
651 if(!str)
652 return E_OUTOFMEMORY;
653
654 TRACE("%s %x\n", debugstr_wn(str, jsstr_length(src)), flags);
655
656 hres = alloc_regexp(ctx, NULL, &regexp);
657 if(FAILED(hres))
658 return hres;
659
660 regexp->str = jsstr_addref(src);
661 regexp->last_index_val = jsval_number(0);
662
663 regexp->jsregexp = regexp_new(ctx, &ctx->tmp_heap, str, jsstr_length(regexp->str), flags, FALSE);
664 if(!regexp->jsregexp) {
665 WARN("regexp_new failed\n");
666 jsdisp_release(&regexp->dispex);
667 return E_FAIL;
668 }
669
670 *ret = &regexp->dispex;
671 return S_OK;
672}
673
675{
676 unsigned flags, opt_len = 0;
677 const WCHAR *opt = NULL;
678 jsstr_t *src;
680
681 if(is_object_instance(src_arg)) {
682 jsdisp_t *obj;
683
684 obj = iface_to_jsdisp(get_object(src_arg));
685 if(obj) {
688
689 hres = create_regexp(ctx, regexp->str, regexp->jsregexp->flags, ret);
691 return hres;
692 }
693
695 }
696 }
697
698 if(!is_string(src_arg)) {
699 FIXME("src_arg = %s\n", debugstr_jsval(src_arg));
700 return E_NOTIMPL;
701 }
702
703 src = get_string(src_arg);
704
705 if(flags_arg) {
706 jsstr_t *opt_str;
707
708 if(!is_string(*flags_arg)) {
709 FIXME("unimplemented for %s\n", debugstr_jsval(*flags_arg));
710 return E_NOTIMPL;
711 }
712
713 opt_str = get_string(*flags_arg);
714 opt = jsstr_flatten(opt_str);
715 if(!opt)
716 return E_OUTOFMEMORY;
717 opt_len = jsstr_length(opt_str);
718 }
719
720 hres = parse_regexp_flags(opt, opt_len, &flags);
721 if(FAILED(hres))
722 return hres;
723
724 return create_regexp(ctx, src, flags, ret);
725}
726
728{
729 static const WCHAR indexW[] = {'i','n','d','e','x',0};
730 static const WCHAR inputW[] = {'i','n','p','u','t',0};
731 static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0};
732
734 match_result_t *match_result;
735 unsigned match_cnt, i;
736 const WCHAR *str;
739
740 str = jsstr_flatten(jsstr);
741 if(!str)
742 return E_OUTOFMEMORY;
743
744 if(!(regexp->jsregexp->flags & REG_GLOB)) {
746 heap_pool_t *mark;
747
748 mark = heap_pool_mark(&ctx->tmp_heap);
749 match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, str);
750 if(!match) {
751 heap_pool_clear(mark);
752 return E_OUTOFMEMORY;
753 }
754
755 hres = regexp_match_next(ctx, &regexp->dispex, 0, jsstr, &match);
756 if(FAILED(hres)) {
757 heap_pool_clear(mark);
758 return hres;
759 }
760
761 if(r) {
762 if(hres == S_OK) {
763 IDispatch *ret;
764
765 hres = create_match_array(ctx, jsstr, match, &ret);
766 if(SUCCEEDED(hres))
767 *r = jsval_disp(ret);
768 }else {
769 *r = jsval_null();
770 }
771 }
772
773 heap_pool_clear(mark);
774 return S_OK;
775 }
776
777 hres = regexp_match(ctx, &regexp->dispex, jsstr, FALSE, &match_result, &match_cnt);
778 if(FAILED(hres))
779 return hres;
780
781 if(!match_cnt) {
782 TRACE("no match\n");
783
784 if(r)
785 *r = jsval_null();
786 return S_OK;
787 }
788
789 hres = create_array(ctx, match_cnt, &array);
790 if(FAILED(hres))
791 return hres;
792
793 for(i=0; i < match_cnt; i++) {
794 jsstr_t *tmp_str;
795
796 tmp_str = jsstr_substr(jsstr, match_result[i].index, match_result[i].length);
797 if(!tmp_str) {
799 break;
800 }
801
803 jsstr_release(tmp_str);
804 if(FAILED(hres))
805 break;
806 }
807
808 while(SUCCEEDED(hres)) {
809 hres = jsdisp_propput_name(array, indexW, jsval_number(match_result[match_cnt-1].index));
810 if(FAILED(hres))
811 break;
812
814 jsval_number(match_result[match_cnt-1].index + match_result[match_cnt-1].length));
815 if(FAILED(hres))
816 break;
817
819 break;
820 }
821
822 heap_free(match_result);
823
824 if(SUCCEEDED(hres) && r)
825 *r = jsval_obj(array);
826 else
828 return hres;
829}
830
832{
833 jsstr_t *ret;
834
835 ret = jsstr_substr(ctx->last_match, ctx->match_parens[idx].index, ctx->match_parens[idx].length);
836 if(!ret)
837 return E_OUTOFMEMORY;
838
839 *r = jsval_string(ret);
840 return S_OK;
841}
842
844{
845 TRACE("\n");
846 return global_idx(ctx, 0, r);
847}
848
850{
851 TRACE("\n");
852 return global_idx(ctx, 1, r);
853}
854
856{
857 TRACE("\n");
858 return global_idx(ctx, 2, r);
859}
860
862{
863 TRACE("\n");
864 return global_idx(ctx, 3, r);
865}
866
868{
869 TRACE("\n");
870 return global_idx(ctx, 4, r);
871}
872
874{
875 TRACE("\n");
876 return global_idx(ctx, 5, r);
877}
878
880{
881 TRACE("\n");
882 return global_idx(ctx, 6, r);
883}
884
886{
887 TRACE("\n");
888 return global_idx(ctx, 7, r);
889}
890
892{
893 TRACE("\n");
894 return global_idx(ctx, 8, r);
895}
896
898{
899 jsstr_t *ret;
900
901 TRACE("\n");
902
903 ret = jsstr_substr(ctx->last_match, 0, ctx->last_match_index);
904 if(!ret)
905 return E_OUTOFMEMORY;
906
907 *r = jsval_string(ret);
908 return S_OK;
909}
910
912{
913 jsstr_t *ret;
914
915 TRACE("\n");
916
917 ret = jsstr_substr(ctx->last_match, ctx->last_match_index+ctx->last_match_length,
918 jsstr_length(ctx->last_match) - ctx->last_match_index - ctx->last_match_length);
919 if(!ret)
920 return E_OUTOFMEMORY;
921
922 *r = jsval_string(ret);
923 return S_OK;
924}
925
927 jsval_t *r)
928{
929 TRACE("\n");
930
931 switch(flags) {
932 case DISPATCH_METHOD:
933 if(argc) {
934 if(is_object_instance(argv[0])) {
936 if(jsdisp) {
937 if(is_class(jsdisp, JSCLASS_REGEXP)) {
938 if(argc > 1 && !is_undefined(argv[1])) {
939 jsdisp_release(jsdisp);
941 }
942
943 if(r)
944 *r = jsval_obj(jsdisp);
945 else
946 jsdisp_release(jsdisp);
947 return S_OK;
948 }
949 jsdisp_release(jsdisp);
950 }
951 }
952 }
953 /* fall through */
954 case DISPATCH_CONSTRUCT: {
955 jsdisp_t *ret;
957
958 if(!argc) {
959 FIXME("no args\n");
960 return E_NOTIMPL;
961 }
962
963 hres = create_regexp_var(ctx, argv[0], argc > 1 ? argv+1 : NULL, &ret);
964 if(FAILED(hres))
965 return hres;
966
967 if(r)
968 *r = jsval_obj(ret);
969 else
971 return S_OK;
972 }
973 default:
974 FIXME("unimplemented flags: %x\n", flags);
975 return E_NOTIMPL;
976 }
977
978 return S_OK;
979}
980
993};
994
1000 NULL,
1001 NULL
1002};
1003
1005{
1006 RegExpInstance *regexp;
1007 HRESULT hres;
1008
1009 static const WCHAR RegExpW[] = {'R','e','g','E','x','p',0};
1010
1011 hres = alloc_regexp(ctx, object_prototype, &regexp);
1012 if(FAILED(hres))
1013 return hres;
1014
1016 PROPF_CONSTR|2, &regexp->dispex, ret);
1017
1018 jsdisp_release(&regexp->dispex);
1019 return hres;
1020}
1021
1023{
1024 const WCHAR *p;
1025 DWORD flags = 0;
1026
1027 for (p = str; p < str+str_len; p++) {
1028 switch (*p) {
1029 case 'g':
1030 flags |= REG_GLOB;
1031 break;
1032 case 'i':
1033 flags |= REG_FOLD;
1034 break;
1035 case 'm':
1037 break;
1038 case 'y':
1039 flags |= REG_STICKY;
1040 break;
1041 default:
1042 WARN("wrong flag %c\n", *p);
1043 return E_FAIL;
1044 }
1045 }
1046
1047 *ret = flags;
1048 return S_OK;
1049}
static int argc
Definition: ServiceArgs.c:12
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
HRESULT create_array(script_ctx_t *ctx, DWORD length, jsdisp_t **ret)
Definition: array.c:1381
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
HRESULT throw_type_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:440
HRESULT throw_regexp_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:430
HRESULT create_builtin_constructor(script_ctx_t *ctx, builtin_invoke_t value_proc, const WCHAR *name, const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret)
Definition: function.c:686
void clear_ei(script_ctx_t *ctx)
Definition: engine.c:430
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
const GLdouble * v
Definition: gl.h:2040
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLuint index
Definition: glext.h:6031
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const WCHAR inputW[]
Definition: htmlelem.c:31
_Check_return_ _CRTIMP double __cdecl floor(_In_ double x)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, jsval_t val)
Definition: dispex.c:1344
HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *constr)
Definition: dispex.c:1030
jsdisp_t * iface_to_jsdisp(IDispatch *iface)
Definition: dispex.c:1060
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val)
Definition: dispex.c:1349
HRESULT builtin_set_const(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t value)
Definition: dispex.c:555
static const WCHAR RegExpW[]
Definition: global.c:50
HRESULT regexp_execute(regexp_t *regexp, void *cx, heap_pool_t *pool, const WCHAR *str, DWORD str_len, match_state_t *result)
Definition: regexp.c:3140
regexp_t * regexp_new(void *cx, heap_pool_t *pool, const WCHAR *str, DWORD str_len, WORD flags, BOOL flat)
Definition: regexp.c:3195
void regexp_destroy(regexp_t *re)
Definition: regexp.c:3181
#define REG_FOLD
Definition: regexp.h:36
#define REG_MULTILINE
Definition: regexp.h:38
#define REG_STICKY
Definition: regexp.h:39
#define REG_GLOB
Definition: regexp.h:37
static match_state_t * alloc_match_state(regexp_t *regexp, heap_pool_t *pool, const WCHAR *pos)
Definition: regexp.h:71
#define PROPF_CONSTR
Definition: jscript.h:98
static BOOL is_vclass(vdisp_t *vdisp, jsclass_t class)
Definition: jscript.h:509
#define DEFAULT_FUNCTION_VALUE
Definition: jscript.h:315
void heap_pool_clear(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:146
#define REM_CHECK_GLOBAL
Definition: jscript.h:489
heap_pool_t * heap_pool_mark(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:182
static void jsdisp_release(jsdisp_t *jsdisp)
Definition: jscript.h:268
#define REM_NO_CTX_UPDATE
Definition: jscript.h:491
HRESULT to_number(script_ctx_t *, jsval_t, double *) DECLSPEC_HIDDEN
Definition: jsutils.c:609
#define REM_RESET_INDEX
Definition: jscript.h:490
#define JS_E_FUNCTION_EXPECTED
Definition: jscript.h:552
#define PROPF_METHOD
Definition: jscript.h:97
static BOOL is_int32(double d)
Definition: jscript.h:514
#define REM_NO_PARENS
Definition: jscript.h:493
static IDispatch * to_disp(jsdisp_t *jsdisp)
Definition: jscript.h:245
#define REM_ALLOC_RESULT
Definition: jscript.h:492
@ JSCLASS_FUNCTION
Definition: jscript.h:126
@ JSCLASS_REGEXP
Definition: jscript.h:131
#define JS_E_REGEXP_SYNTAX
Definition: jscript.h:563
const char * debugstr_jsval(const jsval_t) DECLSPEC_HIDDEN
Definition: jsutils.c:35
HRESULT to_flat_string(script_ctx_t *, jsval_t, jsstr_t **, const WCHAR **) DECLSPEC_HIDDEN
Definition: jsutils.c:798
static BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
Definition: jscript.h:504
static const WCHAR idx8W[]
Definition: jsregexp.c:58
static HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, jsstr_t *jsstr, BOOL gflag, match_result_t **match_result, DWORD *result_cnt)
Definition: jsregexp.c:182
static const WCHAR leftContextW[]
Definition: jsregexp.c:46
static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: jsregexp.c:533
static const builtin_info_t RegExpInst_info
Definition: jsregexp.c:612
static const WCHAR lastIndexW[]
Definition: jsregexp.c:41
static const WCHAR idx1W[]
Definition: jsregexp.c:51
static const WCHAR idx9W[]
Definition: jsregexp.c:59
static HRESULT alloc_regexp(script_ctx_t *ctx, jsdisp_t *object_prototype, RegExpInstance **ret)
Definition: jsregexp.c:621
static HRESULT RegExpConstr_get_idx1(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:843
static HRESULT RegExpConstr_get_idx4(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:861
static const WCHAR idx6W[]
Definition: jsregexp.c:56
static HRESULT RegExp_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: jsregexp.c:557
static const builtin_prop_t RegExpConstr_props[]
Definition: jsregexp.c:981
HRESULT create_regexp_var(script_ctx_t *ctx, jsval_t src_arg, jsval_t *flags_arg, jsdisp_t **ret)
Definition: jsregexp.c:674
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *jsstr, jsval_t *r)
Definition: jsregexp.c:727
static HRESULT RegExpConstr_get_idx2(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:849
static const WCHAR rightContextW[]
Definition: jsregexp.c:48
static const WCHAR testW[]
Definition: jsregexp.c:44
static HRESULT RegExpConstr_get_leftContext(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:897
static HRESULT RegExpConstr_get_idx8(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:885
static RegExpInstance * regexp_from_vdisp(vdisp_t *vdisp)
Definition: jsregexp.c:66
static HRESULT global_idx(script_ctx_t *ctx, DWORD idx, jsval_t *r)
Definition: jsregexp.c:831
static const WCHAR multilineW[]
Definition: jsregexp.c:40
static const WCHAR idx3W[]
Definition: jsregexp.c:53
static const WCHAR sourceW[]
Definition: jsregexp.c:37
static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, DWORD rem_flags, jsstr_t *jsstr, const WCHAR *str, match_state_t *ret)
Definition: jsregexp.c:78
static HRESULT RegExp_get_global(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:259
static RegExpInstance * regexp_from_jsdisp(jsdisp_t *jsdisp)
Definition: jsregexp.c:61
HRESULT create_regexp_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret)
Definition: jsregexp.c:1004
static const builtin_prop_t RegExp_props[]
Definition: jsregexp.c:584
static const WCHAR ignoreCaseW[]
Definition: jsregexp.c:39
static HRESULT RegExpConstr_get_idx6(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:873
static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input_str, const match_state_t *result, IDispatch **ret)
Definition: jsregexp.c:372
static const WCHAR idx7W[]
Definition: jsregexp.c:57
static const builtin_info_t RegExpConstr_info
Definition: jsregexp.c:995
static const WCHAR globalW[]
Definition: jsregexp.c:38
static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: jsregexp.c:497
static HRESULT RegExpConstr_get_rightContext(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:911
static HRESULT RegExpConstr_get_idx9(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:891
static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: jsregexp.c:926
HRESULT regexp_match_next(script_ctx_t *ctx, jsdisp_t *dispex, DWORD rem_flags, jsstr_t *jsstr, match_state_t **ret)
Definition: jsregexp.c:125
static HRESULT RegExp_set_lastIndex(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t value)
Definition: jsregexp.c:307
static const WCHAR toStringW[]
Definition: jsregexp.c:42
static const WCHAR idx4W[]
Definition: jsregexp.c:54
HRESULT create_regexp(script_ctx_t *ctx, jsstr_t *src, DWORD flags, jsdisp_t **ret)
Definition: jsregexp.c:644
static HRESULT RegExpConstr_get_idx5(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:867
static INT index_from_val(script_ctx_t *ctx, jsval_t v)
Definition: jsregexp.c:283
static HRESULT RegExp_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: jsregexp.c:323
static const WCHAR idx5W[]
Definition: jsregexp.c:55
static const WCHAR idx2W[]
Definition: jsregexp.c:52
static HRESULT RegExp_get_source(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:251
static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg, jsstr_t **input, match_state_t **result, BOOL *ret)
Definition: jsregexp.c:442
static void set_last_index(RegExpInstance *This, DWORD last_index)
Definition: jsregexp.c:71
static HRESULT RegExpConstr_get_idx7(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:879
static HRESULT RegExp_get_lastIndex(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:298
static HRESULT RegExp_get_multiline(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:275
static void RegExp_destructor(jsdisp_t *dispex)
Definition: jsregexp.c:573
static const WCHAR execW[]
Definition: jsregexp.c:43
static const builtin_info_t RegExp_info
Definition: jsregexp.c:595
static HRESULT RegExp_get_ignoreCase(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:267
static const builtin_prop_t RegExpInst_props[]
Definition: jsregexp.c:604
static HRESULT RegExpConstr_get_idx3(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: jsregexp.c:855
HRESULT parse_regexp_flags(const WCHAR *str, DWORD str_len, DWORD *ret)
Definition: jsregexp.c:1022
jsstr_t * jsstr_alloc_len(const WCHAR *buf, unsigned len)
Definition: jsstr.c:86
jsstr_t * jsstr_undefined(void)
Definition: jsstr.c:293
jsstr_t * jsstr_empty(void)
Definition: jsstr.c:288
jsstr_t * jsstr_alloc_buf(unsigned len, WCHAR **buf)
Definition: jsstr.c:69
static jsstr_t * jsstr_substr(jsstr_t *str, unsigned off, unsigned len)
Definition: jsstr.h:163
static jsstr_t * jsstr_addref(jsstr_t *str)
Definition: jsstr.h:116
static const WCHAR * jsstr_flatten(jsstr_t *str)
Definition: jsstr.h:139
static void jsstr_release(jsstr_t *str)
Definition: jsstr.h:110
static unsigned jsstr_length(jsstr_t *str)
Definition: jsstr.h:58
static unsigned jsstr_flush(jsstr_t *str, WCHAR *buf)
Definition: jsstr.h:148
HRESULT jsval_copy(jsval_t v, jsval_t *r)
Definition: jsutils.c:231
void jsval_release(jsval_t val)
Definition: jsutils.c:191
static jsval_t jsval_null(void)
Definition: jsval.h:130
static jsval_t jsval_string(jsstr_t *str)
Definition: jsval.h:109
static jsval_t jsval_obj(jsdisp_t *obj)
Definition: jsval.h:125
static jsval_t jsval_bool(BOOL b)
Definition: jsval.h:101
static jsstr_t * get_string(jsval_t v)
Definition: jsval.h:229
static BOOL is_undefined(jsval_t v)
Definition: jsval.h:171
static jsval_t jsval_disp(IDispatch *obj)
Definition: jsval.h:117
static IDispatch * get_object(jsval_t v)
Definition: jsval.h:219
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:166
static jsval_t jsval_number(double n)
Definition: jsval.h:144
#define f
Definition: ke_i.h:83
#define b
Definition: ke_i.h:79
#define debugstr_wn
Definition: kernel32.h:33
char string[160]
Definition: util.h:11
static PVOID ptr
Definition: dispmode.c:27
HRESULT hres
Definition: protocol.c:465
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
#define DISPATCH_METHOD
Definition: oleauto.h:1006
static BOOL is_string(parse_buffer *buf)
Definition: parsing.c:600
const WCHAR * str
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
jsstr_t * str
Definition: jsregexp.c:32
jsdisp_t dispex
Definition: jsregexp.c:29
jsval_t last_index_val
Definition: jsregexp.c:34
INT last_index
Definition: jsregexp.c:33
regexp_t * jsregexp
Definition: jsregexp.c:31
Definition: jsstr.h:39
Definition: jsval.h:54
Definition: match.c:28
WORD flags
Definition: regexp.h:57
union vdisp_t::@443 u
jsdisp_t * jsdisp
Definition: jscript.h:144
#define str_len
Definition: treelist.c:89
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
Definition: pdh_main.c:94
int ret
#define S_FALSE
Definition: winerror.h:2357
__wchar_t WCHAR
Definition: xmlstorage.h:180