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