| 3853 | static reg_errcode_t |
| 3854 | free_tree (void *extra, bin_tree_t *node) |
| 3855 | { |
| 3856 | free_token (&node->token); |
| 3857 | return REG_NOERROR; |
| 3858 | } |
| 3859 | |
| 3860 | |
| 3861 | /* Duplicate the node SRC, and return new node. This is a preorder |
| 3862 | visit similar to the one implemented by the generic visitor, but |
| 3863 | we need more infrastructure to maintain two parallel trees --- so, |
| 3864 | it's easier to duplicate. */ |
| 3865 | |
| 3866 | static bin_tree_t * |
| 3867 | duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa) |
| 3868 | { |
| 3869 | const bin_tree_t *node; |
| 3870 | bin_tree_t *dup_root; |
| 3871 | bin_tree_t **p_new = &dup_root, *dup_node = root->parent; |
| 3872 | |
| 3873 | for (node = root; ; ) |
| 3874 | { |
| 3875 | /* Create a new tree and link it back to the current parent. */ |
| 3876 | *p_new = create_token_tree (dfa, NULL, NULL, &node->token); |
| 3877 | if (*p_new == NULL) |
| 3878 | return NULL; |
| 3879 | (*p_new)->parent = dup_node; |
| 3880 | (*p_new)->token.duplicated = 1; |
| 3881 | dup_node = *p_new; |
| 3882 | |
| 3883 | /* Go to the left node, or up and to the right. */ |
| 3884 | if (node->left) |
| 3885 | { |
| 3886 | node = node->left; |
| 3887 | p_new = &dup_node->left; |
| 3888 | } |
| 3889 | else |
| 3890 | { |
| 3891 | const bin_tree_t *prev = NULL; |
| 3892 | while (node->right == prev || node->right == NULL) |
| 3893 | { |
| 3894 | prev = node; |
| 3895 | node = node->parent; |
| 3896 | dup_node = dup_node->parent; |
no test coverage detected