summaryrefslogtreecommitdiffstats
path: root/gl/regcomp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/regcomp.c')
-rw-r--r--gl/regcomp.c131
1 files changed, 75 insertions, 56 deletions
diff --git a/gl/regcomp.c b/gl/regcomp.c
index 8827e03c..b114b4d1 100644
--- a/gl/regcomp.c
+++ b/gl/regcomp.c
@@ -1,5 +1,6 @@
1/* Extended regular expression matching and search library. 1/* Extended regular expression matching and search library.
2 Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc. 2 Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009
3 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 4 This file is part of the GNU C Library.
4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. 5 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
5 6
@@ -333,8 +334,8 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
333 && dfa->nodes[node].mb_partial) 334 && dfa->nodes[node].mb_partial)
334 *p++ = dfa->nodes[node].opr.c; 335 *p++ = dfa->nodes[node].opr.c;
335 memset (&state, '\0', sizeof (state)); 336 memset (&state, '\0', sizeof (state));
336 if (mbrtowc (&wc, (const char *) buf, p - buf, 337 if (__mbrtowc (&wc, (const char *) buf, p - buf,
337 &state) == p - buf 338 &state) == p - buf
338 && (__wcrtomb ((char *) buf, towlower (wc), &state) 339 && (__wcrtomb ((char *) buf, towlower (wc), &state)
339 != (size_t) -1)) 340 != (size_t) -1))
340 re_set_fastmap (fastmap, false, buf[0]); 341 re_set_fastmap (fastmap, false, buf[0]);
@@ -356,45 +357,65 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
356#ifdef RE_ENABLE_I18N 357#ifdef RE_ENABLE_I18N
357 else if (type == COMPLEX_BRACKET) 358 else if (type == COMPLEX_BRACKET)
358 { 359 {
359 Idx i;
360 re_charset_t *cset = dfa->nodes[node].opr.mbcset; 360 re_charset_t *cset = dfa->nodes[node].opr.mbcset;
361 if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes 361 Idx i;
362 || cset->nranges || cset->nchar_classes) 362
363 {
364# ifdef _LIBC 363# ifdef _LIBC
365 if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0) 364 /* See if we have to try all bytes which start multiple collation
365 elements.
366 e.g. In da_DK, we want to catch 'a' since "aa" is a valid
367 collation element, and don't catch 'b' since 'b' is
368 the only collation element which starts from 'b' (and
369 it is caught by SIMPLE_BRACKET). */
370 if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0
371 && (cset->ncoll_syms || cset->nranges))
366 { 372 {
367 /* In this case we want to catch the bytes which are
368 the first byte of any collation elements.
369 e.g. In da_DK, we want to catch 'a' since "aa"
370 is a valid collation element, and don't catch
371 'b' since 'b' is the only collation element
372 which starts from 'b'. */
373 const int32_t *table = (const int32_t *) 373 const int32_t *table = (const int32_t *)
374 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); 374 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
375 for (i = 0; i < SBC_MAX; ++i) 375 for (i = 0; i < SBC_MAX; ++i)
376 if (table[i] < 0) 376 if (table[i] < 0)
377 re_set_fastmap (fastmap, icase, i); 377 re_set_fastmap (fastmap, icase, i);
378 } 378 }
379# else 379# endif /* _LIBC */
380 if (dfa->mb_cur_max > 1) 380
381 for (i = 0; i < SBC_MAX; ++i) 381 /* See if we have to start the match at all multibyte characters,
382 if (__btowc (i) == WEOF) 382 i.e. where we would not find an invalid sequence. This only
383 re_set_fastmap (fastmap, icase, i); 383 applies to multibyte character sets; for single byte character
384# endif /* not _LIBC */ 384 sets, the SIMPLE_BRACKET again suffices. */
385 if (dfa->mb_cur_max > 1
386 && (cset->nchar_classes || cset->non_match
387# ifdef _LIBC
388 || cset->nequiv_classes
389# endif /* _LIBC */
390 ))
391 {
392 unsigned char c = 0;
393 do
394 {
395 mbstate_t mbs;
396 memset (&mbs, 0, sizeof (mbs));
397 if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2)
398 re_set_fastmap (fastmap, false, (int) c);
399 }
400 while (++c != 0);
385 } 401 }
386 for (i = 0; i < cset->nmbchars; ++i) 402
403 else
387 { 404 {
388 char buf[256]; 405 /* ... Else catch all bytes which can start the mbchars. */
389 mbstate_t state; 406 for (i = 0; i < cset->nmbchars; ++i)
390 memset (&state, '\0', sizeof (state));
391 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
392 re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
393 if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
394 { 407 {
395 if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state) 408 char buf[256];
396 != (size_t) -1) 409 mbstate_t state;
397 re_set_fastmap (fastmap, false, *(unsigned char *) buf); 410 memset (&state, '\0', sizeof (state));
411 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
412 re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
413 if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
414 {
415 if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
416 != (size_t) -1)
417 re_set_fastmap (fastmap, false, *(unsigned char *) buf);
418 }
398 } 419 }
399 } 420 }
400 } 421 }
@@ -776,7 +797,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
776 __libc_lock_init (dfa->lock); 797 __libc_lock_init (dfa->lock);
777 798
778 err = re_string_construct (&regexp, pattern, length, preg->translate, 799 err = re_string_construct (&regexp, pattern, length, preg->translate,
779 syntax & RE_ICASE, dfa); 800 (syntax & RE_ICASE) != 0, dfa);
780 if (BE (err != REG_NOERROR, 0)) 801 if (BE (err != REG_NOERROR, 0))
781 { 802 {
782 re_compile_internal_free_return: 803 re_compile_internal_free_return:
@@ -1057,7 +1078,9 @@ optimize_utf8 (re_dfa_t *dfa)
1057 case BUF_LAST: 1078 case BUF_LAST:
1058 break; 1079 break;
1059 default: 1080 default:
1060 /* Word anchors etc. cannot be handled. */ 1081 /* Word anchors etc. cannot be handled. It's okay to test
1082 opr.ctx_type since constraints (for all DFA nodes) are
1083 created by ORing one or more opr.ctx_type values. */
1061 return; 1084 return;
1062 } 1085 }
1063 break; 1086 break;
@@ -1344,6 +1367,8 @@ calc_first (void *extra, bin_tree_t *node)
1344 node->node_idx = re_dfa_add_node (dfa, node->token); 1367 node->node_idx = re_dfa_add_node (dfa, node->token);
1345 if (BE (node->node_idx == REG_MISSING, 0)) 1368 if (BE (node->node_idx == REG_MISSING, 0))
1346 return REG_ESPACE; 1369 return REG_ESPACE;
1370 if (node->token.type == ANCHOR)
1371 dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
1347 } 1372 }
1348 return REG_NOERROR; 1373 return REG_NOERROR;
1349} 1374}
@@ -1473,21 +1498,18 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
1473 destination. */ 1498 destination. */
1474 org_dest = dfa->edests[org_node].elems[0]; 1499 org_dest = dfa->edests[org_node].elems[0];
1475 re_node_set_empty (dfa->edests + clone_node); 1500 re_node_set_empty (dfa->edests + clone_node);
1476 if (dfa->nodes[org_node].type == ANCHOR) 1501 clone_dest = search_duplicated_node (dfa, org_dest, constraint);
1502 /* If the node is root_node itself, it means the epsilon closure
1503 has a loop. Then tie it to the destination of the root_node. */
1504 if (org_node == root_node && clone_node != org_node)
1477 { 1505 {
1478 /* In case of the node has another constraint, append it. */ 1506 ok = re_node_set_insert (dfa->edests + clone_node, org_dest);
1479 if (org_node == root_node && clone_node != org_node) 1507 if (BE (! ok, 0))
1480 { 1508 return REG_ESPACE;
1481 /* ...but if the node is root_node itself, it means the 1509 break;
1482 epsilon closure have a loop, then tie it to the
1483 destination of the root_node. */
1484 ok = re_node_set_insert (dfa->edests + clone_node, org_dest);
1485 if (BE (! ok, 0))
1486 return REG_ESPACE;
1487 break;
1488 }
1489 constraint |= dfa->nodes[org_node].opr.ctx_type;
1490 } 1510 }
1511 /* In case the node has another constraint, append it. */
1512 constraint |= dfa->nodes[org_node].constraint;
1491 clone_dest = duplicate_node (dfa, org_dest, constraint); 1513 clone_dest = duplicate_node (dfa, org_dest, constraint);
1492 if (BE (clone_dest == REG_MISSING, 0)) 1514 if (BE (clone_dest == REG_MISSING, 0))
1493 return REG_ESPACE; 1515 return REG_ESPACE;
@@ -1505,7 +1527,7 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
1505 clone_dest = search_duplicated_node (dfa, org_dest, constraint); 1527 clone_dest = search_duplicated_node (dfa, org_dest, constraint);
1506 if (clone_dest == REG_MISSING) 1528 if (clone_dest == REG_MISSING)
1507 { 1529 {
1508 /* There are no such a duplicated node, create a new one. */ 1530 /* There is no such duplicated node, create a new one. */
1509 reg_errcode_t err; 1531 reg_errcode_t err;
1510 clone_dest = duplicate_node (dfa, org_dest, constraint); 1532 clone_dest = duplicate_node (dfa, org_dest, constraint);
1511 if (BE (clone_dest == REG_MISSING, 0)) 1533 if (BE (clone_dest == REG_MISSING, 0))
@@ -1520,7 +1542,7 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
1520 } 1542 }
1521 else 1543 else
1522 { 1544 {
1523 /* There are a duplicated node which satisfy the constraint, 1545 /* There is a duplicated node which satisfy the constraint,
1524 use it to avoid infinite loop. */ 1546 use it to avoid infinite loop. */
1525 ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); 1547 ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
1526 if (BE (! ok, 0)) 1548 if (BE (! ok, 0))
@@ -1569,8 +1591,7 @@ duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint)
1569 if (BE (dup_idx != REG_MISSING, 1)) 1591 if (BE (dup_idx != REG_MISSING, 1))
1570 { 1592 {
1571 dfa->nodes[dup_idx].constraint = constraint; 1593 dfa->nodes[dup_idx].constraint = constraint;
1572 if (dfa->nodes[org_idx].type == ANCHOR) 1594 dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;
1573 dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].opr.ctx_type;
1574 dfa->nodes[dup_idx].duplicated = 1; 1595 dfa->nodes[dup_idx].duplicated = 1;
1575 1596
1576 /* Store the index of the original node. */ 1597 /* Store the index of the original node. */
@@ -1652,7 +1673,6 @@ static reg_errcode_t
1652calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) 1673calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
1653{ 1674{
1654 reg_errcode_t err; 1675 reg_errcode_t err;
1655 unsigned int constraint;
1656 Idx i; 1676 Idx i;
1657 bool incomplete; 1677 bool incomplete;
1658 bool ok; 1678 bool ok;
@@ -1666,15 +1686,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
1666 We reference this value to avoid infinite loop. */ 1686 We reference this value to avoid infinite loop. */
1667 dfa->eclosures[node].nelem = REG_MISSING; 1687 dfa->eclosures[node].nelem = REG_MISSING;
1668 1688
1669 constraint = ((dfa->nodes[node].type == ANCHOR) 1689 /* If the current node has constraints, duplicate all nodes
1670 ? dfa->nodes[node].opr.ctx_type : 0); 1690 since they must inherit the constraints. */
1671 /* If the current node has constraints, duplicate all nodes. 1691 if (dfa->nodes[node].constraint
1672 Since they must inherit the constraints. */
1673 if (constraint
1674 && dfa->edests[node].nelem 1692 && dfa->edests[node].nelem
1675 && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) 1693 && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
1676 { 1694 {
1677 err = duplicate_node_closure (dfa, node, node, node, constraint); 1695 err = duplicate_node_closure (dfa, node, node, node,
1696 dfa->nodes[node].constraint);
1678 if (BE (err != REG_NOERROR, 0)) 1697 if (BE (err != REG_NOERROR, 0))
1679 return err; 1698 return err;
1680 } 1699 }