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