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