]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/RegularExpressionDxe/Oniguruma/regexec.c
MdeModulePkg RegularExpressionDxe: Update Oniguruma to 6.9.0
[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
4091 if (*s == *target) {\r
4092 p = s + 1;\r
4093 t = target + 1;\r
4094 while (t < target_end) {\r
b602265d
DG
4095 if (*t != *p++)\r
4096 break;\r
4097 t++;\r
14b0e578
CS
4098 }\r
4099 if (t == target_end)\r
b602265d 4100 return s;\r
14b0e578
CS
4101 }\r
4102 s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s);\r
4103 }\r
4104\r
4105 return (UChar* )NULL;\r
4106}\r
4107\r
4108static UChar*\r
4109slow_search_backward_ic(OnigEncoding enc, int case_fold_flag,\r
b602265d
DG
4110 UChar* target, UChar* target_end,\r
4111 const UChar* text, const UChar* adjust_text,\r
4112 const UChar* text_end, const UChar* text_start)\r
14b0e578
CS
4113{\r
4114 UChar *s;\r
4115\r
4116 s = (UChar* )text_end;\r
4117 s -= (target_end - target);\r
4118 if (s > text_start)\r
4119 s = (UChar* )text_start;\r
4120 else\r
4121 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s);\r
4122\r
4123 while (s >= text) {\r
4124 if (str_lower_case_match(enc, case_fold_flag,\r
4125 target, target_end, s, text_end))\r
4126 return s;\r
4127\r
4128 s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s);\r
4129 }\r
4130\r
4131 return (UChar* )NULL;\r
4132}\r
4133\r
4134static UChar*\r
4135bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,\r
b602265d
DG
4136 const UChar* text, const UChar* text_end,\r
4137 const UChar* text_range)\r
14b0e578
CS
4138{\r
4139 const UChar *s, *se, *t, *p, *end;\r
4140 const UChar *tail;\r
4141 int skip, tlen1;\r
4142\r
4143#ifdef ONIG_DEBUG_SEARCH\r
b602265d
DG
4144 fprintf(stderr, "bm_search_notrev: text: %p, text_end: %p, text_range: %p\n",\r
4145 text, text_end, text_range);\r
14b0e578
CS
4146#endif\r
4147\r
4148 tail = target_end - 1;\r
b602265d 4149 tlen1 = (int )(tail - target);\r
14b0e578
CS
4150 end = text_range;\r
4151 if (end + tlen1 > text_end)\r
4152 end = text_end - tlen1;\r
4153\r
4154 s = text;\r
4155\r
4156 if (IS_NULL(reg->int_map)) {\r
4157 while (s < end) {\r
4158 p = se = s + tlen1;\r
4159 t = tail;\r
4160 while (*p == *t) {\r
b602265d
DG
4161 if (t == target) return (UChar* )s;\r
4162 p--; t--;\r
14b0e578
CS
4163 }\r
4164 skip = reg->map[*se];\r
4165 t = s;\r
4166 do {\r
4167 s += enclen(reg->enc, s);\r
4168 } while ((s - t) < skip && s < end);\r
4169 }\r
4170 }\r
4171 else {\r
4172 while (s < end) {\r
4173 p = se = s + tlen1;\r
4174 t = tail;\r
4175 while (*p == *t) {\r
b602265d
DG
4176 if (t == target) return (UChar* )s;\r
4177 p--; t--;\r
14b0e578
CS
4178 }\r
4179 skip = reg->int_map[*se];\r
4180 t = s;\r
4181 do {\r
4182 s += enclen(reg->enc, s);\r
4183 } while ((s - t) < skip && s < end);\r
4184 }\r
4185 }\r
4186\r
4187 return (UChar* )NULL;\r
4188}\r
4189\r
4190static UChar*\r
4191bm_search(regex_t* reg, const UChar* target, const UChar* target_end,\r
b602265d 4192 const UChar* text, const UChar* text_end, const UChar* text_range)\r
14b0e578
CS
4193{\r
4194 const UChar *s, *t, *p, *end;\r
4195 const UChar *tail;\r
4196\r
4197 end = text_range + (target_end - target) - 1;\r
4198 if (end > text_end)\r
4199 end = text_end;\r
4200\r
4201 tail = target_end - 1;\r
4202 s = text + (target_end - target) - 1;\r
4203 if (IS_NULL(reg->int_map)) {\r
4204 while (s < end) {\r
4205 p = s;\r
4206 t = tail;\r
4207 while (*p == *t) {\r
b602265d
DG
4208 if (t == target) return (UChar* )p;\r
4209 p--; t--;\r
14b0e578
CS
4210 }\r
4211 s += reg->map[*s];\r
4212 }\r
4213 }\r
4214 else { /* see int_map[] */\r
4215 while (s < end) {\r
4216 p = s;\r
4217 t = tail;\r
4218 while (*p == *t) {\r
b602265d
DG
4219 if (t == target) return (UChar* )p;\r
4220 p--; t--;\r
14b0e578
CS
4221 }\r
4222 s += reg->int_map[*s];\r
4223 }\r
4224 }\r
4225 return (UChar* )NULL;\r
4226}\r
4227\r
b602265d 4228#ifdef USE_INT_MAP_BACKWARD\r
14b0e578 4229static int\r
b602265d 4230set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED, int** skip)\r
14b0e578
CS
4231{\r
4232 int i, len;\r
4233\r
4234 if (IS_NULL(*skip)) {\r
4235 *skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);\r
4236 if (IS_NULL(*skip)) return ONIGERR_MEMORY;\r
4237 }\r
4238\r
b602265d 4239 len = end - s;\r
14b0e578
CS
4240 for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)\r
4241 (*skip)[i] = len;\r
4242\r
4243 for (i = len - 1; i > 0; i--)\r
4244 (*skip)[s[i]] = i;\r
4245\r
4246 return 0;\r
4247}\r
4248\r
4249static UChar*\r
4250bm_search_backward(regex_t* reg, const UChar* target, const UChar* target_end,\r
b602265d
DG
4251 const UChar* text, const UChar* adjust_text,\r
4252 const UChar* text_end, const UChar* text_start)\r
14b0e578
CS
4253{\r
4254 const UChar *s, *t, *p;\r
4255\r
4256 s = text_end - (target_end - target);\r
4257 if (text_start < s)\r
4258 s = text_start;\r
4259 else\r
4260 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s);\r
4261\r
4262 while (s >= text) {\r
4263 p = s;\r
4264 t = target;\r
4265 while (t < target_end && *p == *t) {\r
4266 p++; t++;\r
4267 }\r
4268 if (t == target_end)\r
4269 return (UChar* )s;\r
4270\r
4271 s -= reg->int_map_backward[*s];\r
4272 s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s);\r
4273 }\r
4274\r
4275 return (UChar* )NULL;\r
4276}\r
b602265d 4277#endif\r
14b0e578
CS
4278\r
4279static UChar*\r
4280map_search(OnigEncoding enc, UChar map[],\r
b602265d 4281 const UChar* text, const UChar* text_range)\r
14b0e578
CS
4282{\r
4283 const UChar *s = text;\r
4284\r
4285 while (s < text_range) {\r
4286 if (map[*s]) return (UChar* )s;\r
4287\r
4288 s += enclen(enc, s);\r
4289 }\r
4290 return (UChar* )NULL;\r
4291}\r
4292\r
4293static UChar*\r
4294map_search_backward(OnigEncoding enc, UChar map[],\r
b602265d
DG
4295 const UChar* text, const UChar* adjust_text,\r
4296 const UChar* text_start)\r
14b0e578
CS
4297{\r
4298 const UChar *s = text_start;\r
4299\r
4300 while (s >= text) {\r
4301 if (map[*s]) return (UChar* )s;\r
4302\r
4303 s = onigenc_get_prev_char_head(enc, adjust_text, s);\r
4304 }\r
4305 return (UChar* )NULL;\r
4306}\r
b602265d
DG
4307extern int\r
4308onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at,\r
4309 OnigRegion* region, OnigOptionType option)\r
4310{\r
4311 int r;\r
4312 OnigMatchParam mp;\r
4313\r
4314 onig_initialize_match_param(&mp);\r
4315 r = onig_match_with_param(reg, str, end, at, region, option, &mp);\r
4316 onig_free_match_param_content(&mp);\r
4317 return r;\r
4318}\r
14b0e578
CS
4319\r
4320extern int\r
b602265d
DG
4321onig_match_with_param(regex_t* reg, const UChar* str, const UChar* end,\r
4322 const UChar* at, OnigRegion* region, OnigOptionType option,\r
4323 OnigMatchParam* mp)\r
14b0e578
CS
4324{\r
4325 int r;\r
4326 UChar *prev;\r
b602265d 4327 MatchArg msa;\r
14b0e578 4328\r
b602265d
DG
4329 ADJUST_MATCH_PARAM(reg, mp);\r
4330 MATCH_ARG_INIT(msa, reg, option, region, at, mp);\r
14b0e578
CS
4331 if (region\r
4332#ifdef USE_POSIX_API_REGION_OPTION\r
4333 && !IS_POSIX_REGION(option)\r
4334#endif\r
4335 ) {\r
4336 r = onig_region_resize_clear(region, reg->num_mem + 1);\r
4337 }\r
4338 else\r
4339 r = 0;\r
4340\r
4341 if (r == 0) {\r
b602265d
DG
4342 if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
4343 if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end)) {\r
4344 r = ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
4345 goto end;\r
4346 }\r
4347 }\r
4348\r
14b0e578 4349 prev = (UChar* )onigenc_get_prev_char_head(reg->enc, str, at);\r
b602265d 4350 r = match_at(reg, str, end, end, at, prev, &msa);\r
14b0e578
CS
4351 }\r
4352\r
b602265d 4353 end:\r
14b0e578 4354 MATCH_ARG_FREE(msa);\r
14b0e578
CS
4355 return r;\r
4356}\r
4357\r
4358static int\r
4359forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,\r
b602265d 4360 UChar* range, UChar** low, UChar** high, UChar** low_prev)\r
14b0e578
CS
4361{\r
4362 UChar *p, *pprev = (UChar* )NULL;\r
4363\r
4364#ifdef ONIG_DEBUG_SEARCH\r
b602265d
DG
4365 fprintf(stderr, "forward_search_range: str: %p, end: %p, s: %p, range: %p\n",\r
4366 str, end, s, range);\r
14b0e578
CS
4367#endif\r
4368\r
4369 p = s;\r
4370 if (reg->dmin > 0) {\r
4371 if (ONIGENC_IS_SINGLEBYTE(reg->enc)) {\r
4372 p += reg->dmin;\r
4373 }\r
4374 else {\r
4375 UChar *q = p + reg->dmin;\r
b602265d
DG
4376\r
4377 if (q >= end) return 0; /* fail */\r
14b0e578
CS
4378 while (p < q) p += enclen(reg->enc, p);\r
4379 }\r
4380 }\r
4381\r
4382 retry:\r
4383 switch (reg->optimize) {\r
b602265d 4384 case OPTIMIZE_EXACT:\r
14b0e578
CS
4385 p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);\r
4386 break;\r
b602265d 4387 case OPTIMIZE_EXACT_IC:\r
14b0e578
CS
4388 p = slow_search_ic(reg->enc, reg->case_fold_flag,\r
4389 reg->exact, reg->exact_end, p, end, range);\r
4390 break;\r
4391\r
b602265d 4392 case OPTIMIZE_EXACT_BM:\r
14b0e578
CS
4393 p = bm_search(reg, reg->exact, reg->exact_end, p, end, range);\r
4394 break;\r
4395\r
b602265d 4396 case OPTIMIZE_EXACT_BM_NO_REV:\r
14b0e578
CS
4397 p = bm_search_notrev(reg, reg->exact, reg->exact_end, p, end, range);\r
4398 break;\r
4399\r
b602265d 4400 case OPTIMIZE_MAP:\r
14b0e578
CS
4401 p = map_search(reg->enc, reg->map, p, range);\r
4402 break;\r
4403 }\r
4404\r
4405 if (p && p < range) {\r
4406 if (p - reg->dmin < s) {\r
4407 retry_gate:\r
4408 pprev = p;\r
4409 p += enclen(reg->enc, p);\r
4410 goto retry;\r
4411 }\r
4412\r
4413 if (reg->sub_anchor) {\r
4414 UChar* prev;\r
4415\r
4416 switch (reg->sub_anchor) {\r
4417 case ANCHOR_BEGIN_LINE:\r
b602265d
DG
4418 if (!ON_STR_BEGIN(p)) {\r
4419 prev = onigenc_get_prev_char_head(reg->enc,\r
4420 (pprev ? pprev : str), p);\r
4421 if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))\r
4422 goto retry_gate;\r
4423 }\r
4424 break;\r
14b0e578
CS
4425\r
4426 case ANCHOR_END_LINE:\r
b602265d 4427 if (ON_STR_END(p)) {\r
14b0e578 4428#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
b602265d
DG
4429 prev = (UChar* )onigenc_get_prev_char_head(reg->enc,\r
4430 (pprev ? pprev : str), p);\r
4431 if (prev && ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))\r
4432 goto retry_gate;\r
14b0e578 4433#endif\r
b602265d
DG
4434 }\r
4435 else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)\r
14b0e578 4436#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
b602265d 4437 && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)\r
14b0e578 4438#endif\r
b602265d
DG
4439 )\r
4440 goto retry_gate;\r
4441 break;\r
14b0e578
CS
4442 }\r
4443 }\r
4444\r
4445 if (reg->dmax == 0) {\r
4446 *low = p;\r
4447 if (low_prev) {\r
b602265d
DG
4448 if (*low > s)\r
4449 *low_prev = onigenc_get_prev_char_head(reg->enc, s, p);\r
4450 else\r
4451 *low_prev = onigenc_get_prev_char_head(reg->enc,\r
4452 (pprev ? pprev : str), p);\r
14b0e578
CS
4453 }\r
4454 }\r
4455 else {\r
b602265d
DG
4456 if (reg->dmax != INFINITE_LEN) {\r
4457 if (p - str < reg->dmax) {\r
4458 *low = (UChar* )str;\r
4459 if (low_prev)\r
4460 *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low);\r
4461 }\r
4462 else {\r
4463 *low = p - reg->dmax;\r
4464 if (*low > s) {\r
4465 *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,\r
4466 *low, (const UChar** )low_prev);\r
4467 if (low_prev && IS_NULL(*low_prev))\r
4468 *low_prev = onigenc_get_prev_char_head(reg->enc,\r
4469 (pprev ? pprev : s), *low);\r
4470 }\r
4471 else {\r
4472 if (low_prev)\r
4473 *low_prev = onigenc_get_prev_char_head(reg->enc,\r
4474 (pprev ? pprev : str), *low);\r
4475 }\r
4476 }\r
14b0e578
CS
4477 }\r
4478 }\r
4479 /* no needs to adjust *high, *high is used as range check only */\r
4480 *high = p - reg->dmin;\r
4481\r
4482#ifdef ONIG_DEBUG_SEARCH\r
4483 fprintf(stderr,\r
b602265d
DG
4484 "forward_search_range success: low: %d, high: %d, dmin: %d, dmax: %d\n",\r
4485 (int )(*low - str), (int )(*high - str), reg->dmin, reg->dmax);\r
14b0e578
CS
4486#endif\r
4487 return 1; /* success */\r
4488 }\r
4489\r
4490 return 0; /* fail */\r
4491}\r
4492\r
14b0e578
CS
4493\r
4494#define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD 100\r
4495\r
4496static int\r
4497backward_search_range(regex_t* reg, const UChar* str, const UChar* end,\r
b602265d
DG
4498 UChar* s, const UChar* range, UChar* adjrange,\r
4499 UChar** low, UChar** high)\r
14b0e578 4500{\r
14b0e578
CS
4501 UChar *p;\r
4502\r
4503 range += reg->dmin;\r
4504 p = s;\r
4505\r
4506 retry:\r
4507 switch (reg->optimize) {\r
b602265d 4508 case OPTIMIZE_EXACT:\r
14b0e578
CS
4509 exact_method:\r
4510 p = slow_search_backward(reg->enc, reg->exact, reg->exact_end,\r
b602265d 4511 range, adjrange, end, p);\r
14b0e578
CS
4512 break;\r
4513\r
b602265d 4514 case OPTIMIZE_EXACT_IC:\r
14b0e578
CS
4515 p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,\r
4516 reg->exact, reg->exact_end,\r
4517 range, adjrange, end, p);\r
4518 break;\r
4519\r
b602265d
DG
4520 case OPTIMIZE_EXACT_BM:\r
4521 case OPTIMIZE_EXACT_BM_NO_REV:\r
4522#ifdef USE_INT_MAP_BACKWARD\r
14b0e578 4523 if (IS_NULL(reg->int_map_backward)) {\r
b602265d
DG
4524 int r;\r
4525\r
14b0e578 4526 if (s - range < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD)\r
b602265d 4527 goto exact_method;\r
14b0e578
CS
4528\r
4529 r = set_bm_backward_skip(reg->exact, reg->exact_end, reg->enc,\r
b602265d
DG
4530 &(reg->int_map_backward));\r
4531 if (r != 0) return r;\r
14b0e578
CS
4532 }\r
4533 p = bm_search_backward(reg, reg->exact, reg->exact_end, range, adjrange,\r
b602265d
DG
4534 end, p);\r
4535#else\r
4536 goto exact_method;\r
4537#endif\r
14b0e578
CS
4538 break;\r
4539\r
b602265d 4540 case OPTIMIZE_MAP:\r
14b0e578
CS
4541 p = map_search_backward(reg->enc, reg->map, range, adjrange, p);\r
4542 break;\r
4543 }\r
4544\r
4545 if (p) {\r
4546 if (reg->sub_anchor) {\r
4547 UChar* prev;\r
4548\r
4549 switch (reg->sub_anchor) {\r
4550 case ANCHOR_BEGIN_LINE:\r
b602265d
DG
4551 if (!ON_STR_BEGIN(p)) {\r
4552 prev = onigenc_get_prev_char_head(reg->enc, str, p);\r
4553 if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {\r
4554 p = prev;\r
4555 goto retry;\r
4556 }\r
4557 }\r
4558 break;\r
14b0e578
CS
4559\r
4560 case ANCHOR_END_LINE:\r
b602265d 4561 if (ON_STR_END(p)) {\r
14b0e578 4562#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
b602265d
DG
4563 prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);\r
4564 if (IS_NULL(prev)) goto fail;\r
4565 if (ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {\r
4566 p = prev;\r
4567 goto retry;\r
4568 }\r
4569#endif\r
4570 }\r
4571 else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)\r
14b0e578 4572#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
b602265d 4573 && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)\r
14b0e578 4574#endif\r
b602265d
DG
4575 ) {\r
4576 p = onigenc_get_prev_char_head(reg->enc, adjrange, p);\r
4577 if (IS_NULL(p)) goto fail;\r
4578 goto retry;\r
4579 }\r
4580 break;\r
14b0e578
CS
4581 }\r
4582 }\r
4583\r
4584 /* no needs to adjust *high, *high is used as range check only */\r
b602265d 4585 if (reg->dmax != INFINITE_LEN) {\r
14b0e578
CS
4586 *low = p - reg->dmax;\r
4587 *high = p - reg->dmin;\r
4588 *high = onigenc_get_right_adjust_char_head(reg->enc, adjrange, *high);\r
4589 }\r
4590\r
4591#ifdef ONIG_DEBUG_SEARCH\r
4592 fprintf(stderr, "backward_search_range: low: %d, high: %d\n",\r
b602265d 4593 (int )(*low - str), (int )(*high - str));\r
14b0e578
CS
4594#endif\r
4595 return 1; /* success */\r
4596 }\r
4597\r
4598 fail:\r
4599#ifdef ONIG_DEBUG_SEARCH\r
4600 fprintf(stderr, "backward_search_range: fail.\n");\r
4601#endif\r
4602 return 0; /* fail */\r
4603}\r
4604\r
4605\r
4606extern int\r
4607onig_search(regex_t* reg, const UChar* str, const UChar* end,\r
b602265d
DG
4608 const UChar* start, const UChar* range, OnigRegion* region,\r
4609 OnigOptionType option)\r
4610{\r
4611 int r;\r
4612 OnigMatchParam mp;\r
4613\r
4614 onig_initialize_match_param(&mp);\r
4615 r = onig_search_with_param(reg, str, end, start, range, region, option, &mp);\r
4616 onig_free_match_param_content(&mp);\r
4617 return r;\r
4618\r
4619}\r
4620\r
4621extern int\r
4622onig_search_with_param(regex_t* reg, const UChar* str, const UChar* end,\r
4623 const UChar* start, const UChar* range, OnigRegion* region,\r
4624 OnigOptionType option, OnigMatchParam* mp)\r
14b0e578
CS
4625{\r
4626 int r;\r
4627 UChar *s, *prev;\r
b602265d 4628 MatchArg msa;\r
14b0e578 4629 const UChar *orig_start = start;\r
14b0e578 4630 const UChar *orig_range = range;\r
14b0e578
CS
4631\r
4632#ifdef ONIG_DEBUG_SEARCH\r
4633 fprintf(stderr,\r
b602265d
DG
4634 "onig_search (entry point): str: %p, end: %d, start: %d, range: %d\n",\r
4635 str, (int )(end - str), (int )(start - str), (int )(range - str));\r
14b0e578
CS
4636#endif\r
4637\r
b602265d
DG
4638 ADJUST_MATCH_PARAM(reg, mp);\r
4639\r
14b0e578
CS
4640 if (region\r
4641#ifdef USE_POSIX_API_REGION_OPTION\r
4642 && !IS_POSIX_REGION(option)\r
4643#endif\r
4644 ) {\r
4645 r = onig_region_resize_clear(region, reg->num_mem + 1);\r
b602265d 4646 if (r != 0) goto finish_no_msa;\r
14b0e578
CS
4647 }\r
4648\r
4649 if (start > end || start < str) goto mismatch_no_msa;\r
4650\r
b602265d
DG
4651 if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
4652 if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end)) {\r
4653 r = ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
4654 goto finish_no_msa;\r
4655 }\r
4656 }\r
4657\r
14b0e578 4658\r
14b0e578
CS
4659#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
4660#define MATCH_AND_RETURN_CHECK(upper_range) \\r
4661 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \\r
4662 if (r != ONIG_MISMATCH) {\\r
4663 if (r >= 0) {\\r
4664 if (! IS_FIND_LONGEST(reg->options)) {\\r
4665 goto match;\\r
4666 }\\r
4667 }\\r
4668 else goto finish; /* error */ \\r
4669 }\r
4670#else\r
4671#define MATCH_AND_RETURN_CHECK(upper_range) \\r
4672 r = match_at(reg, str, end, (upper_range), s, prev, &msa); \\r
4673 if (r != ONIG_MISMATCH) {\\r
4674 if (r >= 0) {\\r
4675 goto match;\\r
4676 }\\r
4677 else goto finish; /* error */ \\r
4678 }\r
4679#endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */\r
14b0e578
CS
4680\r
4681\r
4682 /* anchor optimize: resume search range */\r
4683 if (reg->anchor != 0 && str < end) {\r
4684 UChar *min_semi_end, *max_semi_end;\r
4685\r
4686 if (reg->anchor & ANCHOR_BEGIN_POSITION) {\r
4687 /* search start-position only */\r
4688 begin_position:\r
4689 if (range > start)\r
b602265d 4690 range = start + 1;\r
14b0e578 4691 else\r
b602265d 4692 range = start;\r
14b0e578
CS
4693 }\r
4694 else if (reg->anchor & ANCHOR_BEGIN_BUF) {\r
4695 /* search str-position only */\r
4696 if (range > start) {\r
b602265d
DG
4697 if (start != str) goto mismatch_no_msa;\r
4698 range = str + 1;\r
14b0e578
CS
4699 }\r
4700 else {\r
b602265d
DG
4701 if (range <= str) {\r
4702 start = str;\r
4703 range = str;\r
4704 }\r
4705 else\r
4706 goto mismatch_no_msa;\r
14b0e578
CS
4707 }\r
4708 }\r
4709 else if (reg->anchor & ANCHOR_END_BUF) {\r
4710 min_semi_end = max_semi_end = (UChar* )end;\r
4711\r
4712 end_buf:\r
b602265d
DG
4713 if ((OnigLen )(max_semi_end - str) < reg->anchor_dmin)\r
4714 goto mismatch_no_msa;\r
14b0e578
CS
4715\r
4716 if (range > start) {\r
b602265d
DG
4717 if ((OnigLen )(min_semi_end - start) > reg->anchor_dmax) {\r
4718 start = min_semi_end - reg->anchor_dmax;\r
4719 if (start < end)\r
4720 start = onigenc_get_right_adjust_char_head(reg->enc, str, start);\r
4721 }\r
4722 if ((OnigLen )(max_semi_end - (range - 1)) < reg->anchor_dmin) {\r
4723 range = max_semi_end - reg->anchor_dmin + 1;\r
4724 }\r
4725\r
4726 if (start > range) goto mismatch_no_msa;\r
4727 /* If start == range, match with empty at end.\r
4728 Backward search is used. */\r
14b0e578
CS
4729 }\r
4730 else {\r
b602265d
DG
4731 if ((OnigLen )(min_semi_end - range) > reg->anchor_dmax) {\r
4732 range = min_semi_end - reg->anchor_dmax;\r
4733 }\r
4734 if ((OnigLen )(max_semi_end - start) < reg->anchor_dmin) {\r
4735 start = max_semi_end - reg->anchor_dmin;\r
4736 start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, start);\r
4737 }\r
4738 if (range > start) goto mismatch_no_msa;\r
14b0e578
CS
4739 }\r
4740 }\r
4741 else if (reg->anchor & ANCHOR_SEMI_END_BUF) {\r
4742 UChar* pre_end = ONIGENC_STEP_BACK(reg->enc, str, end, 1);\r
4743\r
4744 max_semi_end = (UChar* )end;\r
4745 if (ONIGENC_IS_MBC_NEWLINE(reg->enc, pre_end, end)) {\r
b602265d 4746 min_semi_end = pre_end;\r
14b0e578
CS
4747\r
4748#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
b602265d
DG
4749 pre_end = ONIGENC_STEP_BACK(reg->enc, str, pre_end, 1);\r
4750 if (IS_NOT_NULL(pre_end) &&\r
4751 ONIGENC_IS_MBC_CRNL(reg->enc, pre_end, end)) {\r
4752 min_semi_end = pre_end;\r
4753 }\r
14b0e578 4754#endif\r
b602265d
DG
4755 if (min_semi_end > str && start <= min_semi_end) {\r
4756 goto end_buf;\r
4757 }\r
14b0e578
CS
4758 }\r
4759 else {\r
b602265d
DG
4760 min_semi_end = (UChar* )end;\r
4761 goto end_buf;\r
14b0e578
CS
4762 }\r
4763 }\r
b602265d 4764 else if ((reg->anchor & ANCHOR_ANYCHAR_INF_ML)) {\r
14b0e578
CS
4765 goto begin_position;\r
4766 }\r
4767 }\r
4768 else if (str == end) { /* empty string */\r
4769 static const UChar* address_for_empty_string = (UChar* )"";\r
4770\r
4771#ifdef ONIG_DEBUG_SEARCH\r
4772 fprintf(stderr, "onig_search: empty string.\n");\r
4773#endif\r
4774\r
4775 if (reg->threshold_len == 0) {\r
4776 start = end = str = address_for_empty_string;\r
4777 s = (UChar* )start;\r
4778 prev = (UChar* )NULL;\r
4779\r
b602265d 4780 MATCH_ARG_INIT(msa, reg, option, region, start, mp);\r
14b0e578
CS
4781 MATCH_AND_RETURN_CHECK(end);\r
4782 goto mismatch;\r
4783 }\r
4784 goto mismatch_no_msa;\r
4785 }\r
4786\r
4787#ifdef ONIG_DEBUG_SEARCH\r
4788 fprintf(stderr, "onig_search(apply anchor): end: %d, start: %d, range: %d\n",\r
b602265d 4789 (int )(end - str), (int )(start - str), (int )(range - str));\r
14b0e578
CS
4790#endif\r
4791\r
b602265d 4792 MATCH_ARG_INIT(msa, reg, option, region, orig_start, mp);\r
14b0e578
CS
4793\r
4794 s = (UChar* )start;\r
4795 if (range > start) { /* forward search */\r
4796 if (s > str)\r
4797 prev = onigenc_get_prev_char_head(reg->enc, str, s);\r
4798 else\r
4799 prev = (UChar* )NULL;\r
4800\r
b602265d 4801 if (reg->optimize != OPTIMIZE_NONE) {\r
14b0e578
CS
4802 UChar *sch_range, *low, *high, *low_prev;\r
4803\r
4804 sch_range = (UChar* )range;\r
4805 if (reg->dmax != 0) {\r
b602265d
DG
4806 if (reg->dmax == INFINITE_LEN)\r
4807 sch_range = (UChar* )end;\r
4808 else {\r
4809 sch_range += reg->dmax;\r
4810 if (sch_range > end) sch_range = (UChar* )end;\r
4811 }\r
14b0e578
CS
4812 }\r
4813\r
4814 if ((end - start) < reg->threshold_len)\r
4815 goto mismatch;\r
4816\r
b602265d
DG
4817 if (reg->dmax != INFINITE_LEN) {\r
4818 do {\r
4819 if (! forward_search_range(reg, str, end, s, sch_range,\r
4820 &low, &high, &low_prev)) goto mismatch;\r
4821 if (s < low) {\r
4822 s = low;\r
4823 prev = low_prev;\r
4824 }\r
4825 while (s <= high) {\r
4826 MATCH_AND_RETURN_CHECK(orig_range);\r
4827 prev = s;\r
4828 s += enclen(reg->enc, s);\r
4829 }\r
4830 } while (s < range);\r
4831 goto mismatch;\r
14b0e578
CS
4832 }\r
4833 else { /* check only. */\r
b602265d
DG
4834 if (! forward_search_range(reg, str, end, s, sch_range,\r
4835 &low, &high, (UChar** )NULL)) goto mismatch;\r
14b0e578 4836\r
b602265d 4837 if ((reg->anchor & ANCHOR_ANYCHAR_INF) != 0) {\r
14b0e578
CS
4838 do {\r
4839 MATCH_AND_RETURN_CHECK(orig_range);\r
4840 prev = s;\r
4841 s += enclen(reg->enc, s);\r
4842\r
b602265d
DG
4843 if ((reg->anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) == 0) {\r
4844 while (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end) && s < range) {\r
4845 prev = s;\r
4846 s += enclen(reg->enc, s);\r
4847 }\r
14b0e578
CS
4848 }\r
4849 } while (s < range);\r
4850 goto mismatch;\r
4851 }\r
4852 }\r
4853 }\r
4854\r
4855 do {\r
4856 MATCH_AND_RETURN_CHECK(orig_range);\r
4857 prev = s;\r
4858 s += enclen(reg->enc, s);\r
4859 } while (s < range);\r
4860\r
4861 if (s == range) { /* because empty match with /$/. */\r
4862 MATCH_AND_RETURN_CHECK(orig_range);\r
4863 }\r
4864 }\r
4865 else { /* backward search */\r
14b0e578
CS
4866 if (orig_start < end)\r
4867 orig_start += enclen(reg->enc, orig_start); /* is upper range */\r
14b0e578 4868\r
b602265d 4869 if (reg->optimize != OPTIMIZE_NONE) {\r
14b0e578
CS
4870 UChar *low, *high, *adjrange, *sch_start;\r
4871\r
4872 if (range < end)\r
b602265d 4873 adjrange = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, range);\r
14b0e578 4874 else\r
b602265d
DG
4875 adjrange = (UChar* )end;\r
4876\r
4877 if (reg->dmax != INFINITE_LEN &&\r
4878 (end - range) >= reg->threshold_len) {\r
4879 do {\r
4880 sch_start = s + reg->dmax;\r
4881 if (sch_start > end) sch_start = (UChar* )end;\r
4882 if (backward_search_range(reg, str, end, sch_start, range, adjrange,\r
4883 &low, &high) <= 0)\r
4884 goto mismatch;\r
4885\r
4886 if (s > high)\r
4887 s = high;\r
4888\r
4889 while (s >= low) {\r
4890 prev = onigenc_get_prev_char_head(reg->enc, str, s);\r
4891 MATCH_AND_RETURN_CHECK(orig_start);\r
4892 s = prev;\r
4893 }\r
4894 } while (s >= range);\r
4895 goto mismatch;\r
14b0e578
CS
4896 }\r
4897 else { /* check only. */\r
b602265d
DG
4898 if ((end - range) < reg->threshold_len) goto mismatch;\r
4899\r
4900 sch_start = s;\r
4901 if (reg->dmax != 0) {\r
4902 if (reg->dmax == INFINITE_LEN)\r
4903 sch_start = (UChar* )end;\r
4904 else {\r
4905 sch_start += reg->dmax;\r
4906 if (sch_start > end) sch_start = (UChar* )end;\r
4907 else\r
4908 sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc,\r
4909 start, sch_start);\r
4910 }\r
4911 }\r
4912 if (backward_search_range(reg, str, end, sch_start, range, adjrange,\r
4913 &low, &high) <= 0) goto mismatch;\r
14b0e578
CS
4914 }\r
4915 }\r
4916\r
4917 do {\r
4918 prev = onigenc_get_prev_char_head(reg->enc, str, s);\r
4919 MATCH_AND_RETURN_CHECK(orig_start);\r
4920 s = prev;\r
4921 } while (s >= range);\r
4922 }\r
4923\r
4924 mismatch:\r
4925#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
4926 if (IS_FIND_LONGEST(reg->options)) {\r
4927 if (msa.best_len >= 0) {\r
4928 s = msa.best_s;\r
4929 goto match;\r
4930 }\r
4931 }\r
4932#endif\r
4933 r = ONIG_MISMATCH;\r
4934\r
4935 finish:\r
4936 MATCH_ARG_FREE(msa);\r
14b0e578
CS
4937\r
4938 /* If result is mismatch and no FIND_NOT_EMPTY option,\r
b602265d 4939 then the region is not set in match_at(). */\r
14b0e578
CS
4940 if (IS_FIND_NOT_EMPTY(reg->options) && region\r
4941#ifdef USE_POSIX_API_REGION_OPTION\r
4942 && !IS_POSIX_REGION(option)\r
4943#endif\r
4944 ) {\r
4945 onig_region_clear(region);\r
4946 }\r
4947\r
4948#ifdef ONIG_DEBUG\r
4949 if (r != ONIG_MISMATCH)\r
4950 fprintf(stderr, "onig_search: error %d\n", r);\r
4951#endif\r
4952 return r;\r
4953\r
4954 mismatch_no_msa:\r
4955 r = ONIG_MISMATCH;\r
4956 finish_no_msa:\r
14b0e578
CS
4957#ifdef ONIG_DEBUG\r
4958 if (r != ONIG_MISMATCH)\r
4959 fprintf(stderr, "onig_search: error %d\n", r);\r
4960#endif\r
4961 return r;\r
4962\r
4963 match:\r
14b0e578 4964 MATCH_ARG_FREE(msa);\r
b602265d
DG
4965 return (int )(s - str);\r
4966}\r
4967\r
4968extern int\r
4969onig_scan(regex_t* reg, const UChar* str, const UChar* end,\r
4970 OnigRegion* region, OnigOptionType option,\r
4971 int (*scan_callback)(int, int, OnigRegion*, void*),\r
4972 void* callback_arg)\r
4973{\r
4974 int r;\r
4975 int n;\r
4976 int rs;\r
4977 const UChar* start;\r
4978\r
4979 if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
4980 if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end))\r
4981 return ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
4982\r
4983 ONIG_OPTION_OFF(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING);\r
4984 }\r
4985\r
4986 n = 0;\r
4987 start = str;\r
4988 while (1) {\r
4989 r = onig_search(reg, str, end, start, end, region, option);\r
4990 if (r >= 0) {\r
4991 rs = scan_callback(n, r, region, callback_arg);\r
4992 n++;\r
4993 if (rs != 0)\r
4994 return rs;\r
4995\r
4996 if (region->end[0] == start - str) {\r
4997 if (start >= end) break;\r
4998 start += enclen(reg->enc, start);\r
4999 }\r
5000 else\r
5001 start = str + region->end[0];\r
5002\r
5003 if (start > end)\r
5004 break;\r
5005 }\r
5006 else if (r == ONIG_MISMATCH) {\r
5007 break;\r
5008 }\r
5009 else { /* error */\r
5010 return r;\r
5011 }\r
5012 }\r
5013\r
5014 return n;\r
14b0e578
CS
5015}\r
5016\r
5017extern OnigEncoding\r
5018onig_get_encoding(regex_t* reg)\r
5019{\r
5020 return reg->enc;\r
5021}\r
5022\r
5023extern OnigOptionType\r
5024onig_get_options(regex_t* reg)\r
5025{\r
5026 return reg->options;\r
5027}\r
5028\r
5029extern OnigCaseFoldType\r
5030onig_get_case_fold_flag(regex_t* reg)\r
5031{\r
5032 return reg->case_fold_flag;\r
5033}\r
5034\r
5035extern OnigSyntaxType*\r
5036onig_get_syntax(regex_t* reg)\r
5037{\r
5038 return reg->syntax;\r
5039}\r
5040\r
5041extern int\r
5042onig_number_of_captures(regex_t* reg)\r
5043{\r
5044 return reg->num_mem;\r
5045}\r
5046\r
5047extern int\r
5048onig_number_of_capture_histories(regex_t* reg)\r
5049{\r
5050#ifdef USE_CAPTURE_HISTORY\r
5051 int i, n;\r
5052\r
5053 n = 0;\r
5054 for (i = 0; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {\r
b602265d 5055 if (MEM_STATUS_AT(reg->capture_history, i) != 0)\r
14b0e578
CS
5056 n++;\r
5057 }\r
5058 return n;\r
5059#else\r
5060 return 0;\r
5061#endif\r
5062}\r
5063\r
5064extern void\r
5065onig_copy_encoding(OnigEncoding to, OnigEncoding from)\r
5066{\r
5067 *to = *from;\r
5068}\r
5069\r
b602265d
DG
5070\r
5071/* for callout functions */\r
5072\r
5073#ifdef USE_CALLOUT\r
5074\r
5075extern OnigCalloutFunc\r
5076onig_get_progress_callout(void)\r
5077{\r
5078 return DefaultProgressCallout;\r
5079}\r
5080\r
5081extern int\r
5082onig_set_progress_callout(OnigCalloutFunc f)\r
5083{\r
5084 DefaultProgressCallout = f;\r
5085 return ONIG_NORMAL;\r
5086}\r
5087\r
5088extern OnigCalloutFunc\r
5089onig_get_retraction_callout(void)\r
5090{\r
5091 return DefaultRetractionCallout;\r
5092}\r
5093\r
5094extern int\r
5095onig_set_retraction_callout(OnigCalloutFunc f)\r
5096{\r
5097 DefaultRetractionCallout = f;\r
5098 return ONIG_NORMAL;\r
5099}\r
5100\r
5101extern int\r
5102onig_get_callout_num_by_callout_args(OnigCalloutArgs* args)\r
5103{\r
5104 return args->num;\r
5105}\r
5106\r
5107extern OnigCalloutIn\r
5108onig_get_callout_in_by_callout_args(OnigCalloutArgs* args)\r
5109{\r
5110 return args->in;\r
5111}\r
5112\r
5113extern int\r
5114onig_get_name_id_by_callout_args(OnigCalloutArgs* args)\r
5115{\r
5116 return args->name_id;\r
5117}\r
5118\r
5119extern const UChar*\r
5120onig_get_contents_by_callout_args(OnigCalloutArgs* args)\r
5121{\r
5122 int num;\r
5123 CalloutListEntry* e;\r
5124\r
5125 num = args->num;\r
5126 e = onig_reg_callout_list_at(args->regex, num);\r
5127 if (IS_NULL(e)) return 0;\r
5128 if (e->of == ONIG_CALLOUT_OF_CONTENTS) {\r
5129 return e->u.content.start;\r
5130 }\r
5131\r
5132 return 0;\r
5133}\r
5134\r
5135extern const UChar*\r
5136onig_get_contents_end_by_callout_args(OnigCalloutArgs* args)\r
5137{\r
5138 int num;\r
5139 CalloutListEntry* e;\r
5140\r
5141 num = args->num;\r
5142 e = onig_reg_callout_list_at(args->regex, num);\r
5143 if (IS_NULL(e)) return 0;\r
5144 if (e->of == ONIG_CALLOUT_OF_CONTENTS) {\r
5145 return e->u.content.end;\r
5146 }\r
5147\r
5148 return 0;\r
5149}\r
5150\r
5151extern int\r
5152onig_get_args_num_by_callout_args(OnigCalloutArgs* args)\r
5153{\r
5154 int num;\r
5155 CalloutListEntry* e;\r
5156\r
5157 num = args->num;\r
5158 e = onig_reg_callout_list_at(args->regex, num);\r
5159 if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
5160 if (e->of == ONIG_CALLOUT_OF_NAME) {\r
5161 return e->u.arg.num;\r
5162 }\r
5163\r
5164 return ONIGERR_INVALID_ARGUMENT;\r
5165}\r
5166\r
5167extern int\r
5168onig_get_passed_args_num_by_callout_args(OnigCalloutArgs* args)\r
5169{\r
5170 int num;\r
5171 CalloutListEntry* e;\r
5172\r
5173 num = args->num;\r
5174 e = onig_reg_callout_list_at(args->regex, num);\r
5175 if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
5176 if (e->of == ONIG_CALLOUT_OF_NAME) {\r
5177 return e->u.arg.passed_num;\r
5178 }\r
5179\r
5180 return ONIGERR_INVALID_ARGUMENT;\r
5181}\r
5182\r
5183extern int\r
5184onig_get_arg_by_callout_args(OnigCalloutArgs* args, int index,\r
5185 OnigType* type, OnigValue* val)\r
5186{\r
5187 int num;\r
5188 CalloutListEntry* e;\r
5189\r
5190 num = args->num;\r
5191 e = onig_reg_callout_list_at(args->regex, num);\r
5192 if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
5193 if (e->of == ONIG_CALLOUT_OF_NAME) {\r
5194 if (IS_NOT_NULL(type)) *type = e->u.arg.types[index];\r
5195 if (IS_NOT_NULL(val)) *val = e->u.arg.vals[index];\r
5196 return ONIG_NORMAL;\r
5197 }\r
5198\r
5199 return ONIGERR_INVALID_ARGUMENT;\r
5200}\r
5201\r
5202extern const UChar*\r
5203onig_get_string_by_callout_args(OnigCalloutArgs* args)\r
5204{\r
5205 return args->string;\r
5206}\r
5207\r
5208extern const UChar*\r
5209onig_get_string_end_by_callout_args(OnigCalloutArgs* args)\r
5210{\r
5211 return args->string_end;\r
5212}\r
5213\r
5214extern const UChar*\r
5215onig_get_start_by_callout_args(OnigCalloutArgs* args)\r
5216{\r
5217 return args->start;\r
5218}\r
5219\r
5220extern const UChar*\r
5221onig_get_right_range_by_callout_args(OnigCalloutArgs* args)\r
5222{\r
5223 return args->right_range;\r
5224}\r
5225\r
5226extern const UChar*\r
5227onig_get_current_by_callout_args(OnigCalloutArgs* args)\r
5228{\r
5229 return args->current;\r
5230}\r
5231\r
5232extern OnigRegex\r
5233onig_get_regex_by_callout_args(OnigCalloutArgs* args)\r
5234{\r
5235 return args->regex;\r
5236}\r
5237\r
5238extern unsigned long\r
5239onig_get_retry_counter_by_callout_args(OnigCalloutArgs* args)\r
5240{\r
5241 return args->retry_in_match_counter;\r
5242}\r
5243\r
5244\r
5245extern int\r
5246onig_get_capture_range_in_callout(OnigCalloutArgs* a, int mem_num, int* begin, int* end)\r
5247{\r
5248 OnigRegex reg;\r
5249 const UChar* str;\r
5250 StackType* stk_base;\r
5251 int i;\r
5252\r
5253 i = mem_num;\r
5254 reg = a->regex;\r
5255 str = a->string;\r
5256 stk_base = a->stk_base;\r
5257\r
5258 if (i > 0) {\r
5259 if (a->mem_end_stk[i] != INVALID_STACK_INDEX) {\r
5260 if (MEM_STATUS_AT(reg->bt_mem_start, i))\r
5261 *begin = (int )(STACK_AT(a->mem_start_stk[i])->u.mem.pstr - str);\r
5262 else\r
5263 *begin = (int )((UChar* )((void* )a->mem_start_stk[i]) - str);\r
5264\r
5265 *end = (int )((MEM_STATUS_AT(reg->bt_mem_end, i)\r
5266 ? STACK_AT(a->mem_end_stk[i])->u.mem.pstr\r
5267 : (UChar* )((void* )a->mem_end_stk[i])) - str);\r
5268 }\r
5269 else {\r
5270 *begin = *end = ONIG_REGION_NOTPOS;\r
5271 }\r
5272 }\r
5273 else if (i == 0) {\r
5274#if 0\r
5275 *begin = a->start - str;\r
5276 *end = a->current - str;\r
5277#else\r
5278 return ONIGERR_INVALID_ARGUMENT;\r
5279#endif\r
5280 }\r
5281 else\r
5282 return ONIGERR_INVALID_ARGUMENT;\r
5283\r
5284 return ONIG_NORMAL;\r
5285}\r
5286\r
5287extern int\r
5288onig_get_used_stack_size_in_callout(OnigCalloutArgs* a, int* used_num, int* used_bytes)\r
5289{\r
5290 int n;\r
5291\r
5292 n = (int )(a->stk - a->stk_base);\r
5293\r
5294 if (used_num != 0)\r
5295 *used_num = n;\r
5296\r
5297 if (used_bytes != 0)\r
5298 *used_bytes = n * sizeof(StackType);\r
5299\r
5300 return ONIG_NORMAL;\r
5301}\r
5302\r
5303\r
5304/* builtin callout functions */\r
5305\r
5306extern int\r
5307onig_builtin_fail(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
5308{\r
5309 return ONIG_CALLOUT_FAIL;\r
5310}\r
5311\r
5312extern int\r
5313onig_builtin_mismatch(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
5314{\r
5315 return ONIG_MISMATCH;\r
5316}\r
5317\r
5318#if 0\r
5319extern int\r
5320onig_builtin_success(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
5321{\r
5322 return ONIG_CALLOUT_SUCCESS;\r
5323}\r
5324#endif\r
5325\r
5326extern int\r
5327onig_builtin_error(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
5328{\r
5329 int r;\r
5330 int n;\r
5331 OnigValue val;\r
5332\r
5333 r = onig_get_arg_by_callout_args(args, 0, 0, &val);\r
5334 if (r != ONIG_NORMAL) return r;\r
5335\r
5336 n = (int )val.l;\r
5337 if (n >= 0) {\r
5338 n = ONIGERR_INVALID_CALLOUT_BODY;\r
5339 }\r
5340\r
5341 return n;\r
5342}\r
5343\r
5344extern int\r
5345onig_builtin_count(OnigCalloutArgs* args, void* user_data)\r
5346{\r
5347 (void )onig_check_callout_data_and_clear_old_values(args);\r
5348\r
5349 return onig_builtin_total_count(args, user_data);\r
5350}\r
5351\r
5352extern int\r
5353onig_builtin_total_count(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
5354{\r
5355 int r;\r
5356 int slot;\r
5357 OnigType type;\r
5358 OnigValue val;\r
5359 OnigValue aval;\r
5360 OnigCodePoint count_type;\r
5361\r
5362 r = onig_get_arg_by_callout_args(args, 0, &type, &aval);\r
5363 if (r != ONIG_NORMAL) return r;\r
5364\r
5365 count_type = aval.c;\r
5366 if (count_type != '>' && count_type != 'X' && count_type != '<')\r
5367 return ONIGERR_INVALID_CALLOUT_ARG;\r
5368\r
5369 r = onig_get_callout_data_by_callout_args_self_dont_clear_old(args, 0,\r
5370 &type, &val);\r
5371 if (r < ONIG_NORMAL)\r
5372 return r;\r
5373 else if (r > ONIG_NORMAL) {\r
5374 /* type == void: initial state */\r
5375 val.l = 0;\r
5376 }\r
5377\r
5378 if (args->in == ONIG_CALLOUT_IN_RETRACTION) {\r
5379 slot = 2;\r
5380 if (count_type == '<')\r
5381 val.l++;\r
5382 else if (count_type == 'X')\r
5383 val.l--;\r
5384 }\r
5385 else {\r
5386 slot = 1;\r
5387 if (count_type != '<')\r
5388 val.l++;\r
5389 }\r
5390\r
5391 r = onig_set_callout_data_by_callout_args_self(args, 0, ONIG_TYPE_LONG, &val);\r
5392 if (r != ONIG_NORMAL) return r;\r
5393\r
5394 /* slot 1: in progress counter, slot 2: in retraction counter */\r
5395 r = onig_get_callout_data_by_callout_args_self_dont_clear_old(args, slot,\r
5396 &type, &val);\r
5397 if (r < ONIG_NORMAL)\r
5398 return r;\r
5399 else if (r > ONIG_NORMAL) {\r
5400 val.l = 0;\r
5401 }\r
5402\r
5403 val.l++;\r
5404 r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
5405 if (r != ONIG_NORMAL) return r;\r
5406\r
5407 return ONIG_CALLOUT_SUCCESS;\r
5408}\r
5409\r
5410extern int\r
5411onig_builtin_max(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
5412{\r
5413 int r;\r
5414 int slot;\r
5415 long max_val;\r
5416 OnigCodePoint count_type;\r
5417 OnigType type;\r
5418 OnigValue val;\r
5419 OnigValue aval;\r
5420\r
5421 (void )onig_check_callout_data_and_clear_old_values(args);\r
5422\r
5423 slot = 0;\r
5424 r = onig_get_callout_data_by_callout_args_self(args, slot, &type, &val);\r
5425 if (r < ONIG_NORMAL)\r
5426 return r;\r
5427 else if (r > ONIG_NORMAL) {\r
5428 /* type == void: initial state */\r
5429 type = ONIG_TYPE_LONG;\r
5430 val.l = 0;\r
5431 }\r
5432\r
5433 r = onig_get_arg_by_callout_args(args, 0, &type, &aval);\r
5434 if (r != ONIG_NORMAL) return r;\r
5435 if (type == ONIG_TYPE_TAG) {\r
5436 r = onig_get_callout_data_by_callout_args(args, aval.tag, 0, &type, &aval);\r
5437 if (r < ONIG_NORMAL) return r;\r
5438 else if (r > ONIG_NORMAL)\r
5439 max_val = 0L;\r
5440 else\r
5441 max_val = aval.l;\r
5442 }\r
5443 else { /* LONG */\r
5444 max_val = aval.l;\r
5445 }\r
5446\r
5447 r = onig_get_arg_by_callout_args(args, 1, &type, &aval);\r
5448 if (r != ONIG_NORMAL) return r;\r
5449\r
5450 count_type = aval.c;\r
5451 if (count_type != '>' && count_type != 'X' && count_type != '<')\r
5452 return ONIGERR_INVALID_CALLOUT_ARG;\r
5453\r
5454 if (args->in == ONIG_CALLOUT_IN_RETRACTION) {\r
5455 if (count_type == '<') {\r
5456 if (val.l >= max_val) return ONIG_CALLOUT_FAIL;\r
5457 val.l++;\r
5458 }\r
5459 else if (count_type == 'X')\r
5460 val.l--;\r
5461 }\r
5462 else {\r
5463 if (count_type != '<') {\r
5464 if (val.l >= max_val) return ONIG_CALLOUT_FAIL;\r
5465 val.l++;\r
5466 }\r
5467 }\r
5468\r
5469 r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
5470 if (r != ONIG_NORMAL) return r;\r
5471\r
5472 return ONIG_CALLOUT_SUCCESS;\r
5473}\r
5474\r
5475enum OP_CMP {\r
5476 OP_EQ,\r
5477 OP_NE,\r
5478 OP_LT,\r
5479 OP_GT,\r
5480 OP_LE,\r
5481 OP_GE\r
5482};\r
5483\r
5484extern int\r
5485onig_builtin_cmp(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
5486{\r
5487 int r;\r
5488 int slot;\r
5489 long lv;\r
5490 long rv;\r
5491 OnigType type;\r
5492 OnigValue val;\r
5493 regex_t* reg;\r
5494 enum OP_CMP op;\r
5495\r
5496 reg = args->regex;\r
5497\r
5498 r = onig_get_arg_by_callout_args(args, 0, &type, &val);\r
5499 if (r != ONIG_NORMAL) return r;\r
5500\r
5501 if (type == ONIG_TYPE_TAG) {\r
5502 r = onig_get_callout_data_by_callout_args(args, val.tag, 0, &type, &val);\r
5503 if (r < ONIG_NORMAL) return r;\r
5504 else if (r > ONIG_NORMAL)\r
5505 lv = 0L;\r
5506 else\r
5507 lv = val.l;\r
5508 }\r
5509 else { /* ONIG_TYPE_LONG */\r
5510 lv = val.l;\r
5511 }\r
5512\r
5513 r = onig_get_arg_by_callout_args(args, 2, &type, &val);\r
5514 if (r != ONIG_NORMAL) return r;\r
5515\r
5516 if (type == ONIG_TYPE_TAG) {\r
5517 r = onig_get_callout_data_by_callout_args(args, val.tag, 0, &type, &val);\r
5518 if (r < ONIG_NORMAL) return r;\r
5519 else if (r > ONIG_NORMAL)\r
5520 rv = 0L;\r
5521 else\r
5522 rv = val.l;\r
5523 }\r
5524 else { /* ONIG_TYPE_LONG */\r
5525 rv = val.l;\r
5526 }\r
5527\r
5528 slot = 0;\r
5529 r = onig_get_callout_data_by_callout_args_self(args, slot, &type, &val);\r
5530 if (r < ONIG_NORMAL)\r
5531 return r;\r
5532 else if (r > ONIG_NORMAL) {\r
5533 /* type == void: initial state */\r
5534 OnigCodePoint c1, c2;\r
5535 UChar* p;\r
5536\r
5537 r = onig_get_arg_by_callout_args(args, 1, &type, &val);\r
5538 if (r != ONIG_NORMAL) return r;\r
5539\r
5540 p = val.s.start;\r
5541 c1 = ONIGENC_MBC_TO_CODE(reg->enc, p, val.s.end);\r
5542 p += ONIGENC_MBC_ENC_LEN(reg->enc, p);\r
5543 if (p < val.s.end) {\r
5544 c2 = ONIGENC_MBC_TO_CODE(reg->enc, p, val.s.end);\r
5545 p += ONIGENC_MBC_ENC_LEN(reg->enc, p);\r
5546 if (p != val.s.end) return ONIGERR_INVALID_CALLOUT_ARG;\r
5547 }\r
5548 else\r
5549 c2 = 0;\r
5550\r
5551 switch (c1) {\r
5552 case '=':\r
5553 if (c2 != '=') return ONIGERR_INVALID_CALLOUT_ARG;\r
5554 op = OP_EQ;\r
5555 break;\r
5556 case '!':\r
5557 if (c2 != '=') return ONIGERR_INVALID_CALLOUT_ARG;\r
5558 op = OP_NE;\r
5559 break;\r
5560 case '<':\r
5561 if (c2 == '=') op = OP_LE;\r
5562 else if (c2 == 0) op = OP_LT;\r
5563 else return ONIGERR_INVALID_CALLOUT_ARG;\r
5564 break;\r
5565 case '>':\r
5566 if (c2 == '=') op = OP_GE;\r
5567 else if (c2 == 0) op = OP_GT;\r
5568 else return ONIGERR_INVALID_CALLOUT_ARG;\r
5569 break;\r
5570 default:\r
5571 return ONIGERR_INVALID_CALLOUT_ARG;\r
5572 break;\r
5573 }\r
5574 val.l = (long )op;\r
5575 r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
5576 if (r != ONIG_NORMAL) return r;\r
5577 }\r
5578 else {\r
5579 op = (enum OP_CMP )val.l;\r
5580 }\r
5581\r
5582 switch (op) {\r
5583 case OP_EQ: r = (lv == rv); break;\r
5584 case OP_NE: r = (lv != rv); break;\r
5585 case OP_LT: r = (lv < rv); break;\r
5586 case OP_GT: r = (lv > rv); break;\r
5587 case OP_LE: r = (lv <= rv); break;\r
5588 case OP_GE: r = (lv >= rv); break;\r
5589 }\r
5590\r
5591 return r == 0 ? ONIG_CALLOUT_FAIL : ONIG_CALLOUT_SUCCESS;\r
5592}\r
5593\r
5594\r
5595//#include <stdio.h>\r
5596\r
5597static FILE* OutFp;\r
5598\r
5599/* name start with "onig_" for macros. */\r
5600static int\r
5601onig_builtin_monitor(OnigCalloutArgs* args, void* user_data)\r
5602{\r
5603 int r;\r
5604 int num;\r
5605 size_t tag_len;\r
5606 const UChar* start;\r
5607 const UChar* right;\r
5608 const UChar* current;\r
5609 const UChar* string;\r
5610 const UChar* strend;\r
5611 const UChar* tag_start;\r
5612 const UChar* tag_end;\r
5613 regex_t* reg;\r
5614 OnigCalloutIn in;\r
5615 OnigType type;\r
5616 OnigValue val;\r
5617 char buf[20];\r
5618 FILE* fp;\r
5619\r
5620 fp = OutFp;\r
5621\r
5622 r = onig_get_arg_by_callout_args(args, 0, &type, &val);\r
5623 if (r != ONIG_NORMAL) return r;\r
5624\r
5625 in = onig_get_callout_in_by_callout_args(args);\r
5626 if (in == ONIG_CALLOUT_IN_PROGRESS) {\r
5627 if (val.c == '<')\r
5628 return ONIG_CALLOUT_SUCCESS;\r
5629 }\r
5630 else {\r
5631 if (val.c != 'X' && val.c != '<')\r
5632 return ONIG_CALLOUT_SUCCESS;\r
5633 }\r
5634\r
5635 num = onig_get_callout_num_by_callout_args(args);\r
5636 start = onig_get_start_by_callout_args(args);\r
5637 right = onig_get_right_range_by_callout_args(args);\r
5638 current = onig_get_current_by_callout_args(args);\r
5639 string = onig_get_string_by_callout_args(args);\r
5640 strend = onig_get_string_end_by_callout_args(args);\r
5641 reg = onig_get_regex_by_callout_args(args);\r
5642 tag_start = onig_get_callout_tag_start(reg, num);\r
5643 tag_end = onig_get_callout_tag_end(reg, num);\r
5644\r
5645 if (tag_start == 0)\r
5646 sprintf_s(buf, sizeof(buf), "#%d", num);\r
5647 else {\r
5648 /* CAUTION: tag string is not terminated with NULL. */\r
5649 int i;\r
5650\r
5651 tag_len = tag_end - tag_start;\r
5652 if (tag_len >= sizeof(buf)) tag_len = sizeof(buf) - 1;\r
5653 for (i = 0; i < tag_len; i++) buf[i] = tag_start[i];\r
5654 buf[tag_len] = '\0';\r
5655 }\r
5656\r
5657 fprintf(fp, "ONIG-MONITOR: %-4s %s at: %d [%d - %d] len: %d\n",\r
5658 buf,\r
5659 in == ONIG_CALLOUT_IN_PROGRESS ? "=>" : "<=",\r
5660 (int )(current - string),\r
5661 (int )(start - string),\r
5662 (int )(right - string),\r
5663 (int )(strend - string));\r
5664 //fflush(fp);\r
5665\r
5666 return ONIG_CALLOUT_SUCCESS;\r
5667}\r
5668\r
5669extern int\r
5670onig_setup_builtin_monitors_by_ascii_encoded_name(void* fp /* FILE* */)\r
5671{\r
5672 int id;\r
5673 char* name;\r
5674 OnigEncoding enc;\r
5675 unsigned int ts[4];\r
5676 OnigValue opts[4];\r
5677\r
5678 if (IS_NOT_NULL(fp))\r
5679 OutFp = (FILE* )fp;\r
5680 else\r
5681 OutFp = stdout;\r
5682\r
5683 enc = ONIG_ENCODING_ASCII;\r
5684\r
5685 name = "MON";\r
5686 ts[0] = ONIG_TYPE_CHAR;\r
5687 opts[0].c = '>';\r
5688 BC_B_O(name, monitor, 1, ts, 1, opts);\r
5689\r
5690 return ONIG_NORMAL;\r
5691}\r
5692\r
5693#endif /* USE_CALLOUT */\r