|
Ruby 1.9.2p290(2011-07-09revision32553)
|
00001 /* -*- mode:c; c-file-style:"gnu" -*- */ 00002 /********************************************************************** 00003 regparse.c - Oniguruma (regular expression library) 00004 **********************************************************************/ 00005 /*- 00006 * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp> 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 1. Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * 2. Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the distribution. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 00022 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00024 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00025 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00026 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00027 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 */ 00030 00031 #include "regparse.h" 00032 00033 #define WARN_BUFSIZE 256 00034 00035 #define CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS 00036 00037 00038 const OnigSyntaxType OnigSyntaxRuby = { 00039 (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY | 00040 ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 | 00041 ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS | 00042 ONIG_SYN_OP_ESC_C_CONTROL ) 00043 & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END ) 00044 , ( ONIG_SYN_OP2_QMARK_GROUP_EFFECT | 00045 ONIG_SYN_OP2_OPTION_RUBY | 00046 ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP | ONIG_SYN_OP2_ESC_K_NAMED_BACKREF | 00047 ONIG_SYN_OP2_ESC_G_SUBEXP_CALL | 00048 ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY | 00049 ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT | 00050 ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT | 00051 ONIG_SYN_OP2_CCLASS_SET_OP | ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL | 00052 ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB | 00053 ONIG_SYN_OP2_ESC_H_XDIGIT ) 00054 , ( SYN_GNU_REGEX_BV | 00055 ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV | 00056 ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND | 00057 ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP | 00058 ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME | 00059 ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY | 00060 ONIG_SYN_WARN_CC_OP_NOT_ESCAPED | 00061 ONIG_SYN_WARN_CC_DUP | 00062 ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT ) 00063 , ONIG_OPTION_NONE 00064 , 00065 { 00066 (OnigCodePoint )'\\' /* esc */ 00067 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */ 00068 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */ 00069 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */ 00070 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */ 00071 , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */ 00072 } 00073 }; 00074 00075 const OnigSyntaxType* OnigDefaultSyntax = ONIG_SYNTAX_RUBY; 00076 00077 extern void onig_null_warn(const char* s ARG_UNUSED) { } 00078 00079 #ifdef DEFAULT_WARN_FUNCTION 00080 static OnigWarnFunc onig_warn = (OnigWarnFunc )DEFAULT_WARN_FUNCTION; 00081 #else 00082 static OnigWarnFunc onig_warn = onig_null_warn; 00083 #endif 00084 00085 #ifdef DEFAULT_VERB_WARN_FUNCTION 00086 static OnigWarnFunc onig_verb_warn = (OnigWarnFunc )DEFAULT_VERB_WARN_FUNCTION; 00087 #else 00088 static OnigWarnFunc onig_verb_warn = onig_null_warn; 00089 #endif 00090 00091 extern void onig_set_warn_func(OnigWarnFunc f) 00092 { 00093 onig_warn = f; 00094 } 00095 00096 extern void onig_set_verb_warn_func(OnigWarnFunc f) 00097 { 00098 onig_verb_warn = f; 00099 } 00100 00101 static void CC_DUP_WARN(ScanEnv *env); 00102 00103 static void 00104 bbuf_free(BBuf* bbuf) 00105 { 00106 if (IS_NOT_NULL(bbuf)) { 00107 if (IS_NOT_NULL(bbuf->p)) xfree(bbuf->p); 00108 xfree(bbuf); 00109 } 00110 } 00111 00112 static int 00113 bbuf_clone(BBuf** rto, BBuf* from) 00114 { 00115 int r; 00116 BBuf *to; 00117 00118 *rto = to = (BBuf* )xmalloc(sizeof(BBuf)); 00119 CHECK_NULL_RETURN_MEMERR(to); 00120 r = BBUF_INIT(to, from->alloc); 00121 if (r != 0) return r; 00122 to->used = from->used; 00123 xmemcpy(to->p, from->p, from->used); 00124 return 0; 00125 } 00126 00127 #define BACKREF_REL_TO_ABS(rel_no, env) \ 00128 ((env)->num_mem + 1 + (rel_no)) 00129 00130 #define ONOFF(v,f,negative) (negative) ? ((v) &= ~(f)) : ((v) |= (f)) 00131 00132 #define MBCODE_START_POS(enc) \ 00133 (OnigCodePoint )(ONIGENC_MBC_MINLEN(enc) > 1 ? 0 : 0x80) 00134 00135 #define SET_ALL_MULTI_BYTE_RANGE(enc, pbuf) \ 00136 add_code_range_to_buf(pbuf, env, MBCODE_START_POS(enc), ~((OnigCodePoint )0)) 00137 00138 #define ADD_ALL_MULTI_BYTE_RANGE(enc, mbuf) do {\ 00139 if (! ONIGENC_IS_SINGLEBYTE(enc)) {\ 00140 r = SET_ALL_MULTI_BYTE_RANGE(enc, &(mbuf));\ 00141 if (r) return r;\ 00142 }\ 00143 } while (0) 00144 00145 00146 #define BITSET_SET_BIT_CHKDUP(bs, pos) do { \ 00147 if (BITSET_AT(bs, pos)) CC_DUP_WARN(env); \ 00148 BS_ROOM(bs, pos) |= BS_BIT(pos); \ 00149 } while (0) 00150 00151 #define BITSET_IS_EMPTY(bs,empty) do {\ 00152 int i;\ 00153 empty = 1;\ 00154 for (i = 0; i < (int )BITSET_SIZE; i++) {\ 00155 if ((bs)[i] != 0) {\ 00156 empty = 0; break;\ 00157 }\ 00158 }\ 00159 } while (0) 00160 00161 static void 00162 bitset_set_range(ScanEnv *env, BitSetRef bs, int from, int to) 00163 { 00164 int i; 00165 for (i = from; i <= to && i < SINGLE_BYTE_SIZE; i++) { 00166 BITSET_SET_BIT_CHKDUP(bs, i); 00167 } 00168 } 00169 00170 #if 0 00171 static void 00172 bitset_set_all(BitSetRef bs) 00173 { 00174 int i; 00175 for (i = 0; i < BITSET_SIZE; i++) { bs[i] = ~((Bits )0); } 00176 } 00177 #endif 00178 00179 static void 00180 bitset_invert(BitSetRef bs) 00181 { 00182 int i; 00183 for (i = 0; i < (int )BITSET_SIZE; i++) { bs[i] = ~(bs[i]); } 00184 } 00185 00186 static void 00187 bitset_invert_to(BitSetRef from, BitSetRef to) 00188 { 00189 int i; 00190 for (i = 0; i < (int )BITSET_SIZE; i++) { to[i] = ~(from[i]); } 00191 } 00192 00193 static void 00194 bitset_and(BitSetRef dest, BitSetRef bs) 00195 { 00196 int i; 00197 for (i = 0; i < (int )BITSET_SIZE; i++) { dest[i] &= bs[i]; } 00198 } 00199 00200 static void 00201 bitset_or(BitSetRef dest, BitSetRef bs) 00202 { 00203 int i; 00204 for (i = 0; i < (int )BITSET_SIZE; i++) { dest[i] |= bs[i]; } 00205 } 00206 00207 static void 00208 bitset_copy(BitSetRef dest, BitSetRef bs) 00209 { 00210 int i; 00211 for (i = 0; i < (int )BITSET_SIZE; i++) { dest[i] = bs[i]; } 00212 } 00213 00214 extern int 00215 onig_strncmp(const UChar* s1, const UChar* s2, int n) 00216 { 00217 int x; 00218 00219 while (n-- > 0) { 00220 x = *s2++ - *s1++; 00221 if (x) return x; 00222 } 00223 return 0; 00224 } 00225 00226 extern void 00227 onig_strcpy(UChar* dest, const UChar* src, const UChar* end) 00228 { 00229 ptrdiff_t len = end - src; 00230 if (len > 0) { 00231 xmemcpy(dest, src, len); 00232 dest[len] = (UChar )0; 00233 } 00234 } 00235 00236 #ifdef USE_NAMED_GROUP 00237 static UChar* 00238 strdup_with_null(OnigEncoding enc, UChar* s, UChar* end) 00239 { 00240 ptrdiff_t slen; 00241 int term_len, i; 00242 UChar *r; 00243 00244 slen = end - s; 00245 term_len = ONIGENC_MBC_MINLEN(enc); 00246 00247 r = (UChar* )xmalloc(slen + term_len); 00248 CHECK_NULL_RETURN(r); 00249 xmemcpy(r, s, slen); 00250 00251 for (i = 0; i < term_len; i++) 00252 r[slen + i] = (UChar )0; 00253 00254 return r; 00255 } 00256 #endif 00257 00258 /* scan pattern methods */ 00259 #define PEND_VALUE 0 00260 00261 #define PFETCH_READY UChar* pfetch_prev 00262 #define PEND (p < end ? 0 : 1) 00263 #define PUNFETCH p = pfetch_prev 00264 #define PINC do { \ 00265 pfetch_prev = p; \ 00266 p += enclen(enc, p, end); \ 00267 } while (0) 00268 #define PFETCH(c) do { \ 00269 c = ((enc->max_enc_len == 1) ? *p : ONIGENC_MBC_TO_CODE(enc, p, end)); \ 00270 pfetch_prev = p; \ 00271 p += enclen(enc, p, end); \ 00272 } while (0) 00273 00274 #define PPEEK (p < end ? ONIGENC_MBC_TO_CODE(enc, p, end) : PEND_VALUE) 00275 #define PPEEK_IS(c) (PPEEK == (OnigCodePoint )c) 00276 00277 static UChar* 00278 strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_end, 00279 int capa) 00280 { 00281 UChar* r; 00282 00283 if (dest) 00284 r = (UChar* )xrealloc(dest, capa + 1); 00285 else 00286 r = (UChar* )xmalloc(capa + 1); 00287 00288 CHECK_NULL_RETURN(r); 00289 onig_strcpy(r + (dest_end - dest), src, src_end); 00290 return r; 00291 } 00292 00293 /* dest on static area */ 00294 static UChar* 00295 strcat_capa_from_static(UChar* dest, UChar* dest_end, 00296 const UChar* src, const UChar* src_end, int capa) 00297 { 00298 UChar* r; 00299 00300 r = (UChar* )xmalloc(capa + 1); 00301 CHECK_NULL_RETURN(r); 00302 onig_strcpy(r, dest, dest_end); 00303 onig_strcpy(r + (dest_end - dest), src, src_end); 00304 return r; 00305 } 00306 00307 00308 #ifdef USE_ST_LIBRARY 00309 00310 #include "ruby/st.h" 00311 00312 typedef struct { 00313 const UChar* s; 00314 const UChar* end; 00315 } st_str_end_key; 00316 00317 static int 00318 str_end_cmp(st_data_t xp, st_data_t yp) 00319 { 00320 const st_str_end_key *x, *y; 00321 const UChar *p, *q; 00322 int c; 00323 00324 x = (const st_str_end_key *)xp; 00325 y = (const st_str_end_key *)yp; 00326 if ((x->end - x->s) != (y->end - y->s)) 00327 return 1; 00328 00329 p = x->s; 00330 q = y->s; 00331 while (p < x->end) { 00332 c = (int )*p - (int )*q; 00333 if (c != 0) return c; 00334 00335 p++; q++; 00336 } 00337 00338 return 0; 00339 } 00340 00341 static st_index_t 00342 str_end_hash(st_data_t xp) 00343 { 00344 const st_str_end_key *x = (const st_str_end_key *)xp; 00345 const UChar *p; 00346 st_index_t val = 0; 00347 00348 p = x->s; 00349 while (p < x->end) { 00350 val = val * 997 + (int )*p++; 00351 } 00352 00353 return val + (val >> 5); 00354 } 00355 00356 extern hash_table_type* 00357 onig_st_init_strend_table_with_size(st_index_t size) 00358 { 00359 static const struct st_hash_type hashType = { 00360 str_end_cmp, 00361 str_end_hash, 00362 }; 00363 00364 return (hash_table_type* ) 00365 onig_st_init_table_with_size(&hashType, size); 00366 } 00367 00368 extern int 00369 onig_st_lookup_strend(hash_table_type* table, const UChar* str_key, 00370 const UChar* end_key, hash_data_type *value) 00371 { 00372 st_str_end_key key; 00373 00374 key.s = (UChar* )str_key; 00375 key.end = (UChar* )end_key; 00376 00377 return onig_st_lookup(table, (st_data_t )(&key), value); 00378 } 00379 00380 extern int 00381 onig_st_insert_strend(hash_table_type* table, const UChar* str_key, 00382 const UChar* end_key, hash_data_type value) 00383 { 00384 st_str_end_key* key; 00385 int result; 00386 00387 key = (st_str_end_key* )xmalloc(sizeof(st_str_end_key)); 00388 key->s = (UChar* )str_key; 00389 key->end = (UChar* )end_key; 00390 result = onig_st_insert(table, (st_data_t )key, value); 00391 if (result) { 00392 xfree(key); 00393 } 00394 return result; 00395 } 00396 00397 #endif /* USE_ST_LIBRARY */ 00398 00399 00400 #ifdef USE_NAMED_GROUP 00401 00402 #define INIT_NAME_BACKREFS_ALLOC_NUM 8 00403 00404 typedef struct { 00405 UChar* name; 00406 size_t name_len; /* byte length */ 00407 int back_num; /* number of backrefs */ 00408 int back_alloc; 00409 int back_ref1; 00410 int* back_refs; 00411 } NameEntry; 00412 00413 #ifdef USE_ST_LIBRARY 00414 00415 typedef st_table NameTable; 00416 typedef st_data_t HashDataType; /* 1.6 st.h doesn't define st_data_t type */ 00417 00418 #define NAMEBUF_SIZE 24 00419 #define NAMEBUF_SIZE_1 25 00420 00421 #ifdef ONIG_DEBUG 00422 static int 00423 i_print_name_entry(UChar* key, NameEntry* e, void* arg) 00424 { 00425 int i; 00426 FILE* fp = (FILE* )arg; 00427 00428 fprintf(fp, "%s: ", e->name); 00429 if (e->back_num == 0) 00430 fputs("-", fp); 00431 else if (e->back_num == 1) 00432 fprintf(fp, "%d", e->back_ref1); 00433 else { 00434 for (i = 0; i < e->back_num; i++) { 00435 if (i > 0) fprintf(fp, ", "); 00436 fprintf(fp, "%d", e->back_refs[i]); 00437 } 00438 } 00439 fputs("\n", fp); 00440 return ST_CONTINUE; 00441 } 00442 00443 extern int 00444 onig_print_names(FILE* fp, regex_t* reg) 00445 { 00446 NameTable* t = (NameTable* )reg->name_table; 00447 00448 if (IS_NOT_NULL(t)) { 00449 fprintf(fp, "name table\n"); 00450 onig_st_foreach(t, i_print_name_entry, (HashDataType )fp); 00451 fputs("\n", fp); 00452 } 00453 return 0; 00454 } 00455 #endif /* ONIG_DEBUG */ 00456 00457 static int 00458 i_free_name_entry(UChar* key, NameEntry* e, void* arg ARG_UNUSED) 00459 { 00460 xfree(e->name); 00461 if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs); 00462 xfree(key); 00463 xfree(e); 00464 return ST_DELETE; 00465 } 00466 00467 static int 00468 names_clear(regex_t* reg) 00469 { 00470 NameTable* t = (NameTable* )reg->name_table; 00471 00472 if (IS_NOT_NULL(t)) { 00473 onig_st_foreach(t, i_free_name_entry, 0); 00474 } 00475 return 0; 00476 } 00477 00478 extern int 00479 onig_names_free(regex_t* reg) 00480 { 00481 int r; 00482 NameTable* t; 00483 00484 r = names_clear(reg); 00485 if (r) return r; 00486 00487 t = (NameTable* )reg->name_table; 00488 if (IS_NOT_NULL(t)) onig_st_free_table(t); 00489 reg->name_table = (void* )NULL; 00490 return 0; 00491 } 00492 00493 static NameEntry* 00494 name_find(regex_t* reg, const UChar* name, const UChar* name_end) 00495 { 00496 NameEntry* e; 00497 NameTable* t = (NameTable* )reg->name_table; 00498 00499 e = (NameEntry* )NULL; 00500 if (IS_NOT_NULL(t)) { 00501 onig_st_lookup_strend(t, name, name_end, (HashDataType* )((void* )(&e))); 00502 } 00503 return e; 00504 } 00505 00506 typedef struct { 00507 int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*); 00508 regex_t* reg; 00509 void* arg; 00510 int ret; 00511 OnigEncoding enc; 00512 } INamesArg; 00513 00514 static int 00515 i_names(UChar* key ARG_UNUSED, NameEntry* e, INamesArg* arg) 00516 { 00517 int r = (*(arg->func))(e->name, 00518 e->name + e->name_len, 00519 e->back_num, 00520 (e->back_num > 1 ? e->back_refs : &(e->back_ref1)), 00521 arg->reg, arg->arg); 00522 if (r != 0) { 00523 arg->ret = r; 00524 return ST_STOP; 00525 } 00526 return ST_CONTINUE; 00527 } 00528 00529 extern int 00530 onig_foreach_name(regex_t* reg, 00531 int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg) 00532 { 00533 INamesArg narg; 00534 NameTable* t = (NameTable* )reg->name_table; 00535 00536 narg.ret = 0; 00537 if (IS_NOT_NULL(t)) { 00538 narg.func = func; 00539 narg.reg = reg; 00540 narg.arg = arg; 00541 narg.enc = reg->enc; /* should be pattern encoding. */ 00542 onig_st_foreach(t, i_names, (HashDataType )&narg); 00543 } 00544 return narg.ret; 00545 } 00546 00547 static int 00548 i_renumber_name(UChar* key ARG_UNUSED, NameEntry* e, GroupNumRemap* map) 00549 { 00550 int i; 00551 00552 if (e->back_num > 1) { 00553 for (i = 0; i < e->back_num; i++) { 00554 e->back_refs[i] = map[e->back_refs[i]].new_val; 00555 } 00556 } 00557 else if (e->back_num == 1) { 00558 e->back_ref1 = map[e->back_ref1].new_val; 00559 } 00560 00561 return ST_CONTINUE; 00562 } 00563 00564 extern int 00565 onig_renumber_name_table(regex_t* reg, GroupNumRemap* map) 00566 { 00567 NameTable* t = (NameTable* )reg->name_table; 00568 00569 if (IS_NOT_NULL(t)) { 00570 onig_st_foreach(t, i_renumber_name, (HashDataType )map); 00571 } 00572 return 0; 00573 } 00574 00575 00576 extern int 00577 onig_number_of_names(regex_t* reg) 00578 { 00579 NameTable* t = (NameTable* )reg->name_table; 00580 00581 if (IS_NOT_NULL(t)) 00582 return t->num_entries; 00583 else 00584 return 0; 00585 } 00586 00587 #else /* USE_ST_LIBRARY */ 00588 00589 #define INIT_NAMES_ALLOC_NUM 8 00590 00591 typedef struct { 00592 NameEntry* e; 00593 int num; 00594 int alloc; 00595 } NameTable; 00596 00597 #ifdef ONIG_DEBUG 00598 extern int 00599 onig_print_names(FILE* fp, regex_t* reg) 00600 { 00601 int i, j; 00602 NameEntry* e; 00603 NameTable* t = (NameTable* )reg->name_table; 00604 00605 if (IS_NOT_NULL(t) && t->num > 0) { 00606 fprintf(fp, "name table\n"); 00607 for (i = 0; i < t->num; i++) { 00608 e = &(t->e[i]); 00609 fprintf(fp, "%s: ", e->name); 00610 if (e->back_num == 0) { 00611 fputs("-", fp); 00612 } 00613 else if (e->back_num == 1) { 00614 fprintf(fp, "%d", e->back_ref1); 00615 } 00616 else { 00617 for (j = 0; j < e->back_num; j++) { 00618 if (j > 0) fprintf(fp, ", "); 00619 fprintf(fp, "%d", e->back_refs[j]); 00620 } 00621 } 00622 fputs("\n", fp); 00623 } 00624 fputs("\n", fp); 00625 } 00626 return 0; 00627 } 00628 #endif 00629 00630 static int 00631 names_clear(regex_t* reg) 00632 { 00633 int i; 00634 NameEntry* e; 00635 NameTable* t = (NameTable* )reg->name_table; 00636 00637 if (IS_NOT_NULL(t)) { 00638 for (i = 0; i < t->num; i++) { 00639 e = &(t->e[i]); 00640 if (IS_NOT_NULL(e->name)) { 00641 xfree(e->name); 00642 e->name = NULL; 00643 e->name_len = 0; 00644 e->back_num = 0; 00645 e->back_alloc = 0; 00646 if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs); 00647 e->back_refs = (int* )NULL; 00648 } 00649 } 00650 if (IS_NOT_NULL(t->e)) { 00651 xfree(t->e); 00652 t->e = NULL; 00653 } 00654 t->num = 0; 00655 } 00656 return 0; 00657 } 00658 00659 extern int 00660 onig_names_free(regex_t* reg) 00661 { 00662 int r; 00663 NameTable* t; 00664 00665 r = names_clear(reg); 00666 if (r) return r; 00667 00668 t = (NameTable* )reg->name_table; 00669 if (IS_NOT_NULL(t)) xfree(t); 00670 reg->name_table = NULL; 00671 return 0; 00672 } 00673 00674 static NameEntry* 00675 name_find(regex_t* reg, UChar* name, UChar* name_end) 00676 { 00677 int i, len; 00678 NameEntry* e; 00679 NameTable* t = (NameTable* )reg->name_table; 00680 00681 if (IS_NOT_NULL(t)) { 00682 len = name_end - name; 00683 for (i = 0; i < t->num; i++) { 00684 e = &(t->e[i]); 00685 if (len == e->name_len && onig_strncmp(name, e->name, len) == 0) 00686 return e; 00687 } 00688 } 00689 return (NameEntry* )NULL; 00690 } 00691 00692 extern int 00693 onig_foreach_name(regex_t* reg, 00694 int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg) 00695 { 00696 int i, r; 00697 NameEntry* e; 00698 NameTable* t = (NameTable* )reg->name_table; 00699 00700 if (IS_NOT_NULL(t)) { 00701 for (i = 0; i < t->num; i++) { 00702 e = &(t->e[i]); 00703 r = (*func)(e->name, e->name + e->name_len, e->back_num, 00704 (e->back_num > 1 ? e->back_refs : &(e->back_ref1)), 00705 reg, arg); 00706 if (r != 0) return r; 00707 } 00708 } 00709 return 0; 00710 } 00711 00712 extern int 00713 onig_number_of_names(regex_t* reg) 00714 { 00715 NameTable* t = (NameTable* )reg->name_table; 00716 00717 if (IS_NOT_NULL(t)) 00718 return t->num; 00719 else 00720 return 0; 00721 } 00722 00723 #endif /* else USE_ST_LIBRARY */ 00724 00725 static int 00726 name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env) 00727 { 00728 int alloc; 00729 NameEntry* e; 00730 NameTable* t = (NameTable* )reg->name_table; 00731 00732 if (name_end - name <= 0) 00733 return ONIGERR_EMPTY_GROUP_NAME; 00734 00735 e = name_find(reg, name, name_end); 00736 if (IS_NULL(e)) { 00737 #ifdef USE_ST_LIBRARY 00738 if (IS_NULL(t)) { 00739 t = onig_st_init_strend_table_with_size(5); 00740 reg->name_table = (void* )t; 00741 } 00742 e = (NameEntry* )xmalloc(sizeof(NameEntry)); 00743 CHECK_NULL_RETURN_MEMERR(e); 00744 00745 e->name = strdup_with_null(reg->enc, name, name_end); 00746 if (IS_NULL(e->name)) { 00747 xfree(e); 00748 return ONIGERR_MEMORY; 00749 } 00750 onig_st_insert_strend(t, e->name, (e->name + (name_end - name)), 00751 (HashDataType )e); 00752 00753 e->name_len = name_end - name; 00754 e->back_num = 0; 00755 e->back_alloc = 0; 00756 e->back_refs = (int* )NULL; 00757 00758 #else 00759 00760 if (IS_NULL(t)) { 00761 alloc = INIT_NAMES_ALLOC_NUM; 00762 t = (NameTable* )xmalloc(sizeof(NameTable)); 00763 CHECK_NULL_RETURN_MEMERR(t); 00764 t->e = NULL; 00765 t->alloc = 0; 00766 t->num = 0; 00767 00768 t->e = (NameEntry* )xmalloc(sizeof(NameEntry) * alloc); 00769 if (IS_NULL(t->e)) { 00770 xfree(t); 00771 return ONIGERR_MEMORY; 00772 } 00773 t->alloc = alloc; 00774 reg->name_table = t; 00775 goto clear; 00776 } 00777 else if (t->num == t->alloc) { 00778 int i; 00779 00780 alloc = t->alloc * 2; 00781 t->e = (NameEntry* )xrealloc(t->e, sizeof(NameEntry) * alloc); 00782 CHECK_NULL_RETURN_MEMERR(t->e); 00783 t->alloc = alloc; 00784 00785 clear: 00786 for (i = t->num; i < t->alloc; i++) { 00787 t->e[i].name = NULL; 00788 t->e[i].name_len = 0; 00789 t->e[i].back_num = 0; 00790 t->e[i].back_alloc = 0; 00791 t->e[i].back_refs = (int* )NULL; 00792 } 00793 } 00794 e = &(t->e[t->num]); 00795 t->num++; 00796 e->name = strdup_with_null(reg->enc, name, name_end); 00797 if (IS_NULL(e->name)) return ONIGERR_MEMORY; 00798 e->name_len = name_end - name; 00799 #endif 00800 } 00801 00802 if (e->back_num >= 1 && 00803 ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME)) { 00804 onig_scan_env_set_error_string(env, ONIGERR_MULTIPLEX_DEFINED_NAME, 00805 name, name_end); 00806 return ONIGERR_MULTIPLEX_DEFINED_NAME; 00807 } 00808 00809 e->back_num++; 00810 if (e->back_num == 1) { 00811 e->back_ref1 = backref; 00812 } 00813 else { 00814 if (e->back_num == 2) { 00815 alloc = INIT_NAME_BACKREFS_ALLOC_NUM; 00816 e->back_refs = (int* )xmalloc(sizeof(int) * alloc); 00817 CHECK_NULL_RETURN_MEMERR(e->back_refs); 00818 e->back_alloc = alloc; 00819 e->back_refs[0] = e->back_ref1; 00820 e->back_refs[1] = backref; 00821 } 00822 else { 00823 if (e->back_num > e->back_alloc) { 00824 alloc = e->back_alloc * 2; 00825 e->back_refs = (int* )xrealloc(e->back_refs, sizeof(int) * alloc); 00826 CHECK_NULL_RETURN_MEMERR(e->back_refs); 00827 e->back_alloc = alloc; 00828 } 00829 e->back_refs[e->back_num - 1] = backref; 00830 } 00831 } 00832 00833 return 0; 00834 } 00835 00836 extern int 00837 onig_name_to_group_numbers(regex_t* reg, const UChar* name, 00838 const UChar* name_end, int** nums) 00839 { 00840 NameEntry* e = name_find(reg, name, name_end); 00841 00842 if (IS_NULL(e)) return ONIGERR_UNDEFINED_NAME_REFERENCE; 00843 00844 switch (e->back_num) { 00845 case 0: 00846 *nums = 0; 00847 break; 00848 case 1: 00849 *nums = &(e->back_ref1); 00850 break; 00851 default: 00852 *nums = e->back_refs; 00853 break; 00854 } 00855 return e->back_num; 00856 } 00857 00858 extern int 00859 onig_name_to_backref_number(regex_t* reg, const UChar* name, 00860 const UChar* name_end, OnigRegion *region) 00861 { 00862 int i, n, *nums; 00863 00864 n = onig_name_to_group_numbers(reg, name, name_end, &nums); 00865 if (n < 0) 00866 return n; 00867 else if (n == 0) 00868 return ONIGERR_PARSER_BUG; 00869 else if (n == 1) 00870 return nums[0]; 00871 else { 00872 if (IS_NOT_NULL(region)) { 00873 for (i = n - 1; i >= 0; i--) { 00874 if (region->beg[nums[i]] != ONIG_REGION_NOTPOS) 00875 return nums[i]; 00876 } 00877 } 00878 return nums[n - 1]; 00879 } 00880 } 00881 00882 #else /* USE_NAMED_GROUP */ 00883 00884 extern int 00885 onig_name_to_group_numbers(regex_t* reg, const UChar* name, 00886 const UChar* name_end, int** nums) 00887 { 00888 return ONIG_NO_SUPPORT_CONFIG; 00889 } 00890 00891 extern int 00892 onig_name_to_backref_number(regex_t* reg, const UChar* name, 00893 const UChar* name_end, OnigRegion* region) 00894 { 00895 return ONIG_NO_SUPPORT_CONFIG; 00896 } 00897 00898 extern int 00899 onig_foreach_name(regex_t* reg, 00900 int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg) 00901 { 00902 return ONIG_NO_SUPPORT_CONFIG; 00903 } 00904 00905 extern int 00906 onig_number_of_names(regex_t* reg) 00907 { 00908 return 0; 00909 } 00910 #endif /* else USE_NAMED_GROUP */ 00911 00912 extern int 00913 onig_noname_group_capture_is_active(regex_t* reg) 00914 { 00915 if (ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_DONT_CAPTURE_GROUP)) 00916 return 0; 00917 00918 #ifdef USE_NAMED_GROUP 00919 if (onig_number_of_names(reg) > 0 && 00920 IS_SYNTAX_BV(reg->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) && 00921 !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) { 00922 return 0; 00923 } 00924 #endif 00925 00926 return 1; 00927 } 00928 00929 00930 #define INIT_SCANENV_MEMNODES_ALLOC_SIZE 16 00931 00932 static void 00933 scan_env_clear(ScanEnv* env) 00934 { 00935 int i; 00936 00937 BIT_STATUS_CLEAR(env->capture_history); 00938 BIT_STATUS_CLEAR(env->bt_mem_start); 00939 BIT_STATUS_CLEAR(env->bt_mem_end); 00940 BIT_STATUS_CLEAR(env->backrefed_mem); 00941 env->error = (UChar* )NULL; 00942 env->error_end = (UChar* )NULL; 00943 env->num_call = 0; 00944 env->num_mem = 0; 00945 #ifdef USE_NAMED_GROUP 00946 env->num_named = 0; 00947 #endif 00948 env->mem_alloc = 0; 00949 env->mem_nodes_dynamic = (Node** )NULL; 00950 00951 for (i = 0; i < SCANENV_MEMNODES_SIZE; i++) 00952 env->mem_nodes_static[i] = NULL_NODE; 00953 00954 #ifdef USE_COMBINATION_EXPLOSION_CHECK 00955 env->num_comb_exp_check = 0; 00956 env->comb_exp_max_regnum = 0; 00957 env->curr_max_regnum = 0; 00958 env->has_recursion = 0; 00959 #endif 00960 env->warnings_flag = 0; 00961 } 00962 00963 static int 00964 scan_env_add_mem_entry(ScanEnv* env) 00965 { 00966 int i, need, alloc; 00967 Node** p; 00968 00969 need = env->num_mem + 1; 00970 if (need >= SCANENV_MEMNODES_SIZE) { 00971 if (env->mem_alloc <= need) { 00972 if (IS_NULL(env->mem_nodes_dynamic)) { 00973 alloc = INIT_SCANENV_MEMNODES_ALLOC_SIZE; 00974 p = (Node** )xmalloc(sizeof(Node*) * alloc); 00975 xmemcpy(p, env->mem_nodes_static, 00976 sizeof(Node*) * SCANENV_MEMNODES_SIZE); 00977 } 00978 else { 00979 alloc = env->mem_alloc * 2; 00980 p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc); 00981 } 00982 CHECK_NULL_RETURN_MEMERR(p); 00983 00984 for (i = env->num_mem + 1; i < alloc; i++) 00985 p[i] = NULL_NODE; 00986 00987 env->mem_nodes_dynamic = p; 00988 env->mem_alloc = alloc; 00989 } 00990 } 00991 00992 env->num_mem++; 00993 return env->num_mem; 00994 } 00995 00996 static int 00997 scan_env_set_mem_node(ScanEnv* env, int num, Node* node) 00998 { 00999 if (env->num_mem >= num) 01000 SCANENV_MEM_NODES(env)[num] = node; 01001 else 01002 return ONIGERR_PARSER_BUG; 01003 return 0; 01004 } 01005 01006 01007 #ifdef USE_PARSE_TREE_NODE_RECYCLE 01008 typedef struct _FreeNode { 01009 struct _FreeNode* next; 01010 } FreeNode; 01011 01012 static FreeNode* FreeNodeList = (FreeNode* )NULL; 01013 #endif 01014 01015 extern void 01016 onig_node_free(Node* node) 01017 { 01018 start: 01019 if (IS_NULL(node)) return ; 01020 01021 switch (NTYPE(node)) { 01022 case NT_STR: 01023 if (NSTR(node)->capa != 0 && 01024 IS_NOT_NULL(NSTR(node)->s) && NSTR(node)->s != NSTR(node)->buf) { 01025 xfree(NSTR(node)->s); 01026 } 01027 break; 01028 01029 case NT_LIST: 01030 case NT_ALT: 01031 onig_node_free(NCAR(node)); 01032 { 01033 Node* next_node = NCDR(node); 01034 01035 #ifdef USE_PARSE_TREE_NODE_RECYCLE 01036 { 01037 FreeNode* n = (FreeNode* )node; 01038 01039 THREAD_ATOMIC_START; 01040 n->next = FreeNodeList; 01041 FreeNodeList = n; 01042 THREAD_ATOMIC_END; 01043 } 01044 #else 01045 xfree(node); 01046 #endif 01047 node = next_node; 01048 goto start; 01049 } 01050 break; 01051 01052 case NT_CCLASS: 01053 { 01054 CClassNode* cc = NCCLASS(node); 01055 01056 if (IS_NCCLASS_SHARE(cc)) return ; 01057 if (cc->mbuf) 01058 bbuf_free(cc->mbuf); 01059 } 01060 break; 01061 01062 case NT_QTFR: 01063 if (NQTFR(node)->target) 01064 onig_node_free(NQTFR(node)->target); 01065 break; 01066 01067 case NT_ENCLOSE: 01068 if (NENCLOSE(node)->target) 01069 onig_node_free(NENCLOSE(node)->target); 01070 break; 01071 01072 case NT_BREF: 01073 if (IS_NOT_NULL(NBREF(node)->back_dynamic)) 01074 xfree(NBREF(node)->back_dynamic); 01075 break; 01076 01077 case NT_ANCHOR: 01078 if (NANCHOR(node)->target) 01079 onig_node_free(NANCHOR(node)->target); 01080 break; 01081 } 01082 01083 #ifdef USE_PARSE_TREE_NODE_RECYCLE 01084 { 01085 FreeNode* n = (FreeNode* )node; 01086 01087 THREAD_ATOMIC_START; 01088 n->next = FreeNodeList; 01089 FreeNodeList = n; 01090 THREAD_ATOMIC_END; 01091 } 01092 #else 01093 xfree(node); 01094 #endif 01095 } 01096 01097 #ifdef USE_PARSE_TREE_NODE_RECYCLE 01098 extern int 01099 onig_free_node_list(void) 01100 { 01101 FreeNode* n; 01102 01103 /* THREAD_ATOMIC_START; */ 01104 while (IS_NOT_NULL(FreeNodeList)) { 01105 n = FreeNodeList; 01106 FreeNodeList = FreeNodeList->next; 01107 xfree(n); 01108 } 01109 /* THREAD_ATOMIC_END; */ 01110 return 0; 01111 } 01112 #endif 01113 01114 static Node* 01115 node_new(void) 01116 { 01117 Node* node; 01118 01119 #ifdef USE_PARSE_TREE_NODE_RECYCLE 01120 THREAD_ATOMIC_START; 01121 if (IS_NOT_NULL(FreeNodeList)) { 01122 node = (Node* )FreeNodeList; 01123 FreeNodeList = FreeNodeList->next; 01124 THREAD_ATOMIC_END; 01125 return node; 01126 } 01127 THREAD_ATOMIC_END; 01128 #endif 01129 01130 node = (Node* )xmalloc(sizeof(Node)); 01131 /* xmemset(node, 0, sizeof(Node)); */ 01132 return node; 01133 } 01134 01135 01136 static void 01137 initialize_cclass(CClassNode* cc) 01138 { 01139 BITSET_CLEAR(cc->bs); 01140 /* cc->base.flags = 0; */ 01141 cc->flags = 0; 01142 cc->mbuf = NULL; 01143 } 01144 01145 static Node* 01146 node_new_cclass(void) 01147 { 01148 Node* node = node_new(); 01149 CHECK_NULL_RETURN(node); 01150 01151 SET_NTYPE(node, NT_CCLASS); 01152 initialize_cclass(NCCLASS(node)); 01153 return node; 01154 } 01155 01156 static Node* 01157 node_new_cclass_by_codepoint_range(int not, OnigCodePoint sb_out, 01158 const OnigCodePoint ranges[]) 01159 { 01160 int n, i; 01161 CClassNode* cc; 01162 OnigCodePoint j; 01163 01164 Node* node = node_new_cclass(); 01165 CHECK_NULL_RETURN(node); 01166 01167 cc = NCCLASS(node); 01168 if (not != 0) NCCLASS_SET_NOT(cc); 01169 01170 BITSET_CLEAR(cc->bs); 01171 if (sb_out > 0 && IS_NOT_NULL(ranges)) { 01172 n = ONIGENC_CODE_RANGE_NUM(ranges); 01173 for (i = 0; i < n; i++) { 01174 for (j = ONIGENC_CODE_RANGE_FROM(ranges, i); 01175 j <= (OnigCodePoint )ONIGENC_CODE_RANGE_TO(ranges, i); j++) { 01176 if (j >= sb_out) goto sb_end; 01177 01178 BITSET_SET_BIT(cc->bs, j); 01179 } 01180 } 01181 } 01182 01183 sb_end: 01184 if (IS_NULL(ranges)) { 01185 is_null: 01186 cc->mbuf = NULL; 01187 } 01188 else { 01189 BBuf* bbuf; 01190 01191 n = ONIGENC_CODE_RANGE_NUM(ranges); 01192 if (n == 0) goto is_null; 01193 01194 bbuf = (BBuf* )xmalloc(sizeof(BBuf)); 01195 CHECK_NULL_RETURN(bbuf); 01196 bbuf->alloc = n + 1; 01197 bbuf->used = n + 1; 01198 bbuf->p = (UChar* )((void* )ranges); 01199 01200 cc->mbuf = bbuf; 01201 } 01202 01203 return node; 01204 } 01205 01206 static Node* 01207 node_new_ctype(int type, int not) 01208 { 01209 Node* node = node_new(); 01210 CHECK_NULL_RETURN(node); 01211 01212 SET_NTYPE(node, NT_CTYPE); 01213 NCTYPE(node)->ctype = type; 01214 NCTYPE(node)->not = not; 01215 return node; 01216 } 01217 01218 static Node* 01219 node_new_anychar(void) 01220 { 01221 Node* node = node_new(); 01222 CHECK_NULL_RETURN(node); 01223 01224 SET_NTYPE(node, NT_CANY); 01225 return node; 01226 } 01227 01228 static Node* 01229 node_new_list(Node* left, Node* right) 01230 { 01231 Node* node = node_new(); 01232 CHECK_NULL_RETURN(node); 01233 01234 SET_NTYPE(node, NT_LIST); 01235 NCAR(node) = left; 01236 NCDR(node) = right; 01237 return node; 01238 } 01239 01240 extern Node* 01241 onig_node_new_list(Node* left, Node* right) 01242 { 01243 return node_new_list(left, right); 01244 } 01245 01246 extern Node* 01247 onig_node_list_add(Node* list, Node* x) 01248 { 01249 Node *n; 01250 01251 n = onig_node_new_list(x, NULL); 01252 if (IS_NULL(n)) return NULL_NODE; 01253 01254 if (IS_NOT_NULL(list)) { 01255 while (IS_NOT_NULL(NCDR(list))) 01256 list = NCDR(list); 01257 01258 NCDR(list) = n; 01259 } 01260 01261 return n; 01262 } 01263 01264 extern Node* 01265 onig_node_new_alt(Node* left, Node* right) 01266 { 01267 Node* node = node_new(); 01268 CHECK_NULL_RETURN(node); 01269 01270 SET_NTYPE(node, NT_ALT); 01271 NCAR(node) = left; 01272 NCDR(node) = right; 01273 return node; 01274 } 01275 01276 extern Node* 01277 onig_node_new_anchor(int type) 01278 { 01279 Node* node = node_new(); 01280 CHECK_NULL_RETURN(node); 01281 01282 SET_NTYPE(node, NT_ANCHOR); 01283 NANCHOR(node)->type = type; 01284 NANCHOR(node)->target = NULL; 01285 NANCHOR(node)->char_len = -1; 01286 return node; 01287 } 01288 01289 static Node* 01290 node_new_backref(int back_num, int* backrefs, int by_name, 01291 #ifdef USE_BACKREF_WITH_LEVEL 01292 int exist_level, int nest_level, 01293 #endif 01294 ScanEnv* env) 01295 { 01296 int i; 01297 Node* node = node_new(); 01298 01299 CHECK_NULL_RETURN(node); 01300 01301 SET_NTYPE(node, NT_BREF); 01302 NBREF(node)->state = 0; 01303 NBREF(node)->back_num = back_num; 01304 NBREF(node)->back_dynamic = (int* )NULL; 01305 if (by_name != 0) 01306 NBREF(node)->state |= NST_NAME_REF; 01307 01308 #ifdef USE_BACKREF_WITH_LEVEL 01309 if (exist_level != 0) { 01310 NBREF(node)->state |= NST_NEST_LEVEL; 01311 NBREF(node)->nest_level = nest_level; 01312 } 01313 #endif 01314 01315 for (i = 0; i < back_num; i++) { 01316 if (backrefs[i] <= env->num_mem && 01317 IS_NULL(SCANENV_MEM_NODES(env)[backrefs[i]])) { 01318 NBREF(node)->state |= NST_RECURSION; /* /...(\1).../ */ 01319 break; 01320 } 01321 } 01322 01323 if (back_num <= NODE_BACKREFS_SIZE) { 01324 for (i = 0; i < back_num; i++) 01325 NBREF(node)->back_static[i] = backrefs[i]; 01326 } 01327 else { 01328 int* p = (int* )xmalloc(sizeof(int) * back_num); 01329 if (IS_NULL(p)) { 01330 onig_node_free(node); 01331 return NULL; 01332 } 01333 NBREF(node)->back_dynamic = p; 01334 for (i = 0; i < back_num; i++) 01335 p[i] = backrefs[i]; 01336 } 01337 return node; 01338 } 01339 01340 #ifdef USE_SUBEXP_CALL 01341 static Node* 01342 node_new_call(UChar* name, UChar* name_end, int gnum) 01343 { 01344 Node* node = node_new(); 01345 CHECK_NULL_RETURN(node); 01346 01347 SET_NTYPE(node, NT_CALL); 01348 NCALL(node)->state = 0; 01349 NCALL(node)->target = NULL_NODE; 01350 NCALL(node)->name = name; 01351 NCALL(node)->name_end = name_end; 01352 NCALL(node)->group_num = gnum; /* call by number if gnum != 0 */ 01353 return node; 01354 } 01355 #endif 01356 01357 static Node* 01358 node_new_quantifier(int lower, int upper, int by_number) 01359 { 01360 Node* node = node_new(); 01361 CHECK_NULL_RETURN(node); 01362 01363 SET_NTYPE(node, NT_QTFR); 01364 NQTFR(node)->state = 0; 01365 NQTFR(node)->target = NULL; 01366 NQTFR(node)->lower = lower; 01367 NQTFR(node)->upper = upper; 01368 NQTFR(node)->greedy = 1; 01369 NQTFR(node)->target_empty_info = NQ_TARGET_ISNOT_EMPTY; 01370 NQTFR(node)->head_exact = NULL_NODE; 01371 NQTFR(node)->next_head_exact = NULL_NODE; 01372 NQTFR(node)->is_refered = 0; 01373 if (by_number != 0) 01374 NQTFR(node)->state |= NST_BY_NUMBER; 01375 01376 #ifdef USE_COMBINATION_EXPLOSION_CHECK 01377 NQTFR(node)->comb_exp_check_num = 0; 01378 #endif 01379 01380 return node; 01381 } 01382 01383 static Node* 01384 node_new_enclose(int type) 01385 { 01386 Node* node = node_new(); 01387 CHECK_NULL_RETURN(node); 01388 01389 SET_NTYPE(node, NT_ENCLOSE); 01390 NENCLOSE(node)->type = type; 01391 NENCLOSE(node)->state = 0; 01392 NENCLOSE(node)->regnum = 0; 01393 NENCLOSE(node)->option = 0; 01394 NENCLOSE(node)->target = NULL; 01395 NENCLOSE(node)->call_addr = -1; 01396 NENCLOSE(node)->opt_count = 0; 01397 return node; 01398 } 01399 01400 extern Node* 01401 onig_node_new_enclose(int type) 01402 { 01403 return node_new_enclose(type); 01404 } 01405 01406 static Node* 01407 node_new_enclose_memory(OnigOptionType option, int is_named) 01408 { 01409 Node* node = node_new_enclose(ENCLOSE_MEMORY); 01410 CHECK_NULL_RETURN(node); 01411 if (is_named != 0) 01412 SET_ENCLOSE_STATUS(node, NST_NAMED_GROUP); 01413 01414 #ifdef USE_SUBEXP_CALL 01415 NENCLOSE(node)->option = option; 01416 #endif 01417 return node; 01418 } 01419 01420 static Node* 01421 node_new_option(OnigOptionType option) 01422 { 01423 Node* node = node_new_enclose(ENCLOSE_OPTION); 01424 CHECK_NULL_RETURN(node); 01425 NENCLOSE(node)->option = option; 01426 return node; 01427 } 01428 01429 extern int 01430 onig_node_str_cat(Node* node, const UChar* s, const UChar* end) 01431 { 01432 ptrdiff_t addlen = end - s; 01433 01434 if (addlen > 0) { 01435 ptrdiff_t len = NSTR(node)->end - NSTR(node)->s; 01436 01437 if (NSTR(node)->capa > 0 || (len + addlen > NODE_STR_BUF_SIZE - 1)) { 01438 UChar* p; 01439 ptrdiff_t capa = len + addlen + NODE_STR_MARGIN; 01440 01441 if (capa <= NSTR(node)->capa) { 01442 onig_strcpy(NSTR(node)->s + len, s, end); 01443 } 01444 else { 01445 if (NSTR(node)->s == NSTR(node)->buf) 01446 p = strcat_capa_from_static(NSTR(node)->s, NSTR(node)->end, 01447 s, end, capa); 01448 else 01449 p = strcat_capa(NSTR(node)->s, NSTR(node)->end, s, end, capa); 01450 01451 CHECK_NULL_RETURN_MEMERR(p); 01452 NSTR(node)->s = p; 01453 NSTR(node)->capa = capa; 01454 } 01455 } 01456 else { 01457 onig_strcpy(NSTR(node)->s + len, s, end); 01458 } 01459 NSTR(node)->end = NSTR(node)->s + len + addlen; 01460 } 01461 01462 return 0; 01463 } 01464 01465 extern int 01466 onig_node_str_set(Node* node, const UChar* s, const UChar* end) 01467 { 01468 onig_node_str_clear(node); 01469 return onig_node_str_cat(node, s, end); 01470 } 01471 01472 static int 01473 node_str_cat_char(Node* node, UChar c) 01474 { 01475 UChar s[1]; 01476 01477 s[0] = c; 01478 return onig_node_str_cat(node, s, s + 1); 01479 } 01480 01481 extern void 01482 onig_node_conv_to_str_node(Node* node, int flag) 01483 { 01484 SET_NTYPE(node, NT_STR); 01485 NSTR(node)->flag = flag; 01486 NSTR(node)->capa = 0; 01487 NSTR(node)->s = NSTR(node)->buf; 01488 NSTR(node)->end = NSTR(node)->buf; 01489 } 01490 01491 extern void 01492 onig_node_str_clear(Node* node) 01493 { 01494 if (NSTR(node)->capa != 0 && 01495 IS_NOT_NULL(NSTR(node)->s) && NSTR(node)->s != NSTR(node)->buf) { 01496 xfree(NSTR(node)->s); 01497 } 01498 01499 NSTR(node)->capa = 0; 01500 NSTR(node)->flag = 0; 01501 NSTR(node)->s = NSTR(node)->buf; 01502 NSTR(node)->end = NSTR(node)->buf; 01503 } 01504 01505 static Node* 01506 node_new_str(const UChar* s, const UChar* end) 01507 { 01508 Node* node = node_new(); 01509 CHECK_NULL_RETURN(node); 01510 01511 SET_NTYPE(node, NT_STR); 01512 NSTR(node)->capa = 0; 01513 NSTR(node)->flag = 0; 01514 NSTR(node)->s = NSTR(node)->buf; 01515 NSTR(node)->end = NSTR(node)->buf; 01516 if (onig_node_str_cat(node, s, end)) { 01517 onig_node_free(node); 01518 return NULL; 01519 } 01520 return node; 01521 } 01522 01523 extern Node* 01524 onig_node_new_str(const UChar* s, const UChar* end) 01525 { 01526 return node_new_str(s, end); 01527 } 01528 01529 static Node* 01530 node_new_str_raw(UChar* s, UChar* end) 01531 { 01532 Node* node = node_new_str(s, end); 01533 NSTRING_SET_RAW(node); 01534 return node; 01535 } 01536 01537 static Node* 01538 node_new_empty(void) 01539 { 01540 return node_new_str(NULL, NULL); 01541 } 01542 01543 static Node* 01544 node_new_str_raw_char(UChar c) 01545 { 01546 UChar p[1]; 01547 01548 p[0] = c; 01549 return node_new_str_raw(p, p + 1); 01550 } 01551 01552 static Node* 01553 str_node_split_last_char(StrNode* sn, OnigEncoding enc) 01554 { 01555 const UChar *p; 01556 Node* n = NULL_NODE; 01557 01558 if (sn->end > sn->s) { 01559 p = onigenc_get_prev_char_head(enc, sn->s, sn->end, sn->end); 01560 if (p && p > sn->s) { /* can be splitted. */ 01561 n = node_new_str(p, sn->end); 01562 if ((sn->flag & NSTR_RAW) != 0) 01563 NSTRING_SET_RAW(n); 01564 sn->end = (UChar* )p; 01565 } 01566 } 01567 return n; 01568 } 01569 01570 static int 01571 str_node_can_be_split(StrNode* sn, OnigEncoding enc) 01572 { 01573 if (sn->end > sn->s) { 01574 return ((enclen(enc, sn->s, sn->end) < sn->end - sn->s) ? 1 : 0); 01575 } 01576 return 0; 01577 } 01578 01579 #ifdef USE_PAD_TO_SHORT_BYTE_CHAR 01580 static int 01581 node_str_head_pad(StrNode* sn, int num, UChar val) 01582 { 01583 UChar buf[NODE_STR_BUF_SIZE]; 01584 int i, len; 01585 01586 len = sn->end - sn->s; 01587 onig_strcpy(buf, sn->s, sn->end); 01588 onig_strcpy(&(sn->s[num]), buf, buf + len); 01589 sn->end += num; 01590 01591 for (i = 0; i < num; i++) { 01592 sn->s[i] = val; 01593 } 01594 } 01595 #endif 01596 01597 extern int 01598 onig_scan_unsigned_number(UChar** src, const UChar* end, OnigEncoding enc) 01599 { 01600 unsigned int num, val; 01601 OnigCodePoint c; 01602 UChar* p = *src; 01603 PFETCH_READY; 01604 01605 num = 0; 01606 while (!PEND) { 01607 PFETCH(c); 01608 if (ONIGENC_IS_CODE_DIGIT(enc, c)) { 01609 val = (unsigned int )DIGITVAL(c); 01610 if ((INT_MAX_LIMIT - val) / 10UL < num) 01611 return -1; /* overflow */ 01612 01613 num = num * 10 + val; 01614 } 01615 else { 01616 PUNFETCH; 01617 break; 01618 } 01619 } 01620 *src = p; 01621 return num; 01622 } 01623 01624 static int 01625 scan_unsigned_hexadecimal_number(UChar** src, UChar* end, int maxlen, 01626 OnigEncoding enc) 01627 { 01628 OnigCodePoint c; 01629 unsigned int num, val; 01630 UChar* p = *src; 01631 PFETCH_READY; 01632 01633 num = 0; 01634 while (!PEND && maxlen-- != 0) { 01635 PFETCH(c); 01636 if (ONIGENC_IS_CODE_XDIGIT(enc, c)) { 01637 val = (unsigned int )XDIGITVAL(enc,c); 01638 if ((INT_MAX_LIMIT - val) / 16UL < num) 01639 return -1; /* overflow */ 01640 01641 num = (num << 4) + XDIGITVAL(enc,c); 01642 } 01643 else { 01644 PUNFETCH; 01645 break; 01646 } 01647 } 01648 *src = p; 01649 return num; 01650 } 01651 01652 static int 01653 scan_unsigned_octal_number(UChar** src, UChar* end, int maxlen, 01654 OnigEncoding enc) 01655 { 01656 OnigCodePoint c; 01657 unsigned int num, val; 01658 UChar* p = *src; 01659 PFETCH_READY; 01660 01661 num = 0; 01662 while (!PEND && maxlen-- != 0) { 01663 PFETCH(c); 01664 if (ONIGENC_IS_CODE_DIGIT(enc, c) && c < '8') { 01665 val = ODIGITVAL(c); 01666 if ((INT_MAX_LIMIT - val) / 8UL < num) 01667 return -1; /* overflow */ 01668 01669 num = (num << 3) + val; 01670 } 01671 else { 01672 PUNFETCH; 01673 break; 01674 } 01675 } 01676 *src = p; 01677 return num; 01678 } 01679 01680 01681 #define BBUF_WRITE_CODE_POINT(bbuf,pos,code) \ 01682 BBUF_WRITE(bbuf, pos, &(code), SIZE_CODE_POINT) 01683 01684 /* data format: 01685 [n][from-1][to-1][from-2][to-2] ... [from-n][to-n] 01686 (all data size is OnigCodePoint) 01687 */ 01688 static int 01689 new_code_range(BBuf** pbuf) 01690 { 01691 #define INIT_MULTI_BYTE_RANGE_SIZE (SIZE_CODE_POINT * 5) 01692 int r; 01693 OnigCodePoint n; 01694 BBuf* bbuf; 01695 01696 bbuf = *pbuf = (BBuf* )xmalloc(sizeof(BBuf)); 01697 CHECK_NULL_RETURN_MEMERR(*pbuf); 01698 r = BBUF_INIT(*pbuf, INIT_MULTI_BYTE_RANGE_SIZE); 01699 if (r) return r; 01700 01701 n = 0; 01702 BBUF_WRITE_CODE_POINT(bbuf, 0, n); 01703 return 0; 01704 } 01705 01706 static int 01707 add_code_range_to_buf0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to, 01708 int checkdup) 01709 { 01710 int r, inc_n, pos; 01711 int low, high, bound, x; 01712 OnigCodePoint n, *data; 01713 BBuf* bbuf; 01714 01715 if (from > to) { 01716 n = from; from = to; to = n; 01717 } 01718 01719 if (IS_NULL(*pbuf)) { 01720 r = new_code_range(pbuf); 01721 if (r) return r; 01722 bbuf = *pbuf; 01723 n = 0; 01724 } 01725 else { 01726 bbuf = *pbuf; 01727 GET_CODE_POINT(n, bbuf->p); 01728 } 01729 data = (OnigCodePoint* )(bbuf->p); 01730 data++; 01731 01732 for (low = 0, bound = n; low < bound; ) { 01733 x = (low + bound) >> 1; 01734 if (from > data[x*2 + 1]) 01735 low = x + 1; 01736 else 01737 bound = x; 01738 } 01739 01740 for (high = low, bound = n; high < bound; ) { 01741 x = (high + bound) >> 1; 01742 if (to >= data[x*2] - 1) 01743 high = x + 1; 01744 else 01745 bound = x; 01746 } 01747 01748 inc_n = low + 1 - high; 01749 if (n + inc_n > ONIG_MAX_MULTI_BYTE_RANGES_NUM) 01750 return ONIGERR_TOO_MANY_MULTI_BYTE_RANGES; 01751 01752 if (inc_n != 1) { 01753 if (checkdup && to >= data[low*2]) CC_DUP_WARN(env); 01754 if (from > data[low*2]) 01755 from = data[low*2]; 01756 if (to < data[(high - 1)*2 + 1]) 01757 to = data[(high - 1)*2 + 1]; 01758 } 01759 01760 if (inc_n != 0 && (OnigCodePoint )high < n) { 01761 int from_pos = SIZE_CODE_POINT * (1 + high * 2); 01762 int to_pos = SIZE_CODE_POINT * (1 + (low + 1) * 2); 01763 int size = (n - high) * 2 * SIZE_CODE_POINT; 01764 01765 if (inc_n > 0) { 01766 BBUF_MOVE_RIGHT(bbuf, from_pos, to_pos, size); 01767 } 01768 else { 01769 BBUF_MOVE_LEFT_REDUCE(bbuf, from_pos, to_pos); 01770 } 01771 } 01772 01773 pos = SIZE_CODE_POINT * (1 + low * 2); 01774 BBUF_ENSURE_SIZE(bbuf, pos + SIZE_CODE_POINT * 2); 01775 BBUF_WRITE_CODE_POINT(bbuf, pos, from); 01776 BBUF_WRITE_CODE_POINT(bbuf, pos + SIZE_CODE_POINT, to); 01777 n += inc_n; 01778 BBUF_WRITE_CODE_POINT(bbuf, 0, n); 01779 01780 return 0; 01781 } 01782 01783 static int 01784 add_code_range_to_buf(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to) 01785 { 01786 return add_code_range_to_buf0(pbuf, env, from, to, 1); 01787 } 01788 01789 static int 01790 add_code_range0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to, int checkdup) 01791 { 01792 if (from > to) { 01793 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC)) 01794 return 0; 01795 else 01796 return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS; 01797 } 01798 01799 return add_code_range_to_buf0(pbuf, env, from, to, checkdup); 01800 } 01801 01802 static int 01803 add_code_range(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to) 01804 { 01805 return add_code_range0(pbuf, env, from, to, 1); 01806 } 01807 01808 static int 01809 not_code_range_buf(OnigEncoding enc, BBuf* bbuf, BBuf** pbuf, ScanEnv* env) 01810 { 01811 int r, i, n; 01812 OnigCodePoint pre, from, *data, to = 0; 01813 01814 *pbuf = (BBuf* )NULL; 01815 if (IS_NULL(bbuf)) { 01816 set_all: 01817 return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf); 01818 } 01819 01820 data = (OnigCodePoint* )(bbuf->p); 01821 GET_CODE_POINT(n, data); 01822 data++; 01823 if (n <= 0) goto set_all; 01824 01825 r = 0; 01826 pre = MBCODE_START_POS(enc); 01827 for (i = 0; i < n; i++) { 01828 from = data[i*2]; 01829 to = data[i*2+1]; 01830 if (pre <= from - 1) { 01831 r = add_code_range_to_buf(pbuf, env, pre, from - 1); 01832 if (r != 0) return r; 01833 } 01834 if (to == ~((OnigCodePoint )0)) break; 01835 pre = to + 1; 01836 } 01837 if (to < ~((OnigCodePoint )0)) { 01838 r = add_code_range_to_buf(pbuf, env, to + 1, ~((OnigCodePoint )0)); 01839 } 01840 return r; 01841 } 01842 01843 #define SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2) do {\ 01844 BBuf *tbuf; \ 01845 int tnot; \ 01846 tnot = not1; not1 = not2; not2 = tnot; \ 01847 tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf; \ 01848 } while (0) 01849 01850 static int 01851 or_code_range_buf(OnigEncoding enc, BBuf* bbuf1, int not1, 01852 BBuf* bbuf2, int not2, BBuf** pbuf, ScanEnv* env) 01853 { 01854 int r; 01855 OnigCodePoint i, n1, *data1; 01856 OnigCodePoint from, to; 01857 01858 *pbuf = (BBuf* )NULL; 01859 if (IS_NULL(bbuf1) && IS_NULL(bbuf2)) { 01860 if (not1 != 0 || not2 != 0) 01861 return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf); 01862 return 0; 01863 } 01864 01865 r = 0; 01866 if (IS_NULL(bbuf2)) 01867 SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2); 01868 01869 if (IS_NULL(bbuf1)) { 01870 if (not1 != 0) { 01871 return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf); 01872 } 01873 else { 01874 if (not2 == 0) { 01875 return bbuf_clone(pbuf, bbuf2); 01876 } 01877 else { 01878 return not_code_range_buf(enc, bbuf2, pbuf, env); 01879 } 01880 } 01881 } 01882 01883 if (not1 != 0) 01884 SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2); 01885 01886 data1 = (OnigCodePoint* )(bbuf1->p); 01887 GET_CODE_POINT(n1, data1); 01888 data1++; 01889 01890 if (not2 == 0 && not1 == 0) { /* 1 OR 2 */ 01891 r = bbuf_clone(pbuf, bbuf2); 01892 } 01893 else if (not1 == 0) { /* 1 OR (not 2) */ 01894 r = not_code_range_buf(enc, bbuf2, pbuf, env); 01895 } 01896 if (r != 0) return r; 01897 01898 for (i = 0; i < n1; i++) { 01899 from = data1[i*2]; 01900 to = data1[i*2+1]; 01901 r = add_code_range_to_buf(pbuf, env, from, to); 01902 if (r != 0) return r; 01903 } 01904 return 0; 01905 } 01906 01907 static int 01908 and_code_range1(BBuf** pbuf, ScanEnv* env, OnigCodePoint from1, OnigCodePoint to1, 01909 OnigCodePoint* data, int n) 01910 { 01911 int i, r; 01912 OnigCodePoint from2, to2; 01913 01914 for (i = 0; i < n; i++) { 01915 from2 = data[i*2]; 01916 to2 = data[i*2+1]; 01917 if (from2 < from1) { 01918 if (to2 < from1) continue; 01919 else { 01920 from1 = to2 + 1; 01921 } 01922 } 01923 else if (from2 <= to1) { 01924 if (to2 < to1) { 01925 if (from1 <= from2 - 1) { 01926 r = add_code_range_to_buf(pbuf, env, from1, from2-1); 01927 if (r != 0) return r; 01928 } 01929 from1 = to2 + 1; 01930 } 01931 else { 01932 to1 = from2 - 1; 01933 } 01934 } 01935 else { 01936 from1 = from2; 01937 } 01938 if (from1 > to1) break; 01939 } 01940 if (from1 <= to1) { 01941 r = add_code_range_to_buf(pbuf, env, from1, to1); 01942 if (r != 0) return r; 01943 } 01944 return 0; 01945 } 01946 01947 static int 01948 and_code_range_buf(BBuf* bbuf1, int not1, BBuf* bbuf2, int not2, BBuf** pbuf, ScanEnv* env) 01949 { 01950 int r; 01951 OnigCodePoint i, j, n1, n2, *data1, *data2; 01952 OnigCodePoint from, to, from1, to1, from2, to2; 01953 01954 *pbuf = (BBuf* )NULL; 01955 if (IS_NULL(bbuf1)) { 01956 if (not1 != 0 && IS_NOT_NULL(bbuf2)) /* not1 != 0 -> not2 == 0 */ 01957 return bbuf_clone(pbuf, bbuf2); 01958 return 0; 01959 } 01960 else if (IS_NULL(bbuf2)) { 01961 if (not2 != 0) 01962 return bbuf_clone(pbuf, bbuf1); 01963 return 0; 01964 } 01965 01966 if (not1 != 0) 01967 SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2); 01968 01969 data1 = (OnigCodePoint* )(bbuf1->p); 01970 data2 = (OnigCodePoint* )(bbuf2->p); 01971 GET_CODE_POINT(n1, data1); 01972 GET_CODE_POINT(n2, data2); 01973 data1++; 01974 data2++; 01975 01976 if (not2 == 0 && not1 == 0) { /* 1 AND 2 */ 01977 for (i = 0; i < n1; i++) { 01978 from1 = data1[i*2]; 01979 to1 = data1[i*2+1]; 01980 for (j = 0; j < n2; j++) { 01981 from2 = data2[j*2]; 01982 to2 = data2[j*2+1]; 01983 if (from2 > to1) break; 01984 if (to2 < from1) continue; 01985 from = MAX(from1, from2); 01986 to = MIN(to1, to2); 01987 r = add_code_range_to_buf(pbuf, env, from, to); 01988 if (r != 0) return r; 01989 } 01990 } 01991 } 01992 else if (not1 == 0) { /* 1 AND (not 2) */ 01993 for (i = 0; i < n1; i++) { 01994 from1 = data1[i*2]; 01995 to1 = data1[i*2+1]; 01996 r = and_code_range1(pbuf, env, from1, to1, data2, n2); 01997 if (r != 0) return r; 01998 } 01999 } 02000 02001 return 0; 02002 } 02003 02004 static int 02005 and_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env) 02006 { 02007 OnigEncoding enc = env->enc; 02008 int r, not1, not2; 02009 BBuf *buf1, *buf2, *pbuf = 0; 02010 BitSetRef bsr1, bsr2; 02011 BitSet bs1, bs2; 02012 02013 not1 = IS_NCCLASS_NOT(dest); 02014 bsr1 = dest->bs; 02015 buf1 = dest->mbuf; 02016 not2 = IS_NCCLASS_NOT(cc); 02017 bsr2 = cc->bs; 02018 buf2 = cc->mbuf; 02019 02020 if (not1 != 0) { 02021 bitset_invert_to(bsr1, bs1); 02022 bsr1 = bs1; 02023 } 02024 if (not2 != 0) { 02025 bitset_invert_to(bsr2, bs2); 02026 bsr2 = bs2; 02027 } 02028 bitset_and(bsr1, bsr2); 02029 if (bsr1 != dest->bs) { 02030 bitset_copy(dest->bs, bsr1); 02031 bsr1 = dest->bs; 02032 } 02033 if (not1 != 0) { 02034 bitset_invert(dest->bs); 02035 } 02036 02037 if (! ONIGENC_IS_SINGLEBYTE(enc)) { 02038 if (not1 != 0 && not2 != 0) { 02039 r = or_code_range_buf(enc, buf1, 0, buf2, 0, &pbuf, env); 02040 } 02041 else { 02042 r = and_code_range_buf(buf1, not1, buf2, not2, &pbuf, env); 02043 if (r == 0 && not1 != 0) { 02044 BBuf *tbuf = 0; 02045 r = not_code_range_buf(enc, pbuf, &tbuf, env); 02046 bbuf_free(pbuf); 02047 pbuf = tbuf; 02048 } 02049 } 02050 if (r != 0) { 02051 bbuf_free(pbuf); 02052 return r; 02053 } 02054 02055 dest->mbuf = pbuf; 02056 bbuf_free(buf1); 02057 return r; 02058 } 02059 return 0; 02060 } 02061 02062 static int 02063 or_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env) 02064 { 02065 OnigEncoding enc = env->enc; 02066 int r, not1, not2; 02067 BBuf *buf1, *buf2, *pbuf = 0; 02068 BitSetRef bsr1, bsr2; 02069 BitSet bs1, bs2; 02070 02071 not1 = IS_NCCLASS_NOT(dest); 02072 bsr1 = dest->bs; 02073 buf1 = dest->mbuf; 02074 not2 = IS_NCCLASS_NOT(cc); 02075 bsr2 = cc->bs; 02076 buf2 = cc->mbuf; 02077 02078 if (not1 != 0) { 02079 bitset_invert_to(bsr1, bs1); 02080 bsr1 = bs1; 02081 } 02082 if (not2 != 0) { 02083 bitset_invert_to(bsr2, bs2); 02084 bsr2 = bs2; 02085 } 02086 bitset_or(bsr1, bsr2); 02087 if (bsr1 != dest->bs) { 02088 bitset_copy(dest->bs, bsr1); 02089 bsr1 = dest->bs; 02090 } 02091 if (not1 != 0) { 02092 bitset_invert(dest->bs); 02093 } 02094 02095 if (! ONIGENC_IS_SINGLEBYTE(enc)) { 02096 if (not1 != 0 && not2 != 0) { 02097 r = and_code_range_buf(buf1, 0, buf2, 0, &pbuf, env); 02098 } 02099 else { 02100 r = or_code_range_buf(enc, buf1, not1, buf2, not2, &pbuf, env); 02101 if (r == 0 && not1 != 0) { 02102 BBuf *tbuf = 0; 02103 r = not_code_range_buf(enc, pbuf, &tbuf, env); 02104 bbuf_free(pbuf); 02105 pbuf = tbuf; 02106 } 02107 } 02108 if (r != 0) { 02109 bbuf_free(pbuf); 02110 return r; 02111 } 02112 02113 dest->mbuf = pbuf; 02114 bbuf_free(buf1); 02115 return r; 02116 } 02117 else 02118 return 0; 02119 } 02120 02121 static void UNKNOWN_ESC_WARN(ScanEnv *env, int c); 02122 02123 static int 02124 conv_backslash_value(int c, ScanEnv* env) 02125 { 02126 if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_CONTROL_CHARS)) { 02127 switch (c) { 02128 case 'n': return '\n'; 02129 case 't': return '\t'; 02130 case 'r': return '\r'; 02131 case 'f': return '\f'; 02132 case 'a': return '\007'; 02133 case 'b': return '\010'; 02134 case 'e': return '\033'; 02135 case 'v': 02136 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_V_VTAB)) 02137 return '\v'; 02138 break; 02139 02140 default: 02141 if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) 02142 UNKNOWN_ESC_WARN(env, c); 02143 break; 02144 } 02145 } 02146 return c; 02147 } 02148 02149 #if 0 /* no invalid quantifier */ 02150 static int 02151 is_invalid_quantifier_target(Node* node) 02152 { 02153 switch (NTYPE(node)) { 02154 case NT_ANCHOR: 02155 return 1; 02156 break; 02157 02158 case NT_ENCLOSE: 02159 /* allow enclosed elements */ 02160 /* return is_invalid_quantifier_target(NENCLOSE(node)->target); */ 02161 break; 02162 02163 case NT_LIST: 02164 do { 02165 if (! is_invalid_quantifier_target(NCAR(node))) return 0; 02166 } while (IS_NOT_NULL(node = NCDR(node))); 02167 return 0; 02168 break; 02169 02170 case NT_ALT: 02171 do { 02172 if (is_invalid_quantifier_target(NCAR(node))) return 1; 02173 } while (IS_NOT_NULL(node = NCDR(node))); 02174 break; 02175 02176 default: 02177 break; 02178 } 02179 return 0; 02180 } 02181 #else 02182 #define is_invalid_quantifier_target(node) 0 02183 #endif 02184 02185 /* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */ 02186 static int 02187 popular_quantifier_num(QtfrNode* q) 02188 { 02189 if (q->greedy) { 02190 if (q->lower == 0) { 02191 if (q->upper == 1) return 0; 02192 else if (IS_REPEAT_INFINITE(q->upper)) return 1; 02193 } 02194 else if (q->lower == 1) { 02195 if (IS_REPEAT_INFINITE(q->upper)) return 2; 02196 } 02197 } 02198 else { 02199 if (q->lower == 0) { 02200 if (q->upper == 1) return 3; 02201 else if (IS_REPEAT_INFINITE(q->upper)) return 4; 02202 } 02203 else if (q->lower == 1) { 02204 if (IS_REPEAT_INFINITE(q->upper)) return 5; 02205 } 02206 } 02207 return -1; 02208 } 02209 02210 02211 enum ReduceType { 02212 RQ_ASIS = 0, /* as is */ 02213 RQ_DEL = 1, /* delete parent */ 02214 RQ_A, /* to '*' */ 02215 RQ_AQ, /* to '*?' */ 02216 RQ_QQ, /* to '??' */ 02217 RQ_P_QQ, /* to '+)??' */ 02218 RQ_PQ_Q /* to '+?)?' */ 02219 }; 02220 02221 static enum ReduceType const ReduceTypeTable[6][6] = { 02222 {RQ_DEL, RQ_A, RQ_A, RQ_QQ, RQ_AQ, RQ_ASIS}, /* '?' */ 02223 {RQ_DEL, RQ_DEL, RQ_DEL, RQ_P_QQ, RQ_P_QQ, RQ_DEL}, /* '*' */ 02224 {RQ_A, RQ_A, RQ_DEL, RQ_ASIS, RQ_P_QQ, RQ_DEL}, /* '+' */ 02225 {RQ_DEL, RQ_AQ, RQ_AQ, RQ_DEL, RQ_AQ, RQ_AQ}, /* '??' */ 02226 {RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL}, /* '*?' */ 02227 {RQ_ASIS, RQ_PQ_Q, RQ_DEL, RQ_AQ, RQ_AQ, RQ_DEL} /* '+?' */ 02228 }; 02229 02230 extern void 02231 onig_reduce_nested_quantifier(Node* pnode, Node* cnode) 02232 { 02233 int pnum, cnum; 02234 QtfrNode *p, *c; 02235 02236 p = NQTFR(pnode); 02237 c = NQTFR(cnode); 02238 pnum = popular_quantifier_num(p); 02239 cnum = popular_quantifier_num(c); 02240 if (pnum < 0 || cnum < 0) return ; 02241 02242 switch(ReduceTypeTable[cnum][pnum]) { 02243 case RQ_DEL: 02244 *pnode = *cnode; 02245 break; 02246 case RQ_A: 02247 p->target = c->target; 02248 p->lower = 0; p->upper = REPEAT_INFINITE; p->greedy = 1; 02249 break; 02250 case RQ_AQ: 02251 p->target = c->target; 02252 p->lower = 0; p->upper = REPEAT_INFINITE; p->greedy = 0; 02253 break; 02254 case RQ_QQ: 02255 p->target = c->target; 02256 p->lower = 0; p->upper = 1; p->greedy = 0; 02257 break; 02258 case RQ_P_QQ: 02259 p->target = cnode; 02260 p->lower = 0; p->upper = 1; p->greedy = 0; 02261 c->lower = 1; c->upper = REPEAT_INFINITE; c->greedy = 1; 02262 return ; 02263 break; 02264 case RQ_PQ_Q: 02265 p->target = cnode; 02266 p->lower = 0; p->upper = 1; p->greedy = 1; 02267 c->lower = 1; c->upper = REPEAT_INFINITE; c->greedy = 0; 02268 return ; 02269 break; 02270 case RQ_ASIS: 02271 p->target = cnode; 02272 return ; 02273 break; 02274 } 02275 02276 c->target = NULL_NODE; 02277 onig_node_free(cnode); 02278 } 02279 02280 02281 enum TokenSyms { 02282 TK_EOT = 0, /* end of token */ 02283 TK_RAW_BYTE = 1, 02284 TK_CHAR, 02285 TK_STRING, 02286 TK_CODE_POINT, 02287 TK_ANYCHAR, 02288 TK_CHAR_TYPE, 02289 TK_BACKREF, 02290 TK_CALL, 02291 TK_ANCHOR, 02292 TK_OP_REPEAT, 02293 TK_INTERVAL, 02294 TK_ANYCHAR_ANYTIME, /* SQL '%' == .* */ 02295 TK_ALT, 02296 TK_SUBEXP_OPEN, 02297 TK_SUBEXP_CLOSE, 02298 TK_CC_OPEN, 02299 TK_QUOTE_OPEN, 02300 TK_CHAR_PROPERTY, /* \p{...}, \P{...} */ 02301 /* in cc */ 02302 TK_CC_CLOSE, 02303 TK_CC_RANGE, 02304 TK_POSIX_BRACKET_OPEN, 02305 TK_CC_AND, /* && */ 02306 TK_CC_CC_OPEN /* [ */ 02307 }; 02308 02309 typedef struct { 02310 enum TokenSyms type; 02311 int escaped; 02312 int base; /* is number: 8, 16 (used in [....]) */ 02313 UChar* backp; 02314 union { 02315 UChar* s; 02316 int c; 02317 OnigCodePoint code; 02318 int anchor; 02319 int subtype; 02320 struct { 02321 int lower; 02322 int upper; 02323 int greedy; 02324 int possessive; 02325 } repeat; 02326 struct { 02327 int num; 02328 int ref1; 02329 int* refs; 02330 int by_name; 02331 #ifdef USE_BACKREF_WITH_LEVEL 02332 int exist_level; 02333 int level; /* \k<name+n> */ 02334 #endif 02335 } backref; 02336 struct { 02337 UChar* name; 02338 UChar* name_end; 02339 int gnum; 02340 } call; 02341 struct { 02342 int ctype; 02343 int not; 02344 } prop; 02345 } u; 02346 } OnigToken; 02347 02348 02349 static int 02350 fetch_range_quantifier(UChar** src, UChar* end, OnigToken* tok, ScanEnv* env) 02351 { 02352 int low, up, syn_allow, non_low = 0; 02353 int r = 0; 02354 OnigCodePoint c; 02355 OnigEncoding enc = env->enc; 02356 UChar* p = *src; 02357 PFETCH_READY; 02358 02359 syn_allow = IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INVALID_INTERVAL); 02360 02361 if (PEND) { 02362 if (syn_allow) 02363 return 1; /* "....{" : OK! */ 02364 else 02365 return ONIGERR_END_PATTERN_AT_LEFT_BRACE; /* "....{" syntax error */ 02366 } 02367 02368 if (! syn_allow) { 02369 c = PPEEK; 02370 if (c == ')' || c == '(' || c == '|') { 02371 return ONIGERR_END_PATTERN_AT_LEFT_BRACE; 02372 } 02373 } 02374 02375 low = onig_scan_unsigned_number(&p, end, env->enc); 02376 if (low < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE; 02377 if (low > ONIG_MAX_REPEAT_NUM) 02378 return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE; 02379 02380 if (p == *src) { /* can't read low */ 02381 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV)) { 02382 /* allow {,n} as {0,n} */ 02383 low = 0; 02384 non_low = 1; 02385 } 02386 else 02387 goto invalid; 02388 } 02389 02390 if (PEND) goto invalid; 02391 PFETCH(c); 02392 if (c == ',') { 02393 UChar* prev = p; 02394 up = onig_scan_unsigned_number(&p, end, env->enc); 02395 if (up < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE; 02396 if (up > ONIG_MAX_REPEAT_NUM) 02397 return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE; 02398 02399 if (p == prev) { 02400 if (non_low != 0) 02401 goto invalid; 02402 up = REPEAT_INFINITE; /* {n,} : {n,infinite} */ 02403 } 02404 } 02405 else { 02406 if (non_low != 0) 02407 goto invalid; 02408 02409 PUNFETCH; 02410 up = low; /* {n} : exact n times */ 02411 r = 2; /* fixed */ 02412 } 02413 02414 if (PEND) goto invalid; 02415 PFETCH(c); 02416 if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) { 02417 if (c != MC_ESC(env->syntax)) goto invalid; 02418 PFETCH(c); 02419 } 02420 if (c != '}') goto invalid; 02421 02422 if (!IS_REPEAT_INFINITE(up) && low > up) { 02423 return ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE; 02424 } 02425 02426 tok->type = TK_INTERVAL; 02427 tok->u.repeat.lower = low; 02428 tok->u.repeat.upper = up; 02429 *src = p; 02430 return r; /* 0: normal {n,m}, 2: fixed {n} */ 02431 02432 invalid: 02433 if (syn_allow) 02434 return 1; /* OK */ 02435 else 02436 return ONIGERR_INVALID_REPEAT_RANGE_PATTERN; 02437 } 02438 02439 /* \M-, \C-, \c, or \... */ 02440 static int 02441 fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env) 02442 { 02443 int v; 02444 OnigCodePoint c; 02445 OnigEncoding enc = env->enc; 02446 UChar* p = *src; 02447 PFETCH_READY; 02448 02449 if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE; 02450 02451 PFETCH(c); 02452 switch (c) { 02453 case 'M': 02454 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META)) { 02455 if (PEND) return ONIGERR_END_PATTERN_AT_META; 02456 PFETCH(c); 02457 if (c != '-') return ONIGERR_META_CODE_SYNTAX; 02458 if (PEND) return ONIGERR_END_PATTERN_AT_META; 02459 PFETCH(c); 02460 if (c == MC_ESC(env->syntax)) { 02461 v = fetch_escaped_value(&p, end, env); 02462 if (v < 0) return v; 02463 c = (OnigCodePoint )v; 02464 } 02465 c = ((c & 0xff) | 0x80); 02466 } 02467 else 02468 goto backslash; 02469 break; 02470 02471 case 'C': 02472 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL)) { 02473 if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL; 02474 PFETCH(c); 02475 if (c != '-') return ONIGERR_CONTROL_CODE_SYNTAX; 02476 goto control; 02477 } 02478 else 02479 goto backslash; 02480 02481 case 'c': 02482 if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_C_CONTROL)) { 02483 control: 02484 if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL; 02485 PFETCH(c); 02486 if (c == '?') { 02487 c = 0177; 02488 } 02489 else { 02490 if (c == MC_ESC(env->syntax)) { 02491 v = fetch_escaped_value(&p, end, env); 02492 if (v < 0) return v; 02493 c = (OnigCodePoint )v; 02494 } 02495 c &= 0x9f; 02496 } 02497 break; 02498 } 02499 /* fall through */ 02500 02501 default: 02502 { 02503 backslash: 02504 c = conv_backslash_value(c, env); 02505 } 02506 break; 02507 } 02508 02509 *src = p; 02510 return c; 02511 } 02512 02513 static int fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env); 02514 02515 static OnigCodePoint 02516 get_name_end_code_point(OnigCodePoint start) 02517 { 02518 switch (start) { 02519 case '<': return (OnigCodePoint )'>'; break; 02520 case '\'': return (OnigCodePoint )'\''; break; 02521 default: 02522 break; 02523 } 02524 02525 return (OnigCodePoint )0; 02526 } 02527 02528 #ifdef USE_NAMED_GROUP 02529 #ifdef USE_BACKREF_WITH_LEVEL 02530 /* 02531 \k<name+n>, \k<name-n> 02532 \k<num+n>, \k<num-n> 02533 \k<-num+n>, \k<-num-n> 02534 */ 02535 static int 02536 fetch_name_with_level(OnigCodePoint start_code, UChar** src, UChar* end, 02537 UChar** rname_end, ScanEnv* env, 02538 int* rback_num, int* rlevel) 02539 { 02540 int r, sign, is_num, exist_level; 02541 OnigCodePoint end_code; 02542 OnigCodePoint c = 0; 02543 OnigEncoding enc = env->enc; 02544 UChar *name_end; 02545 UChar *pnum_head; 02546 UChar *p = *src; 02547 PFETCH_READY; 02548 02549 *rback_num = 0; 02550 is_num = exist_level = 0; 02551 sign = 1; 02552 pnum_head = *src; 02553 02554 end_code = get_name_end_code_point(start_code); 02555 02556 name_end = end; 02557 r = 0; 02558 if (PEND) { 02559 return ONIGERR_EMPTY_GROUP_NAME; 02560 } 02561 else { 02562 PFETCH(c); 02563 if (c == end_code) 02564 return ONIGERR_EMPTY_GROUP_NAME; 02565 02566 if (ONIGENC_IS_CODE_DIGIT(enc, c)) { 02567 is_num = 1; 02568 } 02569 else if (c == '-') { 02570 is_num = 2; 02571 sign = -1; 02572 pnum_head = p; 02573 } 02574 else if (!ONIGENC_IS_CODE_WORD(enc, c)) { 02575 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; 02576 } 02577 } 02578 02579 while (!PEND) { 02580 name_end = p; 02581 PFETCH(c); 02582 if (c == end_code || c == ')' || c == '+' || c == '-') { 02583 if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME; 02584 break; 02585 } 02586 02587 if (is_num != 0) { 02588 if (ONIGENC_IS_CODE_DIGIT(enc, c)) { 02589 is_num = 1; 02590 } 02591 else { 02592 r = ONIGERR_INVALID_GROUP_NAME; 02593 is_num = 0; 02594 } 02595 } 02596 else if (!ONIGENC_IS_CODE_WORD(enc, c)) { 02597 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; 02598 } 02599 } 02600 02601 if (r == 0 && c != end_code) { 02602 if (c == '+' || c == '-') { 02603 int level; 02604 int flag = (c == '-' ? -1 : 1); 02605 02606 PFETCH(c); 02607 if (! ONIGENC_IS_CODE_DIGIT(enc, c)) goto err; 02608 PUNFETCH; 02609 level = onig_scan_unsigned_number(&p, end, enc); 02610 if (level < 0) return ONIGERR_TOO_BIG_NUMBER; 02611 *rlevel = (level * flag); 02612 exist_level = 1; 02613 02614 PFETCH(c); 02615 if (c == end_code) 02616 goto end; 02617 } 02618 02619 err: 02620 r = ONIGERR_INVALID_GROUP_NAME; 02621 name_end = end; 02622 } 02623 02624 end: 02625 if (r == 0) { 02626 if (is_num != 0) { 02627 *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc); 02628 if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER; 02629 else if (*rback_num == 0) goto err; 02630 02631 *rback_num *= sign; 02632 } 02633 02634 *rname_end = name_end; 02635 *src = p; 02636 return (exist_level ? 1 : 0); 02637 } 02638 else { 02639 onig_scan_env_set_error_string(env, r, *src, name_end); 02640 return r; 02641 } 02642 } 02643 #endif /* USE_BACKREF_WITH_LEVEL */ 02644 02645 /* 02646 def: 0 -> define name (don't allow number name) 02647 1 -> reference name (allow number name) 02648 */ 02649 static int 02650 fetch_name(OnigCodePoint start_code, UChar** src, UChar* end, 02651 UChar** rname_end, ScanEnv* env, int* rback_num, int ref) 02652 { 02653 int r, is_num, sign; 02654 OnigCodePoint end_code; 02655 OnigCodePoint c = 0; 02656 OnigEncoding enc = env->enc; 02657 UChar *name_end; 02658 UChar *pnum_head; 02659 UChar *p = *src; 02660 PFETCH_READY; 02661 02662 *rback_num = 0; 02663 02664 end_code = get_name_end_code_point(start_code); 02665 02666 name_end = end; 02667 pnum_head = *src; 02668 r = 0; 02669 is_num = 0; 02670 sign = 1; 02671 if (PEND) { 02672 return ONIGERR_EMPTY_GROUP_NAME; 02673 } 02674 else { 02675 PFETCH(c); 02676 if (c == end_code) 02677 return ONIGERR_EMPTY_GROUP_NAME; 02678 02679 if (ONIGENC_IS_CODE_DIGIT(enc, c)) { 02680 if (ref == 1) 02681 is_num = 1; 02682 else { 02683 r = ONIGERR_INVALID_GROUP_NAME; 02684 is_num = 0; 02685 } 02686 } 02687 else if (c == '-') { 02688 if (ref == 1) { 02689 is_num = 2; 02690 sign = -1; 02691 pnum_head = p; 02692 } 02693 else { 02694 r = ONIGERR_INVALID_GROUP_NAME; 02695 is_num = 0; 02696 } 02697 } 02698 else if (!ONIGENC_IS_CODE_WORD(enc, c)) { 02699 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; 02700 } 02701 } 02702 02703 if (r == 0) { 02704 while (!PEND) { 02705 name_end = p; 02706 PFETCH(c); 02707 if (c == end_code || c == ')') { 02708 if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME; 02709 break; 02710 } 02711 02712 if (is_num != 0) { 02713 if (ONIGENC_IS_CODE_DIGIT(enc, c)) { 02714 is_num = 1; 02715 } 02716 else { 02717 if (!ONIGENC_IS_CODE_WORD(enc, c)) 02718 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; 02719 else 02720 r = ONIGERR_INVALID_GROUP_NAME; 02721 02722 is_num = 0; 02723 } 02724 } 02725 else { 02726 if (!ONIGENC_IS_CODE_WORD(enc, c)) { 02727 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; 02728 } 02729 } 02730 } 02731 02732 if (c != end_code) { 02733 r = ONIGERR_INVALID_GROUP_NAME; 02734 name_end = end; 02735 } 02736 02737 if (is_num != 0) { 02738 *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc); 02739 if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER; 02740 else if (*rback_num == 0) { 02741 r = ONIGERR_INVALID_GROUP_NAME; 02742 goto err; 02743 } 02744 02745 *rback_num *= sign; 02746 } 02747 02748 *rname_end = name_end; 02749 *src = p; 02750 return 0; 02751 } 02752 else { 02753 while (!PEND) { 02754 name_end = p; 02755 PFETCH(c); 02756 if (c == end_code || c == ')') 02757 break; 02758 } 02759 if (PEND) 02760 name_end = end; 02761 02762 err: 02763 onig_scan_env_set_error_string(env, r, *src, name_end); 02764 return r; 02765 } 02766 } 02767 #else 02768 static int 02769 fetch_name(OnigCodePoint start_code, UChar** src, UChar* end, 02770 UChar** rname_end, ScanEnv* env, int* rback_num, int ref) 02771 { 02772 int r, is_num, sign; 02773 OnigCodePoint end_code; 02774 OnigCodePoint c = 0; 02775 UChar *name_end; 02776 OnigEncoding enc = env->enc; 02777 UChar *pnum_head; 02778 UChar *p = *src; 02779 PFETCH_READY; 02780 02781 *rback_num = 0; 02782 02783 end_code = get_name_end_code_point(start_code); 02784 02785 *rname_end = name_end = end; 02786 r = 0; 02787 pnum_head = *src; 02788 is_num = 0; 02789 sign = 1; 02790 02791 if (PEND) { 02792 return ONIGERR_EMPTY_GROUP_NAME; 02793 } 02794 else { 02795 PFETCH(c); 02796 if (c == end_code) 02797 return ONIGERR_EMPTY_GROUP_NAME; 02798 02799 if (ONIGENC_IS_CODE_DIGIT(enc, c)) { 02800 is_num = 1; 02801 } 02802 else if (c == '-') { 02803 is_num = 2; 02804 sign = -1; 02805 pnum_head = p; 02806 } 02807 else { 02808 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; 02809 } 02810 } 02811 02812 while (!PEND) { 02813 name_end = p; 02814 02815 PFETCH(c); 02816 if (c == end_code || c == ')') break; 02817 if (! ONIGENC_IS_CODE_DIGIT(enc, c)) 02818 r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME; 02819 } 02820 if (r == 0 && c != end_code) { 02821 r = ONIGERR_INVALID_GROUP_NAME; 02822 name_end = end; 02823 } 02824 02825 if (r == 0) { 02826 *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc); 02827 if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER; 02828 else if (*rback_num == 0) { 02829 r = ONIGERR_INVALID_GROUP_NAME; 02830 goto err; 02831 } 02832 *rback_num *= sign; 02833 02834 *rname_end = name_end; 02835 *src = p; 02836 return 0; 02837 } 02838 else { 02839 err: 02840 onig_scan_env_set_error_string(env, r, *src, name_end); 02841 return r; 02842 } 02843 } 02844 #endif /* USE_NAMED_GROUP */ 02845 02846 void onig_vsnprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc, 02847 UChar* pat, UChar* pat_end, const UChar *fmt, va_list args); 02848 02849 static void 02850 onig_syntax_warn(ScanEnv *env, const char *fmt, ...) 02851 { 02852 va_list args; 02853 UChar buf[WARN_BUFSIZE]; 02854 va_start(args, fmt); 02855 onig_vsnprintf_with_pattern(buf, WARN_BUFSIZE, env->enc, 02856 env->pattern, env->pattern_end, 02857 (const UChar *)fmt, args); 02858 va_end(args); 02859 if (env->sourcefile == NULL) 02860 rb_warn("%s", (char *)buf); 02861 else 02862 rb_compile_warn(env->sourcefile, env->sourceline, "%s", (char *)buf); 02863 } 02864 02865 static void 02866 CC_ESC_WARN(ScanEnv *env, UChar *c) 02867 { 02868 if (onig_warn == onig_null_warn) return ; 02869 02870 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED) && 02871 IS_SYNTAX_BV(env->syntax, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC)) { 02872 onig_syntax_warn(env, "character class has '%s' without escape", c); 02873 } 02874 } 02875 02876 static void 02877 CLOSE_BRACKET_WITHOUT_ESC_WARN(ScanEnv* env, UChar* c) 02878 { 02879 if (onig_warn == onig_null_warn) return ; 02880 02881 if (IS_SYNTAX_BV((env)->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED)) { 02882 onig_syntax_warn(env, "regular expression has '%s' without escape", c); 02883 } 02884 } 02885 02886 static void 02887 CC_DUP_WARN(ScanEnv *env) 02888 { 02889 if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ; 02890 02891 if (IS_SYNTAX_BV((env)->syntax, ONIG_SYN_WARN_CC_DUP) && 02892 !((env)->warnings_flag & ONIG_SYN_WARN_CC_DUP)) { 02893 (env)->warnings_flag |= ONIG_SYN_WARN_CC_DUP; 02894 onig_syntax_warn(env, "character class has duplicated range"); 02895 } 02896 } 02897 02898 static void 02899 UNKNOWN_ESC_WARN(ScanEnv *env, int c) 02900 { 02901 if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ; 02902 onig_syntax_warn(env, "Unknown escape \\%c is ignored", c); 02903 } 02904 02905 static UChar* 02906 find_str_position(OnigCodePoint s[], int n, UChar* from, UChar* to, 02907 UChar **next, OnigEncoding enc) 02908 { 02909 int i; 02910 OnigCodePoint x; 02911 UChar *q; 02912 UChar *p = from; 02913 02914 while (p < to) { 02915 x = ONIGENC_MBC_TO_CODE(enc, p, to); 02916 q = p + enclen(enc, p, to); 02917 if (x == s[0]) { 02918 for (i = 1; i < n && q < to; i++) { 02919 x = ONIGENC_MBC_TO_CODE(enc, q, to); 02920 if (x != s[i]) break; 02921 q += enclen(enc, q, to); 02922 } 02923 if (i >= n) { 02924 if (IS_NOT_NULL(next)) 02925 *next = q; 02926 return p; 02927 } 02928 } 02929 p = q; 02930 } 02931 return NULL_UCHARP; 02932 } 02933 02934 static int 02935 str_exist_check_with_esc(OnigCodePoint s[], int n, UChar* from, UChar* to, 02936 OnigCodePoint bad, OnigEncoding enc, const OnigSyntaxType* syn) 02937 { 02938 int i, in_esc; 02939 OnigCodePoint x; 02940 UChar *q; 02941 UChar *p = from; 02942 02943 in_esc = 0; 02944 while (p < to) { 02945 if (in_esc) { 02946 in_esc = 0; 02947 p += enclen(enc, p, to); 02948 } 02949 else { 02950 x = ONIGENC_MBC_TO_CODE(enc, p, to); 02951 q = p + enclen(enc, p, to); 02952 if (x == s[0]) { 02953 for (i = 1; i < n && q < to; i++) { 02954 x = ONIGENC_MBC_TO_CODE(enc, q, to); 02955 if (x != s[i]) break; 02956 q += enclen(enc, q, to); 02957 } 02958 if (i >= n) return 1; 02959 p += enclen(enc, p, to); 02960 } 02961 else { 02962 x = ONIGENC_MBC_TO_CODE(enc, p, to); 02963 if (x == bad) return 0; 02964 else if (x == MC_ESC(syn)) in_esc = 1; 02965 p = q; 02966 } 02967 } 02968 } 02969 return 0; 02970 } 02971 02972 static int 02973 fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env) 02974 { 02975 int num; 02976 OnigCodePoint c, c2; 02977 const OnigSyntaxType* syn = env->syntax; 02978 OnigEncoding enc = env->enc; 02979 UChar* prev; 02980 UChar* p = *src; 02981 PFETCH_READY; 02982 02983 if (PEND) { 02984 tok->type = TK_EOT; 02985 return tok->type; 02986 } 02987 02988 PFETCH(c); 02989 tok->type = TK_CHAR; 02990 tok->base = 0; 02991 tok->u.c = c; 02992 tok->escaped = 0; 02993 02994 if (c == ']') { 02995 tok->type = TK_CC_CLOSE; 02996 } 02997 else if (c == '-') { 02998 tok->type = TK_CC_RANGE; 02999 } 03000 else if (c == MC_ESC(syn)) { 03001 if (! IS_SYNTAX_BV(syn, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC)) 03002 goto end; 03003 03004 if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE; 03005 03006 PFETCH(c); 03007 tok->escaped = 1; 03008 tok->u.c = c; 03009 switch (c) { 03010 case 'w': 03011 tok->type = TK_CHAR_TYPE; 03012 tok->u.prop.ctype = ONIGENC_CTYPE_W; 03013 tok->u.prop.not = 0; 03014 break; 03015 case 'W': 03016 tok->type = TK_CHAR_TYPE; 03017 tok->u.prop.ctype = ONIGENC_CTYPE_W; 03018 tok->u.prop.not = 1; 03019 break; 03020 case 'd': 03021 tok->type = TK_CHAR_TYPE; 03022 tok->u.prop.ctype = ONIGENC_CTYPE_D; 03023 tok->u.prop.not = 0; 03024 break; 03025 case 'D': 03026 tok->type = TK_CHAR_TYPE; 03027 tok->u.prop.ctype = ONIGENC_CTYPE_D; 03028 tok->u.prop.not = 1; 03029 break; 03030 case 's': 03031 tok->type = TK_CHAR_TYPE; 03032 tok->u.prop.ctype = ONIGENC_CTYPE_S; 03033 tok->u.prop.not = 0; 03034 break; 03035 case 'S': 03036 tok->type = TK_CHAR_TYPE; 03037 tok->u.prop.ctype = ONIGENC_CTYPE_S; 03038 tok->u.prop.not = 1; 03039 break; 03040 case 'h': 03041 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break; 03042 tok->type = TK_CHAR_TYPE; 03043 tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT; 03044 tok->u.prop.not = 0; 03045 break; 03046 case 'H': 03047 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break; 03048 tok->type = TK_CHAR_TYPE; 03049 tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT; 03050 tok->u.prop.not = 1; 03051 break; 03052 03053 case 'p': 03054 case 'P': 03055 c2 = PPEEK; 03056 if (c2 == '{' && 03057 IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) { 03058 PINC; 03059 tok->type = TK_CHAR_PROPERTY; 03060 tok->u.prop.not = (c == 'P' ? 1 : 0); 03061 03062 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) { 03063 PFETCH(c2); 03064 if (c2 == '^') { 03065 tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0); 03066 } 03067 else 03068 PUNFETCH; 03069 } 03070 } 03071 else { 03072 onig_syntax_warn(env, "invalid Unicode Property \\%c", c); 03073 } 03074 break; 03075 03076 case 'x': 03077 if (PEND) break; 03078 03079 prev = p; 03080 if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) { 03081 PINC; 03082 num = scan_unsigned_hexadecimal_number(&p, end, 8, enc); 03083 if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE; 03084 if (!PEND) { 03085 c2 = PPEEK; 03086 if (ONIGENC_IS_CODE_XDIGIT(enc, c2)) 03087 return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE; 03088 } 03089 03090 if (p > prev + enclen(enc, prev, end) && !PEND && (PPEEK_IS('}'))) { 03091 PINC; 03092 tok->type = TK_CODE_POINT; 03093 tok->base = 16; 03094 tok->u.code = (OnigCodePoint )num; 03095 } 03096 else { 03097 /* can't read nothing or invalid format */ 03098 p = prev; 03099 } 03100 } 03101 else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) { 03102 num = scan_unsigned_hexadecimal_number(&p, end, 2, enc); 03103 if (num < 0) return ONIGERR_TOO_BIG_NUMBER; 03104 if (p == prev) { /* can't read nothing. */ 03105 num = 0; /* but, it's not error */ 03106 } 03107 tok->type = TK_RAW_BYTE; 03108 tok->base = 16; 03109 tok->u.c = num; 03110 } 03111 break; 03112 03113 case 'u': 03114 if (PEND) break; 03115 03116 prev = p; 03117 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) { 03118 num = scan_unsigned_hexadecimal_number(&p, end, 4, enc); 03119 if (num < 0) return ONIGERR_TOO_BIG_NUMBER; 03120 if (p == prev) { /* can't read nothing. */ 03121 num = 0; /* but, it's not error */ 03122 } 03123 tok->type = TK_CODE_POINT; 03124 tok->base = 16; 03125 tok->u.code = (OnigCodePoint )num; 03126 } 03127 break; 03128 03129 case '0': 03130 case '1': case '2': case '3': case '4': case '5': case '6': case '7': 03131 if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) { 03132 PUNFETCH; 03133 prev = p; 03134 num = scan_unsigned_octal_number(&p, end, 3, enc); 03135 if (num < 0) return ONIGERR_TOO_BIG_NUMBER; 03136 if (p == prev) { /* can't read nothing. */ 03137 num = 0; /* but, it's not error */ 03138 } 03139 tok->type = TK_RAW_BYTE; 03140 tok->base = 8; 03141 tok->u.c = num; 03142 } 03143 break; 03144 03145 default: 03146 PUNFETCH; 03147 num = fetch_escaped_value(&p, end, env); 03148 if (num < 0) return num; 03149 if (tok->u.c != num) { 03150 tok->u.code = (OnigCodePoint )num; 03151 tok->type = TK_CODE_POINT; 03152 } 03153 break; 03154 } 03155 } 03156 else if (c == '[') { 03157 if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_POSIX_BRACKET) && (PPEEK_IS(':'))) { 03158 OnigCodePoint send[] = { (OnigCodePoint )':', (OnigCodePoint )']' }; 03159 tok->backp = p; /* point at '[' is readed */ 03160 PINC; 03161 if (str_exist_check_with_esc(send, 2, p, end, 03162 (OnigCodePoint )']', enc, syn)) { 03163 tok->type = TK_POSIX_BRACKET_OPEN; 03164 } 03165 else { 03166 PUNFETCH; 03167 goto cc_in_cc; 03168 } 03169 } 03170 else { 03171 cc_in_cc: 03172 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP)) { 03173 tok->type = TK_CC_CC_OPEN; 03174 } 03175 else { 03176 CC_ESC_WARN(env, (UChar* )"["); 03177 } 03178 } 03179 } 03180 else if (c == '&') { 03181 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP) && 03182 !PEND && (PPEEK_IS('&'))) { 03183 PINC; 03184 tok->type = TK_CC_AND; 03185 } 03186 } 03187 03188 end: 03189 *src = p; 03190 return tok->type; 03191 } 03192 03193 static int 03194 fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env) 03195 { 03196 int r, num; 03197 OnigCodePoint c; 03198 OnigEncoding enc = env->enc; 03199 const OnigSyntaxType* syn = env->syntax; 03200 UChar* prev; 03201 UChar* p = *src; 03202 PFETCH_READY; 03203 03204 start: 03205 if (PEND) { 03206 tok->type = TK_EOT; 03207 return tok->type; 03208 } 03209 03210 tok->type = TK_STRING; 03211 tok->base = 0; 03212 tok->backp = p; 03213 03214 PFETCH(c); 03215 if (IS_MC_ESC_CODE(c, syn)) { 03216 if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE; 03217 03218 tok->backp = p; 03219 PFETCH(c); 03220 03221 tok->u.c = c; 03222 tok->escaped = 1; 03223 switch (c) { 03224 case '*': 03225 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF)) break; 03226 tok->type = TK_OP_REPEAT; 03227 tok->u.repeat.lower = 0; 03228 tok->u.repeat.upper = REPEAT_INFINITE; 03229 goto greedy_check; 03230 break; 03231 03232 case '+': 03233 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_PLUS_ONE_INF)) break; 03234 tok->type = TK_OP_REPEAT; 03235 tok->u.repeat.lower = 1; 03236 tok->u.repeat.upper = REPEAT_INFINITE; 03237 goto greedy_check; 03238 break; 03239 03240 case '?': 03241 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_QMARK_ZERO_ONE)) break; 03242 tok->type = TK_OP_REPEAT; 03243 tok->u.repeat.lower = 0; 03244 tok->u.repeat.upper = 1; 03245 greedy_check: 03246 if (!PEND && PPEEK_IS('?') && 03247 IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_NON_GREEDY)) { 03248 PFETCH(c); 03249 tok->u.repeat.greedy = 0; 03250 tok->u.repeat.possessive = 0; 03251 } 03252 else { 03253 possessive_check: 03254 if (!PEND && PPEEK_IS('+') && 03255 ((IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT) && 03256 tok->type != TK_INTERVAL) || 03257 (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL) && 03258 tok->type == TK_INTERVAL))) { 03259 PFETCH(c); 03260 tok->u.repeat.greedy = 1; 03261 tok->u.repeat.possessive = 1; 03262 } 03263 else { 03264 tok->u.repeat.greedy = 1; 03265 tok->u.repeat.possessive = 0; 03266 } 03267 } 03268 break; 03269 03270 case '{': 03271 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) break; 03272 r = fetch_range_quantifier(&p, end, tok, env); 03273 if (r < 0) return r; /* error */ 03274 if (r == 0) goto greedy_check; 03275 else if (r == 2) { /* {n} */ 03276 if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY)) 03277 goto possessive_check; 03278 03279 goto greedy_check; 03280 } 03281 /* r == 1 : normal char */ 03282 break; 03283 03284 case '|': 03285 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_VBAR_ALT)) break; 03286 tok->type = TK_ALT; 03287 break; 03288 03289 case '(': 03290 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break; 03291 tok->type = TK_SUBEXP_OPEN; 03292 break; 03293 03294 case ')': 03295 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break; 03296 tok->type = TK_SUBEXP_CLOSE; 03297 break; 03298 03299 case 'w': 03300 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break; 03301 tok->type = TK_CHAR_TYPE; 03302 tok->u.prop.ctype = ONIGENC_CTYPE_W; 03303 tok->u.prop.not = 0; 03304 break; 03305 03306 case 'W': 03307 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break; 03308 tok->type = TK_CHAR_TYPE; 03309 tok->u.prop.ctype = ONIGENC_CTYPE_W; 03310 tok->u.prop.not = 1; 03311 break; 03312 03313 case 'b': 03314 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break; 03315 tok->type = TK_ANCHOR; 03316 tok->u.anchor = ANCHOR_WORD_BOUND; 03317 break; 03318 03319 case 'B': 03320 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break; 03321 tok->type = TK_ANCHOR; 03322 tok->u.anchor = ANCHOR_NOT_WORD_BOUND; 03323 break; 03324 03325 #ifdef USE_WORD_BEGIN_END 03326 case '<': 03327 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break; 03328 tok->type = TK_ANCHOR; 03329 tok->u.anchor = ANCHOR_WORD_BEGIN; 03330 break; 03331 03332 case '>': 03333 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break; 03334 tok->type = TK_ANCHOR; 03335 tok->u.anchor = ANCHOR_WORD_END; 03336 break; 03337 #endif 03338 03339 case 's': 03340 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break; 03341 tok->type = TK_CHAR_TYPE; 03342 tok->u.prop.ctype = ONIGENC_CTYPE_S; 03343 tok->u.prop.not = 0; 03344 break; 03345 03346 case 'S': 03347 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break; 03348 tok->type = TK_CHAR_TYPE; 03349 tok->u.prop.ctype = ONIGENC_CTYPE_S; 03350 tok->u.prop.not = 1; 03351 break; 03352 03353 case 'd': 03354 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break; 03355 tok->type = TK_CHAR_TYPE; 03356 tok->u.prop.ctype = ONIGENC_CTYPE_D; 03357 tok->u.prop.not = 0; 03358 break; 03359 03360 case 'D': 03361 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break; 03362 tok->type = TK_CHAR_TYPE; 03363 tok->u.prop.ctype = ONIGENC_CTYPE_D; 03364 tok->u.prop.not = 1; 03365 break; 03366 03367 case 'h': 03368 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break; 03369 tok->type = TK_CHAR_TYPE; 03370 tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT; 03371 tok->u.prop.not = 0; 03372 break; 03373 03374 case 'H': 03375 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break; 03376 tok->type = TK_CHAR_TYPE; 03377 tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT; 03378 tok->u.prop.not = 1; 03379 break; 03380 03381 case 'A': 03382 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break; 03383 begin_buf: 03384 tok->type = TK_ANCHOR; 03385 tok->u.subtype = ANCHOR_BEGIN_BUF; 03386 break; 03387 03388 case 'Z': 03389 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break; 03390 tok->type = TK_ANCHOR; 03391 tok->u.subtype = ANCHOR_SEMI_END_BUF; 03392 break; 03393 03394 case 'z': 03395 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break; 03396 end_buf: 03397 tok->type = TK_ANCHOR; 03398 tok->u.subtype = ANCHOR_END_BUF; 03399 break; 03400 03401 case 'G': 03402 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR)) break; 03403 tok->type = TK_ANCHOR; 03404 tok->u.subtype = ANCHOR_BEGIN_POSITION; 03405 break; 03406 03407 case '`': 03408 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break; 03409 goto begin_buf; 03410 break; 03411 03412 case '\'': 03413 if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break; 03414 goto end_buf; 03415 break; 03416 03417 case 'x': 03418 if (PEND) break; 03419 03420 prev = p; 03421 if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) { 03422 PINC; 03423 num = scan_unsigned_hexadecimal_number(&p, end, 8, enc); 03424 if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE; 03425 if (!PEND) { 03426 if (ONIGENC_IS_CODE_XDIGIT(enc, PPEEK)) 03427 return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE; 03428 } 03429 03430 if ((p > prev + enclen(enc, prev, end)) && !PEND && PPEEK_IS('}')) { 03431 PINC; 03432 tok->type = TK_CODE_POINT; 03433 tok->u.code = (OnigCodePoint )num; 03434 } 03435 else { 03436 /* can't read nothing or invalid format */ 03437 p = prev; 03438 } 03439 } 03440 else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) { 03441 num = scan_unsigned_hexadecimal_number(&p, end, 2, enc); 03442 if (num < 0) return ONIGERR_TOO_BIG_NUMBER; 03443 if (p == prev) { /* can't read nothing. */ 03444 num = 0; /* but, it's not error */ 03445 } 03446 tok->type = TK_RAW_BYTE; 03447 tok->base = 16; 03448 tok->u.c = num; 03449 } 03450 break; 03451 03452 case 'u': 03453 if (PEND) break; 03454 03455 prev = p; 03456 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) { 03457 num = scan_unsigned_hexadecimal_number(&p, end, 4, enc); 03458 if (num < 0) return ONIGERR_TOO_BIG_NUMBER; 03459 if (p == prev) { /* can't read nothing. */ 03460 num = 0; /* but, it's not error */ 03461 } 03462 tok->type = TK_CODE_POINT; 03463 tok->base = 16; 03464 tok->u.code = (OnigCodePoint )num; 03465 } 03466 break; 03467 03468 case '1': case '2': case '3': case '4': 03469 case '5': case '6': case '7': case '8': case '9': 03470 PUNFETCH; 03471 prev = p; 03472 num = onig_scan_unsigned_number(&p, end, enc); 03473 if (num < 0 || num > ONIG_MAX_BACKREF_NUM) { 03474 goto skip_backref; 03475 } 03476 03477 if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_DECIMAL_BACKREF) && 03478 (num <= env->num_mem || num <= 9)) { /* This spec. from GNU regex */ 03479 if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) { 03480 if (num > env->num_mem || IS_NULL(SCANENV_MEM_NODES(env)[num])) 03481 return ONIGERR_INVALID_BACKREF; 03482 } 03483 03484 tok->type = TK_BACKREF; 03485 tok->u.backref.num = 1; 03486 tok->u.backref.ref1 = num; 03487 tok->u.backref.by_name = 0; 03488 #ifdef USE_BACKREF_WITH_LEVEL 03489 tok->u.backref.exist_level = 0; 03490 #endif 03491 break; 03492 } 03493 03494 skip_backref: 03495 if (c == '8' || c == '9') { 03496 /* normal char */ 03497 p = prev; PINC; 03498 break; 03499 } 03500 03501 p = prev; 03502 /* fall through */ 03503 case '0': 03504 if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) { 03505 prev = p; 03506 num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc); 03507 if (num < 0) return ONIGERR_TOO_BIG_NUMBER; 03508 if (p == prev) { /* can't read nothing. */ 03509 num = 0; /* but, it's not error */ 03510 } 03511 tok->type = TK_RAW_BYTE; 03512 tok->base = 8; 03513 tok->u.c = num; 03514 } 03515 else if (c != '0') { 03516 PINC; 03517 } 03518 break; 03519 03520 #ifdef USE_NAMED_GROUP 03521 case 'k': 03522 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_K_NAMED_BACKREF)) { 03523 PFETCH(c); 03524 if (c == '<' || c == '\'') { 03525 UChar* name_end; 03526 int* backs; 03527 int back_num; 03528 03529 prev = p; 03530 03531 #ifdef USE_BACKREF_WITH_LEVEL 03532 name_end = NULL_UCHARP; /* no need. escape gcc warning. */ 03533 r = fetch_name_with_level((OnigCodePoint )c, &p, end, &name_end, 03534 env, &back_num, &tok->u.backref.level); 03535 if (r == 1) tok->u.backref.exist_level = 1; 03536 else tok->u.backref.exist_level = 0; 03537 #else 03538 r = fetch_name(&p, end, &name_end, env, &back_num, 1); 03539 #endif 03540 if (r < 0) return r; 03541 03542 if (back_num != 0) { 03543 if (back_num < 0) { 03544 back_num = BACKREF_REL_TO_ABS(back_num, env); 03545 if (back_num <= 0) 03546 return ONIGERR_INVALID_BACKREF; 03547 } 03548 03549 if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) { 03550 if (back_num > env->num_mem || 03551 IS_NULL(SCANENV_MEM_NODES(env)[back_num])) 03552 return ONIGERR_INVALID_BACKREF; 03553 } 03554 tok->type = TK_BACKREF; 03555 tok->u.backref.by_name = 0; 03556 tok->u.backref.num = 1; 03557 tok->u.backref.ref1 = back_num; 03558 } 03559 else { 03560 num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs); 03561 if (num <= 0) { 03562 onig_scan_env_set_error_string(env, 03563 ONIGERR_UNDEFINED_NAME_REFERENCE, prev, name_end); 03564 return ONIGERR_UNDEFINED_NAME_REFERENCE; 03565 } 03566 if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) { 03567 int i; 03568 for (i = 0; i < num; i++) { 03569 if (backs[i] > env->num_mem || 03570 IS_NULL(SCANENV_MEM_NODES(env)[backs[i]])) 03571 return ONIGERR_INVALID_BACKREF; 03572 } 03573 } 03574 03575 tok->type = TK_BACKREF; 03576 tok->u.backref.by_name = 1; 03577 if (num == 1) { 03578 tok->u.backref.num = 1; 03579 tok->u.backref.ref1 = backs[0]; 03580 } 03581 else { 03582 tok->u.backref.num = num; 03583 tok->u.backref.refs = backs; 03584 } 03585 } 03586 } 03587 else { 03588 PUNFETCH; 03589 onig_syntax_warn(env, "invalid back reference"); 03590 } 03591 } 03592 break; 03593 #endif 03594 03595 #ifdef USE_SUBEXP_CALL 03596 case 'g': 03597 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_SUBEXP_CALL)) { 03598 PFETCH(c); 03599 if (c == '<' || c == '\'') { 03600 int gnum; 03601 UChar* name_end; 03602 03603 prev = p; 03604 r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &gnum, 1); 03605 if (r < 0) return r; 03606 03607 tok->type = TK_CALL; 03608 tok->u.call.name = prev; 03609 tok->u.call.name_end = name_end; 03610 tok->u.call.gnum = gnum; 03611 } 03612 else { 03613 onig_syntax_warn(env, "invalid subexp call"); 03614 PUNFETCH; 03615 } 03616 } 03617 break; 03618 #endif 03619 03620 case 'Q': 03621 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE)) { 03622 tok->type = TK_QUOTE_OPEN; 03623 } 03624 break; 03625 03626 case 'p': 03627 case 'P': 03628 if (PPEEK_IS('{') && 03629 IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) { 03630 PINC; 03631 tok->type = TK_CHAR_PROPERTY; 03632 tok->u.prop.not = (c == 'P' ? 1 : 0); 03633 03634 if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) { 03635 PFETCH(c); 03636 if (c == '^') { 03637 tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0); 03638 } 03639 else 03640 PUNFETCH; 03641 } 03642 } 03643 else { 03644 onig_syntax_warn(env, "invalid Unicode Property \\%c", c); 03645 } 03646 break; 03647 03648 default: 03649 PUNFETCH; 03650 num = fetch_escaped_value(&p, end, env); 03651 if (num < 0) return num; 03652 /* set_raw: */ 03653 if (tok->u.c != num) { 03654 tok->type = TK_CODE_POINT; 03655 tok->u.code = (OnigCodePoint )num; 03656 } 03657 else { /* string */ 03658 p = tok->backp + enclen(enc, tok->backp, end); 03659 } 03660 break; 03661 } 03662 } 03663 else { 03664 tok->u.c = c; 03665 tok->escaped = 0; 03666 03667 #ifdef USE_VARIABLE_META_CHARS 03668 if ((c != ONIG_INEFFECTIVE_META_CHAR) && 03669 IS_SYNTAX_OP(syn, ONIG_SYN_OP_VARIABLE_META_CHARACTERS)) { 03670 if (c == MC_ANYCHAR(syn)) 03671 goto any_char; 03672 else if (c == MC_ANYTIME(syn)) 03673 goto anytime; 03674 else if (c == MC_ZERO_OR_ONE_TIME(syn)) 03675 goto zero_or_one_time; 03676 else if (c == MC_ONE_OR_MORE_TIME(syn)) 03677 goto one_or_more_time; 03678 else if (c == MC_ANYCHAR_ANYTIME(syn)) { 03679 tok->type = TK_ANYCHAR_ANYTIME; 03680 goto out; 03681 } 03682 } 03683 #endif 03684 03685 switch (c) { 03686 case '.': 03687 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_DOT_ANYCHAR)) break; 03688 #ifdef USE_VARIABLE_META_CHARS 03689 any_char: 03690 #endif 03691 tok->type = TK_ANYCHAR; 03692 break; 03693 03694 case '*': 03695 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ASTERISK_ZERO_INF)) break; 03696 #ifdef USE_VARIABLE_META_CHARS 03697 anytime: 03698 #endif 03699 tok->type = TK_OP_REPEAT; 03700 tok->u.repeat.lower = 0; 03701 tok->u.repeat.upper = REPEAT_INFINITE; 03702 goto greedy_check; 03703 break; 03704 03705 case '+': 03706 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_PLUS_ONE_INF)) break; 03707 #ifdef USE_VARIABLE_META_CHARS 03708 one_or_more_time: 03709 #endif 03710 tok->type = TK_OP_REPEAT; 03711 tok->u.repeat.lower = 1; 03712 tok->u.repeat.upper = REPEAT_INFINITE; 03713 goto greedy_check; 03714 break; 03715 03716 case '?': 03717 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_ZERO_ONE)) break; 03718 #ifdef USE_VARIABLE_META_CHARS 03719 zero_or_one_time: 03720 #endif 03721 tok->type = TK_OP_REPEAT; 03722 tok->u.repeat.lower = 0; 03723 tok->u.repeat.upper = 1; 03724 goto greedy_check; 03725 break; 03726 03727 case '{': 03728 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACE_INTERVAL)) break; 03729 r = fetch_range_quantifier(&p, end, tok, env); 03730 if (r < 0) return r; /* error */ 03731 if (r == 0) goto greedy_check; 03732 else if (r == 2) { /* {n} */ 03733 if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY)) 03734 goto possessive_check; 03735 03736 goto greedy_check; 03737 } 03738 /* r == 1 : normal char */ 03739 break; 03740 03741 case '|': 03742 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_VBAR_ALT)) break; 03743 tok->type = TK_ALT; 03744 break; 03745 03746 case '(': 03747 if (PPEEK_IS('?') && 03748 IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) { 03749 PINC; 03750 if (PPEEK_IS('#')) { 03751 PFETCH(c); 03752 while (1) { 03753 if (PEND) return ONIGERR_END_PATTERN_IN_GROUP; 03754 PFETCH(c); 03755 if (c == MC_ESC(syn)) { 03756 if (!PEND) PFETCH(c); 03757 } 03758 else { 03759 if (c == ')') break; 03760 } 03761 } 03762 goto start; 03763 } 03764 PUNFETCH; 03765 } 03766 03767 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break; 03768 tok->type = TK_SUBEXP_OPEN; 03769 break; 03770 03771 case ')': 03772 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break; 03773 tok->type = TK_SUBEXP_CLOSE; 03774 break; 03775 03776 case '^': 03777 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break; 03778 tok->type = TK_ANCHOR; 03779 tok->u.subtype = (IS_SINGLELINE(env->option) 03780 ? ANCHOR_BEGIN_BUF : ANCHOR_BEGIN_LINE); 03781 break; 03782 03783 case '$': 03784 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break; 03785 tok->type = TK_ANCHOR; 03786 tok->u.subtype = (IS_SINGLELINE(env->option) 03787 ? ANCHOR_SEMI_END_BUF : ANCHOR_END_LINE); 03788 break; 03789 03790 case '[': 03791 if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACKET_CC)) break; 03792 tok->type = TK_CC_OPEN; 03793 break; 03794 03795 case ']': 03796 if (*src > env->pattern) /* /].../ is allowed. */ 03797 CLOSE_BRACKET_WITHOUT_ESC_WARN(env, (UChar* )"]"); 03798 break; 03799 03800 case '#': 03801 if (IS_EXTEND(env->option)) { 03802 while (!PEND) { 03803 PFETCH(c); 03804 if (ONIGENC_IS_CODE_NEWLINE(enc, c)) 03805 break; 03806 } 03807 goto start; 03808 break; 03809 } 03810 break; 03811 03812 case ' ': case '\t': case '\n': case '\r': case '\f': 03813 if (IS_EXTEND(env->option)) 03814 goto start; 03815 break; 03816 03817 default: 03818 /* string */ 03819 break; 03820 } 03821 } 03822 03823 #ifdef USE_VARIABLE_META_CHARS 03824 out: 03825 #endif 03826 *src = p; 03827 return tok->type; 03828 } 03829 03830 static int 03831 add_ctype_to_cc_by_range(CClassNode* cc, int ctype ARG_UNUSED, int not, 03832 ScanEnv* env, 03833 OnigCodePoint sb_out, const OnigCodePoint mbr[]) 03834 { 03835 int i, r; 03836 OnigCodePoint j; 03837 03838 int n = ONIGENC_CODE_RANGE_NUM(mbr); 03839 03840 if (not == 0) { 03841 for (i = 0; i < n; i++) { 03842 for (j = ONIGENC_CODE_RANGE_FROM(mbr, i); 03843 j <= ONIGENC_CODE_RANGE_TO(mbr, i); j++) { 03844 if (j >= sb_out) { 03845 if (j > ONIGENC_CODE_RANGE_FROM(mbr, i)) { 03846 r = add_code_range_to_buf(&(cc->mbuf), env, j, 03847 ONIGENC_CODE_RANGE_TO(mbr, i)); 03848 if (r != 0) return r; 03849 i++; 03850 } 03851 03852 goto sb_end; 03853 } 03854 BITSET_SET_BIT_CHKDUP(cc->bs, j); 03855 } 03856 } 03857 03858 sb_end: 03859 for ( ; i < n; i++) { 03860 r = add_code_range_to_buf(&(cc->mbuf), env, 03861 ONIGENC_CODE_RANGE_FROM(mbr, i), 03862 ONIGENC_CODE_RANGE_TO(mbr, i)); 03863 if (r != 0) return r; 03864 } 03865 } 03866 else { 03867 OnigCodePoint prev = 0; 03868 03869 for (i = 0; i < n; i++) { 03870 for (j = prev; 03871 j < ONIGENC_CODE_RANGE_FROM(mbr, i); j++) { 03872 if (j >= sb_out) { 03873 goto sb_end2; 03874 } 03875 BITSET_SET_BIT_CHKDUP(cc->bs, j); 03876 } 03877 prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1; 03878 } 03879 for (j = prev; j < sb_out; j++) { 03880 BITSET_SET_BIT_CHKDUP(cc->bs, j); 03881 } 03882 03883 sb_end2: 03884 prev = sb_out; 03885 03886 for (i = 0; i < n; i++) { 03887 if (prev < ONIGENC_CODE_RANGE_FROM(mbr, i)) { 03888 r = add_code_range_to_buf(&(cc->mbuf), env, prev, 03889 ONIGENC_CODE_RANGE_FROM(mbr, i) - 1); 03890 if (r != 0) return r; 03891 } 03892 prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1; 03893 } 03894 if (prev < 0x7fffffff) { 03895 r = add_code_range_to_buf(&(cc->mbuf), env, prev, 0x7fffffff); 03896 if (r != 0) return r; 03897 } 03898 } 03899 03900 return 0; 03901 } 03902 03903 static int 03904 add_ctype_to_cc(CClassNode* cc, int ctype, int not, ScanEnv* env) 03905 { 03906 int c, r; 03907 const OnigCodePoint *ranges; 03908 OnigCodePoint sb_out; 03909 OnigEncoding enc = env->enc; 03910 03911 switch (ctype) { 03912 case ONIGENC_CTYPE_D: 03913 case ONIGENC_CTYPE_S: 03914 case ONIGENC_CTYPE_W: 03915 ctype ^= ONIGENC_CTYPE_SPECIAL_MASK; 03916 if (not != 0) { 03917 for (c = 0; c < SINGLE_BYTE_SIZE; c++) { 03918 if (! ONIGENC_IS_ASCII_CODE_CTYPE((OnigCodePoint )c, ctype)) 03919 BITSET_SET_BIT_CHKDUP(cc->bs, c); 03920 } 03921 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf); 03922 } 03923 else { 03924 for (c = 0; c < SINGLE_BYTE_SIZE; c++) { 03925 if (ONIGENC_IS_ASCII_CODE_CTYPE((OnigCodePoint )c, ctype)) 03926 BITSET_SET_BIT_CHKDUP(cc->bs, c); 03927 } 03928 } 03929 return 0; 03930 break; 03931 } 03932 03933 r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sb_out, &ranges); 03934 if (r == 0) { 03935 return add_ctype_to_cc_by_range(cc, ctype, not, env, sb_out, ranges); 03936 } 03937 else if (r != ONIG_NO_SUPPORT_CONFIG) { 03938 return r; 03939 } 03940 03941 r = 0; 03942 switch (ctype) { 03943 case ONIGENC_CTYPE_ALPHA: 03944 case ONIGENC_CTYPE_BLANK: 03945 case ONIGENC_CTYPE_CNTRL: 03946 case ONIGENC_CTYPE_DIGIT: 03947 case ONIGENC_CTYPE_LOWER: 03948 case ONIGENC_CTYPE_PUNCT: 03949 case ONIGENC_CTYPE_SPACE: 03950 case ONIGENC_CTYPE_UPPER: 03951 case ONIGENC_CTYPE_XDIGIT: 03952 case ONIGENC_CTYPE_ASCII: 03953 case ONIGENC_CTYPE_ALNUM: 03954 if (not != 0) { 03955 for (c = 0; c < SINGLE_BYTE_SIZE; c++) { 03956 if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype)) 03957 BITSET_SET_BIT_CHKDUP(cc->bs, c); 03958 } 03959 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf); 03960 } 03961 else { 03962 for (c = 0; c < SINGLE_BYTE_SIZE; c++) { 03963 if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype)) 03964 BITSET_SET_BIT_CHKDUP(cc->bs, c); 03965 } 03966 } 03967 break; 03968 03969 case ONIGENC_CTYPE_GRAPH: 03970 case ONIGENC_CTYPE_PRINT: 03971 if (not != 0) { 03972 for (c = 0; c < SINGLE_BYTE_SIZE; c++) { 03973 if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype)) 03974 BITSET_SET_BIT_CHKDUP(cc->bs, c); 03975 } 03976 } 03977 else { 03978 for (c = 0; c < SINGLE_BYTE_SIZE; c++) { 03979 if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype)) 03980 BITSET_SET_BIT_CHKDUP(cc->bs, c); 03981 } 03982 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf); 03983 } 03984 break; 03985 03986 case ONIGENC_CTYPE_WORD: 03987 if (not == 0) { 03988 for (c = 0; c < SINGLE_BYTE_SIZE; c++) { 03989 if (IS_CODE_SB_WORD(enc, c)) BITSET_SET_BIT_CHKDUP(cc->bs, c); 03990 } 03991 ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf); 03992 } 03993 else { 03994 for (c = 0; c < SINGLE_BYTE_SIZE; c++) { 03995 if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* check invalid code point */ 03996 && ! ONIGENC_IS_CODE_WORD(enc, c)) 03997 BITSET_SET_BIT_CHKDUP(cc->bs, c); 03998 } 03999 } 04000 break; 04001 04002 default: 04003 return ONIGERR_PARSER_BUG; 04004 break; 04005 } 04006 04007 return r; 04008 } 04009 04010 static int 04011 parse_posix_bracket(CClassNode* cc, UChar** src, UChar* end, ScanEnv* env) 04012 { 04013 #define POSIX_BRACKET_CHECK_LIMIT_LENGTH 20 04014 #define POSIX_BRACKET_NAME_MIN_LEN 4 04015 04016 static const PosixBracketEntryType PBS[] = { 04017 { (UChar* )"alnum", ONIGENC_CTYPE_ALNUM, 5 }, 04018 { (UChar* )"alpha", ONIGENC_CTYPE_ALPHA, 5 }, 04019 { (UChar* )"blank", ONIGENC_CTYPE_BLANK, 5 }, 04020 { (UChar* )"cntrl", ONIGENC_CTYPE_CNTRL, 5 }, 04021 { (UChar* )"digit", ONIGENC_CTYPE_DIGIT, 5 }, 04022 { (UChar* )"graph", ONIGENC_CTYPE_GRAPH, 5 }, 04023 { (UChar* )"lower", ONIGENC_CTYPE_LOWER, 5 }, 04024 { (UChar* )"print", ONIGENC_CTYPE_PRINT, 5 }, 04025 { (UChar* )"punct", ONIGENC_CTYPE_PUNCT, 5 }, 04026 { (UChar* )"space", ONIGENC_CTYPE_SPACE, 5 }, 04027 { (UChar* )"upper", ONIGENC_CTYPE_UPPER, 5 }, 04028 { (UChar* )"xdigit", ONIGENC_CTYPE_XDIGIT, 6 }, 04029 { (UChar* )"ascii", ONIGENC_CTYPE_ASCII, 5 }, 04030 { (UChar* )"word", ONIGENC_CTYPE_WORD, 4 }, 04031 { (UChar* )NULL, -1, 0 } 04032 }; 04033 04034 const PosixBracketEntryType *pb; 04035 int not, i, r; 04036 OnigCodePoint c; 04037 OnigEncoding enc = env->enc; 04038 UChar *p = *src; 04039 PFETCH_READY; 04040 04041 if (PPEEK_IS('^')) { 04042 PINC; 04043 not = 1; 04044 } 04045 else 04046 not = 0; 04047 04048 if (onigenc_strlen(enc, p, end) < POSIX_BRACKET_NAME_MIN_LEN + 3) 04049 goto not_posix_bracket; 04050 04051 for (pb = PBS; IS_NOT_NULL(pb->name); pb++) { 04052 if (onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0) { 04053 p = (UChar* )onigenc_step(enc, p, end, pb->len); 04054 if (onigenc_with_ascii_strncmp(enc, p, end, (UChar* )":]", 2) != 0) 04055 return ONIGERR_INVALID_POSIX_BRACKET_TYPE; 04056 04057 r = add_ctype_to_cc(cc, pb->ctype, not, env); 04058 if (r != 0) return r; 04059 04060 PINC; PINC; 04061 *src = p; 04062 return 0; 04063 } 04064 } 04065 04066 not_posix_bracket: 04067 c = 0; 04068 i = 0; 04069 while (!PEND && ((c = PPEEK) != ':') && c != ']') { 04070 PINC; 04071 if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break; 04072 } 04073 if (c == ':' && ! PEND) { 04074 PINC; 04075 if (! PEND) { 04076 PFETCH(c); 04077 if (c == ']') 04078 return ONIGERR_INVALID_POSIX_BRACKET_TYPE; 04079 } 04080 } 04081 04082 return 1; /* 1: is not POSIX bracket, but no error. */ 04083 } 04084 04085 static int 04086 fetch_char_property_to_ctype(UChar** src, UChar* end, ScanEnv* env) 04087 { 04088 int r; 04089 OnigCodePoint c; 04090 OnigEncoding enc = env->enc; 04091 UChar *prev, *start, *p = *src; 04092 PFETCH_READY; 04093 04094 r = 0; 04095 start = prev = p; 04096 04097 while (!PEND) { 04098 prev = p; 04099 PFETCH(c); 04100 if (c == '}') { 04101 r = ONIGENC_PROPERTY_NAME_TO_CTYPE(enc, start, prev); 04102 if (r < 0) break; 04103 04104 *src = p; 04105 return r; 04106 } 04107 else if (c == '(' || c == ')' || c == '{' || c == '|') { 04108 r = ONIGERR_INVALID_CHAR_PROPERTY_NAME; 04109 break; 04110 } 04111 } 04112 04113 onig_scan_env_set_error_string(env, r, *src, prev); 04114 return r; 04115 } 04116 04117 static int 04118 parse_char_property(Node** np, OnigToken* tok, UChar** src, UChar* end, 04119 ScanEnv* env) 04120 { 04121 int r, ctype; 04122 CClassNode* cc; 04123 04124 ctype = fetch_char_property_to_ctype(src, end, env); 04125 if (ctype < 0) return ctype; 04126 04127 *np = node_new_cclass(); 04128 CHECK_NULL_RETURN_MEMERR(*np); 04129 cc = NCCLASS(*np); 04130 r = add_ctype_to_cc(cc, ctype, 0, env); 04131 if (r != 0) return r; 04132 if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc); 04133 04134 return 0; 04135 } 04136 04137 04138 enum CCSTATE { 04139 CCS_VALUE, 04140 CCS_RANGE, 04141 CCS_COMPLETE, 04142 CCS_START 04143 }; 04144 04145 enum CCVALTYPE { 04146 CCV_SB, 04147 CCV_CODE_POINT, 04148 CCV_CLASS 04149 }; 04150 04151 static int 04152 next_state_class(CClassNode* cc, OnigCodePoint* vs, enum CCVALTYPE* type, 04153 enum CCSTATE* state, ScanEnv* env) 04154 { 04155 int r; 04156 04157 if (*state == CCS_RANGE) 04158 return ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE; 04159 04160 if (*state == CCS_VALUE && *type != CCV_CLASS) { 04161 if (*type == CCV_SB) 04162 BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*vs)); 04163 else if (*type == CCV_CODE_POINT) { 04164 r = add_code_range(&(cc->mbuf), env, *vs, *vs); 04165 if (r < 0) return r; 04166 } 04167 } 04168 04169 *state = CCS_VALUE; 04170 *type = CCV_CLASS; 04171 return 0; 04172 } 04173 04174 static int 04175 next_state_val(CClassNode* cc, OnigCodePoint *vs, OnigCodePoint v, 04176 int* vs_israw, int v_israw, 04177 enum CCVALTYPE intype, enum CCVALTYPE* type, 04178 enum CCSTATE* state, ScanEnv* env) 04179 { 04180 int r; 04181 04182 switch (*state) { 04183 case CCS_VALUE: 04184 if (*type == CCV_SB) 04185 BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*vs)); 04186 else if (*type == CCV_CODE_POINT) { 04187 r = add_code_range(&(cc->mbuf), env, *vs, *vs); 04188 if (r < 0) return r; 04189 } 04190 break; 04191 04192 case CCS_RANGE: 04193 if (intype == *type) { 04194 if (intype == CCV_SB) { 04195 if (*vs > 0xff || v > 0xff) 04196 return ONIGERR_INVALID_CODE_POINT_VALUE; 04197 04198 if (*vs > v) { 04199 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC)) 04200 goto ccs_range_end; 04201 else 04202 return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS; 04203 } 04204 bitset_set_range(env, cc->bs, (int )*vs, (int )v); 04205 } 04206 else { 04207 r = add_code_range(&(cc->mbuf), env, *vs, v); 04208 if (r < 0) return r; 04209 } 04210 } 04211 else { 04212 #if 0 04213 if (intype == CCV_CODE_POINT && *type == CCV_SB) { 04214 #endif 04215 if (*vs > v) { 04216 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC)) 04217 goto ccs_range_end; 04218 else 04219 return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS; 04220 } 04221 bitset_set_range(env, cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff)); 04222 r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*vs, v); 04223 if (r < 0) return r; 04224 #if 0 04225 } 04226 else 04227 return ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE; 04228 #endif 04229 } 04230 ccs_range_end: 04231 *state = CCS_COMPLETE; 04232 break; 04233 04234 case CCS_COMPLETE: 04235 case CCS_START: 04236 *state = CCS_VALUE; 04237 break; 04238 04239 default: 04240 break; 04241 } 04242 04243 *vs_israw = v_israw; 04244 *vs = v; 04245 *type = intype; 04246 return 0; 04247 } 04248 04249 static int 04250 code_exist_check(OnigCodePoint c, UChar* from, UChar* end, int ignore_escaped, 04251 ScanEnv* env) 04252 { 04253 int in_esc; 04254 OnigCodePoint code; 04255 OnigEncoding enc = env->enc; 04256 UChar* p = from; 04257 PFETCH_READY; 04258 04259 in_esc = 0; 04260 while (! PEND) { 04261 if (ignore_escaped && in_esc) { 04262 in_esc = 0; 04263 } 04264 else { 04265 PFETCH(code); 04266 if (code == c) return 1; 04267 if (code == MC_ESC(env->syntax)) in_esc = 1; 04268 } 04269 } 04270 return 0; 04271 } 04272 04273 static int 04274 parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end, 04275 ScanEnv* env) 04276 { 04277 int r, neg, len, fetched, and_start; 04278 OnigCodePoint v, vs; 04279 UChar *p; 04280 Node* node; 04281 CClassNode *cc, *prev_cc; 04282 CClassNode work_cc; 04283 04284 enum CCSTATE state; 04285 enum CCVALTYPE val_type, in_type; 04286 int val_israw, in_israw; 04287 04288 prev_cc = (CClassNode* )NULL; 04289 *np = NULL_NODE; 04290 r = fetch_token_in_cc(tok, src, end, env); 04291 if (r == TK_CHAR && tok->u.c == '^' && tok->escaped == 0) { 04292 neg = 1; 04293 r = fetch_token_in_cc(tok, src, end, env); 04294 } 04295 else { 04296 neg = 0; 04297 } 04298 04299 if (r < 0) return r; 04300 if (r == TK_CC_CLOSE) { 04301 if (! code_exist_check((OnigCodePoint )']', 04302 *src, env->pattern_end, 1, env)) 04303 return ONIGERR_EMPTY_CHAR_CLASS; 04304 04305 CC_ESC_WARN(env, (UChar* )"]"); 04306 r = tok->type = TK_CHAR; /* allow []...] */ 04307 } 04308 04309 *np = node = node_new_cclass(); 04310 CHECK_NULL_RETURN_MEMERR(node); 04311 cc = NCCLASS(node); 04312 04313 and_start = 0; 04314 state = CCS_START; 04315 p = *src; 04316 while (r != TK_CC_CLOSE) { 04317 fetched = 0; 04318 switch (r) { 04319 case TK_CHAR: 04320 if ((tok->u.code >= SINGLE_BYTE_SIZE) || 04321 (len = ONIGENC_CODE_TO_MBCLEN(env->enc, tok->u.c)) > 1) { 04322 in_type = CCV_CODE_POINT; 04323 } 04324 else if (len < 0) { 04325 r = len; 04326 goto err; 04327 } 04328 else { 04329 sb_char: 04330 in_type = CCV_SB; 04331 } 04332 v = (OnigCodePoint )tok->u.c; 04333 in_israw = 0; 04334 goto val_entry2; 04335 break; 04336 04337 case TK_RAW_BYTE: 04338 /* tok->base != 0 : octal or hexadec. */ 04339 if (! ONIGENC_IS_SINGLEBYTE(env->enc) && tok->base != 0) { 04340 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN]; 04341 UChar* bufe = buf + ONIGENC_CODE_TO_MBC_MAXLEN; 04342 UChar* psave = p; 04343 int i, base = tok->base; 04344 04345 buf[0] = tok->u.c; 04346 for (i = 1; i < ONIGENC_MBC_MAXLEN(env->enc); i++) { 04347 r = fetch_token_in_cc(tok, &p, end, env); 04348 if (r < 0) goto err; 04349 if (r != TK_RAW_BYTE || tok->base != base) { 04350 fetched = 1; 04351 break; 04352 } 04353 buf[i] = tok->u.c; 04354 } 04355 04356 if (i < ONIGENC_MBC_MINLEN(env->enc)) { 04357 r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING; 04358 goto err; 04359 } 04360 04361 len = enclen(env->enc, buf, buf+i); 04362 if (i < len) { 04363 r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING; 04364 goto err; 04365 } 04366 else if (i > len) { /* fetch back */ 04367 p = psave; 04368 for (i = 1; i < len; i++) { 04369 r = fetch_token_in_cc(tok, &p, end, env); 04370 } 04371 fetched = 0; 04372 } 04373 04374 if (i == 1) { 04375 v = (OnigCodePoint )buf[0]; 04376 goto raw_single; 04377 } 04378 else { 04379 v = ONIGENC_MBC_TO_CODE(env->enc, buf, bufe); 04380 in_type = CCV_CODE_POINT; 04381 } 04382 } 04383 else { 04384 v = (OnigCodePoint )tok->u.c; 04385 raw_single: 04386 in_type = CCV_SB; 04387 } 04388 in_israw = 1; 04389 goto val_entry2; 04390 break; 04391 04392 case TK_CODE_POINT: 04393 v = tok->u.code; 04394 in_israw = 1; 04395 val_entry: 04396 len = ONIGENC_CODE_TO_MBCLEN(env->enc, v); 04397 if (len < 0) { 04398 r = len; 04399 goto err; 04400 } 04401 in_type = (len == 1 ? CCV_SB : CCV_CODE_POINT); 04402 val_entry2: 04403 r = next_state_val(cc, &vs, v, &val_israw, in_israw, in_type, &val_type, 04404 &state, env); 04405 if (r != 0) goto err; 04406 break; 04407 04408 case TK_POSIX_BRACKET_OPEN: 04409 r = parse_posix_bracket(cc, &p, end, env); 04410 if (r < 0) goto err; 04411 if (r == 1) { /* is not POSIX bracket */ 04412 CC_ESC_WARN(env, (UChar* )"["); 04413 p = tok->backp; 04414 v = (OnigCodePoint )tok->u.c; 04415 in_israw = 0; 04416 goto val_entry; 04417 } 04418 goto next_class; 04419 break; 04420 04421 case TK_CHAR_TYPE: 04422 r = add_ctype_to_cc(cc, tok->u.prop.ctype, tok->u.prop.not, env); 04423 if (r != 0) return r; 04424 04425 next_class: 04426 r = next_state_class(cc, &vs, &val_type, &state, env); 04427 if (r != 0) goto err; 04428 break; 04429 04430 case TK_CHAR_PROPERTY: 04431 { 04432 int ctype; 04433 04434 ctype = fetch_char_property_to_ctype(&p, end, env); 04435 if (ctype < 0) return ctype; 04436 r = add_ctype_to_cc(cc, ctype, tok->u.prop.not, env); 04437 if (r != 0) return r; 04438 goto next_class; 04439 } 04440 break; 04441 04442 case TK_CC_RANGE: 04443 if (state == CCS_VALUE) { 04444 r = fetch_token_in_cc(tok, &p, end, env); 04445 if (r < 0) goto err; 04446 fetched = 1; 04447 if (r == TK_CC_CLOSE) { /* allow [x-] */ 04448 range_end_val: 04449 v = (OnigCodePoint )'-'; 04450 in_israw = 0; 04451 goto val_entry; 04452 } 04453 else if (r == TK_CC_AND) { 04454 CC_ESC_WARN(env, (UChar* )"-"); 04455 goto range_end_val; 04456 } 04457 state = CCS_RANGE; 04458 } 04459 else if (state == CCS_START) { 04460 /* [-xa] is allowed */ 04461 v = (OnigCodePoint )tok->u.c; 04462 in_israw = 0; 04463 04464 r = fetch_token_in_cc(tok, &p, end, env); 04465 if (r < 0) goto err; 04466 fetched = 1; 04467 /* [--x] or [a&&-x] is warned. */ 04468 if (r == TK_CC_RANGE || and_start != 0) 04469 CC_ESC_WARN(env, (UChar* )"-"); 04470 04471 goto val_entry; 04472 } 04473 else if (state == CCS_RANGE) { 04474 CC_ESC_WARN(env, (UChar* )"-"); 04475 goto sb_char; /* [!--x] is allowed */ 04476 } 04477 else { /* CCS_COMPLETE */ 04478 r = fetch_token_in_cc(tok, &p, end, env); 04479 if (r < 0) goto err; 04480 fetched = 1; 04481 if (r == TK_CC_CLOSE) goto range_end_val; /* allow [a-b-] */ 04482 else if (r == TK_CC_AND) { 04483 CC_ESC_WARN(env, (UChar* )"-"); 04484 goto range_end_val; 04485 } 04486 04487 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC)) { 04488 CC_ESC_WARN(env, (UChar* )"-"); 04489 goto sb_char; /* [0-9-a] is allowed as [0-9\-a] */ 04490 } 04491 r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS; 04492 goto err; 04493 } 04494 break; 04495 04496 case TK_CC_CC_OPEN: /* [ */ 04497 { 04498 Node *anode; 04499 CClassNode* acc; 04500 04501 r = parse_char_class(&anode, tok, &p, end, env); 04502 if (r == 0) { 04503 acc = NCCLASS(anode); 04504 r = or_cclass(cc, acc, env); 04505 } 04506 onig_node_free(anode); 04507 if (r != 0) goto err; 04508 } 04509 break; 04510 04511 case TK_CC_AND: /* && */ 04512 { 04513 if (state == CCS_VALUE) { 04514 r = next_state_val(cc, &vs, 0, &val_israw, 0, val_type, 04515 &val_type, &state, env); 04516 if (r != 0) goto err; 04517 } 04518 /* initialize local variables */ 04519 and_start = 1; 04520 state = CCS_START; 04521 04522 if (IS_NOT_NULL(prev_cc)) { 04523 r = and_cclass(prev_cc, cc, env); 04524 if (r != 0) goto err; 04525 bbuf_free(cc->mbuf); 04526 } 04527 else { 04528 prev_cc = cc; 04529 cc = &work_cc; 04530 } 04531 initialize_cclass(cc); 04532 } 04533 break; 04534 04535 case TK_EOT: 04536 r = ONIGERR_PREMATURE_END_OF_CHAR_CLASS; 04537 goto err; 04538 break; 04539 default: 04540 r = ONIGERR_PARSER_BUG; 04541 goto err; 04542 break; 04543 } 04544 04545 if (fetched) 04546 r = tok->type; 04547 else { 04548 r = fetch_token_in_cc(tok, &p, end, env); 04549 if (r < 0) goto err; 04550 } 04551 } 04552 04553 if (state == CCS_VALUE) { 04554 r = next_state_val(cc, &vs, 0, &val_israw, 0, val_type, 04555 &val_type, &state, env); 04556 if (r != 0) goto err; 04557 } 04558 04559 if (IS_NOT_NULL(prev_cc)) { 04560 r = and_cclass(prev_cc, cc, env); 04561 if (r != 0) goto err; 04562 bbuf_free(cc->mbuf); 04563 cc = prev_cc; 04564 } 04565 04566 if (neg != 0) 04567 NCCLASS_SET_NOT(cc); 04568 else 04569 NCCLASS_CLEAR_NOT(cc); 04570 if (IS_NCCLASS_NOT(cc) && 04571 IS_SYNTAX_BV(env->syntax, ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC)) { 04572 int is_empty; 04573 04574 is_empty = (IS_NULL(cc->mbuf) ? 1 : 0); 04575 if (is_empty != 0) 04576 BITSET_IS_EMPTY(cc->bs, is_empty); 04577 04578 if (is_empty == 0) { 04579 #define NEWLINE_CODE 0x0a 04580 04581 if (ONIGENC_IS_CODE_NEWLINE(env->enc, NEWLINE_CODE)) { 04582 if (ONIGENC_CODE_TO_MBCLEN(env->enc, NEWLINE_CODE) == 1) 04583 BITSET_SET_BIT_CHKDUP(cc->bs, NEWLINE_CODE); 04584 else 04585 add_code_range(&(cc->mbuf), env, NEWLINE_CODE, NEWLINE_CODE); 04586 } 04587 } 04588 } 04589 *src = p; 04590 return 0; 04591 04592 err: 04593 if (cc != NCCLASS(*np)) 04594 bbuf_free(cc->mbuf); 04595 return r; 04596 } 04597 04598 static int parse_subexp(Node** top, OnigToken* tok, int term, 04599 UChar** src, UChar* end, ScanEnv* env); 04600 04601 static int 04602 parse_enclose(Node** np, OnigToken* tok, int term, UChar** src, UChar* end, 04603 ScanEnv* env) 04604 { 04605 int r, num; 04606 Node *target; 04607 OnigOptionType option; 04608 OnigCodePoint c; 04609 OnigEncoding enc = env->enc; 04610 04611 #ifdef USE_NAMED_GROUP 04612 int list_capture; 04613 #endif 04614 04615 UChar* p = *src; 04616 PFETCH_READY; 04617 04618 *np = NULL; 04619 if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS; 04620 04621 option = env->option; 04622 if (PPEEK_IS('?') && 04623 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) { 04624 PINC; 04625 if (PEND) return ONIGERR_END_PATTERN_IN_GROUP; 04626 04627 PFETCH(c); 04628 switch (c) { 04629 case ':': /* (?:...) grouping only */ 04630 group: 04631 r = fetch_token(tok, &p, end, env); 04632 if (r < 0) return r; 04633 r = parse_subexp(np, tok, term, &p, end, env); 04634 if (r < 0) return r; 04635 *src = p; 04636 return 1; /* group */ 04637 break; 04638 04639 case '=': 04640 *np = onig_node_new_anchor(ANCHOR_PREC_READ); 04641 break; 04642 case '!': /* preceding read */ 04643 *np = onig_node_new_anchor(ANCHOR_PREC_READ_NOT); 04644 break; 04645 case '>': /* (?>...) stop backtrack */ 04646 *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK); 04647 break; 04648 04649 #ifdef USE_NAMED_GROUP 04650 case '\'': 04651 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) { 04652 goto named_group1; 04653 } 04654 else 04655 return ONIGERR_UNDEFINED_GROUP_OPTION; 04656 break; 04657 #endif 04658 04659 case '<': /* look behind (?<=...), (?<!...) */ 04660 PFETCH(c); 04661 if (c == '=') 04662 *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND); 04663 else if (c == '!') 04664 *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND_NOT); 04665 #ifdef USE_NAMED_GROUP 04666 else { 04667 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) { 04668 UChar *name; 04669 UChar *name_end; 04670 04671 PUNFETCH; 04672 c = '<'; 04673 04674 named_group1: 04675 list_capture = 0; 04676 04677 named_group2: 04678 name = p; 04679 r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0); 04680 if (r < 0) return r; 04681 04682 num = scan_env_add_mem_entry(env); 04683 if (num < 0) return num; 04684 if (list_capture != 0 && num >= (int )BIT_STATUS_BITS_NUM) 04685 return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY; 04686 04687 r = name_add(env->reg, name, name_end, num, env); 04688 if (r != 0) return r; 04689 *np = node_new_enclose_memory(env->option, 1); 04690 CHECK_NULL_RETURN_MEMERR(*np); 04691 NENCLOSE(*np)->regnum = num; 04692 if (list_capture != 0) 04693 BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num); 04694 env->num_named++; 04695 } 04696 else { 04697 return ONIGERR_UNDEFINED_GROUP_OPTION; 04698 } 04699 } 04700 #else 04701 else { 04702 return ONIGERR_UNDEFINED_GROUP_OPTION; 04703 } 04704 #endif 04705 break; 04706 04707 case '@': 04708 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY)) { 04709 #ifdef USE_NAMED_GROUP 04710 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) { 04711 PFETCH(c); 04712 if (c == '<' || c == '\'') { 04713 list_capture = 1; 04714 goto named_group2; /* (?@<name>...) */ 04715 } 04716 PUNFETCH; 04717 } 04718 #endif 04719 *np = node_new_enclose_memory(env->option, 0); 04720 CHECK_NULL_RETURN_MEMERR(*np); 04721 num = scan_env_add_mem_entry(env); 04722 if (num < 0) { 04723 onig_node_free(*np); 04724 return num; 04725 } 04726 else if (num >= (int )BIT_STATUS_BITS_NUM) { 04727 onig_node_free(*np); 04728 return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY; 04729 } 04730 NENCLOSE(*np)->regnum = num; 04731 BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num); 04732 } 04733 else { 04734 return ONIGERR_UNDEFINED_GROUP_OPTION; 04735 } 04736 break; 04737 04738 #ifdef USE_POSIXLINE_OPTION 04739 case 'p': 04740 #endif 04741 case '-': case 'i': case 'm': case 's': case 'x': 04742 { 04743 int neg = 0; 04744 04745 while (1) { 04746 switch (c) { 04747 case ':': 04748 case ')': 04749 break; 04750 04751 case '-': neg = 1; break; 04752 case 'x': ONOFF(option, ONIG_OPTION_EXTEND, neg); break; 04753 case 'i': ONOFF(option, ONIG_OPTION_IGNORECASE, neg); break; 04754 case 's': 04755 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) { 04756 ONOFF(option, ONIG_OPTION_MULTILINE, neg); 04757 } 04758 else 04759 return ONIGERR_UNDEFINED_GROUP_OPTION; 04760 break; 04761 04762 case 'm': 04763 if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) { 04764 ONOFF(option, ONIG_OPTION_SINGLELINE, (neg == 0 ? 1 : 0)); 04765 } 04766 else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) { 04767 ONOFF(option, ONIG_OPTION_MULTILINE, neg); 04768 } 04769 else 04770 return ONIGERR_UNDEFINED_GROUP_OPTION; 04771 break; 04772 #ifdef USE_POSIXLINE_OPTION 04773 case 'p': 04774 ONOFF(option, ONIG_OPTION_MULTILINE|ONIG_OPTION_SINGLELINE, neg); 04775 break; 04776 #endif 04777 default: 04778 return ONIGERR_UNDEFINED_GROUP_OPTION; 04779 } 04780 04781 if (c == ')') { 04782 *np = node_new_option(option); 04783 CHECK_NULL_RETURN_MEMERR(*np); 04784 *src = p; 04785 return 2; /* option only */ 04786 } 04787 else if (c == ':') { 04788 OnigOptionType prev = env->option; 04789 04790 env->option = option; 04791 r = fetch_token(tok, &p, end, env); 04792 if (r < 0) return r; 04793 r = parse_subexp(&target, tok, term, &p, end, env); 04794 env->option = prev; 04795 if (r < 0) return r; 04796 *np = node_new_option(option); 04797 CHECK_NULL_RETURN_MEMERR(*np); 04798 NENCLOSE(*np)->target = target; 04799 *src = p; 04800 return 0; 04801 } 04802 04803 if (PEND) return ONIGERR_END_PATTERN_IN_GROUP; 04804 PFETCH(c); 04805 } 04806 } 04807 break; 04808 04809 default: 04810 return ONIGERR_UNDEFINED_GROUP_OPTION; 04811 } 04812 } 04813 else { 04814 if (ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_DONT_CAPTURE_GROUP)) 04815 goto group; 04816 04817 *np = node_new_enclose_memory(env->option, 0); 04818 CHECK_NULL_RETURN_MEMERR(*np); 04819 num = scan_env_add_mem_entry(env); 04820 if (num < 0) return num; 04821 NENCLOSE(*np)->regnum = num; 04822 } 04823 04824 CHECK_NULL_RETURN_MEMERR(*np); 04825 r = fetch_token(tok, &p, end, env); 04826 if (r < 0) return r; 04827 r = parse_subexp(&target, tok, term, &p, end, env); 04828 if (r < 0) { 04829 onig_node_free(target); 04830 return r; 04831 } 04832 04833 if (NTYPE(*np) == NT_ANCHOR) 04834 NANCHOR(*np)->target = target; 04835 else { 04836 NENCLOSE(*np)->target = target; 04837 if (NENCLOSE(*np)->type == ENCLOSE_MEMORY) { 04838 /* Don't move this to previous of parse_subexp() */ 04839 r = scan_env_set_mem_node(env, NENCLOSE(*np)->regnum, *np); 04840 if (r != 0) return r; 04841 } 04842 } 04843 04844 *src = p; 04845 return 0; 04846 } 04847 04848 static const char* const PopularQStr[] = { 04849 "?", "*", "+", "??", "*?", "+?" 04850 }; 04851 04852 static const char* const ReduceQStr[] = { 04853 "", "", "*", "*?", "??", "+ and ??", "+? and ?" 04854 }; 04855 04856 static int 04857 set_quantifier(Node* qnode, Node* target, int group, ScanEnv* env) 04858 { 04859 QtfrNode* qn; 04860 04861 qn = NQTFR(qnode); 04862 if (qn->lower == 1 && qn->upper == 1) { 04863 return 1; 04864 } 04865 04866 switch (NTYPE(target)) { 04867 case NT_STR: 04868 if (! group) { 04869 StrNode* sn = NSTR(target); 04870 if (str_node_can_be_split(sn, env->enc)) { 04871 Node* n = str_node_split_last_char(sn, env->enc); 04872 if (IS_NOT_NULL(n)) { 04873 qn->target = n; 04874 return 2; 04875 } 04876 } 04877 } 04878 break; 04879 04880 case NT_QTFR: 04881 { /* check redundant double repeat. */ 04882 /* verbose warn (?:.?)? etc... but not warn (.?)? etc... */ 04883 QtfrNode* qnt = NQTFR(target); 04884 int nestq_num = popular_quantifier_num(qn); 04885 int targetq_num = popular_quantifier_num(qnt); 04886 04887 #ifdef USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR 04888 if (!IS_QUANTIFIER_BY_NUMBER(qn) && !IS_QUANTIFIER_BY_NUMBER(qnt) && 04889 IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT)) { 04890 UChar buf[WARN_BUFSIZE]; 04891 04892 switch(ReduceTypeTable[targetq_num][nestq_num]) { 04893 case RQ_ASIS: 04894 break; 04895 04896 case RQ_DEL: 04897 if (onig_verb_warn != onig_null_warn) { 04898 onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc, 04899 env->pattern, env->pattern_end, 04900 (UChar* )"redundant nested repeat operator"); 04901 (*onig_verb_warn)((char* )buf); 04902 } 04903 goto warn_exit; 04904 break; 04905 04906 default: 04907 if (onig_verb_warn != onig_null_warn) { 04908 onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc, 04909 env->pattern, env->pattern_end, 04910 (UChar* )"nested repeat operator %s and %s was replaced with '%s'", 04911 PopularQStr[targetq_num], PopularQStr[nestq_num], 04912 ReduceQStr[ReduceTypeTable[targetq_num][nestq_num]]); 04913 (*onig_verb_warn)((char* )buf); 04914 } 04915 goto warn_exit; 04916 break; 04917 } 04918 } 04919 04920 warn_exit: 04921 #endif 04922 if (targetq_num >= 0) { 04923 if (nestq_num >= 0) { 04924 onig_reduce_nested_quantifier(qnode, target); 04925 goto q_exit; 04926 } 04927 else if (targetq_num == 1 || targetq_num == 2) { /* * or + */ 04928 /* (?:a*){n,m}, (?:a+){n,m} => (?:a*){n,n}, (?:a+){n,n} */ 04929 if (! IS_REPEAT_INFINITE(qn->upper) && qn->upper > 1 && qn->greedy) { 04930 qn->upper = (qn->lower == 0 ? 1 : qn->lower); 04931 } 04932 } 04933 } 04934 } 04935 break; 04936 04937 default: 04938 break; 04939 } 04940 04941 qn->target = target; 04942 q_exit: 04943 return 0; 04944 } 04945 04946 04947 #ifdef USE_SHARED_CCLASS_TABLE 04948 04949 #define THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS 8 04950 04951 /* for ctype node hash table */ 04952 04953 typedef struct { 04954 OnigEncoding enc; 04955 int not; 04956 int type; 04957 } type_cclass_key; 04958 04959 static int type_cclass_cmp(type_cclass_key* x, type_cclass_key* y) 04960 { 04961 if (x->type != y->type) return 1; 04962 if (x->enc != y->enc) return 1; 04963 if (x->not != y->not) return 1; 04964 return 0; 04965 } 04966 04967 static st_index_t type_cclass_hash(type_cclass_key* key) 04968 { 04969 int i, val; 04970 UChar *p; 04971 04972 val = 0; 04973 04974 p = (UChar* )&(key->enc); 04975 for (i = 0; i < (int )sizeof(key->enc); i++) { 04976 val = val * 997 + (int )*p++; 04977 } 04978 04979 p = (UChar* )(&key->type); 04980 for (i = 0; i < (int )sizeof(key->type); i++) { 04981 val = val * 997 + (int )*p++; 04982 } 04983 04984 val += key->not; 04985 return val + (val >> 5); 04986 } 04987 04988 static const struct st_hash_type type_type_cclass_hash = { 04989 type_cclass_cmp, 04990 type_cclass_hash, 04991 }; 04992 04993 static st_table* OnigTypeCClassTable; 04994 04995 04996 static int 04997 i_free_shared_class(type_cclass_key* key, Node* node, void* arg ARG_UNUSED) 04998 { 04999 if (IS_NOT_NULL(node)) { 05000 CClassNode* cc = NCCLASS(node); 05001 if (IS_NOT_NULL(cc->mbuf)) xfree(cc->mbuf); 05002 xfree(node); 05003 } 05004 05005 if (IS_NOT_NULL(key)) xfree(key); 05006 return ST_DELETE; 05007 } 05008 05009 extern int 05010 onig_free_shared_cclass_table(void) 05011 { 05012 THREAD_ATOMIC_START; 05013 if (IS_NOT_NULL(OnigTypeCClassTable)) { 05014 onig_st_foreach(OnigTypeCClassTable, i_free_shared_class, 0); 05015 onig_st_free_table(OnigTypeCClassTable); 05016 OnigTypeCClassTable = NULL; 05017 } 05018 THREAD_ATOMIC_END; 05019 05020 return 0; 05021 } 05022 05023 #endif /* USE_SHARED_CCLASS_TABLE */ 05024 05025 05026 #ifndef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS 05027 static int 05028 clear_not_flag_cclass(CClassNode* cc, OnigEncoding enc) 05029 { 05030 BBuf *tbuf; 05031 int r; 05032 05033 if (IS_NCCLASS_NOT(cc)) { 05034 bitset_invert(cc->bs); 05035 05036 if (! ONIGENC_IS_SINGLEBYTE(enc)) { 05037 r = not_code_range_buf(enc, cc->mbuf, &tbuf); 05038 if (r != 0) return r; 05039 05040 bbuf_free(cc->mbuf); 05041 cc->mbuf = tbuf; 05042 } 05043 05044 NCCLASS_CLEAR_NOT(cc); 05045 } 05046 05047 return 0; 05048 } 05049 #endif /* CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS */ 05050 05051 typedef struct { 05052 ScanEnv* env; 05053 CClassNode* cc; 05054 Node* alt_root; 05055 Node** ptail; 05056 } IApplyCaseFoldArg; 05057 05058 static int 05059 i_apply_case_fold(OnigCodePoint from, OnigCodePoint to[], 05060 int to_len, void* arg) 05061 { 05062 IApplyCaseFoldArg* iarg; 05063 ScanEnv* env; 05064 CClassNode* cc; 05065 BitSetRef bs; 05066 05067 iarg = (IApplyCaseFoldArg* )arg; 05068 env = iarg->env; 05069 cc = iarg->cc; 05070 bs = cc->bs; 05071 05072 if (to_len == 1) { 05073 int is_in = onig_is_code_in_cc(env->enc, from, cc); 05074 #ifdef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS 05075 if ((is_in != 0 && !IS_NCCLASS_NOT(cc)) || 05076 (is_in == 0 && IS_NCCLASS_NOT(cc))) { 05077 if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) { 05078 add_code_range0(&(cc->mbuf), env, *to, *to, 0); 05079 } 05080 else { 05081 BITSET_SET_BIT(bs, *to); 05082 } 05083 } 05084 #else 05085 if (is_in != 0) { 05086 if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) { 05087 if (IS_NCCLASS_NOT(cc)) clear_not_flag_cclass(cc, env->enc); 05088 add_code_range0(&(cc->mbuf), env, *to, *to, 0); 05089 } 05090 else { 05091 if (IS_NCCLASS_NOT(cc)) { 05092 BITSET_CLEAR_BIT(bs, *to); 05093 } 05094 else 05095 BITSET_SET_BIT(bs, *to); 05096 } 05097 } 05098 #endif /* CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS */ 05099 } 05100 else { 05101 int r, i, len; 05102 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN]; 05103 Node *snode = NULL_NODE; 05104 05105 if (onig_is_code_in_cc(env->enc, from, cc) 05106 #ifdef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS 05107 && !IS_NCCLASS_NOT(cc) 05108 #endif 05109 ) { 05110 for (i = 0; i < to_len; i++) { 05111 len = ONIGENC_CODE_TO_MBC(env->enc, to[i], buf); 05112 if (i == 0) { 05113 snode = onig_node_new_str(buf, buf + len); 05114 CHECK_NULL_RETURN_MEMERR(snode); 05115 05116 /* char-class expanded multi-char only 05117 compare with string folded at match time. */ 05118 NSTRING_SET_AMBIG(snode); 05119 } 05120 else { 05121 r = onig_node_str_cat(snode, buf, buf + len); 05122 if (r < 0) { 05123 onig_node_free(snode); 05124 return r; 05125 } 05126 } 05127 } 05128 05129 *(iarg->ptail) = onig_node_new_alt(snode, NULL_NODE); 05130 CHECK_NULL_RETURN_MEMERR(*(iarg->ptail)); 05131 iarg->ptail = &(NCDR((*(iarg->ptail)))); 05132 } 05133 } 05134 05135 return 0; 05136 } 05137 05138 static int 05139 parse_exp(Node** np, OnigToken* tok, int term, 05140 UChar** src, UChar* end, ScanEnv* env) 05141 { 05142 int r, len, group = 0; 05143 Node* qn; 05144 Node** targetp; 05145 05146 *np = NULL; 05147 if (tok->type == (enum TokenSyms )term) 05148 goto end_of_token; 05149 05150 switch (tok->type) { 05151 case TK_ALT: 05152 case TK_EOT: 05153 end_of_token: 05154 *np = node_new_empty(); 05155 return tok->type; 05156 05157 case TK_SUBEXP_OPEN: 05158 r = parse_enclose(np, tok, TK_SUBEXP_CLOSE, src, end, env); 05159 if (r < 0) return r; 05160 if (r == 1) group = 1; 05161 else if (r == 2) { /* option only */ 05162 Node* target; 05163 OnigOptionType prev = env->option; 05164 05165 env->option = NENCLOSE(*np)->option; 05166 r = fetch_token(tok, src, end, env); 05167 if (r < 0) return r; 05168 r = parse_subexp(&target, tok, term, src, end, env); 05169 env->option = prev; 05170 if (r < 0) { 05171 onig_node_free(target); 05172 return r; 05173 } 05174 NENCLOSE(*np)->target = target; 05175 return tok->type; 05176 } 05177 break; 05178 05179 case TK_SUBEXP_CLOSE: 05180 if (! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP)) 05181 return ONIGERR_UNMATCHED_CLOSE_PARENTHESIS; 05182 05183 if (tok->escaped) goto tk_raw_byte; 05184 else goto tk_byte; 05185 break; 05186 05187 case TK_STRING: 05188 tk_byte: 05189 { 05190 *np = node_new_str(tok->backp, *src); 05191 CHECK_NULL_RETURN_MEMERR(*np); 05192 05193 while (1) { 05194 r = fetch_token(tok, src, end, env); 05195 if (r < 0) return r; 05196 if (r != TK_STRING) break; 05197 05198 r = onig_node_str_cat(*np, tok->backp, *src); 05199 if (r < 0) return r; 05200 } 05201 05202 string_end: 05203 targetp = np; 05204 goto repeat; 05205 } 05206 break; 05207 05208 case TK_RAW_BYTE: 05209 tk_raw_byte: 05210 { 05211 *np = node_new_str_raw_char((UChar )tok->u.c); 05212 CHECK_NULL_RETURN_MEMERR(*np); 05213 len = 1; 05214 while (1) { 05215 if (len >= ONIGENC_MBC_MINLEN(env->enc)) { 05216 if (len == enclen(env->enc, NSTR(*np)->s, NSTR(*np)->end)) { 05217 r = fetch_token(tok, src, end, env); 05218 NSTRING_CLEAR_RAW(*np); 05219 goto string_end; 05220 } 05221 } 05222 05223 r = fetch_token(tok, src, end, env); 05224 if (r < 0) return r; 05225 if (r != TK_RAW_BYTE) { 05226 /* Don't use this, it is wrong for little endian encodings. */ 05227 #ifdef USE_PAD_TO_SHORT_BYTE_CHAR 05228 int rem; 05229 if (len < ONIGENC_MBC_MINLEN(env->enc)) { 05230 rem = ONIGENC_MBC_MINLEN(env->enc) - len; 05231 (void )node_str_head_pad(NSTR(*np), rem, (UChar )0); 05232 if (len + rem == enclen(env->enc, NSTR(*np)->s)) { 05233 NSTRING_CLEAR_RAW(*np); 05234 goto string_end; 05235 } 05236 } 05237 #endif 05238 return ONIGERR_TOO_SHORT_MULTI_BYTE_STRING; 05239 } 05240 05241 r = node_str_cat_char(*np, (UChar )tok->u.c); 05242 if (r < 0) return r; 05243 05244 len++; 05245 } 05246 } 05247 break; 05248 05249 case TK_CODE_POINT: 05250 { 05251 UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN]; 05252 int num = ONIGENC_CODE_TO_MBC(env->enc, tok->u.code, buf); 05253 if (num < 0) return num; 05254 #ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG 05255 *np = node_new_str_raw(buf, buf + num); 05256 #else 05257 *np = node_new_str(buf, buf + num); 05258 #endif 05259 CHECK_NULL_RETURN_MEMERR(*np); 05260 } 05261 break; 05262 05263 case TK_QUOTE_OPEN: 05264 { 05265 OnigCodePoint end_op[2]; 05266 UChar *qstart, *qend, *nextp; 05267 05268 end_op[0] = (OnigCodePoint )MC_ESC(env->syntax); 05269 end_op[1] = (OnigCodePoint )'E'; 05270 qstart = *src; 05271 qend = find_str_position(end_op, 2, qstart, end, &nextp, env->enc); 05272 if (IS_NULL(qend)) { 05273 nextp = qend = end; 05274 } 05275 *np = node_new_str(qstart, qend); 05276 CHECK_NULL_RETURN_MEMERR(*np); 05277 *src = nextp; 05278 } 05279 break; 05280 05281 case TK_CHAR_TYPE: 05282 { 05283 switch (tok->u.prop.ctype) { 05284 case ONIGENC_CTYPE_D: 05285 case ONIGENC_CTYPE_S: 05286 case ONIGENC_CTYPE_W: 05287 { 05288 CClassNode* cc; 05289 *np = node_new_cclass(); 05290 CHECK_NULL_RETURN_MEMERR(*np); 05291 cc = NCCLASS(*np); 05292 add_ctype_to_cc(cc, tok->u.prop.ctype, 0, env); 05293 if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc); 05294 } 05295 break; 05296 05297 case ONIGENC_CTYPE_WORD: 05298 *np = node_new_ctype(tok->u.prop.ctype, tok->u.prop.not); 05299 CHECK_NULL_RETURN_MEMERR(*np); 05300 break; 05301 05302 case ONIGENC_CTYPE_SPACE: 05303 case ONIGENC_CTYPE_DIGIT: 05304 case ONIGENC_CTYPE_XDIGIT: 05305 { 05306 CClassNode* cc; 05307 05308 #ifdef USE_SHARED_CCLASS_TABLE 05309 const OnigCodePoint *mbr; 05310 OnigCodePoint sb_out; 05311 05312 r = ONIGENC_GET_CTYPE_CODE_RANGE(env->enc, tok->u.prop.ctype, 05313 &sb_out, &mbr); 05314 if (r == 0 && 05315 ONIGENC_CODE_RANGE_NUM(mbr) 05316 >= THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS) { 05317 type_cclass_key key; 05318 type_cclass_key* new_key; 05319 05320 key.enc = env->enc; 05321 key.not = tok->u.prop.not; 05322 key.type = tok->u.prop.ctype; 05323 05324 THREAD_ATOMIC_START; 05325 05326 if (IS_NULL(OnigTypeCClassTable)) { 05327 OnigTypeCClassTable 05328 = onig_st_init_table_with_size(&type_type_cclass_hash, 10); 05329 if (IS_NULL(OnigTypeCClassTable)) { 05330 THREAD_ATOMIC_END; 05331 return ONIGERR_MEMORY; 05332 } 05333 } 05334 else { 05335 if (onig_st_lookup(OnigTypeCClassTable, (st_data_t )&key, 05336 (st_data_t* )np)) { 05337 THREAD_ATOMIC_END; 05338 break; 05339 } 05340 } 05341 05342 *np = node_new_cclass_by_codepoint_range(tok->u.prop.not, 05343 sb_out, mbr); 05344 if (IS_NULL(*np)) { 05345 THREAD_ATOMIC_END; 05346 return ONIGERR_MEMORY; 05347 } 05348 05349 cc = NCCLASS(*np); 05350 NCCLASS_SET_SHARE(cc); 05351 new_key = (type_cclass_key* )xmalloc(sizeof(type_cclass_key)); 05352 xmemcpy(new_key, &key, sizeof(type_cclass_key)); 05353 onig_st_add_direct(OnigTypeCClassTable, (st_data_t )new_key, 05354 (st_data_t )*np); 05355 05356 THREAD_ATOMIC_END; 05357 } 05358 else { 05359 #endif 05360 *np = node_new_cclass(); 05361 CHECK_NULL_RETURN_MEMERR(*np); 05362 cc = NCCLASS(*np); 05363 add_ctype_to_cc(cc, tok->u.prop.ctype, 0, env); 05364 if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc); 05365 #ifdef USE_SHARED_CCLASS_TABLE 05366 } 05367 #endif 05368 } 05369 break; 05370 05371 default: 05372 return ONIGERR_PARSER_BUG; 05373 break; 05374 } 05375 } 05376 break; 05377 05378 case TK_CHAR_PROPERTY: 05379 r = parse_char_property(np, tok, src, end, env); 05380 if (r != 0) return r; 05381 break; 05382 05383 case TK_CC_OPEN: 05384 { 05385 CClassNode* cc; 05386 05387 r = parse_char_class(np, tok, src, end, env); 05388 if (r != 0) return r; 05389 05390 cc = NCCLASS(*np); 05391 if (IS_IGNORECASE(env->option)) { 05392 IApplyCaseFoldArg iarg; 05393 05394 iarg.env = env; 05395 iarg.cc = cc; 05396 iarg.alt_root = NULL_NODE; 05397 iarg.ptail = &(iarg.alt_root); 05398 05399 r = ONIGENC_APPLY_ALL_CASE_FOLD(env->enc, env->case_fold_flag, 05400 i_apply_case_fold, &iarg); 05401 if (r != 0) { 05402 onig_node_free(iarg.alt_root); 05403 return r; 05404 } 05405 if (IS_NOT_NULL(iarg.alt_root)) { 05406 Node* work = onig_node_new_alt(*np, iarg.alt_root); 05407 if (IS_NULL(work)) { 05408 onig_node_free(iarg.alt_root); 05409 return ONIGERR_MEMORY; 05410 } 05411 *np = work; 05412 } 05413 } 05414 } 05415 break; 05416 05417 case TK_ANYCHAR: 05418 *np = node_new_anychar(); 05419 CHECK_NULL_RETURN_MEMERR(*np); 05420 break; 05421 05422 case TK_ANYCHAR_ANYTIME: 05423 *np = node_new_anychar(); 05424 CHECK_NULL_RETURN_MEMERR(*np); 05425 qn = node_new_quantifier(0, REPEAT_INFINITE, 0); 05426 CHECK_NULL_RETURN_MEMERR(qn); 05427 NQTFR(qn)->target = *np; 05428 *np = qn; 05429 break; 05430 05431 case TK_BACKREF: 05432 len = tok->u.backref.num; 05433 *np = node_new_backref(len, 05434 (len > 1 ? tok->u.backref.refs : &(tok->u.backref.ref1)), 05435 tok->u.backref.by_name, 05436 #ifdef USE_BACKREF_WITH_LEVEL 05437 tok->u.backref.exist_level, 05438 tok->u.backref.level, 05439 #endif 05440 env); 05441 CHECK_NULL_RETURN_MEMERR(*np); 05442 break; 05443 05444 #ifdef USE_SUBEXP_CALL 05445 case TK_CALL: 05446 { 05447 int gnum = tok->u.call.gnum; 05448 05449 if (gnum < 0) { 05450 gnum = BACKREF_REL_TO_ABS(gnum, env); 05451 if (gnum <= 0) 05452 return ONIGERR_INVALID_BACKREF; 05453 } 05454 *np = node_new_call(tok->u.call.name, tok->u.call.name_end, gnum); 05455 CHECK_NULL_RETURN_MEMERR(*np); 05456 env->num_call++; 05457 } 05458 break; 05459 #endif 05460 05461 case TK_ANCHOR: 05462 *np = onig_node_new_anchor(tok->u.anchor); 05463 break; 05464 05465 case TK_OP_REPEAT: 05466 case TK_INTERVAL: 05467 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS)) { 05468 if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS)) 05469 return ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED; 05470 else 05471 *np = node_new_empty(); 05472 } 05473 else { 05474 goto tk_byte; 05475 } 05476 break; 05477 05478 default: 05479 return ONIGERR_PARSER_BUG; 05480 break; 05481 } 05482 05483 { 05484 targetp = np; 05485 05486 re_entry: 05487 r = fetch_token(tok, src, end, env); 05488 if (r < 0) return r; 05489 05490 repeat: 05491 if (r == TK_OP_REPEAT || r == TK_INTERVAL) { 05492 if (is_invalid_quantifier_target(*targetp)) 05493 return ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID; 05494 05495 qn = node_new_quantifier(tok->u.repeat.lower, tok->u.repeat.upper, 05496 (r == TK_INTERVAL ? 1 : 0)); 05497 CHECK_NULL_RETURN_MEMERR(qn); 05498 NQTFR(qn)->greedy = tok->u.repeat.greedy; 05499 r = set_quantifier(qn, *targetp, group, env); 05500 if (r < 0) { 05501 onig_node_free(qn); 05502 return r; 05503 } 05504 05505 if (tok->u.repeat.possessive != 0) { 05506 Node* en; 05507 en = node_new_enclose(ENCLOSE_STOP_BACKTRACK); 05508 if (IS_NULL(en)) { 05509 onig_node_free(qn); 05510 return ONIGERR_MEMORY; 05511 } 05512 NENCLOSE(en)->target = qn; 05513 qn = en; 05514 } 05515 05516 if (r == 0) { 05517 *targetp = qn; 05518 } 05519 else if (r == 1) { 05520 onig_node_free(qn); 05521 } 05522 else if (r == 2) { /* split case: /abc+/ */ 05523 Node *tmp; 05524 05525 *targetp = node_new_list(*targetp, NULL); 05526 if (IS_NULL(*targetp)) { 05527 onig_node_free(qn); 05528 return ONIGERR_MEMORY; 05529 } 05530 tmp = NCDR(*targetp) = node_new_list(qn, NULL); 05531 if (IS_NULL(tmp)) { 05532 onig_node_free(qn); 05533 return ONIGERR_MEMORY; 05534 } 05535 targetp = &(NCAR(tmp)); 05536 } 05537 goto re_entry; 05538 } 05539 } 05540 05541 return r; 05542 } 05543 05544 static int 05545 parse_branch(Node** top, OnigToken* tok, int term, 05546 UChar** src, UChar* end, ScanEnv* env) 05547 { 05548 int r; 05549 Node *node, **headp; 05550 05551 *top = NULL; 05552 r = parse_exp(&node, tok, term, src, end, env); 05553 if (r < 0) { 05554 onig_node_free(node); 05555 return r; 05556 } 05557 05558 if (r == TK_EOT || r == term || r == TK_ALT) { 05559 *top = node; 05560 } 05561 else { 05562 *top = node_new_list(node, NULL); 05563 headp = &(NCDR(*top)); 05564 while (r != TK_EOT && r != term && r != TK_ALT) { 05565 r = parse_exp(&node, tok, term, src, end, env); 05566 if (r < 0) { 05567 onig_node_free(node); 05568 return r; 05569 } 05570 05571 if (NTYPE(node) == NT_LIST) { 05572 *headp = node; 05573 while (IS_NOT_NULL(NCDR(node))) node = NCDR(node); 05574 headp = &(NCDR(node)); 05575 } 05576 else { 05577 *headp = node_new_list(node, NULL); 05578 headp = &(NCDR(*headp)); 05579 } 05580 } 05581 } 05582 05583 return r; 05584 } 05585 05586 /* term_tok: TK_EOT or TK_SUBEXP_CLOSE */ 05587 static int 05588 parse_subexp(Node** top, OnigToken* tok, int term, 05589 UChar** src, UChar* end, ScanEnv* env) 05590 { 05591 int r; 05592 Node *node, **headp; 05593 05594 *top = NULL; 05595 r = parse_branch(&node, tok, term, src, end, env); 05596 if (r < 0) { 05597 onig_node_free(node); 05598 return r; 05599 } 05600 05601 if (r == term) { 05602 *top = node; 05603 } 05604 else if (r == TK_ALT) { 05605 *top = onig_node_new_alt(node, NULL); 05606 headp = &(NCDR(*top)); 05607 while (r == TK_ALT) { 05608 r = fetch_token(tok, src, end, env); 05609 if (r < 0) return r; 05610 r = parse_branch(&node, tok, term, src, end, env); 05611 if (r < 0) { 05612 onig_node_free(node); 05613 return r; 05614 } 05615 05616 *headp = onig_node_new_alt(node, NULL); 05617 headp = &(NCDR(*headp)); 05618 } 05619 05620 if (tok->type != (enum TokenSyms )term) 05621 goto err; 05622 } 05623 else { 05624 onig_node_free(node); 05625 err: 05626 if (term == TK_SUBEXP_CLOSE) 05627 return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS; 05628 else 05629 return ONIGERR_PARSER_BUG; 05630 } 05631 05632 return r; 05633 } 05634 05635 static int 05636 parse_regexp(Node** top, UChar** src, UChar* end, ScanEnv* env) 05637 { 05638 int r; 05639 OnigToken tok; 05640 05641 r = fetch_token(&tok, src, end, env); 05642 if (r < 0) return r; 05643 r = parse_subexp(top, &tok, TK_EOT, src, end, env); 05644 if (r < 0) return r; 05645 return 0; 05646 } 05647 05648 extern int 05649 onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, 05650 regex_t* reg, ScanEnv* env) 05651 { 05652 int r; 05653 UChar* p; 05654 05655 #ifdef USE_NAMED_GROUP 05656 names_clear(reg); 05657 #endif 05658 05659 scan_env_clear(env); 05660 env->option = reg->options; 05661 env->case_fold_flag = reg->case_fold_flag; 05662 env->enc = reg->enc; 05663 env->syntax = reg->syntax; 05664 env->pattern = (UChar* )pattern; 05665 env->pattern_end = (UChar* )end; 05666 env->reg = reg; 05667 05668 *root = NULL; 05669 p = (UChar* )pattern; 05670 r = parse_regexp(root, &p, (UChar* )end, env); 05671 reg->num_mem = env->num_mem; 05672 return r; 05673 } 05674 05675 extern void 05676 onig_scan_env_set_error_string(ScanEnv* env, int ecode ARG_UNUSED, 05677 UChar* arg, UChar* arg_end) 05678 { 05679 env->error = arg; 05680 env->error_end = arg_end; 05681 } 05682
1.7.3