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