* xmlXPathNodeSetMerge: * @val1: the first NodeSet or NULL * @val2: the second NodeSet * * Merges two nodesets, all nodes from @val2 are added to @val1 * if @val1 is NULL, a new set is created and copied from @val2 * * Returns @val1 once extended or NULL in case of error. * * Frees @val1 in case of error. */
| 3017 | * Frees @val1 in case of error. |
| 3018 | */ |
| 3019 | xmlNodeSetPtr |
| 3020 | xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) { |
| 3021 | int i, j, initNr, skip; |
| 3022 | xmlNodePtr n1, n2; |
| 3023 | |
| 3024 | if (val1 == NULL) { |
| 3025 | val1 = xmlXPathNodeSetCreate(NULL); |
| 3026 | if (val1 == NULL) |
| 3027 | return (NULL); |
| 3028 | } |
| 3029 | if (val2 == NULL) |
| 3030 | return(val1); |
| 3031 | |
| 3032 | /* @@ with_ns to check whether namespace nodes should be looked at @@ */ |
| 3033 | initNr = val1->nodeNr; |
| 3034 | |
| 3035 | for (i = 0;i < val2->nodeNr;i++) { |
| 3036 | n2 = val2->nodeTab[i]; |
| 3037 | /* |
| 3038 | * check against duplicates |
| 3039 | */ |
| 3040 | skip = 0; |
| 3041 | for (j = 0; j < initNr; j++) { |
| 3042 | n1 = val1->nodeTab[j]; |
| 3043 | if (n1 == n2) { |
| 3044 | skip = 1; |
| 3045 | break; |
| 3046 | } else if ((n1->type == XML_NAMESPACE_DECL) && |
| 3047 | (n2->type == XML_NAMESPACE_DECL)) { |
| 3048 | if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) && |
| 3049 | (xmlStrEqual(((xmlNsPtr) n1)->prefix, |
| 3050 | ((xmlNsPtr) n2)->prefix))) |
| 3051 | { |
| 3052 | skip = 1; |
| 3053 | break; |
| 3054 | } |
| 3055 | } |
| 3056 | } |
| 3057 | if (skip) |
| 3058 | continue; |
| 3059 | |
| 3060 | /* |
| 3061 | * grow the nodeTab if needed |
| 3062 | */ |
| 3063 | if (val1->nodeMax == 0) { |
| 3064 | val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * |
| 3065 | sizeof(xmlNodePtr)); |
| 3066 | if (val1->nodeTab == NULL) |
| 3067 | goto error; |
| 3068 | memset(val1->nodeTab, 0 , |
| 3069 | XML_NODESET_DEFAULT * sizeof(xmlNodePtr)); |
| 3070 | val1->nodeMax = XML_NODESET_DEFAULT; |
| 3071 | } else if (val1->nodeNr == val1->nodeMax) { |
| 3072 | xmlNodePtr *temp; |
| 3073 | |
| 3074 | if (val1->nodeMax >= XPATH_MAX_NODESET_LENGTH) |
| 3075 | goto error; |
| 3076 | temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 * |
no test coverage detected