Annotation of embedaddon/php/ext/mbstring/oniguruma/regparse.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>