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