Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

regexec.c
Go to the documentation of this file.
1 /**********************************************************************
2 regexec.c - Onigmo (Oniguruma-mod) (regular expression library)
3 **********************************************************************/
4 /*-
5 * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
6 * Copyright (c) 2011-2013 K.Takata <kentkt AT csc DOT jp>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #include "regint.h"
32
33 /* #define USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
34
35 #ifdef USE_CRNL_AS_LINE_TERMINATOR
36 #define ONIGENC_IS_MBC_CRNL(enc,p,end) \
37 (ONIGENC_MBC_TO_CODE(enc,p,end) == 13 && \
38 ONIGENC_MBC_TO_CODE(enc,(p+enclen(enc,p,end)),end) == 10)
39 #define ONIGENC_IS_MBC_NEWLINE_EX(enc,p,start,end,option,check_prev) \
40 is_mbc_newline_ex((enc),(p),(start),(end),(option),(check_prev))
41 static int
42 is_mbc_newline_ex(OnigEncoding enc, const UChar *p, const UChar *start,
43 const UChar *end, OnigOptionType option, int check_prev)
44 {
45 if (IS_NEWLINE_CRLF(option)) {
46 if (ONIGENC_MBC_TO_CODE(enc, p, end) == 0x0a) {
47 if (check_prev) {
48 const UChar *prev = onigenc_get_prev_char_head(enc, start, p, end);
49 if ((prev != NULL) && ONIGENC_MBC_TO_CODE(enc, prev, end) == 0x0d)
50 return 0;
51 else
52 return 1;
53 }
54 else
55 return 1;
56 }
57 else {
58 const UChar *pnext = p + enclen(enc, p, end);
59 if (pnext < end &&
60 ONIGENC_MBC_TO_CODE(enc, p, end) == 0x0d &&
61 ONIGENC_MBC_TO_CODE(enc, pnext, end) == 0x0a)
62 return 1;
63 if (ONIGENC_IS_MBC_NEWLINE(enc, p, end))
64 return 1;
65 return 0;
66 }
67 }
68 else {
69 return ONIGENC_IS_MBC_NEWLINE(enc, p, end);
70 }
71 }
72 #else /* USE_CRNL_AS_LINE_TERMINATOR */
73 #define ONIGENC_IS_MBC_NEWLINE_EX(enc,p,start,end,option,check_prev) \
74 ONIGENC_IS_MBC_NEWLINE((enc), (p), (end))
75 #endif /* USE_CRNL_AS_LINE_TERMINATOR */
76
77 #ifdef USE_CAPTURE_HISTORY
78 static void history_tree_free(OnigCaptureTreeNode* node);
79
80 static void
81 history_tree_clear(OnigCaptureTreeNode* node)
82 {
83 int i;
84
85 if (IS_NOT_NULL(node)) {
86 for (i = 0; i < node->num_childs; i++) {
87 if (IS_NOT_NULL(node->childs[i])) {
88 history_tree_free(node->childs[i]);
89 }
90 }
91 for (i = 0; i < node->allocated; i++) {
92 node->childs[i] = (OnigCaptureTreeNode* )0;
93 }
94 node->num_childs = 0;
95 node->beg = ONIG_REGION_NOTPOS;
96 node->end = ONIG_REGION_NOTPOS;
97 node->group = -1;
98 xfree(node->childs);
99 node->childs = (OnigCaptureTreeNode** )0;
100 }
101 }
102
103 static void
104 history_tree_free(OnigCaptureTreeNode* node)
105 {
106 history_tree_clear(node);
107 xfree(node);
108 }
109
110 static void
111 history_root_free(OnigRegion* r)
112 {
113 if (IS_NOT_NULL(r->history_root)) {
114 history_tree_free(r->history_root);
115 r->history_root = (OnigCaptureTreeNode* )0;
116 }
117 }
118
119 static OnigCaptureTreeNode*
120 history_node_new(void)
121 {
122 OnigCaptureTreeNode* node;
123
124 node = (OnigCaptureTreeNode* )xmalloc(sizeof(OnigCaptureTreeNode));
125 CHECK_NULL_RETURN(node);
126 node->childs = (OnigCaptureTreeNode** )0;
127 node->allocated = 0;
128 node->num_childs = 0;
129 node->group = -1;
130 node->beg = ONIG_REGION_NOTPOS;
131 node->end = ONIG_REGION_NOTPOS;
132
133 return node;
134 }
135
136 static int
137 history_tree_add_child(OnigCaptureTreeNode* parent, OnigCaptureTreeNode* child)
138 {
139 #define HISTORY_TREE_INIT_ALLOC_SIZE 8
140
141 if (parent->num_childs >= parent->allocated) {
142 int n, i;
143
144 if (IS_NULL(parent->childs)) {
145 n = HISTORY_TREE_INIT_ALLOC_SIZE;
146 parent->childs =
147 (OnigCaptureTreeNode** )xmalloc(sizeof(OnigCaptureTreeNode*) * n);
148 CHECK_NULL_RETURN_MEMERR(parent->childs);
149 }
150 else {
151 OnigCaptureTreeNode** tmp;
152 n = parent->allocated * 2;
153 tmp =
154 (OnigCaptureTreeNode** )xrealloc(parent->childs,
155 sizeof(OnigCaptureTreeNode*) * n);
156 if (tmp == 0) {
157 history_tree_clear(parent);
158 return ONIGERR_MEMORY;
159 }
160 parent->childs = tmp;
161 }
162 for (i = parent->allocated; i < n; i++) {
163 parent->childs[i] = (OnigCaptureTreeNode* )0;
164 }
165 parent->allocated = n;
166 }
167
168 parent->childs[parent->num_childs] = child;
169 parent->num_childs++;
170 return 0;
171 }
172
173 static OnigCaptureTreeNode*
174 history_tree_clone(OnigCaptureTreeNode* node)
175 {
176 int i, r;
177 OnigCaptureTreeNode *clone, *child;
178
179 clone = history_node_new();
180 CHECK_NULL_RETURN(clone);
181
182 clone->beg = node->beg;
183 clone->end = node->end;
184 for (i = 0; i < node->num_childs; i++) {
185 child = history_tree_clone(node->childs[i]);
186 if (IS_NULL(child)) {
187 history_tree_free(clone);
188 return (OnigCaptureTreeNode* )0;
189 }
190 r = history_tree_add_child(clone, child);
191 if (r != 0) {
192 history_tree_free(child);
193 history_tree_free(clone);
194 return (OnigCaptureTreeNode* )0;
195 }
196 }
197
198 return clone;
199 }
200
201 extern OnigCaptureTreeNode*
202 onig_get_capture_tree(OnigRegion* region)
203 {
204 return region->history_root;
205 }
206 #endif /* USE_CAPTURE_HISTORY */
207
208 extern void
209 onig_region_clear(OnigRegion* region)
210 {
211 int i;
212
213 for (i = 0; i < region->num_regs; i++) {
214 region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
215 }
216 #ifdef USE_CAPTURE_HISTORY
217 history_root_free(region);
218 #endif
219 }
220
221 extern int
222 onig_region_resize(OnigRegion* region, int n)
223 {
224 region->num_regs = n;
225
226 if (n < ONIG_NREGION)
227 n = ONIG_NREGION;
228
229 if (region->allocated == 0) {
230 region->beg = (OnigPosition* )xmalloc(n * sizeof(OnigPosition));
231 if (region->beg == 0)
232 return ONIGERR_MEMORY;
233
234 region->end = (OnigPosition* )xmalloc(n * sizeof(OnigPosition));
235 if (region->end == 0) {
236 xfree(region->beg);
237 return ONIGERR_MEMORY;
238 }
239
240 region->allocated = n;
241 }
242 else if (region->allocated < n) {
243 OnigPosition *tmp;
244
245 region->allocated = 0;
246 tmp = (OnigPosition* )xrealloc(region->beg, n * sizeof(OnigPosition));
247 if (tmp == 0) {
248 xfree(region->beg);
249 xfree(region->end);
250 return ONIGERR_MEMORY;
251 }
252 region->beg = tmp;
253 tmp = (OnigPosition* )xrealloc(region->end, n * sizeof(OnigPosition));
254 if (tmp == 0) {
255 xfree(region->beg);
256 xfree(region->end);
257 return ONIGERR_MEMORY;
258 }
259 region->end = tmp;
260
261 region->allocated = n;
262 }
263
264 return 0;
265 }
266
267 static int
268 onig_region_resize_clear(OnigRegion* region, int n)
269 {
270 int r;
271
272 r = onig_region_resize(region, n);
273 if (r != 0) return r;
274 onig_region_clear(region);
275 return 0;
276 }
277
278 extern int
279 onig_region_set(OnigRegion* region, int at, int beg, int end)
280 {
281 if (at < 0) return ONIGERR_INVALID_ARGUMENT;
282
283 if (at >= region->allocated) {
284 int r = onig_region_resize(region, at + 1);
285 if (r < 0) return r;
286 }
287
288 region->beg[at] = beg;
289 region->end[at] = end;
290 return 0;
291 }
292
293 extern void
294 onig_region_init(OnigRegion* region)
295 {
296 region->num_regs = 0;
297 region->allocated = 0;
298 region->beg = (OnigPosition* )0;
299 region->end = (OnigPosition* )0;
300 region->history_root = (OnigCaptureTreeNode* )0;
301 }
302
303 extern OnigRegion*
304 onig_region_new(void)
305 {
306 OnigRegion* r;
307
308 r = (OnigRegion* )xmalloc(sizeof(OnigRegion));
309 if (r)
310 onig_region_init(r);
311 return r;
312 }
313
314 extern void
315 onig_region_free(OnigRegion* r, int free_self)
316 {
317 if (r) {
318 if (r->allocated > 0) {
319 if (r->beg) xfree(r->beg);
320 if (r->end) xfree(r->end);
321 r->allocated = 0;
322 }
323 #ifdef USE_CAPTURE_HISTORY
324 history_root_free(r);
325 #endif
326 if (free_self) xfree(r);
327 }
328 }
329
330 extern void
331 onig_region_copy(OnigRegion* to, OnigRegion* from)
332 {
333 #define RREGC_SIZE (sizeof(int) * from->num_regs)
334 int i, r;
335
336 if (to == from) return;
337
338 r = onig_region_resize(to, from->num_regs);
339 if (r) return;
340
341 for (i = 0; i < from->num_regs; i++) {
342 to->beg[i] = from->beg[i];
343 to->end[i] = from->end[i];
344 }
345 to->num_regs = from->num_regs;
346
347 #ifdef USE_CAPTURE_HISTORY
348 history_root_free(to);
349
350 if (IS_NOT_NULL(from->history_root)) {
351 to->history_root = history_tree_clone(from->history_root);
352 }
353 #endif
354 }
355
356
358 #define INVALID_STACK_INDEX -1
359
360 /* stack type */
361 /* used by normal-POP */
362 #define STK_ALT 0x0001
363 #define STK_LOOK_BEHIND_NOT 0x0002
364 #define STK_POS_NOT 0x0003
365 /* handled by normal-POP */
366 #define STK_MEM_START 0x0100
367 #define STK_MEM_END 0x8200
368 #define STK_REPEAT_INC 0x0300
369 #define STK_STATE_CHECK_MARK 0x1000
370 /* avoided by normal-POP */
371 #define STK_NULL_CHECK_START 0x3000
372 #define STK_NULL_CHECK_END 0x5000 /* for recursive call */
373 #define STK_MEM_END_MARK 0x8400
374 #define STK_POS 0x0500 /* used when POP-POS */
375 #define STK_STOP_BT 0x0600 /* mark for "(?>...)" */
376 #define STK_REPEAT 0x0700
377 #define STK_CALL_FRAME 0x0800
378 #define STK_RETURN 0x0900
379 #define STK_VOID 0x0a00 /* for fill a blank */
380
381 /* stack type check mask */
382 #define STK_MASK_POP_USED 0x00ff
383 #define STK_MASK_TO_VOID_TARGET 0x10ff
384 #define STK_MASK_MEM_END_OR_MARK 0x8000 /* MEM_END or MEM_END_MARK */
385
386 #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
387 #define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
388 (msa).stack_p = (void* )0;\
389 (msa).options = (arg_option);\
390 (msa).region = (arg_region);\
391 (msa).start = (arg_start);\
392 (msa).gpos = (arg_gpos);\
393 (msa).best_len = ONIG_MISMATCH;\
394 } while(0)
395 #else
396 #define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
397 (msa).stack_p = (void* )0;\
398 (msa).options = (arg_option);\
399 (msa).region = (arg_region);\
400 (msa).start = (arg_start);\
401 (msa).gpos = (arg_gpos);\
402 } while(0)
403 #endif
404
405 #ifdef USE_COMBINATION_EXPLOSION_CHECK
406
407 #define STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE 16
408
409 #define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num) do { \
410 if ((state_num) > 0 && str_len >= STATE_CHECK_STRING_THRESHOLD_LEN) {\
411 unsigned int size = (unsigned int )(((str_len) + 1) * (state_num) + 7) >> 3;\
412 offset = ((offset) * (state_num)) >> 3;\
413 if (size > 0 && offset < size && size < STATE_CHECK_BUFF_MAX_SIZE) {\
414 if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {\
415 (msa).state_check_buff = (void* )xmalloc(size);\
416 CHECK_NULL_RETURN_MEMERR((msa).state_check_buff);\
417 }\
418 else \
419 (msa).state_check_buff = (void* )xalloca(size);\
420 xmemset(((char* )((msa).state_check_buff)+(offset)), 0, \
421 (size_t )(size - (offset))); \
422 (msa).state_check_buff_size = size;\
423 }\
424 else {\
425 (msa).state_check_buff = (void* )0;\
426 (msa).state_check_buff_size = 0;\
427 }\
428 }\
429 else {\
430 (msa).state_check_buff = (void* )0;\
431 (msa).state_check_buff_size = 0;\
432 }\
433 } while(0)
434
435 #define MATCH_ARG_FREE(msa) do {\
436 if ((msa).stack_p) xfree((msa).stack_p);\
437 if ((msa).state_check_buff_size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) { \
438 if ((msa).state_check_buff) xfree((msa).state_check_buff);\
439 }\
440 } while(0)
441 #else /* USE_COMBINATION_EXPLOSION_CHECK */
442 #define MATCH_ARG_FREE(msa) if ((msa).stack_p) xfree((msa).stack_p)
443 #endif /* USE_COMBINATION_EXPLOSION_CHECK */
444
445
446
447 #define MAX_PTR_NUM 100
448
449 #define STACK_INIT(alloc_addr, heap_addr, ptr_num, stack_num) do {\
450 if (ptr_num > MAX_PTR_NUM) {\
451 alloc_addr = (char* )xmalloc(sizeof(OnigStackIndex) * (ptr_num));\
452 heap_addr = alloc_addr;\
453 if (msa->stack_p) {\
454 stk_alloc = (OnigStackType* )(msa->stack_p);\
455 stk_base = stk_alloc;\
456 stk = stk_base;\
457 stk_end = stk_base + msa->stack_n;\
458 } else {\
459 stk_alloc = (OnigStackType* )xalloca(sizeof(OnigStackType) * (stack_num));\
460 stk_base = stk_alloc;\
461 stk = stk_base;\
462 stk_end = stk_base + (stack_num);\
463 }\
464 } else if (msa->stack_p) {\
465 alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num));\
466 heap_addr = NULL;\
467 stk_alloc = (OnigStackType* )(msa->stack_p);\
468 stk_base = stk_alloc;\
469 stk = stk_base;\
470 stk_end = stk_base + msa->stack_n;\
471 }\
472 else {\
473 alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num)\
474 + sizeof(OnigStackType) * (stack_num));\
475 heap_addr = NULL;\
476 stk_alloc = (OnigStackType* )(alloc_addr + sizeof(OnigStackIndex) * (ptr_num));\
477 stk_base = stk_alloc;\
478 stk = stk_base;\
479 stk_end = stk_base + (stack_num);\
480 }\
481 } while(0)
482
483 #define STACK_SAVE do{\
484 if (stk_base != stk_alloc) {\
485 msa->stack_p = stk_base;\
486 msa->stack_n = stk_end - stk_base; /* TODO: check overflow */\
487 };\
488 } while(0)
489
490 static unsigned int MatchStackLimitSize = DEFAULT_MATCH_STACK_LIMIT_SIZE;
491
492 extern unsigned int
493 onig_get_match_stack_limit_size(void)
494 {
495 return MatchStackLimitSize;
496 }
497
498 extern int
499 onig_set_match_stack_limit_size(unsigned int size)
500 {
501 MatchStackLimitSize = size;
502 return 0;
503 }
504
505 static int
506 stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
507 OnigStackType** arg_stk, OnigStackType* stk_alloc, OnigMatchArg* msa)
508 {
509 size_t n;
510 OnigStackType *x, *stk_base, *stk_end, *stk;
511
512 stk_base = *arg_stk_base;
513 stk_end = *arg_stk_end;
514 stk = *arg_stk;
515
516 n = stk_end - stk_base;
517 if (stk_base == stk_alloc && IS_NULL(msa->stack_p)) {
518 x = (OnigStackType* )xmalloc(sizeof(OnigStackType) * n * 2);
519 if (IS_NULL(x)) {
520 STACK_SAVE;
521 return ONIGERR_MEMORY;
522 }
523 xmemcpy(x, stk_base, n * sizeof(OnigStackType));
524 n *= 2;
525 }
526 else {
527 unsigned int limit_size = MatchStackLimitSize;
528 n *= 2;
529 if (limit_size != 0 && n > limit_size) {
530 if ((unsigned int )(stk_end - stk_base) == limit_size)
531 return ONIGERR_MATCH_STACK_LIMIT_OVER;
532 else
533 n = limit_size;
534 }
535 x = (OnigStackType* )xrealloc(stk_base, sizeof(OnigStackType) * n);
536 if (IS_NULL(x)) {
537 STACK_SAVE;
538 return ONIGERR_MEMORY;
539 }
540 }
541 *arg_stk = x + (stk - stk_base);
542 *arg_stk_base = x;
543 *arg_stk_end = x + n;
544 return 0;
545 }
546
547 #define STACK_ENSURE(n) do {\
548 if (stk_end - stk < (n)) {\
549 int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\
550 if (r != 0) {\
551 STACK_SAVE;\
552 if (xmalloc_base) xfree(xmalloc_base);\
553 return r;\
554 }\
555 }\
556 } while(0)
557
558 #define STACK_AT(index) (stk_base + (index))
559 #define GET_STACK_INDEX(stk) ((stk) - stk_base)
560
561 #define STACK_PUSH_TYPE(stack_type) do {\
562 STACK_ENSURE(1);\
563 stk->type = (stack_type);\
564 STACK_INC;\
565 } while(0)
566
567 #define IS_TO_VOID_TARGET(stk) (((stk)->type & STK_MASK_TO_VOID_TARGET) != 0)
568
569 #ifdef USE_COMBINATION_EXPLOSION_CHECK
570 #define STATE_CHECK_POS(s,snum) \
571 (((s) - str) * num_comb_exp_check + ((snum) - 1))
572 #define STATE_CHECK_VAL(v,snum) do {\
573 if (state_check_buff != NULL) {\
574 int x = STATE_CHECK_POS(s,snum);\
575 (v) = state_check_buff[x/8] & (1<<(x%8));\
576 }\
577 else (v) = 0;\
578 } while(0)
579
580
581 #define ELSE_IF_STATE_CHECK_MARK(stk) \
582 else if ((stk)->type == STK_STATE_CHECK_MARK) { \
583 int x = STATE_CHECK_POS(stk->u.state.pstr, stk->u.state.state_check);\
584 state_check_buff[x/8] |= (1<<(x%8)); \
585 }
586
587 #define STACK_PUSH(stack_type,pat,s,sprev,keep) do {\
588 STACK_ENSURE(1);\
589 stk->type = (stack_type);\
590 stk->u.state.pcode = (pat);\
591 stk->u.state.pstr = (s);\
592 stk->u.state.pstr_prev = (sprev);\
593 stk->u.state.state_check = 0;\
594 stk->u.state.pkeep = (keep);\
595 STACK_INC;\
596 } while(0)
597
598 #define STACK_PUSH_ENSURED(stack_type,pat) do {\
599 stk->type = (stack_type);\
600 stk->u.state.pcode = (pat);\
601 stk->u.state.state_check = 0;\
602 STACK_INC;\
603 } while(0)
604
605 #define STACK_PUSH_ALT_WITH_STATE_CHECK(pat,s,sprev,snum,keep) do {\
606 STACK_ENSURE(1);\
607 stk->type = STK_ALT;\
608 stk->u.state.pcode = (pat);\
609 stk->u.state.pstr = (s);\
610 stk->u.state.pstr_prev = (sprev);\
611 stk->u.state.state_check = ((state_check_buff != NULL) ? (snum) : 0);\
612 stk->u.state.pkeep = (keep);\
613 STACK_INC;\
614 } while(0)
615
616 #define STACK_PUSH_STATE_CHECK(s,snum) do {\
617 if (state_check_buff != NULL) {\
618 STACK_ENSURE(1);\
619 stk->type = STK_STATE_CHECK_MARK;\
620 stk->u.state.pstr = (s);\
621 stk->u.state.state_check = (snum);\
622 STACK_INC;\
623 }\
624 } while(0)
625
626 #else /* USE_COMBINATION_EXPLOSION_CHECK */
627
628 #define ELSE_IF_STATE_CHECK_MARK(stk)
629
630 #define STACK_PUSH(stack_type,pat,s,sprev,keep) do {\
631 STACK_ENSURE(1);\
632 stk->type = (stack_type);\
633 stk->u.state.pcode = (pat);\
634 stk->u.state.pstr = (s);\
635 stk->u.state.pstr_prev = (sprev);\
636 stk->u.state.pkeep = (keep);\
637 STACK_INC;\
638 } while(0)
639
640 #define STACK_PUSH_ENSURED(stack_type,pat) do {\
641 stk->type = (stack_type);\
642 stk->u.state.pcode = (pat);\
643 STACK_INC;\
644 } while(0)
645 #endif /* USE_COMBINATION_EXPLOSION_CHECK */
646
647 #define STACK_PUSH_ALT(pat,s,sprev,keep) STACK_PUSH(STK_ALT,pat,s,sprev,keep)
648 #define STACK_PUSH_POS(s,sprev,keep) STACK_PUSH(STK_POS,NULL_UCHARP,s,sprev,keep)
649 #define STACK_PUSH_POS_NOT(pat,s,sprev,keep) STACK_PUSH(STK_POS_NOT,pat,s,sprev,keep)
650 #define STACK_PUSH_STOP_BT STACK_PUSH_TYPE(STK_STOP_BT)
651 #define STACK_PUSH_LOOK_BEHIND_NOT(pat,s,sprev,keep) \
652 STACK_PUSH(STK_LOOK_BEHIND_NOT,pat,s,sprev,keep)
653
654 #define STACK_PUSH_REPEAT(id, pat) do {\
655 STACK_ENSURE(1);\
656 stk->type = STK_REPEAT;\
657 stk->u.repeat.num = (id);\
658 stk->u.repeat.pcode = (pat);\
659 stk->u.repeat.count = 0;\
660 STACK_INC;\
661 } while(0)
662
663 #define STACK_PUSH_REPEAT_INC(sindex) do {\
664 STACK_ENSURE(1);\
665 stk->type = STK_REPEAT_INC;\
666 stk->u.repeat_inc.si = (sindex);\
667 STACK_INC;\
668 } while(0)
669
670 #define STACK_PUSH_MEM_START(mnum, s) do {\
671 STACK_ENSURE(1);\
672 stk->type = STK_MEM_START;\
673 stk->u.mem.num = (mnum);\
674 stk->u.mem.pstr = (s);\
675 stk->u.mem.start = mem_start_stk[mnum];\
676 stk->u.mem.end = mem_end_stk[mnum];\
677 mem_start_stk[mnum] = GET_STACK_INDEX(stk);\
678 mem_end_stk[mnum] = INVALID_STACK_INDEX;\
679 STACK_INC;\
680 } while(0)
681
682 #define STACK_PUSH_MEM_END(mnum, s) do {\
683 STACK_ENSURE(1);\
684 stk->type = STK_MEM_END;\
685 stk->u.mem.num = (mnum);\
686 stk->u.mem.pstr = (s);\
687 stk->u.mem.start = mem_start_stk[mnum];\
688 stk->u.mem.end = mem_end_stk[mnum];\
689 mem_end_stk[mnum] = GET_STACK_INDEX(stk);\
690 STACK_INC;\
691 } while(0)
692
693 #define STACK_PUSH_MEM_END_MARK(mnum) do {\
694 STACK_ENSURE(1);\
695 stk->type = STK_MEM_END_MARK;\
696 stk->u.mem.num = (mnum);\
697 STACK_INC;\
698 } while(0)
699
700 #define STACK_GET_MEM_START(mnum, k) do {\
701 int level = 0;\
702 k = stk;\
703 while (k > stk_base) {\
704 k--;\
705 if ((k->type & STK_MASK_MEM_END_OR_MARK) != 0 \
706 && k->u.mem.num == (mnum)) {\
707 level++;\
708 }\
709 else if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
710 if (level == 0) break;\
711 level--;\
712 }\
713 }\
714 } while(0)
715
716 #define STACK_GET_MEM_RANGE(k, mnum, start, end) do {\
717 int level = 0;\
718 while (k < stk) {\
719 if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
720 if (level == 0) (start) = k->u.mem.pstr;\
721 level++;\
722 }\
723 else if (k->type == STK_MEM_END && k->u.mem.num == (mnum)) {\
724 level--;\
725 if (level == 0) {\
726 (end) = k->u.mem.pstr;\
727 break;\
728 }\
729 }\
730 k++;\
731 }\
732 } while(0)
733
734 #define STACK_PUSH_NULL_CHECK_START(cnum, s) do {\
735 STACK_ENSURE(1);\
736 stk->type = STK_NULL_CHECK_START;\
737 stk->u.null_check.num = (cnum);\
738 stk->u.null_check.pstr = (s);\
739 STACK_INC;\
740 } while(0)
741
742 #define STACK_PUSH_NULL_CHECK_END(cnum) do {\
743 STACK_ENSURE(1);\
744 stk->type = STK_NULL_CHECK_END;\
745 stk->u.null_check.num = (cnum);\
746 STACK_INC;\
747 } while(0)
748
749 #define STACK_PUSH_CALL_FRAME(pat) do {\
750 STACK_ENSURE(1);\
751 stk->type = STK_CALL_FRAME;\
752 stk->u.call_frame.ret_addr = (pat);\
753 STACK_INC;\
754 } while(0)
755
756 #define STACK_PUSH_RETURN do {\
757 STACK_ENSURE(1);\
758 stk->type = STK_RETURN;\
759 STACK_INC;\
760 } while(0)
761
762
763 #ifdef ONIG_DEBUG
764 #define STACK_BASE_CHECK(p, at) \
765 if ((p) < stk_base) {\
766 fprintf(stderr, "at %s\n", at);\
767 goto stack_error;\
768 }
769 #else
770 #define STACK_BASE_CHECK(p, at)
771 #endif
772
773 #define STACK_POP_ONE do {\
774 stk--;\
775 STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \
776 } while(0)
777
778 #define STACK_POP do {\
779 switch (pop_level) {\
780 case STACK_POP_LEVEL_FREE:\
781 while (1) {\
782 stk--;\
783 STACK_BASE_CHECK(stk, "STACK_POP"); \
784 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
785 ELSE_IF_STATE_CHECK_MARK(stk);\
786 }\
787 break;\
788 case STACK_POP_LEVEL_MEM_START:\
789 while (1) {\
790 stk--;\
791 STACK_BASE_CHECK(stk, "STACK_POP 2"); \
792 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
793 else if (stk->type == STK_MEM_START) {\
794 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
795 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
796 }\
797 ELSE_IF_STATE_CHECK_MARK(stk);\
798 }\
799 break;\
800 default:\
801 while (1) {\
802 stk--;\
803 STACK_BASE_CHECK(stk, "STACK_POP 3"); \
804 if ((stk->type & STK_MASK_POP_USED) != 0) break;\
805 else if (stk->type == STK_MEM_START) {\
806 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
807 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
808 }\
809 else if (stk->type == STK_REPEAT_INC) {\
810 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
811 }\
812 else if (stk->type == STK_MEM_END) {\
813 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
814 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
815 }\
816 ELSE_IF_STATE_CHECK_MARK(stk);\
817 }\
818 break;\
819 }\
820 } while(0)
821
822 #define STACK_POP_TIL_POS_NOT do {\
823 while (1) {\
824 stk--;\
825 STACK_BASE_CHECK(stk, "STACK_POP_TIL_POS_NOT"); \
826 if (stk->type == STK_POS_NOT) break;\
827 else if (stk->type == STK_MEM_START) {\
828 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
829 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
830 }\
831 else if (stk->type == STK_REPEAT_INC) {\
832 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
833 }\
834 else if (stk->type == STK_MEM_END) {\
835 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
836 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
837 }\
838 ELSE_IF_STATE_CHECK_MARK(stk);\
839 }\
840 } while(0)
841
842 #define STACK_POP_TIL_LOOK_BEHIND_NOT do {\
843 while (1) {\
844 stk--;\
845 STACK_BASE_CHECK(stk, "STACK_POP_TIL_LOOK_BEHIND_NOT"); \
846 if (stk->type == STK_LOOK_BEHIND_NOT) break;\
847 else if (stk->type == STK_MEM_START) {\
848 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
849 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
850 }\
851 else if (stk->type == STK_REPEAT_INC) {\
852 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
853 }\
854 else if (stk->type == STK_MEM_END) {\
855 mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
856 mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
857 }\
858 ELSE_IF_STATE_CHECK_MARK(stk);\
859 }\
860 } while(0)
861
862 #define STACK_POS_END(k) do {\
863 k = stk;\
864 while (1) {\
865 k--;\
866 STACK_BASE_CHECK(k, "STACK_POS_END"); \
867 if (IS_TO_VOID_TARGET(k)) {\
868 k->type = STK_VOID;\
869 }\
870 else if (k->type == STK_POS) {\
871 k->type = STK_VOID;\
872 break;\
873 }\
874 }\
875 } while(0)
876
877 #define STACK_STOP_BT_END do {\
878 OnigStackType *k = stk;\
879 while (1) {\
880 k--;\
881 STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \
882 if (IS_TO_VOID_TARGET(k)) {\
883 k->type = STK_VOID;\
884 }\
885 else if (k->type == STK_STOP_BT) {\
886 k->type = STK_VOID;\
887 break;\
888 }\
889 }\
890 } while(0)
891
892 #define STACK_NULL_CHECK(isnull,id,s) do {\
893 OnigStackType* k = stk;\
894 while (1) {\
895 k--;\
896 STACK_BASE_CHECK(k, "STACK_NULL_CHECK"); \
897 if (k->type == STK_NULL_CHECK_START) {\
898 if (k->u.null_check.num == (id)) {\
899 (isnull) = (k->u.null_check.pstr == (s));\
900 break;\
901 }\
902 }\
903 }\
904 } while(0)
905
906 #define STACK_NULL_CHECK_REC(isnull,id,s) do {\
907 int level = 0;\
908 OnigStackType* k = stk;\
909 while (1) {\
910 k--;\
911 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_REC"); \
912 if (k->type == STK_NULL_CHECK_START) {\
913 if (k->u.null_check.num == (id)) {\
914 if (level == 0) {\
915 (isnull) = (k->u.null_check.pstr == (s));\
916 break;\
917 }\
918 else level--;\
919 }\
920 }\
921 else if (k->type == STK_NULL_CHECK_END) {\
922 level++;\
923 }\
924 }\
925 } while(0)
926
927 #define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\
928 OnigStackType* k = stk;\
929 while (1) {\
930 k--;\
931 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST"); \
932 if (k->type == STK_NULL_CHECK_START) {\
933 if (k->u.null_check.num == (id)) {\
934 if (k->u.null_check.pstr != (s)) {\
935 (isnull) = 0;\
936 break;\
937 }\
938 else {\
939 UChar* endp;\
940 (isnull) = 1;\
941 while (k < stk) {\
942 if (k->type == STK_MEM_START) {\
943 if (k->u.mem.end == INVALID_STACK_INDEX) {\
944 (isnull) = 0; break;\
945 }\
946 if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
947 endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
948 else\
949 endp = (UChar* )k->u.mem.end;\
950 if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
951 (isnull) = 0; break;\
952 }\
953 else if (endp != s) {\
954 (isnull) = -1; /* empty, but position changed */ \
955 }\
956 }\
957 k++;\
958 }\
959 break;\
960 }\
961 }\
962 }\
963 }\
964 } while(0)
965
966 #define STACK_NULL_CHECK_MEMST_REC(isnull,id,s,reg) do {\
967 int level = 0;\
968 OnigStackType* k = stk;\
969 while (1) {\
970 k--;\
971 STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST_REC"); \
972 if (k->type == STK_NULL_CHECK_START) {\
973 if (k->u.null_check.num == (id)) {\
974 if (level == 0) {\
975 if (k->u.null_check.pstr != (s)) {\
976 (isnull) = 0;\
977 break;\
978 }\
979 else {\
980 UChar* endp;\
981 (isnull) = 1;\
982 while (k < stk) {\
983 if (k->type == STK_MEM_START) {\
984 if (k->u.mem.end == INVALID_STACK_INDEX) {\
985 (isnull) = 0; break;\
986 }\
987 if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
988 endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
989 else\
990 endp = (UChar* )k->u.mem.end;\
991 if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
992 (isnull) = 0; break;\
993 }\
994 else if (endp != s) {\
995 (isnull) = -1; /* empty, but position changed */ \
996 }\
997 }\
998 k++;\
999 }\
1000 break;\
1001 }\
1002 }\
1003 else {\
1004 level--;\
1005 }\
1006 }\
1007 }\
1008 else if (k->type == STK_NULL_CHECK_END) {\
1009 if (k->u.null_check.num == (id)) level++;\
1010 }\
1011 }\
1012 } while(0)
1013
1014 #define STACK_GET_REPEAT(id, k) do {\
1015 int level = 0;\
1016 k = stk;\
1017 while (1) {\
1018 k--;\
1019 STACK_BASE_CHECK(k, "STACK_GET_REPEAT"); \
1020 if (k->type == STK_REPEAT) {\
1021 if (level == 0) {\
1022 if (k->u.repeat.num == (id)) {\
1023 break;\
1024 }\
1025 }\
1026 }\
1027 else if (k->type == STK_CALL_FRAME) level--;\
1028 else if (k->type == STK_RETURN) level++;\
1029 }\
1030 } while(0)
1031
1032 #define STACK_RETURN(addr) do {\
1033 int level = 0;\
1034 OnigStackType* k = stk;\
1035 while (1) {\
1036 k--;\
1037 STACK_BASE_CHECK(k, "STACK_RETURN"); \
1038 if (k->type == STK_CALL_FRAME) {\
1039 if (level == 0) {\
1040 (addr) = k->u.call_frame.ret_addr;\
1041 break;\
1042 }\
1043 else level--;\
1044 }\
1045 else if (k->type == STK_RETURN)\
1046 level++;\
1047 }\
1048 } while(0)
1049
1050
1051 #define STRING_CMP(s1,s2,len) do {\
1052 while (len-- > 0) {\
1053 if (*s1++ != *s2++) goto fail;\
1054 }\
1055 } while(0)
1056
1057 #define STRING_CMP_IC(case_fold_flag,s1,ps2,len,text_end) do {\
1058 if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len, text_end) == 0) \
1059 goto fail; \
1060 } while(0)
1061
1062 static int string_cmp_ic(OnigEncoding enc, int case_fold_flag,
1063 UChar* s1, UChar** ps2, OnigDistance mblen, const UChar* text_end)
1064 {
1065 UChar buf1[ONIGENC_MBC_CASE_FOLD_MAXLEN];
1066 UChar buf2[ONIGENC_MBC_CASE_FOLD_MAXLEN];
1067 UChar *p1, *p2, *end1, *s2;
1068 int len1, len2;
1069
1070 s2 = *ps2;
1071 end1 = s1 + mblen;
1072 while (s1 < end1) {
1073 len1 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s1, text_end, buf1);
1074 len2 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s2, text_end, buf2);
1075 if (len1 != len2) return 0;
1076 p1 = buf1;
1077 p2 = buf2;
1078 while (len1-- > 0) {
1079 if (*p1 != *p2) return 0;
1080 p1++;
1081 p2++;
1082 }
1083 }
1084
1085 *ps2 = s2;
1086 return 1;
1087 }
1088
1089 #define STRING_CMP_VALUE(s1,s2,len,is_fail) do {\
1090 is_fail = 0;\
1091 while (len-- > 0) {\
1092 if (*s1++ != *s2++) {\
1093 is_fail = 1; break;\
1094 }\
1095 }\
1096 } while(0)
1097
1098 #define STRING_CMP_VALUE_IC(case_fold_flag,s1,ps2,len,text_end,is_fail) do {\
1099 if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len, text_end) == 0) \
1100 is_fail = 1; \
1101 else \
1102 is_fail = 0; \
1103 } while(0)
1104
1105
1106 #define IS_EMPTY_STR (str == end)
1107 #define ON_STR_BEGIN(s) ((s) == str)
1108 #define ON_STR_END(s) ((s) == end)
1109 #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
1110 #define DATA_ENSURE_CHECK1 (s < right_range)
1111 #define DATA_ENSURE_CHECK(n) (s + (n) <= right_range)
1112 #define DATA_ENSURE(n) if (s + (n) > right_range) goto fail
1113 #else
1114 #define DATA_ENSURE_CHECK1 (s < end)
1115 #define DATA_ENSURE_CHECK(n) (s + (n) <= end)
1116 #define DATA_ENSURE(n) if (s + (n) > end) goto fail
1117 #endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
1118
1119
1120 #ifdef USE_CAPTURE_HISTORY
1121 static int
1122 make_capture_history_tree(OnigCaptureTreeNode* node, OnigStackType** kp,
1123 OnigStackType* stk_top, UChar* str, regex_t* reg)
1124 {
1125 int n, r;
1126 OnigCaptureTreeNode* child;
1127 OnigStackType* k = *kp;
1128
1129 while (k < stk_top) {
1130 if (k->type == STK_MEM_START) {
1131 n = k->u.mem.num;
1132 if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP &&
1133 BIT_STATUS_AT(reg->capture_history, n) != 0) {
1134 child = history_node_new();
1135 CHECK_NULL_RETURN_MEMERR(child);
1136 child->group = n;
1137 child->beg = k->u.mem.pstr - str;
1138 r = history_tree_add_child(node, child);
1139 if (r != 0) {
1140 history_tree_free(child);
1141 return r;
1142 }
1143 *kp = (k + 1);
1144 r = make_capture_history_tree(child, kp, stk_top, str, reg);
1145 if (r != 0) return r;
1146
1147 k = *kp;
1148 child->end = k->u.mem.pstr - str;
1149 }
1150 }
1151 else if (k->type == STK_MEM_END) {
1152 if (k->u.mem.num == node->group) {
1153 node->end = k->u.mem.pstr - str;
1154 *kp = k;
1155 return 0;
1156 }
1157 }
1158 k++;
1159 }
1160
1161 return 1; /* 1: root node ending. */
1162 }
1163 #endif /* USE_CAPTURE_HISTORY */
1164
1165 #ifdef USE_BACKREF_WITH_LEVEL
1166 static int mem_is_in_memp(int mem, int num, UChar* memp)
1167 {
1168 int i;
1169 MemNumType m;
1170
1171 for (i = 0; i < num; i++) {
1172 GET_MEMNUM_INC(m, memp);
1173 if (mem == (int )m) return 1;
1174 }
1175 return 0;
1176 }
1177
1178 static int backref_match_at_nested_level(regex_t* reg
1179 , OnigStackType* top, OnigStackType* stk_base
1180 , int ignore_case, int case_fold_flag
1181 , int nest, int mem_num, UChar* memp, UChar** s, const UChar* send)
1182 {
1183 UChar *ss, *p, *pstart, *pend = NULL_UCHARP;
1184 int level;
1185 OnigStackType* k;
1186
1187 level = 0;
1188 k = top;
1189 k--;
1190 while (k >= stk_base) {
1191 if (k->type == STK_CALL_FRAME) {
1192 level--;
1193 }
1194 else if (k->type == STK_RETURN) {
1195 level++;
1196 }
1197 else if (level == nest) {
1198 if (k->type == STK_MEM_START) {
1199 if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
1200 pstart = k->u.mem.pstr;
1201 if (pend != NULL_UCHARP) {
1202 if (pend - pstart > send - *s) return 0; /* or goto next_mem; */
1203 p = pstart;
1204 ss = *s;
1205
1206 if (ignore_case != 0) {
1207 if (string_cmp_ic(reg->enc, case_fold_flag,
1208 pstart, &ss, pend - pstart, send) == 0)
1209 return 0; /* or goto next_mem; */
1210 }
1211 else {
1212 while (p < pend) {
1213 if (*p++ != *ss++) return 0; /* or goto next_mem; */
1214 }
1215 }
1216
1217 *s = ss;
1218 return 1;
1219 }
1220 }
1221 }
1222 else if (k->type == STK_MEM_END) {
1223 if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
1224 pend = k->u.mem.pstr;
1225 }
1226 }
1227 }
1228 k--;
1229 }
1230
1231 return 0;
1232 }
1233 #endif /* USE_BACKREF_WITH_LEVEL */
1234
1235
1236 #ifdef ONIG_DEBUG_STATISTICS
1237
1238 #define USE_TIMEOFDAY
1239
1240 #ifdef USE_TIMEOFDAY
1241 #ifdef HAVE_SYS_TIME_H
1242 #include <sys/time.h>
1243 #endif
1244 #ifdef HAVE_UNISTD_H
1245 #include <unistd.h>
1246 #endif
1247 static struct timeval ts, te;
1248 #define GETTIME(t) gettimeofday(&(t), (struct timezone* )0)
1249 #define TIMEDIFF(te,ts) (((te).tv_usec - (ts).tv_usec) + \
1250 (((te).tv_sec - (ts).tv_sec)*1000000))
1251 #else /* USE_TIMEOFDAY */
1252 #ifdef HAVE_SYS_TIMES_H
1253 #include <sys/times.h>
1254 #endif
1255 static struct tms ts, te;
1256 #define GETTIME(t) times(&(t))
1257 #define TIMEDIFF(te,ts) ((te).tms_utime - (ts).tms_utime)
1258 #endif /* USE_TIMEOFDAY */
1259
1260 static int OpCounter[256];
1261 static int OpPrevCounter[256];
1262 static unsigned long OpTime[256];
1263 static int OpCurr = OP_FINISH;
1264 static int OpPrevTarget = OP_FAIL;
1265 static int MaxStackDepth = 0;
1266
1267 #define MOP_IN(opcode) do {\
1268 if (opcode == OpPrevTarget) OpPrevCounter[OpCurr]++;\
1269 OpCurr = opcode;\
1270 OpCounter[opcode]++;\
1271 GETTIME(ts);\
1272 } while(0)
1273
1274 #define MOP_OUT do {\
1275 GETTIME(te);\
1276 OpTime[OpCurr] += TIMEDIFF(te, ts);\
1277 } while(0)
1278
1279 extern void
1280 onig_statistics_init(void)
1281 {
1282 int i;
1283 for (i = 0; i < 256; i++) {
1284 OpCounter[i] = OpPrevCounter[i] = 0; OpTime[i] = 0;
1285 }
1286 MaxStackDepth = 0;
1287 }
1288
1289 extern void
1290 onig_print_statistics(FILE* f)
1291 {
1292 int i;
1293 fprintf(f, " count prev time\n");
1294 for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
1295 fprintf(f, "%8d: %8d: %10ld: %s\n",
1296 OpCounter[i], OpPrevCounter[i], OpTime[i], OnigOpInfo[i].name);
1297 }
1298 fprintf(f, "\nmax stack depth: %d\n", MaxStackDepth);
1299 }
1300
1301 #define STACK_INC do {\
1302 stk++;\
1303 if (stk - stk_base > MaxStackDepth) \
1304 MaxStackDepth = stk - stk_base;\
1305 } while(0)
1306
1307 #else /* ONIG_DEBUG_STATISTICS */
1308 #define STACK_INC stk++
1309
1310 #define MOP_IN(opcode)
1311 #define MOP_OUT
1312 #endif /* ONIG_DEBUG_STATISTICS */
1313
1314
1315
1316 /* matching region of POSIX API */
1317 typedef int regoff_t;
1318
1319 typedef struct {
1320 regoff_t rm_so;
1321 regoff_t rm_eo;
1322 } posix_regmatch_t;
1323
1324 void onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar* bpend, UChar** nextp,
1325 OnigEncoding enc);
1326
1327 /* match data(str - end) from position (sstart). */
1328 /* if sstart == str then set sprev to NULL. */
1329 static OnigPosition
1330 match_at(regex_t* reg, const UChar* str, const UChar* end,
1331 #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
1332 const UChar* right_range,
1333 #endif
1334 const UChar* sstart, UChar* sprev, OnigMatchArg* msa)
1335 {
1336 static const UChar FinishCode[] = { OP_FINISH };
1337
1338 int i, num_mem, pop_level;
1339 ptrdiff_t n, best_len;
1340 LengthType tlen, tlen2;
1341 MemNumType mem;
1342 RelAddrType addr;
1343 OnigOptionType option = reg->options;
1344 OnigEncoding encode = reg->enc;
1345 OnigCaseFoldType case_fold_flag = reg->case_fold_flag;
1346 UChar *s, *q, *sbegin;
1347 UChar *p = reg->p;
1348 UChar *pkeep;
1349 char *alloca_base;
1350 char *xmalloc_base = NULL;
1351 OnigStackType *stk_alloc, *stk_base, *stk, *stk_end;
1352 OnigStackType *stkp; /* used as any purpose. */
1353 OnigStackIndex si;
1354 OnigStackIndex *repeat_stk;
1355 OnigStackIndex *mem_start_stk, *mem_end_stk;
1356 #ifdef USE_COMBINATION_EXPLOSION_CHECK
1357 int scv;
1358 unsigned char* state_check_buff = msa->state_check_buff;
1359 int num_comb_exp_check = reg->num_comb_exp_check;
1360 #endif
1361
1362 #ifdef USE_SUBEXP_CALL
1363 /* Stack #0 is used to store the pattern itself and used for (?R), \g<0>, etc. */
1364 n = reg->num_repeat + (reg->num_mem + 1) * 2;
1365
1366 STACK_INIT(alloca_base, xmalloc_base, n, INIT_MATCH_STACK_SIZE);
1367 pop_level = reg->stack_pop_level;
1368 num_mem = reg->num_mem;
1369 repeat_stk = (OnigStackIndex* )alloca_base;
1370
1371 mem_start_stk = (OnigStackIndex* )(repeat_stk + reg->num_repeat);
1372 mem_end_stk = mem_start_stk + (num_mem + 1);
1373 for (i = 0; i <= num_mem; i++) {
1374 mem_start_stk[i] = mem_end_stk[i] = INVALID_STACK_INDEX;
1375 }
1376 #else /* USE_SUBEXP_CALL */
1377 /* Stack #0 not is used. */
1378 n = reg->num_repeat + reg->num_mem * 2;
1379
1380 STACK_INIT(alloca_base, xmalloc_base, n, INIT_MATCH_STACK_SIZE);
1381 pop_level = reg->stack_pop_level;
1382 num_mem = reg->num_mem;
1383 repeat_stk = (OnigStackIndex* )alloca_base;
1384
1385 mem_start_stk = (OnigStackIndex* )(repeat_stk + reg->num_repeat);
1386 mem_end_stk = mem_start_stk + num_mem;
1387 mem_start_stk--; /* for index start from 1,
1388 mem_start_stk[1]..mem_start_stk[num_mem] */
1389 mem_end_stk--; /* for index start from 1,
1390 mem_end_stk[1]..mem_end_stk[num_mem] */
1391 for (i = 1; i <= num_mem; i++) {
1392 mem_start_stk[i] = mem_end_stk[i] = INVALID_STACK_INDEX;
1393 }
1394 #endif /* USE_SUBEXP_CALL */
1395
1396 #ifdef ONIG_DEBUG_MATCH
1397 fprintf(stderr, "match_at: str: %"PRIdPTR" (%p), end: %"PRIdPTR" (%p), start: %"PRIdPTR" (%p), sprev: %"PRIdPTR" (%p)\n",
1398 (intptr_t)str, str, (intptr_t)end, end, (intptr_t)sstart, sstart, (intptr_t)sprev, sprev);
1399 fprintf(stderr, "size: %d, start offset: %d\n",
1400 (int )(end - str), (int )(sstart - str));
1401 #endif
1402
1403 STACK_PUSH_ENSURED(STK_ALT, (UChar *)FinishCode); /* bottom stack */
1404 best_len = ONIG_MISMATCH;
1405 s = (UChar* )sstart;
1406 pkeep = (UChar* )sstart;
1407 while (1) {
1408 #ifdef ONIG_DEBUG_MATCH
1409 if (s) {
1410 UChar *q, *bp, buf[50];
1411 int len;
1412 fprintf(stderr, "%4d> \"", (int )(s - str));
1413 bp = buf;
1414 if (*p != OP_FINISH) { /* s may not be a valid pointer if OP_FINISH. */
1415 for (i = 0, q = s; i < 7 && q < end; i++) {
1416 len = enclen(encode, q, end);
1417 while (len-- > 0) *bp++ = *q++;
1418 }
1419 }
1420 if (q < end) { xmemcpy(bp, "...\"", 4); bp += 4; }
1421 else { xmemcpy(bp, "\"", 1); bp += 1; }
1422 *bp = 0;
1423 fputs((char* )buf, stderr);
1424 for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);
1425 onig_print_compiled_byte_code(stderr, p, p + strlen((char *)p), NULL, encode);
1426 fprintf(stderr, "\n");
1427 }
1428 #endif
1429
1430 sbegin = s;
1431 switch (*p++) {
1432 case OP_END: MOP_IN(OP_END);
1433 n = s - sstart;
1434 if (n > best_len) {
1435 OnigRegion* region;
1436 #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
1437 if (IS_FIND_LONGEST(option)) {
1438 if (n > msa->best_len) {
1439 msa->best_len = n;
1440 msa->best_s = (UChar* )sstart;
1441 }
1442 else
1443 goto end_best_len;
1444 }
1445 #endif
1446 best_len = n;
1447 region = msa->region;
1448 if (region) {
1449 #ifdef USE_POSIX_API_REGION_OPTION
1450 if (IS_POSIX_REGION(msa->options)) {
1451 posix_regmatch_t* rmt = (posix_regmatch_t* )region;
1452
1453 rmt[0].rm_so = (regoff_t )(((pkeep > s) ? s : pkeep) - str);
1454 rmt[0].rm_eo = (regoff_t )(s - str);
1455 for (i = 1; i <= num_mem; i++) {
1456 if (mem_end_stk[i] != INVALID_STACK_INDEX) {
1457 if (BIT_STATUS_AT(reg->bt_mem_start, i))
1458 rmt[i].rm_so = (regoff_t )(STACK_AT(mem_start_stk[i])->u.mem.pstr - str);
1459 else
1460 rmt[i].rm_so = (regoff_t )((UChar* )((void* )(mem_start_stk[i])) - str);
1461
1462 rmt[i].rm_eo = (regoff_t )((BIT_STATUS_AT(reg->bt_mem_end, i)
1463 ? STACK_AT(mem_end_stk[i])->u.mem.pstr
1464 : (UChar* )((void* )mem_end_stk[i])) - str);
1465 }
1466 else {
1467 rmt[i].rm_so = rmt[i].rm_eo = ONIG_REGION_NOTPOS;
1468 }
1469 }
1470 }
1471 else {
1472 #endif /* USE_POSIX_API_REGION_OPTION */
1473 region->beg[0] = ((pkeep > s) ? s : pkeep) - str;
1474 region->end[0] = s - str;
1475 for (i = 1; i <= num_mem; i++) {
1476 if (mem_end_stk[i] != INVALID_STACK_INDEX) {
1477 if (BIT_STATUS_AT(reg->bt_mem_start, i))
1478 region->beg[i] = STACK_AT(mem_start_stk[i])->u.mem.pstr - str;
1479 else
1480 region->beg[i] = (UChar* )((void* )mem_start_stk[i]) - str;
1481
1482 region->end[i] = (BIT_STATUS_AT(reg->bt_mem_end, i)
1483 ? STACK_AT(mem_end_stk[i])->u.mem.pstr
1484 : (UChar* )((void* )mem_end_stk[i])) - str;
1485 }
1486 else {
1487 region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
1488 }
1489 }
1490
1491 #ifdef USE_CAPTURE_HISTORY
1492 if (reg->capture_history != 0) {
1493 int r;
1494 OnigCaptureTreeNode* node;
1495
1496 if (IS_NULL(region->history_root)) {
1497 region->history_root = node = history_node_new();
1498 CHECK_NULL_RETURN_MEMERR(node);
1499 }
1500 else {
1501 node = region->history_root;
1502 history_tree_clear(node);
1503 }
1504
1505 node->group = 0;
1506 node->beg = ((pkeep > s) ? s : pkeep) - str;
1507 node->end = s - str;
1508
1509 stkp = stk_base;
1510 r = make_capture_history_tree(region->history_root, &stkp,
1511 stk, (UChar* )str, reg);
1512 if (r < 0) {
1513 best_len = r; /* error code */
1514 goto finish;
1515 }
1516 }
1517 #endif /* USE_CAPTURE_HISTORY */
1518 #ifdef USE_POSIX_API_REGION_OPTION
1519 } /* else IS_POSIX_REGION() */
1520 #endif
1521 } /* if (region) */
1522 } /* n > best_len */
1523
1524 #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
1525 end_best_len:
1526 #endif
1527 MOP_OUT;
1528
1529 if (IS_FIND_CONDITION(option)) {
1530 if (IS_FIND_NOT_EMPTY(option) && s == sstart) {
1531 best_len = ONIG_MISMATCH;
1532 goto fail; /* for retry */
1533 }
1534 if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {
1535 goto fail; /* for retry */
1536 }
1537 }
1538
1539 /* default behavior: return first-matching result. */
1540 goto finish;
1541 break;
1542
1543 case OP_EXACT1: MOP_IN(OP_EXACT1);
1544 #if 0
1545 DATA_ENSURE(1);
1546 if (*p != *s) goto fail;
1547 p++; s++;
1548 #endif
1549 if (*p != *s++) goto fail;
1550 DATA_ENSURE(0);
1551 p++;
1552 MOP_OUT;
1553 break;
1554
1555 case OP_EXACT1_IC: MOP_IN(OP_EXACT1_IC);
1556 {
1557 int len;
1558 UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
1559
1560 DATA_ENSURE(1);
1561 len = ONIGENC_MBC_CASE_FOLD(encode,
1562 /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
1563 case_fold_flag,
1564 &s, end, lowbuf);
1565 DATA_ENSURE(0);
1566 q = lowbuf;
1567 while (len-- > 0) {
1568 if (*p != *q) {
1569 goto fail;
1570 }
1571 p++; q++;
1572 }
1573 }
1574 MOP_OUT;
1575 break;
1576
1577 case OP_EXACT2: MOP_IN(OP_EXACT2);
1578 DATA_ENSURE(2);
1579 if (*p != *s) goto fail;
1580 p++; s++;
1581 if (*p != *s) goto fail;
1582 sprev = s;
1583 p++; s++;
1584 MOP_OUT;
1585 continue;
1586 break;
1587
1588 case OP_EXACT3: MOP_IN(OP_EXACT3);
1589 DATA_ENSURE(3);
1590 if (*p != *s) goto fail;
1591 p++; s++;
1592 if (*p != *s) goto fail;
1593 p++; s++;
1594 if (*p != *s) goto fail;
1595 sprev = s;
1596 p++; s++;
1597 MOP_OUT;
1598 continue;
1599 break;
1600
1601 case OP_EXACT4: MOP_IN(OP_EXACT4);
1602 DATA_ENSURE(4);
1603 if (*p != *s) goto fail;
1604 p++; s++;
1605 if (*p != *s) goto fail;
1606 p++; s++;
1607 if (*p != *s) goto fail;
1608 p++; s++;
1609 if (*p != *s) goto fail;
1610 sprev = s;
1611 p++; s++;
1612 MOP_OUT;
1613 continue;
1614 break;
1615
1616 case OP_EXACT5: MOP_IN(OP_EXACT5);
1617 DATA_ENSURE(5);
1618 if (*p != *s) goto fail;
1619 p++; s++;
1620 if (*p != *s) goto fail;
1621 p++; s++;
1622 if (*p != *s) goto fail;
1623 p++; s++;
1624 if (*p != *s) goto fail;
1625 p++; s++;
1626 if (*p != *s) goto fail;
1627 sprev = s;
1628 p++; s++;
1629 MOP_OUT;
1630 continue;
1631 break;
1632
1633 case OP_EXACTN: MOP_IN(OP_EXACTN);
1634 GET_LENGTH_INC(tlen, p);
1635 DATA_ENSURE(tlen);
1636 while (tlen-- > 0) {
1637 if (*p++ != *s++) goto fail;
1638 }
1639 sprev = s - 1;
1640 MOP_OUT;
1641 continue;
1642 break;
1643
1644 case OP_EXACTN_IC: MOP_IN(OP_EXACTN_IC);
1645 {
1646 int len;
1647 UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
1648
1649 GET_LENGTH_INC(tlen, p);
1650 endp = p + tlen;
1651
1652 while (p < endp) {
1653 sprev = s;
1654 DATA_ENSURE(1);
1655 len = ONIGENC_MBC_CASE_FOLD(encode,
1656 /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
1657 case_fold_flag,
1658 &s, end, lowbuf);
1659 DATA_ENSURE(0);
1660 q = lowbuf;
1661 while (len-- > 0) {
1662 if (*p != *q) goto fail;
1663 p++; q++;
1664 }
1665 }
1666 }
1667
1668 MOP_OUT;
1669 continue;
1670 break;
1671
1672 case OP_EXACTMB2N1: MOP_IN(OP_EXACTMB2N1);
1673 DATA_ENSURE(2);
1674 if (*p != *s) goto fail;
1675 p++; s++;
1676 if (*p != *s) goto fail;
1677 p++; s++;
1678 MOP_OUT;
1679 break;
1680
1681 case OP_EXACTMB2N2: MOP_IN(OP_EXACTMB2N2);
1682 DATA_ENSURE(4);
1683 if (*p != *s) goto fail;
1684 p++; s++;
1685 if (*p != *s) goto fail;
1686 p++; s++;
1687 sprev = s;
1688 if (*p != *s) goto fail;
1689 p++; s++;
1690 if (*p != *s) goto fail;
1691 p++; s++;
1692 MOP_OUT;
1693 continue;
1694 break;
1695
1696 case OP_EXACTMB2N3: MOP_IN(OP_EXACTMB2N3);
1697 DATA_ENSURE(6);
1698 if (*p != *s) goto fail;
1699 p++; s++;
1700 if (*p != *s) goto fail;
1701 p++; s++;
1702 if (*p != *s) goto fail;
1703 p++; s++;
1704 if (*p != *s) goto fail;
1705 p++; s++;
1706 sprev = s;
1707 if (*p != *s) goto fail;
1708 p++; s++;
1709 if (*p != *s) goto fail;
1710 p++; s++;
1711 MOP_OUT;
1712 continue;
1713 break;
1714
1715 case OP_EXACTMB2N: MOP_IN(OP_EXACTMB2N);
1716 GET_LENGTH_INC(tlen, p);
1717 DATA_ENSURE(tlen * 2);
1718 while (tlen-- > 0) {
1719 if (*p != *s) goto fail;
1720 p++; s++;
1721 if (*p != *s) goto fail;
1722 p++; s++;
1723 }
1724 sprev = s - 2;
1725 MOP_OUT;
1726 continue;
1727 break;
1728
1729 case OP_EXACTMB3N: MOP_IN(OP_EXACTMB3N);
1730 GET_LENGTH_INC(tlen, p);
1731 DATA_ENSURE(tlen * 3);
1732 while (tlen-- > 0) {
1733 if (*p != *s) goto fail;
1734 p++; s++;
1735 if (*p != *s) goto fail;
1736 p++; s++;
1737 if (*p != *s) goto fail;
1738 p++; s++;
1739 }
1740 sprev = s - 3;
1741 MOP_OUT;
1742 continue;
1743 break;
1744
1745 case OP_EXACTMBN: MOP_IN(OP_EXACTMBN);
1746 GET_LENGTH_INC(tlen, p); /* mb-len */
1747 GET_LENGTH_INC(tlen2, p); /* string len */
1748 tlen2 *= tlen;
1749 DATA_ENSURE(tlen2);
1750 while (tlen2-- > 0) {
1751 if (*p != *s) goto fail;
1752 p++; s++;
1753 }
1754 sprev = s - tlen;
1755 MOP_OUT;
1756 continue;
1757 break;
1758
1759 case OP_CCLASS: MOP_IN(OP_CCLASS);
1760 DATA_ENSURE(1);
1761 if (BITSET_AT(((BitSetRef )p), *s) == 0) goto fail;
1762 p += SIZE_BITSET;
1763 s += enclen(encode, s, end); /* OP_CCLASS can match mb-code. \D, \S */
1764 MOP_OUT;
1765 break;
1766
1767 case OP_CCLASS_MB: MOP_IN(OP_CCLASS_MB);
1768 if (! ONIGENC_IS_MBC_HEAD(encode, s, end)) goto fail;
1769
1770 cclass_mb:
1771 GET_LENGTH_INC(tlen, p);
1772 {
1773 OnigCodePoint code;
1774 UChar *ss;
1775 int mb_len;
1776
1777 DATA_ENSURE(1);
1778 mb_len = enclen(encode, s, end);
1779 DATA_ENSURE(mb_len);
1780 ss = s;
1781 s += mb_len;
1782 code = ONIGENC_MBC_TO_CODE(encode, ss, s);
1783
1784 #ifdef PLATFORM_UNALIGNED_WORD_ACCESS
1785 if (! onig_is_in_code_range(p, code)) goto fail;
1786 #else
1787 q = p;
1788 ALIGNMENT_RIGHT(q);
1789 if (! onig_is_in_code_range(q, code)) goto fail;
1790 #endif
1791 }
1792 p += tlen;
1793 MOP_OUT;
1794 break;
1795
1796 case OP_CCLASS_MIX: MOP_IN(OP_CCLASS_MIX);
1797 DATA_ENSURE(1);
1798 if (ONIGENC_IS_MBC_HEAD(encode, s, end)) {
1799 p += SIZE_BITSET;
1800 goto cclass_mb;
1801 }
1802 else {
1803 if (BITSET_AT(((BitSetRef )p), *s) == 0)
1804 goto fail;
1805
1806 p += SIZE_BITSET;
1807 GET_LENGTH_INC(tlen, p);
1808 p += tlen;
1809 s++;
1810 }
1811 MOP_OUT;
1812 break;
1813
1814 case OP_CCLASS_NOT: MOP_IN(OP_CCLASS_NOT);
1815 DATA_ENSURE(1);
1816 if (BITSET_AT(((BitSetRef )p), *s) != 0) goto fail;
1817 p += SIZE_BITSET;
1818 s += enclen(encode, s, end);
1819 MOP_OUT;
1820 break;
1821
1822 case OP_CCLASS_MB_NOT: MOP_IN(OP_CCLASS_MB_NOT);
1823 DATA_ENSURE(1);
1824 if (! ONIGENC_IS_MBC_HEAD(encode, s, end)) {
1825 s++;
1826 GET_LENGTH_INC(tlen, p);
1827 p += tlen;
1828 goto cc_mb_not_success;
1829 }
1830
1831 cclass_mb_not:
1832 GET_LENGTH_INC(tlen, p);
1833 {
1834 OnigCodePoint code;
1835 UChar *ss;
1836 int mb_len = enclen(encode, s, end);
1837
1838 if (! DATA_ENSURE_CHECK(mb_len)) {
1839 DATA_ENSURE(1);
1840 s = (UChar* )end;
1841 p += tlen;
1842 goto cc_mb_not_success;
1843 }
1844
1845 ss = s;
1846 s += mb_len;
1847 code = ONIGENC_MBC_TO_CODE(encode, ss, s);
1848
1849 #ifdef PLATFORM_UNALIGNED_WORD_ACCESS
1850 if (onig_is_in_code_range(p, code)) goto fail;
1851 #else
1852 q = p;
1853 ALIGNMENT_RIGHT(q);
1854 if (onig_is_in_code_range(q, code)) goto fail;
1855 #endif
1856 }
1857 p += tlen;
1858
1859 cc_mb_not_success:
1860 MOP_OUT;
1861 break;
1862
1863 case OP_CCLASS_MIX_NOT: MOP_IN(OP_CCLASS_MIX_NOT);
1864 DATA_ENSURE(1);
1865 if (ONIGENC_IS_MBC_HEAD(encode, s, end)) {
1866 p += SIZE_BITSET;
1867 goto cclass_mb_not;
1868 }
1869 else {
1870 if (BITSET_AT(((BitSetRef )p), *s) != 0)
1871 goto fail;
1872
1873 p += SIZE_BITSET;
1874 GET_LENGTH_INC(tlen, p);
1875 p += tlen;
1876 s++;
1877 }
1878 MOP_OUT;
1879 break;
1880
1881 case OP_CCLASS_NODE: MOP_IN(OP_CCLASS_NODE);
1882 {
1883 OnigCodePoint code;
1884 void *node;
1885 int mb_len;
1886 UChar *ss;
1887
1888 DATA_ENSURE(1);
1889 GET_POINTER_INC(node, p);
1890 mb_len = enclen(encode, s, end);
1891 ss = s;
1892 s += mb_len;
1893 DATA_ENSURE(0);
1894 code = ONIGENC_MBC_TO_CODE(encode, ss, s);
1895 if (onig_is_code_in_cc_len(mb_len, code, node) == 0) goto fail;
1896 }
1897 MOP_OUT;
1898 break;
1899
1900 case OP_ANYCHAR: MOP_IN(OP_ANYCHAR);
1901 DATA_ENSURE(1);
1902 n = enclen(encode, s, end);
1903 DATA_ENSURE(n);
1904 if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0)) goto fail;
1905 s += n;
1906 MOP_OUT;
1907 break;
1908
1909 case OP_ANYCHAR_ML: MOP_IN(OP_ANYCHAR_ML);
1910 DATA_ENSURE(1);
1911 n = enclen(encode, s, end);
1912 DATA_ENSURE(n);
1913 s += n;
1914 MOP_OUT;
1915 break;
1916
1917 case OP_ANYCHAR_STAR: MOP_IN(OP_ANYCHAR_STAR);
1918 while (DATA_ENSURE_CHECK1) {
1919 STACK_PUSH_ALT(p, s, sprev, pkeep);
1920 n = enclen(encode, s, end);
1921 DATA_ENSURE(n);
1922 if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0)) goto fail;
1923 sprev = s;
1924 s += n;
1925 }
1926 MOP_OUT;
1927 break;
1928
1929 case OP_ANYCHAR_ML_STAR: MOP_IN(OP_ANYCHAR_ML_STAR);
1930 while (DATA_ENSURE_CHECK1) {
1931 STACK_PUSH_ALT(p, s, sprev, pkeep);
1932 n = enclen(encode, s, end);
1933 if (n > 1) {
1934 DATA_ENSURE(n);
1935 sprev = s;
1936 s += n;
1937 }
1938 else {
1939 sprev = s;
1940 s++;
1941 }
1942 }
1943 MOP_OUT;
1944 break;
1945
1946 case OP_ANYCHAR_STAR_PEEK_NEXT: MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
1947 while (DATA_ENSURE_CHECK1) {
1948 if (*p == *s) {
1949 STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
1950 }
1951 n = enclen(encode, s, end);
1952 DATA_ENSURE(n);
1953 if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0)) goto fail;
1954 sprev = s;
1955 s += n;
1956 }
1957 p++;
1958 MOP_OUT;
1959 break;
1960
1961 case OP_ANYCHAR_ML_STAR_PEEK_NEXT:MOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
1962 while (DATA_ENSURE_CHECK1) {
1963 if (*p == *s) {
1964 STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
1965 }
1966 n = enclen(encode, s, end);
1967 if (n > 1) {
1968 DATA_ENSURE(n);
1969 sprev = s;
1970 s += n;
1971 }
1972 else {
1973 sprev = s;
1974 s++;
1975 }
1976 }
1977 p++;
1978 MOP_OUT;
1979 break;
1980
1981 #ifdef USE_COMBINATION_EXPLOSION_CHECK
1982 case OP_STATE_CHECK_ANYCHAR_STAR: MOP_IN(OP_STATE_CHECK_ANYCHAR_STAR);
1983 GET_STATE_CHECK_NUM_INC(mem, p);
1984 while (DATA_ENSURE_CHECK1) {
1985 STATE_CHECK_VAL(scv, mem);
1986 if (scv) goto fail;
1987
1988 STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
1989 n = enclen(encode, s, end);
1990 DATA_ENSURE(n);
1991 if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0)) goto fail;
1992 sprev = s;
1993 s += n;
1994 }
1995 MOP_OUT;
1996 break;
1997
1998 case OP_STATE_CHECK_ANYCHAR_ML_STAR:
1999 MOP_IN(OP_STATE_CHECK_ANYCHAR_ML_STAR);
2000
2001 GET_STATE_CHECK_NUM_INC(mem, p);
2002 while (DATA_ENSURE_CHECK1) {
2003 STATE_CHECK_VAL(scv, mem);
2004 if (scv) goto fail;
2005
2006 STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
2007 n = enclen(encode, s, end);
2008 if (n > 1) {
2009 DATA_ENSURE(n);
2010 sprev = s;
2011 s += n;
2012 }
2013 else {
2014 sprev = s;
2015 s++;
2016 }
2017 }
2018 MOP_OUT;
2019 break;
2020 #endif /* USE_COMBINATION_EXPLOSION_CHECK */
2021
2022 case OP_WORD: MOP_IN(OP_WORD);
2023 DATA_ENSURE(1);
2024 if (! ONIGENC_IS_MBC_WORD(encode, s, end))
2025 goto fail;
2026
2027 s += enclen(encode, s, end);
2028 MOP_OUT;
2029 break;
2030
2031 case OP_ASCII_WORD: MOP_IN(OP_ASCII_WORD);
2032 DATA_ENSURE(1);
2033 if (! ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
2034 goto fail;
2035
2036 s += enclen(encode, s, end);
2037 MOP_OUT;
2038 break;
2039
2040 case OP_NOT_WORD: MOP_IN(OP_NOT_WORD);
2041 DATA_ENSURE(1);
2042 if (ONIGENC_IS_MBC_WORD(encode, s, end))
2043 goto fail;
2044
2045 s += enclen(encode, s, end);
2046 MOP_OUT;
2047 break;
2048
2049 case OP_NOT_ASCII_WORD: MOP_IN(OP_NOT_ASCII_WORD);
2050 DATA_ENSURE(1);
2051 if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
2052 goto fail;
2053
2054 s += enclen(encode, s, end);
2055 MOP_OUT;
2056 break;
2057
2058 case OP_WORD_BOUND: MOP_IN(OP_WORD_BOUND);
2059 if (ON_STR_BEGIN(s)) {
2060 DATA_ENSURE(1);
2061 if (! ONIGENC_IS_MBC_WORD(encode, s, end))
2062 goto fail;
2063 }
2064 else if (ON_STR_END(s)) {
2065 if (! ONIGENC_IS_MBC_WORD(encode, sprev, end))
2066 goto fail;
2067 }
2068 else {
2069 if (ONIGENC_IS_MBC_WORD(encode, s, end)
2070 == ONIGENC_IS_MBC_WORD(encode, sprev, end))
2071 goto fail;
2072 }
2073 MOP_OUT;
2074 continue;
2075 break;
2076
2077 case OP_ASCII_WORD_BOUND: MOP_IN(OP_ASCII_WORD_BOUND);
2078 if (ON_STR_BEGIN(s)) {
2079 DATA_ENSURE(1);
2080 if (! ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
2081 goto fail;
2082 }
2083 else if (ON_STR_END(s)) {
2084 if (! ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
2085 goto fail;
2086 }
2087 else {
2088 if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)
2089 == ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
2090 goto fail;
2091 }
2092 MOP_OUT;
2093 continue;
2094 break;
2095
2096 case OP_NOT_WORD_BOUND: MOP_IN(OP_NOT_WORD_BOUND);
2097 if (ON_STR_BEGIN(s)) {
2098 if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end))
2099 goto fail;
2100 }
2101 else if (ON_STR_END(s)) {
2102 if (ONIGENC_IS_MBC_WORD(encode, sprev, end))
2103 goto fail;
2104 }
2105 else {
2106 if (ONIGENC_IS_MBC_WORD(encode, s, end)
2107 != ONIGENC_IS_MBC_WORD(encode, sprev, end))
2108 goto fail;
2109 }
2110 MOP_OUT;
2111 continue;
2112 break;
2113
2114 case OP_NOT_ASCII_WORD_BOUND: MOP_IN(OP_NOT_ASCII_WORD_BOUND);
2115 if (ON_STR_BEGIN(s)) {
2116 if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
2117 goto fail;
2118 }
2119 else if (ON_STR_END(s)) {
2120 if (ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
2121 goto fail;
2122 }
2123 else {
2124 if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)
2125 != ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
2126 goto fail;
2127 }
2128 MOP_OUT;
2129 continue;
2130 break;
2131
2132 #ifdef USE_WORD_BEGIN_END
2133 case OP_WORD_BEGIN: MOP_IN(OP_WORD_BEGIN);
2134 if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end)) {
2135 if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
2136 MOP_OUT;
2137 continue;
2138 }
2139 }
2140 goto fail;
2141 break;
2142
2143 case OP_ASCII_WORD_BEGIN: MOP_IN(OP_ASCII_WORD_BEGIN);
2144 if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)) {
2145 if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end)) {
2146 MOP_OUT;
2147 continue;
2148 }
2149 }
2150 goto fail;
2151 break;
2152
2153 case OP_WORD_END: MOP_IN(OP_WORD_END);
2154 if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
2155 if (ON_STR_END(s) || !ONIGENC_IS_MBC_WORD(encode, s, end)) {
2156 MOP_OUT;
2157 continue;
2158 }
2159 }
2160 goto fail;
2161 break;
2162
2163 case OP_ASCII_WORD_END: MOP_IN(OP_ASCII_WORD_END);
2164 if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end)) {
2165 if (ON_STR_END(s) || !ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)) {
2166 MOP_OUT;
2167 continue;
2168 }
2169 }
2170 goto fail;
2171 break;
2172 #endif
2173
2174 case OP_BEGIN_BUF: MOP_IN(OP_BEGIN_BUF);
2175 if (! ON_STR_BEGIN(s)) goto fail;
2176
2177 MOP_OUT;
2178 continue;
2179 break;
2180
2181 case OP_END_BUF: MOP_IN(OP_END_BUF);
2182 if (! ON_STR_END(s)) goto fail;
2183
2184 MOP_OUT;
2185 continue;
2186 break;
2187
2188 case OP_BEGIN_LINE: MOP_IN(OP_BEGIN_LINE);
2189 op_begin_line:
2190 if (ON_STR_BEGIN(s)) {
2191 if (IS_NOTBOL(msa->options)) goto fail;
2192 MOP_OUT;
2193 continue;
2194 }
2195 else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)
2196 #ifdef USE_CRNL_AS_LINE_TERMINATOR
2197 && !(IS_NEWLINE_CRLF(option)
2198 && ONIGENC_IS_MBC_CRNL(encode, sprev, end))
2199 #endif
2200 && !ON_STR_END(s)) {
2201 MOP_OUT;
2202 continue;
2203 }
2204 goto fail;
2205 break;
2206
2207 case OP_END_LINE: MOP_IN(OP_END_LINE);
2208 if (ON_STR_END(s)) {
2209 #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
2210 if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE_EX(encode, sprev, str, end, option, 1)) {
2211 #endif
2212 if (IS_NOTEOL(msa->options)) goto fail;
2213 MOP_OUT;
2214 continue;
2215 #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
2216 }
2217 #endif
2218 }
2219 else if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 1)) {
2220 MOP_OUT;
2221 continue;
2222 }
2223 goto fail;
2224 break;
2225
2226 case OP_SEMI_END_BUF: MOP_IN(OP_SEMI_END_BUF);
2227 if (ON_STR_END(s)) {
2228 #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
2229 if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE_EX(encode, sprev, str, end, option, 1)) {
2230 #endif
2231 if (IS_NOTEOL(msa->options)) goto fail;
2232 MOP_OUT;
2233 continue;
2234 #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
2235 }
2236 #endif
2237 }
2238 else if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 1)) {
2239 UChar* ss = s + enclen(encode, s, end);
2240 if (ON_STR_END(ss)) {
2241 MOP_OUT;
2242 continue;
2243 }
2244 #ifdef USE_CRNL_AS_LINE_TERMINATOR
2245 else if (IS_NEWLINE_CRLF(option)
2246 && ONIGENC_IS_MBC_CRNL(encode, s, end)) {
2247 ss += enclen(encode, ss, end);
2248 if (ON_STR_END(ss)) {
2249 MOP_OUT;
2250 continue;
2251 }
2252 }
2253 #endif
2254 }
2255 goto fail;
2256 break;
2257
2258 case OP_BEGIN_POSITION: MOP_IN(OP_BEGIN_POSITION);
2259 if (s != msa->gpos)
2260 goto fail;
2261
2262 MOP_OUT;
2263 continue;
2264 break;
2265
2266 case OP_BEGIN_POS_OR_LINE: MOP_IN(OP_BEGIN_POS_OR_LINE);
2267 if (s != msa->gpos)
2268 goto op_begin_line;
2269
2270 MOP_OUT;
2271 continue;
2272 break;
2273
2274 case OP_MEMORY_START_PUSH: MOP_IN(OP_MEMORY_START_PUSH);
2275 GET_MEMNUM_INC(mem, p);
2276 STACK_PUSH_MEM_START(mem, s);
2277 MOP_OUT;
2278 continue;
2279 break;
2280
2281 case OP_MEMORY_START: MOP_IN(OP_MEMORY_START);
2282 GET_MEMNUM_INC(mem, p);
2283 mem_start_stk[mem] = (OnigStackIndex )((void* )s);
2284 MOP_OUT;
2285 continue;
2286 break;
2287
2288 case OP_MEMORY_END_PUSH: MOP_IN(OP_MEMORY_END_PUSH);
2289 GET_MEMNUM_INC(mem, p);
2290 STACK_PUSH_MEM_END(mem, s);
2291 MOP_OUT;
2292 continue;
2293 break;
2294
2295 case OP_MEMORY_END: MOP_IN(OP_MEMORY_END);
2296 GET_MEMNUM_INC(mem, p);
2297 mem_end_stk[mem] = (OnigStackIndex )((void* )s);
2298 MOP_OUT;
2299 continue;
2300 break;
2301
2302 case OP_KEEP: MOP_IN(OP_KEEP);
2303 pkeep = s;
2304 MOP_OUT;
2305 continue;
2306 break;
2307
2308 #ifdef USE_SUBEXP_CALL
2309 case OP_MEMORY_END_PUSH_REC: MOP_IN(OP_MEMORY_END_PUSH_REC);
2310 GET_MEMNUM_INC(mem, p);
2311 STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */
2312 STACK_PUSH_MEM_END(mem, s);
2313 mem_start_stk[mem] = GET_STACK_INDEX(stkp);
2314 MOP_OUT;
2315 continue;
2316 break;
2317
2318 case OP_MEMORY_END_REC: MOP_IN(OP_MEMORY_END_REC);
2319 GET_MEMNUM_INC(mem, p);
2320 mem_end_stk[mem] = (OnigStackIndex )((void* )s);
2321 STACK_GET_MEM_START(mem, stkp);
2322
2323 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
2324 mem_start_stk[mem] = GET_STACK_INDEX(stkp);
2325 else
2326 mem_start_stk[mem] = (OnigStackIndex )((void* )stkp->u.mem.pstr);
2327
2328 STACK_PUSH_MEM_END_MARK(mem);
2329 MOP_OUT;
2330 continue;
2331 break;
2332 #endif
2333
2334 case OP_BACKREF1: MOP_IN(OP_BACKREF1);
2335 mem = 1;
2336 goto backref;
2337 break;
2338
2339 case OP_BACKREF2: MOP_IN(OP_BACKREF2);
2340 mem = 2;
2341 goto backref;
2342 break;
2343
2344 case OP_BACKREFN: MOP_IN(OP_BACKREFN);
2345 GET_MEMNUM_INC(mem, p);
2346 backref:
2347 {
2348 int len;
2349 UChar *pstart, *pend;
2350
2351 /* if you want to remove following line,
2352 you should check in parse and compile time. */
2353 if (mem > num_mem) goto fail;
2354 if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;
2355 if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;
2356
2357 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
2358 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
2359 else
2360 pstart = (UChar* )((void* )mem_start_stk[mem]);
2361
2362 pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
2363 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
2364 : (UChar* )((void* )mem_end_stk[mem]));
2365 n = pend - pstart;
2366 DATA_ENSURE(n);
2367 sprev = s;
2368 STRING_CMP(pstart, s, n);
2369 while (sprev + (len = enclen(encode, sprev, end)) < s)
2370 sprev += len;
2371
2372 MOP_OUT;
2373 continue;
2374 }
2375 break;
2376
2377 case OP_BACKREFN_IC: MOP_IN(OP_BACKREFN_IC);
2378 GET_MEMNUM_INC(mem, p);
2379 {
2380 int len;
2381 UChar *pstart, *pend;
2382
2383 /* if you want to remove following line,
2384 you should check in parse and compile time. */
2385 if (mem > num_mem) goto fail;
2386 if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;
2387 if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;
2388
2389 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
2390 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
2391 else
2392 pstart = (UChar* )((void* )mem_start_stk[mem]);
2393
2394 pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
2395 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
2396 : (UChar* )((void* )mem_end_stk[mem]));
2397 n = pend - pstart;
2398 DATA_ENSURE(n);
2399 sprev = s;
2400 STRING_CMP_IC(case_fold_flag, pstart, &s, (int)n, end);
2401 while (sprev + (len = enclen(encode, sprev, end)) < s)
2402 sprev += len;
2403
2404 MOP_OUT;
2405 continue;
2406 }
2407 break;
2408
2409 case OP_BACKREF_MULTI: MOP_IN(OP_BACKREF_MULTI);
2410 {
2411 int len, is_fail;
2412 UChar *pstart, *pend, *swork;
2413
2414 GET_LENGTH_INC(tlen, p);
2415 for (i = 0; i < tlen; i++) {
2416 GET_MEMNUM_INC(mem, p);
2417
2418 if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;
2419 if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
2420
2421 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
2422 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
2423 else
2424 pstart = (UChar* )((void* )mem_start_stk[mem]);
2425
2426 pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
2427 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
2428 : (UChar* )((void* )mem_end_stk[mem]));
2429 n = pend - pstart;
2430 DATA_ENSURE(n);
2431 sprev = s;
2432 swork = s;
2433 STRING_CMP_VALUE(pstart, swork, n, is_fail);
2434 if (is_fail) continue;
2435 s = swork;
2436 while (sprev + (len = enclen(encode, sprev, end)) < s)
2437 sprev += len;
2438
2439 p += (SIZE_MEMNUM * (tlen - i - 1));
2440 break; /* success */
2441 }
2442 if (i == tlen) goto fail;
2443 MOP_OUT;
2444 continue;
2445 }
2446 break;
2447
2448 case OP_BACKREF_MULTI_IC: MOP_IN(OP_BACKREF_MULTI_IC);
2449 {
2450 int len, is_fail;
2451 UChar *pstart, *pend, *swork;
2452
2453 GET_LENGTH_INC(tlen, p);
2454 for (i = 0; i < tlen; i++) {
2455 GET_MEMNUM_INC(mem, p);
2456
2457 if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;
2458 if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
2459
2460 if (BIT_STATUS_AT(reg->bt_mem_start, mem))
2461 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
2462 else
2463 pstart = (UChar* )((void* )mem_start_stk[mem]);
2464
2465 pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
2466 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
2467 : (UChar* )((void* )mem_end_stk[mem]));
2468 n = pend - pstart;
2469 DATA_ENSURE(n);
2470 sprev = s;
2471 swork = s;
2472 STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, end, is_fail);
2473 if (is_fail) continue;
2474 s = swork;
2475 while (sprev + (len = enclen(encode, sprev, end)) < s)
2476 sprev += len;
2477
2478 p += (SIZE_MEMNUM * (tlen - i - 1));
2479 break; /* success */
2480 }
2481 if (i == tlen) goto fail;
2482 MOP_OUT;
2483 continue;
2484 }
2485 break;
2486
2487 #ifdef USE_BACKREF_WITH_LEVEL
2488 case OP_BACKREF_WITH_LEVEL:
2489 {
2490 int len;
2491 OnigOptionType ic;
2492 LengthType level;
2493
2494 GET_OPTION_INC(ic, p);
2495 GET_LENGTH_INC(level, p);
2496 GET_LENGTH_INC(tlen, p);
2497
2498 sprev = s;
2499 if (backref_match_at_nested_level(reg, stk, stk_base, ic
2500 , case_fold_flag, (int )level, (int )tlen, p, &s, end)) {
2501 while (sprev + (len = enclen(encode, sprev, end)) < s)
2502 sprev += len;
2503
2504 p += (SIZE_MEMNUM * tlen);
2505 }
2506 else
2507 goto fail;
2508
2509 MOP_OUT;
2510 continue;
2511 }
2512
2513 break;
2514 #endif
2515
2516 #if 0 /* no need: IS_DYNAMIC_OPTION() == 0 */
2517 case OP_SET_OPTION_PUSH: MOP_IN(OP_SET_OPTION_PUSH);
2518 GET_OPTION_INC(option, p);
2519 STACK_PUSH_ALT(p, s, sprev, pkeep);
2520 p += SIZE_OP_SET_OPTION + SIZE_OP_FAIL;
2521 MOP_OUT;
2522 continue;
2523 break;
2524
2525 case OP_SET_OPTION: MOP_IN(OP_SET_OPTION);
2526 GET_OPTION_INC(option, p);
2527 MOP_OUT;
2528 continue;
2529 break;
2530 #endif
2531
2532 case OP_NULL_CHECK_START: MOP_IN(OP_NULL_CHECK_START);
2533 GET_MEMNUM_INC(mem, p); /* mem: null check id */
2534 STACK_PUSH_NULL_CHECK_START(mem, s);
2535 MOP_OUT;
2536 continue;
2537 break;
2538
2539 case OP_NULL_CHECK_END: MOP_IN(OP_NULL_CHECK_END);
2540 {
2541 int isnull;
2542
2543 GET_MEMNUM_INC(mem, p); /* mem: null check id */
2544 STACK_NULL_CHECK(isnull, mem, s);
2545 if (isnull) {
2546 #ifdef ONIG_DEBUG_MATCH
2547 fprintf(stderr, "NULL_CHECK_END: skip id:%d, s:%"PRIdPTR" (%p)\n",
2548 (int )mem, (intptr_t )s, s);
2549 #endif
2550 null_check_found:
2551 /* empty loop founded, skip next instruction */
2552 switch (*p++) {
2553 case OP_JUMP:
2554 case OP_PUSH:
2555 p += SIZE_RELADDR;
2556 break;
2557 case OP_REPEAT_INC:
2558 case OP_REPEAT_INC_NG:
2559 case OP_REPEAT_INC_SG:
2560 case OP_REPEAT_INC_NG_SG:
2561 p += SIZE_MEMNUM;
2562 break;
2563 default:
2564 goto unexpected_bytecode_error;
2565 break;
2566 }
2567 }
2568 }
2569 MOP_OUT;
2570 continue;
2571 break;
2572
2573 #ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
2574 case OP_NULL_CHECK_END_MEMST: MOP_IN(OP_NULL_CHECK_END_MEMST);
2575 {
2576 int isnull;
2577
2578 GET_MEMNUM_INC(mem, p); /* mem: null check id */
2579 STACK_NULL_CHECK_MEMST(isnull, mem, s, reg);
2580 if (isnull) {
2581 #ifdef ONIG_DEBUG_MATCH
2582 fprintf(stderr, "NULL_CHECK_END_MEMST: skip id:%d, s:%"PRIdPTR" (%p)\n",
2583 (int )mem, (intptr_t )s, s);
2584 #endif
2585 if (isnull == -1) goto fail;
2586 goto null_check_found;
2587 }
2588 }
2589 MOP_OUT;
2590 continue;
2591 break;
2592 #endif
2593
2594 #ifdef USE_SUBEXP_CALL
2595 case OP_NULL_CHECK_END_MEMST_PUSH:
2596 MOP_IN(OP_NULL_CHECK_END_MEMST_PUSH);
2597 {
2598 int isnull;
2599
2600 GET_MEMNUM_INC(mem, p); /* mem: null check id */
2601 #ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
2602 STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);
2603 #else
2604 STACK_NULL_CHECK_REC(isnull, mem, s);
2605 #endif
2606 if (isnull) {
2607 #ifdef ONIG_DEBUG_MATCH
2608 fprintf(stderr, "NULL_CHECK_END_MEMST_PUSH: skip id:%d, s:%"PRIdPTR" (%p)\n",
2609 (int )mem, (intptr_t )s, s);
2610 #endif
2611 if (isnull == -1) goto fail;
2612 goto null_check_found;
2613 }
2614 else {
2615 STACK_PUSH_NULL_CHECK_END(mem);
2616 }
2617 }
2618 MOP_OUT;
2619 continue;
2620 break;
2621 #endif
2622
2623 case OP_JUMP: MOP_IN(OP_JUMP);
2624 GET_RELADDR_INC(addr, p);
2625 p += addr;
2626 MOP_OUT;
2627 CHECK_INTERRUPT_IN_MATCH_AT;
2628 continue;
2629 break;
2630
2631 case OP_PUSH: MOP_IN(OP_PUSH);
2632 GET_RELADDR_INC(addr, p);
2633 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
2634 MOP_OUT;
2635 continue;
2636 break;
2637
2638 #ifdef USE_COMBINATION_EXPLOSION_CHECK
2639 case OP_STATE_CHECK_PUSH: MOP_IN(OP_STATE_CHECK_PUSH);
2640 GET_STATE_CHECK_NUM_INC(mem, p);
2641 STATE_CHECK_VAL(scv, mem);
2642 if (scv) goto fail;
2643
2644 GET_RELADDR_INC(addr, p);
2645 STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
2646 MOP_OUT;
2647 continue;
2648 break;
2649
2650 case OP_STATE_CHECK_PUSH_OR_JUMP: MOP_IN(OP_STATE_CHECK_PUSH_OR_JUMP);
2651 GET_STATE_CHECK_NUM_INC(mem, p);
2652 GET_RELADDR_INC(addr, p);
2653 STATE_CHECK_VAL(scv, mem);
2654 if (scv) {
2655 p += addr;
2656 }
2657 else {
2658 STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
2659 }
2660 MOP_OUT;
2661 continue;
2662 break;
2663
2664 case OP_STATE_CHECK: MOP_IN(OP_STATE_CHECK);
2665 GET_STATE_CHECK_NUM_INC(mem, p);
2666 STATE_CHECK_VAL(scv, mem);
2667 if (scv) goto fail;
2668
2669 STACK_PUSH_STATE_CHECK(s, mem);
2670 MOP_OUT;
2671 continue;
2672 break;
2673 #endif /* USE_COMBINATION_EXPLOSION_CHECK */
2674
2675 case OP_POP: MOP_IN(OP_POP);
2676 STACK_POP_ONE;
2677 MOP_OUT;
2678 continue;
2679 break;
2680
2681 case OP_PUSH_OR_JUMP_EXACT1: MOP_IN(OP_PUSH_OR_JUMP_EXACT1);
2682 GET_RELADDR_INC(addr, p);
2683 if (*p == *s && DATA_ENSURE_CHECK1) {
2684 p++;
2685 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
2686 MOP_OUT;
2687 continue;
2688 }
2689 p += (addr + 1);
2690 MOP_OUT;
2691 continue;
2692 break;
2693
2694 case OP_PUSH_IF_PEEK_NEXT: MOP_IN(OP_PUSH_IF_PEEK_NEXT);
2695 GET_RELADDR_INC(addr, p);
2696 if (*p == *s) {
2697 p++;
2698 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
2699 MOP_OUT;
2700 continue;
2701 }
2702 p++;
2703 MOP_OUT;
2704 continue;
2705 break;
2706
2707 case OP_REPEAT: MOP_IN(OP_REPEAT);
2708 {
2709 GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
2710 GET_RELADDR_INC(addr, p);
2711
2712 STACK_ENSURE(1);
2713 repeat_stk[mem] = GET_STACK_INDEX(stk);
2714 STACK_PUSH_REPEAT(mem, p);
2715
2716 if (reg->repeat_range[mem].lower == 0) {
2717 STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
2718 }
2719 }
2720 MOP_OUT;
2721 continue;
2722 break;
2723
2724 case OP_REPEAT_NG: MOP_IN(OP_REPEAT_NG);
2725 {
2726 GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
2727 GET_RELADDR_INC(addr, p);
2728
2729 STACK_ENSURE(1);
2730 repeat_stk[mem] = GET_STACK_INDEX(stk);
2731 STACK_PUSH_REPEAT(mem, p);
2732
2733 if (reg->repeat_range[mem].lower == 0) {
2734 STACK_PUSH_ALT(p, s, sprev, pkeep);
2735 p += addr;
2736 }
2737 }
2738 MOP_OUT;
2739 continue;
2740 break;
2741
2742 case OP_REPEAT_INC: MOP_IN(OP_REPEAT_INC);
2743 GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
2744 si = repeat_stk[mem];
2745 stkp = STACK_AT(si);
2746
2747 repeat_inc:
2748 stkp->u.repeat.count++;
2749 if (stkp->u.repeat.count >= reg->repeat_range[mem].upper) {
2750 /* end of repeat. Nothing to do. */
2751 }
2752 else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
2753 STACK_PUSH_ALT(p, s, sprev, pkeep);
2754 p = STACK_AT(si)->u.repeat.pcode; /* Don't use stkp after PUSH. */
2755 }
2756 else {
2757 p = stkp->u.repeat.pcode;
2758 }
2759 STACK_PUSH_REPEAT_INC(si);
2760 MOP_OUT;
2761 CHECK_INTERRUPT_IN_MATCH_AT;
2762 continue;
2763 break;
2764
2765 case OP_REPEAT_INC_SG: MOP_IN(OP_REPEAT_INC_SG);
2766 GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
2767 STACK_GET_REPEAT(mem, stkp);
2768 si = GET_STACK_INDEX(stkp);
2769 goto repeat_inc;
2770 break;
2771
2772 case OP_REPEAT_INC_NG: MOP_IN(OP_REPEAT_INC_NG);
2773 GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
2774 si = repeat_stk[mem];
2775 stkp = STACK_AT(si);
2776
2777 repeat_inc_ng:
2778 stkp->u.repeat.count++;
2779 if (stkp->u.repeat.count < reg->repeat_range[mem].upper) {
2780 if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
2781 UChar* pcode = stkp->u.repeat.pcode;
2782
2783 STACK_PUSH_REPEAT_INC(si);
2784 STACK_PUSH_ALT(pcode, s, sprev, pkeep);
2785 }
2786 else {
2787 p = stkp->u.repeat.pcode;
2788 STACK_PUSH_REPEAT_INC(si);
2789 }
2790 }
2791 else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {
2792 STACK_PUSH_REPEAT_INC(si);
2793 }
2794 MOP_OUT;
2795 CHECK_INTERRUPT_IN_MATCH_AT;
2796 continue;
2797 break;
2798
2799 case OP_REPEAT_INC_NG_SG: MOP_IN(OP_REPEAT_INC_NG_SG);
2800 GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
2801 STACK_GET_REPEAT(mem, stkp);
2802 si = GET_STACK_INDEX(stkp);
2803 goto repeat_inc_ng;
2804 break;
2805
2806 case OP_PUSH_POS: MOP_IN(OP_PUSH_POS);
2807 STACK_PUSH_POS(s, sprev, pkeep);
2808 MOP_OUT;
2809 continue;
2810 break;
2811
2812 case OP_POP_POS: MOP_IN(OP_POP_POS);
2813 {
2814 STACK_POS_END(stkp);
2815 s = stkp->u.state.pstr;
2816 sprev = stkp->u.state.pstr_prev;
2817 }
2818 MOP_OUT;
2819 continue;
2820 break;
2821
2822 case OP_PUSH_POS_NOT: MOP_IN(OP_PUSH_POS_NOT);
2823 GET_RELADDR_INC(addr, p);
2824 STACK_PUSH_POS_NOT(p + addr, s, sprev, pkeep);
2825 MOP_OUT;
2826 continue;
2827 break;
2828
2829 case OP_FAIL_POS: MOP_IN(OP_FAIL_POS);
2830 STACK_POP_TIL_POS_NOT;
2831 goto fail;
2832 break;
2833
2834 case OP_PUSH_STOP_BT: MOP_IN(OP_PUSH_STOP_BT);
2835 STACK_PUSH_STOP_BT;
2836 MOP_OUT;
2837 continue;
2838 break;
2839
2840 case OP_POP_STOP_BT: MOP_IN(OP_POP_STOP_BT);
2841 STACK_STOP_BT_END;
2842 MOP_OUT;
2843 continue;
2844 break;
2845
2846 case OP_LOOK_BEHIND: MOP_IN(OP_LOOK_BEHIND);
2847 GET_LENGTH_INC(tlen, p);
2848 s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, end, (int )tlen);
2849 if (IS_NULL(s)) goto fail;
2850 sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s, end);
2851 MOP_OUT;
2852 continue;
2853 break;
2854
2855 case OP_PUSH_LOOK_BEHIND_NOT: MOP_IN(OP_PUSH_LOOK_BEHIND_NOT);
2856 GET_RELADDR_INC(addr, p);
2857 GET_LENGTH_INC(tlen, p);
2858 q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, end, (int )tlen);
2859 if (IS_NULL(q)) {
2860 /* too short case -> success. ex. /(?<!XXX)a/.match("a")
2861 If you want to change to fail, replace following line. */
2862 p += addr;
2863 /* goto fail; */
2864 }
2865 else {
2866 STACK_PUSH_LOOK_BEHIND_NOT(p + addr, s, sprev, pkeep);
2867 s = q;
2868 sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s, end);
2869 }
2870 MOP_OUT;
2871 continue;
2872 break;
2873
2874 case OP_FAIL_LOOK_BEHIND_NOT: MOP_IN(OP_FAIL_LOOK_BEHIND_NOT);
2875 STACK_POP_TIL_LOOK_BEHIND_NOT;
2876 goto fail;
2877 break;
2878
2879 #ifdef USE_SUBEXP_CALL
2880 case OP_CALL: MOP_IN(OP_CALL);
2881 GET_ABSADDR_INC(addr, p);
2882 STACK_PUSH_CALL_FRAME(p);
2883 p = reg->p + addr;
2884 MOP_OUT;
2885 continue;
2886 break;
2887
2888 case OP_RETURN: MOP_IN(OP_RETURN);
2889 STACK_RETURN(p);
2890 STACK_PUSH_RETURN;
2891 MOP_OUT;
2892 continue;
2893 break;
2894 #endif
2895
2896 case OP_CONDITION: MOP_IN(OP_CONDITION);
2897 GET_MEMNUM_INC(mem, p);
2898 GET_RELADDR_INC(addr, p);
2899 if ((mem > num_mem) ||
2900 (mem_end_stk[mem] == INVALID_STACK_INDEX) ||
2901 (mem_start_stk[mem] == INVALID_STACK_INDEX)) {
2902 p += addr;
2903 }
2904 MOP_OUT;
2905 continue;
2906 break;
2907
2908 case OP_FINISH:
2909 goto finish;
2910 break;
2911
2912 fail:
2913 MOP_OUT;
2914 /* fall */
2915 case OP_FAIL: MOP_IN(OP_FAIL);
2916 STACK_POP;
2917 p = stk->u.state.pcode;
2918 s = stk->u.state.pstr;
2919 sprev = stk->u.state.pstr_prev;
2920 pkeep = stk->u.state.pkeep;
2921
2922 #ifdef USE_COMBINATION_EXPLOSION_CHECK
2923 if (stk->u.state.state_check != 0) {
2924 stk->type = STK_STATE_CHECK_MARK;
2925 stk++;
2926 }
2927 #endif
2928
2929 MOP_OUT;
2930 continue;
2931 break;
2932
2933 default:
2934 goto bytecode_error;
2935
2936 } /* end of switch */
2937 sprev = sbegin;
2938 } /* end of while(1) */
2939
2940 finish:
2941 STACK_SAVE;
2942 if (xmalloc_base) xfree(xmalloc_base);
2943 return best_len;
2944
2945 #ifdef ONIG_DEBUG
2946 stack_error:
2947 STACK_SAVE;
2948 if (xmalloc_base) xfree(xmalloc_base);
2949 return ONIGERR_STACK_BUG;
2950 #endif
2951
2952 bytecode_error:
2953 STACK_SAVE;
2954 if (xmalloc_base) xfree(xmalloc_base);
2955 return ONIGERR_UNDEFINED_BYTECODE;
2956
2957 unexpected_bytecode_error:
2958 STACK_SAVE;
2959 if (xmalloc_base) xfree(xmalloc_base);
2960 return ONIGERR_UNEXPECTED_BYTECODE;
2961 }
2962
2963
2964 static UChar*
2965 slow_search(OnigEncoding enc, UChar* target, UChar* target_end,
2966 const UChar* text, const UChar* text_end, UChar* text_range)
2967 {
2968 UChar *t, *p, *s, *end;
2969
2970 end = (UChar* )text_end;
2971 end -= target_end - target - 1;
2972 if (end > text_range)
2973 end = text_range;
2974
2975 s = (UChar* )text;
2976
2977 if (enc->max_enc_len == enc->min_enc_len) {
2978 int n = enc->max_enc_len;
2979
2980 while (s < end) {
2981 if (*s == *target) {
2982 p = s + 1;
2983 t = target + 1;
2984 if (target_end == t || memcmp(t, p, target_end - t) == 0)
2985 return s;
2986 }
2987 s += n;
2988 }
2989 return (UChar* )NULL;
2990 }
2991 while (s < end) {
2992 if (*s == *target) {
2993 p = s + 1;
2994 t = target + 1;
2995 if (target_end == t || memcmp(t, p, target_end - t) == 0)
2996 return s;
2997 }
2998 s += enclen(enc, s, text_end);
2999 }
3000
3001 return (UChar* )NULL;
3002 }
3003
3004 static int
3005 str_lower_case_match(OnigEncoding enc, int case_fold_flag,
3006 const UChar* t, const UChar* tend,
3007 const UChar* p, const UChar* end)
3008 {
3009 int lowlen;
3010 UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
3011
3012 while (t < tend) {
3013 lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf);
3014 q = lowbuf;
3015 while (lowlen > 0) {
3016 if (*t++ != *q++) return 0;
3017 lowlen--;
3018 }
3019 }
3020
3021 return 1;
3022 }
3023
3024 static UChar*
3025 slow_search_ic(OnigEncoding enc, int case_fold_flag,
3026 UChar* target, UChar* target_end,
3027 const UChar* text, const UChar* text_end, UChar* text_range)
3028 {
3029 UChar *s, *end;
3030
3031 end = (UChar* )text_end;
3032 end -= target_end - target - 1;
3033 if (end > text_range)
3034 end = text_range;
3035
3036 s = (UChar* )text;
3037
3038 while (s < end) {
3039 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3040 s, text_end))
3041 return s;
3042
3043 s += enclen(enc, s, text_end);
3044 }
3045
3046 return (UChar* )NULL;
3047 }
3048
3049 static UChar*
3050 slow_search_backward(OnigEncoding enc, UChar* target, UChar* target_end,
3051 const UChar* text, const UChar* adjust_text,
3052 const UChar* text_end, const UChar* text_start)
3053 {
3054 UChar *t, *p, *s;
3055
3056 s = (UChar* )text_end;
3057 s -= (target_end - target);
3058 if (s > text_start)
3059 s = (UChar* )text_start;
3060 else
3061 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s, text_end);
3062
3063 while (s >= text) {
3064 if (*s == *target) {
3065 p = s + 1;
3066 t = target + 1;
3067 while (t < target_end) {
3068 if (*t != *p++)
3069 break;
3070 t++;
3071 }
3072 if (t == target_end)
3073 return s;
3074 }
3075 s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
3076 }
3077
3078 return (UChar* )NULL;
3079 }
3080
3081 static UChar*
3082 slow_search_backward_ic(OnigEncoding enc, int case_fold_flag,
3083 UChar* target, UChar* target_end,
3084 const UChar* text, const UChar* adjust_text,
3085 const UChar* text_end, const UChar* text_start)
3086 {
3087 UChar *s;
3088
3089 s = (UChar* )text_end;
3090 s -= (target_end - target);
3091 if (s > text_start)
3092 s = (UChar* )text_start;
3093 else
3094 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s, text_end);
3095
3096 while (s >= text) {
3097 if (str_lower_case_match(enc, case_fold_flag,
3098 target, target_end, s, text_end))
3099 return s;
3100
3101 s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
3102 }
3103
3104 return (UChar* )NULL;
3105 }
3106
3107 #ifndef USE_SUNDAY_QUICK_SEARCH
3108 /* Boyer-Moore-Horspool search applied to a multibyte string */
3109 static UChar*
3110 bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
3111 const UChar* text, const UChar* text_end,
3112 const UChar* text_range)
3113 {
3114 const UChar *s, *se, *t, *p, *end;
3115 const UChar *tail;
3116 ptrdiff_t skip, tlen1;
3117
3118 #ifdef ONIG_DEBUG_SEARCH
3119 fprintf(stderr, "bm_search_notrev: text: %"PRIuPTR" (%p), text_end: %"PRIuPTR" (%p), text_range: %"PRIuPTR" (%p)\n",
3120 text, text, text_end, text_end, text_range, text_range);
3121 #endif
3122
3123 tail = target_end - 1;
3124 tlen1 = tail - target;
3125 end = text_range;
3126 if (end + tlen1 > text_end)
3127 end = text_end - tlen1;
3128
3129 s = text;
3130
3131 if (IS_NULL(reg->int_map)) {
3132 while (s < end) {
3133 p = se = s + tlen1;
3134 t = tail;
3135 while (*p == *t) {
3136 if (t == target) return (UChar* )s;
3137 p--; t--;
3138 }
3139 skip = reg->map[*se];
3140 t = s;
3141 do {
3142 s += enclen(reg->enc, s, end);
3143 } while ((s - t) < skip && s < end);
3144 }
3145 }
3146 else {
3147 while (s < end) {
3148 p = se = s + tlen1;
3149 t = tail;
3150 while (*p == *t) {
3151 if (t == target) return (UChar* )s;
3152 p--; t--;
3153 }
3154 skip = reg->int_map[*se];
3155 t = s;
3156 do {
3157 s += enclen(reg->enc, s, end);
3158 } while ((s - t) < skip && s < end);
3159 }
3160 }
3161
3162 return (UChar* )NULL;
3163 }
3164
3165 /* Boyer-Moore-Horspool search */
3166 static UChar*
3167 bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
3168 const UChar* text, const UChar* text_end, const UChar* text_range)
3169 {
3170 const UChar *s, *t, *p, *end;
3171 const UChar *tail;
3172
3173 #ifdef ONIG_DEBUG_SEARCH
3174 fprintf(stderr, "bm_search: text: %"PRIuPTR", text_end: %"PRIuPTR", text_range: %"PRIuPTR"\n",
3175 text, text_end, text_range);
3176 #endif
3177
3178 end = text_range + (target_end - target) - 1;
3179 if (end > text_end)
3180 end = text_end;
3181
3182 tail = target_end - 1;
3183 s = text + (target_end - target) - 1;
3184 if (IS_NULL(reg->int_map)) {
3185 while (s < end) {
3186 p = s;
3187 t = tail;
3188 #ifdef ONIG_DEBUG_SEARCH
3189 fprintf(stderr, "bm_search_loop: pos: %d %s\n",
3190 (int)(s - text), s);
3191 #endif
3192 while (*p == *t) {
3193 if (t == target) return (UChar* )p;
3194 p--; t--;
3195 }
3196 s += reg->map[*s];
3197 }
3198 }
3199 else { /* see int_map[] */
3200 while (s < end) {
3201 p = s;
3202 t = tail;
3203 while (*p == *t) {
3204 if (t == target) return (UChar* )p;
3205 p--; t--;
3206 }
3207 s += reg->int_map[*s];
3208 }
3209 }
3210 return (UChar* )NULL;
3211 }
3212
3213 /* Boyer-Moore-Horspool search applied to a multibyte string (ignore case) */
3214 static UChar*
3215 bm_search_notrev_ic(regex_t* reg, const UChar* target, const UChar* target_end,
3216 const UChar* text, const UChar* text_end,
3217 const UChar* text_range)
3218 {
3219 const UChar *s, *se, *t, *end;
3220 const UChar *tail;
3221 ptrdiff_t skip, tlen1;
3222 OnigEncoding enc = reg->enc;
3223 int case_fold_flag = reg->case_fold_flag;
3224
3225 #ifdef ONIG_DEBUG_SEARCH
3226 fprintf(stderr, "bm_search_notrev_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
3227 (int )text, text, (int )text_end, text_end, (int )text_range, text_range);
3228 #endif
3229
3230 tail = target_end - 1;
3231 tlen1 = tail - target;
3232 end = text_range;
3233 if (end + tlen1 > text_end)
3234 end = text_end - tlen1;
3235
3236 s = text;
3237
3238 if (IS_NULL(reg->int_map)) {
3239 while (s < end) {
3240 se = s + tlen1;
3241 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3242 s, se + 1))
3243 return (UChar* )s;
3244 skip = reg->map[*se];
3245 t = s;
3246 do {
3247 s += enclen(reg->enc, s, end);
3248 } while ((s - t) < skip && s < end);
3249 }
3250 }
3251 else {
3252 while (s < end) {
3253 se = s + tlen1;
3254 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3255 s, se + 1))
3256 return (UChar* )s;
3257 skip = reg->int_map[*se];
3258 t = s;
3259 do {
3260 s += enclen(reg->enc, s, end);
3261 } while ((s - t) < skip && s < end);
3262 }
3263 }
3264
3265 return (UChar* )NULL;
3266 }
3267
3268 /* Boyer-Moore-Horspool search (ignore case) */
3269 static UChar*
3270 bm_search_ic(regex_t* reg, const UChar* target, const UChar* target_end,
3271 const UChar* text, const UChar* text_end, const UChar* text_range)
3272 {
3273 const UChar *s, *p, *end;
3274 const UChar *tail;
3275 OnigEncoding enc = reg->enc;
3276 int case_fold_flag = reg->case_fold_flag;
3277
3278 #ifdef ONIG_DEBUG_SEARCH
3279 fprintf(stderr, "bm_search_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
3280 (int )text, text, (int )text_end, text_end, (int )text_range, text_range);
3281 #endif
3282
3283 end = text_range + (target_end - target) - 1;
3284 if (end > text_end)
3285 end = text_end;
3286
3287 tail = target_end - 1;
3288 s = text + (target_end - target) - 1;
3289 if (IS_NULL(reg->int_map)) {
3290 while (s < end) {
3291 p = s - (target_end - target) + 1;
3292 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3293 p, s + 1))
3294 return (UChar* )p;
3295 s += reg->map[*s];
3296 }
3297 }
3298 else { /* see int_map[] */
3299 while (s < end) {
3300 p = s - (target_end - target) + 1;
3301 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3302 p, s + 1))
3303 return (UChar* )p;
3304 s += reg->int_map[*s];
3305 }
3306 }
3307 return (UChar* )NULL;
3308 }
3309
3310 #else /* USE_SUNDAY_QUICK_SEARCH */
3311
3312 /* Sunday's quick search applied to a multibyte string */
3313 static UChar*
3314 bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
3315 const UChar* text, const UChar* text_end,
3316 const UChar* text_range)
3317 {
3318 const UChar *s, *se, *t, *p, *end;
3319 const UChar *tail;
3320 ptrdiff_t skip, tlen1;
3321 OnigEncoding enc = reg->enc;
3322
3323 #ifdef ONIG_DEBUG_SEARCH
3324 fprintf(stderr, "bm_search_notrev: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
3325 (int )text, text, (int )text_end, text_end, (int )text_range, text_range);
3326 #endif
3327
3328 tail = target_end - 1;
3329 tlen1 = tail - target;
3330 end = text_range;
3331 if (end + tlen1 > text_end)
3332 end = text_end - tlen1;
3333
3334 s = text;
3335
3336 if (IS_NULL(reg->int_map)) {
3337 while (s < end) {
3338 p = se = s + tlen1;
3339 t = tail;
3340 while (*p == *t) {
3341 if (t == target) return (UChar* )s;
3342 p--; t--;
3343 }
3344 if (s + 1 >= end) break;
3345 skip = reg->map[se[1]];
3346 t = s;
3347 do {
3348 s += enclen(enc, s, end);
3349 } while ((s - t) < skip && s < end);
3350 }
3351 }
3352 else {
3353 while (s < end) {
3354 p = se = s + tlen1;
3355 t = tail;
3356 while (*p == *t) {
3357 if (t == target) return (UChar* )s;
3358 p--; t--;
3359 }
3360 if (s + 1 >= end) break;
3361 skip = reg->int_map[se[1]];
3362 t = s;
3363 do {
3364 s += enclen(enc, s, end);
3365 } while ((s - t) < skip && s < end);
3366 }
3367 }
3368
3369 return (UChar* )NULL;
3370 }
3371
3372 /* Sunday's quick search */
3373 static UChar*
3374 bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
3375 const UChar* text, const UChar* text_end, const UChar* text_range)
3376 {
3377 const UChar *s, *t, *p, *end;
3378 const UChar *tail;
3379 ptrdiff_t tlen1;
3380
3381 tail = target_end - 1;
3382 tlen1 = tail - target;
3383 end = text_range + tlen1;
3384 if (end > text_end)
3385 end = text_end;
3386
3387 s = text + tlen1;
3388 if (IS_NULL(reg->int_map)) {
3389 while (s < end) {
3390 p = s;
3391 t = tail;
3392 while (*p == *t) {
3393 if (t == target) return (UChar* )p;
3394 p--; t--;
3395 }
3396 if (s + 1 >= end) break;
3397 s += reg->map[s[1]];
3398 }
3399 }
3400 else { /* see int_map[] */
3401 while (s < end) {
3402 p = s;
3403 t = tail;
3404 while (*p == *t) {
3405 if (t == target) return (UChar* )p;
3406 p--; t--;
3407 }
3408 if (s + 1 >= end) break;
3409 s += reg->int_map[s[1]];
3410 }
3411 }
3412 return (UChar* )NULL;
3413 }
3414
3415 /* Sunday's quick search applied to a multibyte string (ignore case) */
3416 static UChar*
3417 bm_search_notrev_ic(regex_t* reg, const UChar* target, const UChar* target_end,
3418 const UChar* text, const UChar* text_end,
3419 const UChar* text_range)
3420 {
3421 const UChar *s, *se, *t, *end;
3422 const UChar *tail;
3423 ptrdiff_t skip, tlen1;
3424 OnigEncoding enc = reg->enc;
3425 int case_fold_flag = reg->case_fold_flag;
3426
3427 #ifdef ONIG_DEBUG_SEARCH
3428 fprintf(stderr, "bm_search_notrev_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
3429 (int )text, text, (int )text_end, text_end, (int )text_range, text_range);
3430 #endif
3431
3432 tail = target_end - 1;
3433 tlen1 = tail - target;
3434 end = text_range;
3435 if (end + tlen1 > text_end)
3436 end = text_end - tlen1;
3437
3438 s = text;
3439
3440 if (IS_NULL(reg->int_map)) {
3441 while (s < end) {
3442 se = s + tlen1;
3443 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3444 s, se + 1))
3445 return (UChar* )s;
3446 if (s + 1 >= end) break;
3447 skip = reg->map[se[1]];
3448 t = s;
3449 do {
3450 s += enclen(enc, s, end);
3451 } while ((s - t) < skip && s < end);
3452 }
3453 }
3454 else {
3455 while (s < end) {
3456 se = s + tlen1;
3457 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3458 s, se + 1))
3459 return (UChar* )s;
3460 if (s + 1 >= end) break;
3461 skip = reg->int_map[se[1]];
3462 t = s;
3463 do {
3464 s += enclen(enc, s, end);
3465 } while ((s - t) < skip && s < end);
3466 }
3467 }
3468
3469 return (UChar* )NULL;
3470 }
3471
3472 /* Sunday's quick search (ignore case) */
3473 static UChar*
3474 bm_search_ic(regex_t* reg, const UChar* target, const UChar* target_end,
3475 const UChar* text, const UChar* text_end, const UChar* text_range)
3476 {
3477 const UChar *s, *p, *end;
3478 const UChar *tail;
3479 ptrdiff_t tlen1;
3480 OnigEncoding enc = reg->enc;
3481 int case_fold_flag = reg->case_fold_flag;
3482
3483 #ifdef ONIG_DEBUG_SEARCH
3484 fprintf(stderr, "bm_search_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
3485 (int )text, text, (int )text_end, text_end, (int )text_range, text_range);
3486 #endif
3487
3488 tail = target_end - 1;
3489 tlen1 = tail - target;
3490 end = text_range + tlen1;
3491 if (end > text_end)
3492 end = text_end;
3493
3494 s = text + tlen1;
3495 if (IS_NULL(reg->int_map)) {
3496 while (s < end) {
3497 p = s - tlen1;
3498 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3499 p, s + 1))
3500 return (UChar* )p;
3501 if (s + 1 >= end) break;
3502 s += reg->map[s[1]];
3503 }
3504 }
3505 else { /* see int_map[] */
3506 while (s < end) {
3507 p = s - tlen1;
3508 if (str_lower_case_match(enc, case_fold_flag, target, target_end,
3509 p, s + 1))
3510 return (UChar* )p;
3511 if (s + 1 >= end) break;
3512 s += reg->int_map[s[1]];
3513 }
3514 }
3515 return (UChar* )NULL;
3516 }
3517 #endif /* USE_SUNDAY_QUICK_SEARCH */
3518
3519 static int
3520 set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED,
3521 int** skip)
3522 {
3523 int i, len;
3524
3525 if (IS_NULL(*skip)) {
3526 *skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
3527 if (IS_NULL(*skip)) return ONIGERR_MEMORY;
3528 }
3529
3530 len = (int )(end - s);
3531 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
3532 (*skip)[i] = len;
3533
3534 for (i = len - 1; i > 0; i--)
3535 (*skip)[s[i]] = i;
3536
3537 return 0;
3538 }
3539
3540 static UChar*
3541 bm_search_backward(regex_t* reg, const UChar* target, const UChar* target_end,
3542 const UChar* text, const UChar* adjust_text,
3543 const UChar* text_end, const UChar* text_start)
3544 {
3545 const UChar *s, *t, *p;
3546
3547 s = text_end - (target_end - target);
3548 if (text_start < s)
3549 s = text_start;
3550 else
3551 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s, text_end);
3552
3553 while (s >= text) {
3554 p = s;
3555 t = target;
3556 while (t < target_end && *p == *t) {
3557 p++; t++;
3558 }
3559 if (t == target_end)
3560 return (UChar* )s;
3561
3562 s -= reg->int_map_backward[*s];
3563 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s, text_end);
3564 }
3565
3566 return (UChar* )NULL;
3567 }
3568
3569 static UChar*
3570 map_search(OnigEncoding enc, UChar map[],
3571 const UChar* text, const UChar* text_range, const UChar* text_end)
3572 {
3573 const UChar *s = text;
3574
3575 while (s < text_range) {
3576 if (map[*s]) return (UChar* )s;
3577
3578 s += enclen(enc, s, text_end);
3579 }
3580 return (UChar* )NULL;
3581 }
3582
3583 static UChar*
3584 map_search_backward(OnigEncoding enc, UChar map[],
3585 const UChar* text, const UChar* adjust_text,
3586 const UChar* text_start, const UChar* text_end)
3587 {
3588 const UChar *s = text_start;
3589
3590 while (s >= text) {
3591 if (map[*s]) return (UChar* )s;
3592
3593 s = onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
3594 }
3595 return (UChar* )NULL;
3596 }
3597
3598 extern OnigPosition
3599 onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, OnigRegion* region,
3600 OnigOptionType option)
3601 {
3602 ptrdiff_t r;
3603 UChar *prev;
3604 OnigMatchArg msa;
3605
3606 #if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
3607 start:
3608 THREAD_ATOMIC_START;
3609 if (ONIG_STATE(reg) >= ONIG_STATE_NORMAL) {
3610 ONIG_STATE_INC(reg);
3611 if (IS_NOT_NULL(reg->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {
3612 onig_chain_reduce(reg);
3613 ONIG_STATE_INC(reg);
3614 }
3615 }
3616 else {
3617 int n;
3618
3619 THREAD_ATOMIC_END;
3620 n = 0;
3621 while (ONIG_STATE(reg) < ONIG_STATE_NORMAL) {
3622 if (++n > THREAD_PASS_LIMIT_COUNT)
3623 return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;
3624 THREAD_PASS;
3625 }
3626 goto start;
3627 }
3628 THREAD_ATOMIC_END;
3629 #endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
3630
3631 MATCH_ARG_INIT(msa, option, region, at, at);
3632 #ifdef USE_COMBINATION_EXPLOSION_CHECK
3633 {
3634 int offset = at - str;
3635 STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);
3636 }
3637 #endif
3638
3639 if (region
3640 #ifdef USE_POSIX_API_REGION_OPTION
3641 && !IS_POSIX_REGION(option)
3642 #endif
3643 ) {
3644 r = onig_region_resize_clear(region, reg->num_mem + 1);
3645 }
3646 else
3647 r = 0;
3648
3649 if (r == 0) {
3650 prev = (UChar* )onigenc_get_prev_char_head(reg->enc, str, at, end);
3651 r = match_at(reg, str, end,
3652 #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
3653 end,
3654 #endif
3655 at, prev, &msa);
3656 }
3657
3658 MATCH_ARG_FREE(msa);
3659 ONIG_STATE_DEC_THREAD(reg);
3660 return r;
3661 }
3662
3663 static int
3664 forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
3665 UChar* range, UChar** low, UChar** high, UChar** low_prev)
3666 {
3667 UChar *p, *pprev = (UChar* )NULL;
3668
3669 #ifdef ONIG_DEBUG_SEARCH
3670 fprintf(stderr, "forward_search_range: str: %"PRIuPTR" (%p), end: %"PRIuPTR" (%p), s: %"PRIuPTR" (%p), range: %"PRIuPTR" (%p)\n",
3671 str, str, end, end, s, s, range, range);
3672 #endif
3673
3674 p = s;
3675 if (reg->dmin > 0) {
3676 if (ONIGENC_IS_SINGLEBYTE(reg->enc)) {
3677 p += reg->dmin;
3678 }
3679 else {
3680 UChar *q = p + reg->dmin;
3681 while (p < q) p += enclen(reg->enc, p, end);
3682 }
3683 }
3684
3685 retry:
3686 switch (reg->optimize) {
3687 case ONIG_OPTIMIZE_EXACT:
3688 p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);
3689 break;
3690 case ONIG_OPTIMIZE_EXACT_IC:
3691 p = slow_search_ic(reg->enc, reg->case_fold_flag,
3692 reg->exact, reg->exact_end, p, end, range);
3693 break;
3694
3695 case ONIG_OPTIMIZE_EXACT_BM:
3696 p = bm_search(reg, reg->exact, reg->exact_end, p, end, range);
3697 break;
3698
3699 case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:
3700 p = bm_search_notrev(reg, reg->exact, reg->exact_end, p, end, range);
3701 break;
3702
3703 case ONIG_OPTIMIZE_EXACT_BM_IC:
3704 p = bm_search_ic(reg, reg->exact, reg->exact_end, p, end, range);
3705 break;
3706
3707 case ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC:
3708 p = bm_search_notrev_ic(reg, reg->exact, reg->exact_end, p, end, range);
3709 break;
3710
3711 case ONIG_OPTIMIZE_MAP:
3712 p = map_search(reg->enc, reg->map, p, range, end);
3713 break;
3714 }
3715
3716 if (p && p < range) {
3717 if (p - reg->dmin < s) {
3718 retry_gate:
3719 pprev = p;
3720 p += enclen(reg->enc, p, end);
3721 goto retry;
3722 }
3723
3724 if (reg->sub_anchor) {
3725 UChar* prev;
3726
3727 switch (reg->sub_anchor) {
3728 case ANCHOR_BEGIN_LINE:
3729 if (!ON_STR_BEGIN(p)) {
3730 prev = onigenc_get_prev_char_head(reg->enc,
3731 (pprev ? pprev : str), p, end);
3732 if (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0))
3733 goto retry_gate;
3734 }
3735 break;
3736
3737 case ANCHOR_END_LINE:
3738 if (ON_STR_END(p)) {
3739 #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
3740 prev = (UChar* )onigenc_get_prev_char_head(reg->enc,
3741 (pprev ? pprev : str), p);
3742 if (prev && ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 1))
3743 goto retry_gate;
3744 #endif
3745 }
3746 else if (! ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, p, str, end, reg->options, 1))
3747 goto retry_gate;
3748 break;
3749 }
3750 }
3751
3752 if (reg->dmax == 0) {
3753 *low = p;
3754 if (low_prev) {
3755 if (*low > s)
3756 *low_prev = onigenc_get_prev_char_head(reg->enc, s, p, end);
3757 else
3758 *low_prev = onigenc_get_prev_char_head(reg->enc,
3759 (pprev ? pprev : str), p, end);
3760 }
3761 }
3762 else {
3763 if (reg->dmax != ONIG_INFINITE_DISTANCE) {
3764 *low = p - reg->dmax;
3765 if (*low > s) {
3766 *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
3767 *low, end, (const UChar** )low_prev);
3768 if (low_prev && IS_NULL(*low_prev))
3769 *low_prev = onigenc_get_prev_char_head(reg->enc,
3770 (pprev ? pprev : s), *low, end);
3771 }
3772 else {
3773 if (low_prev)
3774 *low_prev = onigenc_get_prev_char_head(reg->enc,
3775 (pprev ? pprev : str), *low, end);
3776 }
3777 }
3778 }
3779 /* no needs to adjust *high, *high is used as range check only */
3780 *high = p - reg->dmin;
3781
3782 #ifdef ONIG_DEBUG_SEARCH
3783 fprintf(stderr,
3784 "forward_search_range success: low: %d, high: %d, dmin: %d, dmax: %d\n",
3785 (int )(*low - str), (int )(*high - str), reg->dmin, reg->dmax);
3786 #endif
3787 return 1; /* success */
3788 }
3789
3790 return 0; /* fail */
3791 }
3792
3793 static int set_bm_backward_skip P_((UChar* s, UChar* end, OnigEncoding enc,
3794 int** skip));
3795
3796 #define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD 100
3797
3798 static int
3799 backward_search_range(regex_t* reg, const UChar* str, const UChar* end,
3800 UChar* s, const UChar* range, UChar* adjrange,
3801 UChar** low, UChar** high)
3802 {
3803 int r;
3804 UChar *p;
3805
3806 range += reg->dmin;
3807 p = s;
3808
3809 retry:
3810 switch (reg->optimize) {
3811 case ONIG_OPTIMIZE_EXACT:
3812 exact_method:
3813 p = slow_search_backward(reg->enc, reg->exact, reg->exact_end,
3814 range, adjrange, end, p);
3815 break;
3816
3817 case ONIG_OPTIMIZE_EXACT_IC:
3818 case ONIG_OPTIMIZE_EXACT_BM_IC:
3819 case ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC:
3820 p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,
3821 reg->exact, reg->exact_end,
3822 range, adjrange, end, p);
3823 break;
3824
3825 case ONIG_OPTIMIZE_EXACT_BM:
3826 case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:
3827 if (IS_NULL(reg->int_map_backward)) {
3828 if (s - range < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD)
3829 goto exact_method;
3830
3831 r = set_bm_backward_skip(reg->exact, reg->exact_end, reg->enc,
3832 &(reg->int_map_backward));
3833 if (r) return r;
3834 }
3835 p = bm_search_backward(reg, reg->exact, reg->exact_end, range, adjrange,
3836 end, p);
3837 break;
3838
3839 case ONIG_OPTIMIZE_MAP:
3840 p = map_search_backward(reg->enc, reg->map, range, adjrange, p, end);
3841 break;
3842 }
3843
3844 if (p) {
3845 if (reg->sub_anchor) {
3846 UChar* prev;
3847
3848 switch (reg->sub_anchor) {
3849 case ANCHOR_BEGIN_LINE:
3850 if (!ON_STR_BEGIN(p)) {
3851 prev = onigenc_get_prev_char_head(reg->enc, str, p, end);
3852 if (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0)) {
3853 p = prev;
3854 goto retry;
3855 }
3856 }
3857 break;
3858
3859 case ANCHOR_END_LINE:
3860 if (ON_STR_END(p)) {
3861 #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
3862 prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);
3863 if (IS_NULL(prev)) goto fail;
3864 if (ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 1)) {
3865 p = prev;
3866 goto retry;
3867 }
3868 #endif
3869 }
3870 else if (! ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, p, str, end, reg->options, 1)) {
3871 p = onigenc_get_prev_char_head(reg->enc, adjrange, p, end);
3872 if (IS_NULL(p)) goto fail;
3873 goto retry;
3874 }
3875 break;
3876 }
3877 }
3878
3879 /* no needs to adjust *high, *high is used as range check only */
3880 if (reg->dmax != ONIG_INFINITE_DISTANCE) {
3881 *low = p - reg->dmax;
3882 *high = p - reg->dmin;
3883 *high = onigenc_get_right_adjust_char_head(reg->enc, adjrange, *high, end);
3884 }
3885
3886 #ifdef ONIG_DEBUG_SEARCH
3887 fprintf(stderr, "backward_search_range: low: %d, high: %d\n",
3888 (int )(*low - str), (int )(*high - str));
3889 #endif
3890 return 1; /* success */
3891 }
3892
3893 fail:
3894 #ifdef ONIG_DEBUG_SEARCH
3895 fprintf(stderr, "backward_search_range: fail.\n");
3896 #endif
3897 return 0; /* fail */
3898 }
3899
3900
3901 extern OnigPosition
3902 onig_search(regex_t* reg, const UChar* str, const UChar* end,
3903 const UChar* start, const UChar* range, OnigRegion* region, OnigOptionType option)
3904 {
3905 return onig_search_gpos(reg, str, end, start, start, range, region, option);
3906 }
3907
3908 extern OnigPosition
3909 onig_search_gpos(regex_t* reg, const UChar* str, const UChar* end,
3910 const UChar* global_pos,
3911 const UChar* start, const UChar* range, OnigRegion* region, OnigOptionType option)
3912 {
3913 ptrdiff_t r;
3914 UChar *s, *prev;
3915 OnigMatchArg msa;
3916 #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
3917 const UChar *orig_start = start;
3918 const UChar *orig_range = range;
3919 #endif
3920
3921 #if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
3922 start:
3923 THREAD_ATOMIC_START;
3924 if (ONIG_STATE(reg) >= ONIG_STATE_NORMAL) {
3925 ONIG_STATE_INC(reg);
3926 if (IS_NOT_NULL(reg->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {
3927 onig_chain_reduce(reg);
3928 ONIG_STATE_INC(reg);
3929 }
3930 }
3931 else {
3932 int n;
3933
3934 THREAD_ATOMIC_END;
3935 n = 0;
3936 while (ONIG_STATE(reg) < ONIG_STATE_NORMAL) {
3937 if (++n > THREAD_PASS_LIMIT_COUNT)
3938 return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;
3939 THREAD_PASS;
3940 }
3941 goto start;
3942 }
3943 THREAD_ATOMIC_END;
3944 #endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
3945
3946 #ifdef ONIG_DEBUG_SEARCH
3947 fprintf(stderr,
3948 "onig_search (entry point): str: %"PRIuPTR" (%p), end: %"PRIuPTR", start: %"PRIuPTR", range: %"PRIuPTR"\n",
3949 str, str, end - str, start - str, range - str);
3950 #endif
3951
3952 if (region
3953 #ifdef USE_POSIX_API_REGION_OPTION
3954 && !IS_POSIX_REGION(option)
3955 #endif
3956 ) {
3957 r = onig_region_resize_clear(region, reg->num_mem + 1);
3958 if (r) goto finish_no_msa;
3959 }
3960
3961 if (start > end || start < str) goto mismatch_no_msa;
3962
3963
3964 #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
3965 #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
3966 #define MATCH_AND_RETURN_CHECK(upper_range) \
3967 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
3968 if (r != ONIG_MISMATCH) {\
3969 if (r >= 0) {\
3970 if (! IS_FIND_LONGEST(reg->options)) {\
3971 goto match;\
3972 }\
3973 }\
3974 else goto finish; /* error */ \
3975 }
3976 #else
3977 #define MATCH_AND_RETURN_CHECK(upper_range) \
3978 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
3979 if (r != ONIG_MISMATCH) {\
3980 if (r >= 0) {\
3981 goto match;\
3982 }\
3983 else goto finish; /* error */ \
3984 }
3985 #endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */
3986 #else
3987 #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
3988 #define MATCH_AND_RETURN_CHECK(none) \
3989 r = match_at(reg, str, end, s, prev, &msa);\
3990 if (r != ONIG_MISMATCH) {\
3991 if (r >= 0) {\
3992 if (! IS_FIND_LONGEST(reg->options)) {\
3993 goto match;\
3994 }\
3995 }\
3996 else goto finish; /* error */ \
3997 }
3998 #else
3999 #define MATCH_AND_RETURN_CHECK(none) \
4000 r = match_at(reg, str, end, s, prev, &msa);\
4001 if (r != ONIG_MISMATCH) {\
4002 if (r >= 0) {\
4003 goto match;\
4004 }\
4005 else goto finish; /* error */ \
4006 }
4007 #endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */
4008 #endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
4009
4010
4011 /* anchor optimize: resume search range */
4012 if (reg->anchor != 0 && str < end) {
4013 UChar *min_semi_end, *max_semi_end;
4014
4015 if (reg->anchor & ANCHOR_BEGIN_POSITION) {
4016 /* search start-position only */
4017 begin_position:
4018 if (range > start)
4019 range = start + 1;
4020 else
4021 range = start;
4022 }
4023 else if (reg->anchor & ANCHOR_BEGIN_BUF) {
4024 /* search str-position only */
4025 if (range > start) {
4026 if (start != str) goto mismatch_no_msa;
4027 range = str + 1;
4028 }
4029 else {
4030 if (range <= str) {
4031 start = str;
4032 range = str;
4033 }
4034 else
4035 goto mismatch_no_msa;
4036 }
4037 }
4038 else if (reg->anchor & ANCHOR_END_BUF) {
4039 min_semi_end = max_semi_end = (UChar* )end;
4040
4041 end_buf:
4042 if ((OnigDistance )(max_semi_end - str) < reg->anchor_dmin)
4043 goto mismatch_no_msa;
4044
4045 if (range > start) {
4046 if ((OnigDistance )(min_semi_end - start) > reg->anchor_dmax) {
4047 start = min_semi_end - reg->anchor_dmax;
4048 if (start < end)
4049 start = onigenc_get_right_adjust_char_head(reg->enc, str, start, end);
4050 }
4051 if ((OnigDistance )(max_semi_end - (range - 1)) < reg->anchor_dmin) {
4052 range = max_semi_end - reg->anchor_dmin + 1;
4053 }
4054
4055 if (start > range) goto mismatch_no_msa;
4056 /* If start == range, match with empty at end.
4057 Backward search is used. */
4058 }
4059 else {
4060 if ((OnigDistance )(min_semi_end - range) > reg->anchor_dmax) {
4061 range = min_semi_end - reg->anchor_dmax;
4062 }
4063 if ((OnigDistance )(max_semi_end - start) < reg->anchor_dmin) {
4064 start = max_semi_end - reg->anchor_dmin;
4065 start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, start, end);
4066 }
4067 if (range > start) goto mismatch_no_msa;
4068 }
4069 }
4070 else if (reg->anchor & ANCHOR_SEMI_END_BUF) {
4071 UChar* pre_end = ONIGENC_STEP_BACK(reg->enc, str, end, end, 1);
4072
4073 max_semi_end = (UChar* )end;
4074 if (ONIGENC_IS_MBC_NEWLINE(reg->enc, pre_end, end)) {
4075 min_semi_end = pre_end;
4076
4077 #ifdef USE_CRNL_AS_LINE_TERMINATOR
4078 pre_end = ONIGENC_STEP_BACK(reg->enc, str, pre_end, end, 1);
4079 if (IS_NOT_NULL(pre_end) &&
4080 IS_NEWLINE_CRLF(reg->options) &&
4081 ONIGENC_IS_MBC_CRNL(reg->enc, pre_end, end)) {
4082 min_semi_end = pre_end;
4083 }
4084 #endif
4085 if (min_semi_end > str && start <= min_semi_end) {
4086 goto end_buf;
4087 }
4088 }
4089 else {
4090 min_semi_end = (UChar* )end;
4091 goto end_buf;
4092 }
4093 }
4094 else if ((reg->anchor & ANCHOR_ANYCHAR_STAR_ML)) {
4095 if (! (reg->anchor & ANCHOR_LOOK_BEHIND)) {
4096 goto begin_position;
4097 }
4098 }
4099 }
4100 else if (str == end) { /* empty string */
4101 static const UChar address_for_empty_string[] = "";
4102
4103 #ifdef ONIG_DEBUG_SEARCH
4104 fprintf(stderr, "onig_search: empty string.\n");
4105 #endif
4106
4107 if (reg->threshold_len == 0) {
4108 start = end = str = address_for_empty_string;
4109 s = (UChar* )start;
4110 prev = (UChar* )NULL;
4111
4112 MATCH_ARG_INIT(msa, option, region, start, start);
4113 #ifdef USE_COMBINATION_EXPLOSION_CHECK
4114 msa.state_check_buff = (void* )0;
4115 msa.state_check_buff_size = 0; /* NO NEED, for valgrind */
4116 #endif
4117 MATCH_AND_RETURN_CHECK(end);
4118 goto mismatch;
4119 }
4120 goto mismatch_no_msa;
4121 }
4122
4123 #ifdef ONIG_DEBUG_SEARCH
4124 fprintf(stderr, "onig_search(apply anchor): end: %d, start: %d, range: %d\n",
4125 (int )(end - str), (int )(start - str), (int )(range - str));
4126 #endif
4127
4128 MATCH_ARG_INIT(msa, option, region, start, global_pos);
4129 #ifdef USE_COMBINATION_EXPLOSION_CHECK
4130 {
4131 int offset = (MIN(start, range) - str);
4132 STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);
4133 }
4134 #endif
4135
4136 s = (UChar* )start;
4137 if (range > start) { /* forward search */
4138 if (s > str)
4139 prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
4140 else
4141 prev = (UChar* )NULL;
4142
4143 if (reg->optimize != ONIG_OPTIMIZE_NONE) {
4144 UChar *sch_range, *low, *high, *low_prev;
4145
4146 sch_range = (UChar* )range;
4147 if (reg->dmax != 0) {
4148 if (reg->dmax == ONIG_INFINITE_DISTANCE)
4149 sch_range = (UChar* )end;
4150 else {
4151 sch_range += reg->dmax;
4152 if (sch_range > end) sch_range = (UChar* )end;
4153 }
4154 }
4155
4156 if ((end - start) < reg->threshold_len)
4157 goto mismatch;
4158
4159 if (reg->dmax != ONIG_INFINITE_DISTANCE) {
4160 do {
4161 if (! forward_search_range(reg, str, end, s, sch_range,
4162 &low, &high, &low_prev)) goto mismatch;
4163 if (s < low) {
4164 s = low;
4165 prev = low_prev;
4166 }
4167 while (s <= high) {
4168 MATCH_AND_RETURN_CHECK(orig_range);
4169 prev = s;
4170 s += enclen(reg->enc, s, end);
4171 }
4172 } while (s < range);
4173 goto mismatch;
4174 }
4175 else { /* check only. */
4176 if (! forward_search_range(reg, str, end, s, sch_range,
4177 &low, &high, (UChar** )NULL)) goto mismatch;
4178
4179 if ((reg->anchor & ANCHOR_ANYCHAR_STAR) != 0) {
4180 do {
4181 if ((reg->anchor & ANCHOR_BEGIN_POSITION) == 0)
4182 msa.gpos = s; /* move \G position */
4183 MATCH_AND_RETURN_CHECK(orig_range);
4184 prev = s;
4185 s += enclen(reg->enc, s, end);
4186
4187 if ((reg->anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) == 0) {
4188 while (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0)
4189 && s < range) {
4190 prev = s;
4191 s += enclen(reg->enc, s, end);
4192 }
4193 }
4194 } while (s < range);
4195 goto mismatch;
4196 }
4197 }
4198 }
4199
4200 do {
4201 MATCH_AND_RETURN_CHECK(orig_range);
4202 prev = s;
4203 s += enclen(reg->enc, s, end);
4204 } while (s < range);
4205
4206 if (s == range) { /* because empty match with /$/. */
4207 MATCH_AND_RETURN_CHECK(orig_range);
4208 }
4209 }
4210 else { /* backward search */
4211 #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
4212 if (orig_start < end)
4213 orig_start += enclen(reg->enc, orig_start, end); /* is upper range */
4214 #endif
4215
4216 if (reg->optimize != ONIG_OPTIMIZE_NONE) {
4217 UChar *low, *high, *adjrange, *sch_start;
4218
4219 if (range < end)
4220 adjrange = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, range, end);
4221 else
4222 adjrange = (UChar* )end;
4223
4224 if (reg->dmax != ONIG_INFINITE_DISTANCE &&
4225 (end - range) >= reg->threshold_len) {
4226 do {
4227 sch_start = s + reg->dmax;
4228 if (sch_start > end) sch_start = (UChar* )end;
4229 if (backward_search_range(reg, str, end, sch_start, range, adjrange,
4230 &low, &high) <= 0)
4231 goto mismatch;
4232
4233 if (s > high)
4234 s = high;
4235
4236 while (s >= low) {
4237 prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
4238 MATCH_AND_RETURN_CHECK(orig_start);
4239 s = prev;
4240 }
4241 } while (s >= range);
4242 goto mismatch;
4243 }
4244 else { /* check only. */
4245 if ((end - range) < reg->threshold_len) goto mismatch;
4246
4247 sch_start = s;
4248 if (reg->dmax != 0) {
4249 if (reg->dmax == ONIG_INFINITE_DISTANCE)
4250 sch_start = (UChar* )end;
4251 else {
4252 sch_start += reg->dmax;
4253 if (sch_start > end) sch_start = (UChar* )end;
4254 else
4255 sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc,
4256 start, sch_start, end);
4257 }
4258 }
4259 if (backward_search_range(reg, str, end, sch_start, range, adjrange,
4260 &low, &high) <= 0) goto mismatch;
4261 }
4262 }
4263
4264 do {
4265 prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
4266 MATCH_AND_RETURN_CHECK(orig_start);
4267 s = prev;
4268 } while (s >= range);
4269 }
4270
4271 mismatch:
4272 #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
4273 if (IS_FIND_LONGEST(reg->options)) {
4274 if (msa.best_len >= 0) {
4275 s = msa.best_s;
4276 goto match;
4277 }
4278 }
4279 #endif
4280 r = ONIG_MISMATCH;
4281
4282 finish:
4283 MATCH_ARG_FREE(msa);
4284 ONIG_STATE_DEC_THREAD(reg);
4285
4286 /* If result is mismatch and no FIND_NOT_EMPTY option,
4287 then the region is not set in match_at(). */
4288 if (IS_FIND_NOT_EMPTY(reg->options) && region
4289 #ifdef USE_POSIX_API_REGION_OPTION
4290 && !IS_POSIX_REGION(option)
4291 #endif
4292 ) {
4293 onig_region_clear(region);
4294 }
4295
4296 #ifdef ONIG_DEBUG
4297 if (r != ONIG_MISMATCH)
4298 fprintf(stderr, "onig_search: error %d\n", r);
4299 #endif
4300 return r;
4301
4302 mismatch_no_msa:
4303 r = ONIG_MISMATCH;
4304 finish_no_msa:
4305 ONIG_STATE_DEC_THREAD(reg);
4306 #ifdef ONIG_DEBUG
4307 if (r != ONIG_MISMATCH)
4308 fprintf(stderr, "onig_search: error %d\n", r);
4309 #endif
4310 return r;
4311
4312 match:
4313 ONIG_STATE_DEC_THREAD(reg);
4314 MATCH_ARG_FREE(msa);
4315 return s - str;
4316 }
4317
4318 extern OnigEncoding
4319 onig_get_encoding(regex_t* reg)
4320 {
4321 return reg->enc;
4322 }
4323
4324 extern OnigOptionType
4325 onig_get_options(regex_t* reg)
4326 {
4327 return reg->options;
4328 }
4329
4330 extern OnigCaseFoldType
4331 onig_get_case_fold_flag(regex_t* reg)
4332 {
4333 return reg->case_fold_flag;
4334 }
4335
4336 extern const OnigSyntaxType*
4337 onig_get_syntax(regex_t* reg)
4338 {
4339 return reg->syntax;
4340 }
4341
4342 extern int
4343 onig_number_of_captures(regex_t* reg)
4344 {
4345 return reg->num_mem;
4346 }
4347
4348 extern int
4349 onig_number_of_capture_histories(regex_t* reg)
4350 {
4351 #ifdef USE_CAPTURE_HISTORY
4352 int i, n;
4353
4354 n = 0;
4355 for (i = 0; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {
4356 if (BIT_STATUS_AT(reg->capture_history, i) != 0)
4357 n++;
4358 }
4359 return n;
4360 #else
4361 return 0;
4362 #endif
4363 }
4364
4365 extern void
4366 onig_copy_encoding(OnigEncoding to, OnigEncoding from)
4367 {
4368 *to = *from;
4369 }
4370
OP_ASCII_WORD_BEGIN
Definition: regint.h:566
STACK_PUSH_POS_NOT
#define STACK_PUSH_POS_NOT(pat, s, sprev, keep)
Definition: regexec.c:649
onig_region_resize
int onig_region_resize(OnigRegion *region, int n)
Definition: regexec.c:222
ANCHOR_ANYCHAR_STAR_ML
#define ANCHOR_ANYCHAR_STAR_ML
Definition: regint.h:515
IS_POSIX_REGION
#define IS_POSIX_REGION(option)
Definition: regint.h:369
BIT_STATUS_AT
#define BIT_STATUS_AT(stats, n)
Definition: regint.h:335
OP_NULL_CHECK_START
Definition: regint.h:606
mem_is_in_memp
static int mem_is_in_memp(int mem, int num, UChar *memp)
Definition: regexec.c:1166
OnigCaptureTreeNodeStruct
Definition: oniguruma.h:602
OP_WORD_END
Definition: regint.h:560
OnigCodePoint
unsigned int OnigCodePoint
Definition: oniguruma.h:112
re_pattern_buffer::num_repeat
int num_repeat
Definition: oniguruma.h:666
OP_CCLASS_MB
Definition: regint.h:541
IS_NULL
#define IS_NULL(p)
Definition: regint.h:276
onig_get_match_stack_limit_size
unsigned int onig_get_match_stack_limit_size(void)
Definition: regexec.c:493
STACK_RETURN
#define STACK_RETURN(addr)
Definition: regexec.c:1032
slow_search_backward
static UChar * slow_search_backward(OnigEncoding enc, UChar *target, UChar *target_end, const UChar *text, const UChar *adjust_text, const UChar *text_end, const UChar *text_start)
Definition: regexec.c:3050
str_lower_case_match
static int str_lower_case_match(OnigEncoding enc, int case_fold_flag, const UChar *t, const UChar *tend, const UChar *p, const UChar *end)
Definition: regexec.c:3005
STACK_GET_MEM_START
#define STACK_GET_MEM_START(mnum, k)
Definition: regexec.c:700
re_pattern_buffer::int_map_backward
int * int_map_backward
Definition: oniguruma.h:694
_OnigStackType
Definition: regint.h:783
DATA_ENSURE_CHECK
#define DATA_ENSURE_CHECK(n)
Definition: regexec.c:1115
IS_NOTEOL
#define IS_NOTEOL(option)
Definition: regint.h:368
tail
#define tail
Definition: st.c:108
STACK_PUSH_STOP_BT
#define STACK_PUSH_STOP_BT
Definition: regexec.c:650
OP_EXACTMB2N
Definition: regint.h:533
strlen
size_t strlen(const char *)
STACK_PUSH_MEM_END_MARK
#define STACK_PUSH_MEM_END_MARK(mnum)
Definition: regexec.c:693
forward_search_range
static int forward_search_range(regex_t *reg, const UChar *str, const UChar *end, UChar *s, UChar *range, UChar **low, UChar **high, UChar **low_prev)
Definition: regexec.c:3664
onig_print_compiled_byte_code
void onig_print_compiled_byte_code(FILE *f, UChar *bp, UChar *bpend, UChar **nextp, OnigEncoding enc)
OP_PUSH_STOP_BT
Definition: regint.h:615
ONIG_OPTIMIZE_EXACT
#define ONIG_OPTIMIZE_EXACT
Definition: regint.h:321
OnigStackIndex
intptr_t OnigStackIndex
Definition: regint.h:781
ANCHOR_END_BUF
#define ANCHOR_END_BUF
Definition: regint.h:501
OnigCaptureTreeNodeStruct::end
OnigPosition end
Definition: oniguruma.h:605
OnigRepeatRange::upper
int upper
Definition: oniguruma.h:640
ONIGERR_STACK_BUG
#define ONIGERR_STACK_BUG
Definition: oniguruma.h:531
OP_MEMORY_END
Definition: regint.h:589
ONIGENC_IS_MBC_NEWLINE
#define ONIGENC_IS_MBC_NEWLINE(enc, p, end)
Definition: oniguruma.h:265
STACK_POP_ONE
#define STACK_POP_ONE
Definition: regexec.c:773
SIZE_MEMNUM
#define SIZE_MEMNUM
Definition: regint.h:649
STACK_POP_TIL_POS_NOT
#define STACK_POP_TIL_POS_NOT
Definition: regexec.c:822
OP_EXACTMB2N3
Definition: regint.h:532
onig_region_resize_clear
static int onig_region_resize_clear(OnigRegion *region, int n)
Definition: regexec.c:268
_OnigStackType::mem
struct _OnigStackType::@135::@139 mem
OP_CONDITION
Definition: regint.h:624
onigenc_get_right_adjust_char_head
UChar * onigenc_get_right_adjust_char_head(OnigEncoding enc, const UChar *start, const UChar *s, const UChar *end)
Definition: regenc.c:66
STK_MEM_START
#define STK_MEM_START
Definition: regexec.c:366
OnigCaseFoldType
unsigned int OnigCaseFoldType
Definition: oniguruma.h:119
ONIGENC_MBC_CASE_FOLD
#define ONIGENC_MBC_CASE_FOLD(enc, flag, pp, end, buf)
Definition: oniguruma.h:232
STACK_PUSH_ENSURED
#define STACK_PUSH_ENSURED(stack_type, pat)
Definition: regexec.c:640
re_pattern_buffer::bt_mem_end
unsigned int bt_mem_end
Definition: oniguruma.h:672
NULL_UCHARP
#define NULL_UCHARP
Definition: regint.h:280
ANCHOR_BEGIN_LINE
#define ANCHOR_BEGIN_LINE
Definition: regint.h:499
OP_END_BUF
Definition: regint.h:570
re_registers::end
OnigPosition * end
Definition: oniguruma.h:616
OP_REPEAT_NG
Definition: regint.h:601
OP_EXACTMB2N1
Definition: regint.h:530
onig_set_match_stack_limit_size
int onig_set_match_stack_limit_size(unsigned int size)
Definition: regexec.c:499
onig_region_copy
void onig_region_copy(OnigRegion *to, OnigRegion *from)
Definition: regexec.c:331
onig_is_in_code_range
int onig_is_in_code_range(const UChar *p, OnigCodePoint code)
Definition: regcomp.c:6028
GET_STATE_CHECK_NUM_INC
#define GET_STATE_CHECK_NUM_INC(num, p)
Definition: regint.h:664
ONIG_REGION_NOTPOS
#define ONIG_REGION_NOTPOS
Definition: oniguruma.h:628
backref_match_at_nested_level
static int backref_match_at_nested_level(regex_t *reg, OnigStackType *top, OnigStackType *stk_base, int ignore_case, int case_fold_flag, int nest, int mem_num, UChar *memp, UChar **s, const UChar *send)
Definition: regexec.c:1178
OP_EXACT1_IC
Definition: regint.h:537
OP_SEMI_END_BUF
Definition: regint.h:573
MATCH_ARG_INIT
#define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos)
Definition: regexec.c:387
OP_STATE_CHECK_PUSH
Definition: regint.h:626
onig_get_options
OnigOptionType onig_get_options(regex_t *reg)
Definition: regexec.c:4325
_OnigStackType::state
struct _OnigStackType::@135::@136 state
OP_EXACT4
Definition: regint.h:527
match_at
static OnigPosition match_at(regex_t *reg, const UChar *str, const UChar *end, const UChar *sstart, UChar *sprev, OnigMatchArg *msa)
Definition: regexec.c:1330
ON_STR_BEGIN
#define ON_STR_BEGIN(s)
Definition: regexec.c:1107
OP_REPEAT_INC_NG_SG
Definition: regint.h:605
re_pattern_buffer::anchor_dmax
OnigDistance anchor_dmax
Definition: oniguruma.h:688
ANCHOR_END_LINE
#define ANCHOR_END_LINE
Definition: regint.h:503
STACK_ENSURE
#define STACK_ENSURE(n)
Definition: regexec.c:547
OP_BACKREFN_IC
Definition: regint.h:580
USE_POSIX_API_REGION_OPTION
#define USE_POSIX_API_REGION_OPTION
Definition: regint.h:111
OP_WORD
Definition: regint.h:555
_OnigStackType::type
unsigned int type
Definition: regint.h:784
OP_CCLASS_MIX_NOT
Definition: regint.h:545
STACK_PUSH_MEM_END
#define STACK_PUSH_MEM_END(mnum, s)
Definition: regexec.c:682
OnigMatchArg::gpos
const UChar * gpos
Definition: regint.h:830
OnigMatchArg::best_s
UChar * best_s
Definition: regint.h:833
set_bm_backward_skip
static int set_bm_backward_skip(UChar *s, UChar *end, OnigEncoding enc ARG_UNUSED, int **skip)
Definition: regexec.c:3520
onig_region_clear
void onig_region_clear(OnigRegion *region)
Definition: regexec.c:209
OP_MEMORY_END_PUSH_REC
Definition: regint.h:588
re_pattern_buffer::map
unsigned char map[ONIG_CHAR_TABLE_SIZE]
Definition: oniguruma.h:692
OnigEncodingTypeST::min_enc_len
int min_enc_len
Definition: oniguruma.h:162
STACK_NULL_CHECK_MEMST
#define STACK_NULL_CHECK_MEMST(isnull, id, s, reg)
Definition: regexec.c:927
STACK_PUSH_NULL_CHECK_END
#define STACK_PUSH_NULL_CHECK_END(cnum)
Definition: regexec.c:742
OnigMatchArg::best_len
OnigPosition best_len
Definition: regint.h:832
OnigSyntaxType
Definition: oniguruma.h:380
STK_CALL_FRAME
#define STK_CALL_FRAME
Definition: regexec.c:377
OP_WORD_BOUND
Definition: regint.h:557
STK_RETURN
#define STK_RETURN
Definition: regexec.c:378
ONIG_OPTIMIZE_EXACT_IC
#define ONIG_OPTIMIZE_EXACT_IC
Definition: regint.h:324
MATCH_AND_RETURN_CHECK
#define MATCH_AND_RETURN_CHECK(none)
OP_POP
Definition: regint.h:597
OP_STATE_CHECK_ANYCHAR_STAR
Definition: regint.h:629
OP_EXACTN
Definition: regint.h:529
onigenc_get_right_adjust_char_head_with_prev
UChar * onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc, const UChar *start, const UChar *s, const UChar *end, const UChar **prev)
Definition: regenc.c:76
re_pattern_buffer
Definition: oniguruma.h:658
OP_BACKREF_MULTI
Definition: regint.h:581
OP_REPEAT
Definition: regint.h:600
GET_OPTION_INC
#define GET_OPTION_INC(option, p)
Definition: regint.h:662
MOP_OUT
#define MOP_OUT
Definition: regexec.c:1311
re_pattern_buffer::p
unsigned char * p
Definition: oniguruma.h:660
OP_NULL_CHECK_END_MEMST_PUSH
Definition: regint.h:609
ANCHOR_BEGIN_POSITION
#define ANCHOR_BEGIN_POSITION
Definition: regint.h:500
GET_LENGTH_INC
#define GET_LENGTH_INC(len, p)
Definition: regint.h:659
OP_KEEP
Definition: regint.h:592
OnigOptionType
unsigned int OnigOptionType
Definition: oniguruma.h:347
re_pattern_buffer::anchor_dmin
OnigDistance anchor_dmin
Definition: oniguruma.h:687
_OnigStackType::u
union _OnigStackType::@135 u
re_registers::history_root
OnigCaptureTreeNode * history_root
Definition: oniguruma.h:618
onig_number_of_captures
int onig_number_of_captures(regex_t *reg)
Definition: regexec.c:4343
re_pattern_buffer::bt_mem_start
unsigned int bt_mem_start
Definition: oniguruma.h:671
STACK_PUSH_LOOK_BEHIND_NOT
#define STACK_PUSH_LOOK_BEHIND_NOT(pat, s, sprev, keep)
Definition: regexec.c:651
INIT_MATCH_STACK_SIZE
#define INIT_MATCH_STACK_SIZE
Definition: regint.h:79
re_pattern_buffer::exact
unsigned char * exact
Definition: oniguruma.h:690
SIZE_OP_FAIL
#define SIZE_OP_FAIL
Definition: regint.h:690
STACK_STOP_BT_END
#define STACK_STOP_BT_END
Definition: regexec.c:877
map_search
static UChar * map_search(OnigEncoding enc, UChar map[], const UChar *text, const UChar *text_range, const UChar *text_end)
Definition: regexec.c:3570
STACK_GET_REPEAT
#define STACK_GET_REPEAT(id, k)
Definition: regexec.c:1014
MATCH_ARG_FREE
#define MATCH_ARG_FREE(msa)
Definition: regexec.c:442
OP_ANYCHAR_STAR_PEEK_NEXT
Definition: regint.h:552
OP_PUSH
Definition: regint.h:596
OP_NOT_WORD_BOUND
Definition: regint.h:558
__sFILE
Definition: vsnprintf.c:175
re_registers
Definition: oniguruma.h:612
onigenc_get_prev_char_head
UChar * onigenc_get_prev_char_head(OnigEncoding enc, const UChar *start, const UChar *s, const UChar *end)
Definition: regenc.c:92
ONIGENC_STEP_BACK
#define ONIGENC_STEP_BACK(enc, start, s, end, n)
Definition: oniguruma.h:242
re_pattern_buffer::sub_anchor
int sub_anchor
Definition: oniguruma.h:689
MatchStackLimitSize
static unsigned int MatchStackLimitSize
Definition: regexec.c:490
onig_chain_reduce
void onig_chain_reduce(regex_t *reg)
Definition: regcomp.c:5650
ONIGENC_IS_MBC_CRNL
#define ONIGENC_IS_MBC_CRNL(enc, p, end)
Definition: regexec.c:36
OP_MEMORY_START_PUSH
Definition: regint.h:586
re_pattern_buffer::repeat_range
OnigRepeatRange * repeat_range
Definition: oniguruma.h:675
fail
#define fail()
Definition: date_strptime.c:118
GET_MEMNUM_INC
#define GET_MEMNUM_INC(num, p)
Definition: regint.h:660
OP_NOT_ASCII_WORD_BOUND
Definition: regint.h:565
RelAddrType
int RelAddrType
Definition: regint.h:637
ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC
#define ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC
Definition: regint.h:327
THREAD_ATOMIC_END
#define THREAD_ATOMIC_END
Definition: regint.h:119
onig_region_set
int onig_region_set(OnigRegion *region, int at, int beg, int end)
Definition: regexec.c:279
OP_EXACTN_IC
Definition: regint.h:538
STACK_SAVE
#define STACK_SAVE
Definition: regexec.c:483
onig_region_init
void onig_region_init(OnigRegion *region)
Definition: regexec.c:294
CHECK_INTERRUPT_IN_MATCH_AT
#define CHECK_INTERRUPT_IN_MATCH_AT
Definition: regint.h:130
re_pattern_buffer::case_fold_flag
OnigCaseFoldType case_fold_flag
Definition: oniguruma.h:680
bm_search_notrev
static UChar * bm_search_notrev(regex_t *reg, const UChar *target, const UChar *target_end, const UChar *text, const UChar *text_end, const UChar *text_range)
Definition: regexec.c:3314
OnigCaptureTreeNodeStruct::beg
OnigPosition beg
Definition: oniguruma.h:604
ONIG_CHAR_TABLE_SIZE
#define ONIG_CHAR_TABLE_SIZE
Definition: oniguruma.h:647
OP_BACKREF_WITH_LEVEL
Definition: regint.h:583
level
#define level
OP_STATE_CHECK_PUSH_OR_JUMP
Definition: regint.h:627
IS_FIND_LONGEST
#define IS_FIND_LONGEST(option)
Definition: regint.h:363
OP_CCLASS_MIX
Definition: regint.h:542
re_pattern_buffer::num_comb_exp_check
int num_comb_exp_check
Definition: oniguruma.h:668
OnigCaptureTreeNodeStruct::num_childs
int num_childs
Definition: oniguruma.h:607
ONIG_STATE_NORMAL
#define ONIG_STATE_NORMAL
Definition: oniguruma.h:650
DATA_ENSURE_CHECK1
#define DATA_ENSURE_CHECK1
Definition: regexec.c:1114
ARG_UNUSED
#define ARG_UNUSED
Definition: nkf.h:181
onig_get_encoding
OnigEncoding onig_get_encoding(regex_t *reg)
Definition: regexec.c:4319
re_pattern_buffer::threshold_len
int threshold_len
Definition: oniguruma.h:685
OP_BEGIN_BUF
Definition: regint.h:569
MOP_IN
#define MOP_IN(opcode)
Definition: regexec.c:1310
OP_FAIL
Definition: regint.h:594
ALIGNMENT_RIGHT
#define ALIGNMENT_RIGHT(addr)
Definition: regint.h:307
ONIGERR_UNEXPECTED_BYTECODE
#define ONIGERR_UNEXPECTED_BYTECODE
Definition: oniguruma.h:533
OP_MEMORY_START
Definition: regint.h:585
BITSET_AT
#define BITSET_AT(bs, pos)
Definition: regint.h:412
xmemcpy
#define xmemcpy
Definition: regint.h:182
unistd.h
OP_BACKREF1
Definition: regint.h:577
ONIGENC_IS_MBC_HEAD
#define ONIGENC_IS_MBC_HEAD(enc, p, e)
Definition: oniguruma.h:219
CHECK_NULL_RETURN_MEMERR
#define CHECK_NULL_RETURN_MEMERR(p)
Definition: regint.h:279
onig_region_free
void onig_region_free(OnigRegion *r, int free_self)
Definition: regexec.c:315
ONIG_OPTIMIZE_MAP
#define ONIG_OPTIMIZE_MAP
Definition: regint.h:325
OP_EXACT5
Definition: regint.h:528
OP_BEGIN_LINE
Definition: regint.h:571
STK_ALT
#define STK_ALT
Definition: regexec.c:362
GET_STACK_INDEX
#define GET_STACK_INDEX(stk)
Definition: regexec.c:559
range
#define range(low, item, hi)
Definition: date_strftime.c:21
bm_search_ic
static UChar * bm_search_ic(regex_t *reg, const UChar *target, const UChar *target_end, const UChar *text, const UChar *text_end, const UChar *text_range)
Definition: regexec.c:3474
re_pattern_buffer::stack_pop_level
int stack_pop_level
Definition: oniguruma.h:673
OP_ASCII_WORD_BOUND
Definition: regint.h:564
OnigMatchArg::stack_p
void * stack_p
Definition: regint.h:825
re_pattern_buffer::chain
struct re_pattern_buffer * chain
Definition: oniguruma.h:699
regoff_t
int regoff_t
Definition: regexec.c:1317
DEFAULT_MATCH_STACK_LIMIT_SIZE
#define DEFAULT_MATCH_STACK_LIMIT_SIZE
Definition: regint.h:80
stack_double
static int stack_double(OnigStackType **arg_stk_base, OnigStackType **arg_stk_end, OnigStackType **arg_stk, OnigStackType *stk_alloc, OnigMatchArg *msa)
Definition: regexec.c:506
slow_search_ic
static UChar * slow_search_ic(OnigEncoding enc, int case_fold_flag, UChar *target, UChar *target_end, const UChar *text, const UChar *text_end, UChar *text_range)
Definition: regexec.c:3025
IS_EMPTY_STR
#define IS_EMPTY_STR
Definition: regexec.c:1106
THREAD_PASS
#define THREAD_PASS
Definition: regint.h:120
ONIG_OPTIMIZE_EXACT_BM_IC
#define ONIG_OPTIMIZE_EXACT_BM_IC
Definition: regint.h:326
STACK_PUSH_CALL_FRAME
#define STACK_PUSH_CALL_FRAME(pat)
Definition: regexec.c:749
OP_ANYCHAR_ML_STAR
Definition: regint.h:551
OP_POP_STOP_BT
Definition: regint.h:616
OnigMatchArg::region
OnigRegion * region
Definition: regint.h:828
SIZE_BITSET
#define SIZE_BITSET
Definition: regint.h:402
onig_search_gpos
OnigPosition onig_search_gpos(regex_t *reg, const UChar *str, const UChar *end, const UChar *global_pos, const UChar *start, const UChar *range, OnigRegion *region, OnigOptionType option)
Definition: regexec.c:3909
timeval
Definition: ossl_asn1.c:16
THREAD_ATOMIC_START
#define THREAD_ATOMIC_START
Definition: regint.h:118
ONIGENC_IS_MBC_WORD
#define ONIGENC_IS_MBC_WORD(enc, s, end)
Definition: oniguruma.h:222
OnigMatchArg::options
OnigOptionType options
Definition: regint.h:827
OP_PUSH_POS
Definition: regint.h:611
BitSetRef
Bits * BitSetRef
Definition: regint.h:400
ONIGENC_MBC_CASE_FOLD_MAXLEN
#define ONIGENC_MBC_CASE_FOLD_MAXLEN
Definition: oniguruma.h:190
re_pattern_buffer::num_mem
int num_mem
Definition: oniguruma.h:665
OP_CCLASS_MB_NOT
Definition: regint.h:544
OP_PUSH_LOOK_BEHIND_NOT
Definition: regint.h:618
STRING_CMP_IC
#define STRING_CMP_IC(case_fold_flag, s1, ps2, len, text_end)
Definition: regexec.c:1057
STRING_CMP
#define STRING_CMP(s1, s2, len)
Definition: regexec.c:1051
OP_WORD_BEGIN
Definition: regint.h:559
OP_EXACTMBN
Definition: regint.h:535
OP_MEMORY_END_REC
Definition: regint.h:590
LengthType
int LengthType
Definition: regint.h:639
_OnigStackType::repeat
struct _OnigStackType::@135::@137 repeat
STACK_PUSH_RETURN
#define STACK_PUSH_RETURN
Definition: regexec.c:756
ONIGENC_IS_MBC_NEWLINE_EX
#define ONIGENC_IS_MBC_NEWLINE_EX(enc, p, start, end, option, check_prev)
Definition: regexec.c:39
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
OP_NOT_WORD
Definition: regint.h:556
THREAD_PASS_LIMIT_COUNT
#define THREAD_PASS_LIMIT_COUNT
Definition: regint.h:180
OP_EXACT2
Definition: regint.h:525
OP_NULL_CHECK_END_MEMST
Definition: regint.h:608
DATA_ENSURE
#define DATA_ENSURE(n)
Definition: regexec.c:1116
ONIG_STATE_INC
#define ONIG_STATE_INC(reg)
Definition: regint.h:209
STRING_CMP_VALUE
#define STRING_CMP_VALUE(s1, s2, len, is_fail)
Definition: regexec.c:1089
OP_CCLASS_NOT
Definition: regint.h:543
STACK_NULL_CHECK
#define STACK_NULL_CHECK(isnull, id, s)
Definition: regexec.c:892
intptr_t
int intptr_t
Definition: win32.h:87
OP_EXACT1
Definition: regint.h:524
ONIGENC_IS_MBC_ASCII_WORD
#define ONIGENC_IS_MBC_ASCII_WORD(enc, s, end)
Definition: oniguruma.h:224
OnigRepeatRange::lower
int lower
Definition: oniguruma.h:639
ANCHOR_SEMI_END_BUF
#define ANCHOR_SEMI_END_BUF
Definition: regint.h:502
ONIG_OPTIMIZE_NONE
#define ONIG_OPTIMIZE_NONE
Definition: regint.h:320
posix_regmatch_t::rm_so
regoff_t rm_so
Definition: regexec.c:1320
OP_BACKREF_MULTI_IC
Definition: regint.h:582
OP_ANYCHAR_STAR
Definition: regint.h:550
STACK_POP
#define STACK_POP
Definition: regexec.c:778
re_registers::beg
OnigPosition * beg
Definition: oniguruma.h:615
memcmp
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
STACK_PUSH_POS
#define STACK_PUSH_POS(s, sprev, keep)
Definition: regexec.c:648
OP_END
Definition: regint.h:522
ONIG_INFINITE_DISTANCE
#define ONIG_INFINITE_DISTANCE
Definition: oniguruma.h:117
bm_search_backward
static UChar * bm_search_backward(regex_t *reg, const UChar *target, const UChar *target_end, const UChar *text, const UChar *adjust_text, const UChar *text_end, const UChar *text_start)
Definition: regexec.c:3541
OP_FAIL_POS
Definition: regint.h:614
ONIGENC_MBC_TO_CODE
#define ONIGENC_MBC_TO_CODE(enc, p, end)
Definition: oniguruma.h:266
OP_NULL_CHECK_END
Definition: regint.h:607
MIN
#define MIN(a, b)
Definition: regint.h:273
UChar
#define UChar
Definition: oniguruma.h:108
OP_JUMP
Definition: regint.h:595
posix_regmatch_t
Definition: regexec.c:1319
ANCHOR_ANYCHAR_STAR
#define ANCHOR_ANYCHAR_STAR
Definition: regint.h:514
SIZE_RELADDR
#define SIZE_RELADDR
Definition: regint.h:646
OP_FAIL_LOOK_BEHIND_NOT
Definition: regint.h:619
tms
Definition: win32.h:747
OnigCaptureTreeNodeStruct::childs
struct OnigCaptureTreeNodeStruct ** childs
Definition: oniguruma.h:608
OP_ASCII_WORD_END
Definition: regint.h:567
OP_FINISH
Definition: regint.h:521
top
unsigned int top
Definition: nkf.c:4309
ONIG_NREGION
#define ONIG_NREGION
Definition: oniguruma.h:339
CHECK_NULL_RETURN
#define CHECK_NULL_RETURN(p)
Definition: regint.h:278
OP_END_LINE
Definition: regint.h:572
re_pattern_buffer::exact_end
unsigned char * exact_end
Definition: oniguruma.h:691
re_pattern_buffer::dmax
OnigDistance dmax
Definition: oniguruma.h:696
OP_EXACTMB3N
Definition: regint.h:534
backward_search_range
static int backward_search_range(regex_t *reg, const UChar *str, const UChar *end, UChar *s, const UChar *range, UChar *adjrange, UChar **low, UChar **high)
Definition: regexec.c:3799
size
int size
Definition: encoding.c:49
ONIGENC_LEFT_ADJUST_CHAR_HEAD
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end)
Definition: oniguruma.h:236
f
#define f
map_search_backward
static UChar * map_search_backward(OnigEncoding enc, UChar map[], const UChar *text, const UChar *adjust_text, const UChar *text_start, const UChar *text_end)
Definition: regexec.c:3584
onig_search
OnigPosition onig_search(regex_t *reg, const UChar *str, const UChar *end, const UChar *start, const UChar *range, OnigRegion *region, OnigOptionType option)
Definition: regexec.c:3902
posix_regmatch_t::rm_eo
regoff_t rm_eo
Definition: regexec.c:1321
ON_STR_END
#define ON_STR_END(s)
Definition: regexec.c:1108
OP_ANYCHAR_ML_STAR_PEEK_NEXT
Definition: regint.h:553
STACK_PUSH_NULL_CHECK_START
#define STACK_PUSH_NULL_CHECK_START(cnum, s)
Definition: regexec.c:734
OnigPosition
ptrdiff_t OnigPosition
Definition: oniguruma.h:115
SIZE_OP_SET_OPTION
#define SIZE_OP_SET_OPTION
Definition: regint.h:688
OP_REPEAT_INC
Definition: regint.h:602
onig_match
OnigPosition onig_match(regex_t *reg, const UChar *str, const UChar *end, const UChar *at, OnigRegion *region, OnigOptionType option)
Definition: regexec.c:3599
GET_RELADDR_INC
#define GET_RELADDR_INC(addr, p)
Definition: regint.h:657
ONIG_MAX_CAPTURE_HISTORY_GROUP
#define ONIG_MAX_CAPTURE_HISTORY_GROUP
Definition: oniguruma.h:598
xmalloc
#define xmalloc
Definition: defines.h:108
ANCHOR_PREC_READ_NOT
#define ANCHOR_PREC_READ_NOT
Definition: regint.h:510
OnigDistance
size_t OnigDistance
Definition: oniguruma.h:114
STACK_PUSH_MEM_START
#define STACK_PUSH_MEM_START(mnum, s)
Definition: regexec.c:670
re_registers::num_regs
int num_regs
Definition: oniguruma.h:614
bm_search
static UChar * bm_search(regex_t *reg, const UChar *target, const UChar *target_end, const UChar *text, const UChar *text_end, const UChar *text_range)
Definition: regexec.c:3374
slow_search
static UChar * slow_search(OnigEncoding enc, UChar *target, UChar *target_end, const UChar *text, const UChar *text_end, UChar *text_range)
Definition: regexec.c:2965
IS_NEWLINE_CRLF
#define IS_NEWLINE_CRLF(option)
Definition: regint.h:373
OP_MEMORY_END_PUSH
Definition: regint.h:587
re_pattern_buffer::capture_history
unsigned int capture_history
Definition: oniguruma.h:670
OP_PUSH_POS_NOT
Definition: regint.h:613
OP_CCLASS_NODE
Definition: regint.h:546
onig_number_of_capture_histories
int onig_number_of_capture_histories(regex_t *reg)
Definition: regexec.c:4349
ONIGERR_MEMORY
#define ONIGERR_MEMORY
Definition: oniguruma.h:528
IS_FIND_CONDITION
#define IS_FIND_CONDITION(option)
Definition: regint.h:365
re_pattern_buffer::syntax
const OnigSyntaxType * syntax
Definition: oniguruma.h:679
OP_BACKREF2
Definition: regint.h:578
STACK_AT
#define STACK_AT(index)
Definition: regexec.c:558
OP_REPEAT_INC_NG
Definition: regint.h:603
ONIG_MISMATCH
#define ONIG_MISMATCH
Definition: oniguruma.h:524
OP_RETURN
Definition: regint.h:622
OP_BEGIN_POSITION
Definition: regint.h:574
STK_MEM_END
#define STK_MEM_END
Definition: regexec.c:367
onig_copy_encoding
void onig_copy_encoding(OnigEncoding to, OnigEncoding from)
Definition: regexec.c:4366
OP_CCLASS
Definition: regint.h:540
OP_STATE_CHECK_ANYCHAR_ML_STAR
Definition: regint.h:630
onig_get_case_fold_flag
OnigCaseFoldType onig_get_case_fold_flag(regex_t *reg)
Definition: regexec.c:4331
STRING_CMP_VALUE_IC
#define STRING_CMP_VALUE_IC(case_fold_flag, s1, ps2, len, text_end, is_fail)
Definition: regexec.c:1098
STACK_PUSH_ALT
#define STACK_PUSH_ALT(pat, s, sprev, keep)
Definition: regexec.c:647
re_pattern_buffer::dmin
OnigDistance dmin
Definition: oniguruma.h:695
OP_POP_POS
Definition: regint.h:612
OP_ANYCHAR_ML
Definition: regint.h:549
OP_BEGIN_POS_OR_LINE
Definition: regint.h:575
OP_CALL
Definition: regint.h:621
OP_REPEAT_INC_SG
Definition: regint.h:604
IS_NOTBOL
#define IS_NOTBOL(option)
Definition: regint.h:367
ONIGERR_INVALID_ARGUMENT
#define ONIGERR_INVALID_ARGUMENT
Definition: oniguruma.h:538
onig_is_code_in_cc_len
int onig_is_code_in_cc_len(int elen, OnigCodePoint code, CClassNode *cc)
Definition: regcomp.c:6049
name
const char * name
Definition: nkf.c:208
slow_search_backward_ic
static UChar * slow_search_backward_ic(OnigEncoding enc, int case_fold_flag, UChar *target, UChar *target_end, const UChar *text, const UChar *adjust_text, const UChar *text_end, const UChar *text_start)
Definition: regexec.c:3082
xrealloc
#define xrealloc
Definition: defines.h:111
OP_SET_OPTION
Definition: regint.h:634
OP_PUSH_IF_PEEK_NEXT
Definition: regint.h:599
ONIGERR_UNDEFINED_BYTECODE
#define ONIGERR_UNDEFINED_BYTECODE
Definition: oniguruma.h:532
OP_EXACTMB2N2
Definition: regint.h:531
ONIG_OPTIMIZE_EXACT_BM_NOT_REV
#define ONIG_OPTIMIZE_EXACT_BM_NOT_REV
Definition: regint.h:323
ANCHOR_BEGIN_BUF
#define ANCHOR_BEGIN_BUF
Definition: regint.h:498
ONIGERR_MATCH_STACK_LIMIT_OVER
#define ONIGERR_MATCH_STACK_LIMIT_OVER
Definition: oniguruma.h:534
re_pattern_buffer::enc
OnigEncoding enc
Definition: oniguruma.h:677
OP_ANYCHAR
Definition: regint.h:548
STACK_INIT
#define STACK_INIT(alloc_addr, heap_addr, ptr_num, stack_num)
Definition: regexec.c:449
IS_NOT_NULL
#define IS_NOT_NULL(p)
Definition: regint.h:277
USE_CRNL_AS_LINE_TERMINATOR
#define USE_CRNL_AS_LINE_TERMINATOR
Definition: regenc.h:109
onig_region_new
OnigRegion * onig_region_new(void)
Definition: regexec.c:304
regint.h
ANCHOR_LOOK_BEHIND
#define ANCHOR_LOOK_BEHIND
Definition: regint.h:511
OP_PUSH_OR_JUMP_EXACT1
Definition: regint.h:598
MemNumType
short int MemNumType
Definition: regint.h:641
STACK_PUSH_REPEAT_INC
#define STACK_PUSH_REPEAT_INC(sindex)
Definition: regexec.c:663
GET_POINTER_INC
#define GET_POINTER_INC(ptr, p)
Definition: regint.h:663
OnigCaptureTreeNodeStruct::group
int group
Definition: oniguruma.h:603
re_pattern_buffer::anchor
int anchor
Definition: oniguruma.h:686
bm_search_notrev_ic
static UChar * bm_search_notrev_ic(regex_t *reg, const UChar *target, const UChar *target_end, const UChar *text, const UChar *text_end, const UChar *text_range)
Definition: regexec.c:3417
xfree
void void xfree(void *)
STK_STATE_CHECK_MARK
#define STK_STATE_CHECK_MARK
Definition: regexec.c:369
ONIGENC_IS_SINGLEBYTE
#define ONIGENC_IS_SINGLEBYTE(enc)
Definition: oniguruma.h:218
BM_BACKWARD_SEARCH_LENGTH_THRESHOLD
#define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD
Definition: regexec.c:3796
re_registers::allocated
int allocated
Definition: oniguruma.h:613
re_pattern_buffer::optimize
int optimize
Definition: oniguruma.h:684
OP_ASCII_WORD
Definition: regint.h:562
ONIG_OPTIMIZE_EXACT_BM
#define ONIG_OPTIMIZE_EXACT_BM
Definition: regint.h:322
OP_STATE_CHECK
Definition: regint.h:628
re_pattern_buffer::options
OnigOptionType options
Definition: oniguruma.h:678
NULL
#define NULL
Definition: _sdbm.c:103
STACK_POP_TIL_LOOK_BEHIND_NOT
#define STACK_POP_TIL_LOOK_BEHIND_NOT
Definition: regexec.c:842
onig_get_syntax
const OnigSyntaxType * onig_get_syntax(regex_t *reg)
Definition: regexec.c:4337
INVALID_STACK_INDEX
#define INVALID_STACK_INDEX
stack
Definition: regexec.c:358
P_
static int set_bm_backward_skip P_((UChar *s, UChar *end, OnigEncoding enc, int **skip))
STACK_NULL_CHECK_REC
#define STACK_NULL_CHECK_REC(isnull, id, s)
Definition: regexec.c:906
OP_BACKREFN
Definition: regint.h:579
IS_FIND_NOT_EMPTY
#define IS_FIND_NOT_EMPTY(option)
Definition: regint.h:364
match
static int match(VALUE str, VALUE pat, VALUE hash, int(*cb)(VALUE, VALUE))
Definition: date_parse.c:273
is_mbc_newline_ex
static int is_mbc_newline_ex(OnigEncoding enc, const UChar *p, const UChar *start, const UChar *end, OnigOptionType option, int check_prev)
Definition: regexec.c:42
string_cmp_ic
static int string_cmp_ic(OnigEncoding enc, int case_fold_flag, UChar *s1, UChar **ps2, OnigDistance mblen, const UChar *text_end)
Definition: regexec.c:1062
GET_ABSADDR_INC
#define GET_ABSADDR_INC(addr, p)
Definition: regint.h:658
bp
#define bp()
Definition: vm_debug.h:25
re_pattern_buffer::int_map
int * int_map
Definition: oniguruma.h:693
STACK_POS_END
#define STACK_POS_END(k)
Definition: regexec.c:862
OP_SET_OPTION_PUSH
Definition: regint.h:633
OP_NOT_ASCII_WORD
Definition: regint.h:563
OP_LOOK_BEHIND
Definition: regint.h:617
OnigMatchArg
Definition: regint.h:824
ONIG_STATE
#define ONIG_STATE(reg)
Definition: oniguruma.h:655
enclen
#define enclen(enc, p, e)
Definition: regenc.h:76
STACK_PUSH_REPEAT
#define STACK_PUSH_REPEAT(id, pat)
Definition: regexec.c:654
ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT
#define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT
Definition: oniguruma.h:594
OnigEncodingTypeST::max_enc_len
int max_enc_len
Definition: oniguruma.h:161
OP_EXACT3
Definition: regint.h:526
ONIG_STATE_DEC_THREAD
#define ONIG_STATE_DEC_THREAD(reg)
Definition: regint.h:212
OnigEncodingTypeST
Definition: oniguruma.h:158
STACK_NULL_CHECK_MEMST_REC
#define STACK_NULL_CHECK_MEMST_REC(isnull, id, s, reg)
Definition: regexec.c:966
OnigCaptureTreeNodeStruct::allocated
int allocated
Definition: oniguruma.h:606