* xmlXPathNodeSetMergeAndClear: * @set1: the first NodeSet or NULL * @set2: the second NodeSet * * Merges two nodesets, all nodes from @set2 are added to @set1. * Checks for duplicate nodes. Clears set2. * * Returns @set1 once extended or NULL in case of error. * * Frees @set1 in case of error. */
| 3112 | * Frees @set1 in case of error. |
| 3113 | */ |
| 3114 | static xmlNodeSetPtr |
| 3115 | xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2) |
| 3116 | { |
| 3117 | { |
| 3118 | int i, j, initNbSet1; |
| 3119 | xmlNodePtr n1, n2; |
| 3120 | |
| 3121 | initNbSet1 = set1->nodeNr; |
| 3122 | for (i = 0;i < set2->nodeNr;i++) { |
| 3123 | n2 = set2->nodeTab[i]; |
| 3124 | /* |
| 3125 | * Skip duplicates. |
| 3126 | */ |
| 3127 | for (j = 0; j < initNbSet1; j++) { |
| 3128 | n1 = set1->nodeTab[j]; |
| 3129 | if (n1 == n2) { |
| 3130 | goto skip_node; |
| 3131 | } else if ((n1->type == XML_NAMESPACE_DECL) && |
| 3132 | (n2->type == XML_NAMESPACE_DECL)) |
| 3133 | { |
| 3134 | if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) && |
| 3135 | (xmlStrEqual(((xmlNsPtr) n1)->prefix, |
| 3136 | ((xmlNsPtr) n2)->prefix))) |
| 3137 | { |
| 3138 | /* |
| 3139 | * Free the namespace node. |
| 3140 | */ |
| 3141 | xmlXPathNodeSetFreeNs((xmlNsPtr) n2); |
| 3142 | goto skip_node; |
| 3143 | } |
| 3144 | } |
| 3145 | } |
| 3146 | /* |
| 3147 | * grow the nodeTab if needed |
| 3148 | */ |
| 3149 | if (set1->nodeMax == 0) { |
| 3150 | set1->nodeTab = (xmlNodePtr *) xmlMalloc( |
| 3151 | XML_NODESET_DEFAULT * sizeof(xmlNodePtr)); |
| 3152 | if (set1->nodeTab == NULL) |
| 3153 | goto error; |
| 3154 | memset(set1->nodeTab, 0, |
| 3155 | XML_NODESET_DEFAULT * sizeof(xmlNodePtr)); |
| 3156 | set1->nodeMax = XML_NODESET_DEFAULT; |
| 3157 | } else if (set1->nodeNr >= set1->nodeMax) { |
| 3158 | xmlNodePtr *temp; |
| 3159 | |
| 3160 | if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) |
| 3161 | goto error; |
| 3162 | temp = (xmlNodePtr *) xmlRealloc( |
| 3163 | set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr)); |
| 3164 | if (temp == NULL) |
| 3165 | goto error; |
| 3166 | set1->nodeTab = temp; |
| 3167 | set1->nodeMax *= 2; |
| 3168 | } |
| 3169 | set1->nodeTab[set1->nodeNr++] = n2; |
| 3170 | skip_node: |
| 3171 | set2->nodeTab[i] = NULL; |
nothing calls this directly
no test coverage detected