Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

regparse.c
Go to the documentation of this file.
1 /**********************************************************************
2 regparse.c - Onigmo (Oniguruma-mod) (regular expression library)
3 **********************************************************************/
4 /*-
5 * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
6 * Copyright (c) 2011-2013 K.Takata <kentkt AT csc DOT jp>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #include "regparse.h"
32
33 #define WARN_BUFSIZE 256
34
35 #define CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
36
37
38 const OnigSyntaxType OnigSyntaxRuby = {
39 (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
40 ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
41 ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS |
42 ONIG_SYN_OP_ESC_C_CONTROL )
43 & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
44 , ( ONIG_SYN_OP2_QMARK_GROUP_EFFECT |
45 ONIG_SYN_OP2_OPTION_RUBY |
46 ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP | ONIG_SYN_OP2_ESC_K_NAMED_BACKREF |
47 ONIG_SYN_OP2_ESC_G_SUBEXP_CALL |
48 ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY |
49 ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
50 ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT |
51 ONIG_SYN_OP2_CCLASS_SET_OP | ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL |
52 ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB |
53 ONIG_SYN_OP2_ESC_H_XDIGIT |
54 ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER |
55 ONIG_SYN_OP2_QMARK_LPAREN_CONDITION |
56 ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK |
57 ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP )
58 , ( SYN_GNU_REGEX_BV |
59 ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV |
60 ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND |
61 ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP |
62 ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME |
63 ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY |
64 ONIG_SYN_WARN_CC_OP_NOT_ESCAPED |
65 ONIG_SYN_WARN_CC_DUP |
66 ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT )
67 , ( ONIG_OPTION_ASCII_RANGE | ONIG_OPTION_POSIX_BRACKET_ALL_RANGE |
68 ONIG_OPTION_WORD_BOUND_ALL_RANGE )
69 ,
70 {
71 (OnigCodePoint )'\\' /* esc */
72 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
73 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
74 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
75 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
76 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
77 }
78 };
79
80 const OnigSyntaxType* OnigDefaultSyntax = ONIG_SYNTAX_RUBY;
81
82 extern void onig_null_warn(const char* s ARG_UNUSED) { }
83
84 #ifdef DEFAULT_WARN_FUNCTION
85 static OnigWarnFunc onig_warn = (OnigWarnFunc )DEFAULT_WARN_FUNCTION;
86 #else
87 static OnigWarnFunc onig_warn = onig_null_warn;
88 #endif
89
90 #ifdef DEFAULT_VERB_WARN_FUNCTION
91 static OnigWarnFunc onig_verb_warn = (OnigWarnFunc )DEFAULT_VERB_WARN_FUNCTION;
92 #else
93 static OnigWarnFunc onig_verb_warn = onig_null_warn;
94 #endif
95
96 extern void onig_set_warn_func(OnigWarnFunc f)
97 {
98 onig_warn = f;
99 }
100
101 extern void onig_set_verb_warn_func(OnigWarnFunc f)
102 {
103 onig_verb_warn = f;
104 }
105
106 static void CC_DUP_WARN(ScanEnv *env);
107
108 static void
109 bbuf_free(BBuf* bbuf)
110 {
111 if (IS_NOT_NULL(bbuf)) {
112 if (IS_NOT_NULL(bbuf->p)) xfree(bbuf->p);
113 xfree(bbuf);
114 }
115 }
116
117 static int
118 bbuf_clone(BBuf** rto, BBuf* from)
119 {
120 int r;
121 BBuf *to;
122
123 *rto = to = (BBuf* )xmalloc(sizeof(BBuf));
124 CHECK_NULL_RETURN_MEMERR(to);
125 r = BBUF_INIT(to, from->alloc);
126 if (r != 0) return r;
127 to->used = from->used;
128 xmemcpy(to->p, from->p, from->used);
129 return 0;
130 }
131
132 #define BACKREF_REL_TO_ABS(rel_no, env) \
133 ((env)->num_mem + 1 + (rel_no))
134
135 #define ONOFF(v,f,negative) (negative) ? ((v) &= ~(f)) : ((v) |= (f))
136
137 #define MBCODE_START_POS(enc) \
138 (OnigCodePoint )(ONIGENC_MBC_MINLEN(enc) > 1 ? 0 : 0x80)
139
140 #define SET_ALL_MULTI_BYTE_RANGE(enc, pbuf) \
141 add_code_range_to_buf(pbuf, env, MBCODE_START_POS(enc), ONIG_LAST_CODE_POINT)
142
143 #define ADD_ALL_MULTI_BYTE_RANGE(enc, mbuf) do {\
144 if (! ONIGENC_IS_SINGLEBYTE(enc)) {\
145 r = SET_ALL_MULTI_BYTE_RANGE(enc, &(mbuf));\
146 if (r) return r;\
147 }\
148 } while (0)
149
150
151 #define BITSET_SET_BIT_CHKDUP(bs, pos) do { \
152 if (BITSET_AT(bs, pos)) CC_DUP_WARN(env); \
153 BS_ROOM(bs, pos) |= BS_BIT(pos); \
154 } while (0)
155
156 #define BITSET_IS_EMPTY(bs,empty) do {\
157 int i;\
158 empty = 1;\
159 for (i = 0; i < BITSET_SIZE; i++) {\
160 if ((bs)[i] != 0) {\
161 empty = 0; break;\
162 }\
163 }\
164 } while (0)
165
166 static void
167 bitset_set_range(ScanEnv *env, BitSetRef bs, int from, int to)
168 {
169 int i;
170 for (i = from; i <= to && i < SINGLE_BYTE_SIZE; i++) {
171 BITSET_SET_BIT_CHKDUP(bs, i);
172 }
173 }
174
175 #if 0
176 static void
177 bitset_set_all(BitSetRef bs)
178 {
179 int i;
180 for (i = 0; i < BITSET_SIZE; i++) { bs[i] = ~((Bits )0); }
181 }
182 #endif
183
184 static void
185 bitset_invert(BitSetRef bs)
186 {
187 int i;
188 for (i = 0; i < BITSET_SIZE; i++) { bs[i] = ~(bs[i]); }
189 }
190
191 static void
192 bitset_invert_to(BitSetRef from, BitSetRef to)
193 {
194 int i;
195 for (i = 0; i < BITSET_SIZE; i++) { to[i] = ~(from[i]); }
196 }
197
198 static void
199 bitset_and(BitSetRef dest, BitSetRef bs)
200 {
201 int i;
202 for (i = 0; i < BITSET_SIZE; i++) { dest[i] &= bs[i]; }
203 }
204
205 static void
206 bitset_or(BitSetRef dest, BitSetRef bs)
207 {
208 int i;
209 for (i = 0; i < BITSET_SIZE; i++) { dest[i] |= bs[i]; }
210 }
211
212 static void
213 bitset_copy(BitSetRef dest, BitSetRef bs)
214 {
215 int i;
216 for (i = 0; i < BITSET_SIZE; i++) { dest[i] = bs[i]; }
217 }
218
219 extern int
220 onig_strncmp(const UChar* s1, const UChar* s2, int n)
221 {
222 int x;
223
224 while (n-- > 0) {
225 x = *s2++ - *s1++;
226 if (x) return x;
227 }
228 return 0;
229 }
230
231 extern void
232 onig_strcpy(UChar* dest, const UChar* src, const UChar* end)
233 {
234 ptrdiff_t len = end - src;
235 if (len > 0) {
236 xmemcpy(dest, src, len);
237 dest[len] = (UChar )0;
238 }
239 }
240
241 #ifdef USE_NAMED_GROUP
242 static UChar*
243 strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
244 {
245 ptrdiff_t slen;
246 int term_len, i;
247 UChar *r;
248
249 slen = end - s;
250 term_len = ONIGENC_MBC_MINLEN(enc);
251
252 r = (UChar* )xmalloc(slen + term_len);
253 CHECK_NULL_RETURN(r);
254 xmemcpy(r, s, slen);
255
256 for (i = 0; i < term_len; i++)
257 r[slen + i] = (UChar )0;
258
259 return r;
260 }
261 #endif
262
263 /* scan pattern methods */
264 #define PEND_VALUE 0
265
266 #ifdef __GNUC__
267 /* get rid of Wunused-but-set-variable and Wuninitialized */
268 #define PFETCH_READY UChar* pfetch_prev = NULL; (void)pfetch_prev
269 #else
270 #define PFETCH_READY UChar* pfetch_prev
271 #endif
272 #define PEND (p < end ? 0 : 1)
273 #define PUNFETCH p = pfetch_prev
274 #define PINC do { \
275 pfetch_prev = p; \
276 p += enclen(enc, p, end); \
277 } while (0)
278 #define PFETCH(c) do { \
279 c = ((enc->max_enc_len == 1) ? *p : ONIGENC_MBC_TO_CODE(enc, p, end)); \
280 pfetch_prev = p; \
281 p += enclen(enc, p, end); \
282 } while (0)
283
284 #define PPEEK (p < end ? ONIGENC_MBC_TO_CODE(enc, p, end) : PEND_VALUE)
285 #define PPEEK_IS(c) (PPEEK == (OnigCodePoint )c)
286
287 static UChar*
288 strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_end,
289 size_t capa)
290 {
291 UChar* r;
292
293 if (dest)
294 r = (UChar* )xrealloc(dest, capa + 1);
295 else
296 r = (UChar* )xmalloc(capa + 1);
297
298 CHECK_NULL_RETURN(r);
299 onig_strcpy(r + (dest_end - dest), src, src_end);
300 return r;
301 }
302
303 /* dest on static area */
304 static UChar*
305 strcat_capa_from_static(UChar* dest, UChar* dest_end,
306 const UChar* src, const UChar* src_end, size_t capa)
307 {
308 UChar* r;
309
310 r = (UChar* )xmalloc(capa + 1);
311 CHECK_NULL_RETURN(r);
312 onig_strcpy(r, dest, dest_end);
313 onig_strcpy(r + (dest_end - dest), src, src_end);
314 return r;
315 }
316
317
318 #ifdef USE_ST_LIBRARY
319
320 #include "ruby/st.h"
321
322 typedef struct {
323 const UChar* s;
324 const UChar* end;
325 } st_str_end_key;
326
327 static int
328 str_end_cmp(st_data_t xp, st_data_t yp)
329 {
330 const st_str_end_key *x, *y;
331 const UChar *p, *q;
332 int c;
333
334 x = (const st_str_end_key *)xp;
335 y = (const st_str_end_key *)yp;
336 if ((x->end - x->s) != (y->end - y->s))
337 return 1;
338
339 p = x->s;
340 q = y->s;
341 while (p < x->end) {
342 c = (int )*p - (int )*q;
343 if (c != 0) return c;
344
345 p++; q++;
346 }
347
348 return 0;
349 }
350
351 static st_index_t
352 str_end_hash(st_data_t xp)
353 {
354 const st_str_end_key *x = (const st_str_end_key *)xp;
355 const UChar *p;
356 st_index_t val = 0;
357
358 p = x->s;
359 while (p < x->end) {
360 val = val * 997 + (int )*p++;
361 }
362
363 return val + (val >> 5);
364 }
365
366 extern hash_table_type*
367 onig_st_init_strend_table_with_size(st_index_t size)
368 {
369 static const struct st_hash_type hashType = {
370 str_end_cmp,
371 str_end_hash,
372 };
373
374 return (hash_table_type* )
375 onig_st_init_table_with_size(&hashType, size);
376 }
377
378 extern int
379 onig_st_lookup_strend(hash_table_type* table, const UChar* str_key,
380 const UChar* end_key, hash_data_type *value)
381 {
382 st_str_end_key key;
383
384 key.s = (UChar* )str_key;
385 key.end = (UChar* )end_key;
386
387 return onig_st_lookup(table, (st_data_t )(&key), value);
388 }
389
390 extern int
391 onig_st_insert_strend(hash_table_type* table, const UChar* str_key,
392 const UChar* end_key, hash_data_type value)
393 {
394 st_str_end_key* key;
395 int result;
396
397 key = (st_str_end_key* )xmalloc(sizeof(st_str_end_key));
398 key->s = (UChar* )str_key;
399 key->end = (UChar* )end_key;
400 result = onig_st_insert(table, (st_data_t )key, value);
401 if (result) {
402 xfree(key);
403 }
404 return result;
405 }
406
407 #endif /* USE_ST_LIBRARY */
408
409
410 #ifdef USE_NAMED_GROUP
411
412 #define INIT_NAME_BACKREFS_ALLOC_NUM 8
413
414 typedef struct {
415 UChar* name;
416 size_t name_len; /* byte length */
417 int back_num; /* number of backrefs */
418 int back_alloc;
419 int back_ref1;
420 int* back_refs;
421 } NameEntry;
422
423 #ifdef USE_ST_LIBRARY
424
425 typedef st_table NameTable;
426 typedef st_data_t HashDataType; /* 1.6 st.h doesn't define st_data_t type */
427
428 #ifdef ONIG_DEBUG
429 static int
430 i_print_name_entry(UChar* key, NameEntry* e, void* arg)
431 {
432 int i;
433 FILE* fp = (FILE* )arg;
434
435 fprintf(fp, "%s: ", e->name);
436 if (e->back_num == 0)
437 fputs("-", fp);
438 else if (e->back_num == 1)
439 fprintf(fp, "%d", e->back_ref1);
440 else {
441 for (i = 0; i < e->back_num; i++) {
442 if (i > 0) fprintf(fp, ", ");
443 fprintf(fp, "%d", e->back_refs[i]);
444 }
445 }
446 fputs("\n", fp);
447 return ST_CONTINUE;
448 }
449
450 extern int
451 onig_print_names(FILE* fp, regex_t* reg)
452 {
453 NameTable* t = (NameTable* )reg->name_table;
454
455 if (IS_NOT_NULL(t)) {
456 fprintf(fp, "name table\n");
457 onig_st_foreach(t, i_print_name_entry, (HashDataType )fp);
458 fputs("\n", fp);
459 }
460 return 0;
461 }
462 #endif /* ONIG_DEBUG */
463
464 static int
465 i_free_name_entry(UChar* key, NameEntry* e, void* arg ARG_UNUSED)
466 {
467 xfree(e->name);
468 if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
469 xfree(key);
470 xfree(e);
471 return ST_DELETE;
472 }
473
474 static int
475 names_clear(regex_t* reg)
476 {
477 NameTable* t = (NameTable* )reg->name_table;
478
479 if (IS_NOT_NULL(t)) {
480 onig_st_foreach(t, i_free_name_entry, 0);
481 }
482 return 0;
483 }
484
485 extern int
486 onig_names_free(regex_t* reg)
487 {
488 int r;
489 NameTable* t;
490
491 r = names_clear(reg);
492 if (r) return r;
493
494 t = (NameTable* )reg->name_table;
495 if (IS_NOT_NULL(t)) onig_st_free_table(t);
496 reg->name_table = (void* )NULL;
497 return 0;
498 }
499
500 static NameEntry*
501 name_find(regex_t* reg, const UChar* name, const UChar* name_end)
502 {
503 NameEntry* e;
504 NameTable* t = (NameTable* )reg->name_table;
505
506 e = (NameEntry* )NULL;
507 if (IS_NOT_NULL(t)) {
508 onig_st_lookup_strend(t, name, name_end, (HashDataType* )((void* )(&e)));
509 }
510 return e;
511 }
512
513 typedef struct {
514 int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*);
515 regex_t* reg;
516 void* arg;
517 int ret;
518 OnigEncoding enc;
519 } INamesArg;
520
521 static int
522 i_names(UChar* key ARG_UNUSED, NameEntry* e, INamesArg* arg)
523 {
524 int r = (*(arg->func))(e->name,
525 e->name + e->name_len,
526 e->back_num,
527 (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
528 arg->reg, arg->arg);
529 if (r != 0) {
530 arg->ret = r;
531 return ST_STOP;
532 }
533 return ST_CONTINUE;
534 }
535
536 extern int
537 onig_foreach_name(regex_t* reg,
538 int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
539 {
540 INamesArg narg;
541 NameTable* t = (NameTable* )reg->name_table;
542
543 narg.ret = 0;
544 if (IS_NOT_NULL(t)) {
545 narg.func = func;
546 narg.reg = reg;
547 narg.arg = arg;
548 narg.enc = reg->enc; /* should be pattern encoding. */
549 onig_st_foreach(t, i_names, (HashDataType )&narg);
550 }
551 return narg.ret;
552 }
553
554 static int
555 i_renumber_name(UChar* key ARG_UNUSED, NameEntry* e, GroupNumRemap* map)
556 {
557 int i;
558
559 if (e->back_num > 1) {
560 for (i = 0; i < e->back_num; i++) {
561 e->back_refs[i] = map[e->back_refs[i]].new_val;
562 }
563 }
564 else if (e->back_num == 1) {
565 e->back_ref1 = map[e->back_ref1].new_val;
566 }
567
568 return ST_CONTINUE;
569 }
570
571 extern int
572 onig_renumber_name_table(regex_t* reg, GroupNumRemap* map)
573 {
574 NameTable* t = (NameTable* )reg->name_table;
575
576 if (IS_NOT_NULL(t)) {
577 onig_st_foreach(t, i_renumber_name, (HashDataType )map);
578 }
579 return 0;
580 }
581
582
583 extern int
584 onig_number_of_names(regex_t* reg)
585 {
586 NameTable* t = (NameTable* )reg->name_table;
587
588 if (IS_NOT_NULL(t))
589 return (int )t->num_entries;
590 else
591 return 0;
592 }
593
594 #else /* USE_ST_LIBRARY */
595
596 #define INIT_NAMES_ALLOC_NUM 8
597
598 typedef struct {
599 NameEntry* e;
600 int num;
601 int alloc;
602 } NameTable;
603
604 #ifdef ONIG_DEBUG
605 extern int
606 onig_print_names(FILE* fp, regex_t* reg)
607 {
608 int i, j;
609 NameEntry* e;
610 NameTable* t = (NameTable* )reg->name_table;
611
612 if (IS_NOT_NULL(t) && t->num > 0) {
613 fprintf(fp, "name table\n");
614 for (i = 0; i < t->num; i++) {
615 e = &(t->e[i]);
616 fprintf(fp, "%s: ", e->name);
617 if (e->back_num == 0) {
618 fputs("-", fp);
619 }
620 else if (e->back_num == 1) {
621 fprintf(fp, "%d", e->back_ref1);
622 }
623 else {
624 for (j = 0; j < e->back_num; j++) {
625 if (j > 0) fprintf(fp, ", ");
626 fprintf(fp, "%d", e->back_refs[j]);
627 }
628 }
629 fputs("\n", fp);
630 }
631 fputs("\n", fp);
632 }
633 return 0;
634 }
635 #endif
636
637 static int
638 names_clear(regex_t* reg)
639 {
640 int i;
641 NameEntry* e;
642 NameTable* t = (NameTable* )reg->name_table;
643
644 if (IS_NOT_NULL(t)) {
645 for (i = 0; i < t->num; i++) {
646 e = &(t->e[i]);
647 if (IS_NOT_NULL(e->name)) {
648 xfree(e->name);
649 e->name = NULL;
650 e->name_len = 0;
651 e->back_num = 0;
652 e->back_alloc = 0;
653 if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
654 e->back_refs = (int* )NULL;
655 }
656 }
657 if (IS_NOT_NULL(t->e)) {
658 xfree(t->e);
659 t->e = NULL;
660 }
661 t->num = 0;
662 }
663 return 0;
664 }
665
666 extern int
667 onig_names_free(regex_t* reg)
668 {
669 int r;
670 NameTable* t;
671
672 r = names_clear(reg);
673 if (r) return r;
674
675 t = (NameTable* )reg->name_table;
676 if (IS_NOT_NULL(t)) xfree(t);
677 reg->name_table = NULL;
678 return 0;
679 }
680
681 static NameEntry*
682 name_find(regex_t* reg, const UChar* name, const UChar* name_end)
683 {
684 int i, len;
685 NameEntry* e;
686 NameTable* t = (NameTable* )reg->name_table;
687
688 if (IS_NOT_NULL(t)) {
689 len = name_end - name;
690 for (i = 0; i < t->num; i++) {
691 e = &(t->e[i]);
692 if (len == e->name_len && onig_strncmp(name, e->name, len) == 0)
693 return e;
694 }
695 }
696 return (NameEntry* )NULL;
697 }
698
699 extern int
700 onig_foreach_name(regex_t* reg,
701 int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
702 {
703 int i, r;
704 NameEntry* e;
705 NameTable* t = (NameTable* )reg->name_table;
706
707 if (IS_NOT_NULL(t)) {
708 for (i = 0; i < t->num; i++) {
709 e = &(t->e[i]);
710 r = (*func)(e->name, e->name + e->name_len, e->back_num,
711 (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
712 reg, arg);
713 if (r != 0) return r;
714 }
715 }
716 return 0;
717 }
718
719 extern int
720 onig_number_of_names(regex_t* reg)
721 {
722 NameTable* t = (NameTable* )reg->name_table;
723
724 if (IS_NOT_NULL(t))
725 return t->num;
726 else
727 return 0;
728 }
729
730 #endif /* else USE_ST_LIBRARY */
731
732 static int
733 name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
734 {
735 int alloc;
736 NameEntry* e;
737 NameTable* t = (NameTable* )reg->name_table;
738
739 if (name_end - name <= 0)
740 return ONIGERR_EMPTY_GROUP_NAME;
741
742 e = name_find(reg, name, name_end);
743 if (IS_NULL(e)) {
744 #ifdef USE_ST_LIBRARY
745 if (IS_NULL(t)) {
746 t = onig_st_init_strend_table_with_size(5);
747 reg->name_table = (void* )t;
748 }
749 e = (NameEntry* )xmalloc(sizeof(NameEntry));
750 CHECK_NULL_RETURN_MEMERR(e);
751
752 e->name = strdup_with_null(reg->enc, name, name_end);
753 if (IS_NULL(e->name)) {
754 xfree(e);
755 return ONIGERR_MEMORY;
756 }
757 onig_st_insert_strend(t, e->name, (e->name + (name_end - name)),
758 (HashDataType )e);
759
760 e->name_len = name_end - name;
761 e->back_num = 0;
762 e->back_alloc = 0;
763 e->back_refs = (int* )NULL;
764
765 #else
766
767 if (IS_NULL(t)) {
768 alloc = INIT_NAMES_ALLOC_NUM;
769 t = (NameTable* )xmalloc(sizeof(NameTable));
770 CHECK_NULL_RETURN_MEMERR(t);
771 t->e = NULL;
772 t->alloc = 0;
773 t->num = 0;
774
775 t->e = (NameEntry* )xmalloc(sizeof(NameEntry) * alloc);
776 if (IS_NULL(t->e)) {
777 xfree(t);
778 return ONIGERR_MEMORY;
779 }
780 t->alloc = alloc;
781 reg->name_table = t;
782 goto clear;
783 }
784 else if (t->num == t->alloc) {
785 int i;
786 NameEntry* p;
787
788 alloc = t->alloc * 2;
789 p = (NameEntry* )xrealloc(t->e, sizeof(NameEntry) * alloc);
790 CHECK_NULL_RETURN_MEMERR(p);
791 t->e = p;
792 t->alloc = alloc;
793
794 clear:
795 for (i = t->num; i < t->alloc; i++) {
796 t->e[i].name = NULL;
797 t->e[i].name_len = 0;
798 t->e[i].back_num = 0;
799 t->e[i].back_alloc = 0;
800 t->e[i].back_refs = (int* )NULL;
801 }
802 }
803 e = &(t->e[t->num]);
804 t->num++;
805 e->name = strdup_with_null(reg->enc, name, name_end);
806 if (IS_NULL(e->name)) return ONIGERR_MEMORY;
807 e->name_len = name_end - name;
808 #endif
809 }
810
811 if (e->back_num >= 1 &&
812 ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME)) {
813 onig_scan_env_set_error_string(env, ONIGERR_MULTIPLEX_DEFINED_NAME,
814 name, name_end);
815 return ONIGERR_MULTIPLEX_DEFINED_NAME;
816 }
817
818 e->back_num++;
819 if (e->back_num == 1) {
820 e->back_ref1 = backref;
821 }
822 else {
823 if (e->back_num == 2) {
824 alloc = INIT_NAME_BACKREFS_ALLOC_NUM;
825 e->back_refs = (int* )xmalloc(sizeof(int) * alloc);
826 CHECK_NULL_RETURN_MEMERR(e->back_refs);
827 e->back_alloc = alloc;
828 e->back_refs[0] = e->back_ref1;
829 e->back_refs[1] = backref;
830 }
831 else {
832 if (e->back_num > e->back_alloc) {
833 int* p;
834 alloc = e->back_alloc * 2;
835 p = (int* )xrealloc(e->back_refs, sizeof(int) * alloc);
836 CHECK_NULL_RETURN_MEMERR(p);
837 e->back_refs = p;
838 e->back_alloc = alloc;
839 }
840 e->back_refs[e->back_num - 1] = backref;
841 }
842 }
843
844 return 0;
845 }
846
847 extern int
848 onig_name_to_group_numbers(regex_t* reg, const UChar* name,
849 const UChar* name_end, int** nums)
850 {
851 NameEntry* e = name_find(reg, name, name_end);
852
853 if (IS_NULL(e)) return ONIGERR_UNDEFINED_NAME_REFERENCE;
854
855 switch (e->back_num) {
856 case 0:
857 *nums = 0;
858 break;
859 case 1:
860 *nums = &(e->back_ref1);
861 break;
862 default:
863 *nums = e->back_refs;
864 break;
865 }
866 return e->back_num;
867 }
868
869 extern int
870 onig_name_to_backref_number(regex_t* reg, const UChar* name,
871 const UChar* name_end, OnigRegion *region)
872 {
873 int i, n, *nums;
874
875 n = onig_name_to_group_numbers(reg, name, name_end, &nums);
876 if (n < 0)
877 return n;
878 else if (n == 0)
879 return ONIGERR_PARSER_BUG;
880 else if (n == 1)
881 return nums[0];
882 else {
883 if (IS_NOT_NULL(region)) {
884 for (i = n - 1; i >= 0; i--) {
885 if (region->beg[nums[i]] != ONIG_REGION_NOTPOS)
886 return nums[i];
887 }
888 }
889 return nums[n - 1];
890 }
891 }
892
893 #else /* USE_NAMED_GROUP */
894
895 extern int
896 onig_name_to_group_numbers(regex_t* reg, const UChar* name,
897 const UChar* name_end, int** nums)
898 {
899 return ONIG_NO_SUPPORT_CONFIG;
900 }
901
902 extern int
903 onig_name_to_backref_number(regex_t* reg, const UChar* name,
904 const UChar* name_end, OnigRegion* region)
905 {
906 return ONIG_NO_SUPPORT_CONFIG;
907 }
908
909 extern int
910 onig_foreach_name(regex_t* reg,
911 int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
912 {
913 return ONIG_NO_SUPPORT_CONFIG;
914 }
915
916 extern int
917 onig_number_of_names(regex_t* reg)
918 {
919 return 0;
920 }
921 #endif /* else USE_NAMED_GROUP */
922
923 extern int
924 onig_noname_group_capture_is_active(regex_t* reg)
925 {
926 if (ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_DONT_CAPTURE_GROUP))
927 return 0;
928
929 #ifdef USE_NAMED_GROUP
930 if (onig_number_of_names(reg) > 0 &&
931 IS_SYNTAX_BV(reg->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
932 !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
933 return 0;
934 }
935 #endif
936
937 return 1;
938 }
939
940
941 #define INIT_SCANENV_MEMNODES_ALLOC_SIZE 16
942
943 static void
944 scan_env_clear(ScanEnv* env)
945 {
946 int i;
947
948 BIT_STATUS_CLEAR(env->capture_history);
949 BIT_STATUS_CLEAR(env->bt_mem_start);
950 BIT_STATUS_CLEAR(env->bt_mem_end);
951 BIT_STATUS_CLEAR(env->backrefed_mem);
952 env->error = (UChar* )NULL;
953 env->error_end = (UChar* )NULL;
954 env->num_call = 0;
955 env->num_mem = 0;
956 #ifdef USE_NAMED_GROUP
957 env->num_named = 0;
958 #endif
959 env->mem_alloc = 0;
960 env->mem_nodes_dynamic = (Node** )NULL;
961
962 for (i = 0; i < SCANENV_MEMNODES_SIZE; i++)
963 env->mem_nodes_static[i] = NULL_NODE;
964
965 #ifdef USE_COMBINATION_EXPLOSION_CHECK
966 env->num_comb_exp_check = 0;
967 env->comb_exp_max_regnum = 0;
968 env->curr_max_regnum = 0;
969 env->has_recursion = 0;
970 #endif
971 env->warnings_flag = 0;
972 }
973
974 static int
975 scan_env_add_mem_entry(ScanEnv* env)
976 {
977 int i, need, alloc;
978 Node** p;
979
980 need = env->num_mem + 1;
981 if (need > ONIG_MAX_CAPTURE_GROUP_NUM)
982 return ONIGERR_TOO_MANY_CAPTURE_GROUPS;
983 if (need >= SCANENV_MEMNODES_SIZE) {
984 if (env->mem_alloc <= need) {
985 if (IS_NULL(env->mem_nodes_dynamic)) {
986 alloc = INIT_SCANENV_MEMNODES_ALLOC_SIZE;
987 p = (Node** )xmalloc(sizeof(Node*) * alloc);
988 xmemcpy(p, env->mem_nodes_static,
989 sizeof(Node*) * SCANENV_MEMNODES_SIZE);
990 }
991 else {
992 alloc = env->mem_alloc * 2;
993 p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc);
994 }
995 CHECK_NULL_RETURN_MEMERR(p);
996
997 for (i = env->num_mem + 1; i < alloc; i++)
998 p[i] = NULL_NODE;
999
1000 env->mem_nodes_dynamic = p;
1001 env->mem_alloc = alloc;
1002 }
1003 }
1004
1005 env->num_mem++;
1006 return env->num_mem;
1007 }
1008
1009 static int
1010 scan_env_set_mem_node(ScanEnv* env, int num, Node* node)
1011 {
1012 if (env->num_mem >= num)
1013 SCANENV_MEM_NODES(env)[num] = node;
1014 else
1015 return ONIGERR_PARSER_BUG;
1016 return 0;
1017 }
1018
1019
1020 #ifdef USE_PARSE_TREE_NODE_RECYCLE
1021 typedef struct _FreeNode {
1022 struct _FreeNode* next;
1023 } FreeNode;
1024
1025 static FreeNode* FreeNodeList = (FreeNode* )NULL;
1026 #endif
1027
1028 extern void
1029 onig_node_free(Node* node)
1030 {
1031 start:
1032 if (IS_NULL(node)) return ;
1033
1034 switch (NTYPE(node)) {
1035 case NT_STR:
1036 if (NSTR(node)->capa != 0 &&
1037 IS_NOT_NULL(NSTR(node)->s) && NSTR(node)->s != NSTR(node)->buf) {
1038 xfree(NSTR(node)->s);
1039 }
1040 break;
1041
1042 case NT_LIST:
1043 case NT_ALT:
1044 onig_node_free(NCAR(node));
1045 {
1046 Node* next_node = NCDR(node);
1047
1048 #ifdef USE_PARSE_TREE_NODE_RECYCLE
1049 {
1050 FreeNode* n = (FreeNode* )node;
1051
1052 THREAD_ATOMIC_START;
1053 n->next = FreeNodeList;
1054 FreeNodeList = n;
1055 THREAD_ATOMIC_END;
1056 }
1057 #else
1058 xfree(node);
1059 #endif
1060 node = next_node;
1061 goto start;
1062 }
1063 break;
1064
1065 case NT_CCLASS:
1066 {
1067 CClassNode* cc = NCCLASS(node);
1068
1069 if (IS_NCCLASS_SHARE(cc)) return ;
1070 if (cc->mbuf)
1071 bbuf_free(cc->mbuf);
1072 }
1073 break;
1074
1075 case NT_QTFR:
1076 if (NQTFR(node)->target)
1077 onig_node_free(NQTFR(node)->target);
1078 break;
1079
1080 case NT_ENCLOSE:
1081 if (NENCLOSE(node)->target)
1082 onig_node_free(NENCLOSE(node)->target);
1083 break;
1084
1085 case NT_BREF:
1086 if (IS_NOT_NULL(NBREF(node)->back_dynamic))
1087 xfree(NBREF(node)->back_dynamic);
1088 break;
1089
1090 case NT_ANCHOR:
1091 if (NANCHOR(node)->target)
1092 onig_node_free(NANCHOR(node)->target);
1093 break;
1094 }
1095
1096 #ifdef USE_PARSE_TREE_NODE_RECYCLE
1097 {
1098 FreeNode* n = (FreeNode* )node;
1099
1100 THREAD_ATOMIC_START;
1101 n->next = FreeNodeList;
1102 FreeNodeList = n;
1103 THREAD_ATOMIC_END;
1104 }
1105 #else
1106 xfree(node);
1107 #endif
1108 }
1109
1110 #ifdef USE_PARSE_TREE_NODE_RECYCLE
1111 extern int
1112 onig_free_node_list(void)
1113 {
1114 FreeNode* n;
1115
1116 /* THREAD_ATOMIC_START; */
1117 while (IS_NOT_NULL(FreeNodeList)) {
1118 n = FreeNodeList;
1119 FreeNodeList = FreeNodeList->next;
1120 xfree(n);
1121 }
1122 /* THREAD_ATOMIC_END; */
1123 return 0;
1124 }
1125 #endif
1126
1127 static Node*
1128 node_new(void)
1129 {
1130 Node* node;
1131
1132 #ifdef USE_PARSE_TREE_NODE_RECYCLE
1133 THREAD_ATOMIC_START;
1134 if (IS_NOT_NULL(FreeNodeList)) {
1135 node = (Node* )FreeNodeList;
1136 FreeNodeList = FreeNodeList->next;
1137 THREAD_ATOMIC_END;
1138 return node;
1139 }
1140 THREAD_ATOMIC_END;
1141 #endif
1142
1143 node = (Node* )xmalloc(sizeof(Node));
1144 /* xmemset(node, 0, sizeof(Node)); */
1145 return node;
1146 }
1147
1148
1149 static void
1150 initialize_cclass(CClassNode* cc)
1151 {
1152 BITSET_CLEAR(cc->bs);
1153 /* cc->base.flags = 0; */
1154 cc->flags = 0;
1155 cc->mbuf = NULL;
1156 }
1157
1158 static Node*
1159 node_new_cclass(void)
1160 {
1161 Node* node = node_new();
1162 CHECK_NULL_RETURN(node);
1163
1164 SET_NTYPE(node, NT_CCLASS);
1165 initialize_cclass(NCCLASS(node));
1166 return node;
1167 }
1168
1169 static Node*
1170 node_new_cclass_by_codepoint_range(int not, OnigCodePoint sb_out,
1171 const OnigCodePoint ranges[])
1172 {
1173 int n, i;
1174 CClassNode* cc;
1175 OnigCodePoint j;
1176
1177 Node* node = node_new_cclass();
1178 CHECK_NULL_RETURN(node);
1179
1180 cc = NCCLASS(node);
1181 if (not != 0) NCCLASS_SET_NOT(cc);
1182
1183 BITSET_CLEAR(cc->bs);
1184 if (sb_out > 0 && IS_NOT_NULL(ranges)) {
1185 n = ONIGENC_CODE_RANGE_NUM(ranges);
1186 for (i = 0; i < n; i++) {
1187 for (j = ONIGENC_CODE_RANGE_FROM(ranges, i);
1188 j <= (OnigCodePoint )ONIGENC_CODE_RANGE_TO(ranges, i); j++) {
1189 if (j >= sb_out) goto sb_end;
1190
1191 BITSET_SET_BIT(cc->bs, j);
1192 }
1193 }
1194 }
1195
1196 sb_end:
1197 if (IS_NULL(ranges)) {
1198 is_null:
1199 cc->mbuf = NULL;
1200 }
1201 else {
1202 BBuf* bbuf;
1203
1204 n = ONIGENC_CODE_RANGE_NUM(ranges);
1205 if (n == 0) goto is_null;
1206
1207 bbuf = (BBuf* )xmalloc(sizeof(BBuf));
1208 CHECK_NULL_RETURN(bbuf);
1209 bbuf->alloc = n + 1;
1210 bbuf->used = n + 1;
1211 bbuf->p = (UChar* )((void* )ranges);
1212
1213 cc->mbuf = bbuf;
1214 }
1215
1216 return node;
1217 }
1218
1219 static Node*
1220 node_new_ctype(int type, int not, int ascii_range)
1221 {
1222 Node* node = node_new();
1223 CHECK_NULL_RETURN(node);
1224
1225 SET_NTYPE(node, NT_CTYPE);
1226 NCTYPE(node)->ctype = type;
1227 NCTYPE(node)->not = not;
1228 NCTYPE(node)->ascii_range = ascii_range;
1229 return node;
1230 }
1231
1232 static Node*
1233 node_new_anychar(void)
1234 {
1235 Node* node = node_new();
1236 CHECK_NULL_RETURN(node);
1237
1238 SET_NTYPE(node, NT_CANY);
1239 return node;
1240 }
1241
1242 static Node*
1243 node_new_list(Node* left, Node* right)
1244 {
1245 Node* node = node_new();
1246 CHECK_NULL_RETURN(node);
1247
1248 SET_NTYPE(node, NT_LIST);
1249 NCAR(node) = left;
1250 NCDR(node) = right;
1251 return node;
1252 }
1253
1254 extern Node*
1255 onig_node_new_list(Node* left, Node* right)
1256 {
1257 return node_new_list(left, right);
1258 }
1259
1260 extern Node*
1261 onig_node_list_add(Node* list, Node* x)
1262 {
1263 Node *n;
1264
1265 n = onig_node_new_list(x, NULL);
1266 if (IS_NULL(n)) return NULL_NODE;
1267
1268 if (IS_NOT_NULL(list)) {
1269 while (IS_NOT_NULL(NCDR(list)))
1270 list = NCDR(list);
1271
1272 NCDR(list) = n;
1273 }
1274
1275 return n;
1276 }
1277
1278 extern Node*
1279 onig_node_new_alt(Node* left, Node* right)
1280 {
1281 Node* node = node_new();
1282 CHECK_NULL_RETURN(node);
1283
1284 SET_NTYPE(node, NT_ALT);
1285 NCAR(node) = left;
1286 NCDR(node) = right;
1287 return node;
1288 }
1289
1290 extern Node*
1291 onig_node_new_anchor(int type)
1292 {
1293 Node* node = node_new();
1294 CHECK_NULL_RETURN(node);
1295
1296 SET_NTYPE(node, NT_ANCHOR);
1297 NANCHOR(node)->type = type;
1298 NANCHOR(node)->target = NULL;
1299 NANCHOR(node)->char_len = -1;
1300 NANCHOR(node)->ascii_range = 0;
1301 return node;
1302 }
1303
1304 static Node*
1305 node_new_backref(int back_num, int* backrefs, int by_name,
1306 #ifdef USE_BACKREF_WITH_LEVEL
1307 int exist_level, int nest_level,
1308 #endif
1309 ScanEnv* env)
1310 {
1311 int i;
1312 Node* node = node_new();
1313
1314 CHECK_NULL_RETURN(node);
1315
1316 SET_NTYPE(node, NT_BREF);
1317 NBREF(node)->state = 0;
1318 NBREF(node)->back_num = back_num;
1319 NBREF(node)->back_dynamic = (int* )NULL;
1320 if (by_name != 0)
1321 NBREF(node)->state |= NST_NAME_REF;
1322
1323 #ifdef USE_BACKREF_WITH_LEVEL
1324 if (exist_level != 0) {
1325 NBREF(node)->state |= NST_NEST_LEVEL;
1326 NBREF(node)->nest_level = nest_level;
1327 }
1328 #endif
1329
1330 for (i = 0; i < back_num; i++) {
1331 if (backrefs[i] <= env->num_mem &&
1332 IS_NULL(SCANENV_MEM_NODES(env)[backrefs[i]])) {
1333 NBREF(node)->state |= NST_RECURSION; /* /...(\1).../ */
1334 break;
1335 }
1336 }
1337
1338 if (back_num <= NODE_BACKREFS_SIZE) {
1339 for (i = 0; i < back_num; i++)
1340 NBREF(node)->back_static[i] = backrefs[i];
1341 }
1342 else {
1343 int* p = (int* )xmalloc(sizeof(int) * back_num);
1344 if (IS_NULL(p)) {
1345 onig_node_free(node);
1346 return NULL;
1347 }
1348 NBREF(node)->back_dynamic = p;
1349 for (i = 0; i < back_num; i++)
1350 p[i] = backrefs[i];
1351 }
1352 return node;
1353 }
1354
1355 #ifdef USE_SUBEXP_CALL
1356 static Node*
1357 node_new_call(UChar* name, UChar* name_end, int gnum)
1358 {
1359 Node* node = node_new();
1360 CHECK_NULL_RETURN(node);
1361
1362 SET_NTYPE(node, NT_CALL);
1363 NCALL(node)->state = 0;
1364 NCALL(node)->target = NULL_NODE;
1365 NCALL(node)->name = name;
1366 NCALL(node)->name_end = name_end;
1367 NCALL(node)->group_num = gnum; /* call by number if gnum != 0 */
1368 return node;
1369 }
1370 #endif
1371
1372 static Node*
1373 node_new_quantifier(int lower, int upper, int by_number)
1374 {
1375 Node* node = node_new();
1376 CHECK_NULL_RETURN(node);
1377
1378 SET_NTYPE(node, NT_QTFR);
1379 NQTFR(node)->state = 0;
1380 NQTFR(node)->target = NULL;
1381 NQTFR(node)->lower = lower;
1382 NQTFR(node)->upper = upper;
1383 NQTFR(node)->greedy = 1;
1384 NQTFR(node)->target_empty_info = NQ_TARGET_ISNOT_EMPTY;
1385 NQTFR(node)->head_exact = NULL_NODE;
1386 NQTFR(node)->next_head_exact = NULL_NODE;
1387 NQTFR(node)->is_refered = 0;
1388 if (by_number != 0)
1389 NQTFR(node)->state |= NST_BY_NUMBER;
1390
1391 #ifdef USE_COMBINATION_EXPLOSION_CHECK
1392 NQTFR(node)->comb_exp_check_num = 0;
1393 #endif
1394
1395 return node;
1396 }
1397
1398 static Node*
1399 node_new_enclose(int type)
1400 {
1401 Node* node = node_new();
1402 CHECK_NULL_RETURN(node);
1403
1404 SET_NTYPE(node, NT_ENCLOSE);
1405 NENCLOSE(node)->type = type;
1406 NENCLOSE(node)->state = 0;
1407 NENCLOSE(node)->regnum = 0;
1408 NENCLOSE(node)->option = 0;
1409 NENCLOSE(node)->target = NULL;
1410 NENCLOSE(node)->call_addr = -1;
1411 NENCLOSE(node)->opt_count = 0;
1412 return node;
1413 }
1414
1415 extern Node*
1416 onig_node_new_enclose(int type)
1417 {
1418 return node_new_enclose(type);
1419 }
1420
1421 static Node*
1422 node_new_enclose_memory(OnigOptionType option, int is_named)
1423 {
1424 Node* node = node_new_enclose(ENCLOSE_MEMORY);
1425 CHECK_NULL_RETURN(node);
1426 if (is_named != 0)
1427 SET_ENCLOSE_STATUS(node, NST_NAMED_GROUP);
1428
1429 #ifdef USE_SUBEXP_CALL
1430 NENCLOSE(node)->option = option;
1431 #endif
1432 return node;
1433 }
1434
1435 static Node*
1436 node_new_option(OnigOptionType option)
1437 {
1438 Node* node = node_new_enclose(ENCLOSE_OPTION);
1439 CHECK_NULL_RETURN(node);
1440 NENCLOSE(node)->option = option;
1441 return node;
1442 }
1443
1444 extern int
1445 onig_node_str_cat(Node* node, const UChar* s, const UChar* end)
1446 {
1447 ptrdiff_t addlen = end - s;
1448
1449 if (addlen > 0) {
1450 ptrdiff_t len = NSTR(node)->end - NSTR(node)->s;
1451
1452 if (NSTR(node)->capa > 0 || (len + addlen > NODE_STR_BUF_SIZE - 1)) {
1453 UChar* p;
1454 ptrdiff_t capa = len + addlen + NODE_STR_MARGIN;
1455
1456 if (capa <= NSTR(node)->capa) {
1457 onig_strcpy(NSTR(node)->s + len, s, end);
1458 }
1459 else {
1460 if (NSTR(node)->s == NSTR(node)->buf)
1461 p = strcat_capa_from_static(NSTR(node)->s, NSTR(node)->end,
1462 s, end, capa);
1463 else
1464 p = strcat_capa(NSTR(node)->s, NSTR(node)->end, s, end, capa);
1465
1466 CHECK_NULL_RETURN_MEMERR(p);
1467 NSTR(node)->s = p;
1468 NSTR(node)->capa = (int )capa;
1469 }
1470 }
1471 else {
1472 onig_strcpy(NSTR(node)->s + len, s, end);
1473 }
1474 NSTR(node)->end = NSTR(node)->s + len + addlen;
1475 }
1476
1477 return 0;
1478 }
1479
1480 extern int
1481 onig_node_str_set(Node* node, const UChar* s, const UChar* end)
1482 {
1483 onig_node_str_clear(node);
1484 return onig_node_str_cat(node, s, end);
1485 }
1486
1487 static int
1488 node_str_cat_char(Node* node, UChar c)
1489 {
1490 UChar s[1];
1491
1492 s[0] = c;
1493 return onig_node_str_cat(node, s, s + 1);
1494 }
1495
1496 static int
1497 node_str_cat_codepoint(Node* node, OnigEncoding enc, OnigCodePoint c)
1498 {
1499 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
1500 int num = ONIGENC_CODE_TO_MBC(enc, c, buf);
1501 if (num < 0) return num;
1502 return onig_node_str_cat(node, buf, buf + num);
1503 }
1504
1505 extern void
1506 onig_node_conv_to_str_node(Node* node, int flag)
1507 {
1508 SET_NTYPE(node, NT_STR);
1509 NSTR(node)->flag = flag;
1510 NSTR(node)->capa = 0;
1511 NSTR(node)->s = NSTR(node)->buf;
1512 NSTR(node)->end = NSTR(node)->buf;
1513 }
1514
1515 extern void
1516 onig_node_str_clear(Node* node)
1517 {
1518 if (NSTR(node)->capa != 0 &&
1519 IS_NOT_NULL(NSTR(node)->s) && NSTR(node)->s != NSTR(node)->buf) {
1520 xfree(NSTR(node)->s);
1521 }
1522
1523 NSTR(node)->capa = 0;
1524 NSTR(node)->flag = 0;
1525 NSTR(node)->s = NSTR(node)->buf;
1526 NSTR(node)->end = NSTR(node)->buf;
1527 }
1528
1529 static Node*
1530 node_new_str(const UChar* s, const UChar* end)
1531 {
1532 Node* node = node_new();
1533 CHECK_NULL_RETURN(node);
1534
1535 SET_NTYPE(node, NT_STR);
1536 NSTR(node)->capa = 0;
1537 NSTR(node)->flag = 0;
1538 NSTR(node)->s = NSTR(node)->buf;
1539 NSTR(node)->end = NSTR(node)->buf;
1540 if (onig_node_str_cat(node, s, end)) {
1541 onig_node_free(node);
1542 return NULL;
1543 }
1544 return node;
1545 }
1546
1547 extern Node*
1548 onig_node_new_str(const UChar* s, const UChar* end)
1549 {
1550 return node_new_str(s, end);
1551 }
1552
1553 static Node*
1554 node_new_str_raw(UChar* s, UChar* end)
1555 {
1556 Node* node = node_new_str(s, end);
1557 if (IS_NOT_NULL(node))
1558 NSTRING_SET_RAW(node);
1559 return node;
1560 }
1561
1562 static Node*
1563 node_new_empty(void)
1564 {
1565 return node_new_str(NULL, NULL);
1566 }
1567
1568 static Node*
1569 node_new_str_raw_char(UChar c)
1570 {
1571 UChar p[1];
1572
1573 p[0] = c;
1574 return node_new_str_raw(p, p + 1);
1575 }
1576
1577 static Node*
1578 str_node_split_last_char(StrNode* sn, OnigEncoding enc)
1579 {
1580 const UChar *p;
1581 Node* n = NULL_NODE;
1582
1583 if (sn->end > sn->s) {
1584 p = onigenc_get_prev_char_head(enc, sn->s, sn->end, sn->end);
1585 if (p && p > sn->s) { /* can be split. */
1586 n = node_new_str(p, sn->end);
1587 if (IS_NOT_NULL(n) && (sn->flag & NSTR_RAW) != 0)
1588 NSTRING_SET_RAW(n);
1589 sn->end = (UChar* )p;
1590 }
1591 }
1592 return n;
1593 }
1594
1595 static int
1596 str_node_can_be_split(StrNode* sn, OnigEncoding enc)
1597 {
1598 if (sn->end > sn->s) {
1599 return ((enclen(enc, sn->s, sn->end) < sn->end - sn->s) ? 1 : 0);
1600 }
1601 return 0;
1602 }
1603
1604 #ifdef USE_PAD_TO_SHORT_BYTE_CHAR
1605 static int
1606 node_str_head_pad(StrNode* sn, int num, UChar val)
1607 {
1608 UChar buf[NODE_STR_BUF_SIZE];
1609 int i, len;
1610
1611 len = sn->end - sn->s;
1612 onig_strcpy(buf, sn->s, sn->end);
1613 onig_strcpy(&(sn->s[num]), buf, buf + len);
1614 sn->end += num;
1615
1616 for (i = 0; i < num; i++) {
1617 sn->s[i] = val;
1618 }
1619 }
1620 #endif
1621
1622 extern int
1623 onig_scan_unsigned_number(UChar** src, const UChar* end, OnigEncoding enc)
1624 {
1625 unsigned int num, val;
1626 OnigCodePoint c;
1627 UChar* p = *src;
1628 PFETCH_READY;
1629
1630 num = 0;
1631 while (!PEND) {
1632 PFETCH(c);
1633 if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
1634 val = (unsigned int )DIGITVAL(c);
1635 if ((INT_MAX_LIMIT - val) / 10UL < num)
1636 return -1; /* overflow */
1637
1638 num = num * 10 + val;
1639 }
1640 else {
1641 PUNFETCH;
1642 break;
1643 }
1644 }
1645 *src = p;
1646 return num;
1647 }
1648
1649 static int
1650 scan_unsigned_hexadecimal_number(UChar** src, UChar* end, int minlen,
1651 int maxlen, OnigEncoding enc)
1652 {
1653 OnigCodePoint c;
1654 unsigned int num, val;
1655 int restlen;
1656 UChar* p = *src;
1657 PFETCH_READY;
1658
1659 restlen = maxlen - minlen;
1660 num = 0;
1661 while (!PEND && maxlen-- != 0) {
1662 PFETCH(c);
1663 if (ONIGENC_IS_CODE_XDIGIT(enc, c)) {
1664 val = (unsigned int )XDIGITVAL(enc,c);
1665 if ((INT_MAX_LIMIT - val) / 16UL < num)
1666 return -1; /* overflow */
1667
1668 num = (num << 4) + XDIGITVAL(enc,c);
1669 }
1670 else {
1671 PUNFETCH;
1672 break;
1673 }
1674 }
1675 if (maxlen > restlen)
1676 return -2; /* not enough digits */
1677 *src = p;
1678 return num;
1679 }
1680
1681 static int
1682 scan_unsigned_octal_number(UChar** src, UChar* end, int maxlen,
1683 OnigEncoding enc)
1684 {
1685 OnigCodePoint c;
1686 unsigned int num, val;
1687 UChar* p = *src;
1688 PFETCH_READY;
1689
1690 num = 0;
1691 while (!PEND && maxlen-- != 0) {
1692 PFETCH(c);
1693 if (ONIGENC_IS_CODE_DIGIT(enc, c) && c < '8') {
1694 val = ODIGITVAL(c);
1695 if ((INT_MAX_LIMIT - val) / 8UL < num)
1696 return -1; /* overflow */
1697
1698 num = (num << 3) + val;
1699 }
1700 else {
1701 PUNFETCH;
1702 break;
1703 }
1704 }
1705 *src = p;
1706 return num;
1707 }
1708
1709
1710 #define BBUF_WRITE_CODE_POINT(bbuf,pos,code) \
1711 BBUF_WRITE(bbuf, pos, &(code), SIZE_CODE_POINT)
1712
1713 /* data format:
1714 [n][from-1][to-1][from-2][to-2] ... [from-n][to-n]
1715 (all data size is OnigCodePoint)
1716 */
1717 static int
1718 new_code_range(BBuf** pbuf)
1719 {
1720 #define INIT_MULTI_BYTE_RANGE_SIZE (SIZE_CODE_POINT * 5)
1721 int r;
1722 OnigCodePoint n;
1723 BBuf* bbuf;
1724
1725 bbuf = *pbuf = (BBuf* )xmalloc(sizeof(BBuf));
1726 CHECK_NULL_RETURN_MEMERR(*pbuf);
1727 r = BBUF_INIT(*pbuf, INIT_MULTI_BYTE_RANGE_SIZE);
1728 if (r) return r;
1729
1730 n = 0;
1731 BBUF_WRITE_CODE_POINT(bbuf, 0, n);
1732 return 0;
1733 }
1734
1735 static int
1736 add_code_range_to_buf0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to,
1737 int checkdup)
1738 {
1739 int r, inc_n, pos;
1740 OnigCodePoint low, high, bound, x;
1741 OnigCodePoint n, *data;
1742 BBuf* bbuf;
1743
1744 if (from > to) {
1745 n = from; from = to; to = n;
1746 }
1747
1748 if (IS_NULL(*pbuf)) {
1749 r = new_code_range(pbuf);
1750 if (r) return r;
1751 bbuf = *pbuf;
1752 n = 0;
1753 }
1754 else {
1755 bbuf = *pbuf;
1756 GET_CODE_POINT(n, bbuf->p);
1757 }
1758 data = (OnigCodePoint* )(bbuf->p);
1759 data++;
1760
1761 bound = (from == 0) ? 0 : n;
1762 for (low = 0; low < bound; ) {
1763 x = (low + bound) >> 1;
1764 if (from - 1 > data[x*2 + 1])
1765 low = x + 1;
1766 else
1767 bound = x;
1768 }
1769
1770 high = (to == ONIG_LAST_CODE_POINT) ? n : low;
1771 for (bound = n; high < bound; ) {
1772 x = (high + bound) >> 1;
1773 if (to + 1 >= data[x*2])
1774 high = x + 1;
1775 else
1776 bound = x;
1777 }
1778 /* data[(low-1)*2+1] << from <= data[low*2]
1779 * data[(high-1)*2+1] <= to << data[high*2]
1780 */
1781
1782 inc_n = low + 1 - high;
1783 if (n + inc_n > ONIG_MAX_MULTI_BYTE_RANGES_NUM)
1784 return ONIGERR_TOO_MANY_MULTI_BYTE_RANGES;
1785
1786 if (inc_n != 1) {
1787 if (checkdup && from <= data[low*2+1]
1788 && (data[low*2] <= from || data[low*2+1] <= to))
1789 CC_DUP_WARN(env);
1790 if (from > data[low*2])
1791 from = data[low*2];
1792 if (to < data[(high - 1)*2 + 1])
1793 to = data[(high - 1)*2 + 1];
1794 }
1795
1796 if (inc_n != 0) {
1797 int from_pos = SIZE_CODE_POINT * (1 + high * 2);
1798 int to_pos = SIZE_CODE_POINT * (1 + (low + 1) * 2);
1799
1800 if (inc_n > 0) {
1801 if (high < n) {
1802 int size = (n - high) * 2 * SIZE_CODE_POINT;
1803 BBUF_MOVE_RIGHT(bbuf, from_pos, to_pos, size);
1804 }
1805 }
1806 else {
1807 BBUF_MOVE_LEFT_REDUCE(bbuf, from_pos, to_pos);
1808 }
1809 }
1810
1811 pos = SIZE_CODE_POINT * (1 + low * 2);
1812 BBUF_ENSURE_SIZE(bbuf, pos + SIZE_CODE_POINT * 2);
1813 BBUF_WRITE_CODE_POINT(bbuf, pos, from);
1814 BBUF_WRITE_CODE_POINT(bbuf, pos + SIZE_CODE_POINT, to);
1815 n += inc_n;
1816 BBUF_WRITE_CODE_POINT(bbuf, 0, n);
1817
1818 return 0;
1819 }
1820
1821 static int
1822 add_code_range_to_buf(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
1823 {
1824 return add_code_range_to_buf0(pbuf, env, from, to, 1);
1825 }
1826
1827 static int
1828 add_code_range0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to, int checkdup)
1829 {
1830 if (from > to) {
1831 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
1832 return 0;
1833 else
1834 return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
1835 }
1836
1837 return add_code_range_to_buf0(pbuf, env, from, to, checkdup);
1838 }
1839
1840 static int
1841 add_code_range(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
1842 {
1843 return add_code_range0(pbuf, env, from, to, 1);
1844 }
1845
1846 static int
1847 not_code_range_buf(OnigEncoding enc, BBuf* bbuf, BBuf** pbuf, ScanEnv* env)
1848 {
1849 int r, i, n;
1850 OnigCodePoint pre, from, *data, to = 0;
1851
1852 *pbuf = (BBuf* )NULL;
1853 if (IS_NULL(bbuf)) {
1854 set_all:
1855 return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
1856 }
1857
1858 data = (OnigCodePoint* )(bbuf->p);
1859 GET_CODE_POINT(n, data);
1860 data++;
1861 if (n <= 0) goto set_all;
1862
1863 r = 0;
1864 pre = MBCODE_START_POS(enc);
1865 for (i = 0; i < n; i++) {
1866 from = data[i*2];
1867 to = data[i*2+1];
1868 if (pre <= from - 1) {
1869 r = add_code_range_to_buf(pbuf, env, pre, from - 1);
1870 if (r != 0) return r;
1871 }
1872 if (to == ONIG_LAST_CODE_POINT) break;
1873 pre = to + 1;
1874 }
1875 if (to < ONIG_LAST_CODE_POINT) {
1876 r = add_code_range_to_buf(pbuf, env, to + 1, ONIG_LAST_CODE_POINT);
1877 }
1878 return r;
1879 }
1880
1881 #define SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2) do {\
1882 BBuf *tbuf; \
1883 int tnot; \
1884 tnot = not1; not1 = not2; not2 = tnot; \
1885 tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf; \
1886 } while (0)
1887
1888 static int
1889 or_code_range_buf(OnigEncoding enc, BBuf* bbuf1, int not1,
1890 BBuf* bbuf2, int not2, BBuf** pbuf, ScanEnv* env)
1891 {
1892 int r;
1893 OnigCodePoint i, n1, *data1;
1894 OnigCodePoint from, to;
1895
1896 *pbuf = (BBuf* )NULL;
1897 if (IS_NULL(bbuf1) && IS_NULL(bbuf2)) {
1898 if (not1 != 0 || not2 != 0)
1899 return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
1900 return 0;
1901 }
1902
1903 r = 0;
1904 if (IS_NULL(bbuf2))
1905 SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
1906
1907 if (IS_NULL(bbuf1)) {
1908 if (not1 != 0) {
1909 return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
1910 }
1911 else {
1912 if (not2 == 0) {
1913 return bbuf_clone(pbuf, bbuf2);
1914 }
1915 else {
1916 return not_code_range_buf(enc, bbuf2, pbuf, env);
1917 }
1918 }
1919 }
1920
1921 if (not1 != 0)
1922 SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
1923
1924 data1 = (OnigCodePoint* )(bbuf1->p);
1925 GET_CODE_POINT(n1, data1);
1926 data1++;
1927
1928 if (not2 == 0 && not1 == 0) { /* 1 OR 2 */
1929 r = bbuf_clone(pbuf, bbuf2);
1930 }
1931 else if (not1 == 0) { /* 1 OR (not 2) */
1932 r = not_code_range_buf(enc, bbuf2, pbuf, env);
1933 }
1934 if (r != 0) return r;
1935
1936 for (i = 0; i < n1; i++) {
1937 from = data1[i*2];
1938 to = data1[i*2+1];
1939 r = add_code_range_to_buf(pbuf, env, from, to);
1940 if (r != 0) return r;
1941 }
1942 return 0;
1943 }
1944
1945 static int
1946 and_code_range1(BBuf** pbuf, ScanEnv* env, OnigCodePoint from1, OnigCodePoint to1,
1947 OnigCodePoint* data, int n)
1948 {
1949 int i, r;
1950 OnigCodePoint from2, to2;
1951
1952 for (i = 0; i < n; i++) {
1953 from2 = data[i*2];
1954 to2 = data[i*2+1];
1955 if (from2 < from1) {
1956 if (to2 < from1) continue;
1957 else {
1958 from1 = to2 + 1;
1959 }
1960 }
1961 else if (from2 <= to1) {
1962 if (to2 < to1) {
1963 if (from1 <= from2 - 1) {
1964 r = add_code_range_to_buf(pbuf, env, from1, from2-1);
1965 if (r != 0) return r;
1966 }
1967 from1 = to2 + 1;
1968 }
1969 else {
1970 to1 = from2 - 1;
1971 }
1972 }
1973 else {
1974 from1 = from2;
1975 }
1976 if (from1 > to1) break;
1977 }
1978 if (from1 <= to1) {
1979 r = add_code_range_to_buf(pbuf, env, from1, to1);
1980 if (r != 0) return r;
1981 }
1982 return 0;
1983 }
1984
1985 static int
1986 and_code_range_buf(BBuf* bbuf1, int not1, BBuf* bbuf2, int not2, BBuf** pbuf, ScanEnv* env)
1987 {
1988 int r;
1989 OnigCodePoint i, j, n1, n2, *data1, *data2;
1990 OnigCodePoint from, to, from1, to1, from2, to2;
1991
1992 *pbuf = (BBuf* )NULL;
1993 if (IS_NULL(bbuf1)) {
1994 if (not1 != 0 && IS_NOT_NULL(bbuf2)) /* not1 != 0 -> not2 == 0 */
1995 return bbuf_clone(pbuf, bbuf2);
1996 return 0;
1997 }
1998 else if (IS_NULL(bbuf2)) {
1999 if (not2 != 0)
2000 return bbuf_clone(pbuf, bbuf1);
2001 return 0;
2002 }
2003
2004 if (not1 != 0)
2005 SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
2006
2007 data1 = (OnigCodePoint* )(bbuf1->p);
2008 data2 = (OnigCodePoint* )(bbuf2->p);
2009 GET_CODE_POINT(n1, data1);
2010 GET_CODE_POINT(n2, data2);
2011 data1++;
2012 data2++;
2013
2014 if (not2 == 0 && not1 == 0) { /* 1 AND 2 */
2015 for (i = 0; i < n1; i++) {
2016 from1 = data1[i*2];
2017 to1 = data1[i*2+1];
2018 for (j = 0; j < n2; j++) {
2019 from2 = data2[j*2];
2020 to2 = data2[j*2+1];
2021 if (from2 > to1) break;
2022 if (to2 < from1) continue;
2023 from = MAX(from1, from2);
2024 to = MIN(to1, to2);
2025 r = add_code_range_to_buf(pbuf, env, from, to);
2026 if (r != 0) return r;
2027 }
2028 }
2029 }
2030 else if (not1 == 0) { /* 1 AND (not 2) */
2031 for (i = 0; i < n1; i++) {
2032 from1 = data1[i*2];
2033 to1 = data1[i*2+1];
2034 r = and_code_range1(pbuf, env, from1, to1, data2, n2);
2035 if (r != 0) return r;
2036 }
2037 }
2038
2039 return 0;
2040 }
2041
2042 static int
2043 and_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env)
2044 {
2045 OnigEncoding enc = env->enc;
2046 int r, not1, not2;
2047 BBuf *buf1, *buf2, *pbuf = 0;
2048 BitSetRef bsr1, bsr2;
2049 BitSet bs1, bs2;
2050
2051 not1 = IS_NCCLASS_NOT(dest);
2052 bsr1 = dest->bs;
2053 buf1 = dest->mbuf;
2054 not2 = IS_NCCLASS_NOT(cc);
2055 bsr2 = cc->bs;
2056 buf2 = cc->mbuf;
2057
2058 if (not1 != 0) {
2059 bitset_invert_to(bsr1, bs1);
2060 bsr1 = bs1;
2061 }
2062 if (not2 != 0) {
2063 bitset_invert_to(bsr2, bs2);
2064 bsr2 = bs2;
2065 }
2066 bitset_and(bsr1, bsr2);
2067 if (bsr1 != dest->bs) {
2068 bitset_copy(dest->bs, bsr1);
2069 bsr1 = dest->bs;
2070 }
2071 if (not1 != 0) {
2072 bitset_invert(dest->bs);
2073 }
2074
2075 if (! ONIGENC_IS_SINGLEBYTE(enc)) {
2076 if (not1 != 0 && not2 != 0) {
2077 r = or_code_range_buf(enc, buf1, 0, buf2, 0, &pbuf, env);
2078 }
2079 else {
2080 r = and_code_range_buf(buf1, not1, buf2, not2, &pbuf, env);
2081 if (r == 0 && not1 != 0) {
2082 BBuf *tbuf = 0;
2083 r = not_code_range_buf(enc, pbuf, &tbuf, env);
2084 bbuf_free(pbuf);
2085 pbuf = tbuf;
2086 }
2087 }
2088 if (r != 0) {
2089 bbuf_free(pbuf);
2090 return r;
2091 }
2092
2093 dest->mbuf = pbuf;
2094 bbuf_free(buf1);
2095 return r;
2096 }
2097 return 0;
2098 }
2099
2100 static int
2101 or_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env)
2102 {
2103 OnigEncoding enc = env->enc;
2104 int r, not1, not2;
2105 BBuf *buf1, *buf2, *pbuf = 0;
2106 BitSetRef bsr1, bsr2;
2107 BitSet bs1, bs2;
2108
2109 not1 = IS_NCCLASS_NOT(dest);
2110 bsr1 = dest->bs;
2111 buf1 = dest->mbuf;
2112 not2 = IS_NCCLASS_NOT(cc);
2113 bsr2 = cc->bs;
2114 buf2 = cc->mbuf;
2115
2116 if (not1 != 0) {
2117 bitset_invert_to(bsr1, bs1);
2118 bsr1 = bs1;
2119 }
2120 if (not2 != 0) {
2121 bitset_invert_to(bsr2, bs2);
2122 bsr2 = bs2;
2123 }
2124 bitset_or(bsr1, bsr2);
2125 if (bsr1 != dest->bs) {
2126 bitset_copy(dest->bs, bsr1);
2127 bsr1 = dest->bs;
2128 }
2129 if (not1 != 0) {
2130 bitset_invert(dest->bs);
2131 }
2132
2133 if (! ONIGENC_IS_SINGLEBYTE(enc)) {
2134 if (not1 != 0 && not2 != 0) {
2135 r = and_code_range_buf(buf1, 0, buf2, 0, &pbuf, env);
2136 }
2137 else {
2138 r = or_code_range_buf(enc, buf1, not1, buf2, not2, &pbuf, env);
2139 if (r == 0 && not1 != 0) {
2140 BBuf *tbuf = 0;
2141 r = not_code_range_buf(enc, pbuf, &tbuf, env);
2142 bbuf_free(pbuf);
2143 pbuf = tbuf;
2144 }
2145 }
2146 if (r != 0) {
2147 bbuf_free(pbuf);
2148 return r;
2149 }
2150
2151 dest->mbuf = pbuf;
2152 bbuf_free(buf1);
2153 return r;
2154 }
2155 else
2156 return 0;
2157 }
2158
2159 static void UNKNOWN_ESC_WARN(ScanEnv *env, int c);
2160
2161 static int
2162 conv_backslash_value(int c, ScanEnv* env)
2163 {
2164 if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_CONTROL_CHARS)) {
2165 switch (c) {
2166 case 'n': return '\n';
2167 case 't': return '\t';
2168 case 'r': return '\r';
2169 case 'f': return '\f';
2170 case 'a': return '\007';
2171 case 'b': return '\010';
2172 case 'e': return '\033';
2173 case 'v':
2174 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_V_VTAB))
2175 return '\v';
2176 break;
2177
2178 default:
2179 if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
2180 UNKNOWN_ESC_WARN(env, c);
2181 break;
2182 }
2183 }
2184 return c;
2185 }
2186
2187 #ifdef USE_NO_INVALID_QUANTIFIER
2188 #define is_invalid_quantifier_target(node) 0
2189 #else
2190 static int
2191 is_invalid_quantifier_target(Node* node)
2192 {
2193 switch (NTYPE(node)) {
2194 case NT_ANCHOR:
2195 return 1;
2196 break;
2197
2198 case NT_ENCLOSE:
2199 /* allow enclosed elements */
2200 /* return is_invalid_quantifier_target(NENCLOSE(node)->target); */
2201 break;
2202
2203 case NT_LIST:
2204 do {
2205 if (! is_invalid_quantifier_target(NCAR(node))) return 0;
2206 } while (IS_NOT_NULL(node = NCDR(node)));
2207 return 0;
2208 break;
2209
2210 case NT_ALT:
2211 do {
2212 if (is_invalid_quantifier_target(NCAR(node))) return 1;
2213 } while (IS_NOT_NULL(node = NCDR(node)));
2214 break;
2215
2216 default:
2217 break;
2218 }
2219 return 0;
2220 }
2221 #endif
2222
2223 /* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */
2224 static int
2225 popular_quantifier_num(QtfrNode* q)
2226 {
2227 if (q->greedy) {
2228 if (q->lower == 0) {
2229 if (q->upper == 1) return 0;
2230 else if (IS_REPEAT_INFINITE(q->upper)) return 1;
2231 }
2232 else if (q->lower == 1) {
2233 if (IS_REPEAT_INFINITE(q->upper)) return 2;
2234 }
2235 }
2236 else {
2237 if (q->lower == 0) {
2238 if (q->upper == 1) return 3;
2239 else if (IS_REPEAT_INFINITE(q->upper)) return 4;
2240 }
2241 else if (q->lower == 1) {
2242 if (IS_REPEAT_INFINITE(q->upper)) return 5;
2243 }
2244 }
2245 return -1;
2246 }
2247
2248
2249 enum ReduceType {
2250 RQ_ASIS = 0, /* as is */
2251 RQ_DEL = 1, /* delete parent */
2252 RQ_A, /* to '*' */
2253 RQ_AQ, /* to '*?' */
2254 RQ_QQ, /* to '??' */
2255 RQ_P_QQ, /* to '+)??' */
2256 RQ_PQ_Q /* to '+?)?' */
2257 };
2258
2259 static enum ReduceType const ReduceTypeTable[6][6] = {
2260 {RQ_DEL, RQ_A, RQ_A, RQ_QQ, RQ_AQ, RQ_ASIS}, /* '?' */
2261 {RQ_DEL, RQ_DEL, RQ_DEL, RQ_P_QQ, RQ_P_QQ, RQ_DEL}, /* '*' */
2262 {RQ_A, RQ_A, RQ_DEL, RQ_ASIS, RQ_P_QQ, RQ_DEL}, /* '+' */
2263 {RQ_DEL, RQ_AQ, RQ_AQ, RQ_DEL, RQ_AQ, RQ_AQ}, /* '??' */
2264 {RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL}, /* '*?' */
2265 {RQ_ASIS, RQ_PQ_Q, RQ_DEL, RQ_AQ, RQ_AQ, RQ_DEL} /* '+?' */
2266 };
2267
2268 extern void
2269 onig_reduce_nested_quantifier(Node* pnode, Node* cnode)
2270 {
2271 int pnum, cnum;
2272 QtfrNode *p, *c;
2273
2274 p = NQTFR(pnode);
2275 c = NQTFR(cnode);
2276 pnum = popular_quantifier_num(p);
2277 cnum = popular_quantifier_num(c);
2278 if (pnum < 0 || cnum < 0) return ;
2279
2280 switch (ReduceTypeTable[cnum][pnum]) {
2281 case RQ_DEL:
2282 *pnode = *cnode;
2283 break;
2284 case RQ_A:
2285 p->target = c->target;
2286 p->lower = 0; p->upper = REPEAT_INFINITE; p->greedy = 1;
2287 break;
2288 case RQ_AQ:
2289 p->target = c->target;
2290 p->lower = 0; p->upper = REPEAT_INFINITE; p->greedy = 0;
2291 break;
2292 case RQ_QQ:
2293 p->target = c->target;
2294 p->lower = 0; p->upper = 1; p->greedy = 0;
2295 break;
2296 case RQ_P_QQ:
2297 p->target = cnode;
2298 p->lower = 0; p->upper = 1; p->greedy = 0;
2299 c->lower = 1; c->upper = REPEAT_INFINITE; c->greedy = 1;
2300 return ;
2301 break;
2302 case RQ_PQ_Q:
2303 p->target = cnode;
2304 p->lower = 0; p->upper = 1; p->greedy = 1;
2305 c->lower = 1; c->upper = REPEAT_INFINITE; c->greedy = 0;
2306 return ;
2307 break;
2308 case RQ_ASIS:
2309 p->target = cnode;
2310 return ;
2311 break;
2312 }
2313
2314 c->target = NULL_NODE;
2315 onig_node_free(cnode);
2316 }
2317
2318
2319 enum TokenSyms {
2320 TK_EOT = 0, /* end of token */
2321 TK_RAW_BYTE = 1,
2322 TK_CHAR,
2323 TK_STRING,
2324 TK_CODE_POINT,
2325 TK_ANYCHAR,
2326 TK_CHAR_TYPE,
2327 TK_BACKREF,
2328 TK_CALL,
2329 TK_ANCHOR,
2330 TK_OP_REPEAT,
2331 TK_INTERVAL,
2332 TK_ANYCHAR_ANYTIME, /* SQL '%' == .* */
2333 TK_ALT,
2334 TK_SUBEXP_OPEN,
2335 TK_SUBEXP_CLOSE,
2336 TK_CC_OPEN,
2337 TK_QUOTE_OPEN,
2338 TK_CHAR_PROPERTY, /* \p{...}, \P{...} */
2339 TK_LINEBREAK,
2340 TK_EXTENDED_GRAPHEME_CLUSTER,
2341 TK_KEEP,
2342 /* in cc */
2343 TK_CC_CLOSE,
2344 TK_CC_RANGE,
2345 TK_POSIX_BRACKET_OPEN,
2346 TK_CC_AND, /* && */
2347 TK_CC_CC_OPEN /* [ */
2348 };
2349
2350 typedef struct {
2351 enum TokenSyms type;
2352 int escaped;
2353 int base; /* is number: 8, 16 (used in [....]) */
2354 UChar* backp;
2355 union {
2356 UChar* s;
2357 int c;
2358 OnigCodePoint code;
2359 struct {
2360 int subtype;
2361 int ascii_range;
2362 } anchor;
2363 struct {
2364 int lower;
2365 int upper;
2366 int greedy;
2367 int possessive;
2368 } repeat;
2369 struct {
2370 int num;
2371 int ref1;
2372 int* refs;
2373 int by_name;
2374 #ifdef USE_BACKREF_WITH_LEVEL
2375 int exist_level;
2376 int level; /* \k<name+n> */
2377 #endif
2378 } backref;
2379 struct {
2380 UChar* name;
2381 UChar* name_end;
2382 int gnum;
2383 int rel;
2384 } call;
2385 struct {
2386 int ctype;
2387 int not;
2388 } prop;
2389 } u;
2390 } OnigToken;
2391
2392
2393 static int
2394 fetch_range_quantifier(UChar** src, UChar* end, OnigToken* tok, ScanEnv* env)
2395 {
2396 int low, up, syn_allow, non_low = 0;
2397 int r = 0;
2398 OnigCodePoint c;
2399 OnigEncoding enc = env->enc;
2400 UChar* p = *src;
2401 PFETCH_READY;
2402
2403 syn_allow = IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INVALID_INTERVAL);
2404
2405 if (PEND) {
2406 if (syn_allow)
2407 return 1; /* "....{" : OK! */
2408 else
2409 return ONIGERR_END_PATTERN_AT_LEFT_BRACE; /* "....{" syntax error */
2410 }
2411
2412 if (! syn_allow) {
2413 c = PPEEK;
2414 if (c == ')' || c == '(' || c == '|') {
2415 return ONIGERR_END_PATTERN_AT_LEFT_BRACE;
2416 }
2417 }
2418
2419 low = onig_scan_unsigned_number(&p, end, env->enc);
2420 if (low < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
2421 if (low > ONIG_MAX_REPEAT_NUM)
2422 return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
2423
2424 if (p == *src) { /* can't read low */
2425 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV)) {
2426 /* allow {,n} as {0,n} */
2427 low = 0;
2428 non_low = 1;
2429 }
2430 else
2431 goto invalid;
2432 }
2433
2434 if (PEND) goto invalid;
2435 PFETCH(c);
2436 if (c == ',') {
2437 UChar* prev = p;
2438 up = onig_scan_unsigned_number(&p, end, env->enc);
2439 if (up < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
2440 if (up > ONIG_MAX_REPEAT_NUM)
2441 return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
2442
2443 if (p == prev) {
2444 if (non_low != 0)
2445 goto invalid;
2446 up = REPEAT_INFINITE; /* {n,} : {n,infinite} */
2447 }
2448 }
2449 else {
2450 if (non_low != 0)
2451 goto invalid;
2452
2453 PUNFETCH;
2454 up = low; /* {n} : exact n times */
2455 r = 2; /* fixed */
2456 }
2457
2458 if (PEND) goto invalid;
2459 PFETCH(c);
2460 if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) {
2461 if (c != MC_ESC(env->syntax)) goto invalid;
2462 PFETCH(c);
2463 }
2464 if (c != '}') goto invalid;
2465
2466 if (!IS_REPEAT_INFINITE(up) && low > up) {
2467 return ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE;
2468 }
2469
2470 tok->type = TK_INTERVAL;
2471 tok->u.repeat.lower = low;
2472 tok->u.repeat.upper = up;
2473 *src = p;
2474 return r; /* 0: normal {n,m}, 2: fixed {n} */
2475
2476 invalid:
2477 if (syn_allow)
2478 return 1; /* OK */
2479 else
2480 return ONIGERR_INVALID_REPEAT_RANGE_PATTERN;
2481 }
2482
2483 /* \M-, \C-, \c, or \... */
2484 static int
2485 fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env)
2486 {
2487 int v;
2488 OnigCodePoint c;
2489 OnigEncoding enc = env->enc;
2490 UChar* p = *src;
2491 PFETCH_READY;
2492
2493 if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
2494
2495 PFETCH(c);
2496 switch (c) {
2497 case 'M':
2498 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META)) {
2499 if (PEND) return ONIGERR_END_PATTERN_AT_META;
2500 PFETCH(c);
2501 if (c != '-') return ONIGERR_META_CODE_SYNTAX;
2502 if (PEND) return ONIGERR_END_PATTERN_AT_META;
2503 PFETCH(c);
2504 if (c == MC_ESC(env->syntax)) {
2505 v = fetch_escaped_value(&p, end, env);
2506 if (v < 0) return v;
2507 c = (OnigCodePoint )v;
2508 }
2509 c = ((c & 0xff) | 0x80);
2510 }
2511 else
2512 goto backslash;
2513 break;
2514
2515 case 'C':
2516 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL)) {
2517 if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL;
2518 PFETCH(c);
2519 if (c != '-') return ONIGERR_CONTROL_CODE_SYNTAX;
2520 goto control;
2521 }
2522 else
2523 goto backslash;
2524
2525 case 'c':
2526 if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_C_CONTROL)) {
2527 control:
2528 if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL;
2529 PFETCH(c);
2530 if (c == '?') {
2531 c = 0177;
2532 }
2533 else {
2534 if (c == MC_ESC(env->syntax)) {
2535 v = fetch_escaped_value(&p, end, env);
2536 if (v < 0) return v;
2537 c = (OnigCodePoint )v;
2538 }
2539 c &= 0x9f;
2540 }
2541 break;
2542 }
2543 /* fall through */
2544
2545 default:
2546 {
2547 backslash:
2548 c = conv_backslash_value(c, env);
2549 }
2550 break;
2551 }
2552
2553 *src = p;
2554 return c;
2555 }
2556
2557 static int fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env);
2558
2559 static OnigCodePoint
2560 get_name_end_code_point(OnigCodePoint start)
2561 {
2562 switch (start) {
2563 case '<': return (OnigCodePoint )'>'; break;
2564 case '\'': return (OnigCodePoint )'\''; break;
2565 case '(': return (OnigCodePoint )')'; break;
2566 case '{': return (OnigCodePoint )'}'; break;
2567 default:
2568 break;
2569 }
2570
2571 return (OnigCodePoint )0;
2572 }
2573
2574 #ifdef USE_NAMED_GROUP
2575 #ifdef USE_BACKREF_WITH_LEVEL
2576 /*
2577 \k<name+n>, \k<name-n>
2578 \k<num+n>, \k<num-n>
2579 \k<-num+n>, \k<-num-n>
2580 */
2581 static int
2582 fetch_name_with_level(OnigCodePoint start_code, UChar** src, UChar* end,
2583 UChar** rname_end, ScanEnv* env,
2584 int* rback_num, int* rlevel)
2585 {
2586 int r, sign, is_num, exist_level;
2587 OnigCodePoint end_code;
2588 OnigCodePoint c = 0;
2589 OnigEncoding enc = env->enc;
2590 UChar *name_end;
2591 UChar *pnum_head;
2592 UChar *p = *src;
2593 PFETCH_READY;
2594
2595 *rback_num = 0;
2596 is_num = exist_level = 0;
2597 sign = 1;
2598 pnum_head = *src;
2599
2600 end_code = get_name_end_code_point(start_code);
2601
2602 name_end = end;
2603 r = 0;
2604 if (PEND) {
2605 return ONIGERR_EMPTY_GROUP_NAME;
2606 }
2607 else {
2608 PFETCH(c);
2609 if (c == end_code)
2610 return ONIGERR_EMPTY_GROUP_NAME;
2611
2612 if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
2613 is_num = 1;
2614 }
2615 else if (c == '-') {
2616 is_num = 2;
2617 sign = -1;
2618 pnum_head = p;
2619 }
2620 else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
2621 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2622 }
2623 }
2624
2625 while (!PEND) {
2626 name_end = p;
2627 PFETCH(c);
2628 if (c == end_code || c == ')' || c == '+' || c == '-') {
2629 if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME;
2630 break;
2631 }
2632
2633 if (is_num != 0) {
2634 if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
2635 is_num = 1;
2636 }
2637 else {
2638 r = ONIGERR_INVALID_GROUP_NAME;
2639 is_num = 0;
2640 }
2641 }
2642 else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
2643 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2644 }
2645 }
2646
2647 if (r == 0 && c != end_code) {
2648 if (c == '+' || c == '-') {
2649 int level;
2650 int flag = (c == '-' ? -1 : 1);
2651
2652 PFETCH(c);
2653 if (! ONIGENC_IS_CODE_DIGIT(enc, c)) goto err;
2654 PUNFETCH;
2655 level = onig_scan_unsigned_number(&p, end, enc);
2656 if (level < 0) return ONIGERR_TOO_BIG_NUMBER;
2657 *rlevel = (level * flag);
2658 exist_level = 1;
2659
2660 PFETCH(c);
2661 if (c == end_code)
2662 goto end;
2663 }
2664
2665 err:
2666 r = ONIGERR_INVALID_GROUP_NAME;
2667 name_end = end;
2668 }
2669
2670 end:
2671 if (r == 0) {
2672 if (is_num != 0) {
2673 *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
2674 if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
2675 else if (*rback_num == 0) goto err;
2676
2677 *rback_num *= sign;
2678 }
2679
2680 *rname_end = name_end;
2681 *src = p;
2682 return (exist_level ? 1 : 0);
2683 }
2684 else {
2685 onig_scan_env_set_error_string(env, r, *src, name_end);
2686 return r;
2687 }
2688 }
2689 #endif /* USE_BACKREF_WITH_LEVEL */
2690
2691 /*
2692 ref: 0 -> define name (don't allow number name)
2693 1 -> reference name (allow number name)
2694 */
2695 static int
2696 fetch_name(OnigCodePoint start_code, UChar** src, UChar* end,
2697 UChar** rname_end, ScanEnv* env, int* rback_num, int ref)
2698 {
2699 int r, is_num, sign;
2700 OnigCodePoint end_code;
2701 OnigCodePoint c = 0;
2702 OnigEncoding enc = env->enc;
2703 UChar *name_end;
2704 UChar *pnum_head;
2705 UChar *p = *src;
2706 PFETCH_READY;
2707
2708 *rback_num = 0;
2709
2710 end_code = get_name_end_code_point(start_code);
2711
2712 name_end = end;
2713 pnum_head = *src;
2714 r = 0;
2715 is_num = 0;
2716 sign = 1;
2717 if (PEND) {
2718 return ONIGERR_EMPTY_GROUP_NAME;
2719 }
2720 else {
2721 PFETCH(c);
2722 if (c == end_code)
2723 return ONIGERR_EMPTY_GROUP_NAME;
2724
2725 if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
2726 if (ref == 1)
2727 is_num = 1;
2728 else {
2729 r = ONIGERR_INVALID_GROUP_NAME;
2730 is_num = 0;
2731 }
2732 }
2733 else if (c == '-') {
2734 if (ref == 1) {
2735 is_num = 2;
2736 sign = -1;
2737 pnum_head = p;
2738 }
2739 else {
2740 r = ONIGERR_INVALID_GROUP_NAME;
2741 is_num = 0;
2742 }
2743 }
2744 else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
2745 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2746 }
2747 }
2748
2749 if (r == 0) {
2750 while (!PEND) {
2751 name_end = p;
2752 PFETCH(c);
2753 if (c == end_code || c == ')') {
2754 if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME;
2755 break;
2756 }
2757
2758 if (is_num != 0) {
2759 if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
2760 is_num = 1;
2761 }
2762 else {
2763 if (!ONIGENC_IS_CODE_WORD(enc, c))
2764 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2765 else
2766 r = ONIGERR_INVALID_GROUP_NAME;
2767
2768 is_num = 0;
2769 }
2770 }
2771 else {
2772 if (!ONIGENC_IS_CODE_WORD(enc, c)) {
2773 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2774 }
2775 }
2776 }
2777
2778 if (c != end_code) {
2779 r = ONIGERR_INVALID_GROUP_NAME;
2780 name_end = end;
2781 }
2782
2783 if (is_num != 0) {
2784 *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
2785 if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
2786 else if (*rback_num == 0) {
2787 r = ONIGERR_INVALID_GROUP_NAME;
2788 goto err;
2789 }
2790
2791 *rback_num *= sign;
2792 }
2793
2794 *rname_end = name_end;
2795 *src = p;
2796 return 0;
2797 }
2798 else {
2799 while (!PEND) {
2800 name_end = p;
2801 PFETCH(c);
2802 if (c == end_code || c == ')')
2803 break;
2804 }
2805 if (PEND)
2806 name_end = end;
2807
2808 err:
2809 onig_scan_env_set_error_string(env, r, *src, name_end);
2810 return r;
2811 }
2812 }
2813 #else
2814 static int
2815 fetch_name(OnigCodePoint start_code, UChar** src, UChar* end,
2816 UChar** rname_end, ScanEnv* env, int* rback_num, int ref)
2817 {
2818 int r, is_num, sign;
2819 OnigCodePoint end_code;
2820 OnigCodePoint c = 0;
2821 UChar *name_end;
2822 OnigEncoding enc = env->enc;
2823 UChar *pnum_head;
2824 UChar *p = *src;
2825 PFETCH_READY;
2826
2827 *rback_num = 0;
2828
2829 end_code = get_name_end_code_point(start_code);
2830
2831 *rname_end = name_end = end;
2832 r = 0;
2833 pnum_head = *src;
2834 is_num = 0;
2835 sign = 1;
2836
2837 if (PEND) {
2838 return ONIGERR_EMPTY_GROUP_NAME;
2839 }
2840 else {
2841 PFETCH(c);
2842 if (c == end_code)
2843 return ONIGERR_EMPTY_GROUP_NAME;
2844
2845 if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
2846 is_num = 1;
2847 }
2848 else if (c == '-') {
2849 is_num = 2;
2850 sign = -1;
2851 pnum_head = p;
2852 }
2853 else {
2854 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2855 }
2856 }
2857
2858 while (!PEND) {
2859 name_end = p;
2860
2861 PFETCH(c);
2862 if (c == end_code || c == ')') break;
2863 if (! ONIGENC_IS_CODE_DIGIT(enc, c))
2864 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2865 }
2866 if (r == 0 && c != end_code) {
2867 r = ONIGERR_INVALID_GROUP_NAME;
2868 name_end = end;
2869 }
2870
2871 if (r == 0) {
2872 *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
2873 if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
2874 else if (*rback_num == 0) {
2875 r = ONIGERR_INVALID_GROUP_NAME;
2876 goto err;
2877 }
2878 *rback_num *= sign;
2879
2880 *rname_end = name_end;
2881 *src = p;
2882 return 0;
2883 }
2884 else {
2885 err:
2886 onig_scan_env_set_error_string(env, r, *src, name_end);
2887 return r;
2888 }
2889 }
2890 #endif /* USE_NAMED_GROUP */
2891
2892 void onig_vsnprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
2893 UChar* pat, UChar* pat_end, const UChar *fmt, va_list args);
2894
2895 static void
2896 onig_syntax_warn(ScanEnv *env, const char *fmt, ...)
2897 {
2898 va_list args;
2899 UChar buf[WARN_BUFSIZE];
2900 va_start(args, fmt);
2901 onig_vsnprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
2902 env->pattern, env->pattern_end,
2903 (const UChar *)fmt, args);
2904 va_end(args);
2905 if (env->sourcefile == NULL)
2906 rb_warn("%s", (char *)buf);
2907 else
2908 rb_compile_warn(env->sourcefile, env->sourceline, "%s", (char *)buf);
2909 }
2910
2911 static void
2912 CC_ESC_WARN(ScanEnv *env, UChar *c)
2913 {
2914 if (onig_warn == onig_null_warn) return ;
2915
2916 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED) &&
2917 IS_SYNTAX_BV(env->syntax, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC)) {
2918 onig_syntax_warn(env, "character class has '%s' without escape", c);
2919 }
2920 }
2921
2922 static void
2923 CLOSE_BRACKET_WITHOUT_ESC_WARN(ScanEnv* env, UChar* c)
2924 {
2925 if (onig_warn == onig_null_warn) return ;
2926
2927 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED)) {
2928 onig_syntax_warn(env, "regular expression has '%s' without escape", c);
2929 }
2930 }
2931
2932 static void
2933 CC_DUP_WARN(ScanEnv *env)
2934 {
2935 if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ;
2936
2937 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_DUP) &&
2938 !(env->warnings_flag & ONIG_SYN_WARN_CC_DUP)) {
2939 env->warnings_flag |= ONIG_SYN_WARN_CC_DUP;
2940 onig_syntax_warn(env, "character class has duplicated range");
2941 }
2942 }
2943
2944 static void
2945 UNKNOWN_ESC_WARN(ScanEnv *env, int c)
2946 {
2947 if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ;
2948 onig_syntax_warn(env, "Unknown escape \\%c is ignored", c);
2949 }
2950
2951 static UChar*
2952 find_str_position(OnigCodePoint s[], int n, UChar* from, UChar* to,
2953 UChar **next, OnigEncoding enc)
2954 {
2955 int i;
2956 OnigCodePoint x;
2957 UChar *q;
2958 UChar *p = from;
2959
2960 while (p < to) {
2961 x = ONIGENC_MBC_TO_CODE(enc, p, to);
2962 q = p + enclen(enc, p, to);
2963 if (x == s[0]) {
2964 for (i = 1; i < n && q < to; i++) {
2965 x = ONIGENC_MBC_TO_CODE(enc, q, to);
2966 if (x != s[i]) break;
2967 q += enclen(enc, q, to);
2968 }
2969 if (i >= n) {
2970 if (IS_NOT_NULL(next))
2971 *next = q;
2972 return p;
2973 }
2974 }
2975 p = q;
2976 }
2977 return NULL_UCHARP;
2978 }
2979
2980 static int
2981 str_exist_check_with_esc(OnigCodePoint s[], int n, UChar* from, UChar* to,
2982 OnigCodePoint bad, OnigEncoding enc, const OnigSyntaxType* syn)
2983 {
2984 int i, in_esc;
2985 OnigCodePoint x;
2986 UChar *q;
2987 UChar *p = from;
2988
2989 in_esc = 0;
2990 while (p < to) {
2991 if (in_esc) {
2992 in_esc = 0;
2993 p += enclen(enc, p, to);
2994 }
2995 else {
2996 x = ONIGENC_MBC_TO_CODE(enc, p, to);
2997 q = p + enclen(enc, p, to);
2998 if (x == s[0]) {
2999 for (i = 1; i < n && q < to; i++) {
3000 x = ONIGENC_MBC_TO_CODE(enc, q, to);
3001 if (x != s[i]) break;
3002 q += enclen(enc, q, to);
3003 }
3004 if (i >= n) return 1;
3005 p += enclen(enc, p, to);
3006 }
3007 else {
3008 x = ONIGENC_MBC_TO_CODE(enc, p, to);
3009 if (x == bad) return 0;
3010 else if (x == MC_ESC(syn)) in_esc = 1;
3011 p = q;
3012 }
3013 }
3014 }
3015 return 0;
3016 }
3017
3018 static int
3019 fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
3020 {
3021 int num;
3022 OnigCodePoint c, c2;
3023 const OnigSyntaxType* syn = env->syntax;
3024 OnigEncoding enc = env->enc;
3025 UChar* prev;
3026 UChar* p = *src;
3027 PFETCH_READY;
3028
3029 if (PEND) {
3030 tok->type = TK_EOT;
3031 return tok->type;
3032 }
3033
3034 PFETCH(c);
3035 tok->type = TK_CHAR;
3036 tok->base = 0;
3037 tok->u.c = c;
3038 tok->escaped = 0;
3039
3040 if (c == ']') {
3041 tok->type = TK_CC_CLOSE;
3042 }
3043 else if (c == '-') {
3044 tok->type = TK_CC_RANGE;
3045 }
3046 else if (c == MC_ESC(syn)) {
3047 if (! IS_SYNTAX_BV(syn, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC))
3048 goto end;
3049
3050 if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
3051
3052 PFETCH(c);
3053 tok->escaped = 1;
3054 tok->u.c = c;
3055 switch (c) {
3056 case 'w':
3057 tok->type = TK_CHAR_TYPE;
3058 tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
3059 tok->u.prop.not = 0;
3060 break;
3061 case 'W':
3062 tok->type = TK_CHAR_TYPE;
3063 tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
3064 tok->u.prop.not = 1;
3065 break;
3066 case 'd':
3067 tok->type = TK_CHAR_TYPE;
3068 tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
3069 tok->u.prop.not = 0;
3070 break;
3071 case 'D':
3072 tok->type = TK_CHAR_TYPE;
3073 tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
3074 tok->u.prop.not = 1;
3075 break;
3076 case 's':
3077 tok->type = TK_CHAR_TYPE;
3078 tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
3079 tok->u.prop.not = 0;
3080 break;
3081 case 'S':
3082 tok->type = TK_CHAR_TYPE;
3083 tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
3084 tok->u.prop.not = 1;
3085 break;
3086 case 'h':
3087 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
3088 tok->type = TK_CHAR_TYPE;
3089 tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
3090 tok->u.prop.not = 0;
3091 break;
3092 case 'H':
3093 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
3094 tok->type = TK_CHAR_TYPE;
3095 tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
3096 tok->u.prop.not = 1;
3097 break;
3098
3099 case 'p':
3100 case 'P':
3101 c2 = PPEEK;
3102 if (c2 == '{' &&
3103 IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
3104 PINC;
3105 tok->type = TK_CHAR_PROPERTY;
3106 tok->u.prop.not = (c == 'P' ? 1 : 0);
3107
3108 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
3109 PFETCH(c2);
3110 if (c2 == '^') {
3111 tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
3112 }
3113 else
3114 PUNFETCH;
3115 }
3116 }
3117 else {
3118 onig_syntax_warn(env, "invalid Unicode Property \\%c", c);
3119 }
3120 break;
3121
3122 case 'x':
3123 if (PEND) break;
3124
3125 prev = p;
3126 if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
3127 PINC;
3128 num = scan_unsigned_hexadecimal_number(&p, end, 0, 8, enc);
3129 if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
3130 if (!PEND) {
3131 c2 = PPEEK;
3132 if (ONIGENC_IS_CODE_XDIGIT(enc, c2))
3133 return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
3134 }
3135
3136 if (p > prev + enclen(enc, prev, end) && !PEND && (PPEEK_IS('}'))) {
3137 PINC;
3138 tok->type = TK_CODE_POINT;
3139 tok->base = 16;
3140 tok->u.code = (OnigCodePoint )num;
3141 }
3142 else {
3143 /* can't read nothing or invalid format */
3144 p = prev;
3145 }
3146 }
3147 else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
3148 num = scan_unsigned_hexadecimal_number(&p, end, 0, 2, enc);
3149 if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3150 if (p == prev) { /* can't read nothing. */
3151 num = 0; /* but, it's not error */
3152 }
3153 tok->type = TK_RAW_BYTE;
3154 tok->base = 16;
3155 tok->u.c = num;
3156 }
3157 break;
3158
3159 case 'u':
3160 if (PEND) break;
3161
3162 prev = p;
3163 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
3164 num = scan_unsigned_hexadecimal_number(&p, end, 4, 4, enc);
3165 if (num < -1) return ONIGERR_TOO_SHORT_DIGITS;
3166 else if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3167 if (p == prev) { /* can't read nothing. */
3168 num = 0; /* but, it's not error */
3169 }
3170 tok->type = TK_CODE_POINT;
3171 tok->base = 16;
3172 tok->u.code = (OnigCodePoint )num;
3173 }
3174 break;
3175
3176 case '0':
3177 case '1': case '2': case '3': case '4': case '5': case '6': case '7':
3178 if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
3179 PUNFETCH;
3180 prev = p;
3181 num = scan_unsigned_octal_number(&p, end, 3, enc);
3182 if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3183 if (p == prev) { /* can't read nothing. */
3184 num = 0; /* but, it's not error */
3185 }
3186 tok->type = TK_RAW_BYTE;
3187 tok->base = 8;
3188 tok->u.c = num;
3189 }
3190 break;
3191
3192 default:
3193 PUNFETCH;
3194 num = fetch_escaped_value(&p, end, env);
3195 if (num < 0) return num;
3196 if (tok->u.c != num) {
3197 tok->u.code = (OnigCodePoint )num;
3198 tok->type = TK_CODE_POINT;
3199 }
3200 break;
3201 }
3202 }
3203 else if (c == '[') {
3204 if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_POSIX_BRACKET) && (PPEEK_IS(':'))) {
3205 OnigCodePoint send[] = { (OnigCodePoint )':', (OnigCodePoint )']' };
3206 tok->backp = p; /* point at '[' is read */
3207 PINC;
3208 if (str_exist_check_with_esc(send, 2, p, end,
3209 (OnigCodePoint )']', enc, syn)) {
3210 tok->type = TK_POSIX_BRACKET_OPEN;
3211 }
3212 else {
3213 PUNFETCH;
3214 goto cc_in_cc;
3215 }
3216 }
3217 else {
3218 cc_in_cc:
3219 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP)) {
3220 tok->type = TK_CC_CC_OPEN;
3221 }
3222 else {
3223 CC_ESC_WARN(env, (UChar* )"[");
3224 }
3225 }
3226 }
3227 else if (c == '&') {
3228 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP) &&
3229 !PEND && (PPEEK_IS('&'))) {
3230 PINC;
3231 tok->type = TK_CC_AND;
3232 }
3233 }
3234
3235 end:
3236 *src = p;
3237 return tok->type;
3238 }
3239
3240 #ifdef USE_NAMED_GROUP
3241 static int
3242 fetch_named_backref_token(OnigCodePoint c, OnigToken* tok, UChar** src,
3243 UChar* end, ScanEnv* env)
3244 {
3245 int r, num;
3246 const OnigSyntaxType* syn = env->syntax;
3247 UChar* prev;
3248 UChar* p = *src;
3249 UChar* name_end;
3250 int* backs;
3251 int back_num;
3252
3253 prev = p;
3254
3255 #ifdef USE_BACKREF_WITH_LEVEL
3256 name_end = NULL_UCHARP; /* no need. escape gcc warning. */
3257 r = fetch_name_with_level(c, &p, end, &name_end,
3258 env, &back_num, &tok->u.backref.level);
3259 if (r == 1) tok->u.backref.exist_level = 1;
3260 else tok->u.backref.exist_level = 0;
3261 #else
3262 r = fetch_name(&p, end, &name_end, env, &back_num, 1);
3263 #endif
3264 if (r < 0) return r;
3265
3266 if (back_num != 0) {
3267 if (back_num < 0) {
3268 back_num = BACKREF_REL_TO_ABS(back_num, env);
3269 if (back_num <= 0)
3270 return ONIGERR_INVALID_BACKREF;
3271 }
3272
3273 if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
3274 if (back_num > env->num_mem ||
3275 IS_NULL(SCANENV_MEM_NODES(env)[back_num]))
3276 return ONIGERR_INVALID_BACKREF;
3277 }
3278 tok->type = TK_BACKREF;
3279 tok->u.backref.by_name = 0;
3280 tok->u.backref.num = 1;
3281 tok->u.backref.ref1 = back_num;
3282 }
3283 else {
3284 num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs);
3285 if (num <= 0) {
3286 onig_scan_env_set_error_string(env,
3287 ONIGERR_UNDEFINED_NAME_REFERENCE, prev, name_end);
3288 return ONIGERR_UNDEFINED_NAME_REFERENCE;
3289 }
3290 if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
3291 int i;
3292 for (i = 0; i < num; i++) {
3293 if (backs[i] > env->num_mem ||
3294 IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
3295 return ONIGERR_INVALID_BACKREF;
3296 }
3297 }
3298
3299 tok->type = TK_BACKREF;
3300 tok->u.backref.by_name = 1;
3301 if (num == 1) {
3302 tok->u.backref.num = 1;
3303 tok->u.backref.ref1 = backs[0];
3304 }
3305 else {
3306 tok->u.backref.num = num;
3307 tok->u.backref.refs = backs;
3308 }
3309 }
3310 *src = p;
3311 return 0;
3312 }
3313 #endif
3314
3315 static int
3316 fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
3317 {
3318 int r, num;
3319 OnigCodePoint c;
3320 OnigEncoding enc = env->enc;
3321 const OnigSyntaxType* syn = env->syntax;
3322 UChar* prev;
3323 UChar* p = *src;
3324 PFETCH_READY;
3325
3326 start:
3327 if (PEND) {
3328 tok->type = TK_EOT;
3329 return tok->type;
3330 }
3331
3332 tok->type = TK_STRING;
3333 tok->base = 0;
3334 tok->backp = p;
3335
3336 PFETCH(c);
3337 if (IS_MC_ESC_CODE(c, syn)) {
3338 if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
3339
3340 tok->backp = p;
3341 PFETCH(c);
3342
3343 tok->u.c = c;
3344 tok->escaped = 1;
3345 switch (c) {
3346 case '*':
3347 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF)) break;
3348 tok->type = TK_OP_REPEAT;
3349 tok->u.repeat.lower = 0;
3350 tok->u.repeat.upper = REPEAT_INFINITE;
3351 goto greedy_check;
3352 break;
3353
3354 case '+':
3355 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_PLUS_ONE_INF)) break;
3356 tok->type = TK_OP_REPEAT;
3357 tok->u.repeat.lower = 1;
3358 tok->u.repeat.upper = REPEAT_INFINITE;
3359 goto greedy_check;
3360 break;
3361
3362 case '?':
3363 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_QMARK_ZERO_ONE)) break;
3364 tok->type = TK_OP_REPEAT;
3365 tok->u.repeat.lower = 0;
3366 tok->u.repeat.upper = 1;
3367 greedy_check:
3368 if (!PEND && PPEEK_IS('?') &&
3369 IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_NON_GREEDY)) {
3370 PFETCH(c);
3371 tok->u.repeat.greedy = 0;
3372 tok->u.repeat.possessive = 0;
3373 }
3374 else {
3375 possessive_check:
3376 if (!PEND && PPEEK_IS('+') &&
3377 ((IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT) &&
3378 tok->type != TK_INTERVAL) ||
3379 (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL) &&
3380 tok->type == TK_INTERVAL))) {
3381 PFETCH(c);
3382 tok->u.repeat.greedy = 1;
3383 tok->u.repeat.possessive = 1;
3384 }
3385 else {
3386 tok->u.repeat.greedy = 1;
3387 tok->u.repeat.possessive = 0;
3388 }
3389 }
3390 break;
3391
3392 case '{':
3393 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) break;
3394 r = fetch_range_quantifier(&p, end, tok, env);
3395 if (r < 0) return r; /* error */
3396 if (r == 0) goto greedy_check;
3397 else if (r == 2) { /* {n} */
3398 if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY))
3399 goto possessive_check;
3400
3401 goto greedy_check;
3402 }
3403 /* r == 1 : normal char */
3404 break;
3405
3406 case '|':
3407 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_VBAR_ALT)) break;
3408 tok->type = TK_ALT;
3409 break;
3410
3411 case '(':
3412 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break;
3413 tok->type = TK_SUBEXP_OPEN;
3414 break;
3415
3416 case ')':
3417 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break;
3418 tok->type = TK_SUBEXP_CLOSE;
3419 break;
3420
3421 case 'w':
3422 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
3423 tok->type = TK_CHAR_TYPE;
3424 tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
3425 tok->u.prop.not = 0;
3426 break;
3427
3428 case 'W':
3429 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
3430 tok->type = TK_CHAR_TYPE;
3431 tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
3432 tok->u.prop.not = 1;
3433 break;
3434
3435 case 'b':
3436 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
3437 tok->type = TK_ANCHOR;
3438 tok->u.anchor.subtype = ANCHOR_WORD_BOUND;
3439 tok->u.anchor.ascii_range = IS_ASCII_RANGE(env->option)
3440 && ! IS_WORD_BOUND_ALL_RANGE(env->option);
3441 break;
3442
3443 case 'B':
3444 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
3445 tok->type = TK_ANCHOR;
3446 tok->u.anchor.subtype = ANCHOR_NOT_WORD_BOUND;
3447 tok->u.anchor.ascii_range = IS_ASCII_RANGE(env->option)
3448 && ! IS_WORD_BOUND_ALL_RANGE(env->option);
3449 break;
3450
3451 #ifdef USE_WORD_BEGIN_END
3452 case '<':
3453 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
3454 tok->type = TK_ANCHOR;
3455 tok->u.anchor.subtype = ANCHOR_WORD_BEGIN;
3456 tok->u.anchor.ascii_range = IS_ASCII_RANGE(env->option);
3457 break;
3458
3459 case '>':
3460 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
3461 tok->type = TK_ANCHOR;
3462 tok->u.anchor.subtype = ANCHOR_WORD_END;
3463 tok->u.anchor.ascii_range = IS_ASCII_RANGE(env->option);
3464 break;
3465 #endif
3466
3467 case 's':
3468 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
3469 tok->type = TK_CHAR_TYPE;
3470 tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
3471 tok->u.prop.not = 0;
3472 break;
3473
3474 case 'S':
3475 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
3476 tok->type = TK_CHAR_TYPE;
3477 tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
3478 tok->u.prop.not = 1;
3479 break;
3480
3481 case 'd':
3482 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
3483 tok->type = TK_CHAR_TYPE;
3484 tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
3485 tok->u.prop.not = 0;
3486 break;
3487
3488 case 'D':
3489 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
3490 tok->type = TK_CHAR_TYPE;
3491 tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
3492 tok->u.prop.not = 1;
3493 break;
3494
3495 case 'h':
3496 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
3497 tok->type = TK_CHAR_TYPE;
3498 tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
3499 tok->u.prop.not = 0;
3500 break;
3501
3502 case 'H':
3503 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
3504 tok->type = TK_CHAR_TYPE;
3505 tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
3506 tok->u.prop.not = 1;
3507 break;
3508
3509 case 'A':
3510 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
3511 begin_buf:
3512 tok->type = TK_ANCHOR;
3513 tok->u.anchor.subtype = ANCHOR_BEGIN_BUF;
3514 break;
3515
3516 case 'Z':
3517 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
3518 tok->type = TK_ANCHOR;
3519 tok->u.anchor.subtype = ANCHOR_SEMI_END_BUF;
3520 break;
3521
3522 case 'z':
3523 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
3524 end_buf:
3525 tok->type = TK_ANCHOR;
3526 tok->u.anchor.subtype = ANCHOR_END_BUF;
3527 break;
3528
3529 case 'G':
3530 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR)) break;
3531 tok->type = TK_ANCHOR;
3532 tok->u.anchor.subtype = ANCHOR_BEGIN_POSITION;
3533 break;
3534
3535 case '`':
3536 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break;
3537 goto begin_buf;
3538 break;
3539
3540 case '\'':
3541 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break;
3542 goto end_buf;
3543 break;
3544
3545 case 'x':
3546 if (PEND) break;
3547
3548 prev = p;
3549 if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
3550 PINC;
3551 num = scan_unsigned_hexadecimal_number(&p, end, 0, 8, enc);
3552 if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
3553 if (!PEND) {
3554 if (ONIGENC_IS_CODE_XDIGIT(enc, PPEEK))
3555 return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
3556 }
3557
3558 if ((p > prev + enclen(enc, prev, end)) && !PEND && PPEEK_IS('}')) {
3559 PINC;
3560 tok->type = TK_CODE_POINT;
3561 tok->u.code = (OnigCodePoint )num;
3562 }
3563 else {
3564 /* can't read nothing or invalid format */
3565 p = prev;
3566 }
3567 }
3568 else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
3569 num = scan_unsigned_hexadecimal_number(&p, end, 0, 2, enc);
3570 if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3571 if (p == prev) { /* can't read nothing. */
3572 num = 0; /* but, it's not error */
3573 }
3574 tok->type = TK_RAW_BYTE;
3575 tok->base = 16;
3576 tok->u.c = num;
3577 }
3578 break;
3579
3580 case 'u':
3581 if (PEND) break;
3582
3583 prev = p;
3584 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
3585 num = scan_unsigned_hexadecimal_number(&p, end, 4, 4, enc);
3586 if (num < -1) return ONIGERR_TOO_SHORT_DIGITS;
3587 else if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3588 if (p == prev) { /* can't read nothing. */
3589 num = 0; /* but, it's not error */
3590 }
3591 tok->type = TK_CODE_POINT;
3592 tok->base = 16;
3593 tok->u.code = (OnigCodePoint )num;
3594 }
3595 break;
3596
3597 case '1': case '2': case '3': case '4':
3598 case '5': case '6': case '7': case '8': case '9':
3599 PUNFETCH;
3600 prev = p;
3601 num = onig_scan_unsigned_number(&p, end, enc);
3602 if (num < 0 || num > ONIG_MAX_BACKREF_NUM) {
3603 goto skip_backref;
3604 }
3605
3606 if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_DECIMAL_BACKREF) &&
3607 (num <= env->num_mem || num <= 9)) { /* This spec. from GNU regex */
3608 if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
3609 if (num > env->num_mem || IS_NULL(SCANENV_MEM_NODES(env)[num]))
3610 return ONIGERR_INVALID_BACKREF;
3611 }
3612
3613 tok->type = TK_BACKREF;
3614 tok->u.backref.num = 1;
3615 tok->u.backref.ref1 = num;
3616 tok->u.backref.by_name = 0;
3617 #ifdef USE_BACKREF_WITH_LEVEL
3618 tok->u.backref.exist_level = 0;
3619 #endif
3620 break;
3621 }
3622
3623 skip_backref:
3624 if (c == '8' || c == '9') {
3625 /* normal char */
3626 p = prev; PINC;
3627 break;
3628 }
3629
3630 p = prev;
3631 /* fall through */
3632 case '0':
3633 if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
3634 prev = p;
3635 num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc);
3636 if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3637 if (p == prev) { /* can't read nothing. */
3638 num = 0; /* but, it's not error */
3639 }
3640 tok->type = TK_RAW_BYTE;
3641 tok->base = 8;
3642 tok->u.c = num;
3643 }
3644 else if (c != '0') {
3645 PINC;
3646 }
3647 break;
3648
3649 #ifdef USE_NAMED_GROUP
3650 case 'k':
3651 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_K_NAMED_BACKREF)) {
3652 PFETCH(c);
3653 if (c == '<' || c == '\'') {
3654 r = fetch_named_backref_token(c, tok, &p, end, env);
3655 if (r < 0) return r;
3656 }
3657 else {
3658 PUNFETCH;
3659 onig_syntax_warn(env, "invalid back reference");
3660 }
3661 }
3662 break;
3663 #endif
3664
3665 #if defined(USE_SUBEXP_CALL) || defined(USE_NAMED_GROUP)
3666 case 'g':
3667 #ifdef USE_NAMED_GROUP
3668 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_BRACE_BACKREF)) {
3669 PFETCH(c);
3670 if (c == '{') {
3671 r = fetch_named_backref_token(c, tok, &p, end, env);
3672 if (r < 0) return r;
3673 }
3674 else
3675 PUNFETCH;
3676 }
3677 #endif
3678 #ifdef USE_SUBEXP_CALL
3679 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_SUBEXP_CALL)) {
3680 PFETCH(c);
3681 if (c == '<' || c == '\'') {
3682 int gnum = -1, rel = 0;
3683 UChar* name_end;
3684 OnigCodePoint cnext;
3685
3686 cnext = PPEEK;
3687 if (cnext == '0') {
3688 PINC;
3689 if (PPEEK_IS(get_name_end_code_point(c))) { /* \g<0>, \g'0' */
3690 PINC;
3691 name_end = p;
3692 gnum = 0;
3693 }
3694 }
3695 else if (cnext == '+') {
3696 PINC;
3697 rel = 1;
3698 }
3699 prev = p;
3700 if (gnum < 0) {
3701 r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &gnum, 1);
3702 if (r < 0) return r;
3703 }
3704
3705 tok->type = TK_CALL;
3706 tok->u.call.name = prev;
3707 tok->u.call.name_end = name_end;
3708 tok->u.call.gnum = gnum;
3709 tok->u.call.rel = rel;
3710 }
3711 else {
3712 onig_syntax_warn(env, "invalid subexp call");
3713 PUNFETCH;
3714 }
3715 }
3716 #endif
3717 break;
3718 #endif
3719
3720 case 'Q':
3721 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE)) {
3722 tok->type = TK_QUOTE_OPEN;
3723 }
3724 break;
3725
3726 case 'p':
3727 case 'P':
3728 if (PPEEK_IS('{') &&
3729 IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
3730 PINC;
3731 tok->type = TK_CHAR_PROPERTY;
3732 tok->u.prop.not = (c == 'P' ? 1 : 0);
3733
3734 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
3735 PFETCH(c);
3736 if (c == '^') {
3737 tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
3738 }
3739 else
3740 PUNFETCH;
3741 }
3742 }
3743 else {
3744 onig_syntax_warn(env, "invalid Unicode Property \\%c", c);
3745 }
3746 break;
3747
3748 case 'R':
3749 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK)) {
3750 tok->type = TK_LINEBREAK;
3751 }
3752 break;
3753
3754 case 'X':
3755 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER)) {
3756 tok->type = TK_EXTENDED_GRAPHEME_CLUSTER;
3757 }
3758 break;
3759
3760 case 'K':
3761 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP)) {
3762 tok->type = TK_KEEP;
3763 }
3764 break;
3765
3766 default:
3767 PUNFETCH;
3768 num = fetch_escaped_value(&p, end, env);
3769 if (num < 0) return num;
3770 /* set_raw: */
3771 if (tok->u.c != num) {
3772 tok->type = TK_CODE_POINT;
3773 tok->u.code = (OnigCodePoint )num;
3774 }
3775 else { /* string */
3776 p = tok->backp + enclen(enc, tok->backp, end);
3777 }
3778 break;
3779 }
3780 }
3781 else {
3782 tok->u.c = c;
3783 tok->escaped = 0;
3784
3785 #ifdef USE_VARIABLE_META_CHARS
3786 if ((c != ONIG_INEFFECTIVE_META_CHAR) &&
3787 IS_SYNTAX_OP(syn, ONIG_SYN_OP_VARIABLE_META_CHARACTERS)) {
3788 if (c == MC_ANYCHAR(syn))
3789 goto any_char;
3790 else if (c == MC_ANYTIME(syn))
3791 goto anytime;
3792 else if (c == MC_ZERO_OR_ONE_TIME(syn))
3793 goto zero_or_one_time;
3794 else if (c == MC_ONE_OR_MORE_TIME(syn))
3795 goto one_or_more_time;
3796 else if (c == MC_ANYCHAR_ANYTIME(syn)) {
3797 tok->type = TK_ANYCHAR_ANYTIME;
3798 goto out;
3799 }
3800 }
3801 #endif
3802
3803 switch (c) {
3804 case '.':
3805 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_DOT_ANYCHAR)) break;
3806 #ifdef USE_VARIABLE_META_CHARS
3807 any_char:
3808 #endif
3809 tok->type = TK_ANYCHAR;
3810 break;
3811
3812 case '*':
3813 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ASTERISK_ZERO_INF)) break;
3814 #ifdef USE_VARIABLE_META_CHARS
3815 anytime:
3816 #endif
3817 tok->type = TK_OP_REPEAT;
3818 tok->u.repeat.lower = 0;
3819 tok->u.repeat.upper = REPEAT_INFINITE;
3820 goto greedy_check;
3821 break;
3822
3823 case '+':
3824 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_PLUS_ONE_INF)) break;
3825 #ifdef USE_VARIABLE_META_CHARS
3826 one_or_more_time:
3827 #endif
3828 tok->type = TK_OP_REPEAT;
3829 tok->u.repeat.lower = 1;
3830 tok->u.repeat.upper = REPEAT_INFINITE;
3831 goto greedy_check;
3832 break;
3833
3834 case '?':
3835 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_ZERO_ONE)) break;
3836 #ifdef USE_VARIABLE_META_CHARS
3837 zero_or_one_time:
3838 #endif
3839 tok->type = TK_OP_REPEAT;
3840 tok->u.repeat.lower = 0;
3841 tok->u.repeat.upper = 1;
3842 goto greedy_check;
3843 break;
3844
3845 case '{':
3846 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACE_INTERVAL)) break;
3847 r = fetch_range_quantifier(&p, end, tok, env);
3848 if (r < 0) return r; /* error */
3849 if (r == 0) goto greedy_check;
3850 else if (r == 2) { /* {n} */
3851 if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY))
3852 goto possessive_check;
3853
3854 goto greedy_check;
3855 }
3856 /* r == 1 : normal char */
3857 break;
3858
3859 case '|':
3860 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_VBAR_ALT)) break;
3861 tok->type = TK_ALT;
3862 break;
3863
3864 case '(':
3865 if (PPEEK_IS('?') &&
3866 IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
3867 PINC;
3868 if (PPEEK_IS('#')) {
3869 PFETCH(c);
3870 while (1) {
3871 if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
3872 PFETCH(c);
3873 if (c == MC_ESC(syn)) {
3874 if (!PEND) PFETCH(c);
3875 }
3876 else {
3877 if (c == ')') break;
3878 }
3879 }
3880 goto start;
3881 }
3882 #ifdef USE_PERL_SUBEXP_CALL
3883 /* (?&name), (?n), (?R), (?0), (?+n), (?-n) */
3884 c = PPEEK;
3885 if ((c == '&' || c == 'R' || ONIGENC_IS_CODE_DIGIT(enc, c)) &&
3886 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_SUBEXP_CALL)) {
3887 /* (?&name), (?n), (?R), (?0) */
3888 int gnum;
3889 UChar *name;
3890 UChar *name_end;
3891
3892 if (c == 'R' || c == '0') {
3893 PINC; /* skip 'R' / '0' */
3894 if (!PPEEK_IS(')')) return ONIGERR_INVALID_GROUP_NAME;
3895 PINC; /* skip ')' */
3896 name_end = name = p;
3897 gnum = 0;
3898 }
3899 else {
3900 int numref = 1;
3901 if (c == '&') { /* (?&name) */
3902 PINC;
3903 numref = 0; /* don't allow number name */
3904 }
3905 name = p;
3906 r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &gnum, numref);
3907 if (r < 0) return r;
3908 }
3909
3910 tok->type = TK_CALL;
3911 tok->u.call.name = name;
3912 tok->u.call.name_end = name_end;
3913 tok->u.call.gnum = gnum;
3914 tok->u.call.rel = 0;
3915 break;
3916 }
3917 else if ((c == '-' || c == '+') &&
3918 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_SUBEXP_CALL)) {
3919 /* (?+n), (?-n) */
3920 int gnum;
3921 UChar *name;
3922 UChar *name_end;
3923 OnigCodePoint cnext;
3924 PFETCH_READY;
3925
3926 PINC; /* skip '-' / '+' */
3927 cnext = PPEEK;
3928 if (ONIGENC_IS_CODE_DIGIT(enc, cnext)) {
3929 if (c == '-') PUNFETCH;
3930 name = p;
3931 r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &gnum, 1);
3932 if (r < 0) return r;
3933
3934 tok->type = TK_CALL;
3935 tok->u.call.name = name;
3936 tok->u.call.name_end = name_end;
3937 tok->u.call.gnum = gnum;
3938 tok->u.call.rel = 1;
3939 break;
3940 }
3941 }
3942 #endif /* USE_PERL_SUBEXP_CALL */
3943 #ifdef USE_CAPITAL_P_NAMED_GROUP
3944 if (PPEEK_IS('P') &&
3945 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP)) {
3946 int gnum;
3947 UChar *name;
3948 UChar *name_end;
3949 PFETCH_READY;
3950
3951 PINC; /* skip 'P' */
3952 PFETCH(c);
3953 if (c == '=') { /* (?P=name): backref */
3954 r = fetch_named_backref_token((OnigCodePoint )'(', tok, &p, end, env);
3955 if (r < 0) return r;
3956 break;
3957 }
3958 else if (c == '>') { /* (?P>name): subexp call */
3959 name = p;
3960 r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &gnum, 0);
3961 if (r < 0) return r;
3962
3963 tok->type = TK_CALL;
3964 tok->u.call.name = name;
3965 tok->u.call.name_end = name_end;
3966 tok->u.call.gnum = gnum;
3967 tok->u.call.rel = 0;
3968 break;
3969 }
3970 PUNFETCH;
3971 }
3972 #endif /* USE_CAPITAL_P_NAMED_GROUP */
3973 PUNFETCH;
3974 }
3975
3976 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break;
3977 tok->type = TK_SUBEXP_OPEN;
3978 break;
3979
3980 case ')':
3981 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break;
3982 tok->type = TK_SUBEXP_CLOSE;
3983 break;
3984
3985 case '^':
3986 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
3987 tok->type = TK_ANCHOR;
3988 tok->u.anchor.subtype = (IS_SINGLELINE(env->option)
3989 ? ANCHOR_BEGIN_BUF : ANCHOR_BEGIN_LINE);
3990 break;
3991
3992 case '$':
3993 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
3994 tok->type = TK_ANCHOR;
3995 tok->u.anchor.subtype = (IS_SINGLELINE(env->option)
3996 ? ANCHOR_SEMI_END_BUF : ANCHOR_END_LINE);
3997 break;
3998
3999 case '[':
4000 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACKET_CC)) break;
4001 tok->type = TK_CC_OPEN;
4002 break;
4003
4004 case ']':
4005 if (*src > env->pattern) /* /].../ is allowed. */
4006 CLOSE_BRACKET_WITHOUT_ESC_WARN(env, (UChar* )"]");
4007 break;
4008
4009 case '#':
4010 if (IS_EXTEND(env->option)) {
4011 while (!PEND) {
4012 PFETCH(c);
4013 if (ONIGENC_IS_CODE_NEWLINE(enc, c))
4014 break;
4015 }
4016 goto start;
4017 break;
4018 }
4019 break;
4020
4021 case ' ': case '\t': case '\n': case '\r': case '\f':
4022 if (IS_EXTEND(env->option))
4023 goto start;
4024 break;
4025
4026 default:
4027 /* string */
4028 break;
4029 }
4030 }
4031
4032 #ifdef USE_VARIABLE_META_CHARS
4033 out:
4034 #endif
4035 *src = p;
4036 return tok->type;
4037 }
4038
4039 static int
4040 add_ctype_to_cc_by_range(CClassNode* cc, int ctype ARG_UNUSED, int not,
4041 ScanEnv* env,
4042 OnigCodePoint sb_out, const OnigCodePoint mbr[])
4043 {
4044 int i, r;
4045 OnigCodePoint j;
4046
4047 int n = ONIGENC_CODE_RANGE_NUM(mbr);
4048
4049 if (not == 0) {
4050 for (i = 0; i < n; i++) {
4051 for (j = ONIGENC_CODE_RANGE_FROM(mbr, i);
4052 j <= ONIGENC_CODE_RANGE_TO(mbr, i); j++) {
4053 if (j >= sb_out) {
4054 if (j > ONIGENC_CODE_RANGE_FROM(mbr, i)) {
4055 r = add_code_range_to_buf(&(cc->mbuf), env, j,
4056 ONIGENC_CODE_RANGE_TO(mbr, i));
4057 if (r != 0) return r;
4058 i++;
4059 }
4060
4061 goto sb_end;
4062 }
4063 BITSET_SET_BIT_CHKDUP(cc->bs, j);
4064 }
4065 }
4066
4067 sb_end:
4068 for ( ; i < n; i++) {
4069 r = add_code_range_to_buf(&(cc->mbuf), env,
4070 ONIGENC_CODE_RANGE_FROM(mbr, i),
4071 ONIGENC_CODE_RANGE_TO(mbr, i));
4072 if (r != 0) return r;
4073 }
4074 }
4075 else {
4076 OnigCodePoint prev = 0;
4077
4078 for (i = 0; i < n; i++) {
4079 for (j = prev;
4080 j < ONIGENC_CODE_RANGE_FROM(mbr, i); j++) {
4081 if (j >= sb_out) {
4082 goto sb_end2;
4083 }
4084 BITSET_SET_BIT_CHKDUP(cc->bs, j);
4085 }
4086 prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1;
4087 }
4088 for (j = prev; j < sb_out; j++) {
4089 BITSET_SET_BIT_CHKDUP(cc->bs, j);
4090 }
4091
4092 sb_end2:
4093 prev = sb_out;
4094
4095 for (i = 0; i < n; i++) {
4096 if (prev < ONIGENC_CODE_RANGE_FROM(mbr, i)) {
4097 r = add_code_range_to_buf(&(cc->mbuf), env, prev,
4098 ONIGENC_CODE_RANGE_FROM(mbr, i) - 1);
4099 if (r != 0) return r;
4100 }
4101 prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1;
4102 }
4103 if (prev < 0x7fffffff) {
4104 r = add_code_range_to_buf(&(cc->mbuf), env, prev, 0x7fffffff);
4105 if (r != 0) return r;
4106 }
4107 }
4108
4109 return 0;
4110 }
4111
4112 static int
4113 add_ctype_to_cc(CClassNode* cc, int ctype, int not, int char_prop, ScanEnv* env)
4114 {
4115 int maxcode, ascii_range;
4116 int c, r;
4117 const OnigCodePoint *ranges;
4118 OnigCodePoint sb_out;
4119 OnigEncoding enc = env->enc;
4120 OnigOptionType option = env->option;
4121
4122 ascii_range = IS_ASCII_RANGE(option) && (char_prop == 0);
4123
4124 r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sb_out, &ranges);
4125 if (r == 0) {
4126 if (ascii_range) {
4127 CClassNode ccwork;
4128 initialize_cclass(&ccwork);
4129 r = add_ctype_to_cc_by_range(&ccwork, ctype, not, env, sb_out,
4130 ranges);
4131 if (r == 0) {
4132 if (not) {
4133 r = add_code_range_to_buf0(&(ccwork.mbuf), env, 0x80, ONIG_LAST_CODE_POINT, FALSE);
4134 }
4135 else {
4136 CClassNode ccascii;
4137 initialize_cclass(&ccascii);
4138 if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
4139 add_code_range(&(ccascii.mbuf), env, 0x00, 0x7F);
4140 }
4141 else {
4142 bitset_set_range(env, ccascii.bs, 0x00, 0x7F);
4143 }
4144 r = and_cclass(&ccwork, &ccascii, env);
4145 if (IS_NOT_NULL(ccascii.mbuf)) bbuf_free(ccascii.mbuf);
4146 }
4147 if (r == 0) {
4148 r = or_cclass(cc, &ccwork, env);
4149 }
4150 if (IS_NOT_NULL(ccwork.mbuf)) bbuf_free(ccwork.mbuf);
4151 }
4152 }
4153 else {
4154 r = add_ctype_to_cc_by_range(cc, ctype, not, env, sb_out, ranges);
4155 }
4156 return r;
4157 }
4158 else if (r != ONIG_NO_SUPPORT_CONFIG) {
4159 return r;
4160 }
4161
4162 maxcode = ascii_range ? 0x80 : SINGLE_BYTE_SIZE;
4163 r = 0;
4164 switch (ctype) {
4165 case ONIGENC_CTYPE_ALPHA:
4166 case ONIGENC_CTYPE_BLANK:
4167 case ONIGENC_CTYPE_CNTRL:
4168 case ONIGENC_CTYPE_DIGIT:
4169 case ONIGENC_CTYPE_LOWER:
4170 case ONIGENC_CTYPE_PUNCT:
4171 case ONIGENC_CTYPE_SPACE:
4172 case ONIGENC_CTYPE_UPPER:
4173 case ONIGENC_CTYPE_XDIGIT:
4174 case ONIGENC_CTYPE_ASCII:
4175 case ONIGENC_CTYPE_ALNUM:
4176 if (not != 0) {
4177 for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
4178 if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
4179 BITSET_SET_BIT_CHKDUP(cc->bs, c);
4180 }
4181 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
4182 }
4183 else {
4184 for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
4185 if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
4186 BITSET_SET_BIT_CHKDUP(cc->bs, c);
4187 }
4188 }
4189 break;
4190
4191 case ONIGENC_CTYPE_GRAPH:
4192 case ONIGENC_CTYPE_PRINT:
4193 if (not != 0) {
4194 for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
4195 if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype)
4196 || c >= maxcode)
4197 BITSET_SET_BIT_CHKDUP(cc->bs, c);
4198 }
4199 if (ascii_range)
4200 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
4201 }
4202 else {
4203 for (c = 0; c < maxcode; c++) {
4204 if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
4205 BITSET_SET_BIT_CHKDUP(cc->bs, c);
4206 }
4207 if (! ascii_range)
4208 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
4209 }
4210 break;
4211
4212 case ONIGENC_CTYPE_WORD:
4213 if (not == 0) {
4214 for (c = 0; c < maxcode; c++) {
4215 if (ONIGENC_IS_CODE_WORD(enc, c)) BITSET_SET_BIT_CHKDUP(cc->bs, c);
4216 }
4217 if (! ascii_range)
4218 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
4219 }
4220 else {
4221 for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
4222 if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* check invalid code point */
4223 && (! ONIGENC_IS_CODE_WORD(enc, c) || c >= maxcode))
4224 BITSET_SET_BIT_CHKDUP(cc->bs, c);
4225 }
4226 if (ascii_range)
4227 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
4228 }
4229 break;
4230
4231 default:
4232 return ONIGERR_PARSER_BUG;
4233 break;
4234 }
4235
4236 return r;
4237 }
4238
4239 static int
4240 parse_posix_bracket(CClassNode* cc, UChar** src, UChar* end, ScanEnv* env)
4241 {
4242 #define POSIX_BRACKET_CHECK_LIMIT_LENGTH 20
4243 #define POSIX_BRACKET_NAME_MIN_LEN 4
4244
4245 static const PosixBracketEntryType PBS[] = {
4246 { (UChar* )"alnum", ONIGENC_CTYPE_ALNUM, 5 },
4247 { (UChar* )"alpha", ONIGENC_CTYPE_ALPHA, 5 },
4248 { (UChar* )"blank", ONIGENC_CTYPE_BLANK, 5 },
4249 { (UChar* )"cntrl", ONIGENC_CTYPE_CNTRL, 5 },
4250 { (UChar* )"digit", ONIGENC_CTYPE_DIGIT, 5 },
4251 { (UChar* )"graph", ONIGENC_CTYPE_GRAPH, 5 },
4252 { (UChar* )"lower", ONIGENC_CTYPE_LOWER, 5 },
4253 { (UChar* )"print", ONIGENC_CTYPE_PRINT, 5 },
4254 { (UChar* )"punct", ONIGENC_CTYPE_PUNCT, 5 },
4255 { (UChar* )"space", ONIGENC_CTYPE_SPACE, 5 },
4256 { (UChar* )"upper", ONIGENC_CTYPE_UPPER, 5 },
4257 { (UChar* )"xdigit", ONIGENC_CTYPE_XDIGIT, 6 },
4258 { (UChar* )"ascii", ONIGENC_CTYPE_ASCII, 5 },
4259 { (UChar* )"word", ONIGENC_CTYPE_WORD, 4 },
4260 { (UChar* )NULL, -1, 0 }
4261 };
4262
4263 const PosixBracketEntryType *pb;
4264 int not, i, r;
4265 OnigCodePoint c;
4266 OnigEncoding enc = env->enc;
4267 UChar *p = *src;
4268 PFETCH_READY;
4269
4270 if (PPEEK_IS('^')) {
4271 PINC;
4272 not = 1;
4273 }
4274 else
4275 not = 0;
4276
4277 if (onigenc_strlen(enc, p, end) < POSIX_BRACKET_NAME_MIN_LEN + 3)
4278 goto not_posix_bracket;
4279
4280 for (pb = PBS; IS_NOT_NULL(pb->name); pb++) {
4281 if (onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0) {
4282 p = (UChar* )onigenc_step(enc, p, end, pb->len);
4283 if (onigenc_with_ascii_strncmp(enc, p, end, (UChar* )":]", 2) != 0)
4284 return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
4285
4286 r = add_ctype_to_cc(cc, pb->ctype, not,
4287 IS_POSIX_BRACKET_ALL_RANGE(env->option),
4288 env);
4289 if (r != 0) return r;
4290
4291 PINC; PINC;
4292 *src = p;
4293 return 0;
4294 }
4295 }
4296
4297 not_posix_bracket:
4298 c = 0;
4299 i = 0;
4300 while (!PEND && ((c = PPEEK) != ':') && c != ']') {
4301 PINC;
4302 if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
4303 }
4304 if (c == ':' && ! PEND) {
4305 PINC;
4306 if (! PEND) {
4307 PFETCH(c);
4308 if (c == ']')
4309 return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
4310 }
4311 }
4312
4313 return 1; /* 1: is not POSIX bracket, but no error. */
4314 }
4315
4316 static int
4317 fetch_char_property_to_ctype(UChar** src, UChar* end, ScanEnv* env)
4318 {
4319 int r;
4320 OnigCodePoint c;
4321 OnigEncoding enc = env->enc;
4322 UChar *prev, *start, *p = *src;
4323 PFETCH_READY;
4324
4325 r = 0;
4326 start = prev = p;
4327
4328 while (!PEND) {
4329 prev = p;
4330 PFETCH(c);
4331 if (c == '}') {
4332 r = ONIGENC_PROPERTY_NAME_TO_CTYPE(enc, start, prev);
4333 if (r < 0) break;
4334
4335 *src = p;
4336 return r;
4337 }
4338 else if (c == '(' || c == ')' || c == '{' || c == '|') {
4339 r = ONIGERR_INVALID_CHAR_PROPERTY_NAME;
4340 break;
4341 }
4342 }
4343
4344 onig_scan_env_set_error_string(env, r, *src, prev);
4345 return r;
4346 }
4347
4348 static int
4349 parse_char_property(Node** np, OnigToken* tok, UChar** src, UChar* end,
4350 ScanEnv* env)
4351 {
4352 int r, ctype;
4353 CClassNode* cc;
4354
4355 ctype = fetch_char_property_to_ctype(src, end, env);
4356 if (ctype < 0) return ctype;
4357
4358 *np = node_new_cclass();
4359 CHECK_NULL_RETURN_MEMERR(*np);
4360 cc = NCCLASS(*np);
4361 r = add_ctype_to_cc(cc, ctype, 0, 1, env);
4362 if (r != 0) return r;
4363 if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);
4364
4365 return 0;
4366 }
4367
4368
4369 enum CCSTATE {
4370 CCS_VALUE,
4371 CCS_RANGE,
4372 CCS_COMPLETE,
4373 CCS_START
4374 };
4375
4376 enum CCVALTYPE {
4377 CCV_SB,
4378 CCV_CODE_POINT,
4379 CCV_CLASS
4380 };
4381
4382 static int
4383 next_state_class(CClassNode* cc, OnigCodePoint* vs, enum CCVALTYPE* type,
4384 enum CCSTATE* state, ScanEnv* env)
4385 {
4386 int r;
4387
4388 if (*state == CCS_RANGE)
4389 return ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE;
4390
4391 if (*state == CCS_VALUE && *type != CCV_CLASS) {
4392 if (*type == CCV_SB)
4393 BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*vs));
4394 else if (*type == CCV_CODE_POINT) {
4395 r = add_code_range(&(cc->mbuf), env, *vs, *vs);
4396 if (r < 0) return r;
4397 }
4398 }
4399
4400 *state = CCS_VALUE;
4401 *type = CCV_CLASS;
4402 return 0;
4403 }
4404
4405 static int
4406 next_state_val(CClassNode* cc, OnigCodePoint *vs, OnigCodePoint v,
4407 int* vs_israw, int v_israw,
4408 enum CCVALTYPE intype, enum CCVALTYPE* type,
4409 enum CCSTATE* state, ScanEnv* env)
4410 {
4411 int r;
4412
4413 switch (*state) {
4414 case CCS_VALUE:
4415 if (*type == CCV_SB)
4416 BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*vs));
4417 else if (*type == CCV_CODE_POINT) {
4418 r = add_code_range(&(cc->mbuf), env, *vs, *vs);
4419 if (r < 0) return r;
4420 }
4421 break;
4422
4423 case CCS_RANGE:
4424 if (intype == *type) {
4425 if (intype == CCV_SB) {
4426 if (*vs > 0xff || v > 0xff)
4427 return ONIGERR_INVALID_CODE_POINT_VALUE;
4428
4429 if (*vs > v) {
4430 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
4431 goto ccs_range_end;
4432 else
4433 return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
4434 }
4435 bitset_set_range(env, cc->bs, (int )*vs, (int )v);
4436 }
4437 else {
4438 r = add_code_range(&(cc->mbuf), env, *vs, v);
4439 if (r < 0) return r;
4440 }
4441 }
4442 else {
4443 #if 0
4444 if (intype == CCV_CODE_POINT && *type == CCV_SB) {
4445 #endif
4446 if (*vs > v) {
4447 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
4448 goto ccs_range_end;
4449 else
4450 return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
4451 }
4452 bitset_set_range(env, cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff));
4453 r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*vs, v);
4454 if (r < 0) return r;
4455 #if 0
4456 }
4457 else
4458 return ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE;
4459 #endif
4460 }
4461 ccs_range_end:
4462 *state = CCS_COMPLETE;
4463 break;
4464
4465 case CCS_COMPLETE:
4466 case CCS_START:
4467 *state = CCS_VALUE;
4468 break;
4469
4470 default:
4471 break;
4472 }
4473
4474 *vs_israw = v_israw;
4475 *vs = v;
4476 *type = intype;
4477 return 0;
4478 }
4479
4480 static int
4481 code_exist_check(OnigCodePoint c, UChar* from, UChar* end, int ignore_escaped,
4482 ScanEnv* env)
4483 {
4484 int in_esc;
4485 OnigCodePoint code;
4486 OnigEncoding enc = env->enc;
4487 UChar* p = from;
4488 PFETCH_READY;
4489
4490 in_esc = 0;
4491 while (! PEND) {
4492 if (ignore_escaped && in_esc) {
4493 in_esc = 0;
4494 }
4495 else {
4496 PFETCH(code);
4497 if (code == c) return 1;
4498 if (code == MC_ESC(env->syntax)) in_esc = 1;
4499 }
4500 }
4501 return 0;
4502 }
4503
4504 static int
4505 parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
4506 ScanEnv* env)
4507 {
4508 int r, neg, len, fetched, and_start;
4509 OnigCodePoint v, vs;
4510 UChar *p;
4511 Node* node;
4512 CClassNode *cc, *prev_cc;
4513 CClassNode work_cc;
4514
4515 enum CCSTATE state;
4516 enum CCVALTYPE val_type, in_type;
4517 int val_israw, in_israw;
4518
4519 prev_cc = (CClassNode* )NULL;
4520 *np = NULL_NODE;
4521 r = fetch_token_in_cc(tok, src, end, env);
4522 if (r == TK_CHAR && tok->u.c == '^' && tok->escaped == 0) {
4523 neg = 1;
4524 r = fetch_token_in_cc(tok, src, end, env);
4525 }
4526 else {
4527 neg = 0;
4528 }
4529
4530 if (r < 0) return r;
4531 if (r == TK_CC_CLOSE) {
4532 if (! code_exist_check((OnigCodePoint )']',
4533 *src, env->pattern_end, 1, env))
4534 return ONIGERR_EMPTY_CHAR_CLASS;
4535
4536 CC_ESC_WARN(env, (UChar* )"]");
4537 r = tok->type = TK_CHAR; /* allow []...] */
4538 }
4539
4540 *np = node = node_new_cclass();
4541 CHECK_NULL_RETURN_MEMERR(node);
4542 cc = NCCLASS(node);
4543
4544 and_start = 0;
4545 state = CCS_START;
4546 p = *src;
4547 while (r != TK_CC_CLOSE) {
4548 fetched = 0;
4549 switch (r) {
4550 case TK_CHAR:
4551 if ((tok->u.code >= SINGLE_BYTE_SIZE) ||
4552 (len = ONIGENC_CODE_TO_MBCLEN(env->enc, tok->u.c)) > 1) {
4553 in_type = CCV_CODE_POINT;
4554 }
4555 else if (len < 0) {
4556 r = len;
4557 goto err;
4558 }
4559 else {
4560 sb_char:
4561 in_type = CCV_SB;
4562 }
4563 v = (OnigCodePoint )tok->u.c;
4564 in_israw = 0;
4565 goto val_entry2;
4566 break;
4567
4568 case TK_RAW_BYTE:
4569 /* tok->base != 0 : octal or hexadec. */
4570 if (! ONIGENC_IS_SINGLEBYTE(env->enc) && tok->base != 0) {
4571 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
4572 UChar* bufe = buf + ONIGENC_CODE_TO_MBC_MAXLEN;
4573 UChar* psave = p;
4574 int i, base = tok->base;
4575
4576 buf[0] = (UChar )tok->u.c;
4577 for (i = 1; i < ONIGENC_MBC_MAXLEN(env->enc); i++) {
4578 r = fetch_token_in_cc(tok, &p, end, env);
4579 if (r < 0) goto err;
4580 if (r != TK_RAW_BYTE || tok->base != base) {
4581 fetched = 1;
4582 break;
4583 }
4584 buf[i] = (UChar )tok->u.c;
4585 }
4586
4587 if (i < ONIGENC_MBC_MINLEN(env->enc)) {
4588 r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
4589 goto err;
4590 }
4591
4592 len = enclen(env->enc, buf, buf+i);
4593 if (i < len) {
4594 r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
4595 goto err;
4596 }
4597 else if (i > len) { /* fetch back */
4598 p = psave;
4599 for (i = 1; i < len; i++) {
4600 r = fetch_token_in_cc(tok, &p, end, env);
4601 }
4602 fetched = 0;
4603 }
4604
4605 if (i == 1) {
4606 v = (OnigCodePoint )buf[0];
4607 goto raw_single;
4608 }
4609 else {
4610 v = ONIGENC_MBC_TO_CODE(env->enc, buf, bufe);
4611 in_type = CCV_CODE_POINT;
4612 }
4613 }
4614 else {
4615 v = (OnigCodePoint )tok->u.c;
4616 raw_single:
4617 in_type = CCV_SB;
4618 }
4619 in_israw = 1;
4620 goto val_entry2;
4621 break;
4622
4623 case TK_CODE_POINT:
4624 v = tok->u.code;
4625 in_israw = 1;
4626 val_entry:
4627 len = ONIGENC_CODE_TO_MBCLEN(env->enc, v);
4628 if (len < 0) {
4629 r = len;
4630 goto err;
4631 }
4632 in_type = (len == 1 ? CCV_SB : CCV_CODE_POINT);
4633 val_entry2:
4634 r = next_state_val(cc, &vs, v, &val_israw, in_israw, in_type, &val_type,
4635 &state, env);
4636 if (r != 0) goto err;
4637 break;
4638
4639 case TK_POSIX_BRACKET_OPEN:
4640 r = parse_posix_bracket(cc, &p, end, env);
4641 if (r < 0) goto err;
4642 if (r == 1) { /* is not POSIX bracket */
4643 CC_ESC_WARN(env, (UChar* )"[");
4644 p = tok->backp;
4645 v = (OnigCodePoint )tok->u.c;
4646 in_israw = 0;
4647 goto val_entry;
4648 }
4649 goto next_class;
4650 break;
4651
4652 case TK_CHAR_TYPE:
4653 r = add_ctype_to_cc(cc, tok->u.prop.ctype, tok->u.prop.not, 0, env);
4654 if (r != 0) return r;
4655
4656 next_class:
4657 r = next_state_class(cc, &vs, &val_type, &state, env);
4658 if (r != 0) goto err;
4659 break;
4660
4661 case TK_CHAR_PROPERTY:
4662 {
4663 int ctype;
4664
4665 ctype = fetch_char_property_to_ctype(&p, end, env);
4666 if (ctype < 0) return ctype;
4667 r = add_ctype_to_cc(cc, ctype, tok->u.prop.not, 1, env);
4668 if (r != 0) return r;
4669 goto next_class;
4670 }
4671 break;
4672
4673 case TK_CC_RANGE:
4674 if (state == CCS_VALUE) {
4675 r = fetch_token_in_cc(tok, &p, end, env);
4676 if (r < 0) goto err;
4677 fetched = 1;
4678 if (r == TK_CC_CLOSE) { /* allow [x-] */
4679 range_end_val:
4680 v = (OnigCodePoint )'-';
4681 in_israw = 0;
4682 goto val_entry;
4683 }
4684 else if (r == TK_CC_AND) {
4685 CC_ESC_WARN(env, (UChar* )"-");
4686 goto range_end_val;
4687 }
4688 state = CCS_RANGE;
4689 }
4690 else if (state == CCS_START) {
4691 /* [-xa] is allowed */
4692 v = (OnigCodePoint )tok->u.c;
4693 in_israw = 0;
4694
4695 r = fetch_token_in_cc(tok, &p, end, env);
4696 if (r < 0) goto err;
4697 fetched = 1;
4698 /* [--x] or [a&&-x] is warned. */
4699 if (r == TK_CC_RANGE || and_start != 0)
4700 CC_ESC_WARN(env, (UChar* )"-");
4701
4702 goto val_entry;
4703 }
4704 else if (state == CCS_RANGE) {
4705 CC_ESC_WARN(env, (UChar* )"-");
4706 goto sb_char; /* [!--x] is allowed */
4707 }
4708 else { /* CCS_COMPLETE */
4709 r = fetch_token_in_cc(tok, &p, end, env);
4710 if (r < 0) goto err;
4711 fetched = 1;
4712 if (r == TK_CC_CLOSE) goto range_end_val; /* allow [a-b-] */
4713 else if (r == TK_CC_AND) {
4714 CC_ESC_WARN(env, (UChar* )"-");
4715 goto range_end_val;
4716 }
4717
4718 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC)) {
4719 CC_ESC_WARN(env, (UChar* )"-");
4720 goto range_end_val; /* [0-9-a] is allowed as [0-9\-a] */
4721 }
4722 r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS;
4723 goto err;
4724 }
4725 break;
4726
4727 case TK_CC_CC_OPEN: /* [ */
4728 {
4729 Node *anode;
4730 CClassNode* acc;
4731
4732 r = parse_char_class(&anode, tok, &p, end, env);
4733 if (r == 0) {
4734 acc = NCCLASS(anode);
4735 r = or_cclass(cc, acc, env);
4736 }
4737 onig_node_free(anode);
4738 if (r != 0) goto err;
4739 }
4740 break;
4741
4742 case TK_CC_AND: /* && */
4743 {
4744 if (state == CCS_VALUE) {
4745 r = next_state_val(cc, &vs, 0, &val_israw, 0, val_type,
4746 &val_type, &state, env);
4747 if (r != 0) goto err;
4748 }
4749 /* initialize local variables */
4750 and_start = 1;
4751 state = CCS_START;
4752
4753 if (IS_NOT_NULL(prev_cc)) {
4754 r = and_cclass(prev_cc, cc, env);
4755 if (r != 0) goto err;
4756 bbuf_free(cc->mbuf);
4757 }
4758 else {
4759 prev_cc = cc;
4760 cc = &work_cc;
4761 }
4762 initialize_cclass(cc);
4763 }
4764 break;
4765
4766 case TK_EOT:
4767 r = ONIGERR_PREMATURE_END_OF_CHAR_CLASS;
4768 goto err;
4769 break;
4770 default:
4771 r = ONIGERR_PARSER_BUG;
4772 goto err;
4773 break;
4774 }
4775
4776 if (fetched)
4777 r = tok->type;
4778 else {
4779 r = fetch_token_in_cc(tok, &p, end, env);
4780 if (r < 0) goto err;
4781 }
4782 }
4783
4784 if (state == CCS_VALUE) {
4785 r = next_state_val(cc, &vs, 0, &val_israw, 0, val_type,
4786 &val_type, &state, env);
4787 if (r != 0) goto err;
4788 }
4789
4790 if (IS_NOT_NULL(prev_cc)) {
4791 r = and_cclass(prev_cc, cc, env);
4792 if (r != 0) goto err;
4793 bbuf_free(cc->mbuf);
4794 cc = prev_cc;
4795 }
4796
4797 if (neg != 0)
4798 NCCLASS_SET_NOT(cc);
4799 else
4800 NCCLASS_CLEAR_NOT(cc);
4801 if (IS_NCCLASS_NOT(cc) &&
4802 IS_SYNTAX_BV(env->syntax, ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC)) {
4803 int is_empty;
4804
4805 is_empty = (IS_NULL(cc->mbuf) ? 1 : 0);
4806 if (is_empty != 0)
4807 BITSET_IS_EMPTY(cc->bs, is_empty);
4808
4809 if (is_empty == 0) {
4810 #define NEWLINE_CODE 0x0a
4811
4812 if (ONIGENC_IS_CODE_NEWLINE(env->enc, NEWLINE_CODE)) {
4813 if (ONIGENC_CODE_TO_MBCLEN(env->enc, NEWLINE_CODE) == 1)
4814 BITSET_SET_BIT_CHKDUP(cc->bs, NEWLINE_CODE);
4815 else {
4816 r = add_code_range(&(cc->mbuf), env, NEWLINE_CODE, NEWLINE_CODE);
4817 if (r < 0) goto err;
4818 }
4819 }
4820 }
4821 }
4822 *src = p;
4823 return 0;
4824
4825 err:
4826 if (cc != NCCLASS(*np))
4827 bbuf_free(cc->mbuf);
4828 return r;
4829 }
4830
4831 static int parse_subexp(Node** top, OnigToken* tok, int term,
4832 UChar** src, UChar* end, ScanEnv* env);
4833
4834 static int
4835 parse_enclose(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
4836 ScanEnv* env)
4837 {
4838 int r = 0, num;
4839 Node *target, *work1 = NULL, *work2 = NULL;
4840 OnigOptionType option;
4841 OnigCodePoint c;
4842 OnigEncoding enc = env->enc;
4843
4844 #ifdef USE_NAMED_GROUP
4845 int list_capture;
4846 #endif
4847
4848 UChar* p = *src;
4849 PFETCH_READY;
4850
4851 *np = NULL;
4852 if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
4853
4854 option = env->option;
4855 if (PPEEK_IS('?') &&
4856 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
4857 PINC;
4858 if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
4859
4860 PFETCH(c);
4861 switch (c) {
4862 case ':': /* (?:...) grouping only */
4863 group:
4864 r = fetch_token(tok, &p, end, env);
4865 if (r < 0) return r;
4866 r = parse_subexp(np, tok, term, &p, end, env);
4867 if (r < 0) return r;
4868 *src = p;
4869 return 1; /* group */
4870 break;
4871
4872 case '=':
4873 *np = onig_node_new_anchor(ANCHOR_PREC_READ);
4874 break;
4875 case '!': /* preceding read */
4876 *np = onig_node_new_anchor(ANCHOR_PREC_READ_NOT);
4877 break;
4878 case '>': /* (?>...) stop backtrack */
4879 *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
4880 break;
4881
4882 #ifdef USE_NAMED_GROUP
4883 case '\'':
4884 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
4885 goto named_group1;
4886 }
4887 else
4888 return ONIGERR_UNDEFINED_GROUP_OPTION;
4889 break;
4890
4891 #ifdef USE_CAPITAL_P_NAMED_GROUP
4892 case 'P': /* (?P<name>...) */
4893 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP)) {
4894 PFETCH(c);
4895 if (c == '<') goto named_group1;
4896 }
4897 return ONIGERR_UNDEFINED_GROUP_OPTION;
4898 break;
4899 #endif
4900 #endif
4901
4902 case '<': /* look behind (?<=...), (?<!...) */
4903 PFETCH(c);
4904 if (c == '=')
4905 *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND);
4906 else if (c == '!')
4907 *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND_NOT);
4908 #ifdef USE_NAMED_GROUP
4909 else { /* (?<name>...) */
4910 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
4911 UChar *name;
4912 UChar *name_end;
4913
4914 PUNFETCH;
4915 c = '<';
4916
4917 named_group1:
4918 list_capture = 0;
4919
4920 named_group2:
4921 name = p;
4922 r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0);
4923 if (r < 0) return r;
4924
4925 num = scan_env_add_mem_entry(env);
4926 if (num < 0) return num;
4927 if (list_capture != 0 && num >= (int )BIT_STATUS_BITS_NUM)
4928 return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
4929
4930 r = name_add(env->reg, name, name_end, num, env);
4931 if (r != 0) return r;
4932 *np = node_new_enclose_memory(env->option, 1);
4933 CHECK_NULL_RETURN_MEMERR(*np);
4934 NENCLOSE(*np)->regnum = num;
4935 if (list_capture != 0)
4936 BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
4937 env->num_named++;
4938 }
4939 else {
4940 return ONIGERR_UNDEFINED_GROUP_OPTION;
4941 }
4942 }
4943 #else
4944 else {
4945 return ONIGERR_UNDEFINED_GROUP_OPTION;
4946 }
4947 #endif
4948 break;
4949
4950 case '@':
4951 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY)) {
4952 #ifdef USE_NAMED_GROUP
4953 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
4954 PFETCH(c);
4955 if (c == '<' || c == '\'') {
4956 list_capture = 1;
4957 goto named_group2; /* (?@<name>...) */
4958 }
4959 PUNFETCH;
4960 }
4961 #endif
4962 *np = node_new_enclose_memory(env->option, 0);
4963 CHECK_NULL_RETURN_MEMERR(*np);
4964 num = scan_env_add_mem_entry(env);
4965 if (num < 0) {
4966 onig_node_free(*np);
4967 return num;
4968 }
4969 else if (num >= (int )BIT_STATUS_BITS_NUM) {
4970 onig_node_free(*np);
4971 return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
4972 }
4973 NENCLOSE(*np)->regnum = num;
4974 BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
4975 }
4976 else {
4977 return ONIGERR_UNDEFINED_GROUP_OPTION;
4978 }
4979 break;
4980
4981 case '(': /* conditional expression: (?(cond)yes), (?(cond)yes|no) */
4982 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LPAREN_CONDITION)) {
4983 UChar *name = NULL;
4984 UChar *name_end;
4985 PFETCH(c);
4986 if (ONIGENC_IS_CODE_DIGIT(enc, c)) { /* (n) */
4987 PUNFETCH;
4988 r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &num, 1);
4989 if (r < 0) return r;
4990 if (num < 0) {
4991 num = BACKREF_REL_TO_ABS(num, env);
4992 if (num <= 0)
4993 return ONIGERR_INVALID_BACKREF;
4994 }
4995 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_STRICT_CHECK_BACKREF)) {
4996 if (num > env->num_mem ||
4997 IS_NULL(SCANENV_MEM_NODES(env)[num]))
4998 return ONIGERR_INVALID_BACKREF;
4999 }
5000 }
5001 #ifdef USE_NAMED_GROUP
5002 else if (c == '<' || c == '\'') { /* (<name>), ('name') */
5003 int nums;
5004 int *backs;
5005
5006 name = p;
5007 r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0);
5008 if (r < 0) return r;
5009 PFETCH(c);
5010 if (c != ')') return ONIGERR_UNDEFINED_GROUP_OPTION;
5011
5012 nums = onig_name_to_group_numbers(env->reg, name, name_end, &backs);
5013 if (nums <= 0) {
5014 onig_scan_env_set_error_string(env,
5015 ONIGERR_UNDEFINED_NAME_REFERENCE, name, name_end);
5016 return ONIGERR_UNDEFINED_NAME_REFERENCE;
5017 }
5018 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_STRICT_CHECK_BACKREF)) {
5019 int i;
5020 for (i = 0; i < nums; i++) {
5021 if (backs[i] > env->num_mem ||
5022 IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
5023 return ONIGERR_INVALID_BACKREF;
5024 }
5025 }
5026 num = backs[0]; /* XXX: use left most named group as Perl */
5027 }
5028 #endif
5029 else
5030 return ONIGERR_INVALID_CONDITION_PATTERN;
5031 *np = node_new_enclose(ENCLOSE_CONDITION);
5032 CHECK_NULL_RETURN_MEMERR(*np);
5033 NENCLOSE(*np)->regnum = num;
5034 if (IS_NOT_NULL(name)) NENCLOSE(*np)->state |= NST_NAME_REF;
5035 }
5036 else
5037 return ONIGERR_UNDEFINED_GROUP_OPTION;
5038 break;
5039
5040 #if 0
5041 case '|': /* branch reset: (?|...) */
5042 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET)) {
5043 /* TODO */
5044 }
5045 else
5046 return ONIGERR_UNDEFINED_GROUP_OPTION;
5047 break;
5048 #endif
5049
5050 case '^': /* loads default options */
5051 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
5052 /* d-imsx */
5053 ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
5054 ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
5055 ONOFF(option, ONIG_OPTION_SINGLELINE, 0);
5056 ONOFF(option, ONIG_OPTION_MULTILINE, 1);
5057 ONOFF(option, ONIG_OPTION_EXTEND, 1);
5058 PFETCH(c);
5059 }
5060 #if 0
5061 else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
5062 /* d-imx */
5063 ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
5064 ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 0);
5065 ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 0);
5066 ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
5067 ONOFF(option, ONIG_OPTION_MULTILINE, 1);
5068 ONOFF(option, ONIG_OPTION_EXTEND, 1);
5069 PFETCH(c);
5070 }
5071 #endif
5072 else {
5073 return ONIGERR_UNDEFINED_GROUP_OPTION;
5074 }
5075 /* fall through */
5076 #ifdef USE_POSIXLINE_OPTION
5077 case 'p':
5078 #endif
5079 case '-': case 'i': case 'm': case 's': case 'x':
5080 case 'a': case 'd': case 'l': case 'u':
5081 {
5082 int neg = 0;
5083
5084 while (1) {
5085 switch (c) {
5086 case ':':
5087 case ')':
5088 break;
5089
5090 case '-': neg = 1; break;
5091 case 'x': ONOFF(option, ONIG_OPTION_EXTEND, neg); break;
5092 case 'i': ONOFF(option, ONIG_OPTION_IGNORECASE, neg); break;
5093 case 's':
5094 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
5095 ONOFF(option, ONIG_OPTION_MULTILINE, neg);
5096 }
5097 else
5098 return ONIGERR_UNDEFINED_GROUP_OPTION;
5099 break;
5100
5101 case 'm':
5102 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
5103 ONOFF(option, ONIG_OPTION_SINGLELINE, (neg == 0 ? 1 : 0));
5104 }
5105 else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
5106 ONOFF(option, ONIG_OPTION_MULTILINE, neg);
5107 }
5108 else
5109 return ONIGERR_UNDEFINED_GROUP_OPTION;
5110 break;
5111 #ifdef USE_POSIXLINE_OPTION
5112 case 'p':
5113 ONOFF(option, ONIG_OPTION_MULTILINE|ONIG_OPTION_SINGLELINE, neg);
5114 break;
5115 #endif
5116
5117 case 'a': /* limits \d, \s, \w and POSIX brackets to ASCII range */
5118 if ((IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) ||
5119 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
5120 (neg == 0)) {
5121 ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
5122 ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 1);
5123 ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 1);
5124 }
5125 else
5126 return ONIGERR_UNDEFINED_GROUP_OPTION;
5127 break;
5128
5129 case 'u':
5130 if ((IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) ||
5131 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
5132 (neg == 0)) {
5133 ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
5134 ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 1);
5135 ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 1);
5136 }
5137 else
5138 return ONIGERR_UNDEFINED_GROUP_OPTION;
5139 break;
5140
5141 case 'd':
5142 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) &&
5143 (neg == 0)) {
5144 ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
5145 }
5146 else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY) &&
5147 (neg == 0)) {
5148 ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
5149 ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 0);
5150 ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 0);
5151 }
5152 else
5153 return ONIGERR_UNDEFINED_GROUP_OPTION;
5154 break;
5155
5156 case 'l':
5157 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) && (neg == 0)) {
5158 ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
5159 }
5160 else
5161 return ONIGERR_UNDEFINED_GROUP_OPTION;
5162 break;
5163
5164 default:
5165 return ONIGERR_UNDEFINED_GROUP_OPTION;
5166 }
5167
5168 if (c == ')') {
5169 *np = node_new_option(option);
5170 CHECK_NULL_RETURN_MEMERR(*np);
5171 *src = p;
5172 return 2; /* option only */
5173 }
5174 else if (c == ':') {
5175 OnigOptionType prev = env->option;
5176
5177 env->option = option;
5178 r = fetch_token(tok, &p, end, env);
5179 if (r < 0) return r;
5180 r = parse_subexp(&target, tok, term, &p, end, env);
5181 env->option = prev;
5182 if (r < 0) return r;
5183 *np = node_new_option(option);
5184 CHECK_NULL_RETURN_MEMERR(*np);
5185 NENCLOSE(*np)->target = target;
5186 *src = p;
5187 return 0;
5188 }
5189
5190 if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
5191 PFETCH(c);
5192 }
5193 }
5194 break;
5195
5196 default:
5197 return ONIGERR_UNDEFINED_GROUP_OPTION;
5198 }
5199 }
5200 else {
5201 if (ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_DONT_CAPTURE_GROUP))
5202 goto group;
5203
5204 *np = node_new_enclose_memory(env->option, 0);
5205 CHECK_NULL_RETURN_MEMERR(*np);
5206 num = scan_env_add_mem_entry(env);
5207 if (num < 0) return num;
5208 NENCLOSE(*np)->regnum = num;
5209 }
5210
5211 CHECK_NULL_RETURN_MEMERR(*np);
5212 r = fetch_token(tok, &p, end, env);
5213 if (r < 0) return r;
5214 r = parse_subexp(&target, tok, term, &p, end, env);
5215 if (r < 0) {
5216 onig_node_free(target);
5217 return r;
5218 }
5219
5220 if (NTYPE(*np) == NT_ANCHOR)
5221 NANCHOR(*np)->target = target;
5222 else {
5223 NENCLOSE(*np)->target = target;
5224 if (NENCLOSE(*np)->type == ENCLOSE_MEMORY) {
5225 /* Don't move this to previous of parse_subexp() */
5226 r = scan_env_set_mem_node(env, NENCLOSE(*np)->regnum, *np);
5227 if (r != 0) return r;
5228 }
5229 else if (NENCLOSE(*np)->type == ENCLOSE_CONDITION) {
5230 if (NTYPE(target) != NT_ALT) {
5231 /* convert (?(cond)yes) to (?(cond)yes|empty) */
5232 work1 = node_new_empty();
5233 if (IS_NULL(work1)) goto err;
5234 work2 = onig_node_new_alt(work1, NULL_NODE);
5235 if (IS_NULL(work2)) goto err;
5236 work1 = onig_node_new_alt(target, work2);
5237 if (IS_NULL(work1)) goto err;
5238 NENCLOSE(*np)->target = work1;
5239 }
5240 }
5241 }
5242
5243 *src = p;
5244 return 0;
5245
5246 err:
5247 onig_node_free(work1);
5248 onig_node_free(work2);
5249 onig_node_free(*np);
5250 *np = NULL;
5251 return ONIGERR_MEMORY;
5252 }
5253
5254 static const char* const PopularQStr[] = {
5255 "?", "*", "+", "??", "*?", "+?"
5256 };
5257
5258 static const char* const ReduceQStr[] = {
5259 "", "", "*", "*?", "??", "+ and ??", "+? and ?"
5260 };
5261
5262 static int
5263 set_quantifier(Node* qnode, Node* target, int group, ScanEnv* env)
5264 {
5265 QtfrNode* qn;
5266
5267 qn = NQTFR(qnode);
5268 if (qn->lower == 1 && qn->upper == 1) {
5269 return 1;
5270 }
5271
5272 switch (NTYPE(target)) {
5273 case NT_STR:
5274 if (! group) {
5275 StrNode* sn = NSTR(target);
5276 if (str_node_can_be_split(sn, env->enc)) {
5277 Node* n = str_node_split_last_char(sn, env->enc);
5278 if (IS_NOT_NULL(n)) {
5279 qn->target = n;
5280 return 2;
5281 }
5282 }
5283 }
5284 break;
5285
5286 case NT_QTFR:
5287 { /* check redundant double repeat. */
5288 /* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
5289 QtfrNode* qnt = NQTFR(target);
5290 int nestq_num = popular_quantifier_num(qn);
5291 int targetq_num = popular_quantifier_num(qnt);
5292
5293 #ifdef USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
5294 if (!IS_QUANTIFIER_BY_NUMBER(qn) && !IS_QUANTIFIER_BY_NUMBER(qnt) &&
5295 IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT)) {
5296 switch (ReduceTypeTable[targetq_num][nestq_num]) {
5297 case RQ_ASIS:
5298 break;
5299
5300 case RQ_DEL:
5301 if (onig_warn != onig_null_warn) {
5302 onig_syntax_warn(env, "regular expression has redundant nested repeat operator '%s'",
5303 PopularQStr[targetq_num]);
5304 }
5305 goto warn_exit;
5306 break;
5307
5308 default:
5309 if (onig_warn != onig_null_warn) {
5310 onig_syntax_warn(env, "nested repeat operator '%s' and '%s' was replaced with '%s' in regular expression",
5311 PopularQStr[targetq_num], PopularQStr[nestq_num],
5312 ReduceQStr[ReduceTypeTable[targetq_num][nestq_num]]);
5313 }
5314 goto warn_exit;
5315 break;
5316 }
5317 }
5318
5319 warn_exit:
5320 #endif
5321 if (targetq_num >= 0) {
5322 if (nestq_num >= 0) {
5323 onig_reduce_nested_quantifier(qnode, target);
5324 goto q_exit;
5325 }
5326 else if (targetq_num == 1 || targetq_num == 2) { /* * or + */
5327 /* (?:a*){n,m}, (?:a+){n,m} => (?:a*){n,n}, (?:a+){n,n} */
5328 if (! IS_REPEAT_INFINITE(qn->upper) && qn->upper > 1 && qn->greedy) {
5329 qn->upper = (qn->lower == 0 ? 1 : qn->lower);
5330 }
5331 }
5332 }
5333 }
5334 break;
5335
5336 default:
5337 break;
5338 }
5339
5340 qn->target = target;
5341 q_exit:
5342 return 0;
5343 }
5344
5345
5346 #ifdef USE_SHARED_CCLASS_TABLE
5347
5348 #define THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS 8
5349
5350 /* for ctype node hash table */
5351
5352 typedef struct {
5353 OnigEncoding enc;
5354 int not;
5355 int type;
5356 } type_cclass_key;
5357
5358 static int type_cclass_cmp(type_cclass_key* x, type_cclass_key* y)
5359 {
5360 if (x->type != y->type) return 1;
5361 if (x->enc != y->enc) return 1;
5362 if (x->not != y->not) return 1;
5363 return 0;
5364 }
5365
5366 static st_index_t type_cclass_hash(type_cclass_key* key)
5367 {
5368 int i, val;
5369 UChar *p;
5370
5371 val = 0;
5372
5373 p = (UChar* )&(key->enc);
5374 for (i = 0; i < (int )sizeof(key->enc); i++) {
5375 val = val * 997 + (int )*p++;
5376 }
5377
5378 p = (UChar* )(&key->type);
5379 for (i = 0; i < (int )sizeof(key->type); i++) {
5380 val = val * 997 + (int )*p++;
5381 }
5382
5383 val += key->not;
5384 return val + (val >> 5);
5385 }
5386
5387 static const struct st_hash_type type_type_cclass_hash = {
5388 type_cclass_cmp,
5389 type_cclass_hash,
5390 };
5391
5392 static st_table* OnigTypeCClassTable;
5393
5394
5395 static int
5396 i_free_shared_class(type_cclass_key* key, Node* node, void* arg ARG_UNUSED)
5397 {
5398 if (IS_NOT_NULL(node)) {
5399 CClassNode* cc = NCCLASS(node);
5400 if (IS_NOT_NULL(cc->mbuf)) xfree(cc->mbuf);
5401 xfree(node);
5402 }
5403
5404 if (IS_NOT_NULL(key)) xfree(key);
5405 return ST_DELETE;
5406 }
5407
5408 extern int
5409 onig_free_shared_cclass_table(void)
5410 {
5411 THREAD_ATOMIC_START;
5412 if (IS_NOT_NULL(OnigTypeCClassTable)) {
5413 onig_st_foreach(OnigTypeCClassTable, i_free_shared_class, 0);
5414 onig_st_free_table(OnigTypeCClassTable);
5415 OnigTypeCClassTable = NULL;
5416 }
5417 THREAD_ATOMIC_END;
5418
5419 return 0;
5420 }
5421
5422 #endif /* USE_SHARED_CCLASS_TABLE */
5423
5424
5425 #ifndef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
5426 static int
5427 clear_not_flag_cclass(CClassNode* cc, OnigEncoding enc)
5428 {
5429 BBuf *tbuf;
5430 int r;
5431
5432 if (IS_NCCLASS_NOT(cc)) {
5433 bitset_invert(cc->bs);
5434
5435 if (! ONIGENC_IS_SINGLEBYTE(enc)) {
5436 r = not_code_range_buf(enc, cc->mbuf, &tbuf);
5437 if (r != 0) return r;
5438
5439 bbuf_free(cc->mbuf);
5440 cc->mbuf = tbuf;
5441 }
5442
5443 NCCLASS_CLEAR_NOT(cc);
5444 }
5445
5446 return 0;
5447 }
5448 #endif /* CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS */
5449
5450 typedef struct {
5451 ScanEnv* env;
5452 CClassNode* cc;
5453 Node* alt_root;
5454 Node** ptail;
5455 } IApplyCaseFoldArg;
5456
5457 static int
5458 i_apply_case_fold(OnigCodePoint from, OnigCodePoint to[],
5459 int to_len, void* arg)
5460 {
5461 IApplyCaseFoldArg* iarg;
5462 ScanEnv* env;
5463 CClassNode* cc;
5464 BitSetRef bs;
5465
5466 iarg = (IApplyCaseFoldArg* )arg;
5467 env = iarg->env;
5468 cc = iarg->cc;
5469 bs = cc->bs;
5470
5471 if (to_len == 1) {
5472 int is_in = onig_is_code_in_cc(env->enc, from, cc);
5473 #ifdef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
5474 if ((is_in != 0 && !IS_NCCLASS_NOT(cc)) ||
5475 (is_in == 0 && IS_NCCLASS_NOT(cc))) {
5476 if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) {
5477 add_code_range0(&(cc->mbuf), env, *to, *to, 0);
5478 }
5479 else {
5480 BITSET_SET_BIT(bs, *to);
5481 }
5482 }
5483 #else
5484 if (is_in != 0) {
5485 if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) {
5486 if (IS_NCCLASS_NOT(cc)) clear_not_flag_cclass(cc, env->enc);
5487 add_code_range0(&(cc->mbuf), env, *to, *to, 0);
5488 }
5489 else {
5490 if (IS_NCCLASS_NOT(cc)) {
5491 BITSET_CLEAR_BIT(bs, *to);
5492 }
5493 else
5494 BITSET_SET_BIT(bs, *to);
5495 }
5496 }
5497 #endif /* CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS */
5498 }
5499 else {
5500 int r, i, len;
5501 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
5502 Node *snode = NULL_NODE;
5503
5504 if (onig_is_code_in_cc(env->enc, from, cc)
5505 #ifdef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
5506 && !IS_NCCLASS_NOT(cc)
5507 #endif
5508 ) {
5509 for (i = 0; i < to_len; i++) {
5510 len = ONIGENC_CODE_TO_MBC(env->enc, to[i], buf);
5511 if (i == 0) {
5512 snode = onig_node_new_str(buf, buf + len);
5513 CHECK_NULL_RETURN_MEMERR(snode);
5514
5515 /* char-class expanded multi-char only
5516 compare with string folded at match time. */
5517 NSTRING_SET_AMBIG(snode);
5518 }
5519 else {
5520 r = onig_node_str_cat(snode, buf, buf + len);
5521 if (r < 0) {
5522 onig_node_free(snode);
5523 return r;
5524 }
5525 }
5526 }
5527
5528 *(iarg->ptail) = onig_node_new_alt(snode, NULL_NODE);
5529 CHECK_NULL_RETURN_MEMERR(*(iarg->ptail));
5530 iarg->ptail = &(NCDR((*(iarg->ptail))));
5531 }
5532 }
5533
5534 return 0;
5535 }
5536
5537 static int
5538 node_linebreak(Node** np, ScanEnv* env)
5539 {
5540 /* same as (?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}]) */
5541 Node* left = NULL;
5542 Node* right = NULL;
5543 Node* target1 = NULL;
5544 Node* target2 = NULL;
5545 CClassNode* cc;
5546 int num1, num2;
5547 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
5548
5549 /* \x0D\x0A */
5550 num1 = ONIGENC_CODE_TO_MBC(env->enc, 0x0D, buf);
5551 if (num1 < 0) return num1;
5552 num2 = ONIGENC_CODE_TO_MBC(env->enc, 0x0A, buf + num1);
5553 if (num2 < 0) return num2;
5554 left = node_new_str_raw(buf, buf + num1 + num2);
5555 if (IS_NULL(left)) goto err;
5556
5557 /* [\x0A-\x0D] or [\x0A-\x0D\x{85}\x{2028}\x{2029}] */
5558 right = node_new_cclass();
5559 if (IS_NULL(right)) goto err;
5560 cc = NCCLASS(right);
5561 if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
5562 add_code_range(&(cc->mbuf), env, 0x0A, 0x0D);
5563 }
5564 else {
5565 bitset_set_range(env, cc->bs, 0x0A, 0x0D);
5566 }
5567
5568 /* TODO: move this block to enc/unicode.c */
5569 if (ONIGENC_IS_UNICODE(env->enc)) {
5570 /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
5571 add_code_range(&(cc->mbuf), env, 0x85, 0x85);
5572 add_code_range(&(cc->mbuf), env, 0x2028, 0x2029);
5573 }
5574
5575 /* ...|... */
5576 target1 = onig_node_new_alt(right, NULL_NODE);
5577 if (IS_NULL(target1)) goto err;
5578 right = NULL;
5579 target2 = onig_node_new_alt(left, target1);
5580 if (IS_NULL(target2)) goto err;
5581 left = NULL;
5582 target1 = NULL;
5583
5584 /* (?>...) */
5585 *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
5586 if (IS_NULL(*np)) goto err;
5587 NENCLOSE(*np)->target = target2;
5588 return ONIG_NORMAL;
5589
5590 err:
5591 onig_node_free(left);
5592 onig_node_free(right);
5593 onig_node_free(target1);
5594 onig_node_free(target2);
5595 return ONIGERR_MEMORY;
5596 }
5597
5598 static int
5599 node_extended_grapheme_cluster(Node** np, ScanEnv* env)
5600 {
5601 /* same as (?>\P{M}\p{M}*) */
5602 Node* np1 = NULL;
5603 Node* np2 = NULL;
5604 Node* qn = NULL;
5605 Node* list1 = NULL;
5606 Node* list2 = NULL;
5607 int r = 0;
5608
5609 #ifdef USE_UNICODE_PROPERTIES
5610 if (ONIGENC_IS_UNICODE(env->enc)) {
5611 /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
5612 CClassNode* cc1;
5613 CClassNode* cc2;
5614 UChar* propname = (UChar* )"M";
5615 int ctype = env->enc->property_name_to_ctype(ONIG_ENCODING_ASCII,
5616 propname, propname + 1);
5617 if (ctype >= 0) {
5618 /* \P{M} */
5619 np1 = node_new_cclass();
5620 if (IS_NULL(np1)) goto err;
5621 cc1 = NCCLASS(np1);
5622 r = add_ctype_to_cc(cc1, ctype, 0, 1, env);
5623 if (r != 0) goto err;
5624 NCCLASS_SET_NOT(cc1);
5625
5626 /* \p{M}* */
5627 np2 = node_new_cclass();
5628 if (IS_NULL(np2)) goto err;
5629 cc2 = NCCLASS(np2);
5630 r = add_ctype_to_cc(cc2, ctype, 0, 1, env);
5631 if (r != 0) goto err;
5632
5633 qn = node_new_quantifier(0, REPEAT_INFINITE, 0);
5634 if (IS_NULL(qn)) goto err;
5635 NQTFR(qn)->target = np2;
5636 np2 = NULL;
5637
5638 /* \P{M}\p{M}* */
5639 list2 = node_new_list(qn, NULL_NODE);
5640 if (IS_NULL(list2)) goto err;
5641 qn = NULL;
5642 list1 = node_new_list(np1, list2);
5643 if (IS_NULL(list1)) goto err;
5644 np1 = NULL;
5645 list2 = NULL;
5646
5647 /* (?>...) */
5648 *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
5649 if (IS_NULL(*np)) goto err;
5650 NENCLOSE(*np)->target = list1;
5651 return ONIG_NORMAL;
5652 }
5653 }
5654 #endif /* USE_UNICODE_PROPERTIES */
5655 if (IS_NULL(*np)) {
5656 /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
5657 OnigOptionType option;
5658 np1 = node_new_anychar();
5659 if (IS_NULL(np1)) goto err;
5660
5661 option = env->option;
5662 ONOFF(option, ONIG_OPTION_MULTILINE, 0);
5663 *np = node_new_option(option);
5664 if (IS_NULL(*np)) goto err;
5665 NENCLOSE(*np)->target = np1;
5666 }
5667 return ONIG_NORMAL;
5668
5669 err:
5670 onig_node_free(np1);
5671 onig_node_free(np2);
5672 onig_node_free(qn);
5673 onig_node_free(list1);
5674 onig_node_free(list2);
5675 return (r == 0) ? ONIGERR_MEMORY : r;
5676 }
5677
5678 static int
5679 countbits(unsigned int bits)
5680 {
5681 bits = (bits & 0x55555555) + ((bits >> 1) & 0x55555555);
5682 bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
5683 bits = (bits & 0x0f0f0f0f) + ((bits >> 4) & 0x0f0f0f0f);
5684 bits = (bits & 0x00ff00ff) + ((bits >> 8) & 0x00ff00ff);
5685 return (bits & 0x0000ffff) + ((bits >>16) & 0x0000ffff);
5686 }
5687
5688 static int
5689 is_onechar_cclass(CClassNode* cc, OnigCodePoint* code)
5690 {
5691 const OnigCodePoint not_found = ONIG_LAST_CODE_POINT;
5692 OnigCodePoint c = not_found;
5693 int i;
5694 BBuf *bbuf = cc->mbuf;
5695
5696 if (IS_NCCLASS_NOT(cc)) return 0;
5697
5698 /* check bbuf */
5699 if (IS_NOT_NULL(bbuf)) {
5700 OnigCodePoint n, *data;
5701 GET_CODE_POINT(n, bbuf->p);
5702 data = (OnigCodePoint* )(bbuf->p) + 1;
5703 if ((n == 1) && (data[0] == data[1])) {
5704 /* only one char found in the bbuf, save the code point. */
5705 c = data[0];
5706 if (((c < SINGLE_BYTE_SIZE) && BITSET_AT(cc->bs, c))) {
5707 /* skip if c is included in the bitset */
5708 c = not_found;
5709 }
5710 }
5711 else {
5712 return 0; /* the bbuf contains multiple chars */
5713 }
5714 }
5715
5716 /* check bitset */
5717 for (i = 0; i < BITSET_SIZE; i++) {
5718 Bits b1 = cc->bs[i];
5719 if (b1 != 0) {
5720 if (((b1 & (b1 - 1)) == 0) && (c == not_found)) {
5721 c = BITS_IN_ROOM * i + countbits(b1 - 1);
5722 } else {
5723 return 0; /* the character class contains multiple chars */
5724 }
5725 }
5726 }
5727
5728 if (c != not_found) {
5729 *code = c;
5730 return 1;
5731 }
5732
5733 /* the character class contains no char. */
5734 return 0;
5735 }
5736
5737
5738 static int
5739 parse_exp(Node** np, OnigToken* tok, int term,
5740 UChar** src, UChar* end, ScanEnv* env)
5741 {
5742 int r, len, group = 0;
5743 Node* qn;
5744 Node** targetp;
5745
5746 *np = NULL;
5747 if (tok->type == (enum TokenSyms )term)
5748 goto end_of_token;
5749
5750 switch (tok->type) {
5751 case TK_ALT:
5752 case TK_EOT:
5753 end_of_token:
5754 *np = node_new_empty();
5755 return tok->type;
5756 break;
5757
5758 case TK_SUBEXP_OPEN:
5759 r = parse_enclose(np, tok, TK_SUBEXP_CLOSE, src, end, env);
5760 if (r < 0) return r;
5761 if (r == 1) group = 1;
5762 else if (r == 2) { /* option only */
5763 Node* target;
5764 OnigOptionType prev = env->option;
5765
5766 env->option = NENCLOSE(*np)->option;
5767 r = fetch_token(tok, src, end, env);
5768 if (r < 0) return r;
5769 r = parse_subexp(&target, tok, term, src, end, env);
5770 env->option = prev;
5771 if (r < 0) {
5772 onig_node_free(target);
5773 return r;
5774 }
5775 NENCLOSE(*np)->target = target;
5776 return tok->type;
5777 }
5778 break;
5779
5780 case TK_SUBEXP_CLOSE:
5781 if (! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP))
5782 return ONIGERR_UNMATCHED_CLOSE_PARENTHESIS;
5783
5784 if (tok->escaped) goto tk_raw_byte;
5785 else goto tk_byte;
5786 break;
5787
5788 case TK_LINEBREAK:
5789 r = node_linebreak(np, env);
5790 if (r < 0) return r;
5791 break;
5792
5793 case TK_EXTENDED_GRAPHEME_CLUSTER:
5794 r = node_extended_grapheme_cluster(np, env);
5795 if (r < 0) return r;
5796 break;
5797
5798 case TK_KEEP:
5799 *np = onig_node_new_anchor(ANCHOR_KEEP);
5800 CHECK_NULL_RETURN_MEMERR(*np);
5801 break;
5802
5803 case TK_STRING:
5804 tk_byte:
5805 {
5806 *np = node_new_str(tok->backp, *src);
5807 CHECK_NULL_RETURN_MEMERR(*np);
5808
5809 string_loop:
5810 while (1) {
5811 r = fetch_token(tok, src, end, env);
5812 if (r < 0) return r;
5813 if (r == TK_STRING) {
5814 r = onig_node_str_cat(*np, tok->backp, *src);
5815 }
5816 #ifndef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
5817 else if (r == TK_CODE_POINT) {
5818 r = node_str_cat_codepoint(*np, env->enc, tok->u.code);
5819 }
5820 #endif
5821 else {
5822 break;
5823 }
5824 if (r < 0) return r;
5825 }
5826
5827 string_end:
5828 targetp = np;
5829 goto repeat;
5830 }
5831 break;
5832
5833 case TK_RAW_BYTE:
5834 tk_raw_byte:
5835 {
5836 *np = node_new_str_raw_char((UChar )tok->u.c);
5837 CHECK_NULL_RETURN_MEMERR(*np);
5838 len = 1;
5839 while (1) {
5840 if (len >= ONIGENC_MBC_MINLEN(env->enc)) {
5841 if (len == enclen(env->enc, NSTR(*np)->s, NSTR(*np)->end)) {
5842 r = fetch_token(tok, src, end, env);
5843 NSTRING_CLEAR_RAW(*np);
5844 goto string_end;
5845 }
5846 }
5847
5848 r = fetch_token(tok, src, end, env);
5849 if (r < 0) return r;
5850 if (r != TK_RAW_BYTE) {
5851 /* Don't use this, it is wrong for little endian encodings. */
5852 #ifdef USE_PAD_TO_SHORT_BYTE_CHAR
5853 int rem;
5854 if (len < ONIGENC_MBC_MINLEN(env->enc)) {
5855 rem = ONIGENC_MBC_MINLEN(env->enc) - len;
5856 (void )node_str_head_pad(NSTR(*np), rem, (UChar )0);
5857 if (len + rem == enclen(env->enc, NSTR(*np)->s)) {
5858 NSTRING_CLEAR_RAW(*np);
5859 goto string_end;
5860 }
5861 }
5862 #endif
5863 return ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
5864 }
5865
5866 r = node_str_cat_char(*np, (UChar )tok->u.c);
5867 if (r < 0) return r;
5868
5869 len++;
5870 }
5871 }
5872 break;
5873
5874 case TK_CODE_POINT:
5875 {
5876 *np = node_new_empty();
5877 CHECK_NULL_RETURN_MEMERR(*np);
5878 r = node_str_cat_codepoint(*np, env->enc, tok->u.code);
5879 if (r != 0) return r;
5880 #ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
5881 NSTRING_SET_RAW(*np);
5882 #else
5883 goto string_loop;
5884 #endif
5885 }
5886 break;
5887
5888 case TK_QUOTE_OPEN:
5889 {
5890 OnigCodePoint end_op[2];
5891 UChar *qstart, *qend, *nextp;
5892
5893 end_op[0] = (OnigCodePoint )MC_ESC(env->syntax);
5894 end_op[1] = (OnigCodePoint )'E';
5895 qstart = *src;
5896 qend = find_str_position(end_op, 2, qstart, end, &nextp, env->enc);
5897 if (IS_NULL(qend)) {
5898 nextp = qend = end;
5899 }
5900 *np = node_new_str(qstart, qend);
5901 CHECK_NULL_RETURN_MEMERR(*np);
5902 *src = nextp;
5903 }
5904 break;
5905
5906 case TK_CHAR_TYPE:
5907 {
5908 switch (tok->u.prop.ctype) {
5909 case ONIGENC_CTYPE_WORD:
5910 *np = node_new_ctype(tok->u.prop.ctype, tok->u.prop.not,
5911 IS_ASCII_RANGE(env->option));
5912 CHECK_NULL_RETURN_MEMERR(*np);
5913 break;
5914
5915 case ONIGENC_CTYPE_SPACE:
5916 case ONIGENC_CTYPE_DIGIT:
5917 case ONIGENC_CTYPE_XDIGIT:
5918 {
5919 CClassNode* cc;
5920
5921 #ifdef USE_SHARED_CCLASS_TABLE
5922 const OnigCodePoint *mbr;
5923 OnigCodePoint sb_out;
5924
5925 r = ONIGENC_GET_CTYPE_CODE_RANGE(env->enc, tok->u.prop.ctype,
5926 &sb_out, &mbr);
5927 if (r == 0 &&
5928 ! IS_ASCII_RANGE(env->option) &&
5929 ONIGENC_CODE_RANGE_NUM(mbr)
5930 >= THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS) {
5931 type_cclass_key key;
5932 type_cclass_key* new_key;
5933
5934 key.enc = env->enc;
5935 key.not = tok->u.prop.not;
5936 key.type = tok->u.prop.ctype;
5937
5938 THREAD_ATOMIC_START;
5939
5940 if (IS_NULL(OnigTypeCClassTable)) {
5941 OnigTypeCClassTable
5942 = onig_st_init_table_with_size(&type_type_cclass_hash, 10);
5943 if (IS_NULL(OnigTypeCClassTable)) {
5944 THREAD_ATOMIC_END;
5945 return ONIGERR_MEMORY;
5946 }
5947 }
5948 else {
5949 if (onig_st_lookup(OnigTypeCClassTable, (st_data_t )&key,
5950 (st_data_t* )np)) {
5951 THREAD_ATOMIC_END;
5952 break;
5953 }
5954 }
5955
5956 *np = node_new_cclass_by_codepoint_range(tok->u.prop.not,
5957 sb_out, mbr);
5958 if (IS_NULL(*np)) {
5959 THREAD_ATOMIC_END;
5960 return ONIGERR_MEMORY;
5961 }
5962
5963 cc = NCCLASS(*np);
5964 NCCLASS_SET_SHARE(cc);
5965 new_key = (type_cclass_key* )xmalloc(sizeof(type_cclass_key));
5966 xmemcpy(new_key, &key, sizeof(type_cclass_key));
5967 onig_st_add_direct(OnigTypeCClassTable, (st_data_t )new_key,
5968 (st_data_t )*np);
5969
5970 THREAD_ATOMIC_END;
5971 }
5972 else {
5973 #endif
5974 *np = node_new_cclass();
5975 CHECK_NULL_RETURN_MEMERR(*np);
5976 cc = NCCLASS(*np);
5977 r = add_ctype_to_cc(cc, tok->u.prop.ctype, 0, 0, env);
5978 if (r != 0) return r;
5979 if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);
5980 #ifdef USE_SHARED_CCLASS_TABLE
5981 }
5982 #endif
5983 }
5984 break;
5985
5986 default:
5987 return ONIGERR_PARSER_BUG;
5988 break;
5989 }
5990 }
5991 break;
5992
5993 case TK_CHAR_PROPERTY:
5994 r = parse_char_property(np, tok, src, end, env);
5995 if (r != 0) return r;
5996 break;
5997
5998 case TK_CC_OPEN:
5999 {
6000 CClassNode* cc;
6001 OnigCodePoint code;
6002
6003 r = parse_char_class(np, tok, src, end, env);
6004 if (r != 0) return r;
6005
6006 cc = NCCLASS(*np);
6007 if (is_onechar_cclass(cc, &code)) {
6008 onig_node_free(*np);
6009 *np = node_new_empty();
6010 CHECK_NULL_RETURN_MEMERR(*np);
6011 r = node_str_cat_codepoint(*np, env->enc, code);
6012 if (r != 0) return r;
6013 goto string_loop;
6014 }
6015 if (IS_IGNORECASE(env->option)) {
6016 IApplyCaseFoldArg iarg;
6017
6018 iarg.env = env;
6019 iarg.cc = cc;
6020 iarg.alt_root = NULL_NODE;
6021 iarg.ptail = &(iarg.alt_root);
6022
6023 r = ONIGENC_APPLY_ALL_CASE_FOLD(env->enc, env->case_fold_flag,
6024 i_apply_case_fold, &iarg);
6025 if (r != 0) {
6026 onig_node_free(iarg.alt_root);
6027 return r;
6028 }
6029 if (IS_NOT_NULL(iarg.alt_root)) {
6030 Node* work = onig_node_new_alt(*np, iarg.alt_root);
6031 if (IS_NULL(work)) {
6032 onig_node_free(iarg.alt_root);
6033 return ONIGERR_MEMORY;
6034 }
6035 *np = work;
6036 }
6037 }
6038 }
6039 break;
6040
6041 case TK_ANYCHAR:
6042 *np = node_new_anychar();
6043 CHECK_NULL_RETURN_MEMERR(*np);
6044 break;
6045
6046 case TK_ANYCHAR_ANYTIME:
6047 *np = node_new_anychar();
6048 CHECK_NULL_RETURN_MEMERR(*np);
6049 qn = node_new_quantifier(0, REPEAT_INFINITE, 0);
6050 CHECK_NULL_RETURN_MEMERR(qn);
6051 NQTFR(qn)->target = *np;
6052 *np = qn;
6053 break;
6054
6055 case TK_BACKREF:
6056 len = tok->u.backref.num;
6057 *np = node_new_backref(len,
6058 (len > 1 ? tok->u.backref.refs : &(tok->u.backref.ref1)),
6059 tok->u.backref.by_name,
6060 #ifdef USE_BACKREF_WITH_LEVEL
6061 tok->u.backref.exist_level,
6062 tok->u.backref.level,
6063 #endif
6064 env);
6065 CHECK_NULL_RETURN_MEMERR(*np);
6066 break;
6067
6068 #ifdef USE_SUBEXP_CALL
6069 case TK_CALL:
6070 {
6071 int gnum = tok->u.call.gnum;
6072
6073 if (gnum < 0 || tok->u.call.rel != 0) {
6074 if (gnum > 0) gnum--;
6075 gnum = BACKREF_REL_TO_ABS(gnum, env);
6076 if (gnum <= 0)
6077 return ONIGERR_INVALID_BACKREF;
6078 }
6079 *np = node_new_call(tok->u.call.name, tok->u.call.name_end, gnum);
6080 CHECK_NULL_RETURN_MEMERR(*np);
6081 env->num_call++;
6082 }
6083 break;
6084 #endif
6085
6086 case TK_ANCHOR:
6087 *np = onig_node_new_anchor(tok->u.anchor.subtype);
6088 CHECK_NULL_RETURN_MEMERR(*np);
6089 NANCHOR(*np)->ascii_range = tok->u.anchor.ascii_range;
6090 break;
6091
6092 case TK_OP_REPEAT:
6093 case TK_INTERVAL:
6094 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS)) {
6095 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS))
6096 return ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED;
6097 else
6098 *np = node_new_empty();
6099 }
6100 else {
6101 goto tk_byte;
6102 }
6103 break;
6104
6105 default:
6106 return ONIGERR_PARSER_BUG;
6107 break;
6108 }
6109
6110 {
6111 targetp = np;
6112
6113 re_entry:
6114 r = fetch_token(tok, src, end, env);
6115 if (r < 0) return r;
6116
6117 repeat:
6118 if (r == TK_OP_REPEAT || r == TK_INTERVAL) {
6119 if (is_invalid_quantifier_target(*targetp))
6120 return ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID;
6121
6122 qn = node_new_quantifier(tok->u.repeat.lower, tok->u.repeat.upper,
6123 (r == TK_INTERVAL ? 1 : 0));
6124 CHECK_NULL_RETURN_MEMERR(qn);
6125 NQTFR(qn)->greedy = tok->u.repeat.greedy;
6126 r = set_quantifier(qn, *targetp, group, env);
6127 if (r < 0) {
6128 onig_node_free(qn);
6129 return r;
6130 }
6131
6132 if (tok->u.repeat.possessive != 0) {
6133 Node* en;
6134 en = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
6135 if (IS_NULL(en)) {
6136 onig_node_free(qn);
6137 return ONIGERR_MEMORY;
6138 }
6139 NENCLOSE(en)->target = qn;
6140 qn = en;
6141 }
6142
6143 if (r == 0) {
6144 *targetp = qn;
6145 }
6146 else if (r == 1) {
6147 onig_node_free(qn);
6148 }
6149 else if (r == 2) { /* split case: /abc+/ */
6150 Node *tmp;
6151
6152 *targetp = node_new_list(*targetp, NULL);
6153 if (IS_NULL(*targetp)) {
6154 onig_node_free(qn);
6155 return ONIGERR_MEMORY;
6156 }
6157 tmp = NCDR(*targetp) = node_new_list(qn, NULL);
6158 if (IS_NULL(tmp)) {
6159 onig_node_free(qn);
6160 return ONIGERR_MEMORY;
6161 }
6162 targetp = &(NCAR(tmp));
6163 }
6164 goto re_entry;
6165 }
6166 }
6167
6168 return r;
6169 }
6170
6171 static int
6172 parse_branch(Node** top, OnigToken* tok, int term,
6173 UChar** src, UChar* end, ScanEnv* env)
6174 {
6175 int r;
6176 Node *node, **headp;
6177
6178 *top = NULL;
6179 r = parse_exp(&node, tok, term, src, end, env);
6180 if (r < 0) {
6181 onig_node_free(node);
6182 return r;
6183 }
6184
6185 if (r == TK_EOT || r == term || r == TK_ALT) {
6186 *top = node;
6187 }
6188 else {
6189 *top = node_new_list(node, NULL);
6190 headp = &(NCDR(*top));
6191 while (r != TK_EOT && r != term && r != TK_ALT) {
6192 r = parse_exp(&node, tok, term, src, end, env);
6193 if (r < 0) {
6194 onig_node_free(node);
6195 return r;
6196 }
6197
6198 if (NTYPE(node) == NT_LIST) {
6199 *headp = node;
6200 while (IS_NOT_NULL(NCDR(node))) node = NCDR(node);
6201 headp = &(NCDR(node));
6202 }
6203 else {
6204 *headp = node_new_list(node, NULL);
6205 headp = &(NCDR(*headp));
6206 }
6207 }
6208 }
6209
6210 return r;
6211 }
6212
6213 /* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
6214 static int
6215 parse_subexp(Node** top, OnigToken* tok, int term,
6216 UChar** src, UChar* end, ScanEnv* env)
6217 {
6218 int r;
6219 Node *node, **headp;
6220
6221 *top = NULL;
6222 r = parse_branch(&node, tok, term, src, end, env);
6223 if (r < 0) {
6224 onig_node_free(node);
6225 return r;
6226 }
6227
6228 if (r == term) {
6229 *top = node;
6230 }
6231 else if (r == TK_ALT) {
6232 *top = onig_node_new_alt(node, NULL);
6233 headp = &(NCDR(*top));
6234 while (r == TK_ALT) {
6235 r = fetch_token(tok, src, end, env);
6236 if (r < 0) return r;
6237 r = parse_branch(&node, tok, term, src, end, env);
6238 if (r < 0) {
6239 onig_node_free(node);
6240 return r;
6241 }
6242
6243 *headp = onig_node_new_alt(node, NULL);
6244 headp = &(NCDR(*headp));
6245 }
6246
6247 if (tok->type != (enum TokenSyms )term)
6248 goto err;
6249 }
6250 else {
6251 onig_node_free(node);
6252 err:
6253 if (term == TK_SUBEXP_CLOSE)
6254 return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
6255 else
6256 return ONIGERR_PARSER_BUG;
6257 }
6258
6259 return r;
6260 }
6261
6262 static int
6263 parse_regexp(Node** top, UChar** src, UChar* end, ScanEnv* env)
6264 {
6265 int r;
6266 OnigToken tok;
6267
6268 r = fetch_token(&tok, src, end, env);
6269 if (r < 0) return r;
6270 r = parse_subexp(top, &tok, TK_EOT, src, end, env);
6271 if (r < 0) return r;
6272
6273 #ifdef USE_SUBEXP_CALL
6274 if (env->num_call > 0) {
6275 /* Capture the pattern itself. It is used for (?R), (?0) and \g<0>. */
6276 const int num = 0;
6277 Node* np;
6278 np = node_new_enclose_memory(env->option, 0);
6279 CHECK_NULL_RETURN_MEMERR(np);
6280 NENCLOSE(np)->regnum = num;
6281 NENCLOSE(np)->target = *top;
6282 r = scan_env_set_mem_node(env, num, np);
6283 if (r != 0) return r;
6284 *top = np;
6285 }
6286 #endif
6287 return 0;
6288 }
6289
6290 extern int
6291 onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end,
6292 regex_t* reg, ScanEnv* env)
6293 {
6294 int r;
6295 UChar* p;
6296
6297 #ifdef USE_NAMED_GROUP
6298 names_clear(reg);
6299 #endif
6300
6301 scan_env_clear(env);
6302 env->option = reg->options;
6303 env->case_fold_flag = reg->case_fold_flag;
6304 env->enc = reg->enc;
6305 env->syntax = reg->syntax;
6306 env->pattern = (UChar* )pattern;
6307 env->pattern_end = (UChar* )end;
6308 env->reg = reg;
6309
6310 *root = NULL;
6311 p = (UChar* )pattern;
6312 r = parse_regexp(root, &p, (UChar* )end, env);
6313 reg->num_mem = env->num_mem;
6314 return r;
6315 }
6316
6317 extern void
6318 onig_scan_env_set_error_string(ScanEnv* env, int ecode ARG_UNUSED,
6319 UChar* arg, UChar* arg_end)
6320 {
6321 env->error = arg;
6322 env->error_end = arg_end;
6323 }
TK_STRING
Definition: regparse.c:2323
ScanEnv::pattern
UChar * pattern
Definition: regparse.h:294
ONIGERR_UNDEFINED_GROUP_OPTION
#define ONIGERR_UNDEFINED_GROUP_OPTION
Definition: oniguruma.h:558
bitset_set_range
static void bitset_set_range(ScanEnv *env, BitSetRef bs, int from, int to)
Definition: regparse.c:167
ONIG_SYN_OP2_CCLASS_SET_OP
#define ONIG_SYN_OP2_CCLASS_SET_OP
Definition: oniguruma.h:459
NameEntry
Definition: regparse.c:414
NSTRING_SET_AMBIG
#define NSTRING_SET_AMBIG(node)
Definition: regparse.h:106
ONIGENC_CTYPE_BLANK
#define ONIGENC_CTYPE_BLANK
Definition: oniguruma.h:196
TK_INTERVAL
Definition: regparse.c:2331
ONIGENC_CTYPE_PUNCT
#define ONIGENC_CTYPE_PUNCT
Definition: oniguruma.h:202
onig_scan_env_set_error_string
void onig_scan_env_set_error_string(ScanEnv *env, int ecode ARG_UNUSED, UChar *arg, UChar *arg_end)
Definition: regparse.c:6318
NCCLASS_SET_NOT
#define NCCLASS_SET_NOT(nd)
Definition: regint.h:762
ONIGERR_INVALID_CONDITION_PATTERN
#define ONIGERR_INVALID_CONDITION_PATTERN
Definition: oniguruma.h:562
onig_warn
static OnigWarnFunc onig_warn
Definition: regparse.c:87
OnigCodePoint
unsigned int OnigCodePoint
Definition: oniguruma.h:112
onig_set_warn_func
void onig_set_warn_func(OnigWarnFunc f)
Definition: regparse.c:96
ST_DELETE
Definition: st.h:100
OnigToken::gnum
int gnum
Definition: regparse.c:2382
CCS_VALUE
Definition: regparse.c:4370
IS_NULL
#define IS_NULL(p)
Definition: regint.h:276
NODE_STR_BUF_SIZE
#define NODE_STR_BUF_SIZE
Definition: regparse.h:96
TK_ANYCHAR_ANYTIME
Definition: regparse.c:2332
ENCLOSE_MEMORY
#define ENCLOSE_MEMORY
Definition: regparse.h:90
_BBuf::alloc
unsigned int alloc
Definition: regint.h:421
popular_quantifier_num
static int popular_quantifier_num(QtfrNode *q)
Definition: regparse.c:2225
ONIG_MAX_REPEAT_NUM
#define ONIG_MAX_REPEAT_NUM
Definition: oniguruma.h:342
ADD_ALL_MULTI_BYTE_RANGE
#define ADD_ALL_MULTI_BYTE_RANGE(enc, mbuf)
Definition: regparse.c:143
OnigToken::backref
struct OnigToken::@142::@145 backref
ScanEnv::pattern_end
UChar * pattern_end
Definition: regparse.h:295
onig_foreach_name
int onig_foreach_name(regex_t *reg, int(*func)(const UChar *, const UChar *, int, int *, regex_t *, void *), void *arg)
Definition: regparse.c:537
TK_SUBEXP_OPEN
Definition: regparse.c:2334
ReduceTypeTable
static enum ReduceType const ReduceTypeTable[6][6]
Definition: regparse.c:2259
IS_REPEAT_INFINITE
#define IS_REPEAT_INFINITE(n)
Definition: regint.h:386
NCCLASS_SET_SHARE
#define NCCLASS_SET_SHARE(nd)
Definition: regint.h:763
ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE
#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE
Definition: oniguruma.h:453
StrNode::end
UChar * end
Definition: regparse.h:168
node_new_list
static Node * node_new_list(Node *left, Node *right)
Definition: regparse.c:1243
onig_free_node_list
int onig_free_node_list(void)
Definition: regparse.c:1112
SET_ALL_MULTI_BYTE_RANGE
#define SET_ALL_MULTI_BYTE_RANGE(enc, pbuf)
Definition: regparse.c:140
RQ_P_QQ
Definition: regparse.c:2255
FALSE
#define FALSE
Definition: nkf.h:174
ONIG_SYN_OP2_ESC_U_HEX4
#define ONIG_SYN_OP2_ESC_U_HEX4
Definition: oniguruma.h:467
onig_node_str_cat
int onig_node_str_cat(Node *node, const UChar *s, const UChar *end)
Definition: regparse.c:1445
CC_ESC_WARN
static void CC_ESC_WARN(ScanEnv *env, UChar *c)
Definition: regparse.c:2912
node_extended_grapheme_cluster
static int node_extended_grapheme_cluster(Node **np, ScanEnv *env)
Definition: regparse.c:5599
onig_node_list_add
Node * onig_node_list_add(Node *list, Node *x)
Definition: regparse.c:1261
IS_SYNTAX_BV
#define IS_SYNTAX_BV(syn, bvm)
Definition: regparse.h:324
ONIGERR_TOO_BIG_WIDE_CHAR_VALUE
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE
Definition: oniguruma.h:589
onig_st_lookup_strend
int onig_st_lookup_strend(hash_table_type *table, const UChar *str_key, const UChar *end_key, hash_data_type *value)
Definition: regparse.c:379
NameEntry::back_refs
int * back_refs
Definition: regparse.c:420
ONIG_SYN_OP_ESC_OCTAL3
#define ONIG_SYN_OP_ESC_OCTAL3
Definition: oniguruma.h:448
ONIGENC_IS_CODE_WORD
#define ONIGENC_IS_CODE_WORD(enc, code)
Definition: oniguruma.h:300
fetch_name_with_level
static int fetch_name_with_level(OnigCodePoint start_code, UChar **src, UChar *end, UChar **rname_end, ScanEnv *env, int *rback_num, int *rlevel)
Definition: regparse.c:2582
INT_MAX_LIMIT
#define INT_MAX_LIMIT
Definition: regint.h:351
PopularQStr
static const char *const PopularQStr[]
Definition: regparse.c:5254
ONIG_OPTION_SINGLELINE
#define ONIG_OPTION_SINGLELINE
Definition: oniguruma.h:357
st_table
Definition: st.h:69
NST_NEST_LEVEL
#define NST_NEST_LEVEL
Definition: regparse.h:136
ONIG_SYN_OP_VARIABLE_META_CHARACTERS
#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS
Definition: oniguruma.h:420
onig_null_warn
void onig_null_warn(const char *s ARG_UNUSED)
Definition: regparse.c:82
ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS
#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS
Definition: oniguruma.h:489
TK_EXTENDED_GRAPHEME_CLUSTER
Definition: regparse.c:2340
onig_st_init_table_with_size
#define onig_st_init_table_with_size
Definition: regint.h:132
ANCHOR_END_BUF
#define ANCHOR_END_BUF
Definition: regint.h:501
ST_STOP
Definition: st.h:100
PINC
#define PINC
Definition: regparse.c:274
BBUF_WRITE_CODE_POINT
#define BBUF_WRITE_CODE_POINT(bbuf, pos, code)
Definition: regparse.c:1710
CClassNode::flags
unsigned int flags
Definition: regint.h:776
scan_env_add_mem_entry
static int scan_env_add_mem_entry(ScanEnv *env)
Definition: regparse.c:975
ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE
#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE
Definition: oniguruma.h:568
ONIG_SYN_OP_BRACE_INTERVAL
#define ONIG_SYN_OP_BRACE_INTERVAL
Definition: oniguruma.h:428
ANCHOR_WORD_BEGIN
#define ANCHOR_WORD_BEGIN
Definition: regint.h:507
GroupNumRemap::new_val
int new_val
Definition: regparse.h:328
SINGLE_BYTE_SIZE
#define SINGLE_BYTE_SIZE
Definition: regint.h:390
bitset_invert_to
static void bitset_invert_to(BitSetRef from, BitSetRef to)
Definition: regparse.c:192
ScanEnv::num_call
int num_call
Definition: regparse.h:299
BITSET_SET_BIT
#define BITSET_SET_BIT(bs, pos)
Definition: regint.h:413
st_str_end_key
Definition: regparse.c:322
ONIG_SYN_OP2_OPTION_RUBY
#define ONIG_SYN_OP2_OPTION_RUBY
Definition: oniguruma.h:456
ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR
#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR
Definition: oniguruma.h:435
ONIG_SYN_OP_ASTERISK_ZERO_INF
#define ONIG_SYN_OP_ASTERISK_ZERO_INF
Definition: oniguruma.h:422
bitset_and
static void bitset_and(BitSetRef dest, BitSetRef bs)
Definition: regparse.c:199
ONIG_SYN_OP2_ESC_G_BRACE_BACKREF
#define ONIG_SYN_OP2_ESC_G_BRACE_BACKREF
Definition: oniguruma.h:479
NCCLASS_CLEAR_NOT
#define NCCLASS_CLEAR_NOT(nd)
Definition: regint.h:764
regparse.h
scan_unsigned_octal_number
static int scan_unsigned_octal_number(UChar **src, UChar *end, int maxlen, OnigEncoding enc)
Definition: regparse.c:1682
OnigToken::code
OnigCodePoint code
Definition: regparse.c:2358
ScanEnv::sourceline
int sourceline
Definition: regparse.h:318
NULL_UCHARP
#define NULL_UCHARP
Definition: regint.h:280
WARN_BUFSIZE
#define WARN_BUFSIZE
Definition: regparse.c:33
SCANENV_MEM_NODES
#define SCANENV_MEM_NODES(senv)
Definition: regparse.h:281
parse_posix_bracket
static int parse_posix_bracket(CClassNode *cc, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:4240
INamesArg::reg
regex_t * reg
Definition: regparse.c:515
ONIG_SYN_OP2_QMARK_SUBEXP_CALL
#define ONIG_SYN_OP2_QMARK_SUBEXP_CALL
Definition: oniguruma.h:480
onig_names_free
int onig_names_free(regex_t *reg)
Definition: regparse.c:486
TK_CC_CLOSE
Definition: regparse.c:2343
ANCHOR_BEGIN_LINE
#define ANCHOR_BEGIN_LINE
Definition: regint.h:499
IS_SYNTAX_OP
#define IS_SYNTAX_OP(syn, opm)
Definition: regparse.h:322
MC_ANYTIME
#define MC_ANYTIME(syn)
Definition: regint.h:717
ONIG_SYN_OP2_ESC_K_NAMED_BACKREF
#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF
Definition: oniguruma.h:461
NEWLINE_CODE
#define NEWLINE_CODE
ST_CONTINUE
Definition: st.h:100
INamesArg::func
int(* func)(const UChar *, const UChar *, int, int *, regex_t *, void *)
Definition: regparse.c:514
OnigEncodingTypeST::property_name_to_ctype
int(* property_name_to_ctype)(struct OnigEncodingTypeST *enc, OnigUChar *p, OnigUChar *end)
Definition: oniguruma.h:170
OnigToken::repeat
struct OnigToken::@142::@144 repeat
fetch_named_backref_token
static int fetch_named_backref_token(OnigCodePoint c, OnigToken *tok, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:3242
IApplyCaseFoldArg::alt_root
Node * alt_root
Definition: regparse.c:5453
ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP
#define ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP
Definition: oniguruma.h:483
parse_char_property
static int parse_char_property(Node **np, OnigToken *tok, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:4349
ScanEnv::error
UChar * error
Definition: regparse.h:296
onig_node_str_set
int onig_node_str_set(Node *node, const UChar *s, const UChar *end)
Definition: regparse.c:1481
OnigToken::refs
int * refs
Definition: regparse.c:2372
IS_NCCLASS_NOT
#define IS_NCCLASS_NOT(nd)
Definition: regint.h:765
ONIG_REGION_NOTPOS
#define ONIG_REGION_NOTPOS
Definition: oniguruma.h:628
scan_env_clear
static void scan_env_clear(ScanEnv *env)
Definition: regparse.c:944
parse_branch
static int parse_branch(Node **top, OnigToken *tok, int term, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:6172
TK_CALL
Definition: regparse.c:2328
ONIG_SYN_OP_VBAR_ALT
#define ONIG_SYN_OP_VBAR_ALT
Definition: oniguruma.h:430
ReduceQStr
static const char *const ReduceQStr[]
Definition: regparse.c:5258
ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR
#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR
Definition: oniguruma.h:434
NENCLOSE
#define NENCLOSE(node)
Definition: regparse.h:77
ONIG_SYN_OP_ESC_W_WORD
#define ONIG_SYN_OP_ESC_W_WORD
Definition: oniguruma.h:438
ONIG_SYN_OP2_QMARK_LPAREN_CONDITION
#define ONIG_SYN_OP2_QMARK_LPAREN_CONDITION
Definition: oniguruma.h:482
node_new_str_raw
static Node * node_new_str_raw(UChar *s, UChar *end)
Definition: regparse.c:1554
ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY
#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY
Definition: oniguruma.h:469
ONIG_OPTION_ASCII_RANGE
#define ONIG_OPTION_ASCII_RANGE
Definition: oniguruma.h:368
OnigToken::c
int c
Definition: regparse.c:2357
StrNode::s
UChar * s
Definition: regparse.h:167
ONIGERR_END_PATTERN_AT_META
#define ONIGERR_END_PATTERN_AT_META
Definition: oniguruma.h:545
Bits
unsigned char Bits
Definition: regint.h:397
ANCHOR_END_LINE
#define ANCHOR_END_LINE
Definition: regint.h:503
ONIG_SYN_OP_QMARK_ZERO_ONE
#define ONIG_SYN_OP_QMARK_ZERO_ONE
Definition: oniguruma.h:426
onig_st_init_strend_table_with_size
hash_table_type * onig_st_init_strend_table_with_size(st_index_t size)
Definition: regparse.c:367
ANCHOR_PREC_READ
#define ANCHOR_PREC_READ
Definition: regint.h:509
NT_QTFR
#define NT_QTFR
Definition: regparse.h:43
ONIG_MAX_MULTI_BYTE_RANGES_NUM
#define ONIG_MAX_MULTI_BYTE_RANGES_NUM
Definition: oniguruma.h:343
CCVALTYPE
CCVALTYPE
Definition: regparse.c:4376
onigenc_strlen
int onigenc_strlen(OnigEncoding enc, const UChar *p, const UChar *end)
Definition: regenc.c:123
tok
#define tok()
Definition: ripper.c:12254
node_linebreak
static int node_linebreak(Node **np, ScanEnv *env)
Definition: regparse.c:5538
IS_SINGLELINE
#define IS_SINGLELINE(option)
Definition: regint.h:359
CClassNode
Definition: regint.h:774
ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF
#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF
Definition: oniguruma.h:423
i_free_shared_class
static int i_free_shared_class(type_cclass_key *key, Node *node, void *arg ARG_UNUSED)
Definition: regparse.c:5396
GET_CODE_POINT
#define GET_CODE_POINT(code, p)
Definition: regint.h:667
ONIGENC_CTYPE_CNTRL
#define ONIGENC_CTYPE_CNTRL
Definition: oniguruma.h:197
bbuf_free
static void bbuf_free(BBuf *bbuf)
Definition: regparse.c:109
ONIG_SYN_OP2_QMARK_GROUP_EFFECT
#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT
Definition: oniguruma.h:454
rb_compile_warn
void rb_compile_warn(const char *file, int line, const char *fmt,...)
Definition: error.c:179
MC_ANYCHAR_ANYTIME
#define MC_ANYCHAR_ANYTIME(syn)
Definition: regint.h:720
onig_node_new_alt
Node * onig_node_new_alt(Node *left, Node *right)
Definition: regparse.c:1279
ONIGENC_CODE_RANGE_TO
#define ONIGENC_CODE_RANGE_TO(range, i)
Definition: oniguruma.h:139
onig_st_insert_strend
int onig_st_insert_strend(hash_table_type *table, const UChar *str_key, const UChar *end_key, hash_data_type value)
Definition: regparse.c:391
ONIG_SYN_BACKSLASH_ESCAPE_IN_CC
#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC
Definition: oniguruma.h:502
BIT_STATUS_ON_AT_SIMPLE
#define BIT_STATUS_ON_AT_SIMPLE(stats, n)
Definition: regint.h:345
SCANENV_MEMNODES_SIZE
#define SCANENV_MEMNODES_SIZE
Definition: regparse.h:280
ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE
#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE
Definition: oniguruma.h:565
NameEntry::back_alloc
int back_alloc
Definition: regparse.c:418
TK_CC_CC_OPEN
Definition: regparse.c:2347
OnigToken::ascii_range
int ascii_range
Definition: regparse.c:2361
is_onechar_cclass
static int is_onechar_cclass(CClassNode *cc, OnigCodePoint *code)
Definition: regparse.c:5689
ONIGENC_CODE_TO_MBC_MAXLEN
#define ONIGENC_CODE_TO_MBC_MAXLEN
Definition: oniguruma.h:189
TokenSyms
TokenSyms
Definition: regparse.c:2319
OnigSyntaxType
Definition: oniguruma.h:380
type_type_cclass_hash
static const struct st_hash_type type_type_cclass_hash
Definition: regparse.c:5387
TK_BACKREF
Definition: regparse.c:2327
ONIG_ENCODING_ASCII
#define ONIG_ENCODING_ASCII
Definition: oniguruma.h:183
BBUF_MOVE_RIGHT
#define BBUF_MOVE_RIGHT(buf, from, to, n)
Definition: regint.h:468
st_index_t
st_data_t st_index_t
Definition: st.h:48
ONIG_SYN_OP_QMARK_NON_GREEDY
#define ONIG_SYN_OP_QMARK_NON_GREEDY
Definition: oniguruma.h:445
re_pattern_buffer
Definition: oniguruma.h:658
ONIG_SYN_WARN_CC_DUP
#define ONIG_SYN_WARN_CC_DUP
Definition: oniguruma.h:508
NST_RECURSION
#define NST_RECURSION
Definition: regparse.h:130
PFETCH
#define PFETCH(c)
Definition: regparse.c:278
ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS
#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS
Definition: oniguruma.h:556
ANCHOR_BEGIN_POSITION
#define ANCHOR_BEGIN_POSITION
Definition: regint.h:500
INamesArg::enc
OnigEncoding enc
Definition: regparse.c:518
ONIGENC_CTYPE_ALNUM
#define ONIGENC_CTYPE_ALNUM
Definition: oniguruma.h:207
ScanEnv::reg
regex_t * reg
Definition: regparse.h:298
ONIG_SYN_OP_DECIMAL_BACKREF
#define ONIG_SYN_OP_DECIMAL_BACKREF
Definition: oniguruma.h:436
CLOSE_BRACKET_WITHOUT_ESC_WARN
static void CLOSE_BRACKET_WITHOUT_ESC_WARN(ScanEnv *env, UChar *c)
Definition: regparse.c:2923
OnigOptionType
unsigned int OnigOptionType
Definition: oniguruma.h:347
OnigToken::greedy
int greedy
Definition: regparse.c:2366
ReduceType
ReduceType
Definition: regparse.c:2249
NameTable
st_table NameTable
Definition: regparse.c:425
ONIGENC_CTYPE_WORD
#define ONIGENC_CTYPE_WORD
Definition: oniguruma.h:206
ANCHOR_NOT_WORD_BOUND
#define ANCHOR_NOT_WORD_BOUND
Definition: regint.h:506
TK_CC_OPEN
Definition: regparse.c:2336
ScanEnv::num_named
int num_named
Definition: regparse.h:305
ONIG_SYN_OP2_ESC_V_VTAB
#define ONIG_SYN_OP2_ESC_V_VTAB
Definition: oniguruma.h:466
MC_ONE_OR_MORE_TIME
#define MC_ONE_OR_MORE_TIME(syn)
Definition: regint.h:719
ONIGENC_CTYPE_ALPHA
#define ONIGENC_CTYPE_ALPHA
Definition: oniguruma.h:195
SYN_GNU_REGEX_OP
#define SYN_GNU_REGEX_OP
Definition: regint.h:734
PFETCH_READY
#define PFETCH_READY
Definition: regparse.c:270
RQ_A
Definition: regparse.c:2252
OnigToken::prop
struct OnigToken::@142::@147 prop
ONIG_LAST_CODE_POINT
#define ONIG_LAST_CODE_POINT
Definition: regint.h:282
TK_CODE_POINT
Definition: regparse.c:2324
ONIGERR_INVALID_CHAR_PROPERTY_NAME
#define ONIGERR_INVALID_CHAR_PROPERTY_NAME
Definition: oniguruma.h:585
ONIG_SYN_OP_POSIX_BRACKET
#define ONIG_SYN_OP_POSIX_BRACKET
Definition: oniguruma.h:444
THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS
#define THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS
Definition: regparse.c:5348
GroupNumRemap
Definition: regparse.h:327
NBREF
#define NBREF(node)
Definition: regparse.h:75
NT_ALT
#define NT_ALT
Definition: regparse.h:47
_FreeNode::next
struct _FreeNode * next
Definition: regparse.c:1022
BIT_STATUS_CLEAR
#define BIT_STATUS_CLEAR(stats)
Definition: regint.h:333
ONIGERR_TOO_MANY_MULTI_BYTE_RANGES
#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES
Definition: oniguruma.h:569
set_quantifier
static int set_quantifier(Node *qnode, Node *target, int group, ScanEnv *env)
Definition: regparse.c:5263
i_apply_case_fold
static int i_apply_case_fold(OnigCodePoint from, OnigCodePoint to[], int to_len, void *arg)
Definition: regparse.c:5458
strcat_capa_from_static
static UChar * strcat_capa_from_static(UChar *dest, UChar *dest_end, const UChar *src, const UChar *src_end, size_t capa)
Definition: regparse.c:305
st_data_t
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:20
add_code_range_to_buf0
static int add_code_range_to_buf0(BBuf **pbuf, ScanEnv *env, OnigCodePoint from, OnigCodePoint to, int checkdup)
Definition: regparse.c:1736
__sFILE
Definition: vsnprintf.c:175
re_registers
Definition: oniguruma.h:612
NCAR
#define NCAR(node)
Definition: regparse.h:82
onigenc_get_prev_char_head
UChar * onigenc_get_prev_char_head(OnigEncoding enc, const UChar *start, const UChar *s, const UChar *end)
Definition: regenc.c:92
type_cclass_key::not
int not
Definition: regparse.c:5354
ONIG_SYN_OP_BRACKET_CC
#define ONIG_SYN_OP_BRACKET_CC
Definition: oniguruma.h:437
ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP
#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP
Definition: oniguruma.h:460
ONIGENC_CTYPE_UPPER
#define ONIGENC_CTYPE_UPPER
Definition: oniguruma.h:204
RQ_AQ
Definition: regparse.c:2253
TK_ANCHOR
Definition: regparse.c:2329
_BBuf
Definition: regint.h:418
IS_IGNORECASE
#define IS_IGNORECASE(option)
Definition: regint.h:361
CClassNode::bs
BitSet bs
Definition: regint.h:777
ONIGERR_END_PATTERN_AT_LEFT_BRACE
#define ONIGERR_END_PATTERN_AT_LEFT_BRACE
Definition: oniguruma.h:540
TK_QUOTE_OPEN
Definition: regparse.c:2337
st_hash_type
Definition: st.h:55
ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT
Definition: oniguruma.h:457
neg
#define neg(x)
Definition: time.c:171
ScanEnv::mem_nodes_static
Node * mem_nodes_static[SCANENV_MEMNODES_SIZE]
Definition: regparse.h:308
initialize_cclass
static void initialize_cclass(CClassNode *cc)
Definition: regparse.c:1150
ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME
Definition: oniguruma.h:496
ScanEnv::sourcefile
const char * sourcefile
Definition: regparse.h:317
BitSet
Bits BitSet[BITSET_SIZE]
Definition: regint.h:399
CCV_CLASS
Definition: regparse.c:4379
node_new_cclass_by_codepoint_range
static Node * node_new_cclass_by_codepoint_range(int not, OnigCodePoint sb_out, const OnigCodePoint ranges[])
Definition: regparse.c:1170
ONIGENC_CTYPE_DIGIT
#define ONIGENC_CTYPE_DIGIT
Definition: oniguruma.h:198
THREAD_ATOMIC_END
#define THREAD_ATOMIC_END
Definition: regint.h:119
parse_regexp
static int parse_regexp(Node **top, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:6263
node_new_quantifier
static Node * node_new_quantifier(int lower, int upper, int by_number)
Definition: regparse.c:1373
IS_NCCLASS_SHARE
#define IS_NCCLASS_SHARE(nd)
Definition: regint.h:766
ONIG_IS_OPTION_ON
#define ONIG_IS_OPTION_ON(options, option)
Definition: oniguruma.h:377
PUNFETCH
#define PUNFETCH
Definition: regparse.c:273
TK_CC_RANGE
Definition: regparse.c:2344
OnigTypeCClassTable
static st_table * OnigTypeCClassTable
Definition: regparse.c:5392
TK_LINEBREAK
Definition: regparse.c:2339
node_new_enclose
static Node * node_new_enclose(int type)
Definition: regparse.c:1399
NST_NAME_REF
#define NST_NAME_REF
Definition: regparse.h:134
OnigToken::anchor
struct OnigToken::@142::@143 anchor
IApplyCaseFoldArg
Definition: regparse.c:5450
parse_subexp
static int parse_subexp(Node **top, OnigToken *tok, int term, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:6215
TK_ALT
Definition: regparse.c:2333
node_new_call
static Node * node_new_call(UChar *name, UChar *name_end, int gnum)
Definition: regparse.c:1357
re_pattern_buffer::case_fold_flag
OnigCaseFoldType case_fold_flag
Definition: oniguruma.h:680
INamesArg::arg
void * arg
Definition: regparse.c:516
ONIG_SYN_OP_ESC_QMARK_ZERO_ONE
#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE
Definition: oniguruma.h:427
ONIG_SYN_OP_ESC_X_BRACE_HEX8
#define ONIG_SYN_OP_ESC_X_BRACE_HEX8
Definition: oniguruma.h:450
ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID
Definition: oniguruma.h:553
TK_CHAR
Definition: regparse.c:2322
node_new
static Node * node_new(void)
Definition: regparse.c:1128
NULL_NODE
#define NULL_NODE
Definition: regparse.h:278
PEND
#define PEND
Definition: regparse.c:272
ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT
#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT
Definition: oniguruma.h:507
INIT_MULTI_BYTE_RANGE_SIZE
#define INIT_MULTI_BYTE_RANGE_SIZE
SIZE_CODE_POINT
#define SIZE_CODE_POINT
Definition: regint.h:653
val
#define val
BBUF_INIT
#define BBUF_INIT(buf, size)
Definition: regint.h:424
ONIGENC_CTYPE_XDIGIT
#define ONIGENC_CTYPE_XDIGIT
Definition: oniguruma.h:205
ONIG_MAX_CAPTURE_GROUP_NUM
#define ONIG_MAX_CAPTURE_GROUP_NUM
Definition: oniguruma.h:341
RQ_PQ_Q
Definition: regparse.c:2256
SET_ENCLOSE_STATUS
#define SET_ENCLOSE_STATUS(node, f)
Definition: regparse.h:139
ScanEnv::syntax
const OnigSyntaxType * syntax
Definition: regparse.h:289
BACKREF_REL_TO_ABS
#define BACKREF_REL_TO_ABS(rel_no, env)
Definition: regparse.c:132
ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP
#define ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP
Definition: oniguruma.h:478
ONIGERR_MULTIPLEX_DEFINED_NAME
#define ONIGERR_MULTIPLEX_DEFINED_NAME
Definition: oniguruma.h:581
ARG_UNUSED
#define ARG_UNUSED
Definition: nkf.h:181
ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP
#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP
Definition: oniguruma.h:490
ONIGERR_TOO_LONG_WIDE_CHAR_VALUE
#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE
Definition: oniguruma.h:575
ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK
#define ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK
Definition: oniguruma.h:474
TK_POSIX_BRACKET_OPEN
Definition: regparse.c:2345
str_exist_check_with_esc
static int str_exist_check_with_esc(OnigCodePoint s[], int n, UChar *from, UChar *to, OnigCodePoint bad, OnigEncoding enc, const OnigSyntaxType *syn)
Definition: regparse.c:2981
add_code_range0
static int add_code_range0(BBuf **pbuf, ScanEnv *env, OnigCodePoint from, OnigCodePoint to, int checkdup)
Definition: regparse.c:1828
ONIG_SYN_OP_ESC_LPAREN_SUBEXP
#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP
Definition: oniguruma.h:433
node_new_ctype
static Node * node_new_ctype(int type, int not, int ascii_range)
Definition: regparse.c:1220
OnigToken::name_end
UChar * name_end
Definition: regparse.c:2381
POSIX_BRACKET_CHECK_LIMIT_LENGTH
#define POSIX_BRACKET_CHECK_LIMIT_LENGTH
INIT_NAME_BACKREFS_ALLOC_NUM
#define INIT_NAME_BACKREFS_ALLOC_NUM
Definition: regparse.c:412
OnigToken::ref1
int ref1
Definition: regparse.c:2371
node_str_cat_codepoint
static int node_str_cat_codepoint(Node *node, OnigEncoding enc, OnigCodePoint c)
Definition: regparse.c:1497
RQ_QQ
Definition: regparse.c:2254
ONIGERR_INVALID_BACKREF
#define ONIGERR_INVALID_BACKREF
Definition: oniguruma.h:572
TK_CC_AND
Definition: regparse.c:2346
MC_ESC
#define MC_ESC(syn)
Definition: regint.h:715
INamesArg
Definition: regparse.c:513
onig_name_to_backref_number
int onig_name_to_backref_number(regex_t *reg, const UChar *name, const UChar *name_end, OnigRegion *region)
Definition: regparse.c:870
fetch_token
static int fetch_token(OnigToken *tok, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:3316
BITSET_AT
#define BITSET_AT(bs, pos)
Definition: regint.h:412
ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE
#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE
Definition: oniguruma.h:566
BITS_IN_ROOM
#define BITS_IN_ROOM
Definition: regint.h:391
onig_free_shared_cclass_table
int onig_free_shared_cclass_table(void)
Definition: regparse.c:5409
scan_unsigned_hexadecimal_number
static int scan_unsigned_hexadecimal_number(UChar **src, UChar *end, int minlen, int maxlen, OnigEncoding enc)
Definition: regparse.c:1650
ONIG_MAX_BACKREF_NUM
#define ONIG_MAX_BACKREF_NUM
Definition: oniguruma.h:340
StrNode
Definition: regparse.h:165
ONIGERR_TOO_SHORT_MULTI_BYTE_STRING
#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING
Definition: oniguruma.h:570
QtfrNode::lower
int lower
Definition: regparse.h:178
NCCLASS
#define NCCLASS(node)
Definition: regparse.h:73
xmemcpy
#define xmemcpy
Definition: regint.h:182
IS_EXTEND
#define IS_EXTEND(option)
Definition: regint.h:362
TK_CHAR_TYPE
Definition: regparse.c:2326
CHECK_NULL_RETURN_MEMERR
#define CHECK_NULL_RETURN_MEMERR(p)
Definition: regint.h:279
ONIGERR_TOO_MANY_CAPTURE_GROUPS
#define ONIGERR_TOO_MANY_CAPTURE_GROUPS
Definition: oniguruma.h:586
onig_node_new_enclose
Node * onig_node_new_enclose(int type)
Definition: regparse.c:1416
NCTYPE
#define NCTYPE(node)
Definition: regparse.h:74
ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS
#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS
Definition: oniguruma.h:488
onig_set_verb_warn_func
void onig_set_verb_warn_func(OnigWarnFunc f)
Definition: regparse.c:101
strcat_capa
static UChar * strcat_capa(UChar *dest, UChar *dest_end, const UChar *src, const UChar *src_end, size_t capa)
Definition: regparse.c:288
NameEntry::name
UChar * name
Definition: regparse.c:415
ScanEnv::mem_alloc
int mem_alloc
Definition: regparse.h:307
get_name_end_code_point
static OnigCodePoint get_name_end_code_point(OnigCodePoint start)
Definition: regparse.c:2560
strdup_with_null
static UChar * strdup_with_null(OnigEncoding enc, UChar *s, UChar *end)
Definition: regparse.c:243
bbuf_clone
static int bbuf_clone(BBuf **rto, BBuf *from)
Definition: regparse.c:118
ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT
#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT
Definition: oniguruma.h:470
TK_ANYCHAR
Definition: regparse.c:2325
FreeNodeList
static FreeNode * FreeNodeList
Definition: regparse.c:1025
fetch_range_quantifier
static int fetch_range_quantifier(UChar **src, UChar *end, OnigToken *tok, ScanEnv *env)
Definition: regparse.c:2394
PPEEK_IS
#define PPEEK_IS(c)
Definition: regparse.c:285
ONIG_SYN_OP_ESC_D_DIGIT
#define ONIG_SYN_OP_ESC_D_DIGIT
Definition: oniguruma.h:442
IApplyCaseFoldArg::ptail
Node ** ptail
Definition: regparse.c:5454
if
if((ID)(DISPID) nameid!=nameid)
Definition: win32ole.c:770
new_code_range
static int new_code_range(BBuf **pbuf)
Definition: regparse.c:1718
INamesArg::ret
int ret
Definition: regparse.c:517
is_invalid_quantifier_target
#define is_invalid_quantifier_target(node)
Definition: regparse.c:2188
NT_LIST
#define NT_LIST
Definition: regparse.h:46
name_add
static int name_add(regex_t *reg, UChar *name, UChar *name_end, int backref, ScanEnv *env)
Definition: regparse.c:733
HashDataType
st_data_t HashDataType
Definition: regparse.c:426
OnigToken::s
UChar * s
Definition: regparse.c:2356
err
int err
Definition: win32.c:114
BITSET_IS_EMPTY
#define BITSET_IS_EMPTY(bs, empty)
Definition: regparse.c:156
NT_ANCHOR
#define NT_ANCHOR
Definition: regparse.h:45
ANCHOR_WORD_END
#define ANCHOR_WORD_END
Definition: regint.h:508
NSTRING_CLEAR_RAW
#define NSTRING_CLEAR_RAW(node)
Definition: regparse.h:105
XDIGITVAL
#define XDIGITVAL(enc, code)
Definition: regint.h:355
PosixBracketEntryType::name
const UChar * name
Definition: regenc.h:102
type_cclass_key
Definition: regparse.c:5352
add_code_range
static int add_code_range(BBuf **pbuf, ScanEnv *env, OnigCodePoint from, OnigCodePoint to)
Definition: regparse.c:1841
fetch_char_property_to_ctype
static int fetch_char_property_to_ctype(UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:4317
QtfrNode::upper
int upper
Definition: regparse.h:179
FreeNode
struct _FreeNode FreeNode
ONIG_SYNTAX_RUBY
#define ONIG_SYNTAX_RUBY
Definition: oniguruma.h:412
OnigSyntaxRuby
const OnigSyntaxType OnigSyntaxRuby
Definition: regparse.c:38
OnigToken::call
struct OnigToken::@142::@146 call
ONIGERR_UNDEFINED_NAME_REFERENCE
#define ONIGERR_UNDEFINED_NAME_REFERENCE
Definition: oniguruma.h:579
ONIGENC_CODE_TO_MBCLEN
#define ONIGENC_CODE_TO_MBCLEN(enc, code)
Definition: oniguruma.h:267
onig_node_conv_to_str_node
void onig_node_conv_to_str_node(Node *node, int flag)
Definition: regparse.c:1506
RQ_DEL
Definition: regparse.c:2251
USE_BACKREF_WITH_LEVEL
#define USE_BACKREF_WITH_LEVEL
Definition: regint.h:63
NT_STR
#define NT_STR
Definition: regparse.h:38
NQTFR
#define NQTFR(node)
Definition: regparse.h:76
onig_st_insert
#define onig_st_insert
Definition: regint.h:139
THREAD_ATOMIC_START
#define THREAD_ATOMIC_START
Definition: regint.h:118
func
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:113
OnigToken::u
union OnigToken::@142 u
and_code_range1
static int and_code_range1(BBuf **pbuf, ScanEnv *env, OnigCodePoint from1, OnigCodePoint to1, OnigCodePoint *data, int n)
Definition: regparse.c:1946
BITSET_SET_BIT_CHKDUP
#define BITSET_SET_BIT_CHKDUP(bs, pos)
Definition: regparse.c:151
BBUF_MOVE_LEFT_REDUCE
#define BBUF_MOVE_LEFT_REDUCE(buf, from, to)
Definition: regint.h:480
_Node
Definition: regparse.h:260
BitSetRef
Bits * BitSetRef
Definition: regint.h:400
IS_WORD_BOUND_ALL_RANGE
#define IS_WORD_BOUND_ALL_RANGE(option)
Definition: regint.h:372
ONIG_SYN_OP_ESC_X_HEX2
#define ONIG_SYN_OP_ESC_X_HEX2
Definition: oniguruma.h:449
re_pattern_buffer::name_table
void * name_table
Definition: oniguruma.h:681
StrNode::flag
unsigned int flag
Definition: regparse.h:169
re_pattern_buffer::num_mem
int num_mem
Definition: oniguruma.h:665
NT_CANY
#define NT_CANY
Definition: regparse.h:41
NST_NAMED_GROUP
#define NST_NAMED_GROUP
Definition: regparse.h:133
OnigToken::upper
int upper
Definition: regparse.c:2365
OnigToken::name
UChar * name
Definition: regparse.c:2380
ONIGERR_END_PATTERN_IN_GROUP
#define ONIGERR_END_PATTERN_IN_GROUP
Definition: oniguruma.h:557
onig_name_to_group_numbers
int onig_name_to_group_numbers(regex_t *reg, const UChar *name, const UChar *name_end, int **nums)
Definition: regparse.c:848
CClassNode::mbuf
BBuf * mbuf
Definition: regint.h:778
IApplyCaseFoldArg::cc
CClassNode * cc
Definition: regparse.c:5452
TK_CHAR_PROPERTY
Definition: regparse.c:2338
PosixBracketEntryType::ctype
int ctype
Definition: regenc.h:103
ODIGITVAL
#define ODIGITVAL(code)
Definition: regint.h:354
SWAP_BBUF_NOT
#define SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2)
Definition: regparse.c:1881
OnigToken::rel
int rel
Definition: regparse.c:2383
TK_KEEP
Definition: regparse.c:2341
ONIGENC_CODE_RANGE_FROM
#define ONIGENC_CODE_RANGE_FROM(range, i)
Definition: oniguruma.h:138
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
SYN_GNU_REGEX_BV
#define SYN_GNU_REGEX_BV
Definition: regint.h:747
ONIGENC_CTYPE_PRINT
#define ONIGENC_CTYPE_PRINT
Definition: oniguruma.h:201
OnigToken::type
enum TokenSyms type
Definition: regparse.c:2351
onig_is_code_in_cc
int onig_is_code_in_cc(OnigEncoding enc, OnigCodePoint code, CClassNode *cc)
Definition: regcomp.c:6072
ONIG_NO_SUPPORT_CONFIG
#define ONIG_NO_SUPPORT_CONFIG
Definition: oniguruma.h:525
ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META
#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META
Definition: oniguruma.h:465
NTYPE
#define NTYPE(node)
Definition: regparse.h:69
ANCHOR_LOOK_BEHIND_NOT
#define ANCHOR_LOOK_BEHIND_NOT
Definition: regint.h:512
type
int type
Definition: tcltklib.c:112
ScanEnv::backrefed_mem
BitStatusType backrefed_mem
Definition: regparse.h:293
NCALL
#define NCALL(node)
Definition: regparse.h:80
NQ_TARGET_ISNOT_EMPTY
#define NQ_TARGET_ISNOT_EMPTY
Definition: regparse.h:117
OnigToken::escaped
int escaped
Definition: regparse.c:2352
ONIG_SYN_STRICT_CHECK_BACKREF
#define ONIG_SYN_STRICT_CHECK_BACKREF
Definition: oniguruma.h:493
result
static VALUE result
Definition: nkf.c:40
ScanEnv::num_mem
int num_mem
Definition: regparse.h:303
or_cclass
static int or_cclass(CClassNode *dest, CClassNode *cc, ScanEnv *env)
Definition: regparse.c:2101
ONIGENC_CODE_TO_MBC
#define ONIGENC_CODE_TO_MBC(enc, code, buf)
Definition: oniguruma.h:268
onig_strncmp
int onig_strncmp(const UChar *s1, const UChar *s2, int n)
Definition: regparse.c:220
ONIG_SYN_ALLOW_INVALID_INTERVAL
#define ONIG_SYN_ALLOW_INVALID_INTERVAL
Definition: oniguruma.h:491
hash_data_type
st_data_t hash_data_type
Definition: regint.h:877
bitset_or
static void bitset_or(BitSetRef dest, BitSetRef bs)
Definition: regparse.c:206
onig_node_new_list
Node * onig_node_new_list(Node *left, Node *right)
Definition: regparse.c:1255
TK_RAW_BYTE
Definition: regparse.c:2321
str_end_cmp
static int str_end_cmp(st_data_t xp, st_data_t yp)
Definition: regparse.c:328
bad
#define bad(x)
Definition: _sdbm.c:125
st_str_end_key::s
const UChar * s
Definition: regparse.c:323
NT_CCLASS
#define NT_CCLASS
Definition: regparse.h:39
NODE_BACKREFS_SIZE
#define NODE_BACKREFS_SIZE
Definition: regparse.h:97
ONIGERR_PARSER_BUG
#define ONIGERR_PARSER_BUG
Definition: oniguruma.h:530
ANCHOR_SEMI_END_BUF
#define ANCHOR_SEMI_END_BUF
Definition: regint.h:502
ONIGENC_IS_CODE_NEWLINE
#define ONIGENC_IS_CODE_NEWLINE(enc, code)
Definition: oniguruma.h:274
onig_node_new_str
Node * onig_node_new_str(const UChar *s, const UChar *end)
Definition: regparse.c:1548
re_registers::beg
OnigPosition * beg
Definition: oniguruma.h:615
ONIGENC_CTYPE_SPACE
#define ONIGENC_CTYPE_SPACE
Definition: oniguruma.h:203
OnigToken::level
int level
Definition: regparse.c:2376
ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL
#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL
Definition: oniguruma.h:464
type_cclass_key::enc
OnigEncoding enc
Definition: regparse.c:5353
ScanEnv::error_end
UChar * error_end
Definition: regparse.h:297
ONIG_SYN_OP2_ESC_H_XDIGIT
#define ONIG_SYN_OP2_ESC_H_XDIGIT
Definition: oniguruma.h:472
onig_node_str_clear
void onig_node_str_clear(Node *node)
Definition: regparse.c:1516
ScanEnv::mem_nodes_dynamic
Node ** mem_nodes_dynamic
Definition: regparse.h:309
TK_OP_REPEAT
Definition: regparse.c:2330
ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR
#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR
Definition: oniguruma.h:468
ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET
#define ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET
Definition: oniguruma.h:481
names_clear
static int names_clear(regex_t *reg)
Definition: regparse.c:475
ONIG_OPTION_CAPTURE_GROUP
#define ONIG_OPTION_CAPTURE_GROUP
Definition: oniguruma.h:362
node_new_str_raw_char
static Node * node_new_str_raw_char(UChar c)
Definition: regparse.c:1569
ONIGENC_MBC_TO_CODE
#define ONIGENC_MBC_TO_CODE(enc, p, end)
Definition: oniguruma.h:266
ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC
#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC
Definition: oniguruma.h:504
ScanEnv::bt_mem_end
BitStatusType bt_mem_end
Definition: regparse.h:292
ONIGENC_IS_UNICODE
#define ONIGENC_IS_UNICODE(enc)
Definition: oniguruma.h:227
fetch_token_in_cc
static int fetch_token_in_cc(OnigToken *tok, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:3019
node_new_cclass
static Node * node_new_cclass(void)
Definition: regparse.c:1159
ONIGENC_MBC_MINLEN
#define ONIGENC_MBC_MINLEN(enc)
Definition: oniguruma.h:264
ENCLOSE_STOP_BACKTRACK
#define ENCLOSE_STOP_BACKTRACK
Definition: regparse.h:92
MIN
#define MIN(a, b)
Definition: regint.h:273
ONIG_SYN_OP_ESC_BRACE_INTERVAL
#define ONIG_SYN_OP_ESC_BRACE_INTERVAL
Definition: oniguruma.h:429
UChar
#define UChar
Definition: oniguruma.h:108
onigenc_step
UChar * onigenc_step(OnigEncoding enc, const UChar *p, const UChar *end, int n)
Definition: regenc.c:113
ONIGERR_EMPTY_CHAR_CLASS
#define ONIGERR_EMPTY_CHAR_CLASS
Definition: oniguruma.h:542
ScanEnv::enc
OnigEncoding enc
Definition: regparse.h:288
OnigToken::subtype
int subtype
Definition: regparse.c:2360
onig_node_free
void onig_node_free(Node *node)
Definition: regparse.c:1029
ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED
Definition: oniguruma.h:552
NANCHOR
#define NANCHOR(node)
Definition: regparse.h:78
ONIG_SYN_OP2_OPTION_PERL
#define ONIG_SYN_OP2_OPTION_PERL
Definition: oniguruma.h:455
NT_BREF
#define NT_BREF
Definition: regparse.h:42
ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV
#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV
Definition: oniguruma.h:492
and_cclass
static int and_cclass(CClassNode *dest, CClassNode *cc, ScanEnv *env)
Definition: regparse.c:2043
MC_ZERO_OR_ONE_TIME
#define MC_ZERO_OR_ONE_TIME(syn)
Definition: regint.h:718
bitset_copy
static void bitset_copy(BitSetRef dest, BitSetRef bs)
Definition: regparse.c:213
i_free_name_entry
static int i_free_name_entry(UChar *key, NameEntry *e, void *arg ARG_UNUSED)
Definition: regparse.c:465
ONIG_SYN_OP_ESC_B_WORD_BOUND
#define ONIG_SYN_OP_ESC_B_WORD_BOUND
Definition: oniguruma.h:440
top
unsigned int top
Definition: nkf.c:4309
CHECK_NULL_RETURN
#define CHECK_NULL_RETURN(p)
Definition: regint.h:278
str_node_can_be_split
static int str_node_can_be_split(StrNode *sn, OnigEncoding enc)
Definition: regparse.c:1596
countbits
static int countbits(unsigned int bits)
Definition: regparse.c:5679
node_new_option
static Node * node_new_option(OnigOptionType option)
Definition: regparse.c:1436
conv_backslash_value
static int conv_backslash_value(int c, ScanEnv *env)
Definition: regparse.c:2162
onig_noname_group_capture_is_active
int onig_noname_group_capture_is_active(regex_t *reg)
Definition: regparse.c:924
MBCODE_START_POS
#define MBCODE_START_POS(enc)
Definition: regparse.c:137
size
int size
Definition: encoding.c:49
CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
#define CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
Definition: regparse.c:35
NameEntry::name_len
size_t name_len
Definition: regparse.c:416
f
#define f
BBUF_ENSURE_SIZE
#define BBUF_ENSURE_SIZE(buf, size)
Definition: regint.h:438
ScanEnv
Definition: regparse.h:285
OnigToken::base
int base
Definition: regparse.c:2353
ONIG_SYN_OP_PLUS_ONE_INF
#define ONIG_SYN_OP_PLUS_ONE_INF
Definition: oniguruma.h:424
or_code_range_buf
static int or_code_range_buf(OnigEncoding enc, BBuf *bbuf1, int not1, BBuf *bbuf2, int not2, BBuf **pbuf, ScanEnv *env)
Definition: regparse.c:1889
PPEEK
#define PPEEK
Definition: regparse.c:284
_BBuf::used
unsigned int used
Definition: regint.h:420
ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP
#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP
Definition: oniguruma.h:495
ONIGENC_IS_CODE_DIGIT
#define ONIGENC_IS_CODE_DIGIT(enc, code)
Definition: oniguruma.h:296
ScanEnv::case_fold_flag
OnigCaseFoldType case_fold_flag
Definition: regparse.h:287
xmalloc
#define xmalloc
Definition: defines.h:108
OnigToken::by_name
int by_name
Definition: regparse.c:2373
scan_env_set_mem_node
static int scan_env_set_mem_node(ScanEnv *env, int num, Node *node)
Definition: regparse.c:1010
ONIG_SYN_OP_ESC_VBAR_ALT
#define ONIG_SYN_OP_ESC_VBAR_ALT
Definition: oniguruma.h:431
ANCHOR_PREC_READ_NOT
#define ANCHOR_PREC_READ_NOT
Definition: regint.h:510
ENCLOSE_CONDITION
#define ENCLOSE_CONDITION
Definition: regparse.h:93
onig_reduce_nested_quantifier
void onig_reduce_nested_quantifier(Node *pnode, Node *cnode)
Definition: regparse.c:2269
fetch_escaped_value
static int fetch_escaped_value(UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:2485
ENCLOSE_OPTION
#define ENCLOSE_OPTION
Definition: regparse.h:91
ONIG_SYN_OP_DOT_ANYCHAR
#define ONIG_SYN_OP_DOT_ANYCHAR
Definition: oniguruma.h:421
onig_verb_warn
static OnigWarnFunc onig_verb_warn
Definition: regparse.c:93
ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS
#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS
Definition: oniguruma.h:551
ONIGENC_APPLY_ALL_CASE_FOLD
#define ONIGENC_APPLY_ALL_CASE_FOLD(enc, case_fold_flag, f, arg)
Definition: oniguruma.h:238
onig_number_of_names
int onig_number_of_names(regex_t *reg)
Definition: regparse.c:584
fetch_name
static int fetch_name(OnigCodePoint start_code, UChar **src, UChar *end, UChar **rname_end, ScanEnv *env, int *rback_num, int ref)
Definition: regparse.c:2696
ONIG_SYN_WARN_CC_OP_NOT_ESCAPED
#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED
Definition: oniguruma.h:506
OnigToken
Definition: regparse.c:2350
ONIG_OPTION_MULTILINE
#define ONIG_OPTION_MULTILINE
Definition: oniguruma.h:355
onig_syntax_warn
static void onig_syntax_warn(ScanEnv *env, const char *fmt,...)
Definition: regparse.c:2896
BITSET_CLEAR_BIT
#define BITSET_CLEAR_BIT(bs, pos)
Definition: regint.h:414
parse_enclose
static int parse_enclose(Node **np, OnigToken *tok, int term, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:4835
RQ_ASIS
Definition: regparse.c:2250
node_str_cat_char
static int node_str_cat_char(Node *node, UChar c)
Definition: regparse.c:1488
key
uint8_t key[16]
Definition: random.c:1250
ONIGERR_END_PATTERN_AT_ESCAPE
#define ONIGERR_END_PATTERN_AT_ESCAPE
Definition: oniguruma.h:544
ONIGERR_MEMORY
#define ONIGERR_MEMORY
Definition: oniguruma.h:528
ONIG_OPTION_EXTEND
#define ONIG_OPTION_EXTEND
Definition: oniguruma.h:354
re_pattern_buffer::syntax
const OnigSyntaxType * syntax
Definition: oniguruma.h:679
ONIGERR_CONTROL_CODE_SYNTAX
#define ONIGERR_CONTROL_CODE_SYNTAX
Definition: oniguruma.h:548
_BBuf::p
UChar * p
Definition: regint.h:419
find_str_position
static UChar * find_str_position(OnigCodePoint s[], int n, UChar *from, UChar *to, UChar **next, OnigEncoding enc)
Definition: regparse.c:2952
RTEST
#define RTEST(v)
Definition: ruby.h:437
and_code_range_buf
static int and_code_range_buf(BBuf *bbuf1, int not1, BBuf *bbuf2, int not2, BBuf **pbuf, ScanEnv *env)
Definition: regparse.c:1986
hash_table_type
void hash_table_type
Definition: regint.h:874
OnigToken::backp
UChar * backp
Definition: regparse.c:2354
ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS
#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS
Definition: oniguruma.h:567
NSTR
#define NSTR(node)
Definition: regparse.h:72
list
struct rb_encoding_entry * list
Definition: encoding.c:47
IS_POSIX_BRACKET_ALL_RANGE
#define IS_POSIX_BRACKET_ALL_RANGE(option)
Definition: regint.h:371
name_find
static NameEntry * name_find(regex_t *reg, const UChar *name, const UChar *name_end)
Definition: regparse.c:501
CCS_RANGE
Definition: regparse.c:4371
REPEAT_INFINITE
#define REPEAT_INFINITE
Definition: regint.h:385
OnigToken::lower
int lower
Definition: regparse.c:2364
not_code_range_buf
static int not_code_range_buf(OnigEncoding enc, BBuf *bbuf, BBuf **pbuf, ScanEnv *env)
Definition: regparse.c:1847
IS_SYNTAX_OP2
#define IS_SYNTAX_OP2(syn, opm)
Definition: regparse.h:323
ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC
#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC
Definition: oniguruma.h:501
NameEntry::back_num
int back_num
Definition: regparse.c:417
type_cclass_key::type
int type
Definition: regparse.c:5355
ONIG_SYN_OP2_ESC_G_SUBEXP_CALL
#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL
Definition: oniguruma.h:462
ONIGERR_INVALID_POSIX_BRACKET_TYPE
#define ONIGERR_INVALID_POSIX_BRACKET_TYPE
Definition: oniguruma.h:559
i_names
static int i_names(UChar *key ARG_UNUSED, NameEntry *e, INamesArg *arg)
Definition: regparse.c:522
OnigToken::ctype
int ctype
Definition: regparse.c:2386
ScanEnv::option
OnigOptionType option
Definition: regparse.h:286
ONIG_INEFFECTIVE_META_CHAR
#define ONIG_INEFFECTIVE_META_CHAR
Definition: oniguruma.h:518
ONIG_NORMAL
#define ONIG_NORMAL
Definition: oniguruma.h:523
NODE_STR_MARGIN
#define NODE_STR_MARGIN
Definition: regparse.h:95
st.h
OnigToken::num
int num
Definition: regparse.c:2370
ONIGERR_EMPTY_GROUP_NAME
#define ONIGERR_EMPTY_GROUP_NAME
Definition: oniguruma.h:576
node_new_empty
static Node * node_new_empty(void)
Definition: regparse.c:1563
type_cclass_hash
static st_index_t type_cclass_hash(type_cclass_key *key)
Definition: regparse.c:5366
ONIGERR_TOO_BIG_NUMBER
#define ONIGERR_TOO_BIG_NUMBER
Definition: oniguruma.h:564
CCSTATE
CCSTATE
Definition: regparse.c:4369
PosixBracketEntryType
Definition: regenc.h:101
ONOFF
#define ONOFF(v, f, negative)
Definition: regparse.c:135
ONIGENC_CODE_RANGE_NUM
#define ONIGENC_CODE_RANGE_NUM(range)
Definition: oniguruma.h:137
add_code_range_to_buf
static int add_code_range_to_buf(BBuf **pbuf, ScanEnv *env, OnigCodePoint from, OnigCodePoint to)
Definition: regparse.c:1822
IS_QUANTIFIER_BY_NUMBER
#define IS_QUANTIFIER_BY_NUMBER(qn)
Definition: regparse.h:161
onig_st_add_direct
#define onig_st_add_direct
Definition: regint.h:142
OnigToken::not
int not
Definition: regparse.c:2387
QtfrNode::target
struct _Node * target
Definition: regparse.h:177
ONIGERR_TOO_SHORT_DIGITS
#define ONIGERR_TOO_SHORT_DIGITS
Definition: oniguruma.h:574
bitset_invert
static void bitset_invert(BitSetRef bs)
Definition: regparse.c:185
QtfrNode::greedy
int greedy
Definition: regparse.h:180
INIT_SCANENV_MEMNODES_ALLOC_SIZE
#define INIT_SCANENV_MEMNODES_ALLOC_SIZE
Definition: regparse.c:941
NST_BY_NUMBER
#define NST_BY_NUMBER
Definition: regparse.h:137
next_state_val
static int next_state_val(CClassNode *cc, OnigCodePoint *vs, OnigCodePoint v, int *vs_israw, int v_israw, enum CCVALTYPE intype, enum CCVALTYPE *type, enum CCSTATE *state, ScanEnv *env)
Definition: regparse.c:4406
ONIG_OPTION_DONT_CAPTURE_GROUP
#define ONIG_OPTION_DONT_CAPTURE_GROUP
Definition: oniguruma.h:361
CCV_SB
Definition: regparse.c:4377
onigenc_with_ascii_strncmp
int onigenc_with_ascii_strncmp(OnigEncoding enc, const UChar *p, const UChar *end, const UChar *sascii, int n)
Definition: regenc.c:854
ONIG_OPTION_POSIX_BRACKET_ALL_RANGE
#define ONIG_OPTION_POSIX_BRACKET_ALL_RANGE
Definition: oniguruma.h:369
ONIG_SYN_OP_ESC_CONTROL_CHARS
#define ONIG_SYN_OP_ESC_CONTROL_CHARS
Definition: oniguruma.h:446
onig_parse_make_tree
int onig_parse_make_tree(Node **root, const UChar *pattern, const UChar *end, regex_t *reg, ScanEnv *env)
Definition: regparse.c:6291
name
const char * name
Definition: nkf.c:208
NT_CALL
#define NT_CALL
Definition: regparse.h:48
xrealloc
#define xrealloc
Definition: defines.h:111
DIGITVAL
#define DIGITVAL(code)
Definition: regint.h:353
onig_scan_unsigned_number
int onig_scan_unsigned_number(UChar **src, const UChar *end, OnigEncoding enc)
Definition: regparse.c:1623
TK_EOT
Definition: regparse.c:2320
onig_st_free_table
#define onig_st_free_table
Definition: regint.h:143
NSTRING_SET_RAW
#define NSTRING_SET_RAW(node)
Definition: regparse.h:104
NT_CTYPE
#define NT_CTYPE
Definition: regparse.h:40
ONIG_OPTION_WORD_BOUND_ALL_RANGE
#define ONIG_OPTION_WORD_BOUND_ALL_RANGE
Definition: oniguruma.h:370
ONIG_OPTION_IGNORECASE
#define ONIG_OPTION_IGNORECASE
Definition: oniguruma.h:353
IApplyCaseFoldArg::env
ScanEnv * env
Definition: regparse.c:5451
ONIG_SYN_OP_LINE_ANCHOR
#define ONIG_SYN_OP_LINE_ANCHOR
Definition: oniguruma.h:443
ANCHOR_BEGIN_BUF
#define ANCHOR_BEGIN_BUF
Definition: regint.h:498
TK_SUBEXP_CLOSE
Definition: regparse.c:2335
NameEntry::back_ref1
int back_ref1
Definition: regparse.c:419
BIT_STATUS_BITS_NUM
#define BIT_STATUS_BITS_NUM
Definition: regint.h:332
ONIG_SYN_OP_ESC_S_WHITE_SPACE
#define ONIG_SYN_OP_ESC_S_WHITE_SPACE
Definition: oniguruma.h:441
re_pattern_buffer::enc
OnigEncoding enc
Definition: oniguruma.h:677
node_new_backref
static Node * node_new_backref(int back_num, int *backrefs, int by_name, int exist_level, int nest_level, ScanEnv *env)
Definition: regparse.c:1305
IS_NOT_NULL
#define IS_NOT_NULL(p)
Definition: regint.h:277
node_new_enclose_memory
static Node * node_new_enclose_memory(OnigOptionType option, int is_named)
Definition: regparse.c:1422
ONIGERR_END_PATTERN_AT_CONTROL
#define ONIGERR_END_PATTERN_AT_CONTROL
Definition: oniguruma.h:546
st_str_end_key::end
const UChar * end
Definition: regparse.c:324
PosixBracketEntryType::len
short int len
Definition: regenc.h:104
CCS_COMPLETE
Definition: regparse.c:4372
ANCHOR_LOOK_BEHIND
#define ANCHOR_LOOK_BEHIND
Definition: regint.h:511
OnigToken::possessive
int possessive
Definition: regparse.c:2367
ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL
Definition: oniguruma.h:458
ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE
#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE
Definition: oniguruma.h:549
onig_strcpy
void onig_strcpy(UChar *dest, const UChar *src, const UChar *end)
Definition: regparse.c:232
next_state_class
static int next_state_class(CClassNode *cc, OnigCodePoint *vs, enum CCVALTYPE *type, enum CCSTATE *state, ScanEnv *env)
Definition: regparse.c:4383
xfree
void void xfree(void *)
POSIX_BRACKET_NAME_MIN_LEN
#define POSIX_BRACKET_NAME_MIN_LEN
ONIGERR_UNMATCHED_CLOSE_PARENTHESIS
#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS
Definition: oniguruma.h:555
UNKNOWN_ESC_WARN
static void UNKNOWN_ESC_WARN(ScanEnv *env, int c)
Definition: regparse.c:2945
ScanEnv::bt_mem_start
BitStatusType bt_mem_start
Definition: regparse.h:291
ONIGERR_PREMATURE_END_OF_CHAR_CLASS
#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS
Definition: oniguruma.h:543
ONIGENC_CTYPE_GRAPH
#define ONIGENC_CTYPE_GRAPH
Definition: oniguruma.h:199
CCS_START
Definition: regparse.c:4373
ONIGERR_INVALID_CODE_POINT_VALUE
#define ONIGERR_INVALID_CODE_POINT_VALUE
Definition: oniguruma.h:587
ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END
#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END
Definition: oniguruma.h:439
QtfrNode
Definition: regparse.h:174
ONIGENC_IS_SINGLEBYTE
#define ONIGENC_IS_SINGLEBYTE(enc)
Definition: oniguruma.h:218
IS_MC_ESC_CODE
#define IS_MC_ESC_CODE(code, syn)
Definition: regint.h:722
ANCHOR_WORD_BOUND
#define ANCHOR_WORD_BOUND
Definition: regint.h:505
ONIGENC_GET_CTYPE_CODE_RANGE
#define ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, sbout, ranges)
Definition: oniguruma.h:303
ONIG_SYN_OP_ESC_C_CONTROL
#define ONIG_SYN_OP_ESC_C_CONTROL
Definition: oniguruma.h:447
ANCHOR_KEEP
#define ANCHOR_KEEP
Definition: regint.h:517
ONIGERR_INVALID_REPEAT_RANGE_PATTERN
#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN
Definition: oniguruma.h:561
re_pattern_buffer::options
OnigOptionType options
Definition: oniguruma.h:678
env
#define env
code_exist_check
static int code_exist_check(OnigCodePoint c, UChar *from, UChar *end, int ignore_escaped, ScanEnv *env)
Definition: regparse.c:4481
MAX
#define MAX(a, b)
Definition: regint.h:274
onig_renumber_name_table
int onig_renumber_name_table(regex_t *reg, GroupNumRemap *map)
Definition: regparse.c:572
NULL
#define NULL
Definition: _sdbm.c:103
ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC
#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC
Definition: oniguruma.h:503
add_ctype_to_cc
static int add_ctype_to_cc(CClassNode *cc, int ctype, int not, int char_prop, ScanEnv *env)
Definition: regparse.c:4113
CCV_CODE_POINT
Definition: regparse.c:4378
node_new_str
static Node * node_new_str(const UChar *s, const UChar *end)
Definition: regparse.c:1530
NCDR
#define NCDR(node)
Definition: regparse.h:83
onig_st_foreach
#define onig_st_foreach
Definition: regint.h:141
st_table::num_entries
st_index_t num_entries
Definition: st.h:85
MC_ANYCHAR
#define MC_ANYCHAR(syn)
Definition: regint.h:716
ScanEnv::warnings_flag
int warnings_flag
Definition: regparse.h:316
ruby_verbose
#define ruby_verbose
Definition: ruby.h:1475
OnigDefaultSyntax
const OnigSyntaxType * OnigDefaultSyntax
Definition: regparse.c:80
ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER
#define ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER
Definition: oniguruma.h:475
ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND
#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND
Definition: oniguruma.h:494
IS_ASCII_RANGE
#define IS_ASCII_RANGE(option)
Definition: regint.h:370
ONIGENC_CTYPE_LOWER
#define ONIGENC_CTYPE_LOWER
Definition: oniguruma.h:200
onig_st_lookup
#define onig_st_lookup
Definition: regint.h:140
node_new_anychar
static Node * node_new_anychar(void)
Definition: regparse.c:1233
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:223
ONIGENC_CTYPE_ASCII
#define ONIGENC_CTYPE_ASCII
Definition: oniguruma.h:208
SET_NTYPE
#define SET_NTYPE(node, ntype)
Definition: regparse.h:70
ONIG_SYN_OP_LPAREN_SUBEXP
#define ONIG_SYN_OP_LPAREN_SUBEXP
Definition: oniguruma.h:432
str_node_split_last_char
static Node * str_node_split_last_char(StrNode *sn, OnigEncoding enc)
Definition: regparse.c:1578
add_ctype_to_cc_by_range
static int add_ctype_to_cc_by_range(CClassNode *cc, int ctype ARG_UNUSED, int not, ScanEnv *env, OnigCodePoint sb_out, const OnigCodePoint mbr[])
Definition: regparse.c:4040
NT_ENCLOSE
#define NT_ENCLOSE
Definition: regparse.h:44
ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY
#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY
Definition: oniguruma.h:584
ONIGERR_INVALID_GROUP_NAME
#define ONIGERR_INVALID_GROUP_NAME
Definition: oniguruma.h:577
OnigToken::exist_level
int exist_level
Definition: regparse.c:2375
ONIGENC_IS_CODE_XDIGIT
#define ONIGENC_IS_CODE_XDIGIT(enc, code)
Definition: oniguruma.h:298
NSTR_RAW
#define NSTR_RAW
Definition: regparse.h:99
CC_DUP_WARN
static void CC_DUP_WARN(ScanEnv *env)
Definition: regparse.c:2933
_FreeNode
Definition: regparse.c:1021
ONIGENC_IS_CODE_CTYPE
#define ONIGENC_IS_CODE_CTYPE(enc, code, ctype)
Definition: oniguruma.h:272
enclen
#define enclen(enc, p, e)
Definition: regenc.h:76
ONIGERR_META_CODE_SYNTAX
#define ONIGERR_META_CODE_SYNTAX
Definition: oniguruma.h:547
parse_exp
static int parse_exp(Node **np, OnigToken *tok, int term, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:5739
ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY
#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY
Definition: oniguruma.h:463
ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY
#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY
Definition: oniguruma.h:497
ONIGENC_PROPERTY_NAME_TO_CTYPE
#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc, p, end)
Definition: oniguruma.h:269
i_renumber_name
static int i_renumber_name(UChar *key ARG_UNUSED, NameEntry *e, GroupNumRemap *map)
Definition: regparse.c:555
onig_vsnprintf_with_pattern
void onig_vsnprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc, UChar *pat, UChar *pat_end, const UChar *fmt, va_list args)
Definition: regerror.c:323
parse_char_class
static int parse_char_class(Node **np, OnigToken *tok, UChar **src, UChar *end, ScanEnv *env)
Definition: regparse.c:4505
OnigEncodingTypeST
Definition: oniguruma.h:158
BITSET_CLEAR
#define BITSET_CLEAR(bs)
Definition: regint.h:404
ScanEnv::capture_history
BitStatusType capture_history
Definition: regparse.h:290
type_cclass_cmp
static int type_cclass_cmp(type_cclass_key *x, type_cclass_key *y)
Definition: regparse.c:5358
ONIGERR_INVALID_CHAR_IN_GROUP_NAME
#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME
Definition: oniguruma.h:578
ONIGENC_MBC_MAXLEN
#define ONIGENC_MBC_MAXLEN(enc)
Definition: oniguruma.h:262
BITSET_SIZE
#define BITSET_SIZE
Definition: regint.h:392
str_end_hash
static st_index_t str_end_hash(st_data_t xp)
Definition: regparse.c:352
ONIG_SYN_OP_ESC_PLUS_ONE_INF
#define ONIG_SYN_OP_ESC_PLUS_ONE_INF
Definition: oniguruma.h:425
onig_node_new_anchor
Node * onig_node_new_anchor(int type)
Definition: regparse.c:1291