MCPcopy Create free account
hub / github.com/git/git / duplicate_node_closure

Function duplicate_node_closure

compat/regex/regcomp.c:1482–1584  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1480 }
1481
1482 return err;
1483}
1484
1485/* Duplicate the epsilon closure of the node ROOT_NODE.
1486 Note that duplicated nodes have constraint INIT_CONSTRAINT in addition
1487 to their own constraint. */
1488
1489static reg_errcode_t
1490internal_function
1491duplicate_node_closure (re_dfa_t *dfa, int top_org_node, int top_clone_node,
1492 int root_node, unsigned int init_constraint)
1493{
1494 int org_node, clone_node, ret;
1495 unsigned int constraint = init_constraint;
1496 for (org_node = top_org_node, clone_node = top_clone_node;;)
1497 {
1498 int org_dest, clone_dest;
1499 if (dfa->nodes[org_node].type == OP_BACK_REF)
1500 {
1501 /* If the back reference epsilon-transit, its destination must
1502 also have the constraint. Then duplicate the epsilon closure
1503 of the destination of the back reference, and store it in
1504 edests of the back reference. */
1505 org_dest = dfa->nexts[org_node];
1506 re_node_set_empty (dfa->edests + clone_node);
1507 clone_dest = duplicate_node (dfa, org_dest, constraint);
1508 if (BE (clone_dest == -1, 0))
1509 return REG_ESPACE;
1510 dfa->nexts[clone_node] = dfa->nexts[org_node];
1511 ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);
1512 if (BE (ret < 0, 0))
1513 return REG_ESPACE;
1514 }
1515 else if (dfa->edests[org_node].nelem == 0)
1516 {
1517 /* In case of the node can't epsilon-transit, don't duplicate the
1518 destination and store the original destination as the
1519 destination of the node. */
1520 dfa->nexts[clone_node] = dfa->nexts[org_node];
1521 break;
1522 }
1523 else if (dfa->edests[org_node].nelem == 1)
1524 {
1525 /* In case of the node can epsilon-transit, and it has only one
1526 destination. */
1527 org_dest = dfa->edests[org_node].elems[0];
1528 re_node_set_empty (dfa->edests + clone_node);
1529 /* If the node is root_node itself, it means the epsilon clsoure
1530 has a loop. Then tie it to the destination of the root_node. */
1531 if (org_node == root_node && clone_node != org_node)
1532 {
1533 ret = re_node_set_insert (dfa->edests + clone_node, org_dest);
1534 if (BE (ret < 0, 0))
1535 return REG_ESPACE;
1536 break;
1537 }
1538 /* In case of the node has another constraint, add it. */
1539 constraint |= dfa->nodes[org_node].constraint;

Callers 1

calc_eclosure_iterFunction · 0.85

Calls 3

duplicate_nodeFunction · 0.85
re_node_set_insertFunction · 0.85
search_duplicated_nodeFunction · 0.85

Tested by

no test coverage detected