]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/RegularExpressionDxe/Oniguruma/regexec.c
MdeModulePkg RegularExpressionDxe: Update Oniguruma from v6.9.0 to v6.9.3
[mirror_edk2.git] / MdeModulePkg / Universal / RegularExpressionDxe / Oniguruma / regexec.c
CommitLineData
14b0e578
CS
1/**********************************************************************\r
2 regexec.c - Oniguruma (regular expression library)\r
3**********************************************************************/\r
4/*-\r
b26691c4 5 * Copyright (c) 2002-2019 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>\r
14b0e578
CS
6 * All rights reserved.\r
7 *\r
14b0e578
CS
8 * Redistribution and use in source and binary forms, with or without\r
9 * modification, are permitted provided that the following conditions\r
10 * are met:\r
11 * 1. Redistributions of source code must retain the above copyright\r
12 * notice, this list of conditions and the following disclaimer.\r
13 * 2. Redistributions in binary form must reproduce the above copyright\r
14 * notice, this list of conditions and the following disclaimer in the\r
15 * documentation and/or other materials provided with the distribution.\r
16 *\r
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\r
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
27 * SUCH DAMAGE.\r
28 */\r
14b0e578
CS
29#include "regint.h"\r
30\r
b602265d
DG
31#define IS_MBC_WORD_ASCII_MODE(enc,s,end,mode) \\r
32 ((mode) == 0 ? ONIGENC_IS_MBC_WORD(enc,s,end) : ONIGENC_IS_MBC_WORD_ASCII(enc,s,end))\r
14b0e578
CS
33\r
34#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
35#define ONIGENC_IS_MBC_CRNL(enc,p,end) \\r
36 (ONIGENC_MBC_TO_CODE(enc,p,end) == 13 && \\r
37 ONIGENC_IS_MBC_NEWLINE(enc,(p+enclen(enc,p)),end))\r
38#endif\r
39\r
b602265d
DG
40#define CHECK_INTERRUPT_IN_MATCH\r
41\r
42#ifdef USE_CALLOUT\r
43typedef struct {\r
44 int last_match_at_call_counter;\r
45 struct {\r
46 OnigType type;\r
47 OnigValue val;\r
48 } slot[ONIG_CALLOUT_DATA_SLOT_NUM];\r
49} CalloutData;\r
50#endif\r
51\r
52struct OnigMatchParamStruct {\r
53 unsigned int match_stack_limit;\r
54 unsigned long retry_limit_in_match;\r
55#ifdef USE_CALLOUT\r
56 OnigCalloutFunc progress_callout_of_contents;\r
57 OnigCalloutFunc retraction_callout_of_contents;\r
58 int match_at_call_counter;\r
59 void* callout_user_data;\r
60 CalloutData* callout_data;\r
61 int callout_data_alloc_num;\r
62#endif\r
63};\r
64\r
65extern int\r
66onig_set_match_stack_limit_size_of_match_param(OnigMatchParam* param,\r
67 unsigned int limit)\r
68{\r
69 param->match_stack_limit = limit;\r
70 return ONIG_NORMAL;\r
71}\r
72\r
73extern int\r
74onig_set_retry_limit_in_match_of_match_param(OnigMatchParam* param,\r
75 unsigned long limit)\r
76{\r
77 param->retry_limit_in_match = limit;\r
78 return ONIG_NORMAL;\r
79}\r
80\r
81extern int\r
82onig_set_progress_callout_of_match_param(OnigMatchParam* param, OnigCalloutFunc f)\r
83{\r
84#ifdef USE_CALLOUT\r
85 param->progress_callout_of_contents = f;\r
86 return ONIG_NORMAL;\r
87#else\r
88 return ONIG_NO_SUPPORT_CONFIG;\r
89#endif\r
90}\r
91\r
92extern int\r
93onig_set_retraction_callout_of_match_param(OnigMatchParam* param, OnigCalloutFunc f)\r
94{\r
95#ifdef USE_CALLOUT\r
96 param->retraction_callout_of_contents = f;\r
97 return ONIG_NORMAL;\r
98#else\r
99 return ONIG_NO_SUPPORT_CONFIG;\r
100#endif\r
101}\r
102\r
103extern int\r
104onig_set_callout_user_data_of_match_param(OnigMatchParam* param, void* user_data)\r
105{\r
106#ifdef USE_CALLOUT\r
107 param->callout_user_data = user_data;\r
108 return ONIG_NORMAL;\r
109#else\r
110 return ONIG_NO_SUPPORT_CONFIG;\r
111#endif\r
112}\r
113\r
114\r
b602265d
DG
115typedef struct {\r
116 void* stack_p;\r
117 int stack_n;\r
118 OnigOptionType options;\r
119 OnigRegion* region;\r
120 int ptr_num;\r
121 const UChar* start; /* search start position (for \G: BEGIN_POSITION) */\r
122 unsigned int match_stack_limit;\r
123 unsigned long retry_limit_in_match;\r
124 OnigMatchParam* mp;\r
125#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
126 int best_len; /* for ONIG_OPTION_FIND_LONGEST */\r
127 UChar* best_s;\r
128#endif\r
129} MatchArg;\r
130\r
131\r
132#ifdef ONIG_DEBUG\r
133\r
134/* arguments type */\r
135typedef enum {\r
b26691c4
LG
136 ARG_SPECIAL = -1,\r
137 ARG_NON = 0,\r
138 ARG_RELADDR = 1,\r
139 ARG_ABSADDR = 2,\r
140 ARG_LENGTH = 3,\r
141 ARG_MEMNUM = 4,\r
142 ARG_OPTION = 5,\r
143 ARG_MODE = 6\r
b602265d
DG
144} OpArgType;\r
145\r
146typedef struct {\r
147 short int opcode;\r
148 char* name;\r
b602265d
DG
149} OpInfoType;\r
150\r
151static OpInfoType OpInfo[] = {\r
b26691c4
LG
152 { OP_FINISH, "finish" },\r
153 { OP_END, "end" },\r
154 { OP_EXACT1, "exact1" },\r
155 { OP_EXACT2, "exact2" },\r
156 { OP_EXACT3, "exact3" },\r
157 { OP_EXACT4, "exact4" },\r
158 { OP_EXACT5, "exact5" },\r
159 { OP_EXACTN, "exactn" },\r
160 { OP_EXACTMB2N1, "exactmb2-n1" },\r
161 { OP_EXACTMB2N2, "exactmb2-n2" },\r
162 { OP_EXACTMB2N3, "exactmb2-n3" },\r
163 { OP_EXACTMB2N, "exactmb2-n" },\r
164 { OP_EXACTMB3N, "exactmb3n" },\r
165 { OP_EXACTMBN, "exactmbn" },\r
166 { OP_EXACT1_IC, "exact1-ic" },\r
167 { OP_EXACTN_IC, "exactn-ic" },\r
168 { OP_CCLASS, "cclass" },\r
169 { OP_CCLASS_MB, "cclass-mb" },\r
170 { OP_CCLASS_MIX, "cclass-mix" },\r
171 { OP_CCLASS_NOT, "cclass-not" },\r
172 { OP_CCLASS_MB_NOT, "cclass-mb-not" },\r
173 { OP_CCLASS_MIX_NOT, "cclass-mix-not" },\r
174 { OP_ANYCHAR, "anychar" },\r
175 { OP_ANYCHAR_ML, "anychar-ml" },\r
176 { OP_ANYCHAR_STAR, "anychar*" },\r
177 { OP_ANYCHAR_ML_STAR, "anychar-ml*" },\r
178 { OP_ANYCHAR_STAR_PEEK_NEXT, "anychar*-peek-next" },\r
179 { OP_ANYCHAR_ML_STAR_PEEK_NEXT, "anychar-ml*-peek-next" },\r
180 { OP_WORD, "word" },\r
181 { OP_WORD_ASCII, "word-ascii" },\r
182 { OP_NO_WORD, "not-word" },\r
183 { OP_NO_WORD_ASCII, "not-word-ascii" },\r
184 { OP_WORD_BOUNDARY, "word-boundary" },\r
185 { OP_NO_WORD_BOUNDARY, "not-word-boundary" },\r
186 { OP_WORD_BEGIN, "word-begin" },\r
187 { OP_WORD_END, "word-end" },\r
188 { OP_TEXT_SEGMENT_BOUNDARY, "text-segment-boundary" },\r
189 { OP_BEGIN_BUF, "begin-buf" },\r
190 { OP_END_BUF, "end-buf" },\r
191 { OP_BEGIN_LINE, "begin-line" },\r
192 { OP_END_LINE, "end-line" },\r
193 { OP_SEMI_END_BUF, "semi-end-buf" },\r
194 { OP_BEGIN_POSITION, "begin-position" },\r
195 { OP_BACKREF1, "backref1" },\r
196 { OP_BACKREF2, "backref2" },\r
197 { OP_BACKREF_N, "backref-n" },\r
198 { OP_BACKREF_N_IC, "backref-n-ic" },\r
199 { OP_BACKREF_MULTI, "backref_multi" },\r
200 { OP_BACKREF_MULTI_IC, "backref_multi-ic" },\r
201 { OP_BACKREF_WITH_LEVEL, "backref_with_level" },\r
202 { OP_BACKREF_WITH_LEVEL_IC, "backref_with_level-c" },\r
203 { OP_BACKREF_CHECK, "backref_check" },\r
204 { OP_BACKREF_CHECK_WITH_LEVEL, "backref_check_with_level" },\r
205 { OP_MEMORY_START_PUSH, "mem-start-push" },\r
206 { OP_MEMORY_START, "mem-start" },\r
207 { OP_MEMORY_END_PUSH, "mem-end-push" },\r
208 { OP_MEMORY_END_PUSH_REC, "mem-end-push-rec" },\r
209 { OP_MEMORY_END, "mem-end" },\r
210 { OP_MEMORY_END_REC, "mem-end-rec" },\r
211 { OP_FAIL, "fail" },\r
212 { OP_JUMP, "jump" },\r
213 { OP_PUSH, "push" },\r
214 { OP_PUSH_SUPER, "push-super" },\r
215 { OP_POP_OUT, "pop-out" },\r
216#ifdef USE_OP_PUSH_OR_JUMP_EXACT\r
217 { OP_PUSH_OR_JUMP_EXACT1, "push-or-jump-e1" },\r
b602265d 218#endif\r
b26691c4
LG
219 { OP_PUSH_IF_PEEK_NEXT, "push-if-peek-next" },\r
220 { OP_REPEAT, "repeat" },\r
221 { OP_REPEAT_NG, "repeat-ng" },\r
222 { OP_REPEAT_INC, "repeat-inc" },\r
223 { OP_REPEAT_INC_NG, "repeat-inc-ng" },\r
224 { OP_REPEAT_INC_SG, "repeat-inc-sg" },\r
225 { OP_REPEAT_INC_NG_SG, "repeat-inc-ng-sg" },\r
226 { OP_EMPTY_CHECK_START, "empty-check-start" },\r
227 { OP_EMPTY_CHECK_END, "empty-check-end" },\r
228 { OP_EMPTY_CHECK_END_MEMST, "empty-check-end-memst" },\r
229 { OP_EMPTY_CHECK_END_MEMST_PUSH,"empty-check-end-memst-push" },\r
230 { OP_PREC_READ_START, "push-pos" },\r
231 { OP_PREC_READ_END, "pop-pos" },\r
232 { OP_PREC_READ_NOT_START, "prec-read-not-start" },\r
233 { OP_PREC_READ_NOT_END, "prec-read-not-end" },\r
234 { OP_ATOMIC_START, "atomic-start" },\r
235 { OP_ATOMIC_END, "atomic-end" },\r
236 { OP_LOOK_BEHIND, "look-behind" },\r
237 { OP_LOOK_BEHIND_NOT_START, "look-behind-not-start" },\r
238 { OP_LOOK_BEHIND_NOT_END, "look-behind-not-end" },\r
239 { OP_CALL, "call" },\r
240 { OP_RETURN, "return" },\r
241 { OP_PUSH_SAVE_VAL, "push-save-val" },\r
242 { OP_UPDATE_VAR, "update-var" },\r
b602265d 243#ifdef USE_CALLOUT\r
b26691c4
LG
244 { OP_CALLOUT_CONTENTS, "callout-contents" },\r
245 { OP_CALLOUT_NAME, "callout-name" },\r
b602265d 246#endif\r
b26691c4 247 { -1, "" }\r
b602265d
DG
248};\r
249\r
250static char*\r
251op2name(int opcode)\r
252{\r
253 int i;\r
254\r
255 for (i = 0; OpInfo[i].opcode >= 0; i++) {\r
b26691c4 256 if (opcode == OpInfo[i].opcode) return OpInfo[i].name;\r
b602265d 257 }\r
b602265d 258\r
b26691c4 259 return "";\r
b602265d
DG
260}\r
261\r
262static void\r
263p_string(FILE* f, int len, UChar* s)\r
264{\r
265 fputs(":", f);\r
266 while (len-- > 0) { fputc(*s++, f); }\r
267}\r
268\r
269static void\r
270p_len_string(FILE* f, LengthType len, int mb_len, UChar* s)\r
271{\r
272 int x = len * mb_len;\r
273\r
274 fprintf(f, ":%d:", len);\r
275 while (x-- > 0) { fputc(*s++, f); }\r
276}\r
277\r
278static void\r
b26691c4 279p_rel_addr(FILE* f, RelAddrType rel_addr, Operation* p, Operation* start)\r
b602265d
DG
280{\r
281 RelAddrType curr = (RelAddrType )(p - start);\r
282\r
283 fprintf(f, "{%d/%d}", rel_addr, curr + rel_addr);\r
284}\r
285\r
286static int\r
287bitset_on_num(BitSetRef bs)\r
288{\r
289 int i, n;\r
290\r
291 n = 0;\r
292 for (i = 0; i < SINGLE_BYTE_SIZE; i++) {\r
293 if (BITSET_AT(bs, i)) n++;\r
294 }\r
b26691c4 295\r
b602265d
DG
296 return n;\r
297}\r
298\r
b26691c4
LG
299static void\r
300print_compiled_byte_code(FILE* f, regex_t* reg, int index,\r
301 Operation* start, OnigEncoding enc)\r
b602265d
DG
302{\r
303 int i, n;\r
b602265d
DG
304 RelAddrType addr;\r
305 LengthType len;\r
306 MemNumType mem;\r
b26691c4 307 OnigCodePoint code;\r
b602265d
DG
308 ModeType mode;\r
309 UChar *q;\r
b26691c4
LG
310 Operation* p;\r
311 enum OpCode opcode;\r
b602265d 312\r
b26691c4 313 p = reg->ops + index;\r
b602265d 314\r
b26691c4
LG
315#ifdef USE_DIRECT_THREADED_CODE\r
316 opcode = reg->ocs[index];\r
317#else\r
318 opcode = p->opcode;\r
319#endif\r
b602265d 320\r
b26691c4
LG
321 fprintf(f, "%s", op2name(opcode));\r
322 switch (opcode) {\r
323 case OP_EXACT1:\r
324 p_string(f, 1, p->exact.s); break;\r
325 case OP_EXACT2:\r
326 p_string(f, 2, p->exact.s); break;\r
327 case OP_EXACT3:\r
328 p_string(f, 3, p->exact.s); break;\r
329 case OP_EXACT4:\r
330 p_string(f, 4, p->exact.s); break;\r
331 case OP_EXACT5:\r
332 p_string(f, 5, p->exact.s); break;\r
333 case OP_EXACTN:\r
334 len = p->exact_n.n;\r
335 p_string(f, len, p->exact_n.s); break;\r
336 case OP_EXACTMB2N1:\r
337 p_string(f, 2, p->exact.s); break;\r
338 case OP_EXACTMB2N2:\r
339 p_string(f, 4, p->exact.s); break;\r
340 case OP_EXACTMB2N3:\r
341 p_string(f, 3, p->exact.s); break;\r
342 case OP_EXACTMB2N:\r
343 len = p->exact_n.n;\r
344 p_len_string(f, len, 2, p->exact_n.s); break;\r
345 case OP_EXACTMB3N:\r
346 len = p->exact_n.n;\r
347 p_len_string(f, len, 3, p->exact_n.s); break;\r
348 case OP_EXACTMBN:\r
349 {\r
350 int mb_len;\r
351\r
352 mb_len = p->exact_len_n.len;\r
353 len = p->exact_len_n.n;\r
354 q = p->exact_len_n.s;\r
355 fprintf(f, ":%d:%d:", mb_len, len);\r
356 n = len * mb_len;\r
357 while (n-- > 0) { fputc(*q++, f); }\r
358 }\r
359 break;\r
360 case OP_EXACT1_IC:\r
361 len = enclen(enc, p->exact.s);\r
362 p_string(f, len, p->exact.s);\r
363 break;\r
364 case OP_EXACTN_IC:\r
365 len = p->exact_n.n;\r
366 p_len_string(f, len, 1, p->exact_n.s);\r
367 break;\r
b602265d 368\r
b26691c4
LG
369 case OP_CCLASS:\r
370 case OP_CCLASS_NOT:\r
371 n = bitset_on_num(p->cclass.bsp);\r
372 fprintf(f, ":%d", n);\r
373 break;\r
374 case OP_CCLASS_MB:\r
375 case OP_CCLASS_MB_NOT:\r
376 {\r
377 OnigCodePoint ncode;\r
378 OnigCodePoint* codes; \r
379\r
380 codes = (OnigCodePoint* )p->cclass_mb.mb;\r
381 GET_CODE_POINT(ncode, codes);\r
382 codes++;\r
383 GET_CODE_POINT(code, codes);\r
384 fprintf(f, ":%u:%u", code, ncode);\r
385 }\r
386 break;\r
387 case OP_CCLASS_MIX:\r
388 case OP_CCLASS_MIX_NOT:\r
389 {\r
390 OnigCodePoint ncode;\r
391 OnigCodePoint* codes;\r
b602265d 392\r
b26691c4
LG
393 codes = (OnigCodePoint* )p->cclass_mix.mb;\r
394 n = bitset_on_num(p->cclass_mix.bsp);\r
b602265d 395\r
b26691c4
LG
396 GET_CODE_POINT(ncode, codes);\r
397 codes++;\r
398 GET_CODE_POINT(code, codes);\r
399 fprintf(f, ":%d:%u:%u", n, code, ncode);\r
400 }\r
401 break;\r
b602265d 402\r
b26691c4
LG
403 case OP_ANYCHAR_STAR_PEEK_NEXT:\r
404 case OP_ANYCHAR_ML_STAR_PEEK_NEXT:\r
405 p_string(f, 1, &(p->anychar_star_peek_next.c));\r
406 break;\r
b602265d 407\r
b26691c4
LG
408 case OP_WORD_BOUNDARY:\r
409 case OP_NO_WORD_BOUNDARY:\r
410 case OP_WORD_BEGIN:\r
411 case OP_WORD_END:\r
412 mode = p->word_boundary.mode;\r
413 fprintf(f, ":%d", mode);\r
414 break;\r
b602265d 415\r
b26691c4
LG
416 case OP_BACKREF_N:\r
417 case OP_BACKREF_N_IC:\r
418 mem = p->backref_n.n1;\r
419 fprintf(f, ":%d", mem);\r
420 break;\r
421 case OP_BACKREF_MULTI_IC:\r
422 case OP_BACKREF_MULTI:\r
423 case OP_BACKREF_CHECK:\r
424 fputs(" ", f);\r
425 n = p->backref_general.num;\r
426 for (i = 0; i < n; i++) {\r
427 mem = (n == 1) ? p->backref_general.n1 : p->backref_general.ns[i];\r
428 if (i > 0) fputs(", ", f);\r
429 fprintf(f, "%d", mem);\r
430 }\r
431 break;\r
432 case OP_BACKREF_WITH_LEVEL:\r
433 case OP_BACKREF_WITH_LEVEL_IC:\r
434 case OP_BACKREF_CHECK_WITH_LEVEL:\r
435 {\r
436 LengthType level;\r
b602265d 437\r
b26691c4
LG
438 level = p->backref_general.nest_level;\r
439 fprintf(f, ":%d", level);\r
b602265d 440 fputs(" ", f);\r
b26691c4
LG
441 n = p->backref_general.num;\r
442 for (i = 0; i < n; i++) {\r
443 mem = (n == 1) ? p->backref_general.n1 : p->backref_general.ns[i];\r
b602265d
DG
444 if (i > 0) fputs(", ", f);\r
445 fprintf(f, "%d", mem);\r
446 }\r
b26691c4
LG
447 }\r
448 break;\r
b602265d 449\r
b26691c4
LG
450 case OP_MEMORY_START:\r
451 case OP_MEMORY_START_PUSH:\r
452 mem = p->memory_start.num;\r
453 fprintf(f, ":%d", mem);\r
454 break;\r
455 case OP_MEMORY_END_PUSH:\r
456 case OP_MEMORY_END_PUSH_REC:\r
457 case OP_MEMORY_END:\r
458 case OP_MEMORY_END_REC:\r
459 mem = p->memory_end.num;\r
460 fprintf(f, ":%d", mem);\r
461 break;\r
b602265d 462\r
b26691c4
LG
463 case OP_JUMP:\r
464 addr = p->jump.addr;\r
465 fputc(':', f);\r
466 p_rel_addr(f, addr, p, start);\r
467 break;\r
b602265d 468\r
b26691c4
LG
469 case OP_PUSH:\r
470 case OP_PUSH_SUPER:\r
471 addr = p->push.addr;\r
472 fputc(':', f);\r
473 p_rel_addr(f, addr, p, start);\r
474 break;\r
b602265d 475\r
b26691c4
LG
476#ifdef USE_OP_PUSH_OR_JUMP_EXACT\r
477 case OP_PUSH_OR_JUMP_EXACT1:\r
478 addr = p->push_or_jump_exact1.addr;\r
479 fputc(':', f);\r
480 p_rel_addr(f, addr, p, start);\r
481 p_string(f, 1, &(p->push_or_jump_exact1.c));\r
482 break;\r
483#endif\r
b602265d 484\r
b26691c4
LG
485 case OP_PUSH_IF_PEEK_NEXT:\r
486 addr = p->push_if_peek_next.addr;\r
487 fputc(':', f);\r
488 p_rel_addr(f, addr, p, start);\r
489 p_string(f, 1, &(p->push_if_peek_next.c));\r
490 break;\r
b602265d 491\r
b26691c4
LG
492 case OP_REPEAT:\r
493 case OP_REPEAT_NG:\r
494 mem = p->repeat.id;\r
495 addr = p->repeat.addr;\r
496 fprintf(f, ":%d:", mem);\r
497 p_rel_addr(f, addr, p, start);\r
498 break;\r
b602265d 499\r
b26691c4
LG
500 case OP_REPEAT_INC:\r
501 case OP_REPEAT_INC_NG:\r
502 case OP_REPEAT_INC_SG:\r
503 case OP_REPEAT_INC_NG_SG:\r
504 mem = p->repeat.id;\r
505 fprintf(f, ":%d", mem);\r
506 break;\r
b602265d 507\r
b26691c4
LG
508 case OP_EMPTY_CHECK_START:\r
509 mem = p->empty_check_start.mem;\r
510 fprintf(f, ":%d", mem);\r
511 break;\r
512 case OP_EMPTY_CHECK_END:\r
513 case OP_EMPTY_CHECK_END_MEMST:\r
514 case OP_EMPTY_CHECK_END_MEMST_PUSH:\r
515 mem = p->empty_check_end.mem;\r
516 fprintf(f, ":%d", mem);\r
517 break;\r
b602265d 518\r
b26691c4
LG
519 case OP_PREC_READ_NOT_START:\r
520 addr = p->prec_read_not_start.addr;\r
521 fputc(':', f);\r
522 p_rel_addr(f, addr, p, start);\r
523 break;\r
b602265d 524\r
b26691c4
LG
525 case OP_LOOK_BEHIND:\r
526 len = p->look_behind.len;\r
527 fprintf(f, ":%d", len);\r
528 break;\r
b602265d 529\r
b26691c4
LG
530 case OP_LOOK_BEHIND_NOT_START:\r
531 addr = p->look_behind_not_start.addr;\r
532 len = p->look_behind_not_start.len;\r
533 fprintf(f, ":%d:", len);\r
534 p_rel_addr(f, addr, p, start);\r
535 break;\r
b602265d 536\r
b26691c4
LG
537 case OP_CALL:\r
538 addr = p->call.addr;\r
539 fprintf(f, ":{/%d}", addr);\r
540 break;\r
b602265d 541\r
b26691c4
LG
542 case OP_PUSH_SAVE_VAL:\r
543 {\r
544 SaveType type;\r
545\r
546 type = p->push_save_val.type;\r
547 mem = p->push_save_val.id;\r
548 fprintf(f, ":%d:%d", type, mem);\r
549 }\r
550 break;\r
551\r
552 case OP_UPDATE_VAR:\r
553 {\r
554 UpdateVarType type;\r
555\r
556 type = p->update_var.type;\r
557 mem = p->update_var.id;\r
558 fprintf(f, ":%d:%d", type, mem);\r
559 }\r
560 break;\r
561\r
562#ifdef USE_CALLOUT\r
563 case OP_CALLOUT_CONTENTS:\r
564 mem = p->callout_contents.num;\r
565 fprintf(f, ":%d", mem);\r
566 break;\r
567\r
568 case OP_CALLOUT_NAME:\r
569 {\r
570 int id;\r
b602265d 571\r
b26691c4
LG
572 id = p->callout_name.id;\r
573 mem = p->callout_name.num;\r
574 fprintf(f, ":%d:%d", id, mem);\r
b602265d 575 }\r
b26691c4
LG
576 break;\r
577#endif\r
578\r
579 case OP_TEXT_SEGMENT_BOUNDARY:\r
580 if (p->text_segment_boundary.not != 0)\r
581 fprintf(f, ":not");\r
582 break;\r
583\r
584 case OP_FINISH:\r
585 case OP_END:\r
586 case OP_ANYCHAR:\r
587 case OP_ANYCHAR_ML:\r
588 case OP_ANYCHAR_STAR:\r
589 case OP_ANYCHAR_ML_STAR:\r
590 case OP_WORD:\r
591 case OP_WORD_ASCII:\r
592 case OP_NO_WORD:\r
593 case OP_NO_WORD_ASCII:\r
594 case OP_BEGIN_BUF:\r
595 case OP_END_BUF:\r
596 case OP_BEGIN_LINE:\r
597 case OP_END_LINE:\r
598 case OP_SEMI_END_BUF:\r
599 case OP_BEGIN_POSITION:\r
600 case OP_BACKREF1:\r
601 case OP_BACKREF2:\r
602 case OP_FAIL:\r
603 case OP_POP_OUT:\r
604 case OP_PREC_READ_START:\r
605 case OP_PREC_READ_END:\r
606 case OP_PREC_READ_NOT_END:\r
607 case OP_ATOMIC_START:\r
608 case OP_ATOMIC_END:\r
609 case OP_LOOK_BEHIND_NOT_END:\r
610 case OP_RETURN:\r
611 break;\r
612\r
613 default:\r
614 fprintf(stderr, "print_compiled_byte_code: undefined code %d\n", opcode);\r
615 break;\r
b602265d 616 }\r
b602265d
DG
617}\r
618#endif /* ONIG_DEBUG */\r
619\r
620#ifdef ONIG_DEBUG_COMPILE\r
621extern void\r
622onig_print_compiled_byte_code_list(FILE* f, regex_t* reg)\r
623{\r
b26691c4
LG
624 Operation* bp;\r
625 Operation* start = reg->ops;\r
626 Operation* end = reg->ops + reg->ops_used;\r
b602265d
DG
627\r
628 fprintf(f, "bt_mem_start: 0x%x, bt_mem_end: 0x%x\n",\r
629 reg->bt_mem_start, reg->bt_mem_end);\r
b26691c4 630 fprintf(f, "code-length: %d\n", reg->ops_used);\r
b602265d
DG
631\r
632 bp = start;\r
633 while (bp < end) {\r
634 int pos = bp - start;\r
635\r
636 fprintf(f, "%4d: ", pos);\r
b26691c4 637 print_compiled_byte_code(f, reg, pos, start, reg->enc);\r
b602265d 638 fprintf(f, "\n");\r
b26691c4 639 bp++;\r
b602265d
DG
640 }\r
641 fprintf(f, "\n");\r
642}\r
643#endif\r
644\r
645\r
14b0e578
CS
646#ifdef USE_CAPTURE_HISTORY\r
647static void history_tree_free(OnigCaptureTreeNode* node);\r
648\r
649static void\r
650history_tree_clear(OnigCaptureTreeNode* node)\r
651{\r
652 int i;\r
653\r
b26691c4
LG
654 if (IS_NULL(node)) return ;\r
655\r
656 for (i = 0; i < node->num_childs; i++) {\r
657 if (IS_NOT_NULL(node->childs[i])) {\r
658 history_tree_free(node->childs[i]);\r
14b0e578 659 }\r
14b0e578 660 }\r
b26691c4
LG
661 for (i = 0; i < node->allocated; i++) {\r
662 node->childs[i] = (OnigCaptureTreeNode* )0;\r
663 }\r
664 node->num_childs = 0;\r
665 node->beg = ONIG_REGION_NOTPOS;\r
666 node->end = ONIG_REGION_NOTPOS;\r
667 node->group = -1;\r
14b0e578
CS
668}\r
669\r
670static void\r
671history_tree_free(OnigCaptureTreeNode* node)\r
672{\r
673 history_tree_clear(node);\r
b26691c4
LG
674 if (IS_NOT_NULL(node->childs)) xfree(node->childs);\r
675\r
14b0e578
CS
676 xfree(node);\r
677}\r
678\r
679static void\r
680history_root_free(OnigRegion* r)\r
681{\r
b26691c4
LG
682 if (IS_NULL(r->history_root)) return ;\r
683\r
684 history_tree_free(r->history_root);\r
685 r->history_root = (OnigCaptureTreeNode* )0;\r
14b0e578
CS
686}\r
687\r
688static OnigCaptureTreeNode*\r
689history_node_new(void)\r
690{\r
691 OnigCaptureTreeNode* node;\r
692\r
693 node = (OnigCaptureTreeNode* )xmalloc(sizeof(OnigCaptureTreeNode));\r
694 CHECK_NULL_RETURN(node);\r
b26691c4 695\r
14b0e578 696 node->childs = (OnigCaptureTreeNode** )0;\r
b26691c4
LG
697 node->allocated = 0;\r
698 node->num_childs = 0;\r
14b0e578
CS
699 node->group = -1;\r
700 node->beg = ONIG_REGION_NOTPOS;\r
701 node->end = ONIG_REGION_NOTPOS;\r
702\r
703 return node;\r
704}\r
705\r
706static int\r
707history_tree_add_child(OnigCaptureTreeNode* parent, OnigCaptureTreeNode* child)\r
708{\r
709#define HISTORY_TREE_INIT_ALLOC_SIZE 8\r
710\r
711 if (parent->num_childs >= parent->allocated) {\r
712 int n, i;\r
713\r
714 if (IS_NULL(parent->childs)) {\r
715 n = HISTORY_TREE_INIT_ALLOC_SIZE;\r
716 parent->childs =\r
b26691c4 717 (OnigCaptureTreeNode** )xmalloc(sizeof(parent->childs[0]) * n);\r
14b0e578
CS
718 }\r
719 else {\r
720 n = parent->allocated * 2;\r
721 parent->childs =\r
722 (OnigCaptureTreeNode** )xrealloc(parent->childs,\r
b26691c4
LG
723 sizeof(parent->childs[0]) * n,\r
724 sizeof(parent->childs[0]) * parent->allocated);\r
14b0e578
CS
725 }\r
726 CHECK_NULL_RETURN_MEMERR(parent->childs);\r
727 for (i = parent->allocated; i < n; i++) {\r
728 parent->childs[i] = (OnigCaptureTreeNode* )0;\r
729 }\r
730 parent->allocated = n;\r
731 }\r
732\r
733 parent->childs[parent->num_childs] = child;\r
734 parent->num_childs++;\r
735 return 0;\r
736}\r
737\r
738static OnigCaptureTreeNode*\r
739history_tree_clone(OnigCaptureTreeNode* node)\r
740{\r
741 int i;\r
742 OnigCaptureTreeNode *clone, *child;\r
743\r
744 clone = history_node_new();\r
745 CHECK_NULL_RETURN(clone);\r
746\r
747 clone->beg = node->beg;\r
748 clone->end = node->end;\r
749 for (i = 0; i < node->num_childs; i++) {\r
750 child = history_tree_clone(node->childs[i]);\r
751 if (IS_NULL(child)) {\r
752 history_tree_free(clone);\r
753 return (OnigCaptureTreeNode* )0;\r
754 }\r
755 history_tree_add_child(clone, child);\r
756 }\r
757\r
758 return clone;\r
759}\r
760\r
761extern OnigCaptureTreeNode*\r
762onig_get_capture_tree(OnigRegion* region)\r
763{\r
764 return region->history_root;\r
765}\r
766#endif /* USE_CAPTURE_HISTORY */\r
767\r
768extern void\r
769onig_region_clear(OnigRegion* region)\r
770{\r
771 int i;\r
772\r
773 for (i = 0; i < region->num_regs; i++) {\r
774 region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;\r
775 }\r
776#ifdef USE_CAPTURE_HISTORY\r
777 history_root_free(region);\r
778#endif\r
779}\r
780\r
781extern int\r
782onig_region_resize(OnigRegion* region, int n)\r
783{\r
784 region->num_regs = n;\r
785\r
786 if (n < ONIG_NREGION)\r
787 n = ONIG_NREGION;\r
788\r
789 if (region->allocated == 0) {\r
790 region->beg = (int* )xmalloc(n * sizeof(int));\r
791 region->end = (int* )xmalloc(n * sizeof(int));\r
792\r
793 if (region->beg == 0 || region->end == 0)\r
794 return ONIGERR_MEMORY;\r
795\r
796 region->allocated = n;\r
797 }\r
798 else if (region->allocated < n) {\r
799 region->beg = (int* )xrealloc(region->beg, n * sizeof(int), region->allocated * sizeof(int));\r
800 region->end = (int* )xrealloc(region->end, n * sizeof(int), region->allocated * sizeof(int));\r
801\r
802 if (region->beg == 0 || region->end == 0)\r
803 return ONIGERR_MEMORY;\r
804\r
805 region->allocated = n;\r
806 }\r
807\r
808 return 0;\r
809}\r
810\r
811static int\r
812onig_region_resize_clear(OnigRegion* region, int n)\r
813{\r
814 int r;\r
b26691c4 815\r
14b0e578
CS
816 r = onig_region_resize(region, n);\r
817 if (r != 0) return r;\r
818 onig_region_clear(region);\r
819 return 0;\r
820}\r
b26691c4 821\r
14b0e578
CS
822extern int\r
823onig_region_set(OnigRegion* region, int at, int beg, int end)\r
824{\r
825 if (at < 0) return ONIGERR_INVALID_ARGUMENT;\r
826\r
827 if (at >= region->allocated) {\r
828 int r = onig_region_resize(region, at + 1);\r
829 if (r < 0) return r;\r
830 }\r
b26691c4 831\r
14b0e578
CS
832 region->beg[at] = beg;\r
833 region->end[at] = end;\r
834 return 0;\r
835}\r
836\r
837extern void\r
838onig_region_init(OnigRegion* region)\r
839{\r
840 region->num_regs = 0;\r
841 region->allocated = 0;\r
842 region->beg = (int* )0;\r
843 region->end = (int* )0;\r
844 region->history_root = (OnigCaptureTreeNode* )0;\r
845}\r
846\r
847extern OnigRegion*\r
848onig_region_new(void)\r
849{\r
850 OnigRegion* r;\r
851\r
852 r = (OnigRegion* )xmalloc(sizeof(OnigRegion));\r
b602265d
DG
853 CHECK_NULL_RETURN(r);\r
854 onig_region_init(r);\r
14b0e578
CS
855 return r;\r
856}\r
857\r
858extern void\r
859onig_region_free(OnigRegion* r, int free_self)\r
860{\r
b602265d 861 if (r != 0) {\r
14b0e578
CS
862 if (r->allocated > 0) {\r
863 if (r->beg) xfree(r->beg);\r
864 if (r->end) xfree(r->end);\r
865 r->allocated = 0;\r
866 }\r
867#ifdef USE_CAPTURE_HISTORY\r
868 history_root_free(r);\r
869#endif\r
870 if (free_self) xfree(r);\r
871 }\r
872}\r
873\r
874extern void\r
875onig_region_copy(OnigRegion* to, OnigRegion* from)\r
876{\r
877#define RREGC_SIZE (sizeof(int) * from->num_regs)\r
878 int i;\r
879\r
880 if (to == from) return;\r
881\r
882 if (to->allocated == 0) {\r
883 if (from->num_regs > 0) {\r
884 to->beg = (int* )xmalloc(RREGC_SIZE);\r
b602265d 885 if (IS_NULL(to->beg)) return;\r
14b0e578 886 to->end = (int* )xmalloc(RREGC_SIZE);\r
b602265d 887 if (IS_NULL(to->end)) return;\r
14b0e578
CS
888 to->allocated = from->num_regs;\r
889 }\r
890 }\r
891 else if (to->allocated < from->num_regs) {\r
892 to->beg = (int* )xrealloc(to->beg, RREGC_SIZE, sizeof(int) * to->allocated);\r
b602265d 893 if (IS_NULL(to->beg)) return;\r
14b0e578 894 to->end = (int* )xrealloc(to->end, RREGC_SIZE, sizeof(int) * to->allocated);\r
b602265d 895 if (IS_NULL(to->end)) return;\r
14b0e578
CS
896 to->allocated = from->num_regs;\r
897 }\r
898\r
899 for (i = 0; i < from->num_regs; i++) {\r
900 to->beg[i] = from->beg[i];\r
901 to->end[i] = from->end[i];\r
902 }\r
903 to->num_regs = from->num_regs;\r
904\r
905#ifdef USE_CAPTURE_HISTORY\r
906 history_root_free(to);\r
907\r
908 if (IS_NOT_NULL(from->history_root)) {\r
909 to->history_root = history_tree_clone(from->history_root);\r
910 }\r
911#endif\r
912}\r
913\r
b602265d
DG
914#ifdef USE_CALLOUT\r
915#define CALLOUT_BODY(func, ain, aname_id, anum, user, args, result) do { \\r
916 args.in = (ain);\\r
917 args.name_id = (aname_id);\\r
918 args.num = anum;\\r
919 args.regex = reg;\\r
920 args.string = str;\\r
921 args.string_end = end;\\r
922 args.start = sstart;\\r
923 args.right_range = right_range;\\r
924 args.current = s;\\r
925 args.retry_in_match_counter = retry_in_match_counter;\\r
926 args.msa = msa;\\r
927 args.stk_base = stk_base;\\r
928 args.stk = stk;\\r
929 args.mem_start_stk = mem_start_stk;\\r
930 args.mem_end_stk = mem_end_stk;\\r
931 result = (func)(&args, user);\\r
932} while (0)\r
933\r
934#define RETRACTION_CALLOUT(func, aname_id, anum, user) do {\\r
935 int result;\\r
936 OnigCalloutArgs args;\\r
937 CALLOUT_BODY(func, ONIG_CALLOUT_IN_RETRACTION, aname_id, anum, user, args, result);\\r
938 switch (result) {\\r
939 case ONIG_CALLOUT_FAIL:\\r
940 case ONIG_CALLOUT_SUCCESS:\\r
941 break;\\r
942 default:\\r
943 if (result > 0) {\\r
944 result = ONIGERR_INVALID_ARGUMENT;\\r
945 }\\r
946 best_len = result;\\r
947 goto finish;\\r
948 break;\\r
949 }\\r
950} while(0)\r
951#endif\r
952\r
14b0e578
CS
953\r
954/** stack **/\r
955#define INVALID_STACK_INDEX -1\r
956\r
b602265d
DG
957#define STK_ALT_FLAG 0x0001\r
958\r
14b0e578
CS
959/* stack type */\r
960/* used by normal-POP */\r
b602265d
DG
961#define STK_SUPER_ALT STK_ALT_FLAG\r
962#define STK_ALT (0x0002 | STK_ALT_FLAG)\r
963#define STK_ALT_PREC_READ_NOT (0x0004 | STK_ALT_FLAG)\r
964#define STK_ALT_LOOK_BEHIND_NOT (0x0006 | STK_ALT_FLAG)\r
965\r
14b0e578 966/* handled by normal-POP */\r
b602265d
DG
967#define STK_MEM_START 0x0010\r
968#define STK_MEM_END 0x8030\r
969#define STK_REPEAT_INC 0x0050\r
970#ifdef USE_CALLOUT\r
971#define STK_CALLOUT 0x0070\r
972#endif\r
973\r
14b0e578 974/* avoided by normal-POP */\r
b602265d
DG
975#define STK_VOID 0x0000 /* for fill a blank */\r
976#define STK_EMPTY_CHECK_START 0x3000\r
977#define STK_EMPTY_CHECK_END 0x5000 /* for recursive call */\r
978#define STK_MEM_END_MARK 0x8100\r
979#define STK_TO_VOID_START 0x1200 /* mark for "(?>...)" */\r
980#define STK_REPEAT 0x0300\r
981#define STK_CALL_FRAME 0x0400\r
982#define STK_RETURN 0x0500\r
983#define STK_SAVE_VAL 0x0600\r
b26691c4
LG
984#define STK_PREC_READ_START 0x0700\r
985#define STK_PREC_READ_END 0x0800\r
14b0e578
CS
986\r
987/* stack type check mask */\r
b602265d
DG
988#define STK_MASK_POP_USED STK_ALT_FLAG\r
989#define STK_MASK_POP_HANDLED 0x0010\r
990#define STK_MASK_POP_HANDLED_TIL (STK_MASK_POP_HANDLED | 0x0004)\r
991#define STK_MASK_TO_VOID_TARGET 0x100e\r
14b0e578
CS
992#define STK_MASK_MEM_END_OR_MARK 0x8000 /* MEM_END or MEM_END_MARK */\r
993\r
b602265d
DG
994typedef intptr_t StackIndex;\r
995\r
996typedef struct _StackType {\r
997 unsigned int type;\r
998 int zid;\r
999 union {\r
1000 struct {\r
b26691c4
LG
1001 Operation* pcode; /* byte code position */\r
1002 UChar* pstr; /* string position */\r
1003 UChar* pstr_prev; /* previous char position of pstr */\r
b602265d
DG
1004 } state;\r
1005 struct {\r
b26691c4
LG
1006 int count; /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */\r
1007 Operation* pcode; /* byte code position (head of repeated target) */\r
b602265d
DG
1008 } repeat;\r
1009 struct {\r
1010 StackIndex si; /* index of stack */\r
1011 } repeat_inc;\r
1012 struct {\r
1013 UChar *pstr; /* start/end position */\r
1014 /* Following information is set, if this stack type is MEM-START */\r
1015 StackIndex prev_start; /* prev. info (for backtrack "(...)*" ) */\r
1016 StackIndex prev_end; /* prev. info (for backtrack "(...)*" ) */\r
1017 } mem;\r
1018 struct {\r
1019 UChar *pstr; /* start position */\r
1020 } empty_check;\r
1021#ifdef USE_CALL\r
1022 struct {\r
b26691c4
LG
1023 Operation *ret_addr; /* byte code position */\r
1024 UChar *pstr; /* string position */\r
b602265d
DG
1025 } call_frame;\r
1026#endif\r
1027 struct {\r
1028 enum SaveType type;\r
1029 UChar* v;\r
1030 UChar* v2;\r
1031 } val;\r
1032#ifdef USE_CALLOUT\r
1033 struct {\r
1034 int num;\r
1035 OnigCalloutFunc func;\r
1036 } callout;\r
1037#endif\r
1038 } u;\r
1039} StackType;\r
1040\r
1041#ifdef USE_CALLOUT\r
1042\r
1043struct OnigCalloutArgsStruct {\r
1044 OnigCalloutIn in;\r
1045 int name_id; /* name id or ONIG_NON_NAME_ID */\r
1046 int num;\r
1047 OnigRegex regex;\r
1048 const OnigUChar* string;\r
1049 const OnigUChar* string_end;\r
1050 const OnigUChar* start;\r
1051 const OnigUChar* right_range;\r
1052 const OnigUChar* current; /* current matching position */\r
1053 unsigned long retry_in_match_counter;\r
1054\r
1055 /* invisible to users */\r
1056 MatchArg* msa;\r
1057 StackType* stk_base;\r
1058 StackType* stk;\r
1059 StackIndex* mem_start_stk;\r
1060 StackIndex* mem_end_stk;\r
1061};\r
1062\r
1063#endif\r
1064\r
1065\r
14b0e578 1066#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
b602265d 1067#define MATCH_ARG_INIT(msa, reg, arg_option, arg_region, arg_start, mp) do { \\r
14b0e578
CS
1068 (msa).stack_p = (void* )0;\\r
1069 (msa).options = (arg_option);\\r
1070 (msa).region = (arg_region);\\r
1071 (msa).start = (arg_start);\\r
b602265d
DG
1072 (msa).match_stack_limit = (mp)->match_stack_limit;\\r
1073 (msa).retry_limit_in_match = (mp)->retry_limit_in_match;\\r
1074 (msa).mp = mp;\\r
14b0e578 1075 (msa).best_len = ONIG_MISMATCH;\\r
b602265d 1076 (msa).ptr_num = (reg)->num_repeat + ((reg)->num_mem + 1) * 2; \\r
14b0e578
CS
1077} while(0)\r
1078#else\r
b602265d 1079#define MATCH_ARG_INIT(msa, reg, arg_option, arg_region, arg_start, mp) do { \\r
14b0e578
CS
1080 (msa).stack_p = (void* )0;\\r
1081 (msa).options = (arg_option);\\r
1082 (msa).region = (arg_region);\\r
1083 (msa).start = (arg_start);\\r
b602265d
DG
1084 (msa).match_stack_limit = (mp)->match_stack_limit;\\r
1085 (msa).retry_limit_in_match = (mp)->retry_limit_in_match;\\r
1086 (msa).mp = mp;\\r
1087 (msa).ptr_num = (reg)->num_repeat + ((reg)->num_mem + 1) * 2; \\r
14b0e578
CS
1088} while(0)\r
1089#endif\r
1090\r
14b0e578 1091#define MATCH_ARG_FREE(msa) if ((msa).stack_p) xfree((msa).stack_p)\r
14b0e578
CS
1092\r
1093\r
b602265d 1094#define ALLOCA_PTR_NUM_LIMIT 50\r
14b0e578 1095\r
b602265d 1096#define STACK_INIT(stack_num) do {\\r
14b0e578 1097 if (msa->stack_p) {\\r
b602265d
DG
1098 is_alloca = 0;\\r
1099 alloc_base = msa->stack_p;\\r
1100 stk_base = (StackType* )(alloc_base\\r
1101 + (sizeof(StackIndex) * msa->ptr_num));\\r
14b0e578
CS
1102 stk = stk_base;\\r
1103 stk_end = stk_base + msa->stack_n;\\r
1104 }\\r
b602265d
DG
1105 else if (msa->ptr_num > ALLOCA_PTR_NUM_LIMIT) {\\r
1106 is_alloca = 0;\\r
1107 alloc_base = (char* )xmalloc(sizeof(StackIndex) * msa->ptr_num\\r
1108 + sizeof(StackType) * (stack_num));\\r
1109 CHECK_NULL_RETURN_MEMERR(alloc_base);\\r
1110 stk_base = (StackType* )(alloc_base\\r
1111 + (sizeof(StackIndex) * msa->ptr_num));\\r
1112 stk = stk_base;\\r
1113 stk_end = stk_base + (stack_num);\\r
1114 }\\r
14b0e578 1115 else {\\r
b602265d
DG
1116 is_alloca = 1;\\r
1117 alloc_base = (char* )xmalloc(sizeof(StackIndex) * msa->ptr_num\\r
1118 + sizeof(StackType) * (stack_num));\\r
1119 CHECK_NULL_RETURN_MEMERR(alloc_base);\\r
1120 stk_base = (StackType* )(alloc_base\\r
1121 + (sizeof(StackIndex) * msa->ptr_num));\\r
14b0e578
CS
1122 stk = stk_base;\\r
1123 stk_end = stk_base + (stack_num);\\r
1124 }\\r
b602265d
DG
1125} while(0);\r
1126\r
14b0e578
CS
1127\r
1128#define STACK_SAVE do{\\r
b602265d
DG
1129 msa->stack_n = (int )(stk_end - stk_base);\\r
1130 if (is_alloca != 0) {\\r
1131 size_t size = sizeof(StackIndex) * msa->ptr_num \\r
1132 + sizeof(StackType) * msa->stack_n;\\r
1133 msa->stack_p = xmalloc(size);\\r
1134 CHECK_NULL_RETURN_MEMERR(msa->stack_p);\\r
1135 xmemcpy(msa->stack_p, alloc_base, size);\\r
1136 }\\r
1137 else {\\r
1138 msa->stack_p = alloc_base;\\r
14b0e578
CS
1139 };\\r
1140} while(0)\r
1141\r
b602265d
DG
1142#define UPDATE_FOR_STACK_REALLOC do{\\r
1143 repeat_stk = (StackIndex* )alloc_base;\\r
1144 mem_start_stk = (StackIndex* )(repeat_stk + reg->num_repeat);\\r
1145 mem_end_stk = mem_start_stk + num_mem + 1;\\r
1146} while(0)\r
1147\r
1148static unsigned int MatchStackLimit = DEFAULT_MATCH_STACK_LIMIT_SIZE;\r
14b0e578
CS
1149\r
1150extern unsigned int\r
1151onig_get_match_stack_limit_size(void)\r
1152{\r
b602265d 1153 return MatchStackLimit;\r
14b0e578
CS
1154}\r
1155\r
1156extern int\r
1157onig_set_match_stack_limit_size(unsigned int size)\r
1158{\r
b602265d 1159 MatchStackLimit = size;\r
14b0e578
CS
1160 return 0;\r
1161}\r
1162\r
b602265d 1163#ifdef USE_RETRY_LIMIT_IN_MATCH\r
14b0e578 1164\r
b602265d 1165static unsigned long RetryLimitInMatch = DEFAULT_RETRY_LIMIT_IN_MATCH;\r
14b0e578 1166\r
b602265d
DG
1167#define CHECK_RETRY_LIMIT_IN_MATCH do {\\r
1168 if (retry_in_match_counter++ > retry_limit_in_match) goto retry_limit_in_match_over;\\r
1169} while (0)\r
14b0e578 1170\r
b602265d 1171#else\r
14b0e578 1172\r
b602265d 1173#define CHECK_RETRY_LIMIT_IN_MATCH\r
14b0e578 1174\r
b602265d 1175#endif /* USE_RETRY_LIMIT_IN_MATCH */\r
14b0e578 1176\r
b602265d
DG
1177extern unsigned long\r
1178onig_get_retry_limit_in_match(void)\r
1179{\r
1180#ifdef USE_RETRY_LIMIT_IN_MATCH\r
1181 return RetryLimitInMatch;\r
1182#else\r
1183 /* return ONIG_NO_SUPPORT_CONFIG; */\r
1184 return 0;\r
1185#endif\r
1186}\r
14b0e578 1187\r
b602265d
DG
1188extern int\r
1189onig_set_retry_limit_in_match(unsigned long size)\r
1190{\r
1191#ifdef USE_RETRY_LIMIT_IN_MATCH\r
1192 RetryLimitInMatch = size;\r
1193 return 0;\r
1194#else\r
1195 return ONIG_NO_SUPPORT_CONFIG;\r
1196#endif\r
1197}\r
1198\r
b26691c4 1199#ifdef USE_CALLOUT\r
b602265d
DG
1200static OnigCalloutFunc DefaultProgressCallout;\r
1201static OnigCalloutFunc DefaultRetractionCallout;\r
b26691c4 1202#endif\r
14b0e578 1203\r
b602265d
DG
1204extern OnigMatchParam*\r
1205onig_new_match_param(void)\r
1206{\r
1207 OnigMatchParam* p;\r
14b0e578 1208\r
b602265d
DG
1209 p = (OnigMatchParam* )xmalloc(sizeof(*p));\r
1210 if (IS_NOT_NULL(p)) {\r
1211 onig_initialize_match_param(p);\r
14b0e578
CS
1212 }\r
1213\r
b602265d
DG
1214 return p;\r
1215}\r
14b0e578 1216\r
b602265d
DG
1217extern void\r
1218onig_free_match_param_content(OnigMatchParam* p)\r
1219{\r
1220#ifdef USE_CALLOUT\r
1221 if (IS_NOT_NULL(p->callout_data)) {\r
1222 xfree(p->callout_data);\r
1223 p->callout_data = 0;\r
1224 }\r
1225#endif\r
1226}\r
14b0e578 1227\r
b602265d
DG
1228extern void\r
1229onig_free_match_param(OnigMatchParam* p)\r
1230{\r
1231 if (IS_NOT_NULL(p)) {\r
1232 onig_free_match_param_content(p);\r
1233 xfree(p);\r
1234 }\r
1235}\r
1236\r
1237extern int\r
1238onig_initialize_match_param(OnigMatchParam* mp)\r
1239{\r
1240 mp->match_stack_limit = MatchStackLimit;\r
1241#ifdef USE_RETRY_LIMIT_IN_MATCH\r
1242 mp->retry_limit_in_match = RetryLimitInMatch;\r
1243#endif\r
b602265d
DG
1244\r
1245#ifdef USE_CALLOUT\r
b26691c4
LG
1246 mp->progress_callout_of_contents = DefaultProgressCallout;\r
1247 mp->retraction_callout_of_contents = DefaultRetractionCallout;\r
b602265d
DG
1248 mp->match_at_call_counter = 0;\r
1249 mp->callout_user_data = 0;\r
1250 mp->callout_data = 0;\r
1251 mp->callout_data_alloc_num = 0;\r
1252#endif\r
1253\r
1254 return ONIG_NORMAL;\r
1255}\r
1256\r
1257#ifdef USE_CALLOUT\r
1258\r
1259static int\r
1260adjust_match_param(regex_t* reg, OnigMatchParam* mp)\r
1261{\r
b26691c4 1262 RegexExt* ext = reg->extp;\r
b602265d
DG
1263\r
1264 mp->match_at_call_counter = 0;\r
1265\r
1266 if (IS_NULL(ext) || ext->callout_num == 0) return ONIG_NORMAL;\r
1267\r
1268 if (ext->callout_num > mp->callout_data_alloc_num) {\r
1269 CalloutData* d;\r
1270 size_t n = ext->callout_num * sizeof(*d);\r
1271 if (IS_NOT_NULL(mp->callout_data))\r
1272 d = (CalloutData* )xrealloc(mp->callout_data, n, mp->callout_data_alloc_num * sizeof(*d));\r
1273 else\r
1274 d = (CalloutData* )xmalloc(n);\r
1275 CHECK_NULL_RETURN_MEMERR(d);\r
1276\r
1277 mp->callout_data = d;\r
1278 mp->callout_data_alloc_num = ext->callout_num;\r
1279 }\r
1280\r
1281 xmemset(mp->callout_data, 0, mp->callout_data_alloc_num * sizeof(CalloutData));\r
1282 return ONIG_NORMAL;\r
1283}\r
1284\r
1285#define ADJUST_MATCH_PARAM(reg, mp) \\r
1286 r = adjust_match_param(reg, mp);\\r
1287 if (r != ONIG_NORMAL) return r;\r
1288\r
1289#define CALLOUT_DATA_AT_NUM(mp, num) ((mp)->callout_data + ((num) - 1))\r
1290\r
1291extern int\r
1292onig_check_callout_data_and_clear_old_values(OnigCalloutArgs* args)\r
1293{\r
1294 OnigMatchParam* mp;\r
1295 int num;\r
1296 CalloutData* d;\r
1297\r
1298 mp = args->msa->mp;\r
1299 num = args->num;\r
1300\r
1301 d = CALLOUT_DATA_AT_NUM(mp, num);\r
1302 if (d->last_match_at_call_counter != mp->match_at_call_counter) {\r
1303 xmemset(d, 0, sizeof(*d));\r
1304 d->last_match_at_call_counter = mp->match_at_call_counter;\r
1305 return d->last_match_at_call_counter;\r
1306 }\r
1307\r
1308 return 0;\r
1309}\r
1310\r
1311extern int\r
1312onig_get_callout_data_dont_clear_old(regex_t* reg, OnigMatchParam* mp,\r
1313 int callout_num, int slot,\r
1314 OnigType* type, OnigValue* val)\r
1315{\r
1316 OnigType t;\r
1317 CalloutData* d;\r
1318\r
1319 if (callout_num <= 0) return ONIGERR_INVALID_ARGUMENT;\r
1320\r
1321 d = CALLOUT_DATA_AT_NUM(mp, callout_num);\r
1322 t = d->slot[slot].type;\r
1323 if (IS_NOT_NULL(type)) *type = t;\r
1324 if (IS_NOT_NULL(val)) *val = d->slot[slot].val;\r
1325 return (t == ONIG_TYPE_VOID ? 1 : ONIG_NORMAL);\r
1326}\r
1327\r
1328extern int\r
1329onig_get_callout_data_by_callout_args_self_dont_clear_old(OnigCalloutArgs* args,\r
1330 int slot, OnigType* type,\r
1331 OnigValue* val)\r
1332{\r
1333 return onig_get_callout_data_dont_clear_old(args->regex, args->msa->mp,\r
1334 args->num, slot, type, val);\r
1335}\r
1336\r
1337extern int\r
1338onig_get_callout_data(regex_t* reg, OnigMatchParam* mp,\r
1339 int callout_num, int slot,\r
1340 OnigType* type, OnigValue* val)\r
1341{\r
1342 OnigType t;\r
1343 CalloutData* d;\r
1344\r
1345 if (callout_num <= 0) return ONIGERR_INVALID_ARGUMENT;\r
1346\r
1347 d = CALLOUT_DATA_AT_NUM(mp, callout_num);\r
1348 if (d->last_match_at_call_counter != mp->match_at_call_counter) {\r
1349 xmemset(d, 0, sizeof(*d));\r
1350 d->last_match_at_call_counter = mp->match_at_call_counter;\r
1351 }\r
1352\r
1353 t = d->slot[slot].type;\r
1354 if (IS_NOT_NULL(type)) *type = t;\r
1355 if (IS_NOT_NULL(val)) *val = d->slot[slot].val;\r
1356 return (t == ONIG_TYPE_VOID ? 1 : ONIG_NORMAL);\r
1357}\r
1358\r
1359extern int\r
1360onig_get_callout_data_by_tag(regex_t* reg, OnigMatchParam* mp,\r
1361 const UChar* tag, const UChar* tag_end, int slot,\r
1362 OnigType* type, OnigValue* val)\r
1363{\r
1364 int num;\r
1365\r
1366 num = onig_get_callout_num_by_tag(reg, tag, tag_end);\r
1367 if (num < 0) return num;\r
1368 if (num == 0) return ONIGERR_INVALID_CALLOUT_TAG_NAME;\r
1369\r
1370 return onig_get_callout_data(reg, mp, num, slot, type, val);\r
1371}\r
1372\r
1373extern int\r
1374onig_get_callout_data_by_callout_args(OnigCalloutArgs* args,\r
1375 int callout_num, int slot,\r
1376 OnigType* type, OnigValue* val)\r
1377{\r
1378 return onig_get_callout_data(args->regex, args->msa->mp, callout_num, slot,\r
1379 type, val);\r
1380}\r
1381\r
1382extern int\r
1383onig_get_callout_data_by_callout_args_self(OnigCalloutArgs* args,\r
1384 int slot, OnigType* type, OnigValue* val)\r
1385{\r
1386 return onig_get_callout_data(args->regex, args->msa->mp, args->num, slot,\r
1387 type, val);\r
1388}\r
1389\r
1390extern int\r
1391onig_set_callout_data(regex_t* reg, OnigMatchParam* mp,\r
1392 int callout_num, int slot,\r
1393 OnigType type, OnigValue* val)\r
1394{\r
1395 CalloutData* d;\r
1396\r
1397 if (callout_num <= 0) return ONIGERR_INVALID_ARGUMENT;\r
1398\r
1399 d = CALLOUT_DATA_AT_NUM(mp, callout_num);\r
1400 d->slot[slot].type = type;\r
1401 d->slot[slot].val = *val;\r
1402 d->last_match_at_call_counter = mp->match_at_call_counter;\r
1403\r
1404 return ONIG_NORMAL;\r
1405}\r
1406\r
1407extern int\r
1408onig_set_callout_data_by_tag(regex_t* reg, OnigMatchParam* mp,\r
1409 const UChar* tag, const UChar* tag_end, int slot,\r
1410 OnigType type, OnigValue* val)\r
1411{\r
1412 int num;\r
1413\r
1414 num = onig_get_callout_num_by_tag(reg, tag, tag_end);\r
1415 if (num < 0) return num;\r
1416 if (num == 0) return ONIGERR_INVALID_CALLOUT_TAG_NAME;\r
1417\r
1418 return onig_set_callout_data(reg, mp, num, slot, type, val);\r
1419}\r
1420\r
1421extern int\r
1422onig_set_callout_data_by_callout_args(OnigCalloutArgs* args,\r
1423 int callout_num, int slot,\r
1424 OnigType type, OnigValue* val)\r
1425{\r
1426 return onig_set_callout_data(args->regex, args->msa->mp, callout_num, slot,\r
1427 type, val);\r
1428}\r
1429\r
1430extern int\r
1431onig_set_callout_data_by_callout_args_self(OnigCalloutArgs* args,\r
1432 int slot, OnigType type, OnigValue* val)\r
1433{\r
1434 return onig_set_callout_data(args->regex, args->msa->mp, args->num, slot,\r
1435 type, val);\r
1436}\r
1437\r
1438#else\r
1439#define ADJUST_MATCH_PARAM(reg, mp)\r
1440#endif /* USE_CALLOUT */\r
1441\r
1442\r
1443static int\r
1444stack_double(int is_alloca, char** arg_alloc_base,\r
1445 StackType** arg_stk_base, StackType** arg_stk_end, StackType** arg_stk,\r
1446 MatchArg* msa)\r
1447{\r
1448 unsigned int n;\r
1449 int used;\r
1450 size_t size;\r
1451 size_t new_size;\r
1452 char* alloc_base;\r
1453 char* new_alloc_base;\r
1454 StackType *stk_base, *stk_end, *stk;\r
1455\r
1456 alloc_base = *arg_alloc_base;\r
1457 stk_base = *arg_stk_base;\r
1458 stk_end = *arg_stk_end;\r
1459 stk = *arg_stk;\r
1460\r
1461 n = (unsigned int )(stk_end - stk_base);\r
1462 size = sizeof(StackIndex) * msa->ptr_num + sizeof(StackType) * n;\r
1463 n *= 2;\r
1464 new_size = sizeof(StackIndex) * msa->ptr_num + sizeof(StackType) * n;\r
1465 if (is_alloca != 0) {\r
1466 new_alloc_base = (char* )xmalloc(new_size);\r
1467 if (IS_NULL(new_alloc_base)) {\r
1468 STACK_SAVE;\r
1469 return ONIGERR_MEMORY;\r
1470 }\r
1471 xmemcpy(new_alloc_base, alloc_base, size);\r
1472 }\r
1473 else {\r
1474 if (msa->match_stack_limit != 0 && n > msa->match_stack_limit) {\r
1475 if ((unsigned int )(stk_end - stk_base) == msa->match_stack_limit)\r
1476 return ONIGERR_MATCH_STACK_LIMIT_OVER;\r
1477 else\r
1478 n = msa->match_stack_limit;\r
1479 }\r
1480 new_alloc_base = (char* )xrealloc(alloc_base, new_size, size);\r
1481 if (IS_NULL(new_alloc_base)) {\r
1482 STACK_SAVE;\r
1483 return ONIGERR_MEMORY;\r
1484 }\r
1485 }\r
1486\r
1487 alloc_base = new_alloc_base;\r
1488 used = (int )(stk - stk_base);\r
1489 *arg_alloc_base = alloc_base;\r
1490 *arg_stk_base = (StackType* )(alloc_base\r
1491 + (sizeof(StackIndex) * msa->ptr_num));\r
1492 *arg_stk = *arg_stk_base + used;\r
1493 *arg_stk_end = *arg_stk_base + n;\r
1494 return 0;\r
1495}\r
14b0e578 1496\r
b602265d
DG
1497#define STACK_ENSURE(n) do {\\r
1498 if ((int )(stk_end - stk) < (n)) {\\r
1499 int r = stack_double(is_alloca, &alloc_base, &stk_base, &stk_end, &stk, msa);\\r
1500 if (r != 0) { STACK_SAVE; return r; } \\r
1501 is_alloca = 0;\\r
1502 UPDATE_FOR_STACK_REALLOC;\\r
14b0e578
CS
1503 }\\r
1504} while(0)\r
1505\r
b602265d
DG
1506#define STACK_AT(index) (stk_base + (index))\r
1507#define GET_STACK_INDEX(stk) ((stk) - stk_base)\r
1508\r
1509#define STACK_PUSH_TYPE(stack_type) do {\\r
1510 STACK_ENSURE(1);\\r
1511 stk->type = (stack_type);\\r
1512 STACK_INC;\\r
1513} while(0)\r
14b0e578 1514\r
b602265d 1515#define IS_TO_VOID_TARGET(stk) (((stk)->type & STK_MASK_TO_VOID_TARGET) != 0)\r
14b0e578
CS
1516\r
1517#define STACK_PUSH(stack_type,pat,s,sprev) do {\\r
1518 STACK_ENSURE(1);\\r
1519 stk->type = (stack_type);\\r
1520 stk->u.state.pcode = (pat);\\r
1521 stk->u.state.pstr = (s);\\r
1522 stk->u.state.pstr_prev = (sprev);\\r
1523 STACK_INC;\\r
1524} while(0)\r
1525\r
1526#define STACK_PUSH_ENSURED(stack_type,pat) do {\\r
1527 stk->type = (stack_type);\\r
1528 stk->u.state.pcode = (pat);\\r
1529 STACK_INC;\\r
1530} while(0)\r
14b0e578 1531\r
b602265d
DG
1532#ifdef ONIG_DEBUG_MATCH\r
1533#define STACK_PUSH_BOTTOM(stack_type,pat) do {\\r
1534 stk->type = (stack_type);\\r
1535 stk->u.state.pcode = (pat);\\r
1536 stk->u.state.pstr = s;\\r
1537 stk->u.state.pstr_prev = sprev;\\r
1538 STACK_INC;\\r
1539} while (0)\r
1540#else\r
1541#define STACK_PUSH_BOTTOM(stack_type,pat) do {\\r
1542 stk->type = (stack_type);\\r
1543 stk->u.state.pcode = (pat);\\r
1544 STACK_INC;\\r
1545} while (0)\r
1546#endif\r
14b0e578 1547\r
b602265d
DG
1548#define STACK_PUSH_ALT(pat,s,sprev) STACK_PUSH(STK_ALT,pat,s,sprev)\r
1549#define STACK_PUSH_SUPER_ALT(pat,s,sprev) STACK_PUSH(STK_SUPER_ALT,pat,s,sprev)\r
b26691c4
LG
1550#define STACK_PUSH_PREC_READ_START(s,sprev) \\r
1551 STACK_PUSH(STK_PREC_READ_START,(Operation* )0,s,sprev)\r
b602265d
DG
1552#define STACK_PUSH_ALT_PREC_READ_NOT(pat,s,sprev) \\r
1553 STACK_PUSH(STK_ALT_PREC_READ_NOT,pat,s,sprev)\r
1554#define STACK_PUSH_TO_VOID_START STACK_PUSH_TYPE(STK_TO_VOID_START)\r
1555#define STACK_PUSH_ALT_LOOK_BEHIND_NOT(pat,s,sprev) \\r
1556 STACK_PUSH(STK_ALT_LOOK_BEHIND_NOT,pat,s,sprev)\r
1557\r
1558#define STACK_PUSH_REPEAT(sid, pat) do {\\r
14b0e578
CS
1559 STACK_ENSURE(1);\\r
1560 stk->type = STK_REPEAT;\\r
b602265d 1561 stk->zid = (sid);\\r
14b0e578
CS
1562 stk->u.repeat.pcode = (pat);\\r
1563 stk->u.repeat.count = 0;\\r
1564 STACK_INC;\\r
1565} while(0)\r
1566\r
1567#define STACK_PUSH_REPEAT_INC(sindex) do {\\r
1568 STACK_ENSURE(1);\\r
1569 stk->type = STK_REPEAT_INC;\\r
1570 stk->u.repeat_inc.si = (sindex);\\r
1571 STACK_INC;\\r
1572} while(0)\r
1573\r
1574#define STACK_PUSH_MEM_START(mnum, s) do {\\r
1575 STACK_ENSURE(1);\\r
1576 stk->type = STK_MEM_START;\\r
b602265d
DG
1577 stk->zid = (mnum);\\r
1578 stk->u.mem.pstr = (s);\\r
1579 stk->u.mem.prev_start = mem_start_stk[mnum];\\r
1580 stk->u.mem.prev_end = mem_end_stk[mnum];\\r
1581 mem_start_stk[mnum] = GET_STACK_INDEX(stk);\\r
1582 mem_end_stk[mnum] = INVALID_STACK_INDEX;\\r
14b0e578
CS
1583 STACK_INC;\\r
1584} while(0)\r
1585\r
1586#define STACK_PUSH_MEM_END(mnum, s) do {\\r
1587 STACK_ENSURE(1);\\r
1588 stk->type = STK_MEM_END;\\r
b602265d
DG
1589 stk->zid = (mnum);\\r
1590 stk->u.mem.pstr = (s);\\r
1591 stk->u.mem.prev_start = mem_start_stk[mnum];\\r
1592 stk->u.mem.prev_end = mem_end_stk[mnum];\\r
14b0e578
CS
1593 mem_end_stk[mnum] = GET_STACK_INDEX(stk);\\r
1594 STACK_INC;\\r
1595} while(0)\r
1596\r
1597#define STACK_PUSH_MEM_END_MARK(mnum) do {\\r
1598 STACK_ENSURE(1);\\r
1599 stk->type = STK_MEM_END_MARK;\\r
b602265d 1600 stk->zid = (mnum);\\r
14b0e578
CS
1601 STACK_INC;\\r
1602} while(0)\r
1603\r
1604#define STACK_GET_MEM_START(mnum, k) do {\\r
1605 int level = 0;\\r
1606 k = stk;\\r
1607 while (k > stk_base) {\\r
1608 k--;\\r
1609 if ((k->type & STK_MASK_MEM_END_OR_MARK) != 0 \\r
b602265d 1610 && k->zid == (mnum)) {\\r
14b0e578
CS
1611 level++;\\r
1612 }\\r
b602265d 1613 else if (k->type == STK_MEM_START && k->zid == (mnum)) {\\r
14b0e578
CS
1614 if (level == 0) break;\\r
1615 level--;\\r
1616 }\\r
1617 }\\r
1618} while(0)\r
1619\r
1620#define STACK_GET_MEM_RANGE(k, mnum, start, end) do {\\r
1621 int level = 0;\\r
1622 while (k < stk) {\\r
1623 if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\\r
1624 if (level == 0) (start) = k->u.mem.pstr;\\r
1625 level++;\\r
1626 }\\r
1627 else if (k->type == STK_MEM_END && k->u.mem.num == (mnum)) {\\r
1628 level--;\\r
1629 if (level == 0) {\\r
1630 (end) = k->u.mem.pstr;\\r
1631 break;\\r
1632 }\\r
1633 }\\r
1634 k++;\\r
1635 }\\r
1636} while(0)\r
1637\r
b602265d 1638#define STACK_PUSH_EMPTY_CHECK_START(cnum, s) do {\\r
14b0e578 1639 STACK_ENSURE(1);\\r
b602265d
DG
1640 stk->type = STK_EMPTY_CHECK_START;\\r
1641 stk->zid = (cnum);\\r
1642 stk->u.empty_check.pstr = (s);\\r
14b0e578
CS
1643 STACK_INC;\\r
1644} while(0)\r
1645\r
b602265d 1646#define STACK_PUSH_EMPTY_CHECK_END(cnum) do {\\r
14b0e578 1647 STACK_ENSURE(1);\\r
b602265d
DG
1648 stk->type = STK_EMPTY_CHECK_END;\\r
1649 stk->zid = (cnum);\\r
14b0e578
CS
1650 STACK_INC;\\r
1651} while(0)\r
1652\r
1653#define STACK_PUSH_CALL_FRAME(pat) do {\\r
1654 STACK_ENSURE(1);\\r
1655 stk->type = STK_CALL_FRAME;\\r
1656 stk->u.call_frame.ret_addr = (pat);\\r
1657 STACK_INC;\\r
1658} while(0)\r
1659\r
1660#define STACK_PUSH_RETURN do {\\r
1661 STACK_ENSURE(1);\\r
1662 stk->type = STK_RETURN;\\r
1663 STACK_INC;\\r
1664} while(0)\r
1665\r
b602265d
DG
1666#define STACK_PUSH_SAVE_VAL(sid, stype, sval) do {\\r
1667 STACK_ENSURE(1);\\r
1668 stk->type = STK_SAVE_VAL;\\r
1669 stk->zid = (sid);\\r
1670 stk->u.val.type = (stype);\\r
1671 stk->u.val.v = (UChar* )(sval);\\r
1672 STACK_INC;\\r
1673} while(0)\r
1674\r
1675#define STACK_PUSH_SAVE_VAL_WITH_SPREV(sid, stype, sval) do {\\r
1676 STACK_ENSURE(1);\\r
1677 stk->type = STK_SAVE_VAL;\\r
1678 stk->zid = (sid);\\r
1679 stk->u.val.type = (stype);\\r
1680 stk->u.val.v = (UChar* )(sval);\\r
1681 stk->u.val.v2 = sprev;\\r
1682 STACK_INC;\\r
1683} while(0)\r
1684\r
1685#define STACK_GET_SAVE_VAL_TYPE_LAST(stype, sval) do {\\r
1686 StackType *k = stk;\\r
1687 while (k > stk_base) {\\r
1688 k--;\\r
1689 STACK_BASE_CHECK(k, "STACK_GET_SAVE_VAL_TYPE_LAST"); \\r
1690 if (k->type == STK_SAVE_VAL && k->u.val.type == (stype)) {\\r
1691 (sval) = k->u.val.v;\\r
1692 break;\\r
1693 }\\r
1694 }\\r
1695} while (0)\r
1696\r
1697#define STACK_GET_SAVE_VAL_TYPE_LAST_ID(stype, sid, sval) do { \\r
1698 int level = 0;\\r
1699 StackType *k = stk;\\r
1700 while (k > stk_base) {\\r
1701 k--;\\r
1702 STACK_BASE_CHECK(k, "STACK_GET_SAVE_VAL_TYPE_LAST_ID"); \\r
1703 if (k->type == STK_SAVE_VAL && k->u.val.type == (stype)\\r
1704 && k->zid == (sid)) {\\r
1705 if (level == 0) {\\r
1706 (sval) = k->u.val.v;\\r
1707 break;\\r
1708 }\\r
1709 }\\r
1710 else if (k->type == STK_CALL_FRAME)\\r
1711 level--;\\r
1712 else if (k->type == STK_RETURN)\\r
1713 level++;\\r
1714 }\\r
1715} while (0)\r
1716\r
1717#define STACK_GET_SAVE_VAL_TYPE_LAST_ID_WITH_SPREV(stype, sid, sval) do { \\r
1718 int level = 0;\\r
1719 StackType *k = stk;\\r
1720 while (k > stk_base) {\\r
1721 k--;\\r
1722 STACK_BASE_CHECK(k, "STACK_GET_SAVE_VAL_TYPE_LAST_ID"); \\r
1723 if (k->type == STK_SAVE_VAL && k->u.val.type == (stype)\\r
1724 && k->zid == (sid)) {\\r
1725 if (level == 0) {\\r
1726 (sval) = k->u.val.v;\\r
1727 sprev = k->u.val.v2;\\r
1728 break;\\r
1729 }\\r
1730 }\\r
1731 else if (k->type == STK_CALL_FRAME)\\r
1732 level--;\\r
1733 else if (k->type == STK_RETURN)\\r
1734 level++;\\r
1735 }\\r
1736} while (0)\r
1737\r
1738#define STACK_GET_SAVE_VAL_TYPE_LAST_ID_FROM(stype, sid, sval, stk_from) do { \\r
1739 int level = 0;\\r
1740 StackType *k = (stk_from);\\r
1741 while (k > stk_base) {\\r
1742 STACK_BASE_CHECK(k, "STACK_GET_SAVE_VAL_TYPE_LAST_ID_FROM"); \\r
1743 if (k->type == STK_SAVE_VAL && k->u.val.type == (stype)\\r
1744 && k->u.val.id == (sid)) {\\r
1745 if (level == 0) {\\r
1746 (sval) = k->u.val.v;\\r
1747 break;\\r
1748 }\\r
1749 }\\r
1750 else if (k->type == STK_CALL_FRAME)\\r
1751 level--;\\r
1752 else if (k->type == STK_RETURN)\\r
1753 level++;\\r
1754 k--;\\r
1755 }\\r
1756} while (0)\r
1757\r
1758#define STACK_PUSH_CALLOUT_CONTENTS(anum, func) do {\\r
1759 STACK_ENSURE(1);\\r
1760 stk->type = STK_CALLOUT;\\r
1761 stk->zid = ONIG_NON_NAME_ID;\\r
1762 stk->u.callout.num = (anum);\\r
1763 stk->u.callout.func = (func);\\r
1764 STACK_INC;\\r
1765} while(0)\r
1766\r
1767#define STACK_PUSH_CALLOUT_NAME(aid, anum, func) do {\\r
1768 STACK_ENSURE(1);\\r
1769 stk->type = STK_CALLOUT;\\r
1770 stk->zid = (aid);\\r
1771 stk->u.callout.num = (anum);\\r
1772 stk->u.callout.func = (func);\\r
1773 STACK_INC;\\r
1774} while(0)\r
14b0e578
CS
1775\r
1776#ifdef ONIG_DEBUG\r
1777#define STACK_BASE_CHECK(p, at) \\r
1778 if ((p) < stk_base) {\\r
1779 fprintf(stderr, "at %s\n", at);\\r
1780 goto stack_error;\\r
1781 }\r
1782#else\r
1783#define STACK_BASE_CHECK(p, at)\r
1784#endif\r
1785\r
1786#define STACK_POP_ONE do {\\r
1787 stk--;\\r
1788 STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \\r
1789} while(0)\r
1790\r
b602265d
DG
1791\r
1792#ifdef USE_CALLOUT\r
1793#define POP_CALLOUT_CASE \\r
1794 else if (stk->type == STK_CALLOUT) {\\r
1795 RETRACTION_CALLOUT(stk->u.callout.func, stk->zid, stk->u.callout.num, msa->mp->callout_user_data);\\r
1796 }\r
1797#else\r
1798#define POP_CALLOUT_CASE\r
1799#endif\r
1800\r
14b0e578
CS
1801#define STACK_POP do {\\r
1802 switch (pop_level) {\\r
1803 case STACK_POP_LEVEL_FREE:\\r
1804 while (1) {\\r
1805 stk--;\\r
1806 STACK_BASE_CHECK(stk, "STACK_POP"); \\r
1807 if ((stk->type & STK_MASK_POP_USED) != 0) break;\\r
14b0e578
CS
1808 }\\r
1809 break;\\r
1810 case STACK_POP_LEVEL_MEM_START:\\r
1811 while (1) {\\r
1812 stk--;\\r
1813 STACK_BASE_CHECK(stk, "STACK_POP 2"); \\r
1814 if ((stk->type & STK_MASK_POP_USED) != 0) break;\\r
1815 else if (stk->type == STK_MEM_START) {\\r
b602265d
DG
1816 mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
1817 mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
14b0e578 1818 }\\r
14b0e578
CS
1819 }\\r
1820 break;\\r
1821 default:\\r
1822 while (1) {\\r
1823 stk--;\\r
1824 STACK_BASE_CHECK(stk, "STACK_POP 3"); \\r
1825 if ((stk->type & STK_MASK_POP_USED) != 0) break;\\r
b602265d
DG
1826 else if ((stk->type & STK_MASK_POP_HANDLED) != 0) {\\r
1827 if (stk->type == STK_MEM_START) {\\r
1828 mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
1829 mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
1830 }\\r
1831 else if (stk->type == STK_REPEAT_INC) {\\r
1832 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\\r
1833 }\\r
1834 else if (stk->type == STK_MEM_END) {\\r
1835 mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
1836 mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
1837 }\\r
1838 POP_CALLOUT_CASE\\r
14b0e578 1839 }\\r
14b0e578
CS
1840 }\\r
1841 break;\\r
1842 }\\r
1843} while(0)\r
1844\r
b602265d 1845#define POP_TIL_BODY(aname, til_type) do {\\r
14b0e578
CS
1846 while (1) {\\r
1847 stk--;\\r
b602265d
DG
1848 STACK_BASE_CHECK(stk, (aname));\\r
1849 if ((stk->type & STK_MASK_POP_HANDLED_TIL) != 0) {\\r
1850 if (stk->type == (til_type)) break;\\r
1851 else {\\r
1852 if (stk->type == STK_MEM_START) {\\r
1853 mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
1854 mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
1855 }\\r
1856 else if (stk->type == STK_REPEAT_INC) {\\r
1857 STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\\r
1858 }\\r
1859 else if (stk->type == STK_MEM_END) {\\r
1860 mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
1861 mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
1862 }\\r
1863 /* Don't call callout here because negation of total success by (?!..) (?<!..) */\\r
1864 }\\r
14b0e578 1865 }\\r
14b0e578
CS
1866 }\\r
1867} while(0)\r
1868\r
b602265d
DG
1869#define STACK_POP_TIL_ALT_PREC_READ_NOT do {\\r
1870 POP_TIL_BODY("STACK_POP_TIL_ALT_PREC_READ_NOT", STK_ALT_PREC_READ_NOT);\\r
14b0e578
CS
1871} while(0)\r
1872\r
b602265d
DG
1873#define STACK_POP_TIL_ALT_LOOK_BEHIND_NOT do {\\r
1874 POP_TIL_BODY("STACK_POP_TIL_ALT_LOOK_BEHIND_NOT", STK_ALT_LOOK_BEHIND_NOT);\\r
14b0e578
CS
1875} while(0)\r
1876\r
b602265d
DG
1877\r
1878#define STACK_EXEC_TO_VOID(k) do {\\r
1879 k = stk;\\r
14b0e578
CS
1880 while (1) {\\r
1881 k--;\\r
b602265d 1882 STACK_BASE_CHECK(k, "STACK_EXEC_TO_VOID"); \\r
14b0e578 1883 if (IS_TO_VOID_TARGET(k)) {\\r
b602265d
DG
1884 if (k->type == STK_TO_VOID_START) {\\r
1885 k->type = STK_VOID;\\r
1886 break;\\r
1887 }\\r
14b0e578
CS
1888 k->type = STK_VOID;\\r
1889 }\\r
14b0e578
CS
1890 }\\r
1891} while(0)\r
1892\r
b26691c4
LG
1893#define STACK_GET_PREC_READ_START(k) do {\\r
1894 int level = 0;\\r
1895 k = stk;\\r
1896 while (1) {\\r
1897 k--;\\r
1898 STACK_BASE_CHECK(k, "STACK_GET_PREC_READ_START");\\r
1899 if (IS_TO_VOID_TARGET(k)) {\\r
1900 k->type = STK_VOID;\\r
1901 }\\r
1902 else if (k->type == STK_PREC_READ_START) {\\r
1903 if (level == 0) {\\r
1904 break;\\r
1905 }\\r
1906 level--;\\r
1907 }\\r
1908 else if (k->type == STK_PREC_READ_END) {\\r
1909 level++;\\r
1910 }\\r
1911 }\\r
1912} while(0)\r
1913\r
b602265d
DG
1914#define STACK_EMPTY_CHECK(isnull,sid,s) do {\\r
1915 StackType* k = stk;\\r
14b0e578
CS
1916 while (1) {\\r
1917 k--;\\r
b602265d
DG
1918 STACK_BASE_CHECK(k, "STACK_EMPTY_CHECK"); \\r
1919 if (k->type == STK_EMPTY_CHECK_START) {\\r
1920 if (k->zid == (sid)) {\\r
1921 (isnull) = (k->u.empty_check.pstr == (s));\\r
14b0e578
CS
1922 break;\\r
1923 }\\r
1924 }\\r
1925 }\\r
1926} while(0)\r
1927\r
b602265d
DG
1928#define STACK_MEM_START_GET_PREV_END_ADDR(k /* STK_MEM_START*/, reg, addr) do {\\r
1929 if (k->u.mem.prev_end == INVALID_STACK_INDEX) {\\r
1930 (addr) = 0;\\r
14b0e578 1931 }\\r
b602265d
DG
1932 else {\\r
1933 if (MEM_STATUS_AT((reg)->bt_mem_end, k->zid))\\r
1934 (addr) = STACK_AT(k->u.mem.prev_end)->u.mem.pstr;\\r
1935 else\\r
1936 (addr) = (UChar* )k->u.mem.prev_end;\\r
1937 }\\r
1938} while (0)\r
14b0e578 1939\r
b26691c4 1940#ifdef USE_STUBBORN_CHECK_CAPTURES_IN_EMPTY_REPEAT\r
b602265d
DG
1941#define STACK_EMPTY_CHECK_MEM(isnull,sid,s,reg) do {\\r
1942 StackType* k = stk;\\r
14b0e578
CS
1943 while (1) {\\r
1944 k--;\\r
b602265d
DG
1945 STACK_BASE_CHECK(k, "STACK_EMPTY_CHECK_MEM"); \\r
1946 if (k->type == STK_EMPTY_CHECK_START) {\\r
1947 if (k->zid == (sid)) {\\r
1948 if (k->u.empty_check.pstr != (s)) {\\r
14b0e578
CS
1949 (isnull) = 0;\\r
1950 break;\\r
1951 }\\r
1952 else {\\r
1953 UChar* endp;\\r
b26691c4 1954 int level = 0;\\r
14b0e578
CS
1955 (isnull) = 1;\\r
1956 while (k < stk) {\\r
b26691c4 1957 if (k->type == STK_MEM_START && level == 0) {\\r
b602265d
DG
1958 STACK_MEM_START_GET_PREV_END_ADDR(k, reg, endp);\\r
1959 if (endp == 0) {\\r
14b0e578
CS
1960 (isnull) = 0; break;\\r
1961 }\\r
b602265d 1962 else if (STACK_AT(k->u.mem.prev_start)->u.mem.pstr != endp) {\\r
14b0e578
CS
1963 (isnull) = 0; break;\\r
1964 }\\r
1965 else if (endp != s) {\\r
1966 (isnull) = -1; /* empty, but position changed */ \\r
1967 }\\r
1968 }\\r
b26691c4
LG
1969 else if (k->type == STK_PREC_READ_START) {\\r
1970 level++;\\r
1971 }\\r
1972 else if (k->type == STK_PREC_READ_END) {\\r
1973 level--;\\r
1974 }\\r
14b0e578
CS
1975 k++;\\r
1976 }\\r
b602265d 1977 break;\\r
14b0e578
CS
1978 }\\r
1979 }\\r
1980 }\\r
1981 }\\r
1982} while(0)\r
1983\r
b602265d 1984#define STACK_EMPTY_CHECK_MEM_REC(isnull,sid,s,reg) do {\\r
14b0e578 1985 int level = 0;\\r
b602265d 1986 StackType* k = stk;\\r
14b0e578
CS
1987 while (1) {\\r
1988 k--;\\r
b602265d
DG
1989 STACK_BASE_CHECK(k, "STACK_EMPTY_CHECK_MEM_REC");\\r
1990 if (k->type == STK_EMPTY_CHECK_START) {\\r
1991 if (k->zid == (sid)) {\\r
14b0e578 1992 if (level == 0) {\\r
b602265d 1993 if (k->u.empty_check.pstr != (s)) {\\r
14b0e578
CS
1994 (isnull) = 0;\\r
1995 break;\\r
1996 }\\r
1997 else {\\r
1998 UChar* endp;\\r
b26691c4 1999 int prec_level = 0;\\r
14b0e578
CS
2000 (isnull) = 1;\\r
2001 while (k < stk) {\\r
2002 if (k->type == STK_MEM_START) {\\r
b26691c4 2003 if (level == 0 && prec_level == 0) {\\r
b602265d
DG
2004 STACK_MEM_START_GET_PREV_END_ADDR(k, reg, endp);\\r
2005 if (endp == 0) {\\r
2006 (isnull) = 0; break;\\r
2007 }\\r
2008 else if (STACK_AT(k->u.mem.prev_start)->u.mem.pstr != endp) { \\r
2009 (isnull) = 0; break;\\r
2010 }\\r
2011 else if (endp != s) {\\r
2012 (isnull) = -1; /* empty, but position changed */\\r
2013 }\\r
14b0e578
CS
2014 }\\r
2015 }\\r
b602265d
DG
2016 else if (k->type == STK_EMPTY_CHECK_START) {\\r
2017 if (k->zid == (sid)) level++;\\r
2018 }\\r
2019 else if (k->type == STK_EMPTY_CHECK_END) {\\r
2020 if (k->zid == (sid)) level--;\\r
2021 }\\r
b26691c4
LG
2022 else if (k->type == STK_PREC_READ_START) {\\r
2023 prec_level++;\\r
2024 }\\r
2025 else if (k->type == STK_PREC_READ_END) {\\r
2026 prec_level--;\\r
2027 }\\r
14b0e578
CS
2028 k++;\\r
2029 }\\r
b602265d 2030 break;\\r
14b0e578
CS
2031 }\\r
2032 }\\r
2033 else {\\r
2034 level--;\\r
2035 }\\r
2036 }\\r
2037 }\\r
b602265d
DG
2038 else if (k->type == STK_EMPTY_CHECK_END) {\\r
2039 if (k->zid == (sid)) level++;\\r
2040 }\\r
2041 }\\r
2042} while(0)\r
2043#else\r
2044#define STACK_EMPTY_CHECK_REC(isnull,id,s) do {\\r
2045 int level = 0;\\r
2046 StackType* k = stk;\\r
2047 while (1) {\\r
2048 k--;\\r
2049 STACK_BASE_CHECK(k, "STACK_EMPTY_CHECK_REC"); \\r
2050 if (k->type == STK_EMPTY_CHECK_START) {\\r
2051 if (k->u.empty_check.num == (id)) {\\r
2052 if (level == 0) {\\r
2053 (isnull) = (k->u.empty_check.pstr == (s));\\r
2054 break;\\r
2055 }\\r
2056 }\\r
2057 level--;\\r
2058 }\\r
2059 else if (k->type == STK_EMPTY_CHECK_END) {\\r
2060 level++;\\r
14b0e578
CS
2061 }\\r
2062 }\\r
2063} while(0)\r
b26691c4 2064#endif /* USE_STUBBORN_CHECK_CAPTURES_IN_EMPTY_REPEAT */\r
14b0e578 2065\r
b602265d 2066#define STACK_GET_REPEAT(sid, k) do {\\r
14b0e578
CS
2067 int level = 0;\\r
2068 k = stk;\\r
2069 while (1) {\\r
2070 k--;\\r
2071 STACK_BASE_CHECK(k, "STACK_GET_REPEAT"); \\r
2072 if (k->type == STK_REPEAT) {\\r
2073 if (level == 0) {\\r
b602265d 2074 if (k->zid == (sid)) {\\r
14b0e578
CS
2075 break;\\r
2076 }\\r
2077 }\\r
2078 }\\r
2079 else if (k->type == STK_CALL_FRAME) level--;\\r
2080 else if (k->type == STK_RETURN) level++;\\r
2081 }\\r
2082} while(0)\r
2083\r
2084#define STACK_RETURN(addr) do {\\r
2085 int level = 0;\\r
b602265d 2086 StackType* k = stk;\\r
14b0e578
CS
2087 while (1) {\\r
2088 k--;\\r
2089 STACK_BASE_CHECK(k, "STACK_RETURN"); \\r
2090 if (k->type == STK_CALL_FRAME) {\\r
2091 if (level == 0) {\\r
2092 (addr) = k->u.call_frame.ret_addr;\\r
2093 break;\\r
2094 }\\r
2095 else level--;\\r
2096 }\\r
2097 else if (k->type == STK_RETURN)\\r
2098 level++;\\r
2099 }\\r
2100} while(0)\r
2101\r
2102\r
2103#define STRING_CMP(s1,s2,len) do {\\r
2104 while (len-- > 0) {\\r
2105 if (*s1++ != *s2++) goto fail;\\r
2106 }\\r
2107} while(0)\r
2108\r
2109#define STRING_CMP_IC(case_fold_flag,s1,ps2,len) do {\\r
2110 if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len) == 0) \\r
2111 goto fail; \\r
2112} while(0)\r
2113\r
2114static int string_cmp_ic(OnigEncoding enc, int case_fold_flag,\r
b602265d 2115 UChar* s1, UChar** ps2, int mblen)\r
14b0e578
CS
2116{\r
2117 UChar buf1[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
2118 UChar buf2[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
2119 UChar *p1, *p2, *end1, *s2, *end2;\r
2120 int len1, len2;\r
2121\r
2122 s2 = *ps2;\r
2123 end1 = s1 + mblen;\r
2124 end2 = s2 + mblen;\r
2125 while (s1 < end1) {\r
2126 len1 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s1, end1, buf1);\r
2127 len2 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s2, end2, buf2);\r
2128 if (len1 != len2) return 0;\r
2129 p1 = buf1;\r
2130 p2 = buf2;\r
2131 while (len1-- > 0) {\r
2132 if (*p1 != *p2) return 0;\r
2133 p1++;\r
2134 p2++;\r
2135 }\r
2136 }\r
2137\r
2138 *ps2 = s2;\r
2139 return 1;\r
2140}\r
2141\r
2142#define STRING_CMP_VALUE(s1,s2,len,is_fail) do {\\r
2143 is_fail = 0;\\r
2144 while (len-- > 0) {\\r
2145 if (*s1++ != *s2++) {\\r
2146 is_fail = 1; break;\\r
2147 }\\r
2148 }\\r
2149} while(0)\r
2150\r
2151#define STRING_CMP_VALUE_IC(case_fold_flag,s1,ps2,len,is_fail) do {\\r
2152 if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len) == 0) \\r
2153 is_fail = 1; \\r
2154 else \\r
2155 is_fail = 0; \\r
2156} while(0)\r
2157\r
2158\r
2159#define IS_EMPTY_STR (str == end)\r
b602265d
DG
2160#define ON_STR_BEGIN(s) ((s) == str)\r
2161#define ON_STR_END(s) ((s) == end)\r
14b0e578
CS
2162#define DATA_ENSURE_CHECK1 (s < right_range)\r
2163#define DATA_ENSURE_CHECK(n) (s + (n) <= right_range)\r
2164#define DATA_ENSURE(n) if (s + (n) > right_range) goto fail\r
14b0e578 2165\r
b602265d 2166#define INIT_RIGHT_RANGE right_range = (UChar* )in_right_range\r
14b0e578
CS
2167\r
2168#ifdef USE_CAPTURE_HISTORY\r
2169static int\r
b602265d
DG
2170make_capture_history_tree(OnigCaptureTreeNode* node, StackType** kp,\r
2171 StackType* stk_top, UChar* str, regex_t* reg)\r
14b0e578
CS
2172{\r
2173 int n, r;\r
2174 OnigCaptureTreeNode* child;\r
b602265d 2175 StackType* k = *kp;\r
14b0e578
CS
2176\r
2177 while (k < stk_top) {\r
2178 if (k->type == STK_MEM_START) {\r
b602265d 2179 n = k->zid;\r
14b0e578 2180 if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP &&\r
b602265d 2181 MEM_STATUS_AT(reg->capture_history, n) != 0) {\r
14b0e578
CS
2182 child = history_node_new();\r
2183 CHECK_NULL_RETURN_MEMERR(child);\r
2184 child->group = n;\r
2185 child->beg = (int )(k->u.mem.pstr - str);\r
2186 r = history_tree_add_child(node, child);\r
2187 if (r != 0) return r;\r
2188 *kp = (k + 1);\r
2189 r = make_capture_history_tree(child, kp, stk_top, str, reg);\r
2190 if (r != 0) return r;\r
2191\r
2192 k = *kp;\r
2193 child->end = (int )(k->u.mem.pstr - str);\r
2194 }\r
2195 }\r
2196 else if (k->type == STK_MEM_END) {\r
b602265d 2197 if (k->zid == node->group) {\r
14b0e578
CS
2198 node->end = (int )(k->u.mem.pstr - str);\r
2199 *kp = k;\r
2200 return 0;\r
2201 }\r
2202 }\r
2203 k++;\r
2204 }\r
2205\r
2206 return 1; /* 1: root node ending. */\r
2207}\r
2208#endif\r
2209\r
2210#ifdef USE_BACKREF_WITH_LEVEL\r
b26691c4 2211static int mem_is_in_memp(int mem, int num, MemNumType* memp)\r
14b0e578
CS
2212{\r
2213 int i;\r
14b0e578
CS
2214\r
2215 for (i = 0; i < num; i++) {\r
b26691c4 2216 if (mem == (int )memp[i]) return 1;\r
14b0e578
CS
2217 }\r
2218 return 0;\r
2219}\r
2220\r
b602265d
DG
2221static int\r
2222backref_match_at_nested_level(regex_t* reg,\r
2223 StackType* top, StackType* stk_base,\r
2224 int ignore_case, int case_fold_flag,\r
b26691c4 2225 int nest, int mem_num, MemNumType* memp,\r
b602265d 2226 UChar** s, const UChar* send)\r
14b0e578
CS
2227{\r
2228 UChar *ss, *p, *pstart, *pend = NULL_UCHARP;\r
2229 int level;\r
b602265d 2230 StackType* k;\r
14b0e578
CS
2231\r
2232 level = 0;\r
2233 k = top;\r
2234 k--;\r
2235 while (k >= stk_base) {\r
2236 if (k->type == STK_CALL_FRAME) {\r
2237 level--;\r
2238 }\r
2239 else if (k->type == STK_RETURN) {\r
2240 level++;\r
2241 }\r
2242 else if (level == nest) {\r
2243 if (k->type == STK_MEM_START) {\r
b602265d
DG
2244 if (mem_is_in_memp(k->zid, mem_num, memp)) {\r
2245 pstart = k->u.mem.pstr;\r
2246 if (IS_NOT_NULL(pend)) {\r
2247 if (pend - pstart > send - *s) return 0; /* or goto next_mem; */\r
2248 p = pstart;\r
2249 ss = *s;\r
2250\r
2251 if (ignore_case != 0) {\r
2252 if (string_cmp_ic(reg->enc, case_fold_flag,\r
2253 pstart, &ss, (int )(pend - pstart)) == 0)\r
2254 return 0; /* or goto next_mem; */\r
2255 }\r
2256 else {\r
2257 while (p < pend) {\r
2258 if (*p++ != *ss++) return 0; /* or goto next_mem; */\r
2259 }\r
2260 }\r
2261\r
2262 *s = ss;\r
2263 return 1;\r
2264 }\r
2265 }\r
14b0e578
CS
2266 }\r
2267 else if (k->type == STK_MEM_END) {\r
b602265d
DG
2268 if (mem_is_in_memp(k->zid, mem_num, memp)) {\r
2269 pend = k->u.mem.pstr;\r
2270 }\r
2271 }\r
2272 }\r
2273 k--;\r
2274 }\r
2275\r
2276 return 0;\r
2277}\r
2278\r
2279static int\r
2280backref_check_at_nested_level(regex_t* reg,\r
2281 StackType* top, StackType* stk_base,\r
b26691c4 2282 int nest, int mem_num, MemNumType* memp)\r
b602265d
DG
2283{\r
2284 int level;\r
2285 StackType* k;\r
2286\r
2287 level = 0;\r
2288 k = top;\r
2289 k--;\r
2290 while (k >= stk_base) {\r
2291 if (k->type == STK_CALL_FRAME) {\r
2292 level--;\r
2293 }\r
2294 else if (k->type == STK_RETURN) {\r
2295 level++;\r
2296 }\r
2297 else if (level == nest) {\r
2298 if (k->type == STK_MEM_END) {\r
2299 if (mem_is_in_memp(k->zid, mem_num, memp)) {\r
2300 return 1;\r
2301 }\r
14b0e578
CS
2302 }\r
2303 }\r
2304 k--;\r
2305 }\r
2306\r
2307 return 0;\r
2308}\r
2309#endif /* USE_BACKREF_WITH_LEVEL */\r
2310\r
2311\r
2312#ifdef ONIG_DEBUG_STATISTICS\r
2313\r
2314#define USE_TIMEOFDAY\r
2315\r
2316#ifdef USE_TIMEOFDAY\r
2317#ifdef HAVE_SYS_TIME_H\r
2318#include <sys/time.h>\r
2319#endif\r
2320#ifdef HAVE_UNISTD_H\r
2321#include <unistd.h>\r
2322#endif\r
2323static struct timeval ts, te;\r
2324#define GETTIME(t) gettimeofday(&(t), (struct timezone* )0)\r
2325#define TIMEDIFF(te,ts) (((te).tv_usec - (ts).tv_usec) + \\r
2326 (((te).tv_sec - (ts).tv_sec)*1000000))\r
2327#else\r
2328#ifdef HAVE_SYS_TIMES_H\r
2329#include <sys/times.h>\r
2330#endif\r
2331static struct tms ts, te;\r
2332#define GETTIME(t) times(&(t))\r
2333#define TIMEDIFF(te,ts) ((te).tms_utime - (ts).tms_utime)\r
2334#endif\r
2335\r
2336static int OpCounter[256];\r
2337static int OpPrevCounter[256];\r
2338static unsigned long OpTime[256];\r
2339static int OpCurr = OP_FINISH;\r
2340static int OpPrevTarget = OP_FAIL;\r
2341static int MaxStackDepth = 0;\r
2342\r
b602265d 2343#define SOP_IN(opcode) do {\\r
14b0e578
CS
2344 if (opcode == OpPrevTarget) OpPrevCounter[OpCurr]++;\\r
2345 OpCurr = opcode;\\r
2346 OpCounter[opcode]++;\\r
2347 GETTIME(ts);\\r
2348} while(0)\r
2349\r
b602265d 2350#define SOP_OUT do {\\r
14b0e578
CS
2351 GETTIME(te);\\r
2352 OpTime[OpCurr] += TIMEDIFF(te, ts);\\r
2353} while(0)\r
2354\r
2355extern void\r
2356onig_statistics_init(void)\r
2357{\r
2358 int i;\r
2359 for (i = 0; i < 256; i++) {\r
2360 OpCounter[i] = OpPrevCounter[i] = 0; OpTime[i] = 0;\r
2361 }\r
2362 MaxStackDepth = 0;\r
2363}\r
2364\r
b602265d 2365extern int\r
14b0e578
CS
2366onig_print_statistics(FILE* f)\r
2367{\r
b602265d 2368 int r;\r
14b0e578 2369 int i;\r
b602265d
DG
2370\r
2371 r = fprintf(f, " count prev time\n");\r
2372 if (r < 0) return -1;\r
2373\r
2374 for (i = 0; OpInfo[i].opcode >= 0; i++) {\r
2375 r = fprintf(f, "%8d: %8d: %10ld: %s\n",\r
2376 OpCounter[i], OpPrevCounter[i], OpTime[i], OpInfo[i].name);\r
2377 if (r < 0) return -1;\r
14b0e578 2378 }\r
b602265d
DG
2379 r = fprintf(f, "\nmax stack depth: %d\n", MaxStackDepth);\r
2380 if (r < 0) return -1;\r
2381\r
2382 return 0;\r
14b0e578
CS
2383}\r
2384\r
2385#define STACK_INC do {\\r
2386 stk++;\\r
2387 if (stk - stk_base > MaxStackDepth) \\r
2388 MaxStackDepth = stk - stk_base;\\r
2389} while(0)\r
2390\r
2391#else\r
2392#define STACK_INC stk++\r
2393\r
b602265d
DG
2394#define SOP_IN(opcode)\r
2395#define SOP_OUT\r
14b0e578
CS
2396#endif\r
2397\r
2398\r
2399/* matching region of POSIX API */\r
2400typedef int regoff_t;\r
2401\r
2402typedef struct {\r
2403 regoff_t rm_so;\r
2404 regoff_t rm_eo;\r
2405} posix_regmatch_t;\r
2406\r
b26691c4
LG
2407\r
2408\r
2409#ifdef USE_THREADED_CODE\r
2410\r
2411#define BYTECODE_INTERPRETER_START GOTO_OP;\r
2412#define BYTECODE_INTERPRETER_END\r
2413#define CASE_OP(x) L_##x: SOP_IN(OP_##x); sbegin = s; MATCH_DEBUG_OUT(0)\r
2414#define DEFAULT_OP /* L_DEFAULT: */\r
2415#define NEXT_OP sprev = sbegin; JUMP_OP\r
2416#define JUMP_OP GOTO_OP\r
2417#ifdef USE_DIRECT_THREADED_CODE\r
2418#define GOTO_OP goto *(p->opaddr)\r
2419#else\r
2420#define GOTO_OP goto *opcode_to_label[p->opcode]\r
2421#endif\r
2422#define BREAK_OP /* Nothing */\r
2423\r
2424#else\r
2425\r
2426#define BYTECODE_INTERPRETER_START \\r
2427 while (1) {\\r
2428 MATCH_DEBUG_OUT(0)\\r
2429 sbegin = s;\\r
2430 switch (p->opcode) {\r
2431#define BYTECODE_INTERPRETER_END } sprev = sbegin; }\r
2432#define CASE_OP(x) case OP_##x: SOP_IN(OP_##x);\r
2433#define DEFAULT_OP default:\r
2434#define NEXT_OP break\r
2435#define JUMP_OP GOTO_OP\r
2436#define GOTO_OP continue; break\r
2437#define BREAK_OP break\r
2438\r
2439#endif /* USE_THREADED_CODE */\r
2440\r
2441#define INC_OP p++\r
2442#define NEXT_OUT SOP_OUT; NEXT_OP\r
2443#define JUMP_OUT SOP_OUT; JUMP_OP\r
2444#define BREAK_OUT SOP_OUT; BREAK_OP\r
2445#define CHECK_INTERRUPT_JUMP_OUT SOP_OUT; CHECK_INTERRUPT_IN_MATCH; JUMP_OP\r
2446\r
2447\r
2448#ifdef ONIG_DEBUG_MATCH\r
2449#define MATCH_DEBUG_OUT(offset) do {\\r
2450 Operation *xp;\\r
2451 UChar *q, *bp, buf[50];\\r
2452 int len, spos;\\r
2453 spos = IS_NOT_NULL(s) ? (int )(s - str) : -1;\\r
2454 xp = p - (offset);\\r
2455 fprintf(stderr, "%7u: %7ld: %4d> \"",\\r
2456 counter, GET_STACK_INDEX(stk), spos);\\r
2457 counter++;\\r
2458 bp = buf;\\r
2459 if (IS_NOT_NULL(s)) {\\r
2460 for (i = 0, q = s; i < 7 && q < end; i++) {\\r
2461 len = enclen(encode, q);\\r
2462 while (len-- > 0) *bp++ = *q++;\\r
2463 }\\r
2464 if (q < end) { xmemcpy(bp, "...\"", 4); bp += 4; }\\r
2465 else { xmemcpy(bp, "\"", 1); bp += 1; }\\r
2466 }\\r
2467 else {\\r
2468 xmemcpy(bp, "\"", 1); bp += 1;\\r
2469 }\\r
2470 *bp = 0;\\r
2471 fputs((char* )buf, stderr);\\r
2472 for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);\\r
2473 if (xp == FinishCode)\\r
2474 fprintf(stderr, "----: finish");\\r
2475 else {\\r
2476 fprintf(stderr, "%4d: ", (int )(xp - reg->ops));\\r
2477 print_compiled_byte_code(stderr, reg, (int )(xp - reg->ops), reg->ops, encode);\\r
2478 }\\r
2479 fprintf(stderr, "\n");\\r
2480 } while(0);\r
2481#else\r
2482#define MATCH_DEBUG_OUT(offset)\r
2483#endif\r
2484\r
2485\r
14b0e578
CS
2486/* match data(str - end) from position (sstart). */\r
2487/* if sstart == str then set sprev to NULL. */\r
2488static int\r
2489match_at(regex_t* reg, const UChar* str, const UChar* end,\r
b602265d
DG
2490 const UChar* in_right_range, const UChar* sstart, UChar* sprev,\r
2491 MatchArg* msa)\r
14b0e578 2492{\r
b26691c4
LG
2493\r
2494#if defined(USE_DIRECT_THREADED_CODE)\r
2495 static Operation FinishCode[] = { { .opaddr=&&L_FINISH } };\r
2496#else\r
2497 static Operation FinishCode[] = { { OP_FINISH } };\r
2498#endif\r
2499\r
2500#ifdef USE_THREADED_CODE\r
2501 static const void *opcode_to_label[] = {\r
2502 &&L_FINISH,\r
2503 &&L_END,\r
2504 &&L_EXACT1,\r
2505 &&L_EXACT2,\r
2506 &&L_EXACT3,\r
2507 &&L_EXACT4,\r
2508 &&L_EXACT5,\r
2509 &&L_EXACTN,\r
2510 &&L_EXACTMB2N1,\r
2511 &&L_EXACTMB2N2,\r
2512 &&L_EXACTMB2N3,\r
2513 &&L_EXACTMB2N,\r
2514 &&L_EXACTMB3N,\r
2515 &&L_EXACTMBN,\r
2516 &&L_EXACT1_IC,\r
2517 &&L_EXACTN_IC,\r
2518 &&L_CCLASS,\r
2519 &&L_CCLASS_MB,\r
2520 &&L_CCLASS_MIX,\r
2521 &&L_CCLASS_NOT,\r
2522 &&L_CCLASS_MB_NOT,\r
2523 &&L_CCLASS_MIX_NOT,\r
2524 &&L_ANYCHAR,\r
2525 &&L_ANYCHAR_ML,\r
2526 &&L_ANYCHAR_STAR,\r
2527 &&L_ANYCHAR_ML_STAR,\r
2528 &&L_ANYCHAR_STAR_PEEK_NEXT,\r
2529 &&L_ANYCHAR_ML_STAR_PEEK_NEXT,\r
2530 &&L_WORD,\r
2531 &&L_WORD_ASCII,\r
2532 &&L_NO_WORD,\r
2533 &&L_NO_WORD_ASCII,\r
2534 &&L_WORD_BOUNDARY,\r
2535 &&L_NO_WORD_BOUNDARY,\r
2536 &&L_WORD_BEGIN,\r
2537 &&L_WORD_END,\r
2538 &&L_TEXT_SEGMENT_BOUNDARY,\r
2539 &&L_BEGIN_BUF,\r
2540 &&L_END_BUF,\r
2541 &&L_BEGIN_LINE,\r
2542 &&L_END_LINE,\r
2543 &&L_SEMI_END_BUF,\r
2544 &&L_BEGIN_POSITION,\r
2545 &&L_BACKREF1,\r
2546 &&L_BACKREF2,\r
2547 &&L_BACKREF_N,\r
2548 &&L_BACKREF_N_IC,\r
2549 &&L_BACKREF_MULTI,\r
2550 &&L_BACKREF_MULTI_IC,\r
2551 &&L_BACKREF_WITH_LEVEL,\r
2552 &&L_BACKREF_WITH_LEVEL_IC,\r
2553 &&L_BACKREF_CHECK,\r
2554 &&L_BACKREF_CHECK_WITH_LEVEL,\r
2555 &&L_MEMORY_START,\r
2556 &&L_MEMORY_START_PUSH,\r
2557 &&L_MEMORY_END_PUSH,\r
2558 &&L_MEMORY_END_PUSH_REC,\r
2559 &&L_MEMORY_END,\r
2560 &&L_MEMORY_END_REC,\r
2561 &&L_FAIL,\r
2562 &&L_JUMP,\r
2563 &&L_PUSH,\r
2564 &&L_PUSH_SUPER,\r
2565 &&L_POP_OUT,\r
2566#ifdef USE_OP_PUSH_OR_JUMP_EXACT\r
2567 &&L_PUSH_OR_JUMP_EXACT1,\r
2568#endif\r
2569 &&L_PUSH_IF_PEEK_NEXT,\r
2570 &&L_REPEAT,\r
2571 &&L_REPEAT_NG,\r
2572 &&L_REPEAT_INC,\r
2573 &&L_REPEAT_INC_NG,\r
2574 &&L_REPEAT_INC_SG,\r
2575 &&L_REPEAT_INC_NG_SG,\r
2576 &&L_EMPTY_CHECK_START,\r
2577 &&L_EMPTY_CHECK_END,\r
2578 &&L_EMPTY_CHECK_END_MEMST,\r
2579 &&L_EMPTY_CHECK_END_MEMST_PUSH,\r
2580 &&L_PREC_READ_START,\r
2581 &&L_PREC_READ_END,\r
2582 &&L_PREC_READ_NOT_START,\r
2583 &&L_PREC_READ_NOT_END,\r
2584 &&L_ATOMIC_START,\r
2585 &&L_ATOMIC_END,\r
2586 &&L_LOOK_BEHIND,\r
2587 &&L_LOOK_BEHIND_NOT_START,\r
2588 &&L_LOOK_BEHIND_NOT_END,\r
2589 &&L_CALL,\r
2590 &&L_RETURN,\r
2591 &&L_PUSH_SAVE_VAL,\r
2592 &&L_UPDATE_VAR,\r
2593#ifdef USE_CALLOUT\r
2594 &&L_CALLOUT_CONTENTS,\r
2595 &&L_CALLOUT_NAME,\r
2596#endif\r
2597 };\r
2598#endif\r
14b0e578
CS
2599\r
2600 int i, n, num_mem, best_len, pop_level;\r
2601 LengthType tlen, tlen2;\r
2602 MemNumType mem;\r
2603 RelAddrType addr;\r
b26691c4 2604 UChar *s, *q, *ps, *sbegin;\r
b602265d
DG
2605 UChar *right_range;\r
2606 int is_alloca;\r
2607 char *alloc_base;\r
2608 StackType *stk_base, *stk, *stk_end;\r
2609 StackType *stkp; /* used as any purpose. */\r
2610 StackIndex si;\r
2611 StackIndex *repeat_stk;\r
2612 StackIndex *mem_start_stk, *mem_end_stk;\r
2613 UChar* keep;\r
2614#ifdef USE_RETRY_LIMIT_IN_MATCH\r
2615 unsigned long retry_limit_in_match;\r
2616 unsigned long retry_in_match_counter;\r
2617#endif\r
2618\r
2619#ifdef USE_CALLOUT\r
2620 int of;\r
2621#endif\r
2622\r
b26691c4 2623 Operation* p = reg->ops;\r
14b0e578
CS
2624 OnigOptionType option = reg->options;\r
2625 OnigEncoding encode = reg->enc;\r
2626 OnigCaseFoldType case_fold_flag = reg->case_fold_flag;\r
b602265d 2627\r
b26691c4
LG
2628#ifdef ONIG_DEBUG_MATCH\r
2629 static unsigned int counter = 1;\r
2630#endif\r
2631\r
2632#ifdef USE_DIRECT_THREADED_CODE\r
2633 if (IS_NULL(msa)) {\r
2634 for (i = 0; i < reg->ops_used; i++) {\r
2635 const void* addr;\r
2636 addr = opcode_to_label[reg->ocs[i]];\r
2637 p->opaddr = addr;\r
2638 p++;\r
2639 }\r
2640 return ONIG_NORMAL;\r
2641 }\r
2642#endif\r
2643\r
b602265d
DG
2644#ifdef USE_CALLOUT\r
2645 msa->mp->match_at_call_counter++;\r
2646#endif\r
2647\r
2648#ifdef USE_RETRY_LIMIT_IN_MATCH\r
2649 retry_limit_in_match = msa->retry_limit_in_match;\r
2650#endif\r
2651\r
14b0e578
CS
2652 pop_level = reg->stack_pop_level;\r
2653 num_mem = reg->num_mem;\r
b602265d
DG
2654 STACK_INIT(INIT_MATCH_STACK_SIZE);\r
2655 UPDATE_FOR_STACK_REALLOC;\r
14b0e578
CS
2656 for (i = 1; i <= num_mem; i++) {\r
2657 mem_start_stk[i] = mem_end_stk[i] = INVALID_STACK_INDEX;\r
2658 }\r
2659\r
2660#ifdef ONIG_DEBUG_MATCH\r
b602265d
DG
2661 fprintf(stderr, "match_at: str: %p, end: %p, start: %p, sprev: %p\n",\r
2662 str, end, sstart, sprev);\r
14b0e578 2663 fprintf(stderr, "size: %d, start offset: %d\n",\r
b602265d 2664 (int )(end - str), (int )(sstart - str));\r
14b0e578
CS
2665#endif\r
2666\r
14b0e578 2667 best_len = ONIG_MISMATCH;\r
b602265d
DG
2668 keep = s = (UChar* )sstart;\r
2669 STACK_PUSH_BOTTOM(STK_ALT, FinishCode); /* bottom stack */\r
2670 INIT_RIGHT_RANGE;\r
2671\r
2672#ifdef USE_RETRY_LIMIT_IN_MATCH\r
2673 retry_in_match_counter = 0;\r
2674#endif\r
2675\r
b26691c4
LG
2676 BYTECODE_INTERPRETER_START {\r
2677 CASE_OP(END)\r
b602265d 2678 n = (int )(s - sstart);\r
14b0e578 2679 if (n > best_len) {\r
b602265d 2680 OnigRegion* region;\r
14b0e578 2681#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
b602265d
DG
2682 if (IS_FIND_LONGEST(option)) {\r
2683 if (n > msa->best_len) {\r
2684 msa->best_len = n;\r
2685 msa->best_s = (UChar* )sstart;\r
2686 }\r
2687 else\r
2688 goto end_best_len;\r
14b0e578
CS
2689 }\r
2690#endif\r
b602265d
DG
2691 best_len = n;\r
2692 region = msa->region;\r
2693 if (region) {\r
2694 if (keep > s) keep = s;\r
2695\r
14b0e578 2696#ifdef USE_POSIX_API_REGION_OPTION\r
b602265d
DG
2697 if (IS_POSIX_REGION(msa->options)) {\r
2698 posix_regmatch_t* rmt = (posix_regmatch_t* )region;\r
2699\r
2700 rmt[0].rm_so = (regoff_t )(keep - str);\r
2701 rmt[0].rm_eo = (regoff_t )(s - str);\r
2702 for (i = 1; i <= num_mem; i++) {\r
2703 if (mem_end_stk[i] != INVALID_STACK_INDEX) {\r
2704 if (MEM_STATUS_AT(reg->bt_mem_start, i))\r
2705 rmt[i].rm_so = (regoff_t )(STACK_AT(mem_start_stk[i])->u.mem.pstr - str);\r
2706 else\r
2707 rmt[i].rm_so = (regoff_t )((UChar* )((void* )(mem_start_stk[i])) - str);\r
2708\r
2709 rmt[i].rm_eo = (regoff_t )((MEM_STATUS_AT(reg->bt_mem_end, i)\r
2710 ? STACK_AT(mem_end_stk[i])->u.mem.pstr\r
2711 : (UChar* )((void* )mem_end_stk[i]))\r
2712 - str);\r
2713 }\r
2714 else {\r
2715 rmt[i].rm_so = rmt[i].rm_eo = ONIG_REGION_NOTPOS;\r
2716 }\r
2717 }\r
2718 }\r
2719 else {\r
14b0e578 2720#endif /* USE_POSIX_API_REGION_OPTION */\r
b602265d
DG
2721 region->beg[0] = (int )(keep - str);\r
2722 region->end[0] = (int )(s - str);\r
2723 for (i = 1; i <= num_mem; i++) {\r
2724 if (mem_end_stk[i] != INVALID_STACK_INDEX) {\r
2725 if (MEM_STATUS_AT(reg->bt_mem_start, i))\r
2726 region->beg[i] = (int )(STACK_AT(mem_start_stk[i])->u.mem.pstr - str);\r
2727 else\r
2728 region->beg[i] = (int )((UChar* )((void* )mem_start_stk[i]) - str);\r
2729\r
2730 region->end[i] = (int )((MEM_STATUS_AT(reg->bt_mem_end, i)\r
2731 ? STACK_AT(mem_end_stk[i])->u.mem.pstr\r
2732 : (UChar* )((void* )mem_end_stk[i])) - str);\r
2733 }\r
2734 else {\r
2735 region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;\r
2736 }\r
2737 }\r
14b0e578
CS
2738\r
2739#ifdef USE_CAPTURE_HISTORY\r
b602265d 2740 if (reg->capture_history != 0) {\r
14b0e578
CS
2741 int r;\r
2742 OnigCaptureTreeNode* node;\r
2743\r
2744 if (IS_NULL(region->history_root)) {\r
2745 region->history_root = node = history_node_new();\r
2746 CHECK_NULL_RETURN_MEMERR(node);\r
2747 }\r
2748 else {\r
2749 node = region->history_root;\r
2750 history_tree_clear(node);\r
2751 }\r
2752\r
2753 node->group = 0;\r
b602265d
DG
2754 node->beg = (int )(keep - str);\r
2755 node->end = (int )(s - str);\r
14b0e578
CS
2756\r
2757 stkp = stk_base;\r
2758 r = make_capture_history_tree(region->history_root, &stkp,\r
2759 stk, (UChar* )str, reg);\r
2760 if (r < 0) {\r
2761 best_len = r; /* error code */\r
2762 goto finish;\r
2763 }\r
b602265d 2764 }\r
14b0e578
CS
2765#endif /* USE_CAPTURE_HISTORY */\r
2766#ifdef USE_POSIX_API_REGION_OPTION\r
b602265d 2767 } /* else IS_POSIX_REGION() */\r
14b0e578 2768#endif\r
b602265d 2769 } /* if (region) */\r
14b0e578
CS
2770 } /* n > best_len */\r
2771\r
2772#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
2773 end_best_len:\r
2774#endif\r
b602265d 2775 SOP_OUT;\r
14b0e578
CS
2776\r
2777 if (IS_FIND_CONDITION(option)) {\r
b602265d
DG
2778 if (IS_FIND_NOT_EMPTY(option) && s == sstart) {\r
2779 best_len = ONIG_MISMATCH;\r
2780 goto fail; /* for retry */\r
2781 }\r
2782 if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {\r
2783 goto fail; /* for retry */\r
2784 }\r
14b0e578
CS
2785 }\r
2786\r
2787 /* default behavior: return first-matching result. */\r
2788 goto finish;\r
14b0e578 2789\r
b26691c4 2790 CASE_OP(EXACT1)\r
14b0e578 2791 DATA_ENSURE(1);\r
b26691c4
LG
2792 ps = p->exact.s;\r
2793 if (*ps != *s) goto fail;\r
2794 s++;\r
2795 INC_OP;\r
2796 NEXT_OUT;\r
14b0e578 2797\r
b26691c4 2798 CASE_OP(EXACT1_IC)\r
14b0e578 2799 {\r
b602265d
DG
2800 int len;\r
2801 UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
2802\r
2803 DATA_ENSURE(1);\r
2804 len = ONIGENC_MBC_CASE_FOLD(encode,\r
2805 /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */\r
2806 case_fold_flag,\r
2807 &s, end, lowbuf);\r
2808 DATA_ENSURE(0);\r
2809 q = lowbuf;\r
b26691c4 2810 ps = p->exact.s;\r
b602265d 2811 while (len-- > 0) {\r
b26691c4
LG
2812 if (*ps != *q) goto fail;\r
2813 ps++; q++;\r
b602265d 2814 }\r
14b0e578 2815 }\r
b26691c4
LG
2816 INC_OP;\r
2817 NEXT_OUT;\r
14b0e578 2818\r
b26691c4 2819 CASE_OP(EXACT2)\r
14b0e578 2820 DATA_ENSURE(2);\r
b26691c4
LG
2821 ps = p->exact.s;\r
2822 if (*ps != *s) goto fail;\r
2823 ps++; s++;\r
2824 if (*ps != *s) goto fail;\r
14b0e578 2825 sprev = s;\r
b26691c4
LG
2826 s++;\r
2827 INC_OP;\r
2828 JUMP_OUT;\r
14b0e578 2829\r
b26691c4 2830 CASE_OP(EXACT3)\r
14b0e578 2831 DATA_ENSURE(3);\r
b26691c4
LG
2832 ps = p->exact.s;\r
2833 if (*ps != *s) goto fail;\r
2834 ps++; s++;\r
2835 if (*ps != *s) goto fail;\r
2836 ps++; s++;\r
2837 if (*ps != *s) goto fail;\r
14b0e578 2838 sprev = s;\r
b26691c4
LG
2839 s++;\r
2840 INC_OP;\r
2841 JUMP_OUT;\r
14b0e578 2842\r
b26691c4 2843 CASE_OP(EXACT4)\r
14b0e578 2844 DATA_ENSURE(4);\r
b26691c4
LG
2845 ps = p->exact.s;\r
2846 if (*ps != *s) goto fail;\r
2847 ps++; s++;\r
2848 if (*ps != *s) goto fail;\r
2849 ps++; s++;\r
2850 if (*ps != *s) goto fail;\r
2851 ps++; s++;\r
2852 if (*ps != *s) goto fail;\r
14b0e578 2853 sprev = s;\r
b26691c4
LG
2854 s++;\r
2855 INC_OP;\r
2856 JUMP_OUT;\r
14b0e578 2857\r
b26691c4 2858 CASE_OP(EXACT5)\r
14b0e578 2859 DATA_ENSURE(5);\r
b26691c4
LG
2860 ps = p->exact.s;\r
2861 if (*ps != *s) goto fail;\r
2862 ps++; s++;\r
2863 if (*ps != *s) goto fail;\r
2864 ps++; s++;\r
2865 if (*ps != *s) goto fail;\r
2866 ps++; s++;\r
2867 if (*ps != *s) goto fail;\r
2868 ps++; s++;\r
2869 if (*ps != *s) goto fail;\r
14b0e578 2870 sprev = s;\r
b26691c4
LG
2871 s++;\r
2872 INC_OP;\r
2873 JUMP_OUT;\r
14b0e578 2874\r
b26691c4
LG
2875 CASE_OP(EXACTN)\r
2876 tlen = p->exact_n.n;\r
14b0e578 2877 DATA_ENSURE(tlen);\r
b26691c4 2878 ps = p->exact_n.s;\r
14b0e578 2879 while (tlen-- > 0) {\r
b26691c4 2880 if (*ps++ != *s++) goto fail;\r
14b0e578
CS
2881 }\r
2882 sprev = s - 1;\r
b26691c4
LG
2883 INC_OP;\r
2884 JUMP_OUT;\r
14b0e578 2885\r
b26691c4 2886 CASE_OP(EXACTN_IC)\r
14b0e578 2887 {\r
b602265d
DG
2888 int len;\r
2889 UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
2890\r
b26691c4
LG
2891 tlen = p->exact_n.n;\r
2892 ps = p->exact_n.s;\r
2893 endp = ps + tlen;\r
2894 while (ps < endp) {\r
b602265d
DG
2895 sprev = s;\r
2896 DATA_ENSURE(1);\r
2897 len = ONIGENC_MBC_CASE_FOLD(encode,\r
2898 /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */\r
2899 case_fold_flag,\r
2900 &s, end, lowbuf);\r
2901 DATA_ENSURE(0);\r
2902 q = lowbuf;\r
2903 while (len-- > 0) {\r
b26691c4
LG
2904 if (*ps != *q) goto fail;\r
2905 ps++; q++;\r
b602265d
DG
2906 }\r
2907 }\r
2908 }\r
2909\r
b26691c4
LG
2910 INC_OP;\r
2911 JUMP_OUT;\r
14b0e578 2912\r
b26691c4 2913 CASE_OP(EXACTMB2N1)\r
14b0e578 2914 DATA_ENSURE(2);\r
b26691c4
LG
2915 ps = p->exact.s;\r
2916 if (*ps != *s) goto fail;\r
2917 ps++; s++;\r
2918 if (*ps != *s) goto fail;\r
2919 s++;\r
2920 INC_OP;\r
2921 NEXT_OUT;\r
2922\r
2923 CASE_OP(EXACTMB2N2)\r
14b0e578 2924 DATA_ENSURE(4);\r
b26691c4
LG
2925 ps = p->exact.s;\r
2926 if (*ps != *s) goto fail;\r
2927 ps++; s++;\r
2928 if (*ps != *s) goto fail;\r
2929 ps++; s++;\r
14b0e578 2930 sprev = s;\r
b26691c4
LG
2931 if (*ps != *s) goto fail;\r
2932 ps++; s++;\r
2933 if (*ps != *s) goto fail;\r
2934 s++;\r
2935 INC_OP;\r
2936 JUMP_OUT;\r
2937\r
2938 CASE_OP(EXACTMB2N3)\r
14b0e578 2939 DATA_ENSURE(6);\r
b26691c4
LG
2940 ps = p->exact.s;\r
2941 if (*ps != *s) goto fail;\r
2942 ps++; s++;\r
2943 if (*ps != *s) goto fail;\r
2944 ps++; s++;\r
2945 if (*ps != *s) goto fail;\r
2946 ps++; s++;\r
2947 if (*ps != *s) goto fail;\r
2948 ps++; s++;\r
14b0e578 2949 sprev = s;\r
b26691c4
LG
2950 if (*ps != *s) goto fail;\r
2951 ps++; s++;\r
2952 if (*ps != *s) goto fail;\r
2953 ps++; s++;\r
2954 INC_OP;\r
2955 JUMP_OUT;\r
2956\r
2957 CASE_OP(EXACTMB2N)\r
2958 tlen = p->exact_n.n;\r
14b0e578 2959 DATA_ENSURE(tlen * 2);\r
b26691c4 2960 ps = p->exact_n.s;\r
14b0e578 2961 while (tlen-- > 0) {\r
b26691c4
LG
2962 if (*ps != *s) goto fail;\r
2963 ps++; s++;\r
2964 if (*ps != *s) goto fail;\r
2965 ps++; s++;\r
14b0e578
CS
2966 }\r
2967 sprev = s - 2;\r
b26691c4
LG
2968 INC_OP;\r
2969 JUMP_OUT;\r
14b0e578 2970\r
b26691c4
LG
2971 CASE_OP(EXACTMB3N)\r
2972 tlen = p->exact_n.n;\r
14b0e578 2973 DATA_ENSURE(tlen * 3);\r
b26691c4 2974 ps = p->exact_n.s;\r
14b0e578 2975 while (tlen-- > 0) {\r
b26691c4
LG
2976 if (*ps != *s) goto fail;\r
2977 ps++; s++;\r
2978 if (*ps != *s) goto fail;\r
2979 ps++; s++;\r
2980 if (*ps != *s) goto fail;\r
2981 ps++; s++;\r
14b0e578
CS
2982 }\r
2983 sprev = s - 3;\r
b26691c4
LG
2984 INC_OP;\r
2985 JUMP_OUT;\r
14b0e578 2986\r
b26691c4
LG
2987 CASE_OP(EXACTMBN)\r
2988 tlen = p->exact_len_n.len; /* mb byte len */\r
2989 tlen2 = p->exact_len_n.n; /* number of chars */\r
14b0e578
CS
2990 tlen2 *= tlen;\r
2991 DATA_ENSURE(tlen2);\r
b26691c4 2992 ps = p->exact_len_n.s;\r
14b0e578 2993 while (tlen2-- > 0) {\r
b26691c4
LG
2994 if (*ps != *s) goto fail;\r
2995 ps++; s++;\r
14b0e578
CS
2996 }\r
2997 sprev = s - tlen;\r
b26691c4
LG
2998 INC_OP;\r
2999 JUMP_OUT;\r
14b0e578 3000\r
b26691c4 3001 CASE_OP(CCLASS)\r
14b0e578 3002 DATA_ENSURE(1);\r
b26691c4
LG
3003 if (BITSET_AT(p->cclass.bsp, *s) == 0) goto fail;\r
3004 s++;\r
3005 INC_OP;\r
3006 NEXT_OUT;\r
14b0e578 3007\r
b26691c4
LG
3008 CASE_OP(CCLASS_MB)\r
3009 DATA_ENSURE(1);\r
14b0e578
CS
3010 if (! ONIGENC_IS_MBC_HEAD(encode, s)) goto fail;\r
3011\r
3012 cclass_mb:\r
14b0e578 3013 {\r
b602265d
DG
3014 OnigCodePoint code;\r
3015 UChar *ss;\r
3016 int mb_len;\r
14b0e578 3017\r
b602265d
DG
3018 DATA_ENSURE(1);\r
3019 mb_len = enclen(encode, s);\r
3020 DATA_ENSURE(mb_len);\r
3021 ss = s;\r
3022 s += mb_len;\r
3023 code = ONIGENC_MBC_TO_CODE(encode, ss, s);\r
b26691c4 3024 if (! onig_is_in_code_range(p->cclass_mb.mb, code)) goto fail;\r
14b0e578 3025 }\r
b26691c4
LG
3026 INC_OP;\r
3027 NEXT_OUT;\r
14b0e578 3028\r
b26691c4 3029 CASE_OP(CCLASS_MIX)\r
14b0e578
CS
3030 DATA_ENSURE(1);\r
3031 if (ONIGENC_IS_MBC_HEAD(encode, s)) {\r
b602265d 3032 goto cclass_mb;\r
14b0e578
CS
3033 }\r
3034 else {\r
b26691c4 3035 if (BITSET_AT(p->cclass_mix.bsp, *s) == 0)\r
b602265d 3036 goto fail;\r
14b0e578 3037\r
b602265d 3038 s++;\r
14b0e578 3039 }\r
b26691c4
LG
3040 INC_OP;\r
3041 NEXT_OUT;\r
14b0e578 3042\r
b26691c4 3043 CASE_OP(CCLASS_NOT)\r
14b0e578 3044 DATA_ENSURE(1);\r
b26691c4 3045 if (BITSET_AT(p->cclass.bsp, *s) != 0) goto fail;\r
14b0e578 3046 s += enclen(encode, s);\r
b26691c4
LG
3047 INC_OP;\r
3048 NEXT_OUT;\r
14b0e578 3049\r
b26691c4 3050 CASE_OP(CCLASS_MB_NOT)\r
14b0e578
CS
3051 DATA_ENSURE(1);\r
3052 if (! ONIGENC_IS_MBC_HEAD(encode, s)) {\r
b602265d 3053 s++;\r
b602265d 3054 goto cc_mb_not_success;\r
14b0e578
CS
3055 }\r
3056\r
3057 cclass_mb_not:\r
14b0e578 3058 {\r
b602265d
DG
3059 OnigCodePoint code;\r
3060 UChar *ss;\r
3061 int mb_len = enclen(encode, s);\r
14b0e578 3062\r
b602265d 3063 if (! DATA_ENSURE_CHECK(mb_len)) {\r
14b0e578 3064 DATA_ENSURE(1);\r
b602265d 3065 s = (UChar* )end;\r
b602265d
DG
3066 goto cc_mb_not_success;\r
3067 }\r
14b0e578 3068\r
b602265d
DG
3069 ss = s;\r
3070 s += mb_len;\r
3071 code = ONIGENC_MBC_TO_CODE(encode, ss, s);\r
b26691c4 3072 if (onig_is_in_code_range(p->cclass_mb.mb, code)) goto fail;\r
14b0e578 3073 }\r
14b0e578
CS
3074\r
3075 cc_mb_not_success:\r
b26691c4
LG
3076 INC_OP;\r
3077 NEXT_OUT;\r
14b0e578 3078\r
b26691c4 3079 CASE_OP(CCLASS_MIX_NOT)\r
14b0e578
CS
3080 DATA_ENSURE(1);\r
3081 if (ONIGENC_IS_MBC_HEAD(encode, s)) {\r
b602265d 3082 goto cclass_mb_not;\r
14b0e578
CS
3083 }\r
3084 else {\r
b26691c4 3085 if (BITSET_AT(p->cclass_mix.bsp, *s) != 0)\r
b602265d 3086 goto fail;\r
14b0e578 3087\r
b602265d 3088 s++;\r
14b0e578 3089 }\r
b26691c4
LG
3090 INC_OP;\r
3091 NEXT_OUT;\r
14b0e578 3092\r
b26691c4 3093 CASE_OP(ANYCHAR)\r
14b0e578
CS
3094 DATA_ENSURE(1);\r
3095 n = enclen(encode, s);\r
3096 DATA_ENSURE(n);\r
3097 if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;\r
3098 s += n;\r
b26691c4
LG
3099 INC_OP;\r
3100 NEXT_OUT;\r
14b0e578 3101\r
b26691c4 3102 CASE_OP(ANYCHAR_ML)\r
14b0e578
CS
3103 DATA_ENSURE(1);\r
3104 n = enclen(encode, s);\r
3105 DATA_ENSURE(n);\r
3106 s += n;\r
b26691c4
LG
3107 INC_OP;\r
3108 NEXT_OUT;\r
14b0e578 3109\r
b26691c4
LG
3110 CASE_OP(ANYCHAR_STAR)\r
3111 INC_OP;\r
14b0e578 3112 while (DATA_ENSURE_CHECK1) {\r
b602265d
DG
3113 STACK_PUSH_ALT(p, s, sprev);\r
3114 n = enclen(encode, s);\r
14b0e578
CS
3115 DATA_ENSURE(n);\r
3116 if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;\r
3117 sprev = s;\r
3118 s += n;\r
3119 }\r
b26691c4 3120 JUMP_OUT;\r
14b0e578 3121\r
b26691c4
LG
3122 CASE_OP(ANYCHAR_ML_STAR)\r
3123 INC_OP;\r
14b0e578 3124 while (DATA_ENSURE_CHECK1) {\r
b602265d
DG
3125 STACK_PUSH_ALT(p, s, sprev);\r
3126 n = enclen(encode, s);\r
3127 if (n > 1) {\r
3128 DATA_ENSURE(n);\r
3129 sprev = s;\r
3130 s += n;\r
3131 }\r
3132 else {\r
3133 sprev = s;\r
3134 s++;\r
3135 }\r
3136 }\r
b26691c4 3137 JUMP_OUT;\r
b602265d 3138\r
b26691c4
LG
3139 CASE_OP(ANYCHAR_STAR_PEEK_NEXT)\r
3140 {\r
3141 UChar c;\r
14b0e578 3142\r
b26691c4
LG
3143 c = p->anychar_star_peek_next.c;\r
3144 INC_OP;\r
3145 while (DATA_ENSURE_CHECK1) {\r
3146 if (c == *s) {\r
3147 STACK_PUSH_ALT(p, s, sprev);\r
3148 }\r
3149 n = enclen(encode, s);\r
b602265d 3150 DATA_ENSURE(n);\r
b26691c4 3151 if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;\r
b602265d
DG
3152 sprev = s;\r
3153 s += n;\r
3154 }\r
b26691c4
LG
3155 }\r
3156 NEXT_OUT;\r
3157\r
3158 CASE_OP(ANYCHAR_ML_STAR_PEEK_NEXT)\r
3159 {\r
3160 UChar c;\r
3161\r
3162 c = p->anychar_star_peek_next.c;\r
3163 INC_OP;\r
3164 while (DATA_ENSURE_CHECK1) {\r
3165 if (c == *s) {\r
3166 STACK_PUSH_ALT(p, s, sprev);\r
3167 }\r
3168 n = enclen(encode, s);\r
3169 if (n > 1) {\r
3170 DATA_ENSURE(n);\r
3171 sprev = s;\r
3172 s += n;\r
3173 }\r
3174 else {\r
3175 sprev = s;\r
3176 s++;\r
3177 }\r
b602265d 3178 }\r
14b0e578 3179 }\r
b26691c4 3180 NEXT_OUT;\r
14b0e578 3181\r
b26691c4 3182 CASE_OP(WORD)\r
b602265d
DG
3183 DATA_ENSURE(1);\r
3184 if (! ONIGENC_IS_MBC_WORD(encode, s, end))\r
3185 goto fail;\r
14b0e578 3186\r
b602265d 3187 s += enclen(encode, s);\r
b26691c4
LG
3188 INC_OP;\r
3189 NEXT_OUT;\r
14b0e578 3190\r
b26691c4 3191 CASE_OP(WORD_ASCII)\r
14b0e578 3192 DATA_ENSURE(1);\r
b602265d
DG
3193 if (! ONIGENC_IS_MBC_WORD_ASCII(encode, s, end))\r
3194 goto fail;\r
14b0e578
CS
3195\r
3196 s += enclen(encode, s);\r
b26691c4
LG
3197 INC_OP;\r
3198 NEXT_OUT;\r
14b0e578 3199\r
b26691c4 3200 CASE_OP(NO_WORD)\r
14b0e578
CS
3201 DATA_ENSURE(1);\r
3202 if (ONIGENC_IS_MBC_WORD(encode, s, end))\r
b602265d 3203 goto fail;\r
14b0e578
CS
3204\r
3205 s += enclen(encode, s);\r
b26691c4
LG
3206 INC_OP;\r
3207 NEXT_OUT;\r
14b0e578 3208\r
b26691c4 3209 CASE_OP(NO_WORD_ASCII)\r
b602265d
DG
3210 DATA_ENSURE(1);\r
3211 if (ONIGENC_IS_MBC_WORD_ASCII(encode, s, end))\r
3212 goto fail;\r
3213\r
3214 s += enclen(encode, s);\r
b26691c4
LG
3215 INC_OP;\r
3216 NEXT_OUT;\r
b602265d 3217\r
b26691c4 3218 CASE_OP(WORD_BOUNDARY)\r
b602265d
DG
3219 {\r
3220 ModeType mode;\r
b602265d 3221\r
b26691c4 3222 mode = p->word_boundary.mode;\r
b602265d
DG
3223 if (ON_STR_BEGIN(s)) {\r
3224 DATA_ENSURE(1);\r
3225 if (! IS_MBC_WORD_ASCII_MODE(encode, s, end, mode))\r
3226 goto fail;\r
3227 }\r
3228 else if (ON_STR_END(s)) {\r
3229 if (! IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode))\r
3230 goto fail;\r
3231 }\r
3232 else {\r
3233 if (IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)\r
3234 == IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode))\r
3235 goto fail;\r
3236 }\r
14b0e578 3237 }\r
b26691c4
LG
3238 INC_OP;\r
3239 JUMP_OUT;\r
14b0e578 3240\r
b26691c4 3241 CASE_OP(NO_WORD_BOUNDARY)\r
b602265d
DG
3242 {\r
3243 ModeType mode;\r
b602265d 3244\r
b26691c4 3245 mode = p->word_boundary.mode;\r
b602265d
DG
3246 if (ON_STR_BEGIN(s)) {\r
3247 if (DATA_ENSURE_CHECK1 && IS_MBC_WORD_ASCII_MODE(encode, s, end, mode))\r
3248 goto fail;\r
3249 }\r
3250 else if (ON_STR_END(s)) {\r
3251 if (IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode))\r
3252 goto fail;\r
3253 }\r
3254 else {\r
3255 if (IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)\r
3256 != IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode))\r
3257 goto fail;\r
3258 }\r
14b0e578 3259 }\r
b26691c4
LG
3260 INC_OP;\r
3261 JUMP_OUT;\r
14b0e578
CS
3262\r
3263#ifdef USE_WORD_BEGIN_END\r
b26691c4 3264 CASE_OP(WORD_BEGIN)\r
b602265d
DG
3265 {\r
3266 ModeType mode;\r
b602265d 3267\r
b26691c4 3268 mode = p->word_boundary.mode;\r
b602265d
DG
3269 if (DATA_ENSURE_CHECK1 && IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)) {\r
3270 if (ON_STR_BEGIN(s) || !IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode)) {\r
b26691c4
LG
3271 INC_OP;\r
3272 JUMP_OUT;\r
b602265d
DG
3273 }\r
3274 }\r
14b0e578
CS
3275 }\r
3276 goto fail;\r
14b0e578 3277\r
b26691c4 3278 CASE_OP(WORD_END)\r
b602265d
DG
3279 {\r
3280 ModeType mode;\r
b602265d 3281\r
b26691c4 3282 mode = p->word_boundary.mode;\r
b602265d
DG
3283 if (!ON_STR_BEGIN(s) && IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode)) {\r
3284 if (ON_STR_END(s) || ! IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)) {\r
b26691c4
LG
3285 INC_OP;\r
3286 JUMP_OUT;\r
b602265d
DG
3287 }\r
3288 }\r
14b0e578
CS
3289 }\r
3290 goto fail;\r
14b0e578
CS
3291#endif\r
3292\r
b26691c4
LG
3293 CASE_OP(TEXT_SEGMENT_BOUNDARY)\r
3294 {\r
3295 int is_break;\r
b602265d 3296\r
b26691c4
LG
3297 switch (p->text_segment_boundary.type) {\r
3298 case EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:\r
3299 is_break = onigenc_egcb_is_break_position(encode, s, sprev, str, end);\r
3300 break;\r
3301#ifdef USE_UNICODE_WORD_BREAK\r
3302 case WORD_BOUNDARY:\r
3303 is_break = onigenc_wb_is_break_position(encode, s, sprev, str, end);\r
3304 break;\r
3305#endif\r
3306 default:\r
3307 goto bytecode_error;\r
3308 break;\r
3309 }\r
b602265d 3310\r
b26691c4
LG
3311 if (p->text_segment_boundary.not != 0)\r
3312 is_break = ! is_break;\r
b602265d 3313\r
b26691c4
LG
3314 if (is_break != 0) {\r
3315 INC_OP;\r
3316 JUMP_OUT;\r
3317 }\r
3318 else {\r
3319 goto fail;\r
3320 }\r
3321 }\r
3322\r
3323 CASE_OP(BEGIN_BUF)\r
14b0e578
CS
3324 if (! ON_STR_BEGIN(s)) goto fail;\r
3325\r
b26691c4
LG
3326 INC_OP;\r
3327 JUMP_OUT;\r
14b0e578 3328\r
b26691c4 3329 CASE_OP(END_BUF)\r
14b0e578
CS
3330 if (! ON_STR_END(s)) goto fail;\r
3331\r
b26691c4
LG
3332 INC_OP;\r
3333 JUMP_OUT;\r
14b0e578 3334\r
b26691c4 3335 CASE_OP(BEGIN_LINE)\r
14b0e578 3336 if (ON_STR_BEGIN(s)) {\r
b602265d 3337 if (IS_NOTBOL(msa->options)) goto fail;\r
b26691c4
LG
3338 INC_OP;\r
3339 JUMP_OUT;\r
14b0e578
CS
3340 }\r
3341 else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end) && !ON_STR_END(s)) {\r
b26691c4
LG
3342 INC_OP;\r
3343 JUMP_OUT;\r
14b0e578
CS
3344 }\r
3345 goto fail;\r
14b0e578 3346\r
b26691c4 3347 CASE_OP(END_LINE)\r
14b0e578
CS
3348 if (ON_STR_END(s)) {\r
3349#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
b602265d 3350 if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {\r
14b0e578 3351#endif\r
b602265d 3352 if (IS_NOTEOL(msa->options)) goto fail;\r
b26691c4
LG
3353 INC_OP;\r
3354 JUMP_OUT;\r
14b0e578 3355#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
b602265d 3356 }\r
14b0e578
CS
3357#endif\r
3358 }\r
3359 else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) {\r
b26691c4
LG
3360 INC_OP;\r
3361 JUMP_OUT;\r
14b0e578
CS
3362 }\r
3363#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
3364 else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {\r
b26691c4
LG
3365 INC_OP;\r
3366 JUMP_OUT;\r
14b0e578
CS
3367 }\r
3368#endif\r
3369 goto fail;\r
14b0e578 3370\r
b26691c4 3371 CASE_OP(SEMI_END_BUF)\r
14b0e578
CS
3372 if (ON_STR_END(s)) {\r
3373#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
b602265d 3374 if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {\r
14b0e578 3375#endif\r
b602265d 3376 if (IS_NOTEOL(msa->options)) goto fail;\r
b26691c4
LG
3377 INC_OP;\r
3378 JUMP_OUT;\r
14b0e578 3379#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
b602265d 3380 }\r
14b0e578
CS
3381#endif\r
3382 }\r
3383 else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end) &&\r
b602265d 3384 ON_STR_END(s + enclen(encode, s))) {\r
b26691c4
LG
3385 INC_OP;\r
3386 JUMP_OUT;\r
14b0e578
CS
3387 }\r
3388#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
3389 else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {\r
3390 UChar* ss = s + enclen(encode, s);\r
b602265d 3391 ss += enclen(encode, ss);\r
14b0e578 3392 if (ON_STR_END(ss)) {\r
b26691c4
LG
3393 INC_OP;\r
3394 JUMP_OUT;\r
14b0e578
CS
3395 }\r
3396 }\r
3397#endif\r
3398 goto fail;\r
14b0e578 3399\r
b26691c4 3400 CASE_OP(BEGIN_POSITION)\r
14b0e578 3401 if (s != msa->start)\r
b602265d 3402 goto fail;\r
14b0e578 3403\r
b26691c4
LG
3404 INC_OP;\r
3405 JUMP_OUT;\r
14b0e578 3406\r
b26691c4
LG
3407 CASE_OP(MEMORY_START_PUSH)\r
3408 mem = p->memory_start.num;\r
14b0e578 3409 STACK_PUSH_MEM_START(mem, s);\r
b26691c4
LG
3410 INC_OP;\r
3411 JUMP_OUT;\r
14b0e578 3412\r
b26691c4
LG
3413 CASE_OP(MEMORY_START)\r
3414 mem = p->memory_start.num;\r
b602265d 3415 mem_start_stk[mem] = (StackIndex )((void* )s);\r
b26691c4
LG
3416 INC_OP;\r
3417 JUMP_OUT;\r
14b0e578 3418\r
b26691c4
LG
3419 CASE_OP(MEMORY_END_PUSH)\r
3420 mem = p->memory_end.num;\r
14b0e578 3421 STACK_PUSH_MEM_END(mem, s);\r
b26691c4
LG
3422 INC_OP;\r
3423 JUMP_OUT;\r
14b0e578 3424\r
b26691c4
LG
3425 CASE_OP(MEMORY_END)\r
3426 mem = p->memory_end.num;\r
b602265d 3427 mem_end_stk[mem] = (StackIndex )((void* )s);\r
b26691c4
LG
3428 INC_OP;\r
3429 JUMP_OUT;\r
14b0e578 3430\r
b602265d 3431#ifdef USE_CALL\r
b26691c4
LG
3432 CASE_OP(MEMORY_END_PUSH_REC)\r
3433 mem = p->memory_end.num;\r
14b0e578 3434 STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */\r
b26691c4 3435 si = GET_STACK_INDEX(stkp);\r
14b0e578 3436 STACK_PUSH_MEM_END(mem, s);\r
b26691c4
LG
3437 mem_start_stk[mem] = si;\r
3438 INC_OP;\r
3439 JUMP_OUT;\r
14b0e578 3440\r
b26691c4
LG
3441 CASE_OP(MEMORY_END_REC)\r
3442 mem = p->memory_end.num;\r
b602265d 3443 mem_end_stk[mem] = (StackIndex )((void* )s);\r
14b0e578
CS
3444 STACK_GET_MEM_START(mem, stkp);\r
3445\r
b602265d
DG
3446 if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
3447 mem_start_stk[mem] = GET_STACK_INDEX(stkp);\r
14b0e578 3448 else\r
b602265d 3449 mem_start_stk[mem] = (StackIndex )((void* )stkp->u.mem.pstr);\r
14b0e578
CS
3450\r
3451 STACK_PUSH_MEM_END_MARK(mem);\r
b26691c4
LG
3452 INC_OP;\r
3453 JUMP_OUT;\r
14b0e578
CS
3454#endif\r
3455\r
b26691c4 3456 CASE_OP(BACKREF1)\r
14b0e578
CS
3457 mem = 1;\r
3458 goto backref;\r
14b0e578 3459\r
b26691c4 3460 CASE_OP(BACKREF2)\r
14b0e578
CS
3461 mem = 2;\r
3462 goto backref;\r
14b0e578 3463\r
b26691c4
LG
3464 CASE_OP(BACKREF_N)\r
3465 mem = p->backref_n.n1;\r
14b0e578
CS
3466 backref:\r
3467 {\r
b602265d
DG
3468 int len;\r
3469 UChar *pstart, *pend;\r
14b0e578 3470\r
b602265d
DG
3471 if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
3472 if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
14b0e578 3473\r
b602265d
DG
3474 if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
3475 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
3476 else\r
3477 pstart = (UChar* )((void* )mem_start_stk[mem]);\r
14b0e578 3478\r
b602265d
DG
3479 pend = (MEM_STATUS_AT(reg->bt_mem_end, mem)\r
3480 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
3481 : (UChar* )((void* )mem_end_stk[mem]));\r
3482 n = (int )(pend - pstart);\r
b26691c4
LG
3483 if (n != 0) {\r
3484 DATA_ENSURE(n);\r
3485 sprev = s;\r
3486 STRING_CMP(s, pstart, n);\r
3487 while (sprev + (len = enclen(encode, sprev)) < s)\r
3488 sprev += len;\r
3489 }\r
14b0e578 3490 }\r
b26691c4
LG
3491 INC_OP;\r
3492 JUMP_OUT;\r
14b0e578 3493\r
b26691c4
LG
3494 CASE_OP(BACKREF_N_IC)\r
3495 mem = p->backref_n.n1;\r
14b0e578 3496 {\r
b602265d
DG
3497 int len;\r
3498 UChar *pstart, *pend;\r
14b0e578 3499\r
b602265d
DG
3500 if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
3501 if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
14b0e578 3502\r
b602265d
DG
3503 if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
3504 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
3505 else\r
3506 pstart = (UChar* )((void* )mem_start_stk[mem]);\r
14b0e578 3507\r
b602265d
DG
3508 pend = (MEM_STATUS_AT(reg->bt_mem_end, mem)\r
3509 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
3510 : (UChar* )((void* )mem_end_stk[mem]));\r
3511 n = (int )(pend - pstart);\r
b26691c4
LG
3512 if (n != 0) {\r
3513 DATA_ENSURE(n);\r
3514 sprev = s;\r
3515 STRING_CMP_IC(case_fold_flag, pstart, &s, n);\r
3516 while (sprev + (len = enclen(encode, sprev)) < s)\r
3517 sprev += len;\r
3518 }\r
14b0e578 3519 }\r
b26691c4
LG
3520 INC_OP;\r
3521 JUMP_OUT;\r
14b0e578 3522\r
b26691c4 3523 CASE_OP(BACKREF_MULTI)\r
14b0e578 3524 {\r
b602265d
DG
3525 int len, is_fail;\r
3526 UChar *pstart, *pend, *swork;\r
3527\r
b26691c4 3528 tlen = p->backref_general.num;\r
b602265d 3529 for (i = 0; i < tlen; i++) {\r
b26691c4 3530 mem = tlen == 1 ? p->backref_general.n1 : p->backref_general.ns[i];\r
b602265d
DG
3531\r
3532 if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;\r
3533 if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;\r
3534\r
3535 if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
3536 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
3537 else\r
3538 pstart = (UChar* )((void* )mem_start_stk[mem]);\r
3539\r
3540 pend = (MEM_STATUS_AT(reg->bt_mem_end, mem)\r
3541 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
3542 : (UChar* )((void* )mem_end_stk[mem]));\r
3543 n = (int )(pend - pstart);\r
b26691c4
LG
3544 if (n != 0) {\r
3545 DATA_ENSURE(n);\r
3546 sprev = s;\r
3547 swork = s;\r
3548 STRING_CMP_VALUE(swork, pstart, n, is_fail);\r
3549 if (is_fail) continue;\r
3550 s = swork;\r
3551 while (sprev + (len = enclen(encode, sprev)) < s)\r
3552 sprev += len;\r
3553 }\r
b602265d
DG
3554 break; /* success */\r
3555 }\r
3556 if (i == tlen) goto fail;\r
b602265d 3557 }\r
b26691c4
LG
3558 INC_OP;\r
3559 JUMP_OUT;\r
b602265d 3560\r
b26691c4 3561 CASE_OP(BACKREF_MULTI_IC)\r
14b0e578 3562 {\r
b602265d
DG
3563 int len, is_fail;\r
3564 UChar *pstart, *pend, *swork;\r
3565\r
b26691c4 3566 tlen = p->backref_general.num;\r
b602265d 3567 for (i = 0; i < tlen; i++) {\r
b26691c4 3568 mem = tlen == 1 ? p->backref_general.n1 : p->backref_general.ns[i];\r
b602265d
DG
3569\r
3570 if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;\r
3571 if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;\r
3572\r
3573 if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
3574 pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
3575 else\r
3576 pstart = (UChar* )((void* )mem_start_stk[mem]);\r
3577\r
3578 pend = (MEM_STATUS_AT(reg->bt_mem_end, mem)\r
3579 ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
3580 : (UChar* )((void* )mem_end_stk[mem]));\r
3581 n = (int )(pend - pstart);\r
b26691c4
LG
3582 if (n != 0) {\r
3583 DATA_ENSURE(n);\r
3584 sprev = s;\r
3585 swork = s;\r
3586 STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, is_fail);\r
3587 if (is_fail) continue;\r
3588 s = swork;\r
3589 while (sprev + (len = enclen(encode, sprev)) < s)\r
3590 sprev += len;\r
3591 }\r
b602265d
DG
3592 break; /* success */\r
3593 }\r
3594 if (i == tlen) goto fail;\r
14b0e578 3595 }\r
b26691c4
LG
3596 INC_OP;\r
3597 JUMP_OUT;\r
14b0e578
CS
3598\r
3599#ifdef USE_BACKREF_WITH_LEVEL\r
b26691c4
LG
3600 CASE_OP(BACKREF_WITH_LEVEL_IC)\r
3601 n = 1; /* ignore case */\r
3602 goto backref_with_level;\r
3603 CASE_OP(BACKREF_WITH_LEVEL)\r
14b0e578 3604 {\r
b602265d 3605 int len;\r
b26691c4
LG
3606 int level;\r
3607 MemNumType* mems;\r
3608 UChar* ssave;\r
3609\r
3610 n = 0;\r
3611 backref_with_level:\r
3612 level = p->backref_general.nest_level;\r
3613 tlen = p->backref_general.num;\r
3614 mems = tlen == 1 ? &(p->backref_general.n1) : p->backref_general.ns;\r
3615\r
3616 ssave = s;\r
3617 if (backref_match_at_nested_level(reg, stk, stk_base, n,\r
3618 case_fold_flag, level, (int )tlen, mems, &s, end)) {\r
3619 if (ssave != s) {\r
3620 sprev = ssave;\r
b602265d
DG
3621 while (sprev + (len = enclen(encode, sprev)) < s)\r
3622 sprev += len;\r
3623 }\r
b602265d
DG
3624 }\r
3625 else\r
3626 goto fail;\r
14b0e578 3627 }\r
b26691c4
LG
3628 INC_OP;\r
3629 JUMP_OUT;\r
14b0e578
CS
3630#endif\r
3631\r
b26691c4 3632 CASE_OP(BACKREF_CHECK)\r
b602265d 3633 {\r
b26691c4 3634 MemNumType* mems;\r
b602265d 3635\r
b26691c4
LG
3636 tlen = p->backref_general.num;\r
3637 mems = tlen == 1 ? &(p->backref_general.n1) : p->backref_general.ns;\r
3638\r
3639 for (i = 0; i < tlen; i++) {\r
3640 mem = mems[i];\r
b602265d
DG
3641 if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;\r
3642 if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;\r
b602265d
DG
3643 break; /* success */\r
3644 }\r
3645 if (i == tlen) goto fail;\r
b602265d 3646 }\r
b26691c4
LG
3647 INC_OP;\r
3648 JUMP_OUT;\r
14b0e578 3649\r
b602265d 3650#ifdef USE_BACKREF_WITH_LEVEL\r
b26691c4 3651 CASE_OP(BACKREF_CHECK_WITH_LEVEL)\r
b602265d
DG
3652 {\r
3653 LengthType level;\r
b26691c4 3654 MemNumType* mems;\r
b602265d 3655\r
b26691c4
LG
3656 level = p->backref_general.nest_level;\r
3657 tlen = p->backref_general.num;\r
3658 mems = tlen == 1 ? &(p->backref_general.n1) : p->backref_general.ns;\r
b602265d
DG
3659\r
3660 if (backref_check_at_nested_level(reg, stk, stk_base,\r
b26691c4 3661 (int )level, (int )tlen, mems) == 0)\r
b602265d 3662 goto fail;\r
b602265d 3663 }\r
b26691c4
LG
3664 INC_OP;\r
3665 JUMP_OUT;\r
14b0e578
CS
3666#endif\r
3667\r
b26691c4
LG
3668 CASE_OP(EMPTY_CHECK_START)\r
3669 mem = p->empty_check_start.mem; /* mem: null check id */\r
b602265d 3670 STACK_PUSH_EMPTY_CHECK_START(mem, s);\r
b26691c4
LG
3671 INC_OP;\r
3672 JUMP_OUT;\r
14b0e578 3673\r
b26691c4 3674 CASE_OP(EMPTY_CHECK_END)\r
14b0e578 3675 {\r
b602265d 3676 int is_empty;\r
14b0e578 3677\r
b26691c4 3678 mem = p->empty_check_end.mem; /* mem: null check id */\r
b602265d 3679 STACK_EMPTY_CHECK(is_empty, mem, s);\r
b26691c4 3680 INC_OP;\r
b602265d 3681 if (is_empty) {\r
14b0e578 3682#ifdef ONIG_DEBUG_MATCH\r
b602265d
DG
3683 fprintf(stderr, "EMPTY_CHECK_END: skip id:%d, s:%p\n", (int )mem, s);\r
3684#endif\r
3685 empty_check_found:\r
3686 /* empty loop founded, skip next instruction */\r
b26691c4
LG
3687#if defined(ONIG_DEBUG) && !defined(USE_DIRECT_THREADED_CODE)\r
3688 switch (p->opcode) {\r
b602265d
DG
3689 case OP_JUMP:\r
3690 case OP_PUSH:\r
b602265d
DG
3691 case OP_REPEAT_INC:\r
3692 case OP_REPEAT_INC_NG:\r
3693 case OP_REPEAT_INC_SG:\r
3694 case OP_REPEAT_INC_NG_SG:\r
b26691c4 3695 INC_OP;\r
b602265d
DG
3696 break;\r
3697 default:\r
3698 goto unexpected_bytecode_error;\r
3699 break;\r
3700 }\r
b26691c4
LG
3701#else\r
3702 INC_OP;\r
3703#endif\r
b602265d
DG
3704 }\r
3705 }\r
b26691c4 3706 JUMP_OUT;\r
14b0e578 3707\r
b26691c4
LG
3708#ifdef USE_STUBBORN_CHECK_CAPTURES_IN_EMPTY_REPEAT\r
3709 CASE_OP(EMPTY_CHECK_END_MEMST)\r
14b0e578 3710 {\r
b602265d 3711 int is_empty;\r
14b0e578 3712\r
b26691c4 3713 mem = p->empty_check_end.mem; /* mem: null check id */\r
b602265d 3714 STACK_EMPTY_CHECK_MEM(is_empty, mem, s, reg);\r
b26691c4 3715 INC_OP;\r
b602265d 3716 if (is_empty) {\r
14b0e578 3717#ifdef ONIG_DEBUG_MATCH\r
b602265d 3718 fprintf(stderr, "EMPTY_CHECK_END_MEM: skip id:%d, s:%p\n", (int)mem, s);\r
14b0e578 3719#endif\r
b602265d
DG
3720 if (is_empty == -1) goto fail;\r
3721 goto empty_check_found;\r
3722 }\r
14b0e578 3723 }\r
b26691c4 3724 JUMP_OUT;\r
14b0e578
CS
3725#endif\r
3726\r
b602265d 3727#ifdef USE_CALL\r
b26691c4 3728 CASE_OP(EMPTY_CHECK_END_MEMST_PUSH)\r
14b0e578 3729 {\r
b602265d 3730 int is_empty;\r
14b0e578 3731\r
b26691c4
LG
3732 mem = p->empty_check_end.mem; /* mem: null check id */\r
3733#ifdef USE_STUBBORN_CHECK_CAPTURES_IN_EMPTY_REPEAT\r
b602265d 3734 STACK_EMPTY_CHECK_MEM_REC(is_empty, mem, s, reg);\r
14b0e578 3735#else\r
b602265d 3736 STACK_EMPTY_CHECK_REC(is_empty, mem, s);\r
14b0e578 3737#endif\r
b26691c4 3738 INC_OP;\r
b602265d 3739 if (is_empty) {\r
14b0e578 3740#ifdef ONIG_DEBUG_MATCH\r
b602265d
DG
3741 fprintf(stderr, "EMPTY_CHECK_END_MEM_PUSH: skip id:%d, s:%p\n",\r
3742 (int )mem, s);\r
14b0e578 3743#endif\r
b602265d
DG
3744 if (is_empty == -1) goto fail;\r
3745 goto empty_check_found;\r
3746 }\r
3747 else {\r
3748 STACK_PUSH_EMPTY_CHECK_END(mem);\r
3749 }\r
3750 }\r
b26691c4 3751 JUMP_OUT;\r
14b0e578
CS
3752#endif\r
3753\r
b26691c4
LG
3754 CASE_OP(JUMP)\r
3755 addr = p->jump.addr;\r
14b0e578 3756 p += addr;\r
b26691c4 3757 CHECK_INTERRUPT_JUMP_OUT;\r
14b0e578 3758\r
b26691c4
LG
3759 CASE_OP(PUSH)\r
3760 addr = p->push.addr;\r
14b0e578 3761 STACK_PUSH_ALT(p + addr, s, sprev);\r
b26691c4
LG
3762 INC_OP;\r
3763 JUMP_OUT;\r
14b0e578 3764\r
b26691c4
LG
3765 CASE_OP(PUSH_SUPER)\r
3766 addr = p->push.addr;\r
b602265d 3767 STACK_PUSH_SUPER_ALT(p + addr, s, sprev);\r
b26691c4
LG
3768 INC_OP;\r
3769 JUMP_OUT;\r
14b0e578 3770\r
b26691c4 3771 CASE_OP(POP_OUT)\r
14b0e578 3772 STACK_POP_ONE;\r
b602265d
DG
3773 /* for stop backtrack */\r
3774 /* CHECK_RETRY_LIMIT_IN_MATCH; */\r
b26691c4
LG
3775 INC_OP;\r
3776 JUMP_OUT;\r
14b0e578 3777\r
b26691c4
LG
3778 #ifdef USE_OP_PUSH_OR_JUMP_EXACT\r
3779 CASE_OP(PUSH_OR_JUMP_EXACT1)\r
3780 {\r
3781 UChar c;\r
14b0e578 3782\r
b26691c4
LG
3783 addr = p->push_or_jump_exact1.addr;\r
3784 c = p->push_or_jump_exact1.c;\r
3785 if (DATA_ENSURE_CHECK1 && c == *s) {\r
3786 STACK_PUSH_ALT(p + addr, s, sprev);\r
3787 INC_OP;\r
3788 JUMP_OUT;\r
3789 }\r
14b0e578 3790 }\r
b26691c4
LG
3791 p += addr;\r
3792 JUMP_OUT;\r
3793#endif\r
14b0e578 3794\r
b26691c4 3795 CASE_OP(PUSH_IF_PEEK_NEXT)\r
14b0e578 3796 {\r
b26691c4 3797 UChar c;\r
14b0e578 3798\r
b26691c4
LG
3799 addr = p->push_if_peek_next.addr;\r
3800 c = p->push_if_peek_next.c;\r
3801 if (c == *s) {\r
b602265d 3802 STACK_PUSH_ALT(p + addr, s, sprev);\r
b26691c4
LG
3803 INC_OP;\r
3804 JUMP_OUT;\r
b602265d 3805 }\r
14b0e578 3806 }\r
b26691c4
LG
3807 INC_OP;\r
3808 JUMP_OUT;\r
14b0e578 3809\r
b26691c4
LG
3810 CASE_OP(REPEAT)\r
3811 mem = p->repeat.id; /* mem: OP_REPEAT ID */\r
3812 addr = p->repeat.addr;\r
14b0e578 3813\r
b26691c4
LG
3814 STACK_ENSURE(1);\r
3815 repeat_stk[mem] = GET_STACK_INDEX(stk);\r
3816 STACK_PUSH_REPEAT(mem, p + 1);\r
14b0e578 3817\r
b26691c4
LG
3818 if (reg->repeat_range[mem].lower == 0) {\r
3819 STACK_PUSH_ALT(p + addr, s, sprev);\r
14b0e578 3820 }\r
b26691c4
LG
3821 INC_OP;\r
3822 JUMP_OUT;\r
14b0e578 3823\r
b26691c4
LG
3824 CASE_OP(REPEAT_NG)\r
3825 mem = p->repeat.id; /* mem: OP_REPEAT ID */\r
3826 addr = p->repeat.addr;\r
3827\r
3828 STACK_ENSURE(1);\r
3829 repeat_stk[mem] = GET_STACK_INDEX(stk);\r
3830 STACK_PUSH_REPEAT(mem, p + 1);\r
3831\r
3832 if (reg->repeat_range[mem].lower == 0) {\r
3833 STACK_PUSH_ALT(p + 1, s, sprev);\r
3834 p += addr;\r
3835 }\r
3836 else\r
3837 INC_OP;\r
3838 JUMP_OUT;\r
3839\r
3840 CASE_OP(REPEAT_INC)\r
3841 mem = p->repeat_inc.id; /* mem: OP_REPEAT ID */\r
3842 si = repeat_stk[mem];\r
14b0e578
CS
3843 stkp = STACK_AT(si);\r
3844\r
3845 repeat_inc:\r
3846 stkp->u.repeat.count++;\r
3847 if (stkp->u.repeat.count >= reg->repeat_range[mem].upper) {\r
3848 /* end of repeat. Nothing to do. */\r
b26691c4 3849 INC_OP;\r
14b0e578
CS
3850 }\r
3851 else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {\r
b26691c4 3852 INC_OP;\r
14b0e578
CS
3853 STACK_PUSH_ALT(p, s, sprev);\r
3854 p = STACK_AT(si)->u.repeat.pcode; /* Don't use stkp after PUSH. */\r
3855 }\r
3856 else {\r
3857 p = stkp->u.repeat.pcode;\r
3858 }\r
3859 STACK_PUSH_REPEAT_INC(si);\r
b26691c4 3860 CHECK_INTERRUPT_JUMP_OUT;\r
14b0e578 3861\r
b26691c4
LG
3862 CASE_OP(REPEAT_INC_SG)\r
3863 mem = p->repeat_inc.id; /* mem: OP_REPEAT ID */\r
14b0e578
CS
3864 STACK_GET_REPEAT(mem, stkp);\r
3865 si = GET_STACK_INDEX(stkp);\r
3866 goto repeat_inc;\r
14b0e578 3867\r
b26691c4
LG
3868 CASE_OP(REPEAT_INC_NG)\r
3869 mem = p->repeat_inc.id; /* mem: OP_REPEAT ID */\r
14b0e578
CS
3870 si = repeat_stk[mem];\r
3871 stkp = STACK_AT(si);\r
3872\r
3873 repeat_inc_ng:\r
3874 stkp->u.repeat.count++;\r
3875 if (stkp->u.repeat.count < reg->repeat_range[mem].upper) {\r
3876 if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {\r
b26691c4 3877 Operation* pcode = stkp->u.repeat.pcode;\r
14b0e578
CS
3878\r
3879 STACK_PUSH_REPEAT_INC(si);\r
3880 STACK_PUSH_ALT(pcode, s, sprev);\r
b26691c4 3881 INC_OP;\r
14b0e578
CS
3882 }\r
3883 else {\r
3884 p = stkp->u.repeat.pcode;\r
3885 STACK_PUSH_REPEAT_INC(si);\r
3886 }\r
3887 }\r
3888 else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {\r
3889 STACK_PUSH_REPEAT_INC(si);\r
b26691c4 3890 INC_OP;\r
14b0e578 3891 }\r
b26691c4 3892 CHECK_INTERRUPT_JUMP_OUT;\r
14b0e578 3893\r
b26691c4
LG
3894 CASE_OP(REPEAT_INC_NG_SG)\r
3895 mem = p->repeat_inc.id; /* mem: OP_REPEAT ID */\r
14b0e578
CS
3896 STACK_GET_REPEAT(mem, stkp);\r
3897 si = GET_STACK_INDEX(stkp);\r
3898 goto repeat_inc_ng;\r
14b0e578 3899\r
b26691c4
LG
3900 CASE_OP(PREC_READ_START)\r
3901 STACK_PUSH_PREC_READ_START(s, sprev);\r
3902 INC_OP;\r
3903 JUMP_OUT;\r
3904\r
3905 CASE_OP(PREC_READ_END)\r
3906 STACK_GET_PREC_READ_START(stkp);\r
3907 s = stkp->u.state.pstr;\r
3908 sprev = stkp->u.state.pstr_prev;\r
3909 STACK_PUSH(STK_PREC_READ_END,0,0,0);\r
3910 INC_OP;\r
3911 JUMP_OUT;\r
3912\r
3913 CASE_OP(PREC_READ_NOT_START)\r
3914 addr = p->prec_read_not_start.addr;\r
b602265d 3915 STACK_PUSH_ALT_PREC_READ_NOT(p + addr, s, sprev);\r
b26691c4
LG
3916 INC_OP;\r
3917 JUMP_OUT;\r
14b0e578 3918\r
b26691c4 3919 CASE_OP(PREC_READ_NOT_END)\r
b602265d 3920 STACK_POP_TIL_ALT_PREC_READ_NOT;\r
14b0e578 3921 goto fail;\r
14b0e578 3922\r
b26691c4 3923 CASE_OP(ATOMIC_START)\r
b602265d 3924 STACK_PUSH_TO_VOID_START;\r
b26691c4
LG
3925 INC_OP;\r
3926 JUMP_OUT;\r
14b0e578 3927\r
b26691c4 3928 CASE_OP(ATOMIC_END)\r
b602265d 3929 STACK_EXEC_TO_VOID(stkp);\r
b26691c4
LG
3930 INC_OP;\r
3931 JUMP_OUT;\r
14b0e578 3932\r
b26691c4
LG
3933 CASE_OP(LOOK_BEHIND)\r
3934 tlen = p->look_behind.len;\r
14b0e578
CS
3935 s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);\r
3936 if (IS_NULL(s)) goto fail;\r
3937 sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);\r
b26691c4
LG
3938 INC_OP;\r
3939 JUMP_OUT;\r
14b0e578 3940\r
b26691c4
LG
3941 CASE_OP(LOOK_BEHIND_NOT_START)\r
3942 addr = p->look_behind_not_start.addr;\r
3943 tlen = p->look_behind_not_start.len;\r
14b0e578
CS
3944 q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);\r
3945 if (IS_NULL(q)) {\r
b602265d
DG
3946 /* too short case -> success. ex. /(?<!XXX)a/.match("a")\r
3947 If you want to change to fail, replace following line. */\r
3948 p += addr;\r
3949 /* goto fail; */\r
14b0e578
CS
3950 }\r
3951 else {\r
b602265d
DG
3952 STACK_PUSH_ALT_LOOK_BEHIND_NOT(p + addr, s, sprev);\r
3953 s = q;\r
3954 sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);\r
b26691c4 3955 INC_OP;\r
14b0e578 3956 }\r
b26691c4 3957 JUMP_OUT;\r
14b0e578 3958\r
b26691c4 3959 CASE_OP(LOOK_BEHIND_NOT_END)\r
b602265d 3960 STACK_POP_TIL_ALT_LOOK_BEHIND_NOT;\r
b26691c4 3961 INC_OP;\r
14b0e578 3962 goto fail;\r
14b0e578 3963\r
b602265d 3964#ifdef USE_CALL\r
b26691c4
LG
3965 CASE_OP(CALL)\r
3966 addr = p->call.addr;\r
3967 INC_OP; STACK_PUSH_CALL_FRAME(p);\r
3968 p = reg->ops + addr;\r
3969 JUMP_OUT;\r
14b0e578 3970\r
b26691c4 3971 CASE_OP(RETURN)\r
14b0e578
CS
3972 STACK_RETURN(p);\r
3973 STACK_PUSH_RETURN;\r
b26691c4 3974 JUMP_OUT;\r
b602265d
DG
3975#endif\r
3976\r
b26691c4 3977 CASE_OP(PUSH_SAVE_VAL)\r
b602265d
DG
3978 {\r
3979 SaveType type;\r
b26691c4
LG
3980\r
3981 type = p->push_save_val.type;\r
3982 mem = p->push_save_val.id; /* mem: save id */\r
b602265d
DG
3983 switch ((enum SaveType )type) {\r
3984 case SAVE_KEEP:\r
3985 STACK_PUSH_SAVE_VAL(mem, type, s);\r
3986 break;\r
3987\r
3988 case SAVE_S:\r
3989 STACK_PUSH_SAVE_VAL_WITH_SPREV(mem, type, s);\r
3990 break;\r
3991\r
3992 case SAVE_RIGHT_RANGE:\r
3993 STACK_PUSH_SAVE_VAL(mem, SAVE_RIGHT_RANGE, right_range);\r
3994 break;\r
3995 }\r
3996 }\r
b26691c4
LG
3997 INC_OP;\r
3998 JUMP_OUT;\r
b602265d 3999\r
b26691c4 4000 CASE_OP(UPDATE_VAR)\r
b602265d
DG
4001 {\r
4002 UpdateVarType type;\r
4003 enum SaveType save_type;\r
4004\r
b26691c4
LG
4005 type = p->update_var.type;\r
4006 mem = p->update_var.id; /* mem: save id */\r
4007\r
b602265d
DG
4008 switch ((enum UpdateVarType )type) {\r
4009 case UPDATE_VAR_KEEP_FROM_STACK_LAST:\r
4010 STACK_GET_SAVE_VAL_TYPE_LAST(SAVE_KEEP, keep);\r
4011 break;\r
4012 case UPDATE_VAR_S_FROM_STACK:\r
4013 STACK_GET_SAVE_VAL_TYPE_LAST_ID_WITH_SPREV(SAVE_S, mem, s);\r
4014 break;\r
4015 case UPDATE_VAR_RIGHT_RANGE_FROM_S_STACK:\r
4016 save_type = SAVE_S;\r
4017 goto get_save_val_type_last_id;\r
4018 break;\r
4019 case UPDATE_VAR_RIGHT_RANGE_FROM_STACK:\r
4020 save_type = SAVE_RIGHT_RANGE;\r
4021 get_save_val_type_last_id:\r
4022 STACK_GET_SAVE_VAL_TYPE_LAST_ID(save_type, mem, right_range);\r
4023 break;\r
4024 case UPDATE_VAR_RIGHT_RANGE_INIT:\r
4025 INIT_RIGHT_RANGE;\r
4026 break;\r
4027 }\r
4028 }\r
b26691c4
LG
4029 INC_OP;\r
4030 JUMP_OUT;\r
b602265d
DG
4031\r
4032#ifdef USE_CALLOUT\r
b26691c4 4033 CASE_OP(CALLOUT_CONTENTS)\r
b602265d 4034 of = ONIG_CALLOUT_OF_CONTENTS;\r
b26691c4 4035 mem = p->callout_contents.num;\r
b602265d 4036 goto callout_common_entry;\r
b26691c4 4037 BREAK_OUT;\r
b602265d 4038\r
b26691c4 4039 CASE_OP(CALLOUT_NAME)\r
b602265d
DG
4040 {\r
4041 int call_result;\r
4042 int name_id;\r
b602265d
DG
4043 int in;\r
4044 CalloutListEntry* e;\r
4045 OnigCalloutFunc func;\r
4046 OnigCalloutArgs args;\r
4047\r
4048 of = ONIG_CALLOUT_OF_NAME;\r
b26691c4
LG
4049 name_id = p->callout_name.id;\r
4050 mem = p->callout_name.num;\r
b602265d
DG
4051\r
4052 callout_common_entry:\r
b26691c4 4053 e = onig_reg_callout_list_at(reg, mem);\r
b602265d
DG
4054 in = e->in;\r
4055 if (of == ONIG_CALLOUT_OF_NAME) {\r
b26691c4 4056 func = onig_get_callout_start_func(reg, mem);\r
b602265d
DG
4057 }\r
4058 else {\r
4059 name_id = ONIG_NON_NAME_ID;\r
4060 func = msa->mp->progress_callout_of_contents;\r
4061 }\r
4062\r
4063 if (IS_NOT_NULL(func) && (in & ONIG_CALLOUT_IN_PROGRESS) != 0) {\r
4064 CALLOUT_BODY(func, ONIG_CALLOUT_IN_PROGRESS, name_id,\r
b26691c4 4065 (int )mem, msa->mp->callout_user_data, args, call_result);\r
b602265d
DG
4066 switch (call_result) {\r
4067 case ONIG_CALLOUT_FAIL:\r
4068 goto fail;\r
4069 break;\r
4070 case ONIG_CALLOUT_SUCCESS:\r
4071 goto retraction_callout2;\r
4072 break;\r
4073 default: /* error code */\r
4074 if (call_result > 0) {\r
4075 call_result = ONIGERR_INVALID_ARGUMENT;\r
4076 }\r
4077 best_len = call_result;\r
4078 goto finish;\r
4079 break;\r
4080 }\r
4081 }\r
4082 else {\r
4083 retraction_callout2:\r
4084 if ((in & ONIG_CALLOUT_IN_RETRACTION) != 0) {\r
4085 if (of == ONIG_CALLOUT_OF_NAME) {\r
4086 if (IS_NOT_NULL(func)) {\r
b26691c4 4087 STACK_PUSH_CALLOUT_NAME(name_id, mem, func);\r
b602265d
DG
4088 }\r
4089 }\r
4090 else {\r
4091 func = msa->mp->retraction_callout_of_contents;\r
4092 if (IS_NOT_NULL(func)) {\r
b26691c4 4093 STACK_PUSH_CALLOUT_CONTENTS(mem, func);\r
b602265d
DG
4094 }\r
4095 }\r
4096 }\r
4097 }\r
4098 }\r
b26691c4
LG
4099 INC_OP;\r
4100 JUMP_OUT;\r
14b0e578
CS
4101#endif\r
4102\r
b26691c4 4103 CASE_OP(FINISH)\r
14b0e578 4104 goto finish;\r
14b0e578 4105\r
b26691c4 4106#ifdef ONIG_DEBUG_STATISTICS\r
14b0e578 4107 fail:\r
b602265d 4108 SOP_OUT;\r
b26691c4
LG
4109 goto fail2;\r
4110#endif\r
4111 CASE_OP(FAIL)\r
4112#ifdef ONIG_DEBUG_STATISTICS\r
4113 fail2:\r
4114#else\r
4115 fail:\r
4116#endif\r
14b0e578
CS
4117 STACK_POP;\r
4118 p = stk->u.state.pcode;\r
4119 s = stk->u.state.pstr;\r
4120 sprev = stk->u.state.pstr_prev;\r
b602265d 4121 CHECK_RETRY_LIMIT_IN_MATCH;\r
b26691c4 4122 JUMP_OUT;\r
14b0e578 4123\r
b26691c4 4124 DEFAULT_OP\r
14b0e578
CS
4125 goto bytecode_error;\r
4126\r
b26691c4 4127 } BYTECODE_INTERPRETER_END;\r
14b0e578
CS
4128\r
4129 finish:\r
4130 STACK_SAVE;\r
14b0e578
CS
4131 return best_len;\r
4132\r
4133#ifdef ONIG_DEBUG\r
4134 stack_error:\r
4135 STACK_SAVE;\r
14b0e578
CS
4136 return ONIGERR_STACK_BUG;\r
4137#endif\r
4138\r
4139 bytecode_error:\r
4140 STACK_SAVE;\r
14b0e578
CS
4141 return ONIGERR_UNDEFINED_BYTECODE;\r
4142\r
b26691c4 4143#if defined(ONIG_DEBUG) && !defined(USE_DIRECT_THREADED_CODE)\r
14b0e578
CS
4144 unexpected_bytecode_error:\r
4145 STACK_SAVE;\r
14b0e578 4146 return ONIGERR_UNEXPECTED_BYTECODE;\r
b26691c4 4147#endif\r
b602265d
DG
4148\r
4149#ifdef USE_RETRY_LIMIT_IN_MATCH\r
4150 retry_limit_in_match_over:\r
4151 STACK_SAVE;\r
4152 return ONIGERR_RETRY_LIMIT_IN_MATCH_OVER;\r
4153#endif\r
14b0e578
CS
4154}\r
4155\r
4156\r
4157static UChar*\r
4158slow_search(OnigEncoding enc, UChar* target, UChar* target_end,\r
b602265d 4159 const UChar* text, const UChar* text_end, UChar* text_range)\r
14b0e578
CS
4160{\r
4161 UChar *t, *p, *s, *end;\r
4162\r
4163 end = (UChar* )text_end;\r
4164 end -= target_end - target - 1;\r
4165 if (end > text_range)\r
4166 end = text_range;\r
4167\r
4168 s = (UChar* )text;\r
4169\r
4170 while (s < end) {\r
4171 if (*s == *target) {\r
4172 p = s + 1;\r
4173 t = target + 1;\r
4174 while (t < target_end) {\r
b602265d
DG
4175 if (*t != *p++)\r
4176 break;\r
4177 t++;\r
14b0e578
CS
4178 }\r
4179 if (t == target_end)\r
b602265d 4180 return s;\r
14b0e578
CS
4181 }\r
4182 s += enclen(enc, s);\r
4183 }\r
4184\r
4185 return (UChar* )NULL;\r
4186}\r
4187\r
4188static int\r
4189str_lower_case_match(OnigEncoding enc, int case_fold_flag,\r
4190 const UChar* t, const UChar* tend,\r
b602265d 4191 const UChar* p, const UChar* end)\r
14b0e578
CS
4192{\r
4193 int lowlen;\r
4194 UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
4195\r
4196 while (t < tend) {\r
4197 lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf);\r
4198 q = lowbuf;\r
4199 while (lowlen > 0) {\r
b602265d 4200 if (*t++ != *q++) return 0;\r
14b0e578
CS
4201 lowlen--;\r
4202 }\r
4203 }\r
4204\r
4205 return 1;\r
4206}\r
4207\r
4208static UChar*\r
4209slow_search_ic(OnigEncoding enc, int case_fold_flag,\r
b602265d
DG
4210 UChar* target, UChar* target_end,\r
4211 const UChar* text, const UChar* text_end, UChar* text_range)\r
14b0e578
CS
4212{\r
4213 UChar *s, *end;\r
4214\r
4215 end = (UChar* )text_end;\r
4216 end -= target_end - target - 1;\r
4217 if (end > text_range)\r
4218 end = text_range;\r
4219\r
4220 s = (UChar* )text;\r
4221\r
4222 while (s < end) {\r
4223 if (str_lower_case_match(enc, case_fold_flag, target, target_end,\r
b602265d 4224 s, text_end))\r
14b0e578
CS
4225 return s;\r
4226\r
4227 s += enclen(enc, s);\r
4228 }\r
4229\r
4230 return (UChar* )NULL;\r
4231}\r
4232\r
4233static UChar*\r
4234slow_search_backward(OnigEncoding enc, UChar* target, UChar* target_end,\r
b602265d
DG
4235 const UChar* text, const UChar* adjust_text,\r
4236 const UChar* text_end, const UChar* text_start)\r
14b0e578
CS
4237{\r
4238 UChar *t, *p, *s;\r
4239\r
4240 s = (UChar* )text_end;\r
4241 s -= (target_end - target);\r
4242 if (s > text_start)\r
4243 s = (UChar* )text_start;\r
4244 else\r
4245 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s);\r
4246\r
4247 while (s >= text) {\r
3948c510
DG
4248 //if text is not null,the logic is correct.\r
4249 //this function is only invoked by backward_search_range,parameter text come\r
4250 //from range, which is checked by "if (range == 0) goto fail" in line 4512\r
4251 //so the check is just for passing static analysis.\r
4252 if(IS_NULL(s))break;\r
14b0e578
CS
4253 if (*s == *target) {\r
4254 p = s + 1;\r
4255 t = target + 1;\r
4256 while (t < target_end) {\r
b602265d
DG
4257 if (*t != *p++)\r
4258 break;\r
4259 t++;\r
14b0e578
CS
4260 }\r
4261 if (t == target_end)\r
b602265d 4262 return s;\r
14b0e578
CS
4263 }\r
4264 s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s);\r
4265 }\r
4266\r
4267 return (UChar* )NULL;\r
4268}\r
4269\r
4270static UChar*\r
4271slow_search_backward_ic(OnigEncoding enc, int case_fold_flag,\r
b602265d
DG
4272 UChar* target, UChar* target_end,\r
4273 const UChar* text, const UChar* adjust_text,\r
4274 const UChar* text_end, const UChar* text_start)\r
14b0e578
CS
4275{\r
4276 UChar *s;\r
4277\r
4278 s = (UChar* )text_end;\r
4279 s -= (target_end - target);\r
4280 if (s > text_start)\r
4281 s = (UChar* )text_start;\r
4282 else\r
4283 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s);\r
4284\r
4285 while (s >= text) {\r
4286 if (str_lower_case_match(enc, case_fold_flag,\r
4287 target, target_end, s, text_end))\r
4288 return s;\r
4289\r
4290 s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s);\r
4291 }\r
4292\r
4293 return (UChar* )NULL;\r
4294}\r
4295\r
b26691c4 4296\r
14b0e578 4297static UChar*\r
b26691c4
LG
4298sunday_quick_search_step_forward(regex_t* reg,\r
4299 const UChar* target, const UChar* target_end,\r
4300 const UChar* text, const UChar* text_end,\r
4301 const UChar* text_range)\r
14b0e578
CS
4302{\r
4303 const UChar *s, *se, *t, *p, *end;\r
4304 const UChar *tail;\r
4305 int skip, tlen1;\r
b26691c4
LG
4306 int map_offset;\r
4307 OnigEncoding enc;\r
14b0e578
CS
4308\r
4309#ifdef ONIG_DEBUG_SEARCH\r
b26691c4
LG
4310 fprintf(stderr,\r
4311 "sunday_quick_search_step_forward: text: %p, text_end: %p, text_range: %p\n", text, text_end, text_range);\r
14b0e578
CS
4312#endif\r
4313\r
b26691c4
LG
4314 enc = reg->enc;\r
4315\r
14b0e578 4316 tail = target_end - 1;\r
b602265d 4317 tlen1 = (int )(tail - target);\r
14b0e578
CS
4318 end = text_range;\r
4319 if (end + tlen1 > text_end)\r
4320 end = text_end - tlen1;\r
4321\r
b26691c4 4322 map_offset = reg->map_offset;\r
14b0e578
CS
4323 s = text;\r
4324\r
b26691c4
LG
4325 while (s < end) {\r
4326 p = se = s + tlen1;\r
4327 t = tail;\r
4328 while (*p == *t) {\r
4329 if (t == target) return (UChar* )s;\r
4330 p--; t--;\r
14b0e578 4331 }\r
b26691c4
LG
4332 if (se + map_offset >= text_end) break;\r
4333 skip = reg->map[*(se + map_offset)];\r
4334#if 0\r
4335 t = s;\r
4336 do {\r
4337 s += enclen(enc, s);\r
4338 } while ((s - t) < skip && s < end);\r
4339#else\r
4340 s += skip;\r
4341 if (s < end)\r
4342 s = onigenc_get_right_adjust_char_head(enc, text, s);\r
4343#endif\r
14b0e578
CS
4344 }\r
4345\r
4346 return (UChar* )NULL;\r
4347}\r
4348\r
4349static UChar*\r
b26691c4
LG
4350sunday_quick_search(regex_t* reg, const UChar* target, const UChar* target_end,\r
4351 const UChar* text, const UChar* text_end,\r
4352 const UChar* text_range)\r
14b0e578
CS
4353{\r
4354 const UChar *s, *t, *p, *end;\r
4355 const UChar *tail;\r
b26691c4 4356 int map_offset;\r
14b0e578 4357\r
b26691c4 4358 end = text_range + (target_end - target);\r
14b0e578
CS
4359 if (end > text_end)\r
4360 end = text_end;\r
4361\r
b26691c4 4362 map_offset = reg->map_offset;\r
14b0e578 4363 tail = target_end - 1;\r
b26691c4
LG
4364 s = text + (tail - target);\r
4365\r
4366 while (s < end) {\r
4367 p = s;\r
4368 t = tail;\r
4369 while (*p == *t) {\r
4370 if (t == target) return (UChar* )p;\r
4371 p--; t--;\r
14b0e578 4372 }\r
b26691c4
LG
4373 if (s + map_offset >= text_end) break;\r
4374 s += reg->map[*(s + map_offset)];\r
14b0e578 4375 }\r
b26691c4 4376\r
14b0e578
CS
4377 return (UChar* )NULL;\r
4378}\r
4379\r
b26691c4
LG
4380static UChar*\r
4381sunday_quick_search_case_fold(regex_t* reg,\r
4382 const UChar* target, const UChar* target_end,\r
4383 const UChar* text, const UChar* text_end,\r
4384 const UChar* text_range)\r
14b0e578 4385{\r
b26691c4
LG
4386 const UChar *s, *se, *end;\r
4387 const UChar *tail;\r
4388 int skip, tlen1;\r
4389 int map_offset;\r
4390 int case_fold_flag;\r
4391 OnigEncoding enc;\r
14b0e578 4392\r
b26691c4
LG
4393#ifdef ONIG_DEBUG_SEARCH\r
4394 fprintf(stderr,\r
4395 "sunday_quick_search_case_fold: text: %p, text_end: %p, text_range: %p\n", text, text_end, text_range);\r
4396#endif\r
14b0e578 4397\r
b26691c4
LG
4398 enc = reg->enc;\r
4399 case_fold_flag = reg->case_fold_flag;\r
14b0e578 4400\r
b26691c4
LG
4401 tail = target_end - 1;\r
4402 tlen1 = (int )(tail - target);\r
4403 end = text_range;\r
4404 if (end + tlen1 > text_end)\r
4405 end = text_end - tlen1;\r
14b0e578 4406\r
b26691c4
LG
4407 map_offset = reg->map_offset;\r
4408 s = text;\r
14b0e578 4409\r
b26691c4
LG
4410 while (s < end) {\r
4411 if (str_lower_case_match(enc, case_fold_flag, target, target_end,\r
4412 s, text_end))\r
14b0e578
CS
4413 return (UChar* )s;\r
4414\r
b26691c4
LG
4415 se = s + tlen1;\r
4416 if (se + map_offset >= text_end) break;\r
4417 skip = reg->map[*(se + map_offset)];\r
4418#if 0\r
4419 p = s;\r
4420 do {\r
4421 s += enclen(enc, s);\r
4422 } while ((s - p) < skip && s < end);\r
4423#else\r
4424 /* This is faster than prev code for long text. ex: /(?i)Twain/ */\r
4425 s += skip;\r
4426 if (s < end)\r
4427 s = onigenc_get_right_adjust_char_head(enc, text, s);\r
4428#endif\r
14b0e578
CS
4429 }\r
4430\r
4431 return (UChar* )NULL;\r
4432}\r
4433\r
4434static UChar*\r
4435map_search(OnigEncoding enc, UChar map[],\r
b602265d 4436 const UChar* text, const UChar* text_range)\r
14b0e578
CS
4437{\r
4438 const UChar *s = text;\r
4439\r
4440 while (s < text_range) {\r
4441 if (map[*s]) return (UChar* )s;\r
4442\r
4443 s += enclen(enc, s);\r
4444 }\r
4445 return (UChar* )NULL;\r
4446}\r
4447\r
4448static UChar*\r
4449map_search_backward(OnigEncoding enc, UChar map[],\r
b602265d
DG
4450 const UChar* text, const UChar* adjust_text,\r
4451 const UChar* text_start)\r
14b0e578
CS
4452{\r
4453 const UChar *s = text_start;\r
4454\r
4455 while (s >= text) {\r
3948c510
DG
4456 //if text is not null,the logic is correct.\r
4457 //this function is only invoked by backward_search_range,parameter text come\r
4458 //from range, which is checked by "if (range == 0) goto fail" in line 4512\r
4459 //so the check is just for passing static analysis.\r
4460 if(IS_NULL(s))break;\r
14b0e578
CS
4461 if (map[*s]) return (UChar* )s;\r
4462\r
4463 s = onigenc_get_prev_char_head(enc, adjust_text, s);\r
4464 }\r
4465 return (UChar* )NULL;\r
4466}\r
b602265d
DG
4467extern int\r
4468onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at,\r
4469 OnigRegion* region, OnigOptionType option)\r
4470{\r
4471 int r;\r
4472 OnigMatchParam mp;\r
4473\r
4474 onig_initialize_match_param(&mp);\r
4475 r = onig_match_with_param(reg, str, end, at, region, option, &mp);\r
4476 onig_free_match_param_content(&mp);\r
4477 return r;\r
4478}\r
14b0e578
CS
4479\r
4480extern int\r
b602265d
DG
4481onig_match_with_param(regex_t* reg, const UChar* str, const UChar* end,\r
4482 const UChar* at, OnigRegion* region, OnigOptionType option,\r
4483 OnigMatchParam* mp)\r
14b0e578
CS
4484{\r
4485 int r;\r
4486 UChar *prev;\r
b602265d 4487 MatchArg msa;\r
14b0e578 4488\r
b602265d
DG
4489 ADJUST_MATCH_PARAM(reg, mp);\r
4490 MATCH_ARG_INIT(msa, reg, option, region, at, mp);\r
14b0e578
CS
4491 if (region\r
4492#ifdef USE_POSIX_API_REGION_OPTION\r
4493 && !IS_POSIX_REGION(option)\r
4494#endif\r
4495 ) {\r
4496 r = onig_region_resize_clear(region, reg->num_mem + 1);\r
4497 }\r
4498 else\r
4499 r = 0;\r
4500\r
4501 if (r == 0) {\r
b602265d
DG
4502 if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
4503 if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end)) {\r
4504 r = ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
4505 goto end;\r
4506 }\r
4507 }\r
4508\r
14b0e578 4509 prev = (UChar* )onigenc_get_prev_char_head(reg->enc, str, at);\r
b602265d 4510 r = match_at(reg, str, end, end, at, prev, &msa);\r
14b0e578
CS
4511 }\r
4512\r
b602265d 4513 end:\r
14b0e578 4514 MATCH_ARG_FREE(msa);\r
14b0e578
CS
4515 return r;\r
4516}\r
4517\r
4518static int\r
4519forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,\r
b602265d 4520 UChar* range, UChar** low, UChar** high, UChar** low_prev)\r
14b0e578
CS
4521{\r
4522 UChar *p, *pprev = (UChar* )NULL;\r
4523\r
4524#ifdef ONIG_DEBUG_SEARCH\r
b602265d
DG
4525 fprintf(stderr, "forward_search_range: str: %p, end: %p, s: %p, range: %p\n",\r
4526 str, end, s, range);\r
14b0e578
CS
4527#endif\r
4528\r
4529 p = s;\r
4530 if (reg->dmin > 0) {\r
4531 if (ONIGENC_IS_SINGLEBYTE(reg->enc)) {\r
4532 p += reg->dmin;\r
4533 }\r
4534 else {\r
4535 UChar *q = p + reg->dmin;\r
b602265d
DG
4536\r
4537 if (q >= end) return 0; /* fail */\r
14b0e578
CS
4538 while (p < q) p += enclen(reg->enc, p);\r
4539 }\r
4540 }\r
4541\r
4542 retry:\r
4543 switch (reg->optimize) {\r
b26691c4 4544 case OPTIMIZE_STR:\r
14b0e578
CS
4545 p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);\r
4546 break;\r
b26691c4 4547 case OPTIMIZE_STR_CASE_FOLD:\r
14b0e578
CS
4548 p = slow_search_ic(reg->enc, reg->case_fold_flag,\r
4549 reg->exact, reg->exact_end, p, end, range);\r
4550 break;\r
4551\r
b26691c4
LG
4552 case OPTIMIZE_STR_CASE_FOLD_FAST:\r
4553 p = sunday_quick_search_case_fold(reg, reg->exact, reg->exact_end, p, end,\r
4554 range);\r
14b0e578
CS
4555 break;\r
4556\r
b26691c4
LG
4557 case OPTIMIZE_STR_FAST:\r
4558 p = sunday_quick_search(reg, reg->exact, reg->exact_end, p, end, range);\r
4559 break;\r
4560\r
4561 case OPTIMIZE_STR_FAST_STEP_FORWARD:\r
4562 p = sunday_quick_search_step_forward(reg, reg->exact, reg->exact_end,\r
4563 p, end, range);\r
14b0e578
CS
4564 break;\r
4565\r
b602265d 4566 case OPTIMIZE_MAP:\r
14b0e578
CS
4567 p = map_search(reg->enc, reg->map, p, range);\r
4568 break;\r
4569 }\r
4570\r
4571 if (p && p < range) {\r
4572 if (p - reg->dmin < s) {\r
4573 retry_gate:\r
4574 pprev = p;\r
4575 p += enclen(reg->enc, p);\r
4576 goto retry;\r
4577 }\r
4578\r
4579 if (reg->sub_anchor) {\r
4580 UChar* prev;\r
4581\r
4582 switch (reg->sub_anchor) {\r
b26691c4 4583 case ANCR_BEGIN_LINE:\r
b602265d
DG
4584 if (!ON_STR_BEGIN(p)) {\r
4585 prev = onigenc_get_prev_char_head(reg->enc,\r
4586 (pprev ? pprev : str), p);\r
4587 if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))\r
4588 goto retry_gate;\r
4589 }\r
4590 break;\r
14b0e578 4591\r
b26691c4 4592 case ANCR_END_LINE:\r
b602265d 4593 if (ON_STR_END(p)) {\r
14b0e578 4594#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
b602265d
DG
4595 prev = (UChar* )onigenc_get_prev_char_head(reg->enc,\r
4596 (pprev ? pprev : str), p);\r
4597 if (prev && ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))\r
4598 goto retry_gate;\r
14b0e578 4599#endif\r
b602265d
DG
4600 }\r
4601 else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)\r
14b0e578 4602#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
b602265d 4603 && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)\r
14b0e578 4604#endif\r
b602265d
DG
4605 )\r
4606 goto retry_gate;\r
4607 break;\r
14b0e578
CS
4608 }\r
4609 }\r
4610\r
4611 if (reg->dmax == 0) {\r
4612 *low = p;\r
4613 if (low_prev) {\r
b602265d
DG
4614 if (*low > s)\r
4615 *low_prev = onigenc_get_prev_char_head(reg->enc, s, p);\r
4616 else\r
4617 *low_prev = onigenc_get_prev_char_head(reg->enc,\r
4618 (pprev ? pprev : str), p);\r
14b0e578
CS
4619 }\r
4620 }\r
4621 else {\r
b602265d
DG
4622 if (reg->dmax != INFINITE_LEN) {\r
4623 if (p - str < reg->dmax) {\r
4624 *low = (UChar* )str;\r
4625 if (low_prev)\r
4626 *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low);\r
4627 }\r
4628 else {\r
4629 *low = p - reg->dmax;\r
4630 if (*low > s) {\r
4631 *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,\r
4632 *low, (const UChar** )low_prev);\r
4633 if (low_prev && IS_NULL(*low_prev))\r
4634 *low_prev = onigenc_get_prev_char_head(reg->enc,\r
4635 (pprev ? pprev : s), *low);\r
4636 }\r
4637 else {\r
4638 if (low_prev)\r
4639 *low_prev = onigenc_get_prev_char_head(reg->enc,\r
4640 (pprev ? pprev : str), *low);\r
4641 }\r
4642 }\r
14b0e578
CS
4643 }\r
4644 }\r
4645 /* no needs to adjust *high, *high is used as range check only */\r
4646 *high = p - reg->dmin;\r
4647\r
4648#ifdef ONIG_DEBUG_SEARCH\r
4649 fprintf(stderr,\r
b602265d
DG
4650 "forward_search_range success: low: %d, high: %d, dmin: %d, dmax: %d\n",\r
4651 (int )(*low - str), (int )(*high - str), reg->dmin, reg->dmax);\r
14b0e578
CS
4652#endif\r
4653 return 1; /* success */\r
4654 }\r
4655\r
4656 return 0; /* fail */\r
4657}\r
4658\r
14b0e578 4659\r
14b0e578
CS
4660static int\r
4661backward_search_range(regex_t* reg, const UChar* str, const UChar* end,\r
b602265d
DG
4662 UChar* s, const UChar* range, UChar* adjrange,\r
4663 UChar** low, UChar** high)\r
14b0e578 4664{\r
14b0e578 4665 UChar *p;\r
b26691c4 4666\r
3948c510 4667 if (range == 0) goto fail;\r
b26691c4 4668\r
14b0e578
CS
4669 range += reg->dmin;\r
4670 p = s;\r
4671\r
4672 retry:\r
4673 switch (reg->optimize) {\r
b26691c4 4674 case OPTIMIZE_STR:\r
14b0e578
CS
4675 exact_method:\r
4676 p = slow_search_backward(reg->enc, reg->exact, reg->exact_end,\r
b602265d 4677 range, adjrange, end, p);\r
14b0e578
CS
4678 break;\r
4679\r
b26691c4
LG
4680 case OPTIMIZE_STR_CASE_FOLD:\r
4681 case OPTIMIZE_STR_CASE_FOLD_FAST:\r
14b0e578
CS
4682 p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,\r
4683 reg->exact, reg->exact_end,\r
4684 range, adjrange, end, p);\r
4685 break;\r
4686\r
b26691c4
LG
4687 case OPTIMIZE_STR_FAST:\r
4688 case OPTIMIZE_STR_FAST_STEP_FORWARD:\r
b602265d 4689 goto exact_method;\r
14b0e578
CS
4690 break;\r
4691\r
b602265d 4692 case OPTIMIZE_MAP:\r
14b0e578
CS
4693 p = map_search_backward(reg->enc, reg->map, range, adjrange, p);\r
4694 break;\r
4695 }\r
4696\r
4697 if (p) {\r
4698 if (reg->sub_anchor) {\r
4699 UChar* prev;\r
4700\r
4701 switch (reg->sub_anchor) {\r
b26691c4 4702 case ANCR_BEGIN_LINE:\r
b602265d
DG
4703 if (!ON_STR_BEGIN(p)) {\r
4704 prev = onigenc_get_prev_char_head(reg->enc, str, p);\r
3948c510 4705 if (IS_NOT_NULL(prev) && !ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {\r
b602265d
DG
4706 p = prev;\r
4707 goto retry;\r
4708 }\r
4709 }\r
4710 break;\r
14b0e578 4711\r
b26691c4 4712 case ANCR_END_LINE:\r
b602265d 4713 if (ON_STR_END(p)) {\r
14b0e578 4714#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
b602265d
DG
4715 prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);\r
4716 if (IS_NULL(prev)) goto fail;\r
4717 if (ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {\r
4718 p = prev;\r
4719 goto retry;\r
4720 }\r
4721#endif\r
4722 }\r
4723 else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)\r
14b0e578 4724#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
b602265d 4725 && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)\r
14b0e578 4726#endif\r
b602265d
DG
4727 ) {\r
4728 p = onigenc_get_prev_char_head(reg->enc, adjrange, p);\r
4729 if (IS_NULL(p)) goto fail;\r
4730 goto retry;\r
4731 }\r
4732 break;\r
14b0e578
CS
4733 }\r
4734 }\r
4735\r
4736 /* no needs to adjust *high, *high is used as range check only */\r
b602265d 4737 if (reg->dmax != INFINITE_LEN) {\r
14b0e578
CS
4738 *low = p - reg->dmax;\r
4739 *high = p - reg->dmin;\r
4740 *high = onigenc_get_right_adjust_char_head(reg->enc, adjrange, *high);\r
4741 }\r
4742\r
4743#ifdef ONIG_DEBUG_SEARCH\r
4744 fprintf(stderr, "backward_search_range: low: %d, high: %d\n",\r
b602265d 4745 (int )(*low - str), (int )(*high - str));\r
14b0e578
CS
4746#endif\r
4747 return 1; /* success */\r
4748 }\r
4749\r
4750 fail:\r
4751#ifdef ONIG_DEBUG_SEARCH\r
4752 fprintf(stderr, "backward_search_range: fail.\n");\r
4753#endif\r
4754 return 0; /* fail */\r
4755}\r
4756\r
4757\r
4758extern int\r
4759onig_search(regex_t* reg, const UChar* str, const UChar* end,\r
b602265d
DG
4760 const UChar* start, const UChar* range, OnigRegion* region,\r
4761 OnigOptionType option)\r
4762{\r
4763 int r;\r
4764 OnigMatchParam mp;\r
4765\r
4766 onig_initialize_match_param(&mp);\r
4767 r = onig_search_with_param(reg, str, end, start, range, region, option, &mp);\r
4768 onig_free_match_param_content(&mp);\r
4769 return r;\r
4770\r
4771}\r
4772\r
4773extern int\r
4774onig_search_with_param(regex_t* reg, const UChar* str, const UChar* end,\r
4775 const UChar* start, const UChar* range, OnigRegion* region,\r
4776 OnigOptionType option, OnigMatchParam* mp)\r
14b0e578
CS
4777{\r
4778 int r;\r
4779 UChar *s, *prev;\r
b602265d 4780 MatchArg msa;\r
14b0e578 4781 const UChar *orig_start = start;\r
14b0e578 4782 const UChar *orig_range = range;\r
14b0e578
CS
4783\r
4784#ifdef ONIG_DEBUG_SEARCH\r
4785 fprintf(stderr,\r
b602265d
DG
4786 "onig_search (entry point): str: %p, end: %d, start: %d, range: %d\n",\r
4787 str, (int )(end - str), (int )(start - str), (int )(range - str));\r
14b0e578
CS
4788#endif\r
4789\r
b602265d
DG
4790 ADJUST_MATCH_PARAM(reg, mp);\r
4791\r
14b0e578
CS
4792 if (region\r
4793#ifdef USE_POSIX_API_REGION_OPTION\r
4794 && !IS_POSIX_REGION(option)\r
4795#endif\r
4796 ) {\r
4797 r = onig_region_resize_clear(region, reg->num_mem + 1);\r
b602265d 4798 if (r != 0) goto finish_no_msa;\r
14b0e578
CS
4799 }\r
4800\r
4801 if (start > end || start < str) goto mismatch_no_msa;\r
4802\r
b602265d
DG
4803 if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
4804 if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end)) {\r
4805 r = ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
4806 goto finish_no_msa;\r
4807 }\r
4808 }\r
4809\r
14b0e578 4810\r
14b0e578
CS
4811#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
4812#define MATCH_AND_RETURN_CHECK(upper_range) \\r
4813 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \\r
4814 if (r != ONIG_MISMATCH) {\\r
4815 if (r >= 0) {\\r
4816 if (! IS_FIND_LONGEST(reg->options)) {\\r
4817 goto match;\\r
4818 }\\r
4819 }\\r
4820 else goto finish; /* error */ \\r
4821 }\r
4822#else\r
4823#define MATCH_AND_RETURN_CHECK(upper_range) \\r
4824 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \\r
4825 if (r != ONIG_MISMATCH) {\\r
4826 if (r >= 0) {\\r
4827 goto match;\\r
4828 }\\r
4829 else goto finish; /* error */ \\r
4830 }\r
4831#endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */\r
14b0e578
CS
4832\r
4833\r
4834 /* anchor optimize: resume search range */\r
4835 if (reg->anchor != 0 && str < end) {\r
4836 UChar *min_semi_end, *max_semi_end;\r
4837\r
b26691c4 4838 if (reg->anchor & ANCR_BEGIN_POSITION) {\r
14b0e578
CS
4839 /* search start-position only */\r
4840 begin_position:\r
4841 if (range > start)\r
b602265d 4842 range = start + 1;\r
14b0e578 4843 else\r
b602265d 4844 range = start;\r
14b0e578 4845 }\r
b26691c4 4846 else if (reg->anchor & ANCR_BEGIN_BUF) {\r
14b0e578
CS
4847 /* search str-position only */\r
4848 if (range > start) {\r
b602265d
DG
4849 if (start != str) goto mismatch_no_msa;\r
4850 range = str + 1;\r
14b0e578
CS
4851 }\r
4852 else {\r
b602265d
DG
4853 if (range <= str) {\r
4854 start = str;\r
4855 range = str;\r
4856 }\r
4857 else\r
4858 goto mismatch_no_msa;\r
14b0e578
CS
4859 }\r
4860 }\r
b26691c4 4861 else if (reg->anchor & ANCR_END_BUF) {\r
14b0e578
CS
4862 min_semi_end = max_semi_end = (UChar* )end;\r
4863\r
4864 end_buf:\r
b602265d
DG
4865 if ((OnigLen )(max_semi_end - str) < reg->anchor_dmin)\r
4866 goto mismatch_no_msa;\r
14b0e578
CS
4867\r
4868 if (range > start) {\r
b602265d
DG
4869 if ((OnigLen )(min_semi_end - start) > reg->anchor_dmax) {\r
4870 start = min_semi_end - reg->anchor_dmax;\r
4871 if (start < end)\r
4872 start = onigenc_get_right_adjust_char_head(reg->enc, str, start);\r
4873 }\r
4874 if ((OnigLen )(max_semi_end - (range - 1)) < reg->anchor_dmin) {\r
4875 range = max_semi_end - reg->anchor_dmin + 1;\r
4876 }\r
4877\r
4878 if (start > range) goto mismatch_no_msa;\r
4879 /* If start == range, match with empty at end.\r
4880 Backward search is used. */\r
14b0e578
CS
4881 }\r
4882 else {\r
b602265d
DG
4883 if ((OnigLen )(min_semi_end - range) > reg->anchor_dmax) {\r
4884 range = min_semi_end - reg->anchor_dmax;\r
4885 }\r
4886 if ((OnigLen )(max_semi_end - start) < reg->anchor_dmin) {\r
4887 start = max_semi_end - reg->anchor_dmin;\r
4888 start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, start);\r
4889 }\r
4890 if (range > start) goto mismatch_no_msa;\r
14b0e578
CS
4891 }\r
4892 }\r
b26691c4 4893 else if (reg->anchor & ANCR_SEMI_END_BUF) {\r
14b0e578
CS
4894 UChar* pre_end = ONIGENC_STEP_BACK(reg->enc, str, end, 1);\r
4895\r
4896 max_semi_end = (UChar* )end;\r
3948c510
DG
4897 // only when str > end, pre_end will be null\r
4898 // line 4659 "if (start > end || start < str) goto mismatch_no_msa"\r
4899 // will guarantee str alwayls less than end\r
4900 // so pre_end won't be null,this check is just for passing staic analysis\r
4901 if (IS_NOT_NULL(pre_end) && ONIGENC_IS_MBC_NEWLINE(reg->enc, pre_end, end)) {\r
b602265d 4902 min_semi_end = pre_end;\r
14b0e578
CS
4903\r
4904#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
b602265d
DG
4905 pre_end = ONIGENC_STEP_BACK(reg->enc, str, pre_end, 1);\r
4906 if (IS_NOT_NULL(pre_end) &&\r
4907 ONIGENC_IS_MBC_CRNL(reg->enc, pre_end, end)) {\r
4908 min_semi_end = pre_end;\r
4909 }\r
14b0e578 4910#endif\r
b602265d
DG
4911 if (min_semi_end > str && start <= min_semi_end) {\r
4912 goto end_buf;\r
4913 }\r
14b0e578
CS
4914 }\r
4915 else {\r
b602265d
DG
4916 min_semi_end = (UChar* )end;\r
4917 goto end_buf;\r
14b0e578
CS
4918 }\r
4919 }\r
b26691c4 4920 else if ((reg->anchor & ANCR_ANYCHAR_INF_ML)) {\r
14b0e578
CS
4921 goto begin_position;\r
4922 }\r
4923 }\r
4924 else if (str == end) { /* empty string */\r
4925 static const UChar* address_for_empty_string = (UChar* )"";\r
4926\r
4927#ifdef ONIG_DEBUG_SEARCH\r
4928 fprintf(stderr, "onig_search: empty string.\n");\r
4929#endif\r
4930\r
4931 if (reg->threshold_len == 0) {\r
4932 start = end = str = address_for_empty_string;\r
4933 s = (UChar* )start;\r
4934 prev = (UChar* )NULL;\r
4935\r
b602265d 4936 MATCH_ARG_INIT(msa, reg, option, region, start, mp);\r
14b0e578
CS
4937 MATCH_AND_RETURN_CHECK(end);\r
4938 goto mismatch;\r
4939 }\r
4940 goto mismatch_no_msa;\r
4941 }\r
4942\r
4943#ifdef ONIG_DEBUG_SEARCH\r
4944 fprintf(stderr, "onig_search(apply anchor): end: %d, start: %d, range: %d\n",\r
b602265d 4945 (int )(end - str), (int )(start - str), (int )(range - str));\r
14b0e578
CS
4946#endif\r
4947\r
b602265d 4948 MATCH_ARG_INIT(msa, reg, option, region, orig_start, mp);\r
14b0e578
CS
4949\r
4950 s = (UChar* )start;\r
4951 if (range > start) { /* forward search */\r
4952 if (s > str)\r
4953 prev = onigenc_get_prev_char_head(reg->enc, str, s);\r
4954 else\r
4955 prev = (UChar* )NULL;\r
4956\r
b602265d 4957 if (reg->optimize != OPTIMIZE_NONE) {\r
14b0e578
CS
4958 UChar *sch_range, *low, *high, *low_prev;\r
4959\r
4960 sch_range = (UChar* )range;\r
4961 if (reg->dmax != 0) {\r
b602265d
DG
4962 if (reg->dmax == INFINITE_LEN)\r
4963 sch_range = (UChar* )end;\r
4964 else {\r
4965 sch_range += reg->dmax;\r
4966 if (sch_range > end) sch_range = (UChar* )end;\r
4967 }\r
14b0e578
CS
4968 }\r
4969\r
4970 if ((end - start) < reg->threshold_len)\r
4971 goto mismatch;\r
4972\r
b602265d
DG
4973 if (reg->dmax != INFINITE_LEN) {\r
4974 do {\r
4975 if (! forward_search_range(reg, str, end, s, sch_range,\r
4976 &low, &high, &low_prev)) goto mismatch;\r
4977 if (s < low) {\r
4978 s = low;\r
4979 prev = low_prev;\r
4980 }\r
4981 while (s <= high) {\r
4982 MATCH_AND_RETURN_CHECK(orig_range);\r
4983 prev = s;\r
4984 s += enclen(reg->enc, s);\r
4985 }\r
4986 } while (s < range);\r
4987 goto mismatch;\r
14b0e578
CS
4988 }\r
4989 else { /* check only. */\r
b602265d
DG
4990 if (! forward_search_range(reg, str, end, s, sch_range,\r
4991 &low, &high, (UChar** )NULL)) goto mismatch;\r
14b0e578 4992\r
b26691c4 4993 if ((reg->anchor & ANCR_ANYCHAR_INF) != 0) {\r
14b0e578
CS
4994 do {\r
4995 MATCH_AND_RETURN_CHECK(orig_range);\r
4996 prev = s;\r
4997 s += enclen(reg->enc, s);\r
4998\r
b26691c4 4999 if ((reg->anchor & (ANCR_LOOK_BEHIND | ANCR_PREC_READ_NOT)) == 0) {\r
b602265d
DG
5000 while (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end) && s < range) {\r
5001 prev = s;\r
5002 s += enclen(reg->enc, s);\r
5003 }\r
14b0e578
CS
5004 }\r
5005 } while (s < range);\r
5006 goto mismatch;\r
5007 }\r
5008 }\r
5009 }\r
5010\r
5011 do {\r
5012 MATCH_AND_RETURN_CHECK(orig_range);\r
5013 prev = s;\r
5014 s += enclen(reg->enc, s);\r
5015 } while (s < range);\r
5016\r
5017 if (s == range) { /* because empty match with /$/. */\r
5018 MATCH_AND_RETURN_CHECK(orig_range);\r
5019 }\r
5020 }\r
5021 else { /* backward search */\r
b26691c4
LG
5022 if (range < str) goto mismatch;\r
5023\r
14b0e578
CS
5024 if (orig_start < end)\r
5025 orig_start += enclen(reg->enc, orig_start); /* is upper range */\r
14b0e578 5026\r
b602265d 5027 if (reg->optimize != OPTIMIZE_NONE) {\r
14b0e578
CS
5028 UChar *low, *high, *adjrange, *sch_start;\r
5029\r
5030 if (range < end)\r
b602265d 5031 adjrange = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, range);\r
14b0e578 5032 else\r
b602265d
DG
5033 adjrange = (UChar* )end;\r
5034\r
5035 if (reg->dmax != INFINITE_LEN &&\r
5036 (end - range) >= reg->threshold_len) {\r
5037 do {\r
5038 sch_start = s + reg->dmax;\r
5039 if (sch_start > end) sch_start = (UChar* )end;\r
5040 if (backward_search_range(reg, str, end, sch_start, range, adjrange,\r
5041 &low, &high) <= 0)\r
5042 goto mismatch;\r
5043\r
5044 if (s > high)\r
5045 s = high;\r
5046\r
5047 while (s >= low) {\r
5048 prev = onigenc_get_prev_char_head(reg->enc, str, s);\r
5049 MATCH_AND_RETURN_CHECK(orig_start);\r
5050 s = prev;\r
5051 }\r
3948c510
DG
5052 // if range is not null,the check is not necessary.\r
5053 // the range is actually the pointer of the end of the matched string\r
5054 // or assigned by "range = str" in line 4708. In RegularExpressionMatch\r
5055 // protocol, the matched string is the parameter String. And str in\r
5056 // line 4708 is the String,too. and the range is calculated from\r
5057 // "Start + onigenc_str_bytelen_null (CHAR16_ENCODING, Start)" in\r
5058 // line 146 in RegularExpressionDxe.c. RegularExpressionMatch ensure\r
5059 // the String is not null,So in both situation, the range can not be NULL.\r
5060 // This check is just for passing static analysis.\r
5061 if(IS_NULL(s))break;\r
b602265d
DG
5062 } while (s >= range);\r
5063 goto mismatch;\r
14b0e578
CS
5064 }\r
5065 else { /* check only. */\r
b602265d
DG
5066 if ((end - range) < reg->threshold_len) goto mismatch;\r
5067\r
5068 sch_start = s;\r
5069 if (reg->dmax != 0) {\r
5070 if (reg->dmax == INFINITE_LEN)\r
5071 sch_start = (UChar* )end;\r
5072 else {\r
5073 sch_start += reg->dmax;\r
5074 if (sch_start > end) sch_start = (UChar* )end;\r
5075 else\r
5076 sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc,\r
5077 start, sch_start);\r
5078 }\r
5079 }\r
5080 if (backward_search_range(reg, str, end, sch_start, range, adjrange,\r
5081 &low, &high) <= 0) goto mismatch;\r
14b0e578
CS
5082 }\r
5083 }\r
5084\r
5085 do {\r
5086 prev = onigenc_get_prev_char_head(reg->enc, str, s);\r
5087 MATCH_AND_RETURN_CHECK(orig_start);\r
5088 s = prev;\r
5089 } while (s >= range);\r
5090 }\r
5091\r
5092 mismatch:\r
5093#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
5094 if (IS_FIND_LONGEST(reg->options)) {\r
5095 if (msa.best_len >= 0) {\r
5096 s = msa.best_s;\r
5097 goto match;\r
5098 }\r
5099 }\r
5100#endif\r
5101 r = ONIG_MISMATCH;\r
5102\r
5103 finish:\r
5104 MATCH_ARG_FREE(msa);\r
14b0e578
CS
5105\r
5106 /* If result is mismatch and no FIND_NOT_EMPTY option,\r
b602265d 5107 then the region is not set in match_at(). */\r
14b0e578
CS
5108 if (IS_FIND_NOT_EMPTY(reg->options) && region\r
5109#ifdef USE_POSIX_API_REGION_OPTION\r
5110 && !IS_POSIX_REGION(option)\r
5111#endif\r
5112 ) {\r
5113 onig_region_clear(region);\r
5114 }\r
5115\r
5116#ifdef ONIG_DEBUG\r
5117 if (r != ONIG_MISMATCH)\r
5118 fprintf(stderr, "onig_search: error %d\n", r);\r
5119#endif\r
5120 return r;\r
5121\r
5122 mismatch_no_msa:\r
5123 r = ONIG_MISMATCH;\r
5124 finish_no_msa:\r
14b0e578
CS
5125#ifdef ONIG_DEBUG\r
5126 if (r != ONIG_MISMATCH)\r
5127 fprintf(stderr, "onig_search: error %d\n", r);\r
5128#endif\r
5129 return r;\r
5130\r
5131 match:\r
14b0e578 5132 MATCH_ARG_FREE(msa);\r
b602265d
DG
5133 return (int )(s - str);\r
5134}\r
5135\r
5136extern int\r
5137onig_scan(regex_t* reg, const UChar* str, const UChar* end,\r
5138 OnigRegion* region, OnigOptionType option,\r
5139 int (*scan_callback)(int, int, OnigRegion*, void*),\r
5140 void* callback_arg)\r
5141{\r
5142 int r;\r
5143 int n;\r
5144 int rs;\r
5145 const UChar* start;\r
5146\r
5147 if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
5148 if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end))\r
5149 return ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
5150\r
5151 ONIG_OPTION_OFF(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING);\r
5152 }\r
5153\r
5154 n = 0;\r
5155 start = str;\r
5156 while (1) {\r
5157 r = onig_search(reg, str, end, start, end, region, option);\r
5158 if (r >= 0) {\r
5159 rs = scan_callback(n, r, region, callback_arg);\r
5160 n++;\r
5161 if (rs != 0)\r
5162 return rs;\r
5163\r
5164 if (region->end[0] == start - str) {\r
5165 if (start >= end) break;\r
5166 start += enclen(reg->enc, start);\r
5167 }\r
5168 else\r
5169 start = str + region->end[0];\r
5170\r
5171 if (start > end)\r
5172 break;\r
5173 }\r
5174 else if (r == ONIG_MISMATCH) {\r
5175 break;\r
5176 }\r
5177 else { /* error */\r
5178 return r;\r
5179 }\r
5180 }\r
5181\r
5182 return n;\r
14b0e578
CS
5183}\r
5184\r
5185extern OnigEncoding\r
5186onig_get_encoding(regex_t* reg)\r
5187{\r
5188 return reg->enc;\r
5189}\r
5190\r
5191extern OnigOptionType\r
5192onig_get_options(regex_t* reg)\r
5193{\r
5194 return reg->options;\r
5195}\r
5196\r
5197extern OnigCaseFoldType\r
5198onig_get_case_fold_flag(regex_t* reg)\r
5199{\r
5200 return reg->case_fold_flag;\r
5201}\r
5202\r
5203extern OnigSyntaxType*\r
5204onig_get_syntax(regex_t* reg)\r
5205{\r
5206 return reg->syntax;\r
5207}\r
5208\r
5209extern int\r
5210onig_number_of_captures(regex_t* reg)\r
5211{\r
5212 return reg->num_mem;\r
5213}\r
5214\r
5215extern int\r
5216onig_number_of_capture_histories(regex_t* reg)\r
5217{\r
5218#ifdef USE_CAPTURE_HISTORY\r
5219 int i, n;\r
5220\r
5221 n = 0;\r
5222 for (i = 0; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {\r
b602265d 5223 if (MEM_STATUS_AT(reg->capture_history, i) != 0)\r
14b0e578
CS
5224 n++;\r
5225 }\r
5226 return n;\r
5227#else\r
5228 return 0;\r
5229#endif\r
5230}\r
5231\r
5232extern void\r
5233onig_copy_encoding(OnigEncoding to, OnigEncoding from)\r
5234{\r
5235 *to = *from;\r
5236}\r
5237\r
b26691c4
LG
5238#ifdef USE_DIRECT_THREADED_CODE\r
5239extern int\r
5240onig_init_for_match_at(regex_t* reg)\r
5241{\r
5242 return match_at(reg, (const UChar* )NULL, (const UChar* )NULL,\r
5243 (const UChar* )NULL, (const UChar* )NULL, (UChar* )NULL,\r
5244 (MatchArg* )NULL);\r
5245}\r
5246#endif\r
5247\r
b602265d
DG
5248\r
5249/* for callout functions */\r
5250\r
5251#ifdef USE_CALLOUT\r
5252\r
5253extern OnigCalloutFunc\r
5254onig_get_progress_callout(void)\r
5255{\r
5256 return DefaultProgressCallout;\r
5257}\r
5258\r
5259extern int\r
5260onig_set_progress_callout(OnigCalloutFunc f)\r
5261{\r
5262 DefaultProgressCallout = f;\r
5263 return ONIG_NORMAL;\r
5264}\r
5265\r
5266extern OnigCalloutFunc\r
5267onig_get_retraction_callout(void)\r
5268{\r
5269 return DefaultRetractionCallout;\r
5270}\r
5271\r
5272extern int\r
5273onig_set_retraction_callout(OnigCalloutFunc f)\r
5274{\r
5275 DefaultRetractionCallout = f;\r
5276 return ONIG_NORMAL;\r
5277}\r
5278\r
5279extern int\r
5280onig_get_callout_num_by_callout_args(OnigCalloutArgs* args)\r
5281{\r
5282 return args->num;\r
5283}\r
5284\r
5285extern OnigCalloutIn\r
5286onig_get_callout_in_by_callout_args(OnigCalloutArgs* args)\r
5287{\r
5288 return args->in;\r
5289}\r
5290\r
5291extern int\r
5292onig_get_name_id_by_callout_args(OnigCalloutArgs* args)\r
5293{\r
5294 return args->name_id;\r
5295}\r
5296\r
5297extern const UChar*\r
5298onig_get_contents_by_callout_args(OnigCalloutArgs* args)\r
5299{\r
5300 int num;\r
5301 CalloutListEntry* e;\r
5302\r
5303 num = args->num;\r
5304 e = onig_reg_callout_list_at(args->regex, num);\r
5305 if (IS_NULL(e)) return 0;\r
5306 if (e->of == ONIG_CALLOUT_OF_CONTENTS) {\r
5307 return e->u.content.start;\r
5308 }\r
5309\r
5310 return 0;\r
5311}\r
5312\r
5313extern const UChar*\r
5314onig_get_contents_end_by_callout_args(OnigCalloutArgs* args)\r
5315{\r
5316 int num;\r
5317 CalloutListEntry* e;\r
5318\r
5319 num = args->num;\r
5320 e = onig_reg_callout_list_at(args->regex, num);\r
5321 if (IS_NULL(e)) return 0;\r
5322 if (e->of == ONIG_CALLOUT_OF_CONTENTS) {\r
5323 return e->u.content.end;\r
5324 }\r
5325\r
5326 return 0;\r
5327}\r
5328\r
5329extern int\r
5330onig_get_args_num_by_callout_args(OnigCalloutArgs* args)\r
5331{\r
5332 int num;\r
5333 CalloutListEntry* e;\r
5334\r
5335 num = args->num;\r
5336 e = onig_reg_callout_list_at(args->regex, num);\r
5337 if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
5338 if (e->of == ONIG_CALLOUT_OF_NAME) {\r
5339 return e->u.arg.num;\r
5340 }\r
5341\r
5342 return ONIGERR_INVALID_ARGUMENT;\r
5343}\r
5344\r
5345extern int\r
5346onig_get_passed_args_num_by_callout_args(OnigCalloutArgs* args)\r
5347{\r
5348 int num;\r
5349 CalloutListEntry* e;\r
5350\r
5351 num = args->num;\r
5352 e = onig_reg_callout_list_at(args->regex, num);\r
5353 if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
5354 if (e->of == ONIG_CALLOUT_OF_NAME) {\r
5355 return e->u.arg.passed_num;\r
5356 }\r
5357\r
5358 return ONIGERR_INVALID_ARGUMENT;\r
5359}\r
5360\r
5361extern int\r
5362onig_get_arg_by_callout_args(OnigCalloutArgs* args, int index,\r
5363 OnigType* type, OnigValue* val)\r
5364{\r
5365 int num;\r
5366 CalloutListEntry* e;\r
5367\r
5368 num = args->num;\r
5369 e = onig_reg_callout_list_at(args->regex, num);\r
5370 if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
5371 if (e->of == ONIG_CALLOUT_OF_NAME) {\r
5372 if (IS_NOT_NULL(type)) *type = e->u.arg.types[index];\r
5373 if (IS_NOT_NULL(val)) *val = e->u.arg.vals[index];\r
5374 return ONIG_NORMAL;\r
5375 }\r
5376\r
5377 return ONIGERR_INVALID_ARGUMENT;\r
5378}\r
5379\r
5380extern const UChar*\r
5381onig_get_string_by_callout_args(OnigCalloutArgs* args)\r
5382{\r
5383 return args->string;\r
5384}\r
5385\r
5386extern const UChar*\r
5387onig_get_string_end_by_callout_args(OnigCalloutArgs* args)\r
5388{\r
5389 return args->string_end;\r
5390}\r
5391\r
5392extern const UChar*\r
5393onig_get_start_by_callout_args(OnigCalloutArgs* args)\r
5394{\r
5395 return args->start;\r
5396}\r
5397\r
5398extern const UChar*\r
5399onig_get_right_range_by_callout_args(OnigCalloutArgs* args)\r
5400{\r
5401 return args->right_range;\r
5402}\r
5403\r
5404extern const UChar*\r
5405onig_get_current_by_callout_args(OnigCalloutArgs* args)\r
5406{\r
5407 return args->current;\r
5408}\r
5409\r
5410extern OnigRegex\r
5411onig_get_regex_by_callout_args(OnigCalloutArgs* args)\r
5412{\r
5413 return args->regex;\r
5414}\r
5415\r
5416extern unsigned long\r
5417onig_get_retry_counter_by_callout_args(OnigCalloutArgs* args)\r
5418{\r
5419 return args->retry_in_match_counter;\r
5420}\r
5421\r
5422\r
5423extern int\r
5424onig_get_capture_range_in_callout(OnigCalloutArgs* a, int mem_num, int* begin, int* end)\r
5425{\r
5426 OnigRegex reg;\r
5427 const UChar* str;\r
5428 StackType* stk_base;\r
5429 int i;\r
5430\r
5431 i = mem_num;\r
5432 reg = a->regex;\r
5433 str = a->string;\r
5434 stk_base = a->stk_base;\r
5435\r
5436 if (i > 0) {\r
5437 if (a->mem_end_stk[i] != INVALID_STACK_INDEX) {\r
5438 if (MEM_STATUS_AT(reg->bt_mem_start, i))\r
5439 *begin = (int )(STACK_AT(a->mem_start_stk[i])->u.mem.pstr - str);\r
5440 else\r
5441 *begin = (int )((UChar* )((void* )a->mem_start_stk[i]) - str);\r
5442\r
5443 *end = (int )((MEM_STATUS_AT(reg->bt_mem_end, i)\r
5444 ? STACK_AT(a->mem_end_stk[i])->u.mem.pstr\r
5445 : (UChar* )((void* )a->mem_end_stk[i])) - str);\r
5446 }\r
5447 else {\r
5448 *begin = *end = ONIG_REGION_NOTPOS;\r
5449 }\r
5450 }\r
5451 else if (i == 0) {\r
5452#if 0\r
5453 *begin = a->start - str;\r
5454 *end = a->current - str;\r
5455#else\r
5456 return ONIGERR_INVALID_ARGUMENT;\r
5457#endif\r
5458 }\r
5459 else\r
5460 return ONIGERR_INVALID_ARGUMENT;\r
5461\r
5462 return ONIG_NORMAL;\r
5463}\r
5464\r
5465extern int\r
5466onig_get_used_stack_size_in_callout(OnigCalloutArgs* a, int* used_num, int* used_bytes)\r
5467{\r
5468 int n;\r
5469\r
5470 n = (int )(a->stk - a->stk_base);\r
5471\r
5472 if (used_num != 0)\r
5473 *used_num = n;\r
5474\r
5475 if (used_bytes != 0)\r
5476 *used_bytes = n * sizeof(StackType);\r
5477\r
5478 return ONIG_NORMAL;\r
5479}\r
5480\r
5481\r
5482/* builtin callout functions */\r
5483\r
5484extern int\r
5485onig_builtin_fail(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
5486{\r
5487 return ONIG_CALLOUT_FAIL;\r
5488}\r
5489\r
5490extern int\r
5491onig_builtin_mismatch(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
5492{\r
5493 return ONIG_MISMATCH;\r
5494}\r
5495\r
5496#if 0\r
5497extern int\r
5498onig_builtin_success(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
5499{\r
5500 return ONIG_CALLOUT_SUCCESS;\r
5501}\r
5502#endif\r
5503\r
5504extern int\r
5505onig_builtin_error(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
5506{\r
5507 int r;\r
5508 int n;\r
5509 OnigValue val;\r
5510\r
5511 r = onig_get_arg_by_callout_args(args, 0, 0, &val);\r
5512 if (r != ONIG_NORMAL) return r;\r
5513\r
5514 n = (int )val.l;\r
5515 if (n >= 0) {\r
5516 n = ONIGERR_INVALID_CALLOUT_BODY;\r
5517 }\r
b26691c4
LG
5518 else if (onig_is_error_code_needs_param(n)) {\r
5519 n = ONIGERR_INVALID_CALLOUT_BODY;\r
5520 }\r
b602265d
DG
5521\r
5522 return n;\r
5523}\r
5524\r
5525extern int\r
5526onig_builtin_count(OnigCalloutArgs* args, void* user_data)\r
5527{\r
5528 (void )onig_check_callout_data_and_clear_old_values(args);\r
5529\r
5530 return onig_builtin_total_count(args, user_data);\r
5531}\r
5532\r
5533extern int\r
5534onig_builtin_total_count(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
5535{\r
5536 int r;\r
5537 int slot;\r
5538 OnigType type;\r
5539 OnigValue val;\r
5540 OnigValue aval;\r
5541 OnigCodePoint count_type;\r
5542\r
5543 r = onig_get_arg_by_callout_args(args, 0, &type, &aval);\r
5544 if (r != ONIG_NORMAL) return r;\r
5545\r
5546 count_type = aval.c;\r
5547 if (count_type != '>' && count_type != 'X' && count_type != '<')\r
5548 return ONIGERR_INVALID_CALLOUT_ARG;\r
5549\r
5550 r = onig_get_callout_data_by_callout_args_self_dont_clear_old(args, 0,\r
5551 &type, &val);\r
5552 if (r < ONIG_NORMAL)\r
5553 return r;\r
5554 else if (r > ONIG_NORMAL) {\r
5555 /* type == void: initial state */\r
5556 val.l = 0;\r
5557 }\r
5558\r
5559 if (args->in == ONIG_CALLOUT_IN_RETRACTION) {\r
5560 slot = 2;\r
5561 if (count_type == '<')\r
5562 val.l++;\r
5563 else if (count_type == 'X')\r
5564 val.l--;\r
5565 }\r
5566 else {\r
5567 slot = 1;\r
5568 if (count_type != '<')\r
5569 val.l++;\r
5570 }\r
5571\r
5572 r = onig_set_callout_data_by_callout_args_self(args, 0, ONIG_TYPE_LONG, &val);\r
5573 if (r != ONIG_NORMAL) return r;\r
5574\r
5575 /* slot 1: in progress counter, slot 2: in retraction counter */\r
5576 r = onig_get_callout_data_by_callout_args_self_dont_clear_old(args, slot,\r
5577 &type, &val);\r
5578 if (r < ONIG_NORMAL)\r
5579 return r;\r
5580 else if (r > ONIG_NORMAL) {\r
5581 val.l = 0;\r
5582 }\r
5583\r
5584 val.l++;\r
5585 r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
5586 if (r != ONIG_NORMAL) return r;\r
5587\r
5588 return ONIG_CALLOUT_SUCCESS;\r
5589}\r
5590\r
5591extern int\r
5592onig_builtin_max(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
5593{\r
5594 int r;\r
5595 int slot;\r
5596 long max_val;\r
5597 OnigCodePoint count_type;\r
5598 OnigType type;\r
5599 OnigValue val;\r
5600 OnigValue aval;\r
5601\r
5602 (void )onig_check_callout_data_and_clear_old_values(args);\r
5603\r
5604 slot = 0;\r
5605 r = onig_get_callout_data_by_callout_args_self(args, slot, &type, &val);\r
5606 if (r < ONIG_NORMAL)\r
5607 return r;\r
5608 else if (r > ONIG_NORMAL) {\r
5609 /* type == void: initial state */\r
5610 type = ONIG_TYPE_LONG;\r
5611 val.l = 0;\r
5612 }\r
5613\r
5614 r = onig_get_arg_by_callout_args(args, 0, &type, &aval);\r
5615 if (r != ONIG_NORMAL) return r;\r
5616 if (type == ONIG_TYPE_TAG) {\r
5617 r = onig_get_callout_data_by_callout_args(args, aval.tag, 0, &type, &aval);\r
5618 if (r < ONIG_NORMAL) return r;\r
5619 else if (r > ONIG_NORMAL)\r
5620 max_val = 0L;\r
5621 else\r
5622 max_val = aval.l;\r
5623 }\r
5624 else { /* LONG */\r
5625 max_val = aval.l;\r
5626 }\r
5627\r
5628 r = onig_get_arg_by_callout_args(args, 1, &type, &aval);\r
5629 if (r != ONIG_NORMAL) return r;\r
5630\r
5631 count_type = aval.c;\r
5632 if (count_type != '>' && count_type != 'X' && count_type != '<')\r
5633 return ONIGERR_INVALID_CALLOUT_ARG;\r
5634\r
5635 if (args->in == ONIG_CALLOUT_IN_RETRACTION) {\r
5636 if (count_type == '<') {\r
5637 if (val.l >= max_val) return ONIG_CALLOUT_FAIL;\r
5638 val.l++;\r
5639 }\r
5640 else if (count_type == 'X')\r
5641 val.l--;\r
5642 }\r
5643 else {\r
5644 if (count_type != '<') {\r
5645 if (val.l >= max_val) return ONIG_CALLOUT_FAIL;\r
5646 val.l++;\r
5647 }\r
5648 }\r
5649\r
5650 r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
5651 if (r != ONIG_NORMAL) return r;\r
5652\r
5653 return ONIG_CALLOUT_SUCCESS;\r
5654}\r
5655\r
5656enum OP_CMP {\r
5657 OP_EQ,\r
5658 OP_NE,\r
5659 OP_LT,\r
5660 OP_GT,\r
5661 OP_LE,\r
5662 OP_GE\r
5663};\r
5664\r
5665extern int\r
5666onig_builtin_cmp(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
5667{\r
5668 int r;\r
5669 int slot;\r
5670 long lv;\r
5671 long rv;\r
5672 OnigType type;\r
5673 OnigValue val;\r
5674 regex_t* reg;\r
5675 enum OP_CMP op;\r
5676\r
5677 reg = args->regex;\r
5678\r
5679 r = onig_get_arg_by_callout_args(args, 0, &type, &val);\r
5680 if (r != ONIG_NORMAL) return r;\r
5681\r
5682 if (type == ONIG_TYPE_TAG) {\r
5683 r = onig_get_callout_data_by_callout_args(args, val.tag, 0, &type, &val);\r
5684 if (r < ONIG_NORMAL) return r;\r
5685 else if (r > ONIG_NORMAL)\r
5686 lv = 0L;\r
5687 else\r
5688 lv = val.l;\r
5689 }\r
5690 else { /* ONIG_TYPE_LONG */\r
5691 lv = val.l;\r
5692 }\r
5693\r
5694 r = onig_get_arg_by_callout_args(args, 2, &type, &val);\r
5695 if (r != ONIG_NORMAL) return r;\r
5696\r
5697 if (type == ONIG_TYPE_TAG) {\r
5698 r = onig_get_callout_data_by_callout_args(args, val.tag, 0, &type, &val);\r
5699 if (r < ONIG_NORMAL) return r;\r
5700 else if (r > ONIG_NORMAL)\r
5701 rv = 0L;\r
5702 else\r
5703 rv = val.l;\r
5704 }\r
5705 else { /* ONIG_TYPE_LONG */\r
5706 rv = val.l;\r
5707 }\r
5708\r
5709 slot = 0;\r
5710 r = onig_get_callout_data_by_callout_args_self(args, slot, &type, &val);\r
5711 if (r < ONIG_NORMAL)\r
5712 return r;\r
5713 else if (r > ONIG_NORMAL) {\r
5714 /* type == void: initial state */\r
5715 OnigCodePoint c1, c2;\r
5716 UChar* p;\r
5717\r
5718 r = onig_get_arg_by_callout_args(args, 1, &type, &val);\r
5719 if (r != ONIG_NORMAL) return r;\r
5720\r
5721 p = val.s.start;\r
5722 c1 = ONIGENC_MBC_TO_CODE(reg->enc, p, val.s.end);\r
5723 p += ONIGENC_MBC_ENC_LEN(reg->enc, p);\r
5724 if (p < val.s.end) {\r
5725 c2 = ONIGENC_MBC_TO_CODE(reg->enc, p, val.s.end);\r
5726 p += ONIGENC_MBC_ENC_LEN(reg->enc, p);\r
5727 if (p != val.s.end) return ONIGERR_INVALID_CALLOUT_ARG;\r
5728 }\r
5729 else\r
5730 c2 = 0;\r
5731\r
5732 switch (c1) {\r
5733 case '=':\r
5734 if (c2 != '=') return ONIGERR_INVALID_CALLOUT_ARG;\r
5735 op = OP_EQ;\r
5736 break;\r
5737 case '!':\r
5738 if (c2 != '=') return ONIGERR_INVALID_CALLOUT_ARG;\r
5739 op = OP_NE;\r
5740 break;\r
5741 case '<':\r
5742 if (c2 == '=') op = OP_LE;\r
5743 else if (c2 == 0) op = OP_LT;\r
5744 else return ONIGERR_INVALID_CALLOUT_ARG;\r
5745 break;\r
5746 case '>':\r
5747 if (c2 == '=') op = OP_GE;\r
5748 else if (c2 == 0) op = OP_GT;\r
5749 else return ONIGERR_INVALID_CALLOUT_ARG;\r
5750 break;\r
5751 default:\r
5752 return ONIGERR_INVALID_CALLOUT_ARG;\r
5753 break;\r
5754 }\r
5755 val.l = (long )op;\r
5756 r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
5757 if (r != ONIG_NORMAL) return r;\r
5758 }\r
5759 else {\r
5760 op = (enum OP_CMP )val.l;\r
5761 }\r
5762\r
5763 switch (op) {\r
5764 case OP_EQ: r = (lv == rv); break;\r
5765 case OP_NE: r = (lv != rv); break;\r
5766 case OP_LT: r = (lv < rv); break;\r
5767 case OP_GT: r = (lv > rv); break;\r
5768 case OP_LE: r = (lv <= rv); break;\r
5769 case OP_GE: r = (lv >= rv); break;\r
5770 }\r
5771\r
5772 return r == 0 ? ONIG_CALLOUT_FAIL : ONIG_CALLOUT_SUCCESS;\r
5773}\r
5774\r
5775\r
5776//#include <stdio.h>\r
5777\r
5778static FILE* OutFp;\r
5779\r
5780/* name start with "onig_" for macros. */\r
5781static int\r
5782onig_builtin_monitor(OnigCalloutArgs* args, void* user_data)\r
5783{\r
5784 int r;\r
5785 int num;\r
5786 size_t tag_len;\r
8122c6bc
GD
5787 // const UChar* start;\r
5788 // const UChar* right;\r
5789 // const UChar* current;\r
5790 // const UChar* string;\r
5791 // const UChar* strend;\r
b602265d
DG
5792 const UChar* tag_start;\r
5793 const UChar* tag_end;\r
5794 regex_t* reg;\r
5795 OnigCalloutIn in;\r
5796 OnigType type;\r
5797 OnigValue val;\r
5798 char buf[20];\r
8122c6bc 5799 // FILE* fp;\r
b602265d 5800\r
8122c6bc 5801 // fp = OutFp;\r
b602265d
DG
5802\r
5803 r = onig_get_arg_by_callout_args(args, 0, &type, &val);\r
5804 if (r != ONIG_NORMAL) return r;\r
5805\r
5806 in = onig_get_callout_in_by_callout_args(args);\r
5807 if (in == ONIG_CALLOUT_IN_PROGRESS) {\r
5808 if (val.c == '<')\r
5809 return ONIG_CALLOUT_SUCCESS;\r
5810 }\r
5811 else {\r
5812 if (val.c != 'X' && val.c != '<')\r
5813 return ONIG_CALLOUT_SUCCESS;\r
5814 }\r
5815\r
5816 num = onig_get_callout_num_by_callout_args(args);\r
8122c6bc
GD
5817 // start = onig_get_start_by_callout_args(args);\r
5818 // right = onig_get_right_range_by_callout_args(args);\r
5819 // current = onig_get_current_by_callout_args(args);\r
5820 // string = onig_get_string_by_callout_args(args);\r
5821 // strend = onig_get_string_end_by_callout_args(args);\r
b602265d
DG
5822 reg = onig_get_regex_by_callout_args(args);\r
5823 tag_start = onig_get_callout_tag_start(reg, num);\r
5824 tag_end = onig_get_callout_tag_end(reg, num);\r
5825\r
5826 if (tag_start == 0)\r
5827 sprintf_s(buf, sizeof(buf), "#%d", num);\r
5828 else {\r
5829 /* CAUTION: tag string is not terminated with NULL. */\r
5830 int i;\r
5831\r
5832 tag_len = tag_end - tag_start;\r
5833 if (tag_len >= sizeof(buf)) tag_len = sizeof(buf) - 1;\r
5834 for (i = 0; i < tag_len; i++) buf[i] = tag_start[i];\r
5835 buf[tag_len] = '\0';\r
5836 }\r
8122c6bc 5837/*\r
b602265d
DG
5838 fprintf(fp, "ONIG-MONITOR: %-4s %s at: %d [%d - %d] len: %d\n",\r
5839 buf,\r
5840 in == ONIG_CALLOUT_IN_PROGRESS ? "=>" : "<=",\r
5841 (int )(current - string),\r
5842 (int )(start - string),\r
5843 (int )(right - string),\r
5844 (int )(strend - string));\r
5845 //fflush(fp);\r
8122c6bc 5846*/\r
b602265d
DG
5847 return ONIG_CALLOUT_SUCCESS;\r
5848}\r
5849\r
5850extern int\r
5851onig_setup_builtin_monitors_by_ascii_encoded_name(void* fp /* FILE* */)\r
5852{\r
5853 int id;\r
5854 char* name;\r
5855 OnigEncoding enc;\r
5856 unsigned int ts[4];\r
5857 OnigValue opts[4];\r
5858\r
5859 if (IS_NOT_NULL(fp))\r
5860 OutFp = (FILE* )fp;\r
5861 else\r
5862 OutFp = stdout;\r
5863\r
5864 enc = ONIG_ENCODING_ASCII;\r
5865\r
5866 name = "MON";\r
5867 ts[0] = ONIG_TYPE_CHAR;\r
5868 opts[0].c = '>';\r
5869 BC_B_O(name, monitor, 1, ts, 1, opts);\r
5870\r
5871 return ONIG_NORMAL;\r
5872}\r
5873\r
5874#endif /* USE_CALLOUT */\r