// FIXME: This code is taken from libexslt 1.1.11; should sync with newer // versions. static void exsltNodeSetFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlChar* strval; xmlNodePtr retNode; xmlXPathObjectPtr ret; if (nargs != 1) { xmlXPathSetArityError(ctxt); return; } if (xmlXPathStackIsNodeSet(ctxt)) { xsltFunctionNodeSet(ctxt, nargs); return; } strval = xmlXPathPopString(ctxt); retNode = xmlNewDocText(0, strval); ret = xmlXPathNewValueTree(retNode); // FIXME: It might be helpful to push any errors from xmlXPathNewValueTree // up to the Javascript Console. if (ret) ret->type = XPATH_NODESET; if (strval) xmlFree(strval); valuePush(ctxt, ret); }
// FIXME: This code is taken from libexslt 1.1.11; should sync with newer versions. static void exsltNodeSetFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlChar *strval; xmlNodePtr retNode; xmlXPathObjectPtr ret; if (nargs != 1) { xmlXPathSetArityError(ctxt); return; } if (xmlXPathStackIsNodeSet(ctxt)) { xsltFunctionNodeSet(ctxt, nargs); return; } strval = xmlXPathPopString(ctxt); retNode = xmlNewDocText(NULL, strval); ret = xmlXPathNewValueTree(retNode); if (ret == NULL) { xsltGenericError(xsltGenericErrorContext, "exsltNodeSetFunction: ret == NULL\n"); } else { ret->type = XPATH_NODESET; } if (strval != NULL) xmlFree(strval); valuePush(ctxt, ret); }
static void exsltNodeSetFunction (xmlXPathParserContextPtr ctxt, int nargs) { if (nargs != 1) { xmlXPathSetArityError(ctxt); return; } if (xmlXPathStackIsNodeSet (ctxt)) { xsltFunctionNodeSet (ctxt, nargs); return; } else { xmlDocPtr fragment; xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); xmlNodePtr txt; xmlChar *strval; xmlXPathObjectPtr obj; /* * SPEC EXSLT: * "You can also use this function to turn a string into a text * node, which is helpful if you want to pass a string to a * function that only accepts a node-set." */ fragment = xsltCreateRVT(tctxt); if (fragment == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "exsltNodeSetFunction: Failed to create a tree fragment.\n"); tctxt->state = XSLT_STATE_STOPPED; return; } xsltRegisterLocalRVT(tctxt, fragment); strval = xmlXPathPopString (ctxt); txt = xmlNewDocText (fragment, strval); xmlAddChild((xmlNodePtr) fragment, txt); obj = xmlXPathNewNodeSet(txt); if (obj == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "exsltNodeSetFunction: Failed to create a node set object.\n"); tctxt->state = XSLT_STATE_STOPPED; } else { /* * Mark it as a function result in order to avoid garbage * collecting of tree fragments */ xsltExtensionInstructionResultRegister(tctxt, obj); } if (strval != NULL) xmlFree (strval); valuePush (ctxt, obj); } }
/** * exsltStrConcatFunction: * @ctxt: an XPath parser context * @nargs: the number of arguments * * Takes a node set and returns the concatenation of the string values * of the nodes in that node set. If the node set is empty, it * returns an empty string. */ static void exsltStrConcatFunction (xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr obj; xmlChar *ret = NULL; int i; if (nargs != 1) { xmlXPathSetArityError(ctxt); return; } if (!xmlXPathStackIsNodeSet(ctxt)) { xmlXPathSetTypeError(ctxt); return; } obj = valuePop (ctxt); if (xmlXPathNodeSetIsEmpty(obj->nodesetval)) { xmlXPathReturnEmptyString(ctxt); return; } for (i = 0; i < obj->nodesetval->nodeNr; i++) { xmlChar *tmp; tmp = xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]); ret = xmlStrcat (ret, tmp); xmlFree(tmp); } xmlXPathFreeObject (obj); xmlXPathReturnString(ctxt, ret); }
static void xsltp_extension_string_join(xmlXPathParserContextPtr ctxt, int nargs) { xmlChar *ret = NULL, *sep = NULL, *str = NULL; xmlNodeSetPtr nodeSet = NULL; int i, j; if (nargs < 2) { xmlXPathSetArityError(ctxt); return; } if (xmlXPathStackIsNodeSet(ctxt)) { xmlXPathSetTypeError(ctxt); return; } sep = xmlXPathPopString(ctxt); for (i = 1; i < nargs; i++) { if (!xmlXPathStackIsNodeSet(ctxt)) { str = xmlXPathPopString(ctxt); if (i == 1) { ret = str; } else { str = xmlStrcat(str, sep); str = xmlStrcat(str, ret); xmlFree(ret); ret = str; } } else { nodeSet = xmlXPathPopNodeSet(ctxt); if (xmlXPathCheckError(ctxt)) { xmlXPathSetTypeError(ctxt); goto fail; } for (j = nodeSet->nodeNr - 1; j >= 0; j--) { str = xmlXPathCastNodeToString(nodeSet->nodeTab[j]); if (i == 1 && j == (nodeSet->nodeNr - 1)) { ret = str; } else { str = xmlStrcat(str, sep); str = xmlStrcat(str, ret); xmlFree(ret); ret = str; } } xmlXPathFreeNodeSet(nodeSet); } } xmlXPathReturnString(ctxt, ret); fail: if (sep != NULL) xmlFree(sep); }
/** * exsltStrReplaceFunction: * @ctxt: an XPath parser context * @nargs: the number of arguments * * Takes a string, and two node sets and returns the string with all strings in * the first node set replaced by all strings in the second node set. */ static void exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) { int i, i_empty, n, slen0, rlen0, *slen, *rlen; void *mem = NULL; const xmlChar *src, *start; xmlChar *string, *search_str = NULL, *replace_str = NULL; xmlChar **search, **replace; xmlNodeSetPtr search_set = NULL, replace_set = NULL; xmlBufferPtr buf; if (nargs != 3) { xmlXPathSetArityError(ctxt); return; } /* get replace argument */ if (!xmlXPathStackIsNodeSet(ctxt)) replace_str = xmlXPathPopString(ctxt); else replace_set = xmlXPathPopNodeSet(ctxt); if (xmlXPathCheckError(ctxt)) goto fail_replace; /* get search argument */ if (!xmlXPathStackIsNodeSet(ctxt)) { search_str = xmlXPathPopString(ctxt); n = 1; } else { search_set = xmlXPathPopNodeSet(ctxt); n = search_set != NULL ? search_set->nodeNr : 0; } if (xmlXPathCheckError(ctxt)) goto fail_search; /* get string argument */ string = xmlXPathPopString(ctxt); if (xmlXPathCheckError(ctxt)) goto fail_string; /* check for empty search node list */ if (n <= 0) { exsltStrReturnString(ctxt, string, xmlStrlen(string)); goto done_empty_search; } /* allocate memory for string pointer and length arrays */ if (n == 1) { search = &search_str; replace = &replace_str; slen = &slen0; rlen = &rlen0; } else { mem = xmlMalloc(2 * n * (sizeof(const xmlChar *) + sizeof(int))); if (mem == NULL) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_malloc; } search = (xmlChar **) mem; replace = search + n; slen = (int *) (replace + n); rlen = slen + n; } /* process arguments */ i_empty = -1; for (i=0; i<n; ++i) { if (search_set != NULL) { search[i] = xmlXPathCastNodeToString(search_set->nodeTab[i]); if (search[i] == NULL) { n = i; goto fail_process_args; } } slen[i] = xmlStrlen(search[i]); if (i_empty < 0 && slen[i] == 0) i_empty = i; if (replace_set != NULL) { if (i < replace_set->nodeNr) { replace[i] = xmlXPathCastNodeToString(replace_set->nodeTab[i]); if (replace[i] == NULL) { n = i + 1; goto fail_process_args; } } else replace[i] = NULL; } else { if (i == 0) replace[i] = replace_str; else replace[i] = NULL; } if (replace[i] == NULL) rlen[i] = 0; else rlen[i] = xmlStrlen(replace[i]); } if (i_empty >= 0 && rlen[i_empty] == 0) i_empty = -1; /* replace operation */ buf = xmlBufferCreate(); if (buf == NULL) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_buffer; } src = string; start = string; while (*src != 0) { int max_len = 0, i_match = 0; for (i=0; i<n; ++i) { if (*src == search[i][0] && slen[i] > max_len && xmlStrncmp(src, search[i], slen[i]) == 0) { i_match = i; max_len = slen[i]; } } if (max_len == 0) { if (i_empty >= 0 && start < src) { if (xmlBufferAdd(buf, start, src - start) || xmlBufferAdd(buf, replace[i_empty], rlen[i_empty])) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_buffer_add; } start = src; } src += xmlUTF8Size(src); } else { if ((start < src && xmlBufferAdd(buf, start, src - start)) || (rlen[i_match] && xmlBufferAdd(buf, replace[i_match], rlen[i_match]))) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_buffer_add; } src += slen[i_match]; start = src; } } if (start < src && xmlBufferAdd(buf, start, src - start)) { xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); goto fail_buffer_add; } /* create result node set */ exsltStrReturnString(ctxt, xmlBufferContent(buf), xmlBufferLength(buf)); /* clean up */ fail_buffer_add: xmlBufferFree(buf); fail_buffer: fail_process_args: if (search_set != NULL) { for (i=0; i<n; ++i) xmlFree(search[i]); } if (replace_set != NULL) { for (i=0; i<n; ++i) { if (replace[i] != NULL) xmlFree(replace[i]); } } if (mem != NULL) xmlFree(mem); fail_malloc: done_empty_search: xmlFree(string); fail_string: if (search_set != NULL) xmlXPathFreeNodeSet(search_set); else xmlFree(search_str); fail_search: if (replace_set != NULL) xmlXPathFreeNodeSet(replace_set); else xmlFree(replace_str); fail_replace: return; }
/** * exsltStrReplaceFunction: * @ctxt: an XPath parser context * @nargs: the number of arguments * * Takes a string, and two node sets and returns the string with all strings in * the first node set replaced by all strings in the second node set. */ static void exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) { xmlChar *str = NULL, *searchStr = NULL, *replaceStr = NULL; xmlNodeSetPtr replaceSet = NULL, searchSet = NULL; xmlChar *ret = NULL, *retSwap = NULL; int i; if (nargs != 3) { xmlXPathSetArityError(ctxt); return; } /* pull out replace argument */ if (!xmlXPathStackIsNodeSet(ctxt)) { replaceStr = xmlXPathPopString(ctxt); } else { replaceSet = xmlXPathPopNodeSet(ctxt); if (xmlXPathCheckError(ctxt)) { xmlXPathSetTypeError(ctxt); goto fail; } } /* behavior driven by search argument from here on */ if (!xmlXPathStackIsNodeSet(ctxt)) { searchStr = xmlXPathPopString(ctxt); str = xmlXPathPopString(ctxt); if (replaceStr == NULL) { xmlXPathSetTypeError(ctxt); goto fail; } ret = exsltStrReplaceInternal(str, searchStr, replaceStr); } else { searchSet = xmlXPathPopNodeSet(ctxt); if (searchSet == NULL || xmlXPathCheckError(ctxt)) { xmlXPathSetTypeError(ctxt); goto fail; } str = xmlXPathPopString(ctxt); ret = xmlStrdup(str); for (i = 0; i < searchSet->nodeNr; i++) { searchStr = xmlXPathCastNodeToString(searchSet->nodeTab[i]); if (replaceSet != NULL) { replaceStr = NULL; if (i < replaceSet->nodeNr) { replaceStr = xmlXPathCastNodeToString(replaceSet->nodeTab[i]); } retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); if (replaceStr != NULL) { xmlFree(replaceStr); replaceStr = NULL; } } else { retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); } xmlFree(ret); if (searchStr != NULL) { xmlFree(searchStr); searchStr = NULL; } ret = retSwap; } if (replaceSet != NULL) xmlXPathFreeNodeSet(replaceSet); if (searchSet != NULL) xmlXPathFreeNodeSet(searchSet); } xmlXPathReturnString(ctxt, ret); fail: if (replaceStr != NULL) xmlFree(replaceStr); if (searchStr != NULL) xmlFree(searchStr); if (str != NULL) xmlFree(str); }