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