Changeset 3613 in kBuild for trunk/src/sed/lib/regcomp.c
- Timestamp:
- Sep 19, 2024 12:34:43 AM (7 months ago)
- Location:
- trunk/src/sed
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/sed
-
Property svn:mergeinfo
set to
/vendor/sed/current merged eligible
-
Property svn:mergeinfo
set to
-
trunk/src/sed/lib/regcomp.c
r3550 r3613 1 1 /* Extended regular expression matching and search library. 2 Copyright (C) 2002 , 2003, 2004, 2005Free Software Foundation, Inc.2 Copyright (C) 2002-2022 Free Software Foundation, Inc. 3 3 This file is part of the GNU C Library. 4 4 Contributed by Isamu Hasegawa <[email protected]>. … … 15 15 16 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, write to the Free 18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307 USA. */ 17 License along with the GNU C Library; if not, see 18 <https://www.gnu.org/licenses/>. */ 19 20 #ifdef _LIBC 21 # include <locale/weight.h> 22 #endif 20 23 21 24 static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, … … 25 28 char *fastmap); 26 29 static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len); 27 #ifdef RE_ENABLE_I18N28 30 static void free_charset (re_charset_t *cset); 29 #endif /* RE_ENABLE_I18N */30 31 static void free_workarea_compile (regex_t *preg); 31 32 static reg_errcode_t create_initial_state (re_dfa_t *dfa); 32 #ifdef RE_ENABLE_I18N33 33 static void optimize_utf8 (re_dfa_t *dfa); 34 #endif35 34 static reg_errcode_t analyze (regex_t *preg); 36 35 static reg_errcode_t preorder (bin_tree_t *root, … … 47 46 static reg_errcode_t calc_next (void *extra, bin_tree_t *node); 48 47 static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node); 49 static int duplicate_node (re_dfa_t *dfa, intorg_idx, unsigned int constraint);50 static int search_duplicated_node (const re_dfa_t *dfa, intorg_node,48 static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint); 49 static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node, 51 50 unsigned int constraint); 52 51 static reg_errcode_t calc_eclosure (re_dfa_t *dfa); 53 52 static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, 54 int node, introot);53 Idx node, bool root); 55 54 static reg_errcode_t calc_inveclosure (re_dfa_t *dfa); 56 static intfetch_number (re_string_t *input, re_token_t *token,55 static Idx fetch_number (re_string_t *input, re_token_t *token, 57 56 reg_syntax_t syntax); 58 57 static int peek_token (re_token_t *token, re_string_t *input, 59 reg_syntax_t syntax) internal_function;58 reg_syntax_t syntax); 60 59 static bin_tree_t *parse (re_string_t *regexp, regex_t *preg, 61 60 reg_syntax_t syntax, reg_errcode_t *err); 62 61 static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg, 63 62 re_token_t *token, reg_syntax_t syntax, 64 intnest, reg_errcode_t *err);63 Idx nest, reg_errcode_t *err); 65 64 static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg, 66 65 re_token_t *token, reg_syntax_t syntax, 67 intnest, reg_errcode_t *err);66 Idx nest, reg_errcode_t *err); 68 67 static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg, 69 68 re_token_t *token, reg_syntax_t syntax, 70 intnest, reg_errcode_t *err);69 Idx nest, reg_errcode_t *err); 71 70 static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg, 72 71 re_token_t *token, reg_syntax_t syntax, 73 intnest, reg_errcode_t *err);72 Idx nest, reg_errcode_t *err); 74 73 static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp, 75 74 re_dfa_t *dfa, re_token_t *token, … … 83 82 re_dfa_t *dfa, 84 83 reg_syntax_t syntax, 85 intaccept_hyphen);84 bool accept_hyphen); 86 85 static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem, 87 86 re_string_t *regexp, 88 87 re_token_t *token); 89 #ifdef RE_ENABLE_I18N90 88 static reg_errcode_t build_equiv_class (bitset_t sbcset, 91 89 re_charset_t *mbcset, 92 int*equiv_class_alloc,90 Idx *equiv_class_alloc, 93 91 const unsigned char *name); 94 92 static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, 95 93 bitset_t sbcset, 96 94 re_charset_t *mbcset, 97 int*char_class_alloc,98 const unsignedchar *class_name,95 Idx *char_class_alloc, 96 const char *class_name, 99 97 reg_syntax_t syntax); 100 #else /* not RE_ENABLE_I18N */101 static reg_errcode_t build_equiv_class (bitset_t sbcset,102 const unsigned char *name);103 static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,104 bitset_t sbcset,105 const unsigned char *class_name,106 reg_syntax_t syntax);107 #endif /* not RE_ENABLE_I18N */108 98 static bin_tree_t *build_charclass_op (re_dfa_t *dfa, 109 99 RE_TRANSLATE_TYPE trans, 110 const unsignedchar *class_name,111 const unsignedchar *extra,112 intnon_match, reg_errcode_t *err);100 const char *class_name, 101 const char *extra, 102 bool non_match, reg_errcode_t *err); 113 103 static bin_tree_t *create_tree (re_dfa_t *dfa, 114 104 bin_tree_t *left, bin_tree_t *right, … … 128 118 but why not be nice? */ 129 119 130 const char __re_error_msgid[] attribute_hidden=120 static const char __re_error_msgid[] = 131 121 { 132 122 #define REG_NOERROR_IDX 0 … … 152 142 "\0" 153 143 #define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference") 154 gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */144 gettext_noop ("Unmatched [, [^, [:, [., or [=") /* REG_EBRACK */ 155 145 "\0" 156 #define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^")146 #define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [, [^, [:, [., or [=") 157 147 gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */ 158 148 "\0" … … 182 172 }; 183 173 184 const size_t __re_error_msgid_idx[] attribute_hidden=174 static const size_t __re_error_msgid_idx[] = 185 175 { 186 176 REG_NOERROR_IDX, … … 210 200 Returns 0 if the pattern was valid, otherwise an error string. 211 201 212 Assumes the `allocated' (and perhaps `buffer') and `translate' fields202 Assumes the 'allocated' (and perhaps 'buffer') and 'translate' fields 213 203 are set in BUFP on entry. */ 214 204 215 205 const char * 216 re_compile_pattern (pattern, length, bufp) 217 const char *pattern; 218 size_t length; 219 struct re_pattern_buffer *bufp; 206 re_compile_pattern (const char *pattern, size_t length, 207 struct re_pattern_buffer *bufp) 220 208 { 221 209 reg_errcode_t ret; … … 235 223 return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); 236 224 } 237 #ifdef _LIBC238 225 weak_alias (__re_compile_pattern, re_compile_pattern) 239 #endif 240 241 /* Set by `re_set_syntax' to the current regexp syntax to recognize. Can 226 227 /* Set by 're_set_syntax' to the current regexp syntax to recognize. Can 242 228 also be assigned to arbitrarily: each pattern buffer stores its own 243 229 syntax, so it can be changed between regex compilations. */ … … 255 241 256 242 reg_syntax_t 257 re_set_syntax (syntax) 258 reg_syntax_t syntax; 243 re_set_syntax (reg_syntax_t syntax) 259 244 { 260 245 reg_syntax_t ret = re_syntax_options; … … 263 248 return ret; 264 249 } 265 #ifdef _LIBC266 250 weak_alias (__re_set_syntax, re_set_syntax) 267 #endif268 251 269 252 int 270 re_compile_fastmap (bufp) 271 struct re_pattern_buffer *bufp; 272 { 273 re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; 253 re_compile_fastmap (struct re_pattern_buffer *bufp) 254 { 255 re_dfa_t *dfa = bufp->buffer; 274 256 char *fastmap = bufp->fastmap; 275 257 … … 285 267 return 0; 286 268 } 287 #ifdef _LIBC288 269 weak_alias (__re_compile_fastmap, re_compile_fastmap) 289 #endif 290 291 static inline void 292 __attribute ((always_inline)) 293 re_set_fastmap (char *fastmap, int icase, int ch) 270 271 static __always_inline void 272 re_set_fastmap (char *fastmap, bool icase, int ch) 294 273 { 295 274 fastmap[ch] = 1; … … 305 284 char *fastmap) 306 285 { 307 re_dfa_t *dfa = (re_dfa_t *)bufp->buffer;308 intnode_cnt;309 inticase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));286 re_dfa_t *dfa = bufp->buffer; 287 Idx node_cnt; 288 bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE)); 310 289 for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) 311 290 { 312 intnode = init_state->nodes.elems[node_cnt];291 Idx node = init_state->nodes.elems[node_cnt]; 313 292 re_token_type_t type = dfa->nodes[node].type; 314 293 … … 316 295 { 317 296 re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); 318 #ifdef RE_ENABLE_I18N319 297 if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) 320 298 { 321 unsigned char *buf = alloca (dfa->mb_cur_max), *p; 299 unsigned char buf[MB_LEN_MAX]; 300 unsigned char *p; 322 301 wchar_t wc; 323 302 mbstate_t state; … … 330 309 *p++ = dfa->nodes[node].opr.c; 331 310 memset (&state, '\0', sizeof (state)); 332 if ( mbrtowc (&wc, (const char *) buf, p - buf,333 &state) == p - buf334 && (__wcrtomb ((char *) buf, towlower (wc), &state)311 if (__mbrtowc (&wc, (const char *) buf, p - buf, 312 &state) == p - buf 313 && (__wcrtomb ((char *) buf, __towlower (wc), &state) 335 314 != (size_t) -1)) 336 re_set_fastmap (fastmap, 0, buf[0]);315 re_set_fastmap (fastmap, false, buf[0]); 337 316 } 338 #endif339 317 } 340 318 else if (type == SIMPLE_BRACKET) … … 350 328 } 351 329 } 352 #ifdef RE_ENABLE_I18N353 330 else if (type == COMPLEX_BRACKET) 354 331 { 355 int i;356 332 re_charset_t *cset = dfa->nodes[node].opr.mbcset; 357 if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes 358 || cset->nranges || cset->nchar_classes) 359 { 360 # ifdef _LIBC 361 if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0) 333 Idx i; 334 335 #ifdef _LIBC 336 /* See if we have to try all bytes which start multiple collation 337 elements. 338 e.g. In da_DK, we want to catch 'a' since "aa" is a valid 339 collation element, and don't catch 'b' since 'b' is 340 the only collation element which starts from 'b' (and 341 it is caught by SIMPLE_BRACKET). */ 342 if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0 343 && (cset->ncoll_syms || cset->nranges)) 362 344 { 363 /* In this case we want to catch the bytes which are364 the first byte of any collation elements.365 e.g. In da_DK, we want to catch 'a' since "aa"366 is a valid collation element, and don't catch367 'b' since 'b' is the only collation element368 which starts from 'b'. */369 345 const int32_t *table = (const int32_t *) 370 346 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); … … 373 349 re_set_fastmap (fastmap, icase, i); 374 350 } 375 # else 376 if (dfa->mb_cur_max > 1) 377 for (i = 0; i < SBC_MAX; ++i) 378 if (__btowc (i) == WEOF) 379 re_set_fastmap (fastmap, icase, i); 380 # endif /* not _LIBC */ 351 #endif /* _LIBC */ 352 353 /* See if we have to start the match at all multibyte characters, 354 i.e. where we would not find an invalid sequence. This only 355 applies to multibyte character sets; for single byte character 356 sets, the SIMPLE_BRACKET again suffices. */ 357 if (dfa->mb_cur_max > 1 358 && (cset->nchar_classes || cset->non_match || cset->nranges 359 #ifdef _LIBC 360 || cset->nequiv_classes 361 #endif /* _LIBC */ 362 )) 363 { 364 unsigned char c = 0; 365 do 366 { 367 mbstate_t mbs; 368 memset (&mbs, 0, sizeof (mbs)); 369 if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2) 370 re_set_fastmap (fastmap, false, (int) c); 371 } 372 while (++c != 0); 381 373 } 382 for (i = 0; i < cset->nmbchars; ++i) 374 375 else 383 376 { 384 char buf[256]; 385 mbstate_t state; 386 memset (&state, '\0', sizeof (state)); 387 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) 388 re_set_fastmap (fastmap, icase, *(unsigned char *) buf); 389 if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) 377 /* ... Else catch all bytes which can start the mbchars. */ 378 for (i = 0; i < cset->nmbchars; ++i) 390 379 { 391 if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state) 392 != (size_t) -1) 393 re_set_fastmap (fastmap, 0, *(unsigned char *) buf); 380 char buf[256]; 381 mbstate_t state; 382 memset (&state, '\0', sizeof (state)); 383 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) 384 re_set_fastmap (fastmap, icase, *(unsigned char *) buf); 385 if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) 386 { 387 if (__wcrtomb (buf, __towlower (cset->mbchars[i]), &state) 388 != (size_t) -1) 389 re_set_fastmap (fastmap, false, *(unsigned char *) buf); 390 } 394 391 } 395 392 } 396 393 } 397 #endif /* RE_ENABLE_I18N */ 398 else if (type == OP_PERIOD 399 #ifdef RE_ENABLE_I18N 400 || type == OP_UTF8_PERIOD 401 #endif /* RE_ENABLE_I18N */ 402 || type == END_OF_RE) 394 else if (type == OP_PERIOD || type == OP_UTF8_PERIOD || type == END_OF_RE) 403 395 { 404 396 memset (fastmap, '\1', sizeof (char) * SBC_MAX); … … 417 409 since POSIX says we shouldn't. Thus, we set 418 410 419 `buffer' to the compiled pattern;420 `used' to the length of the compiled pattern;421 `syntax' to RE_SYNTAX_POSIX_EXTENDED if the411 'buffer' to the compiled pattern; 412 'used' to the length of the compiled pattern; 413 'syntax' to RE_SYNTAX_POSIX_EXTENDED if the 422 414 REG_EXTENDED bit in CFLAGS is set; otherwise, to 423 415 RE_SYNTAX_POSIX_BASIC; 424 `newline_anchor' to REG_NEWLINE being set in CFLAGS;425 `fastmap' to an allocated space for the fastmap;426 `fastmap_accurate' to zero;427 `re_nsub' to the number of subexpressions in PATTERN.416 'newline_anchor' to REG_NEWLINE being set in CFLAGS; 417 'fastmap' to an allocated space for the fastmap; 418 'fastmap_accurate' to zero; 419 're_nsub' to the number of subexpressions in PATTERN. 428 420 429 421 PATTERN is the address of the pattern string. … … 448 440 449 441 int 450 regcomp (preg, pattern, cflags) 451 regex_t *__restrict preg; 452 const char *__restrict pattern; 453 int cflags; 442 regcomp (regex_t *__restrict preg, const char *__restrict pattern, int cflags) 454 443 { 455 444 reg_errcode_t ret; … … 463 452 /* Try to allocate space for the fastmap. */ 464 453 preg->fastmap = re_malloc (char, SBC_MAX); 465 if ( BE (preg->fastmap == NULL, 0))454 if (__glibc_unlikely (preg->fastmap == NULL)) 466 455 return REG_ESPACE; 467 456 … … 489 478 490 479 /* We have already checked preg->fastmap != NULL. */ 491 if ( BE (ret == REG_NOERROR, 1))480 if (__glibc_likely (ret == REG_NOERROR)) 492 481 /* Compute the fastmap now, since regexec cannot modify the pattern 493 482 buffer. This function never fails in this implementation. */ … … 502 491 return (int) ret; 503 492 } 504 #ifdef _LIBC 493 libc_hidden_def (__regcomp) 505 494 weak_alias (__regcomp, regcomp) 506 #endif507 495 508 496 /* Returns a message corresponding to an error code, ERRCODE, returned … … 510 498 511 499 size_t 512 regerror (errcode, preg, errbuf, errbuf_size) 513 int errcode; 514 const regex_t *__restrict preg; 515 char *__restrict errbuf; 516 size_t errbuf_size; 500 regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf, 501 size_t errbuf_size) 517 502 { 518 503 const char *msg; 519 504 size_t msg_size; 520 521 if (BE (errcode < 0 522 || errcode >= (int) (sizeof (__re_error_msgid_idx) 523 / sizeof (__re_error_msgid_idx[0])), 0)) 505 int nerrcodes = sizeof __re_error_msgid_idx / sizeof __re_error_msgid_idx[0]; 506 507 if (__glibc_unlikely (errcode < 0 || errcode >= nerrcodes)) 524 508 /* Only error codes returned by the rest of the code should be passed 525 509 to this routine. If we are given anything else, or if other regex … … 532 516 msg_size = strlen (msg) + 1; /* Includes the null. */ 533 517 534 if (BE (errbuf_size != 0, 1)) 535 { 536 if (BE (msg_size > errbuf_size, 0)) 537 { 538 #if defined HAVE_MEMPCPY || defined _LIBC 539 *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0'; 540 #else 541 memcpy (errbuf, msg, errbuf_size - 1); 542 errbuf[errbuf_size - 1] = 0; 543 #endif 544 } 545 else 546 memcpy (errbuf, msg, msg_size); 518 if (__glibc_likely (errbuf_size != 0)) 519 { 520 size_t cpy_size = msg_size; 521 if (__glibc_unlikely (msg_size > errbuf_size)) 522 { 523 cpy_size = errbuf_size - 1; 524 errbuf[cpy_size] = '\0'; 525 } 526 memcpy (errbuf, msg, cpy_size); 547 527 } 548 528 549 529 return msg_size; 550 530 } 551 #ifdef _LIBC552 531 weak_alias (__regerror, regerror) 553 #endif 554 555 556 #ifdef RE_ENABLE_I18N 532 533 557 534 /* This static array is used for the map to single-byte characters when 558 535 UTF-8 is used. Otherwise we would allocate memory just to initialize … … 562 539 { 563 540 /* Set the first 128 bits. */ 564 #if def _MSC_VER565 BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX, 0, 0, 0, 0541 #if (defined __GNUC__ || __clang_major__ >= 4) && !defined __STRICT_ANSI__ 542 [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX 566 543 #else 567 [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX 544 # if 4 * BITSET_WORD_BITS < ASCII_CHARS 545 # error "bitset_word_t is narrower than 32 bits" 546 # elif 3 * BITSET_WORD_BITS < ASCII_CHARS 547 BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX, 548 # elif 2 * BITSET_WORD_BITS < ASCII_CHARS 549 BITSET_WORD_MAX, BITSET_WORD_MAX, 550 # elif 1 * BITSET_WORD_BITS < ASCII_CHARS 551 BITSET_WORD_MAX, 552 # endif 553 (BITSET_WORD_MAX 554 >> (SBC_MAX % BITSET_WORD_BITS == 0 555 ? 0 556 : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS)) 568 557 #endif 569 558 }; 570 #endif571 559 572 560 … … 574 562 free_dfa_content (re_dfa_t *dfa) 575 563 { 576 inti, j;564 Idx i, j; 577 565 578 566 if (dfa->nodes) … … 603 591 free_state (state); 604 592 } 605 593 re_free (entry->array); 606 594 } 607 595 re_free (dfa->state_table); 608 #ifdef RE_ENABLE_I18N609 596 if (dfa->sb_char != utf8_sb_map) 610 597 re_free (dfa->sb_char); 611 #endif612 598 re_free (dfa->subexp_map); 613 599 #ifdef DEBUG … … 622 608 623 609 void 624 regfree (preg) 625 regex_t *preg; 626 { 627 re_dfa_t *dfa = (re_dfa_t *) preg->buffer; 628 if (BE (dfa != NULL, 1)) 629 free_dfa_content (dfa); 610 regfree (regex_t *preg) 611 { 612 re_dfa_t *dfa = preg->buffer; 613 if (__glibc_likely (dfa != NULL)) 614 { 615 lock_fini (dfa->lock); 616 free_dfa_content (dfa); 617 } 630 618 preg->buffer = NULL; 631 619 preg->allocated = 0; … … 637 625 preg->translate = NULL; 638 626 } 639 #ifdef _LIBC 627 libc_hidden_def (__regfree) 640 628 weak_alias (__regfree, regfree) 641 #endif642 629 643 630 … … 657 644 weak_function 658 645 # endif 659 re_comp (s) 660 const char *s; 646 re_comp (const char *s) 661 647 { 662 648 reg_errcode_t ret; … … 681 667 if (re_comp_buf.fastmap == NULL) 682 668 { 683 re_comp_buf.fastmap = (char *) malloc (SBC_MAX);669 re_comp_buf.fastmap = re_malloc (char, SBC_MAX); 684 670 if (re_comp_buf.fastmap == NULL) 685 671 return (char *) gettext (__re_error_msgid … … 687 673 } 688 674 689 /* Since `re_exec' always passes NULL for the `regs' argument, we675 /* Since 're_exec' always passes NULL for the 'regs' argument, we 690 676 don't need to initialize the pattern buffer fields which affect it. */ 691 677 … … 698 684 return NULL; 699 685 700 /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */686 /* Yes, we're discarding 'const' here if !HAVE_LIBINTL. */ 701 687 return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); 702 688 } … … 734 720 735 721 /* Initialize the dfa. */ 736 dfa = (re_dfa_t *)preg->buffer;737 if ( BE (preg->allocated < sizeof (re_dfa_t), 0))722 dfa = preg->buffer; 723 if (__glibc_unlikely (preg->allocated < sizeof (re_dfa_t))) 738 724 { 739 725 /* If zero allocated, but buffer is non-null, try to realloc … … 745 731 return REG_ESPACE; 746 732 preg->allocated = sizeof (re_dfa_t); 747 preg->buffer = (unsigned char *)dfa;733 preg->buffer = dfa; 748 734 } 749 735 preg->used = sizeof (re_dfa_t); 750 736 751 737 err = init_dfa (dfa, length); 752 if (BE (err != REG_NOERROR, 0)) 738 if (__glibc_unlikely (err == REG_NOERROR && lock_init (dfa->lock) != 0)) 739 err = REG_ESPACE; 740 if (__glibc_unlikely (err != REG_NOERROR)) 753 741 { 754 742 free_dfa_content (dfa); … … 763 751 #endif 764 752 765 __libc_lock_init (dfa->lock);766 767 753 err = re_string_construct (®exp, pattern, length, preg->translate, 768 syntax & RE_ICASE, dfa);769 if ( BE (err != REG_NOERROR, 0))754 (syntax & RE_ICASE) != 0, dfa); 755 if (__glibc_unlikely (err != REG_NOERROR)) 770 756 { 771 757 re_compile_internal_free_return: 772 758 free_workarea_compile (preg); 773 759 re_string_destruct (®exp); 760 lock_fini (dfa->lock); 774 761 free_dfa_content (dfa); 775 762 preg->buffer = NULL; … … 781 768 preg->re_nsub = 0; 782 769 dfa->str_tree = parse (®exp, preg, syntax, &err); 783 if ( BE (dfa->str_tree == NULL, 0))770 if (__glibc_unlikely (dfa->str_tree == NULL)) 784 771 goto re_compile_internal_free_return; 785 772 786 773 /* Analyze the tree and create the nfa. */ 787 774 err = analyze (preg); 788 if ( BE (err != REG_NOERROR, 0))775 if (__glibc_unlikely (err != REG_NOERROR)) 789 776 goto re_compile_internal_free_return; 790 777 791 #ifdef RE_ENABLE_I18N792 778 /* If possible, do searching in single byte encoding to speed things up. */ 793 779 if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL) 794 780 optimize_utf8 (dfa); 795 #endif796 781 797 782 /* Then create the initial state of the dfa. */ … … 802 787 re_string_destruct (®exp); 803 788 804 if (BE (err != REG_NOERROR, 0)) 805 { 789 if (__glibc_unlikely (err != REG_NOERROR)) 790 { 791 lock_fini (dfa->lock); 806 792 free_dfa_content (dfa); 807 793 preg->buffer = NULL; … … 818 804 init_dfa (re_dfa_t *dfa, size_t pat_len) 819 805 { 820 unsigned int table_size;806 __re_size_t table_size; 821 807 #ifndef _LIBC 822 c har *codeset_name;808 const char *codeset_name; 823 809 #endif 810 size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); 811 size_t max_object_size = 812 MAX (sizeof (struct re_state_table_entry), 813 MAX (sizeof (re_token_t), 814 MAX (sizeof (re_node_set), 815 MAX (sizeof (regmatch_t), 816 max_i18n_object_size)))); 824 817 825 818 memset (dfa, '\0', sizeof (re_dfa_t)); … … 828 821 dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; 829 822 830 /* Avoid overflows. */ 831 if (pat_len == SIZE_MAX) 823 /* Avoid overflows. The extra "/ 2" is for the table_size doubling 824 calculation below, and for similar doubling calculations 825 elsewhere. And it's <= rather than <, because some of the 826 doubling calculations add 1 afterwards. */ 827 if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2 828 <= pat_len)) 832 829 return REG_ESPACE; 833 830 … … 855 852 if (get_crt_codepage() == MY_CP_UTF8) 856 853 # else 857 # ifdef HAVE_LANGINFO_CODESET858 854 codeset_name = nl_langinfo (CODESET); 859 # else 860 codeset_name = getenv ("LC_ALL"); 861 if (codeset_name == NULL || codeset_name[0] == '\0') 862 codeset_name = getenv ("LC_CTYPE"); 863 if (codeset_name == NULL || codeset_name[0] == '\0') 864 codeset_name = getenv ("LANG"); 865 if (codeset_name == NULL) 866 codeset_name = ""; 867 else if (strchr (codeset_name, '.') != NULL) 868 codeset_name = strchr (codeset_name, '.') + 1; 869 # endif 870 871 if (strcasecmp (codeset_name, "UTF-8") == 0 872 || strcasecmp (codeset_name, "UTF8") == 0) 855 if ((codeset_name[0] == 'U' || codeset_name[0] == 'u') 856 && (codeset_name[1] == 'T' || codeset_name[1] == 't') 857 && (codeset_name[2] == 'F' || codeset_name[2] == 'f') 858 && strcmp (codeset_name + 3 + (codeset_name[3] == '-'), "8") == 0) 873 859 # endif 874 860 dfa->is_utf8 = 1; … … 879 865 #endif 880 866 881 #ifdef RE_ENABLE_I18N882 867 if (dfa->mb_cur_max > 1) 883 868 { … … 889 874 890 875 dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); 891 if ( BE (dfa->sb_char == NULL, 0))876 if (__glibc_unlikely (dfa->sb_char == NULL)) 892 877 return REG_ESPACE; 893 878 … … 899 884 if (wch != WEOF) 900 885 dfa->sb_char[i] |= (bitset_word_t) 1 << j; 901 # 886 #ifndef _LIBC 902 887 if (isascii (ch) && wch != ch) 903 888 dfa->map_notascii = 1; 904 # 889 #endif 905 890 } 906 891 } 907 892 } 908 #endif 909 910 if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0)) 893 894 if (__glibc_unlikely (dfa->nodes == NULL || dfa->state_table == NULL)) 911 895 return REG_ESPACE; 912 896 return REG_NOERROR; … … 918 902 919 903 static void 920 internal_function921 904 init_word_char (re_dfa_t *dfa) 922 905 { 923 int i, j, ch; 906 int i = 0; 907 int j; 908 int ch = 0; 924 909 dfa->word_ops_used = 1; 925 for (i = 0, ch = 0; i < BITSET_WORDS; ++i) 910 if (__glibc_likely (dfa->map_notascii == 0)) 911 { 912 bitset_word_t bits0 = 0x00000000; 913 bitset_word_t bits1 = 0x03ff0000; 914 bitset_word_t bits2 = 0x87fffffe; 915 bitset_word_t bits3 = 0x07fffffe; 916 if (BITSET_WORD_BITS == 64) 917 { 918 /* Pacify gcc -Woverflow on 32-bit platformns. */ 919 dfa->word_char[0] = bits1 << 31 << 1 | bits0; 920 dfa->word_char[1] = bits3 << 31 << 1 | bits2; 921 i = 2; 922 } 923 else if (BITSET_WORD_BITS == 32) 924 { 925 dfa->word_char[0] = bits0; 926 dfa->word_char[1] = bits1; 927 dfa->word_char[2] = bits2; 928 dfa->word_char[3] = bits3; 929 i = 4; 930 } 931 else 932 goto general_case; 933 ch = 128; 934 935 if (__glibc_likely (dfa->is_utf8)) 936 { 937 memset (&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8); 938 return; 939 } 940 } 941 942 general_case: 943 for (; i < BITSET_WORDS; ++i) 926 944 for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) 927 945 if (isalnum (ch) || ch == '_') … … 934 952 free_workarea_compile (regex_t *preg) 935 953 { 936 re_dfa_t *dfa = (re_dfa_t *)preg->buffer;954 re_dfa_t *dfa = preg->buffer; 937 955 bin_tree_storage_t *storage, *next; 938 956 for (storage = dfa->str_tree_storage; storage; storage = next) … … 953 971 create_initial_state (re_dfa_t *dfa) 954 972 { 955 intfirst, i;973 Idx first, i; 956 974 reg_errcode_t err; 957 975 re_node_set init_nodes; … … 962 980 dfa->init_node = first; 963 981 err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first); 964 if ( BE (err != REG_NOERROR, 0))982 if (__glibc_unlikely (err != REG_NOERROR)) 965 983 return err; 966 984 … … 972 990 for (i = 0; i < init_nodes.nelem; ++i) 973 991 { 974 intnode_idx = init_nodes.elems[i];992 Idx node_idx = init_nodes.elems[i]; 975 993 re_token_type_t type = dfa->nodes[node_idx].type; 976 994 977 intclexp_idx;995 Idx clexp_idx; 978 996 if (type != OP_BACK_REF) 979 997 continue; … … 991 1009 if (type == OP_BACK_REF) 992 1010 { 993 intdest_idx = dfa->edests[node_idx].elems[0];1011 Idx dest_idx = dfa->edests[node_idx].elems[0]; 994 1012 if (!re_node_set_contains (&init_nodes, dest_idx)) 995 1013 { 996 re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); 1014 reg_errcode_t merge_err 1015 = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); 1016 if (merge_err != REG_NOERROR) 1017 return merge_err; 997 1018 i = 0; 998 1019 } … … 1003 1024 dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0); 1004 1025 /* We don't check ERR here, since the initial state must not be NULL. */ 1005 if ( BE (dfa->init_state == NULL, 0))1026 if (__glibc_unlikely (dfa->init_state == NULL)) 1006 1027 return err; 1007 1028 if (dfa->init_state->has_constraint) … … 1015 1036 CONTEXT_NEWLINE 1016 1037 | CONTEXT_BEGBUF); 1017 if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL 1018 || dfa->init_state_begbuf == NULL, 0)) 1038 if (__glibc_unlikely (dfa->init_state_word == NULL 1039 || dfa->init_state_nl == NULL 1040 || dfa->init_state_begbuf == NULL)) 1019 1041 return err; 1020 1042 } … … 1028 1050 1029 1051 1030 #ifdef RE_ENABLE_I18N1031 1052 /* If it is possible to do searching in single byte encoding instead of UTF-8 1032 1053 to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change … … 1036 1057 optimize_utf8 (re_dfa_t *dfa) 1037 1058 { 1038 int node, i, mb_chars = 0, has_period = 0; 1059 Idx node; 1060 int i; 1061 bool mb_chars = false; 1062 bool has_period = false; 1039 1063 1040 1064 for (node = 0; node < dfa->nodes_len; ++node) … … 1042 1066 { 1043 1067 case CHARACTER: 1044 if (dfa->nodes[node].opr.c >= 0x80)1045 mb_chars = 1;1068 if (dfa->nodes[node].opr.c >= ASCII_CHARS) 1069 mb_chars = true; 1046 1070 break; 1047 1071 case ANCHOR: 1048 switch (dfa->nodes[node].opr. idx)1072 switch (dfa->nodes[node].opr.ctx_type) 1049 1073 { 1050 1074 case LINE_FIRST: … … 1054 1078 break; 1055 1079 default: 1056 /* Word anchors etc. cannot be handled. */ 1080 /* Word anchors etc. cannot be handled. It's okay to test 1081 opr.ctx_type since constraints (for all DFA nodes) are 1082 created by ORing one or more opr.ctx_type values. */ 1057 1083 return; 1058 1084 } 1059 1085 break; 1060 1086 case OP_PERIOD: 1061 has_period = 1;1062 1087 has_period = true; 1088 break; 1063 1089 case OP_BACK_REF: 1064 1090 case OP_ALT: … … 1071 1097 return; 1072 1098 case SIMPLE_BRACKET: 1073 /* Just double check. The non-ASCII range starts at 0x80. */ 1074 assert (0x80 % BITSET_WORD_BITS == 0); 1075 for (i = 0x80 / BITSET_WORD_BITS; i < BITSET_WORDS; ++i) 1076 if (dfa->nodes[node].opr.sbcset[i]) 1077 return; 1099 /* Just double check. */ 1100 { 1101 int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0 1102 ? 0 1103 : BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS); 1104 for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i) 1105 { 1106 if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0) 1107 return; 1108 rshift = 0; 1109 } 1110 } 1078 1111 break; 1079 1112 default: … … 1085 1118 { 1086 1119 if (dfa->nodes[node].type == CHARACTER 1087 && dfa->nodes[node].opr.c >= 0x80)1120 && dfa->nodes[node].opr.c >= ASCII_CHARS) 1088 1121 dfa->nodes[node].mb_partial = 0; 1089 1122 else if (dfa->nodes[node].type == OP_PERIOD) … … 1096 1129 dfa->has_mb_node = dfa->nbackref > 0 || has_period; 1097 1130 } 1098 #endif1099 1131 1100 1132 … … 1105 1137 analyze (regex_t *preg) 1106 1138 { 1107 re_dfa_t *dfa = (re_dfa_t *)preg->buffer;1139 re_dfa_t *dfa = preg->buffer; 1108 1140 reg_errcode_t ret; 1109 1141 1110 1142 /* Allocate arrays. */ 1111 dfa->nexts = re_malloc ( int, dfa->nodes_alloc);1112 dfa->org_indices = re_malloc ( int, dfa->nodes_alloc);1143 dfa->nexts = re_malloc (Idx, dfa->nodes_alloc); 1144 dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc); 1113 1145 dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc); 1114 1146 dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc); 1115 if ( BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL1116 || dfa->eclosures == NULL, 0))1147 if (__glibc_unlikely (dfa->nexts == NULL || dfa->org_indices == NULL 1148 || dfa->edests == NULL || dfa->eclosures == NULL)) 1117 1149 return REG_ESPACE; 1118 1150 1119 dfa->subexp_map = re_malloc ( int, preg->re_nsub);1151 dfa->subexp_map = re_malloc (Idx, preg->re_nsub); 1120 1152 if (dfa->subexp_map != NULL) 1121 1153 { 1122 inti;1154 Idx i; 1123 1155 for (i = 0; i < preg->re_nsub; i++) 1124 1156 dfa->subexp_map[i] = i; … … 1129 1161 if (i == preg->re_nsub) 1130 1162 { 1131 free (dfa->subexp_map);1163 re_free (dfa->subexp_map); 1132 1164 dfa->subexp_map = NULL; 1133 1165 } … … 1135 1167 1136 1168 ret = postorder (dfa->str_tree, lower_subexps, preg); 1137 if ( BE (ret != REG_NOERROR, 0))1169 if (__glibc_unlikely (ret != REG_NOERROR)) 1138 1170 return ret; 1139 1171 ret = postorder (dfa->str_tree, calc_first, dfa); 1140 if ( BE (ret != REG_NOERROR, 0))1172 if (__glibc_unlikely (ret != REG_NOERROR)) 1141 1173 return ret; 1142 1174 preorder (dfa->str_tree, calc_next, dfa); 1143 1175 ret = preorder (dfa->str_tree, link_nfa_nodes, dfa); 1144 if ( BE (ret != REG_NOERROR, 0))1176 if (__glibc_unlikely (ret != REG_NOERROR)) 1145 1177 return ret; 1146 1178 ret = calc_eclosure (dfa); 1147 if ( BE (ret != REG_NOERROR, 0))1179 if (__glibc_unlikely (ret != REG_NOERROR)) 1148 1180 return ret; 1149 1181 … … 1154 1186 { 1155 1187 dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); 1156 if ( BE (dfa->inveclosures == NULL, 0))1157 1188 if (__glibc_unlikely (dfa->inveclosures == NULL)) 1189 return REG_ESPACE; 1158 1190 ret = calc_inveclosure (dfa); 1159 1191 } … … 1177 1209 while (node->left || node->right) 1178 1210 if (node->left) 1179 1180 1181 1211 node = node->left; 1212 else 1213 node = node->right; 1182 1214 1183 1215 do 1184 1216 { 1185 1217 reg_errcode_t err = fn (extra, node); 1186 if ( BE (err != REG_NOERROR, 0))1218 if (__glibc_unlikely (err != REG_NOERROR)) 1187 1219 return err; 1188 1220 if (node->parent == NULL) 1189 1221 return REG_NOERROR; 1190 1222 prev = node; … … 1206 1238 { 1207 1239 reg_errcode_t err = fn (extra, node); 1208 if ( BE (err != REG_NOERROR, 0))1240 if (__glibc_unlikely (err != REG_NOERROR)) 1209 1241 return err; 1210 1242 … … 1220 1252 node = node->parent; 1221 1253 if (!node) 1222 1254 return REG_NOERROR; 1223 1255 } 1224 1256 node = node->right; … … 1243 1275 1244 1276 else if (node->token.type == SUBEXP 1245 1246 { 1247 intother_idx = node->left->token.opr.idx;1277 && node->left && node->left->token.type == SUBEXP) 1278 { 1279 Idx other_idx = node->left->token.opr.idx; 1248 1280 1249 1281 node->left = node->left->left; 1250 1282 if (node->left) 1251 1283 node->left->parent = node; 1252 1284 1253 1285 dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx]; 1254 1286 if (other_idx < BITSET_WORD_BITS) 1255 1287 dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx); 1256 1288 } 1257 1289 … … 1286 1318 lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node) 1287 1319 { 1288 re_dfa_t *dfa = (re_dfa_t *)preg->buffer;1320 re_dfa_t *dfa = preg->buffer; 1289 1321 bin_tree_t *body = node->left; 1290 1322 bin_tree_t *op, *cls, *tree1, *tree; … … 1307 1339 tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls; 1308 1340 tree = create_tree (dfa, op, tree1, CONCAT); 1309 if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0)) 1341 if (__glibc_unlikely (tree == NULL || tree1 == NULL 1342 || op == NULL || cls == NULL)) 1310 1343 { 1311 1344 *err = REG_ESPACE; … … 1333 1366 node->first = node; 1334 1367 node->node_idx = re_dfa_add_node (dfa, node->token); 1335 if (BE (node->node_idx == -1, 0)) 1336 return REG_ESPACE; 1368 if (__glibc_unlikely (node->node_idx == -1)) 1369 return REG_ESPACE; 1370 if (node->token.type == ANCHOR) 1371 dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type; 1337 1372 } 1338 1373 return REG_NOERROR; … … 1356 1391 node->left->next = node->next; 1357 1392 if (node->right) 1358 1393 node->right->next = node->next; 1359 1394 break; 1360 1395 } … … 1367 1402 { 1368 1403 re_dfa_t *dfa = (re_dfa_t *) extra; 1369 intidx = node->node_idx;1404 Idx idx = node->node_idx; 1370 1405 reg_errcode_t err = REG_NOERROR; 1371 1406 … … 1376 1411 1377 1412 case END_OF_RE: 1378 assert(node->next == NULL);1413 DEBUG_ASSERT (node->next == NULL); 1379 1414 break; 1380 1415 … … 1382 1417 case OP_ALT: 1383 1418 { 1384 intleft, right;1419 Idx left, right; 1385 1420 dfa->has_plural_match = 1; 1386 1421 if (node->left != NULL) … … 1392 1427 else 1393 1428 right = node->next->node_idx; 1394 assert(left > -1);1395 assert(right > -1);1429 DEBUG_ASSERT (left > -1); 1430 DEBUG_ASSERT (right > -1); 1396 1431 err = re_node_set_init_2 (dfa->edests + idx, left, right); 1397 1432 } … … 1407 1442 dfa->nexts[idx] = node->next->node_idx; 1408 1443 if (node->token.type == OP_BACK_REF) 1409 re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);1444 err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]); 1410 1445 break; 1411 1446 1412 1447 default: 1413 assert(!IS_EPSILON_NODE (node->token.type));1448 DEBUG_ASSERT (!IS_EPSILON_NODE (node->token.type)); 1414 1449 dfa->nexts[idx] = node->next->node_idx; 1415 1450 break; … … 1424 1459 1425 1460 static reg_errcode_t 1426 internal_function 1427 duplicate_node_closure (re_dfa_t *dfa, int top_org_node, int top_clone_node, 1428 int root_node, unsigned int init_constraint) 1429 { 1430 int org_node, clone_node, ret;1461 duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, 1462 Idx root_node, unsigned int init_constraint) 1463 { 1464 Idx org_node, clone_node; 1465 bool ok; 1431 1466 unsigned int constraint = init_constraint; 1432 1467 for (org_node = top_org_node, clone_node = top_clone_node;;) 1433 1468 { 1434 intorg_dest, clone_dest;1469 Idx org_dest, clone_dest; 1435 1470 if (dfa->nodes[org_node].type == OP_BACK_REF) 1436 1471 { … … 1442 1477 re_node_set_empty (dfa->edests + clone_node); 1443 1478 clone_dest = duplicate_node (dfa, org_dest, constraint); 1444 if ( BE (clone_dest == -1, 0))1479 if (__glibc_unlikely (clone_dest == -1)) 1445 1480 return REG_ESPACE; 1446 1481 dfa->nexts[clone_node] = dfa->nexts[org_node]; 1447 ret= re_node_set_insert (dfa->edests + clone_node, clone_dest);1448 if ( BE (ret < 0, 0))1482 ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); 1483 if (__glibc_unlikely (! ok)) 1449 1484 return REG_ESPACE; 1450 1485 } … … 1463 1498 org_dest = dfa->edests[org_node].elems[0]; 1464 1499 re_node_set_empty (dfa->edests + clone_node); 1465 if (dfa->nodes[org_node].type == ANCHOR) 1500 /* If the node is root_node itself, it means the epsilon closure 1501 has a loop. Then tie it to the destination of the root_node. */ 1502 if (org_node == root_node && clone_node != org_node) 1466 1503 { 1467 /* In case of the node has another constraint, append it. */ 1468 if (org_node == root_node && clone_node != org_node) 1469 { 1470 /* ...but if the node is root_node itself, it means the 1471 epsilon closure have a loop, then tie it to the 1472 destination of the root_node. */ 1473 ret = re_node_set_insert (dfa->edests + clone_node, 1474 org_dest); 1475 if (BE (ret < 0, 0)) 1476 return REG_ESPACE; 1477 break; 1478 } 1479 constraint |= dfa->nodes[org_node].opr.ctx_type; 1504 ok = re_node_set_insert (dfa->edests + clone_node, org_dest); 1505 if (__glibc_unlikely (! ok)) 1506 return REG_ESPACE; 1507 break; 1480 1508 } 1509 /* In case the node has another constraint, append it. */ 1510 constraint |= dfa->nodes[org_node].constraint; 1481 1511 clone_dest = duplicate_node (dfa, org_dest, constraint); 1482 if ( BE (clone_dest == -1, 0))1512 if (__glibc_unlikely (clone_dest == -1)) 1483 1513 return REG_ESPACE; 1484 ret= re_node_set_insert (dfa->edests + clone_node, clone_dest);1485 if ( BE (ret < 0, 0))1514 ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); 1515 if (__glibc_unlikely (! ok)) 1486 1516 return REG_ESPACE; 1487 1517 } … … 1496 1526 if (clone_dest == -1) 1497 1527 { 1498 /* There are no such aduplicated node, create a new one. */1528 /* There is no such duplicated node, create a new one. */ 1499 1529 reg_errcode_t err; 1500 1530 clone_dest = duplicate_node (dfa, org_dest, constraint); 1501 if ( BE (clone_dest == -1, 0))1531 if (__glibc_unlikely (clone_dest == -1)) 1502 1532 return REG_ESPACE; 1503 ret= re_node_set_insert (dfa->edests + clone_node, clone_dest);1504 if ( BE (ret < 0, 0))1533 ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); 1534 if (__glibc_unlikely (! ok)) 1505 1535 return REG_ESPACE; 1506 1536 err = duplicate_node_closure (dfa, org_dest, clone_dest, 1507 1537 root_node, constraint); 1508 if ( BE (err != REG_NOERROR, 0))1538 if (__glibc_unlikely (err != REG_NOERROR)) 1509 1539 return err; 1510 1540 } 1511 1541 else 1512 1542 { 1513 /* There are a duplicated node which satisfythe constraint,1543 /* There is a duplicated node which satisfies the constraint, 1514 1544 use it to avoid infinite loop. */ 1515 ret= re_node_set_insert (dfa->edests + clone_node, clone_dest);1516 if ( BE (ret < 0, 0))1545 ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); 1546 if (__glibc_unlikely (! ok)) 1517 1547 return REG_ESPACE; 1518 1548 } … … 1520 1550 org_dest = dfa->edests[org_node].elems[1]; 1521 1551 clone_dest = duplicate_node (dfa, org_dest, constraint); 1522 if ( BE (clone_dest == -1, 0))1552 if (__glibc_unlikely (clone_dest == -1)) 1523 1553 return REG_ESPACE; 1524 ret= re_node_set_insert (dfa->edests + clone_node, clone_dest);1525 if ( BE (ret < 0, 0))1554 ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); 1555 if (__glibc_unlikely (! ok)) 1526 1556 return REG_ESPACE; 1527 1557 } … … 1535 1565 satisfies the constraint CONSTRAINT. */ 1536 1566 1537 static int1538 search_duplicated_node (const re_dfa_t *dfa, intorg_node,1567 static Idx 1568 search_duplicated_node (const re_dfa_t *dfa, Idx org_node, 1539 1569 unsigned int constraint) 1540 1570 { 1541 intidx;1571 Idx idx; 1542 1572 for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx) 1543 1573 { … … 1553 1583 available. */ 1554 1584 1555 static int1556 duplicate_node (re_dfa_t *dfa, intorg_idx, unsigned int constraint)1557 { 1558 intdup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);1559 if ( BE (dup_idx != -1,1))1585 static Idx 1586 duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint) 1587 { 1588 Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]); 1589 if (__glibc_likely (dup_idx != -1)) 1560 1590 { 1561 1591 dfa->nodes[dup_idx].constraint = constraint; 1562 if (dfa->nodes[org_idx].type == ANCHOR) 1563 dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].opr.ctx_type; 1592 dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint; 1564 1593 dfa->nodes[dup_idx].duplicated = 1; 1565 1594 … … 1573 1602 calc_inveclosure (re_dfa_t *dfa) 1574 1603 { 1575 int src, idx, ret; 1604 Idx src, idx; 1605 bool ok; 1576 1606 for (idx = 0; idx < dfa->nodes_len; ++idx) 1577 1607 re_node_set_init_empty (dfa->inveclosures + idx); … … 1579 1609 for (src = 0; src < dfa->nodes_len; ++src) 1580 1610 { 1581 int*elems = dfa->eclosures[src].elems;1611 Idx *elems = dfa->eclosures[src].elems; 1582 1612 for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) 1583 1613 { 1584 ret= re_node_set_insert_last (dfa->inveclosures + elems[idx], src);1585 if ( BE (ret == -1, 0))1614 ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src); 1615 if (__glibc_unlikely (! ok)) 1586 1616 return REG_ESPACE; 1587 1617 } … … 1596 1626 calc_eclosure (re_dfa_t *dfa) 1597 1627 { 1598 int node_idx, incomplete; 1599 #ifdef DEBUG 1600 assert (dfa->nodes_len > 0); 1601 #endif 1602 incomplete = 0; 1628 Idx node_idx; 1629 bool incomplete; 1630 DEBUG_ASSERT (dfa->nodes_len > 0); 1631 incomplete = false; 1603 1632 /* For each nodes, calculate epsilon closure. */ 1604 1633 for (node_idx = 0; ; ++node_idx) … … 1610 1639 if (!incomplete) 1611 1640 break; 1612 incomplete = 0;1641 incomplete = false; 1613 1642 node_idx = 0; 1614 1643 } 1615 1644 1616 #ifdef DEBUG 1617 assert (dfa->eclosures[node_idx].nelem != -1); 1618 #endif 1645 DEBUG_ASSERT (dfa->eclosures[node_idx].nelem != -1); 1619 1646 1620 1647 /* If we have already calculated, skip it. */ 1621 1648 if (dfa->eclosures[node_idx].nelem != 0) 1622 1649 continue; 1623 /* Calculate epsilon closure of `node_idx'. */1624 err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, 1);1625 if ( BE (err != REG_NOERROR, 0))1650 /* Calculate epsilon closure of 'node_idx'. */ 1651 err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true); 1652 if (__glibc_unlikely (err != REG_NOERROR)) 1626 1653 return err; 1627 1654 1628 1655 if (dfa->eclosures[node_idx].nelem == 0) 1629 1656 { 1630 incomplete = 1;1657 incomplete = true; 1631 1658 re_node_set_free (&eclosure_elem); 1632 1659 } … … 1638 1665 1639 1666 static reg_errcode_t 1640 calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, introot)1667 calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) 1641 1668 { 1642 1669 reg_errcode_t err; 1643 unsigned int constraint; 1644 int i, incomplete; 1670 Idx i; 1645 1671 re_node_set eclosure; 1646 incomplete = 0;1672 bool incomplete = false; 1647 1673 err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); 1648 if ( BE (err != REG_NOERROR, 0))1674 if (__glibc_unlikely (err != REG_NOERROR)) 1649 1675 return err; 1676 1677 /* An epsilon closure includes itself. */ 1678 eclosure.elems[eclosure.nelem++] = node; 1650 1679 1651 1680 /* This indicates that we are calculating this node now. … … 1653 1682 dfa->eclosures[node].nelem = -1; 1654 1683 1655 constraint = ((dfa->nodes[node].type == ANCHOR) 1656 ? dfa->nodes[node].opr.ctx_type : 0); 1657 /* If the current node has constraints, duplicate all nodes. 1658 Since they must inherit the constraints. */ 1659 if (constraint 1684 /* If the current node has constraints, duplicate all nodes 1685 since they must inherit the constraints. */ 1686 if (dfa->nodes[node].constraint 1660 1687 && dfa->edests[node].nelem 1661 1688 && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) 1662 1689 { 1663 int org_node, cur_node; 1664 org_node = cur_node = node; 1665 err = duplicate_node_closure (dfa, node, node, node, constraint); 1666 if (BE (err != REG_NOERROR, 0)) 1690 err = duplicate_node_closure (dfa, node, node, node, 1691 dfa->nodes[node].constraint); 1692 if (__glibc_unlikely (err != REG_NOERROR)) 1667 1693 return err; 1668 1694 } … … 1673 1699 { 1674 1700 re_node_set eclosure_elem; 1675 intedest = dfa->edests[node].elems[i];1676 /* If calculating the epsilon closure of `edest' is in progress,1701 Idx edest = dfa->edests[node].elems[i]; 1702 /* If calculating the epsilon closure of 'edest' is in progress, 1677 1703 return intermediate result. */ 1678 1704 if (dfa->eclosures[edest].nelem == -1) 1679 1705 { 1680 incomplete = 1;1706 incomplete = true; 1681 1707 continue; 1682 1708 } 1683 /* If we haven't calculated the epsilon closure of `edest' yet,1709 /* If we haven't calculated the epsilon closure of 'edest' yet, 1684 1710 calculate now. Otherwise use calculated epsilon closure. */ 1685 1711 if (dfa->eclosures[edest].nelem == 0) 1686 1712 { 1687 err = calc_eclosure_iter (&eclosure_elem, dfa, edest, 0);1688 if ( BE (err != REG_NOERROR, 0))1713 err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); 1714 if (__glibc_unlikely (err != REG_NOERROR)) 1689 1715 return err; 1690 1716 } 1691 1717 else 1692 1718 eclosure_elem = dfa->eclosures[edest]; 1693 /* Merge the epsilon closure of `edest'. */ 1694 re_node_set_merge (&eclosure, &eclosure_elem); 1695 /* If the epsilon closure of `edest' is incomplete, 1719 /* Merge the epsilon closure of 'edest'. */ 1720 err = re_node_set_merge (&eclosure, &eclosure_elem); 1721 if (__glibc_unlikely (err != REG_NOERROR)) 1722 return err; 1723 /* If the epsilon closure of 'edest' is incomplete, 1696 1724 the epsilon closure of this node is also incomplete. */ 1697 1725 if (dfa->eclosures[edest].nelem == 0) 1698 1726 { 1699 incomplete = 1;1727 incomplete = true; 1700 1728 re_node_set_free (&eclosure_elem); 1701 1729 } 1702 1730 } 1703 1731 1704 /* Epsilon closures include itself. */1705 re_node_set_insert (&eclosure, node);1706 1732 if (incomplete && !root) 1707 1733 dfa->eclosures[node].nelem = 0; … … 1719 1745 1720 1746 static void 1721 internal_function1722 1747 fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) 1723 1748 { … … 1729 1754 1730 1755 static int 1731 internal_function1732 1756 peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) 1733 1757 { … … 1744 1768 1745 1769 token->word_char = 0; 1746 #ifdef RE_ENABLE_I18N1747 1770 token->mb_partial = 0; 1748 if (input->mb_cur_max > 1 &&1749 !re_string_first_byte (input, re_string_cur_idx (input)))1771 if (input->mb_cur_max > 1 1772 && !re_string_first_byte (input, re_string_cur_idx (input))) 1750 1773 { 1751 1774 token->type = CHARACTER; … … 1753 1776 return 1; 1754 1777 } 1755 #endif1756 1778 if (c == '\\') 1757 1779 { … … 1766 1788 token->opr.c = c2; 1767 1789 token->type = CHARACTER; 1768 #ifdef RE_ENABLE_I18N1769 1790 if (input->mb_cur_max > 1) 1770 1791 { … … 1774 1795 } 1775 1796 else 1776 #endif1777 1797 token->word_char = IS_WORD_CHAR (c2) != 0; 1778 1798 … … 1880 1900 1881 1901 token->type = CHARACTER; 1882 #ifdef RE_ENABLE_I18N1883 1902 if (input->mb_cur_max > 1) 1884 1903 { … … 1887 1906 } 1888 1907 else 1889 #endif1890 1908 token->word_char = IS_WORD_CHAR (token->opr.c); 1891 1909 … … 1934 1952 break; 1935 1953 case '^': 1936 if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) &&1937 re_string_cur_idx (input) != 0)1954 if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) 1955 && re_string_cur_idx (input) != 0) 1938 1956 { 1939 1957 char prev = re_string_peek_byte (input, -1); … … 1945 1963 break; 1946 1964 case '$': 1947 if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&1948 re_string_cur_idx (input) + 1 != re_string_length (input))1965 if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) 1966 && re_string_cur_idx (input) + 1 != re_string_length (input)) 1949 1967 { 1950 1968 re_token_t next; … … 1968 1986 1969 1987 static int 1970 internal_function1971 1988 peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) 1972 1989 { … … 1980 1997 token->opr.c = c; 1981 1998 1982 #ifdef RE_ENABLE_I18N 1983 if (input->mb_cur_max > 1 && 1984 !re_string_first_byte (input, re_string_cur_idx (input))) 1999 if (input->mb_cur_max > 1 2000 && !re_string_first_byte (input, re_string_cur_idx (input))) 1985 2001 { 1986 2002 token->type = CHARACTER; 1987 2003 return 1; 1988 2004 } 1989 #endif /* RE_ENABLE_I18N */1990 2005 1991 2006 if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) … … 2015 2030 token->type = OP_OPEN_COLL_ELEM; 2016 2031 break; 2032 2017 2033 case '=': 2018 2034 token->type = OP_OPEN_EQUIV_CLASS; 2019 2035 break; 2036 2020 2037 case ':': 2021 2038 if (syntax & RE_CHAR_CLASSES) … … 2024 2041 break; 2025 2042 } 2026 /* else fall through. */2043 FALLTHROUGH; 2027 2044 default: 2028 2045 token->type = CHARACTER; … … 2035 2052 switch (c) 2036 2053 { 2037 case '-':2038 token->type = OP_CHARSET_RANGE;2039 break;2040 2054 case ']': 2041 2055 token->type = OP_CLOSE_BRACKET; … … 2044 2058 token->type = OP_NON_MATCH_LIST; 2045 2059 break; 2060 case '-': 2061 /* In V7 Unix grep and Unix awk and mawk, [...---...] 2062 (3 adjacent minus signs) stands for a single minus sign. 2063 Support that without breaking anything else. */ 2064 if (! (re_string_cur_idx (input) + 2 < re_string_length (input) 2065 && re_string_peek_byte (input, 1) == '-' 2066 && re_string_peek_byte (input, 2) == '-')) 2067 { 2068 token->type = OP_CHARSET_RANGE; 2069 break; 2070 } 2071 re_string_skip_bytes (input, 2); 2072 FALLTHROUGH; 2046 2073 default: 2047 2074 token->type = CHARACTER; … … 2055 2082 /* Entry point of the parser. 2056 2083 Parse the regular expression REGEXP and return the structure tree. 2057 If an error is occured, ERR is set by error code, and return NULL.2084 If an error occurs, ERR is set by error code, and return NULL. 2058 2085 This function build the following tree, from regular expression <reg_exp>: 2059 2086 CAT … … 2069 2096 reg_errcode_t *err) 2070 2097 { 2071 re_dfa_t *dfa = (re_dfa_t *)preg->buffer;2098 re_dfa_t *dfa = preg->buffer; 2072 2099 bin_tree_t *tree, *eor, *root; 2073 2100 re_token_t current_token; … … 2075 2102 fetch_token (¤t_token, regexp, syntax | RE_CARET_ANCHORS_HERE); 2076 2103 tree = parse_reg_exp (regexp, preg, ¤t_token, syntax, 0, err); 2077 if ( BE (*err != REG_NOERROR && tree == NULL, 0))2104 if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) 2078 2105 return NULL; 2079 2106 eor = create_tree (dfa, NULL, NULL, END_OF_RE); … … 2082 2109 else 2083 2110 root = eor; 2084 if ( BE (eor == NULL || root == NULL, 0))2111 if (__glibc_unlikely (eor == NULL || root == NULL)) 2085 2112 { 2086 2113 *err = REG_ESPACE; … … 2097 2124 <branch1> <branch2> 2098 2125 2099 ALT means alternative, which represents the operator `|'. */2126 ALT means alternative, which represents the operator '|'. */ 2100 2127 2101 2128 static bin_tree_t * 2102 2129 parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, 2103 reg_syntax_t syntax, intnest, reg_errcode_t *err)2104 { 2105 re_dfa_t *dfa = (re_dfa_t *)preg->buffer;2130 reg_syntax_t syntax, Idx nest, reg_errcode_t *err) 2131 { 2132 re_dfa_t *dfa = preg->buffer; 2106 2133 bin_tree_t *tree, *branch = NULL; 2134 bitset_word_t initial_bkref_map = dfa->completed_bkref_map; 2107 2135 tree = parse_branch (regexp, preg, token, syntax, nest, err); 2108 if ( BE (*err != REG_NOERROR && tree == NULL, 0))2136 if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) 2109 2137 return NULL; 2110 2138 … … 2115 2143 && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) 2116 2144 { 2145 bitset_word_t accumulated_bkref_map = dfa->completed_bkref_map; 2146 dfa->completed_bkref_map = initial_bkref_map; 2117 2147 branch = parse_branch (regexp, preg, token, syntax, nest, err); 2118 if (BE (*err != REG_NOERROR && branch == NULL, 0)) 2119 return NULL; 2148 if (__glibc_unlikely (*err != REG_NOERROR && branch == NULL)) 2149 { 2150 if (tree != NULL) 2151 postorder (tree, free_tree, NULL); 2152 return NULL; 2153 } 2154 dfa->completed_bkref_map |= accumulated_bkref_map; 2120 2155 } 2121 2156 else 2122 2157 branch = NULL; 2123 2158 tree = create_tree (dfa, tree, branch, OP_ALT); 2124 if ( BE (tree == NULL, 0))2159 if (__glibc_unlikely (tree == NULL)) 2125 2160 { 2126 2161 *err = REG_ESPACE; … … 2142 2177 static bin_tree_t * 2143 2178 parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token, 2144 reg_syntax_t syntax, intnest, reg_errcode_t *err)2145 { 2146 bin_tree_t *tree, *exp ;2147 re_dfa_t *dfa = (re_dfa_t *)preg->buffer;2179 reg_syntax_t syntax, Idx nest, reg_errcode_t *err) 2180 { 2181 bin_tree_t *tree, *expr; 2182 re_dfa_t *dfa = preg->buffer; 2148 2183 tree = parse_expression (regexp, preg, token, syntax, nest, err); 2149 if ( BE (*err != REG_NOERROR && tree == NULL, 0))2184 if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) 2150 2185 return NULL; 2151 2186 … … 2153 2188 && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) 2154 2189 { 2155 exp = parse_expression (regexp, preg, token, syntax, nest, err); 2156 if (BE (*err != REG_NOERROR && exp == NULL, 0)) 2157 { 2190 expr = parse_expression (regexp, preg, token, syntax, nest, err); 2191 if (__glibc_unlikely (*err != REG_NOERROR && expr == NULL)) 2192 { 2193 if (tree != NULL) 2194 postorder (tree, free_tree, NULL); 2158 2195 return NULL; 2159 2196 } 2160 if (tree != NULL && exp != NULL)2161 { 2162 tree = create_tree (dfa, tree, exp, CONCAT);2163 if ( tree == NULL)2197 if (tree != NULL && expr != NULL) 2198 { 2199 bin_tree_t *newtree = create_tree (dfa, tree, expr, CONCAT); 2200 if (newtree == NULL) 2164 2201 { 2202 postorder (expr, free_tree, NULL); 2203 postorder (tree, free_tree, NULL); 2165 2204 *err = REG_ESPACE; 2166 2205 return NULL; 2167 2206 } 2207 tree = newtree; 2168 2208 } 2169 2209 else if (tree == NULL) 2170 tree = exp ;2171 /* Otherwise exp == NULL, we don't need to create new tree. */2210 tree = expr; 2211 /* Otherwise expr == NULL, we don't need to create new tree. */ 2172 2212 } 2173 2213 return tree; … … 2182 2222 static bin_tree_t * 2183 2223 parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, 2184 reg_syntax_t syntax, intnest, reg_errcode_t *err)2185 { 2186 re_dfa_t *dfa = (re_dfa_t *)preg->buffer;2224 reg_syntax_t syntax, Idx nest, reg_errcode_t *err) 2225 { 2226 re_dfa_t *dfa = preg->buffer; 2187 2227 bin_tree_t *tree; 2188 2228 switch (token->type) … … 2190 2230 case CHARACTER: 2191 2231 tree = create_token_tree (dfa, NULL, NULL, token); 2192 if ( BE (tree == NULL, 0))2232 if (__glibc_unlikely (tree == NULL)) 2193 2233 { 2194 2234 *err = REG_ESPACE; 2195 2235 return NULL; 2196 2236 } 2197 #ifdef RE_ENABLE_I18N2198 2237 if (dfa->mb_cur_max > 1) 2199 2238 { … … 2205 2244 mbc_remain = create_token_tree (dfa, NULL, NULL, token); 2206 2245 tree = create_tree (dfa, tree, mbc_remain, CONCAT); 2207 if ( BE (mbc_remain == NULL || tree == NULL, 0))2246 if (__glibc_unlikely (mbc_remain == NULL || tree == NULL)) 2208 2247 { 2209 2248 *err = REG_ESPACE; … … 2212 2251 } 2213 2252 } 2214 #endif2215 2253 break; 2254 2216 2255 case OP_OPEN_SUBEXP: 2217 2256 tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err); 2218 if ( BE (*err != REG_NOERROR && tree == NULL, 0))2257 if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) 2219 2258 return NULL; 2220 2259 break; 2260 2221 2261 case OP_OPEN_BRACKET: 2222 2262 tree = parse_bracket_exp (regexp, dfa, token, syntax, err); 2223 if ( BE (*err != REG_NOERROR && tree == NULL, 0))2263 if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) 2224 2264 return NULL; 2225 2265 break; 2266 2226 2267 case OP_BACK_REF: 2227 if (! BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1))2268 if (!__glibc_likely (dfa->completed_bkref_map & (1 << token->opr.idx))) 2228 2269 { 2229 2270 *err = REG_ESUBREG; … … 2232 2273 dfa->used_bkref_map |= 1 << token->opr.idx; 2233 2274 tree = create_token_tree (dfa, NULL, NULL, token); 2234 if ( BE (tree == NULL, 0))2275 if (__glibc_unlikely (tree == NULL)) 2235 2276 { 2236 2277 *err = REG_ESPACE; … … 2240 2281 dfa->has_mb_node = 1; 2241 2282 break; 2283 2242 2284 case OP_OPEN_DUP_NUM: 2243 2285 if (syntax & RE_CONTEXT_INVALID_DUP) … … 2246 2288 return NULL; 2247 2289 } 2248 /* FALLTHROUGH */2290 FALLTHROUGH; 2249 2291 case OP_DUP_ASTERISK: 2250 2292 case OP_DUP_PLUS: … … 2260 2302 return parse_expression (regexp, preg, token, syntax, nest, err); 2261 2303 } 2262 /* else fall through */2304 FALLTHROUGH; 2263 2305 case OP_CLOSE_SUBEXP: 2264 if ((token->type == OP_CLOSE_SUBEXP) &&2265 !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))2306 if ((token->type == OP_CLOSE_SUBEXP) 2307 && !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) 2266 2308 { 2267 2309 *err = REG_ERPAREN; 2268 2310 return NULL; 2269 2311 } 2270 /* else fall through */2312 FALLTHROUGH; 2271 2313 case OP_CLOSE_DUP_NUM: 2272 2314 /* We treat it as a normal character. */ … … 2277 2319 by peek_token. */ 2278 2320 tree = create_token_tree (dfa, NULL, NULL, token); 2279 if ( BE (tree == NULL, 0))2321 if (__glibc_unlikely (tree == NULL)) 2280 2322 { 2281 2323 *err = REG_ESPACE; … … 2283 2325 } 2284 2326 break; 2327 2285 2328 case ANCHOR: 2286 2329 if ((token->opr.ctx_type … … 2289 2332 init_word_char (dfa); 2290 2333 if (token->opr.ctx_type == WORD_DELIM 2291 2334 || token->opr.ctx_type == NOT_WORD_DELIM) 2292 2335 { 2293 2336 bin_tree_t *tree_first, *tree_last; … … 2297 2340 tree_first = create_token_tree (dfa, NULL, NULL, token); 2298 2341 token->opr.ctx_type = WORD_LAST; 2299 2300 2301 2342 } 2343 else 2344 { 2302 2345 token->opr.ctx_type = INSIDE_WORD; 2303 2346 tree_first = create_token_tree (dfa, NULL, NULL, token); 2304 2347 token->opr.ctx_type = INSIDE_NOTWORD; 2305 2348 } 2306 2349 tree_last = create_token_tree (dfa, NULL, NULL, token); 2307 2350 tree = create_tree (dfa, tree_first, tree_last, OP_ALT); 2308 if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0)) 2351 if (__glibc_unlikely (tree_first == NULL || tree_last == NULL 2352 || tree == NULL)) 2309 2353 { 2310 2354 *err = REG_ESPACE; … … 2315 2359 { 2316 2360 tree = create_token_tree (dfa, NULL, NULL, token); 2317 if ( BE (tree == NULL, 0))2361 if (__glibc_unlikely (tree == NULL)) 2318 2362 { 2319 2363 *err = REG_ESPACE; … … 2327 2371 fetch_token (token, regexp, syntax); 2328 2372 return tree; 2373 2329 2374 case OP_PERIOD: 2330 2375 tree = create_token_tree (dfa, NULL, NULL, token); 2331 if ( BE (tree == NULL, 0))2376 if (__glibc_unlikely (tree == NULL)) 2332 2377 { 2333 2378 *err = REG_ESPACE; … … 2337 2382 dfa->has_mb_node = 1; 2338 2383 break; 2384 2339 2385 case OP_WORD: 2340 2386 case OP_NOTWORD: 2341 2387 tree = build_charclass_op (dfa, regexp->trans, 2342 (const unsigned char *)"alnum",2343 (const unsigned char *)"_",2388 "alnum", 2389 "_", 2344 2390 token->type == OP_NOTWORD, err); 2345 if ( BE (*err != REG_NOERROR && tree == NULL, 0))2391 if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) 2346 2392 return NULL; 2347 2393 break; 2394 2348 2395 case OP_SPACE: 2349 2396 case OP_NOTSPACE: 2350 2397 tree = build_charclass_op (dfa, regexp->trans, 2351 (const unsigned char *)"space",2352 (const unsigned char *)"",2398 "space", 2399 "", 2353 2400 token->type == OP_NOTSPACE, err); 2354 if ( BE (*err != REG_NOERROR && tree == NULL, 0))2401 if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) 2355 2402 return NULL; 2356 2403 break; 2404 2357 2405 case OP_ALT: 2358 2406 case END_OF_RE: 2359 2407 return NULL; 2408 2360 2409 case BACK_SLASH: 2361 2410 *err = REG_EESCAPE; 2362 2411 return NULL; 2412 2363 2413 default: 2364 2414 /* Must not happen? */ 2365 #ifdef DEBUG 2366 assert (0); 2367 #endif 2415 DEBUG_ASSERT (false); 2368 2416 return NULL; 2369 2417 } … … 2373 2421 || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM) 2374 2422 { 2375 tree = parse_dup_op (tree, regexp, dfa, token, syntax, err); 2376 if (BE (*err != REG_NOERROR && tree == NULL, 0)) 2377 return NULL; 2423 bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token, 2424 syntax, err); 2425 if (__glibc_unlikely (*err != REG_NOERROR && dup_tree == NULL)) 2426 { 2427 if (tree != NULL) 2428 postorder (tree, free_tree, NULL); 2429 return NULL; 2430 } 2431 tree = dup_tree; 2378 2432 /* In BRE consecutive duplications are not allowed. */ 2379 2433 if ((syntax & RE_CONTEXT_INVALID_DUP) … … 2381 2435 || token->type == OP_OPEN_DUP_NUM)) 2382 2436 { 2437 if (tree != NULL) 2438 postorder (tree, free_tree, NULL); 2383 2439 *err = REG_BADRPT; 2384 2440 return NULL; … … 2398 2454 static bin_tree_t * 2399 2455 parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, 2400 reg_syntax_t syntax, intnest, reg_errcode_t *err)2401 { 2402 re_dfa_t *dfa = (re_dfa_t *)preg->buffer;2456 reg_syntax_t syntax, Idx nest, reg_errcode_t *err) 2457 { 2458 re_dfa_t *dfa = preg->buffer; 2403 2459 bin_tree_t *tree; 2404 2460 size_t cur_nsub; … … 2413 2469 { 2414 2470 tree = parse_reg_exp (regexp, preg, token, syntax, nest, err); 2415 if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0)) 2416 *err = REG_EPAREN; 2417 if (BE (*err != REG_NOERROR, 0)) 2471 if (__glibc_unlikely (*err == REG_NOERROR 2472 && token->type != OP_CLOSE_SUBEXP)) 2473 { 2474 if (tree != NULL) 2475 postorder (tree, free_tree, NULL); 2476 *err = REG_EPAREN; 2477 } 2478 if (__glibc_unlikely (*err != REG_NOERROR)) 2418 2479 return NULL; 2419 2480 } … … 2423 2484 2424 2485 tree = create_tree (dfa, tree, NULL, SUBEXP); 2425 if ( BE (tree == NULL, 0))2486 if (__glibc_unlikely (tree == NULL)) 2426 2487 { 2427 2488 *err = REG_ESPACE; … … 2439 2500 { 2440 2501 bin_tree_t *tree = NULL, *old_tree = NULL; 2441 inti, start, end, start_idx = re_string_cur_idx (regexp);2502 Idx i, start, end, start_idx = re_string_cur_idx (regexp); 2442 2503 re_token_t start_token = *token; 2443 2504 … … 2456 2517 } 2457 2518 } 2458 if ( BE (start != -2, 1))2519 if (__glibc_likely (start != -2)) 2459 2520 { 2460 2521 /* We treat "{n}" as "{n,n}". */ … … 2463 2524 ? fetch_number (regexp, token, syntax) : -2)); 2464 2525 } 2465 if ( BE (start == -2 || end == -2, 0))2526 if (__glibc_unlikely (start == -2 || end == -2)) 2466 2527 { 2467 2528 /* Invalid sequence. */ 2468 if ( BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))2529 if (__glibc_unlikely (!(syntax & RE_INVALID_INTERVAL_ORD))) 2469 2530 { 2470 2531 if (token->type == END_OF_RE) … … 2485 2546 } 2486 2547 2487 if (BE (end != -1 && start > end, 0)) 2548 if (__glibc_unlikely ((end != -1 && start > end) 2549 || token->type != OP_CLOSE_DUP_NUM)) 2488 2550 { 2489 2551 /* First number greater than second. */ … … 2491 2553 return NULL; 2492 2554 } 2555 2556 if (__glibc_unlikely (RE_DUP_MAX < (end == -1 ? start : end))) 2557 { 2558 *err = REG_ESIZE; 2559 return NULL; 2560 } 2493 2561 } 2494 2562 else … … 2500 2568 fetch_token (token, regexp, syntax); 2501 2569 2502 if ( BE (elem == NULL, 0))2570 if (__glibc_unlikely (elem == NULL)) 2503 2571 return NULL; 2504 if ( BE (start == 0 && end == 0,0))2572 if (__glibc_unlikely (start == 0 && end == 0)) 2505 2573 { 2506 2574 postorder (elem, free_tree, NULL); … … 2509 2577 2510 2578 /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}". */ 2511 if ( BE (start > 0,0))2579 if (__glibc_unlikely (start > 0)) 2512 2580 { 2513 2581 tree = elem; … … 2516 2584 elem = duplicate_tree (elem, dfa); 2517 2585 tree = create_tree (dfa, tree, elem, CONCAT); 2518 if ( BE (elem == NULL || tree == NULL, 0))2586 if (__glibc_unlikely (elem == NULL || tree == NULL)) 2519 2587 goto parse_dup_op_espace; 2520 2588 } … … 2525 2593 /* Duplicate ELEM before it is marked optional. */ 2526 2594 elem = duplicate_tree (elem, dfa); 2595 if (__glibc_unlikely (elem == NULL)) 2596 goto parse_dup_op_espace; 2527 2597 old_tree = tree; 2528 2598 } … … 2531 2601 2532 2602 if (elem->token.type == SUBEXP) 2533 postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx); 2534 2535 tree = create_tree (dfa, elem, NULL, (end == -1 ? OP_DUP_ASTERISK : OP_ALT)); 2536 if (BE (tree == NULL, 0)) 2603 { 2604 uintptr_t subidx = elem->token.opr.idx; 2605 postorder (elem, mark_opt_subexp, (void *) subidx); 2606 } 2607 2608 tree = create_tree (dfa, elem, NULL, 2609 (end == -1 ? OP_DUP_ASTERISK : OP_ALT)); 2610 if (__glibc_unlikely (tree == NULL)) 2537 2611 goto parse_dup_op_espace; 2538 2612 … … 2540 2614 to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?... We have 2541 2615 already created the start+1-th copy. */ 2542 for (i = start + 2; i <= end; ++i) 2543 { 2544 elem = duplicate_tree (elem, dfa); 2545 tree = create_tree (dfa, tree, elem, CONCAT); 2546 if (BE (elem == NULL || tree == NULL, 0)) 2547 goto parse_dup_op_espace; 2548 2549 tree = create_tree (dfa, tree, NULL, OP_ALT); 2550 if (BE (tree == NULL, 0)) 2551 goto parse_dup_op_espace; 2552 } 2616 if (TYPE_SIGNED (Idx) || end != -1) 2617 for (i = start + 2; i <= end; ++i) 2618 { 2619 elem = duplicate_tree (elem, dfa); 2620 tree = create_tree (dfa, tree, elem, CONCAT); 2621 if (__glibc_unlikely (elem == NULL || tree == NULL)) 2622 goto parse_dup_op_espace; 2623 2624 tree = create_tree (dfa, tree, NULL, OP_ALT); 2625 if (__glibc_unlikely (tree == NULL)) 2626 goto parse_dup_op_espace; 2627 } 2553 2628 2554 2629 if (old_tree) … … 2567 2642 2568 2643 #ifndef _LIBC 2569 /* Local function for parse_bracket_exp only used in case of NOT _LIBC. 2570 Build the range expression which starts from START_ELEM, and ends 2571 at END_ELEM. The result are written to MBCSET and SBCSET. 2572 RANGE_ALLOC is the allocated size of mbcset->range_starts, and 2573 mbcset->range_ends, is a pointer argument sinse we may 2574 update it. */ 2644 2645 /* Convert the byte B to the corresponding wide character. In a 2646 unibyte locale, treat B as itself. In a multibyte locale, return 2647 WEOF if B is an encoding error. */ 2648 static wint_t 2649 parse_byte (unsigned char b, re_dfa_t const *dfa) 2650 { 2651 return dfa->mb_cur_max > 1 ? __btowc (b) : b; 2652 } 2653 2654 /* Local function for parse_bracket_exp used in _LIBC environment. 2655 Build the range expression which starts from START_ELEM, and ends 2656 at END_ELEM. The result are written to MBCSET and SBCSET. 2657 RANGE_ALLOC is the allocated size of mbcset->range_starts, and 2658 mbcset->range_ends, is a pointer argument since we may 2659 update it. */ 2575 2660 2576 2661 static reg_errcode_t 2577 internal_function 2578 # ifdef RE_ENABLE_I18N 2579 build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc, 2580 bracket_elem_t *start_elem, bracket_elem_t *end_elem) 2581 # else /* not RE_ENABLE_I18N */ 2582 build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, 2583 bracket_elem_t *end_elem) 2584 # endif /* not RE_ENABLE_I18N */ 2585 { 2586 unsigned int start_ch, end_ch; 2662 build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc, 2663 bracket_elem_t *start_elem, bracket_elem_t *end_elem, 2664 re_dfa_t *dfa, reg_syntax_t syntax, uint_fast32_t nrules, 2665 const unsigned char *collseqmb, const char *collseqwc, 2666 int_fast32_t table_size, const void *symb_table, 2667 const unsigned char *extra) 2668 { 2587 2669 /* Equivalence Classes and Character Classes can't be a range start/end. */ 2588 if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS 2589 || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, 2590 0)) 2670 if (__glibc_unlikely (start_elem->type == EQUIV_CLASS 2671 || start_elem->type == CHAR_CLASS 2672 || end_elem->type == EQUIV_CLASS 2673 || end_elem->type == CHAR_CLASS)) 2591 2674 return REG_ERANGE; 2592 2675 2593 2676 /* We can handle no multi character collating elements without libc 2594 2677 support. */ 2595 if ( BE((start_elem->type == COLL_SYM2596 2597 2598 && strlen ((char *) end_elem->opr.name) > 1), 0))2678 if (__glibc_unlikely ((start_elem->type == COLL_SYM 2679 && strlen ((char *) start_elem->opr.name) > 1) 2680 || (end_elem->type == COLL_SYM 2681 && strlen ((char *) end_elem->opr.name) > 1))) 2599 2682 return REG_ECOLLATE; 2600 2683 2601 # ifdef RE_ENABLE_I18N 2602 { 2603 wchar_t wc; 2604 wint_t start_wc; 2605 wint_t end_wc; 2606 wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; 2607 2684 unsigned int 2608 2685 start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch 2609 2686 : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] 2610 : 0)) ;2687 : 0)), 2611 2688 end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch 2612 2689 : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] 2613 2690 : 0)); 2691 wint_t 2614 2692 start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) 2615 ? __btowc (start_ch) : start_elem->opr.wch);2693 ? parse_byte (start_ch, dfa) : start_elem->opr.wch), 2616 2694 end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) 2617 ? __btowc (end_ch) : end_elem->opr.wch); 2618 if (start_wc == WEOF || end_wc == WEOF) 2619 return REG_ECOLLATE; 2620 cmp_buf[0] = start_wc; 2621 cmp_buf[4] = end_wc; 2622 if (wcscoll (cmp_buf, cmp_buf + 4) > 0) 2623 return REG_ERANGE; 2624 2625 /* Got valid collation sequence values, add them as a new entry. 2626 However, for !_LIBC we have no collation elements: if the 2627 character set is single byte, the single byte character set 2628 that we build below suffices. parse_bracket_exp passes 2629 no MBCSET if dfa->mb_cur_max == 1. */ 2630 if (mbcset) 2631 { 2632 /* Check the space of the arrays. */ 2633 if (BE (*range_alloc == mbcset->nranges, 0)) 2634 { 2635 /* There is not enough space, need realloc. */ 2636 wchar_t *new_array_start, *new_array_end; 2637 int new_nranges; 2638 2639 /* +1 in case of mbcset->nranges is 0. */ 2640 new_nranges = 2 * mbcset->nranges + 1; 2641 /* Use realloc since mbcset->range_starts and mbcset->range_ends 2642 are NULL if *range_alloc == 0. */ 2643 new_array_start = re_realloc (mbcset->range_starts, wchar_t, 2644 new_nranges); 2645 new_array_end = re_realloc (mbcset->range_ends, wchar_t, 2646 new_nranges); 2647 2648 if (BE (new_array_start == NULL || new_array_end == NULL, 0)) 2649 return REG_ESPACE; 2650 2651 mbcset->range_starts = new_array_start; 2652 mbcset->range_ends = new_array_end; 2653 *range_alloc = new_nranges; 2654 } 2655 2656 mbcset->range_starts[mbcset->nranges] = start_wc; 2657 mbcset->range_ends[mbcset->nranges++] = end_wc; 2658 } 2659 2660 /* Build the table for single byte characters. */ 2661 for (wc = 0; wc < SBC_MAX; ++wc) 2662 { 2663 cmp_buf[2] = wc; 2664 if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 2665 && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) 2666 bitset_set (sbcset, wc); 2667 } 2668 } 2669 # else /* not RE_ENABLE_I18N */ 2670 { 2671 unsigned int ch; 2672 start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch 2673 : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] 2674 : 0)); 2675 end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch 2676 : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] 2677 : 0)); 2678 if (start_ch > end_ch) 2679 return REG_ERANGE; 2680 /* Build the table for single byte characters. */ 2681 for (ch = 0; ch < SBC_MAX; ++ch) 2682 if (start_ch <= ch && ch <= end_ch) 2683 bitset_set (sbcset, ch); 2684 } 2685 # endif /* not RE_ENABLE_I18N */ 2695 ? parse_byte (end_ch, dfa) : end_elem->opr.wch); 2696 2697 if (start_wc == WEOF || end_wc == WEOF) 2698 return REG_ECOLLATE; 2699 else if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES) 2700 && start_wc > end_wc)) 2701 return REG_ERANGE; 2702 2703 /* Got valid collation sequence values, add them as a new entry. 2704 However, for !_LIBC we have no collation elements: if the 2705 character set is single byte, the single byte character set 2706 that we build below suffices. parse_bracket_exp passes 2707 no MBCSET if dfa->mb_cur_max == 1. */ 2708 if (dfa->mb_cur_max > 1) 2709 { 2710 /* Check the space of the arrays. */ 2711 if (__glibc_unlikely (*range_alloc == mbcset->nranges)) 2712 { 2713 /* There is not enough space, need realloc. */ 2714 wchar_t *new_array_start, *new_array_end; 2715 Idx new_nranges; 2716 2717 /* +1 in case of mbcset->nranges is 0. */ 2718 new_nranges = 2 * mbcset->nranges + 1; 2719 /* Use realloc since mbcset->range_starts and mbcset->range_ends 2720 are NULL if *range_alloc == 0. */ 2721 new_array_start = re_realloc (mbcset->range_starts, wchar_t, 2722 new_nranges); 2723 new_array_end = re_realloc (mbcset->range_ends, wchar_t, 2724 new_nranges); 2725 2726 if (__glibc_unlikely (new_array_start == NULL 2727 || new_array_end == NULL)) 2728 { 2729 re_free (new_array_start); 2730 re_free (new_array_end); 2731 return REG_ESPACE; 2732 } 2733 2734 mbcset->range_starts = new_array_start; 2735 mbcset->range_ends = new_array_end; 2736 *range_alloc = new_nranges; 2737 } 2738 2739 mbcset->range_starts[mbcset->nranges] = start_wc; 2740 mbcset->range_ends[mbcset->nranges++] = end_wc; 2741 } 2742 2743 /* Build the table for single byte characters. */ 2744 for (wchar_t wc = 0; wc < SBC_MAX; ++wc) 2745 { 2746 if (start_wc <= wc && wc <= end_wc) 2747 bitset_set (sbcset, wc); 2748 } 2749 2686 2750 return REG_NOERROR; 2687 2751 } … … 2689 2753 2690 2754 #ifndef _LIBC 2691 /* Helper function for parse_bracket_exp only used in case of NOT _LIBC. .2755 /* Helper function for parse_bracket_exp only used in case of NOT _LIBC. 2692 2756 Build the collating element which is represented by NAME. 2693 2757 The result are written to MBCSET and SBCSET. … … 2696 2760 2697 2761 static reg_errcode_t 2698 internal_function2699 # ifdef RE_ENABLE_I18N2700 2762 build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, 2701 int *coll_sym_alloc, const unsigned char *name) 2702 # else /* not RE_ENABLE_I18N */ 2703 build_collating_symbol (bitset_t sbcset, const unsigned char *name) 2704 # endif /* not RE_ENABLE_I18N */ 2763 Idx *coll_sym_alloc, const unsigned char *name, 2764 uint_fast32_t nrules, int_fast32_t table_size, 2765 const void *symb_table, const unsigned char *extra) 2705 2766 { 2706 2767 size_t name_len = strlen ((const char *) name); 2707 if ( BE (name_len != 1, 0))2768 if (__glibc_unlikely (name_len != 1)) 2708 2769 return REG_ECOLLATE; 2709 2770 else … … 2715 2776 #endif /* not _LIBC */ 2716 2777 2717 /* This function parse bracket expression like "[abc]", "[a-c]",2718 "[[.a-a.]]" etc. */2719 2720 static bin_tree_t *2721 parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,2722 reg_syntax_t syntax, reg_errcode_t *err)2723 {2724 2778 #ifdef _LIBC 2725 const unsigned char *collseqmb; 2726 const char *collseqwc; 2727 uint32_t nrules; 2728 int32_t table_size; 2729 const int32_t *symb_table; 2730 const unsigned char *extra; 2731 2732 /* Local function for parse_bracket_exp used in _LIBC environement. 2733 Seek the collating symbol entry correspondings to NAME. 2734 Return the index of the symbol in the SYMB_TABLE. */ 2735 2736 auto inline int32_t 2737 __attribute ((always_inline)) 2738 seek_collating_symbol_entry (name, name_len) 2739 const unsigned char *name; 2740 size_t name_len; 2741 { 2742 int32_t hash = elem_hash ((const char *) name, name_len); 2743 int32_t elem = hash % table_size; 2744 if (symb_table[2 * elem] != 0) 2745 { 2746 int32_t second = hash % (table_size - 2) + 1; 2747 2748 do 2749 { 2750 /* First compare the hashing value. */ 2751 if (symb_table[2 * elem] == hash 2752 /* Compare the length of the name. */ 2753 && name_len == extra[symb_table[2 * elem + 1]] 2754 /* Compare the name. */ 2755 && memcmp (name, &extra[symb_table[2 * elem + 1] + 1], 2756 name_len) == 0) 2757 { 2758 /* Yep, this is the entry. */ 2759 break; 2760 } 2761 2762 /* Next entry. */ 2763 elem += second; 2764 } 2765 while (symb_table[2 * elem] != 0); 2766 } 2767 return elem; 2768 } 2769 2770 /* Local function for parse_bracket_exp used in _LIBC environement. 2771 Look up the collation sequence value of BR_ELEM. 2772 Return the value if succeeded, UINT_MAX otherwise. */ 2773 2774 auto inline unsigned int 2775 __attribute ((always_inline)) 2776 lookup_collation_sequence_value (br_elem) 2777 bracket_elem_t *br_elem; 2778 { 2779 if (br_elem->type == SB_CHAR) 2780 { 2781 /* 2782 if (MB_CUR_MAX == 1) 2783 */ 2784 if (nrules == 0) 2785 return collseqmb[br_elem->opr.ch]; 2786 else 2787 { 2788 wint_t wc = __btowc (br_elem->opr.ch); 2789 return __collseq_table_lookup (collseqwc, wc); 2790 } 2791 } 2792 else if (br_elem->type == MB_CHAR) 2793 { 2794 return __collseq_table_lookup (collseqwc, br_elem->opr.wch); 2795 } 2796 else if (br_elem->type == COLL_SYM) 2797 { 2798 size_t sym_name_len = strlen ((char *) br_elem->opr.name); 2799 if (nrules != 0) 2800 { 2801 int32_t elem, idx; 2802 elem = seek_collating_symbol_entry (br_elem->opr.name, 2803 sym_name_len); 2804 if (symb_table[2 * elem] != 0) 2805 { 2806 /* We found the entry. */ 2807 idx = symb_table[2 * elem + 1]; 2808 /* Skip the name of collating element name. */ 2809 idx += 1 + extra[idx]; 2810 /* Skip the byte sequence of the collating element. */ 2811 idx += 1 + extra[idx]; 2812 /* Adjust for the alignment. */ 2813 idx = (idx + 3) & ~3; 2814 /* Skip the multibyte collation sequence value. */ 2815 idx += sizeof (unsigned int); 2816 /* Skip the wide char sequence of the collating element. */ 2817 idx += sizeof (unsigned int) * 2818 (1 + *(unsigned int *) (extra + idx)); 2819 /* Return the collation sequence value. */ 2820 return *(unsigned int *) (extra + idx); 2821 } 2822 else if (symb_table[2 * elem] == 0 && sym_name_len == 1) 2823 { 2824 /* No valid character. Match it as a single byte 2825 character. */ 2826 return collseqmb[br_elem->opr.name[0]]; 2827 } 2828 } 2829 else if (sym_name_len == 1) 2830 return collseqmb[br_elem->opr.name[0]]; 2831 } 2832 return UINT_MAX; 2833 } 2834 2835 /* Local function for parse_bracket_exp used in _LIBC environement. 2836 Build the range expression which starts from START_ELEM, and ends 2837 at END_ELEM. The result are written to MBCSET and SBCSET. 2838 RANGE_ALLOC is the allocated size of mbcset->range_starts, and 2839 mbcset->range_ends, is a pointer argument sinse we may 2840 update it. */ 2841 2842 auto inline reg_errcode_t 2843 __attribute ((always_inline)) 2844 build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem) 2845 re_charset_t *mbcset; 2846 int *range_alloc; 2847 bitset_t sbcset; 2848 bracket_elem_t *start_elem, *end_elem; 2849 { 2850 unsigned int ch; 2851 uint32_t start_collseq; 2852 uint32_t end_collseq; 2853 2854 /* Equivalence Classes and Character Classes can't be a range 2855 start/end. */ 2856 if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS 2857 || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, 2858 0)) 2859 return REG_ERANGE; 2860 2861 start_collseq = lookup_collation_sequence_value (start_elem); 2862 end_collseq = lookup_collation_sequence_value (end_elem); 2863 /* Check start/end collation sequence values. */ 2864 if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0)) 2865 return REG_ECOLLATE; 2866 if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0)) 2867 return REG_ERANGE; 2868 2869 /* Got valid collation sequence values, add them as a new entry. 2870 However, if we have no collation elements, and the character set 2871 is single byte, the single byte character set that we 2872 build below suffices. */ 2873 if (nrules > 0 || dfa->mb_cur_max > 1) 2874 { 2875 /* Check the space of the arrays. */ 2876 if (BE (*range_alloc == mbcset->nranges, 0)) 2877 { 2878 /* There is not enough space, need realloc. */ 2879 uint32_t *new_array_start; 2880 uint32_t *new_array_end; 2881 int new_nranges; 2882 2883 /* +1 in case of mbcset->nranges is 0. */ 2884 new_nranges = 2 * mbcset->nranges + 1; 2885 new_array_start = re_realloc (mbcset->range_starts, uint32_t, 2886 new_nranges); 2887 new_array_end = re_realloc (mbcset->range_ends, uint32_t, 2888 new_nranges); 2889 2890 if (BE (new_array_start == NULL || new_array_end == NULL, 0)) 2891 return REG_ESPACE; 2892 2893 mbcset->range_starts = new_array_start; 2894 mbcset->range_ends = new_array_end; 2895 *range_alloc = new_nranges; 2896 } 2897 2898 mbcset->range_starts[mbcset->nranges] = start_collseq; 2899 mbcset->range_ends[mbcset->nranges++] = end_collseq; 2900 } 2901 2902 /* Build the table for single byte characters. */ 2903 for (ch = 0; ch < SBC_MAX; ch++) 2904 { 2905 uint32_t ch_collseq; 2906 /* 2907 if (MB_CUR_MAX == 1) 2908 */ 2909 if (nrules == 0) 2910 ch_collseq = collseqmb[ch]; 2911 else 2912 ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); 2913 if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) 2914 bitset_set (sbcset, ch); 2915 } 2916 return REG_NOERROR; 2917 } 2918 2919 /* Local function for parse_bracket_exp used in _LIBC environement. 2920 Build the collating element which is represented by NAME. 2921 The result are written to MBCSET and SBCSET. 2922 COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a 2923 pointer argument sinse we may update it. */ 2924 2925 auto inline reg_errcode_t 2926 __attribute ((always_inline)) 2927 build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name) 2928 re_charset_t *mbcset; 2929 int *coll_sym_alloc; 2930 bitset_t sbcset; 2931 const unsigned char *name; 2932 { 2933 int32_t elem, idx; 2934 size_t name_len = strlen ((const char *) name); 2779 /* Local function for parse_bracket_exp used in _LIBC environment. 2780 Seek the collating symbol entry corresponding to NAME. 2781 Return the index of the symbol in the SYMB_TABLE, 2782 or -1 if not found. */ 2783 2784 static __always_inline int32_t 2785 seek_collating_symbol_entry (const unsigned char *name, size_t name_len, 2786 const int32_t *symb_table, 2787 int_fast32_t table_size, 2788 const unsigned char *extra) 2789 { 2790 int_fast32_t elem; 2791 2792 for (elem = 0; elem < table_size; elem++) 2793 if (symb_table[2 * elem] != 0) 2794 { 2795 int32_t idx = symb_table[2 * elem + 1]; 2796 /* Skip the name of collating element name. */ 2797 idx += 1 + extra[idx]; 2798 if (/* Compare the length of the name. */ 2799 name_len == extra[idx] 2800 /* Compare the name. */ 2801 && memcmp (name, &extra[idx + 1], name_len) == 0) 2802 /* Yep, this is the entry. */ 2803 return elem; 2804 } 2805 return -1; 2806 } 2807 2808 /* Local function for parse_bracket_exp used in _LIBC environment. 2809 Look up the collation sequence value of BR_ELEM. 2810 Return the value if succeeded, UINT_MAX otherwise. */ 2811 2812 static __always_inline unsigned int 2813 lookup_collation_sequence_value (bracket_elem_t *br_elem, uint32_t nrules, 2814 const unsigned char *collseqmb, 2815 const char *collseqwc, 2816 int_fast32_t table_size, 2817 const int32_t *symb_table, 2818 const unsigned char *extra) 2819 { 2820 if (br_elem->type == SB_CHAR) 2821 { 2822 /* if (MB_CUR_MAX == 1) */ 2823 if (nrules == 0) 2824 return collseqmb[br_elem->opr.ch]; 2825 else 2826 { 2827 wint_t wc = __btowc (br_elem->opr.ch); 2828 return __collseq_table_lookup (collseqwc, wc); 2829 } 2830 } 2831 else if (br_elem->type == MB_CHAR) 2832 { 2935 2833 if (nrules != 0) 2936 { 2937 elem = seek_collating_symbol_entry (name, name_len); 2938 if (symb_table[2 * elem] != 0) 2834 return __collseq_table_lookup (collseqwc, br_elem->opr.wch); 2835 } 2836 else if (br_elem->type == COLL_SYM) 2837 { 2838 size_t sym_name_len = strlen ((char *) br_elem->opr.name); 2839 if (nrules != 0) 2840 { 2841 int32_t elem, idx; 2842 elem = seek_collating_symbol_entry (br_elem->opr.name, 2843 sym_name_len, 2844 symb_table, table_size, 2845 extra); 2846 if (elem != -1) 2939 2847 { 2940 2848 /* We found the entry. */ … … 2942 2850 /* Skip the name of collating element name. */ 2943 2851 idx += 1 + extra[idx]; 2852 /* Skip the byte sequence of the collating element. */ 2853 idx += 1 + extra[idx]; 2854 /* Adjust for the alignment. */ 2855 idx = (idx + 3) & ~3; 2856 /* Skip the multibyte collation sequence value. */ 2857 idx += sizeof (unsigned int); 2858 /* Skip the wide char sequence of the collating element. */ 2859 idx += sizeof (unsigned int) * 2860 (1 + *(unsigned int *) (extra + idx)); 2861 /* Return the collation sequence value. */ 2862 return *(unsigned int *) (extra + idx); 2944 2863 } 2945 else if (sym b_table[2 * elem] == 0 &&name_len == 1)2864 else if (sym_name_len == 1) 2946 2865 { 2947 /* No valid character , treat it as a normal2866 /* No valid character. Match it as a single byte 2948 2867 character. */ 2949 bitset_set (sbcset, name[0]); 2950 return REG_NOERROR; 2868 return collseqmb[br_elem->opr.name[0]]; 2951 2869 } 2952 else 2953 return REG_ECOLLATE; 2954 2955 /* Got valid collation sequence, add it as a new entry. */ 2956 /* Check the space of the arrays. */ 2957 if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0)) 2958 { 2959 /* Not enough, realloc it. */ 2960 /* +1 in case of mbcset->ncoll_syms is 0. */ 2961 int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; 2962 /* Use realloc since mbcset->coll_syms is NULL 2963 if *alloc == 0. */ 2964 int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, 2965 new_coll_sym_alloc); 2966 if (BE (new_coll_syms == NULL, 0)) 2967 return REG_ESPACE; 2968 mbcset->coll_syms = new_coll_syms; 2969 *coll_sym_alloc = new_coll_sym_alloc; 2970 } 2971 mbcset->coll_syms[mbcset->ncoll_syms++] = idx; 2870 } 2871 else if (sym_name_len == 1) 2872 return collseqmb[br_elem->opr.name[0]]; 2873 } 2874 return UINT_MAX; 2875 } 2876 2877 /* Local function for parse_bracket_exp used in _LIBC environment. 2878 Build the range expression which starts from START_ELEM, and ends 2879 at END_ELEM. The result are written to MBCSET and SBCSET. 2880 RANGE_ALLOC is the allocated size of mbcset->range_starts, and 2881 mbcset->range_ends, is a pointer argument since we may 2882 update it. */ 2883 2884 static __always_inline reg_errcode_t 2885 build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc, 2886 bracket_elem_t *start_elem, bracket_elem_t *end_elem, 2887 re_dfa_t *dfa, reg_syntax_t syntax, uint32_t nrules, 2888 const unsigned char *collseqmb, const char *collseqwc, 2889 int_fast32_t table_size, const int32_t *symb_table, 2890 const unsigned char *extra) 2891 { 2892 unsigned int ch; 2893 uint32_t start_collseq; 2894 uint32_t end_collseq; 2895 2896 /* Equivalence Classes and Character Classes can't be a range 2897 start/end. */ 2898 if (__glibc_unlikely (start_elem->type == EQUIV_CLASS 2899 || start_elem->type == CHAR_CLASS 2900 || end_elem->type == EQUIV_CLASS 2901 || end_elem->type == CHAR_CLASS)) 2902 return REG_ERANGE; 2903 2904 /* FIXME: Implement rational ranges here, too. */ 2905 start_collseq = lookup_collation_sequence_value (start_elem, nrules, collseqmb, collseqwc, 2906 table_size, symb_table, extra); 2907 end_collseq = lookup_collation_sequence_value (end_elem, nrules, collseqmb, collseqwc, 2908 table_size, symb_table, extra); 2909 /* Check start/end collation sequence values. */ 2910 if (__glibc_unlikely (start_collseq == UINT_MAX 2911 || end_collseq == UINT_MAX)) 2912 return REG_ECOLLATE; 2913 if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES) 2914 && start_collseq > end_collseq)) 2915 return REG_ERANGE; 2916 2917 /* Got valid collation sequence values, add them as a new entry. 2918 However, if we have no collation elements, and the character set 2919 is single byte, the single byte character set that we 2920 build below suffices. */ 2921 if (nrules > 0 || dfa->mb_cur_max > 1) 2922 { 2923 /* Check the space of the arrays. */ 2924 if (__glibc_unlikely (*range_alloc == mbcset->nranges)) 2925 { 2926 /* There is not enough space, need realloc. */ 2927 uint32_t *new_array_start; 2928 uint32_t *new_array_end; 2929 int new_nranges; 2930 2931 /* +1 in case of mbcset->nranges is 0. */ 2932 new_nranges = 2 * mbcset->nranges + 1; 2933 new_array_start = re_realloc (mbcset->range_starts, uint32_t, 2934 new_nranges); 2935 new_array_end = re_realloc (mbcset->range_ends, uint32_t, 2936 new_nranges); 2937 2938 if (__glibc_unlikely (new_array_start == NULL 2939 || new_array_end == NULL)) 2940 return REG_ESPACE; 2941 2942 mbcset->range_starts = new_array_start; 2943 mbcset->range_ends = new_array_end; 2944 *range_alloc = new_nranges; 2945 } 2946 2947 mbcset->range_starts[mbcset->nranges] = start_collseq; 2948 mbcset->range_ends[mbcset->nranges++] = end_collseq; 2949 } 2950 2951 /* Build the table for single byte characters. */ 2952 for (ch = 0; ch < SBC_MAX; ch++) 2953 { 2954 uint32_t ch_collseq; 2955 /* if (MB_CUR_MAX == 1) */ 2956 if (nrules == 0) 2957 ch_collseq = collseqmb[ch]; 2958 else 2959 ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); 2960 if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) 2961 bitset_set (sbcset, ch); 2962 } 2963 return REG_NOERROR; 2964 } 2965 2966 /* Local function for parse_bracket_exp used in _LIBC environment. 2967 Build the collating element which is represented by NAME. 2968 The result are written to MBCSET and SBCSET. 2969 COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a 2970 pointer argument since we may update it. */ 2971 2972 static __always_inline reg_errcode_t 2973 build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, 2974 Idx *coll_sym_alloc, const unsigned char *name, 2975 uint_fast32_t nrules, int_fast32_t table_size, 2976 const int32_t *symb_table, const unsigned char *extra) 2977 { 2978 int32_t elem, idx; 2979 size_t name_len = strlen ((const char *) name); 2980 if (nrules != 0) 2981 { 2982 elem = seek_collating_symbol_entry (name, name_len, symb_table, 2983 table_size, extra); 2984 if (elem != -1) 2985 { 2986 /* We found the entry. */ 2987 idx = symb_table[2 * elem + 1]; 2988 /* Skip the name of collating element name. */ 2989 idx += 1 + extra[idx]; 2990 } 2991 else if (name_len == 1) 2992 { 2993 /* No valid character, treat it as a normal 2994 character. */ 2995 bitset_set (sbcset, name[0]); 2972 2996 return REG_NOERROR; 2973 2997 } 2974 2998 else 2975 { 2976 if (BE (name_len != 1, 0)) 2977 return REG_ECOLLATE; 2978 else 2979 { 2980 bitset_set (sbcset, name[0]); 2981 return REG_NOERROR; 2982 } 2983 } 2984 } 2985 #endif 2999 return REG_ECOLLATE; 3000 3001 /* Got valid collation sequence, add it as a new entry. */ 3002 /* Check the space of the arrays. */ 3003 if (__glibc_unlikely (*coll_sym_alloc == mbcset->ncoll_syms)) 3004 { 3005 /* Not enough, realloc it. */ 3006 /* +1 in case of mbcset->ncoll_syms is 0. */ 3007 int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; 3008 /* Use realloc since mbcset->coll_syms is NULL 3009 if *alloc == 0. */ 3010 int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, 3011 new_coll_sym_alloc); 3012 if (__glibc_unlikely (new_coll_syms == NULL)) 3013 return REG_ESPACE; 3014 mbcset->coll_syms = new_coll_syms; 3015 *coll_sym_alloc = new_coll_sym_alloc; 3016 } 3017 mbcset->coll_syms[mbcset->ncoll_syms++] = idx; 3018 return REG_NOERROR; 3019 } 3020 else 3021 { 3022 if (__glibc_unlikely (name_len != 1)) 3023 return REG_ECOLLATE; 3024 else 3025 { 3026 bitset_set (sbcset, name[0]); 3027 return REG_NOERROR; 3028 } 3029 } 3030 } 3031 #endif /* _LIBC */ 3032 3033 /* This function parse bracket expression like "[abc]", "[a-c]", 3034 "[[.a-a.]]" etc. */ 3035 3036 static bin_tree_t * 3037 parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, 3038 reg_syntax_t syntax, reg_errcode_t *err) 3039 { 3040 const unsigned char *collseqmb = NULL; 3041 const char *collseqwc = NULL; 3042 uint_fast32_t nrules = 0; 3043 int_fast32_t table_size = 0; 3044 const void *symb_table = NULL; 3045 const unsigned char *extra = NULL; 2986 3046 2987 3047 re_token_t br_token; 2988 3048 re_bitset_ptr_t sbcset; 2989 #ifdef RE_ENABLE_I18N2990 3049 re_charset_t *mbcset; 2991 int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; 2992 int equiv_class_alloc = 0, char_class_alloc = 0; 2993 #endif /* not RE_ENABLE_I18N */ 2994 int non_match = 0; 3050 Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; 3051 Idx equiv_class_alloc = 0, char_class_alloc = 0; 3052 bool non_match = false; 2995 3053 bin_tree_t *work_tree; 2996 3054 int token_len; 2997 int first_round = 1;3055 bool first_round = true; 2998 3056 #ifdef _LIBC 2999 3057 collseqmb = (const unsigned char *) … … 3007 3065 collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); 3008 3066 table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); 3009 symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, 3010 _NL_COLLATE_SYMB_TABLEMB); 3067 symb_table = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_TABLEMB); 3011 3068 extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, 3012 3069 _NL_COLLATE_SYMB_EXTRAMB); … … 3014 3071 #endif 3015 3072 sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); 3016 #ifdef RE_ENABLE_I18N3017 3073 mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); 3018 #endif /* RE_ENABLE_I18N */ 3019 #ifdef RE_ENABLE_I18N 3020 if (BE (sbcset == NULL || mbcset == NULL, 0)) 3021 #else 3022 if (BE (sbcset == NULL, 0)) 3023 #endif /* RE_ENABLE_I18N */ 3024 { 3074 if (__glibc_unlikely (sbcset == NULL || mbcset == NULL)) 3075 { 3076 re_free (sbcset); 3077 re_free (mbcset); 3025 3078 *err = REG_ESPACE; 3026 3079 return NULL; … … 3028 3081 3029 3082 token_len = peek_token_bracket (token, regexp, syntax); 3030 if ( BE (token->type == END_OF_RE, 0))3083 if (__glibc_unlikely (token->type == END_OF_RE)) 3031 3084 { 3032 3085 *err = REG_BADPAT; … … 3035 3088 if (token->type == OP_NON_MATCH_LIST) 3036 3089 { 3037 #ifdef RE_ENABLE_I18N3038 3090 mbcset->non_match = 1; 3039 #endif /* not RE_ENABLE_I18N */ 3040 non_match = 1; 3091 non_match = true; 3041 3092 if (syntax & RE_HAT_LISTS_NOT_NEWLINE) 3042 bitset_set (sbcset, '\ 0');3093 bitset_set (sbcset, '\n'); 3043 3094 re_string_skip_bytes (regexp, token_len); /* Skip a token. */ 3044 3095 token_len = peek_token_bracket (token, regexp, syntax); 3045 if ( BE (token->type == END_OF_RE, 0))3096 if (__glibc_unlikely (token->type == END_OF_RE)) 3046 3097 { 3047 3098 *err = REG_BADPAT; … … 3060 3111 unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE]; 3061 3112 reg_errcode_t ret; 3062 int token_len2 = 0, is_range_exp = 0; 3113 int token_len2 = 0; 3114 bool is_range_exp = false; 3063 3115 re_token_t token2; 3064 3116 3065 3117 start_elem.opr.name = start_name_buf; 3118 start_elem.type = COLL_SYM; 3066 3119 ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa, 3067 3120 syntax, first_round); 3068 if ( BE (ret != REG_NOERROR, 0))3121 if (__glibc_unlikely (ret != REG_NOERROR)) 3069 3122 { 3070 3123 *err = ret; 3071 3124 goto parse_bracket_exp_free_return; 3072 3125 } 3073 first_round = 0;3126 first_round = false; 3074 3127 3075 3128 /* Get information about the next token. We need it in any case. */ … … 3079 3132 if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS) 3080 3133 { 3081 if ( BE (token->type == END_OF_RE, 0))3134 if (__glibc_unlikely (token->type == END_OF_RE)) 3082 3135 { 3083 3136 *err = REG_EBRACK; … … 3088 3141 re_string_skip_bytes (regexp, token_len); /* Skip '-'. */ 3089 3142 token_len2 = peek_token_bracket (&token2, regexp, syntax); 3090 if ( BE (token2.type == END_OF_RE, 0))3143 if (__glibc_unlikely (token2.type == END_OF_RE)) 3091 3144 { 3092 3145 *err = REG_EBRACK; … … 3100 3153 } 3101 3154 else 3102 is_range_exp = 1;3155 is_range_exp = true; 3103 3156 } 3104 3157 } 3105 3158 3106 if (is_range_exp == 1)3159 if (is_range_exp == true) 3107 3160 { 3108 3161 end_elem.opr.name = end_name_buf; 3162 end_elem.type = COLL_SYM; 3109 3163 ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2, 3110 dfa, syntax, 1);3111 if ( BE (ret != REG_NOERROR, 0))3164 dfa, syntax, true); 3165 if (__glibc_unlikely (ret != REG_NOERROR)) 3112 3166 { 3113 3167 *err = ret; … … 3117 3171 token_len = peek_token_bracket (token, regexp, syntax); 3118 3172 3119 #ifdef _LIBC3120 3173 *err = build_range_exp (sbcset, mbcset, &range_alloc, 3121 &start_elem, &end_elem); 3122 #else 3123 # ifdef RE_ENABLE_I18N 3124 *err = build_range_exp (sbcset, 3125 dfa->mb_cur_max > 1 ? mbcset : NULL, 3126 &range_alloc, &start_elem, &end_elem); 3127 # else 3128 *err = build_range_exp (sbcset, &start_elem, &end_elem); 3129 # endif 3130 #endif /* RE_ENABLE_I18N */ 3131 if (BE (*err != REG_NOERROR, 0)) 3174 &start_elem, &end_elem, 3175 dfa, syntax, nrules, collseqmb, collseqwc, 3176 table_size, symb_table, extra); 3177 if (__glibc_unlikely (*err != REG_NOERROR)) 3132 3178 goto parse_bracket_exp_free_return; 3133 3179 } … … 3139 3185 bitset_set (sbcset, start_elem.opr.ch); 3140 3186 break; 3141 #ifdef RE_ENABLE_I18N3142 3187 case MB_CHAR: 3143 3188 /* Check whether the array has enough space. */ 3144 if ( BE (mbchar_alloc == mbcset->nmbchars, 0))3189 if (__glibc_unlikely (mbchar_alloc == mbcset->nmbchars)) 3145 3190 { 3146 3191 wchar_t *new_mbchars; … … 3151 3196 new_mbchars = re_realloc (mbcset->mbchars, wchar_t, 3152 3197 mbchar_alloc); 3153 if ( BE (new_mbchars == NULL, 0))3198 if (__glibc_unlikely (new_mbchars == NULL)) 3154 3199 goto parse_bracket_exp_espace; 3155 3200 mbcset->mbchars = new_mbchars; … … 3157 3202 mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; 3158 3203 break; 3159 #endif /* RE_ENABLE_I18N */3160 3204 case EQUIV_CLASS: 3161 3205 *err = build_equiv_class (sbcset, 3162 #ifdef RE_ENABLE_I18N3163 3206 mbcset, &equiv_class_alloc, 3164 #endif /* RE_ENABLE_I18N */3165 3207 start_elem.opr.name); 3166 if ( BE (*err != REG_NOERROR, 0))3208 if (__glibc_unlikely (*err != REG_NOERROR)) 3167 3209 goto parse_bracket_exp_free_return; 3168 3210 break; 3169 3211 case COLL_SYM: 3170 3212 *err = build_collating_symbol (sbcset, 3171 #ifdef RE_ENABLE_I18N3172 3213 mbcset, &coll_sym_alloc, 3173 #endif /* RE_ENABLE_I18N */ 3174 start_elem.opr.name);3175 if ( BE (*err != REG_NOERROR, 0))3214 start_elem.opr.name, 3215 nrules, table_size, symb_table, extra); 3216 if (__glibc_unlikely (*err != REG_NOERROR)) 3176 3217 goto parse_bracket_exp_free_return; 3177 3218 break; 3178 3219 case CHAR_CLASS: 3179 3220 *err = build_charclass (regexp->trans, sbcset, 3180 #ifdef RE_ENABLE_I18N3181 3221 mbcset, &char_class_alloc, 3182 #endif /* RE_ENABLE_I18N */ 3183 s tart_elem.opr.name, syntax);3184 if ( BE (*err != REG_NOERROR, 0))3222 (const char *) start_elem.opr.name, 3223 syntax); 3224 if (__glibc_unlikely (*err != REG_NOERROR)) 3185 3225 goto parse_bracket_exp_free_return; 3186 3226 break; 3187 3227 default: 3188 assert (0);3228 DEBUG_ASSERT (false); 3189 3229 break; 3190 3230 } 3191 3231 } 3192 if ( BE (token->type == END_OF_RE, 0))3232 if (__glibc_unlikely (token->type == END_OF_RE)) 3193 3233 { 3194 3234 *err = REG_EBRACK; … … 3205 3245 bitset_not (sbcset); 3206 3246 3207 #ifdef RE_ENABLE_I18N3208 3247 /* Ensure only single byte characters are set. */ 3209 3248 if (dfa->mb_cur_max > 1) … … 3221 3260 br_token.opr.mbcset = mbcset; 3222 3261 mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); 3223 if ( BE (mbc_tree == NULL, 0))3262 if (__glibc_unlikely (mbc_tree == NULL)) 3224 3263 goto parse_bracket_exp_espace; 3225 3264 for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx) … … 3230 3269 if (sbc_idx < BITSET_WORDS) 3231 3270 { 3232 3233 3234 3235 3236 if (BE (work_tree == NULL, 0))3237 3238 3239 3240 3241 if (BE (work_tree == NULL, 0))3242 3271 /* Build a tree for simple bracket. */ 3272 br_token.type = SIMPLE_BRACKET; 3273 br_token.opr.sbcset = sbcset; 3274 work_tree = create_token_tree (dfa, NULL, NULL, &br_token); 3275 if (__glibc_unlikely (work_tree == NULL)) 3276 goto parse_bracket_exp_espace; 3277 3278 /* Then join them by ALT node. */ 3279 work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); 3280 if (__glibc_unlikely (work_tree == NULL)) 3281 goto parse_bracket_exp_espace; 3243 3282 } 3244 3283 else … … 3249 3288 } 3250 3289 else 3251 #endif /* not RE_ENABLE_I18N */ 3252 { 3253 #ifdef RE_ENABLE_I18N 3290 { 3254 3291 free_charset (mbcset); 3255 #endif3256 3292 /* Build a tree for simple bracket. */ 3257 3293 br_token.type = SIMPLE_BRACKET; 3258 3294 br_token.opr.sbcset = sbcset; 3259 3295 work_tree = create_token_tree (dfa, NULL, NULL, &br_token); 3260 if ( BE (work_tree == NULL, 0))3261 3296 if (__glibc_unlikely (work_tree == NULL)) 3297 goto parse_bracket_exp_espace; 3262 3298 } 3263 3299 return work_tree; … … 3267 3303 parse_bracket_exp_free_return: 3268 3304 re_free (sbcset); 3269 #ifdef RE_ENABLE_I18N3270 3305 free_charset (mbcset); 3271 #endif /* RE_ENABLE_I18N */3272 3306 return NULL; 3273 3307 } … … 3278 3312 parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp, 3279 3313 re_token_t *token, int token_len, re_dfa_t *dfa, 3280 reg_syntax_t syntax, int accept_hyphen) 3281 { 3282 #ifdef RE_ENABLE_I18N 3314 reg_syntax_t syntax, bool accept_hyphen) 3315 { 3283 3316 int cur_char_size; 3284 3317 cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); … … 3290 3323 return REG_NOERROR; 3291 3324 } 3292 #endif /* RE_ENABLE_I18N */3293 3325 re_string_skip_bytes (regexp, token_len); /* Skip a token. */ 3294 3326 if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS 3295 3327 || token->type == OP_OPEN_EQUIV_CLASS) 3296 3328 return parse_bracket_symbol (elem, regexp, token); 3297 if ( BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen)3329 if (__glibc_unlikely (token->type == OP_CHARSET_RANGE) && !accept_hyphen) 3298 3330 { 3299 3331 /* A '-' must only appear as anything but a range indicator before … … 3360 3392 The result are written to MBCSET and SBCSET. 3361 3393 EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes, 3362 is a pointer argument sin se we may update it. */3394 is a pointer argument since we may update it. */ 3363 3395 3364 3396 static reg_errcode_t 3365 #ifdef RE_ENABLE_I18N3366 3397 build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, 3367 int *equiv_class_alloc, const unsigned char *name) 3368 #else /* not RE_ENABLE_I18N */ 3369 build_equiv_class (bitset_t sbcset, const unsigned char *name) 3370 #endif /* not RE_ENABLE_I18N */ 3398 Idx *equiv_class_alloc, const unsigned char *name) 3371 3399 { 3372 3400 #ifdef _LIBC … … 3380 3408 unsigned int ch; 3381 3409 size_t len; 3382 /* This #include defines a local function! */3383 # include <locale/weight.h>3384 3410 /* Calculate the index for equivalence class. */ 3385 3411 cp = name; … … 3391 3417 indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, 3392 3418 _NL_COLLATE_INDIRECTMB); 3393 idx1 = findidx ( &cp);3394 if ( BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0))3419 idx1 = findidx (table, indirect, extra, &cp, -1); 3420 if (__glibc_unlikely (idx1 == 0 || *cp != '\0')) 3395 3421 /* This isn't a valid character. */ 3396 3422 return REG_ECOLLATE; 3397 3423 3398 /* Build single byte matcing table for this equivalence class. */ 3399 char_buf[1] = (unsigned char) '\0'; 3400 len = weights[idx1]; 3424 /* Build single byte matching table for this equivalence class. */ 3425 len = weights[idx1 & 0xffffff]; 3401 3426 for (ch = 0; ch < SBC_MAX; ++ch) 3402 3427 { 3403 3428 char_buf[0] = ch; 3404 3429 cp = char_buf; 3405 idx2 = findidx ( &cp);3430 idx2 = findidx (table, indirect, extra, &cp, 1); 3406 3431 /* 3407 3432 idx2 = table[ch]; … … 3410 3435 /* This isn't a valid character. */ 3411 3436 continue; 3412 if (len == weights[idx2]) 3413 { 3414 int cnt = 0; 3415 while (cnt <= len && 3416 weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt]) 3417 ++cnt; 3418 3419 if (cnt > len) 3420 bitset_set (sbcset, ch); 3421 } 3437 /* Compare only if the length matches and the collation rule 3438 index is the same. */ 3439 if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24) 3440 && memcmp (weights + (idx1 & 0xffffff) + 1, 3441 weights + (idx2 & 0xffffff) + 1, len) == 0) 3442 bitset_set (sbcset, ch); 3422 3443 } 3423 3444 /* Check whether the array has enough space. */ 3424 if ( BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))3445 if (__glibc_unlikely (*equiv_class_alloc == mbcset->nequiv_classes)) 3425 3446 { 3426 3447 /* Not enough, realloc it. */ 3427 3448 /* +1 in case of mbcset->nequiv_classes is 0. */ 3428 intnew_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;3449 Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1; 3429 3450 /* Use realloc since the array is NULL if *alloc == 0. */ 3430 3451 int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes, 3431 3452 int32_t, 3432 3453 new_equiv_class_alloc); 3433 if ( BE (new_equiv_classes == NULL, 0))3454 if (__glibc_unlikely (new_equiv_classes == NULL)) 3434 3455 return REG_ESPACE; 3435 3456 mbcset->equiv_classes = new_equiv_classes; … … 3441 3462 #endif /* _LIBC */ 3442 3463 { 3443 if ( BE (strlen ((const char *) name) != 1, 0))3464 if (__glibc_unlikely (strlen ((const char *) name) != 1)) 3444 3465 return REG_ECOLLATE; 3445 3466 bitset_set (sbcset, *name); … … 3452 3473 The result are written to MBCSET and SBCSET. 3453 3474 CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes, 3454 is a pointer argument sin se we may update it. */3475 is a pointer argument since we may update it. */ 3455 3476 3456 3477 static reg_errcode_t 3457 #ifdef RE_ENABLE_I18N3458 3478 build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, 3459 re_charset_t *mbcset, int *char_class_alloc, 3460 const unsigned char *class_name, reg_syntax_t syntax) 3461 #else /* not RE_ENABLE_I18N */ 3462 build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, 3463 const unsigned char *class_name, reg_syntax_t syntax) 3464 #endif /* not RE_ENABLE_I18N */ 3479 re_charset_t *mbcset, Idx *char_class_alloc, 3480 const char *class_name, reg_syntax_t syntax) 3465 3481 { 3466 3482 int i; 3467 const char *name = (const char *)class_name;3483 const char *name = class_name; 3468 3484 3469 3485 /* In case of REG_ICASE "upper" and "lower" match the both of … … 3473 3489 name = "alpha"; 3474 3490 3475 #ifdef RE_ENABLE_I18N3476 3491 /* Check the space of the arrays. */ 3477 if ( BE (*char_class_alloc == mbcset->nchar_classes, 0))3492 if (__glibc_unlikely (*char_class_alloc == mbcset->nchar_classes)) 3478 3493 { 3479 3494 /* Not enough, realloc it. */ 3480 3495 /* +1 in case of mbcset->nchar_classes is 0. */ 3481 intnew_char_class_alloc = 2 * mbcset->nchar_classes + 1;3496 Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1; 3482 3497 /* Use realloc since array is NULL if *alloc == 0. */ 3483 3498 wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t, 3484 3499 new_char_class_alloc); 3485 if ( BE (new_char_classes == NULL, 0))3500 if (__glibc_unlikely (new_char_classes == NULL)) 3486 3501 return REG_ESPACE; 3487 3502 mbcset->char_classes = new_char_classes; … … 3489 3504 } 3490 3505 mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name); 3491 #endif /* RE_ENABLE_I18N */3492 3506 3493 3507 #define BUILD_CHARCLASS_LOOP(ctype_func) \ 3494 3508 do { \ 3495 if ( BE (trans != NULL, 0)) \3509 if (__glibc_unlikely (trans != NULL)) \ 3496 3510 { \ 3497 3511 for (i = 0; i < SBC_MAX; ++i) \ 3498 3512 if (ctype_func (i)) \ 3499 3513 bitset_set (sbcset, trans[i]); \ 3500 3514 } \ … … 3502 3516 { \ 3503 3517 for (i = 0; i < SBC_MAX; ++i) \ 3504 3518 if (ctype_func (i)) \ 3505 3519 bitset_set (sbcset, i); \ 3506 3520 } \ … … 3539 3553 static bin_tree_t * 3540 3554 build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, 3541 const unsignedchar *class_name,3542 const unsigned char *extra, intnon_match,3555 const char *class_name, 3556 const char *extra, bool non_match, 3543 3557 reg_errcode_t *err) 3544 3558 { 3545 3559 re_bitset_ptr_t sbcset; 3546 #ifdef RE_ENABLE_I18N3547 3560 re_charset_t *mbcset; 3548 int alloc = 0; 3549 #endif /* not RE_ENABLE_I18N */ 3561 Idx alloc = 0; 3550 3562 reg_errcode_t ret; 3551 re_token_t br_token;3552 3563 bin_tree_t *tree; 3553 3564 3554 3565 sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); 3555 #ifdef RE_ENABLE_I18N 3556 mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); 3557 #endif /* RE_ENABLE_I18N */ 3558 3559 #ifdef RE_ENABLE_I18N 3560 if (BE (sbcset == NULL || mbcset == NULL, 0)) 3561 #else /* not RE_ENABLE_I18N */ 3562 if (BE (sbcset == NULL, 0)) 3563 #endif /* not RE_ENABLE_I18N */ 3566 if (__glibc_unlikely (sbcset == NULL)) 3564 3567 { 3565 3568 *err = REG_ESPACE; 3566 3569 return NULL; 3567 3570 } 3568 3569 if (non_match) 3570 { 3571 #ifdef RE_ENABLE_I18N 3572 /* 3573 if (syntax & RE_HAT_LISTS_NOT_NEWLINE) 3574 bitset_set(cset->sbcset, '\0'); 3575 */ 3576 mbcset->non_match = 1; 3577 #endif /* not RE_ENABLE_I18N */ 3578 } 3571 mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); 3572 if (__glibc_unlikely (mbcset == NULL)) 3573 { 3574 re_free (sbcset); 3575 *err = REG_ESPACE; 3576 return NULL; 3577 } 3578 mbcset->non_match = non_match; 3579 3579 3580 3580 /* We don't care the syntax in this case. */ 3581 ret = build_charclass (trans, sbcset, 3582 #ifdef RE_ENABLE_I18N 3583 mbcset, &alloc, 3584 #endif /* RE_ENABLE_I18N */ 3585 class_name, 0); 3586 3587 if (BE (ret != REG_NOERROR, 0)) 3581 ret = build_charclass (trans, sbcset, mbcset, &alloc, class_name, 0); 3582 3583 if (__glibc_unlikely (ret != REG_NOERROR)) 3588 3584 { 3589 3585 re_free (sbcset); 3590 #ifdef RE_ENABLE_I18N3591 3586 free_charset (mbcset); 3592 #endif /* RE_ENABLE_I18N */3593 3587 *err = ret; 3594 3588 return NULL; … … 3602 3596 bitset_not (sbcset); 3603 3597 3604 #ifdef RE_ENABLE_I18N3605 3598 /* Ensure only single byte characters are set. */ 3606 3599 if (dfa->mb_cur_max > 1) 3607 3600 bitset_mask (sbcset, dfa->sb_char); 3608 #endif3609 3601 3610 3602 /* Build a tree for simple bracket. */ 3611 br_token.type = SIMPLE_BRACKET; 3612 br_token.opr.sbcset = sbcset; 3603 re_token_t br_token = { .type = SIMPLE_BRACKET, .opr.sbcset = sbcset }; 3613 3604 tree = create_token_tree (dfa, NULL, NULL, &br_token); 3614 if ( BE (tree == NULL, 0))3605 if (__glibc_unlikely (tree == NULL)) 3615 3606 goto build_word_op_espace; 3616 3607 3617 #ifdef RE_ENABLE_I18N3618 3608 if (dfa->mb_cur_max > 1) 3619 3609 { … … 3624 3614 dfa->has_mb_node = 1; 3625 3615 mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); 3626 if ( BE (mbc_tree == NULL, 0))3616 if (__glibc_unlikely (mbc_tree == NULL)) 3627 3617 goto build_word_op_espace; 3628 3618 /* Then join them by ALT node. */ 3629 3619 tree = create_tree (dfa, tree, mbc_tree, OP_ALT); 3630 if ( BE (mbc_tree != NULL, 1))3620 if (__glibc_likely (mbc_tree != NULL)) 3631 3621 return tree; 3632 3622 } … … 3636 3626 return tree; 3637 3627 } 3638 #else /* not RE_ENABLE_I18N */3639 return tree;3640 #endif /* not RE_ENABLE_I18N */3641 3628 3642 3629 build_word_op_espace: 3643 3630 re_free (sbcset); 3644 #ifdef RE_ENABLE_I18N3645 3631 free_charset (mbcset); 3646 #endif /* RE_ENABLE_I18N */3647 3632 *err = REG_ESPACE; 3648 3633 return NULL; … … 3650 3635 3651 3636 /* This is intended for the expressions like "a{1,3}". 3652 Fetch a number from `input', and return the number. 3653 Return -1, if the number field is empty like "{,1}". 3654 Return -2, If an error is occured. */ 3655 3656 static int 3637 Fetch a number from 'input', and return the number. 3638 Return -1 if the number field is empty like "{,1}". 3639 Return RE_DUP_MAX + 1 if the number field is too large. 3640 Return -2 if an error occurred. */ 3641 3642 static Idx 3657 3643 fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) 3658 3644 { 3659 intnum = -1;3645 Idx num = -1; 3660 3646 unsigned char c; 3661 3647 while (1) … … 3663 3649 fetch_token (token, input, syntax); 3664 3650 c = token->opr.c; 3665 if ( BE (token->type == END_OF_RE, 0))3651 if (__glibc_unlikely (token->type == END_OF_RE)) 3666 3652 return -2; 3667 3653 if (token->type == OP_CLOSE_DUP_NUM || c == ',') 3668 3654 break; 3669 3655 num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2) 3670 ? -2 : ((num == -1) ? c - '0' : num * 10 + c - '0')); 3671 num = (num > RE_DUP_MAX) ? -2 : num; 3656 ? -2 3657 : num == -1 3658 ? c - '0' 3659 : MIN (RE_DUP_MAX + 1, num * 10 + c - '0')); 3672 3660 } 3673 3661 return num; … … 3675 3663 3676 3664 3677 #ifdef RE_ENABLE_I18N3678 3665 static void 3679 3666 free_charset (re_charset_t *cset) 3680 3667 { 3681 3668 re_free (cset->mbchars); 3682 # 3669 #ifdef _LIBC 3683 3670 re_free (cset->coll_syms); 3684 3671 re_free (cset->equiv_classes); 3672 #endif 3685 3673 re_free (cset->range_starts); 3686 3674 re_free (cset->range_ends); 3687 # endif3688 3675 re_free (cset->char_classes); 3689 3676 re_free (cset); 3690 3677 } 3691 #endif /* RE_ENABLE_I18N */3692 3678 3693 3679 … … 3700 3686 re_token_type_t type) 3701 3687 { 3702 re_token_t t; 3703 t.type = type; 3688 re_token_t t = { .type = type }; 3704 3689 return create_token_tree (dfa, left, right, &t); 3705 3690 } … … 3710 3695 { 3711 3696 bin_tree_t *tree; 3712 if ( BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))3697 if (__glibc_unlikely (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE)) 3713 3698 { 3714 3699 bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1); … … 3745 3730 mark_opt_subexp (void *extra, bin_tree_t *node) 3746 3731 { 3747 int idx = (int) (long) extra;3732 Idx idx = (uintptr_t) extra; 3748 3733 if (node->token.type == SUBEXP && node->token.opr.idx == idx) 3749 3734 node->token.opt_subexp = 1; … … 3757 3742 free_token (re_token_t *node) 3758 3743 { 3759 #ifdef RE_ENABLE_I18N3760 3744 if (node->type == COMPLEX_BRACKET && node->duplicated == 0) 3761 3745 free_charset (node->opr.mbcset); 3762 else 3763 #endif /* RE_ENABLE_I18N */ 3764 if (node->type == SIMPLE_BRACKET && node->duplicated == 0) 3765 re_free (node->opr.sbcset); 3746 else if (node->type == SIMPLE_BRACKET && node->duplicated == 0) 3747 re_free (node->opr.sbcset); 3766 3748 } 3767 3749 … … 3814 3796 dup_node = dup_node->parent; 3815 3797 if (!node) 3816 3798 return dup_root; 3817 3799 } 3818 3800 node = node->right;
Note:
See TracChangeset
for help on using the changeset viewer.