| 1650 | free_return: |
| 1651 | re_node_set_free (&cur_dest); |
| 1652 | return err; |
| 1653 | } |
| 1654 | |
| 1655 | static reg_errcode_t |
| 1656 | internal_function |
| 1657 | build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, |
| 1658 | int str_idx, re_node_set *cur_dest) |
| 1659 | { |
| 1660 | const re_dfa_t *const dfa = mctx->dfa; |
| 1661 | const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes; |
| 1662 | int i; |
| 1663 | |
| 1664 | /* Then build the next sifted state. |
| 1665 | We build the next sifted state on `cur_dest', and update |
| 1666 | `sifted_states[str_idx]' with `cur_dest'. |
| 1667 | Note: |
| 1668 | `cur_dest' is the sifted state from `state_log[str_idx + 1]'. |
| 1669 | `cur_src' points the node_set of the old `state_log[str_idx]' |
| 1670 | (with the epsilon nodes pre-filtered out). */ |
| 1671 | for (i = 0; i < cur_src->nelem; i++) |
| 1672 | { |
| 1673 | int prev_node = cur_src->elems[i]; |
| 1674 | int naccepted = 0; |
| 1675 | int ret; |
| 1676 | |
| 1677 | #ifdef DEBUG |
| 1678 | re_token_type_t type = dfa->nodes[prev_node].type; |
| 1679 | assert (!IS_EPSILON_NODE (type)); |
| 1680 | #endif |
| 1681 | #ifdef RE_ENABLE_I18N |
| 1682 | /* If the node may accept `multi byte'. */ |
| 1683 | if (dfa->nodes[prev_node].accept_mb) |
| 1684 | naccepted = sift_states_iter_mb (mctx, sctx, prev_node, |
| 1685 | str_idx, sctx->last_str_idx); |
| 1686 | #endif /* RE_ENABLE_I18N */ |
| 1687 | |
| 1688 | /* We don't check backreferences here. |
| 1689 | See update_cur_sifted_state(). */ |
| 1690 | if (!naccepted |
| 1691 | && check_node_accept (mctx, dfa->nodes + prev_node, str_idx) |
| 1692 | && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1], |
| 1693 | dfa->nexts[prev_node])) |
| 1694 | naccepted = 1; |
| 1695 | |
| 1696 | if (naccepted == 0) |
| 1697 | continue; |
| 1698 | |
| 1699 | if (sctx->limits.nelem) |
| 1700 | { |
| 1701 | int to_idx = str_idx + naccepted; |
| 1702 | if (check_dst_limits (mctx, &sctx->limits, |
| 1703 | dfa->nexts[prev_node], to_idx, |
| 1704 | prev_node, str_idx)) |
| 1705 | continue; |
| 1706 | } |
| 1707 | ret = re_node_set_insert (cur_dest, prev_node); |
| 1708 | if (BE (ret == -1, 0)) |
| 1709 | return REG_ESPACE; |
no test coverage detected