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