| OLD | NEW |
| 1 /* | 1 /* |
| 2 * functions.c: Implementation of the XSLT extra functions | 2 * functions.c: Implementation of the XSLT extra functions |
| 3 * | 3 * |
| 4 * Reference: | 4 * Reference: |
| 5 * http://www.w3.org/TR/1999/REC-xslt-19991116 | 5 * http://www.w3.org/TR/1999/REC-xslt-19991116 |
| 6 * | 6 * |
| 7 * See Copyright for the status of this software. | 7 * See Copyright for the status of this software. |
| 8 * | 8 * |
| 9 * daniel@veillard.com | 9 * daniel@veillard.com |
| 10 * Bjorn Reese <breese@users.sourceforge.net> for number formatting | 10 * Bjorn Reese <breese@users.sourceforge.net> for number formatting |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); | 173 xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); |
| 174 if (xptrctxt == NULL) { | 174 if (xptrctxt == NULL) { |
| 175 xsltTransformError(tctxt, NULL, NULL, | 175 xsltTransformError(tctxt, NULL, NULL, |
| 176 "document() : internal error xptrctxt == NULL\n"); | 176 "document() : internal error xptrctxt == NULL\n"); |
| 177 goto out_fragment; | 177 goto out_fragment; |
| 178 } | 178 } |
| 179 | 179 |
| 180 resObj = xmlXPtrEval(fragment, xptrctxt); | 180 resObj = xmlXPtrEval(fragment, xptrctxt); |
| 181 xmlXPathFreeContext(xptrctxt); | 181 xmlXPathFreeContext(xptrctxt); |
| 182 #endif | 182 #endif |
| 183 xmlFree(fragment); | |
| 184 | 183 |
| 185 if (resObj == NULL) | 184 if (resObj == NULL) |
| 186 goto out_fragment; | 185 goto out_fragment; |
| 187 | 186 |
| 188 switch (resObj->type) { | 187 switch (resObj->type) { |
| 189 case XPATH_NODESET: | 188 case XPATH_NODESET: |
| 190 break; | 189 break; |
| 191 case XPATH_UNDEFINED: | 190 case XPATH_UNDEFINED: |
| 192 case XPATH_BOOLEAN: | 191 case XPATH_BOOLEAN: |
| 193 case XPATH_NUMBER: | 192 case XPATH_NUMBER: |
| 194 case XPATH_STRING: | 193 case XPATH_STRING: |
| 195 case XPATH_POINT: | 194 case XPATH_POINT: |
| 196 case XPATH_USERS: | 195 case XPATH_USERS: |
| 197 case XPATH_XSLT_TREE: | 196 case XPATH_XSLT_TREE: |
| 198 case XPATH_RANGE: | 197 case XPATH_RANGE: |
| 199 case XPATH_LOCATIONSET: | 198 case XPATH_LOCATIONSET: |
| 200 xsltTransformError(tctxt, NULL, NULL, | 199 xsltTransformError(tctxt, NULL, NULL, |
| 201 "document() : XPointer does not select a node set: #%s\n", | 200 "document() : XPointer does not select a node set: #%s\n", |
| 202 fragment); | 201 fragment); |
| 203 goto out_object; | 202 goto out_object; |
| 204 } | 203 } |
| 205 | 204 |
| 206 valuePush(ctxt, resObj); | 205 valuePush(ctxt, resObj); |
| 206 xmlFree(fragment); |
| 207 return; | 207 return; |
| 208 | 208 |
| 209 out_object: | 209 out_object: |
| 210 xmlXPathFreeObject(resObj); | 210 xmlXPathFreeObject(resObj); |
| 211 | 211 |
| 212 out_fragment: | 212 out_fragment: |
| 213 valuePush(ctxt, xmlXPathNewNodeSet(NULL)); | 213 valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
| 214 xmlFree(fragment); |
| 214 } | 215 } |
| 215 | 216 |
| 216 /** | 217 /** |
| 217 * xsltDocumentFunction: | 218 * xsltDocumentFunction: |
| 218 * @ctxt: the XPath Parser context | 219 * @ctxt: the XPath Parser context |
| 219 * @nargs: the number of arguments | 220 * @nargs: the number of arguments |
| 220 * | 221 * |
| 221 * Implement the document() XSLT function | 222 * Implement the document() XSLT function |
| 222 * node-set document(object, node-set?) | 223 * node-set document(object, node-set?) |
| 223 */ | 224 */ |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 * Implement the generate-id() XSLT function | 659 * Implement the generate-id() XSLT function |
| 659 * string generate-id(node-set?) | 660 * string generate-id(node-set?) |
| 660 */ | 661 */ |
| 661 void | 662 void |
| 662 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ | 663 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
| 663 static char base_address; | 664 static char base_address; |
| 664 xmlNodePtr cur = NULL; | 665 xmlNodePtr cur = NULL; |
| 665 xmlXPathObjectPtr obj = NULL; | 666 xmlXPathObjectPtr obj = NULL; |
| 666 long val; | 667 long val; |
| 667 xmlChar str[30]; | 668 xmlChar str[30]; |
| 668 xmlDocPtr doc; | |
| 669 | 669 |
| 670 if (nargs == 0) { | 670 if (nargs == 0) { |
| 671 cur = ctxt->context->node; | 671 cur = ctxt->context->node; |
| 672 } else if (nargs == 1) { | 672 } else if (nargs == 1) { |
| 673 xmlNodeSetPtr nodelist; | 673 xmlNodeSetPtr nodelist; |
| 674 int i, ret; | 674 int i, ret; |
| 675 | 675 |
| 676 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { | 676 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { |
| 677 ctxt->error = XPATH_INVALID_TYPE; | 677 ctxt->error = XPATH_INVALID_TYPE; |
| 678 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, | 678 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 691 ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); | 691 ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); |
| 692 if (ret == -1) | 692 if (ret == -1) |
| 693 cur = nodelist->nodeTab[i]; | 693 cur = nodelist->nodeTab[i]; |
| 694 } | 694 } |
| 695 } else { | 695 } else { |
| 696 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, | 696 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
| 697 "generate-id() : invalid number of args %d\n", nargs); | 697 "generate-id() : invalid number of args %d\n", nargs); |
| 698 ctxt->error = XPATH_INVALID_ARITY; | 698 ctxt->error = XPATH_INVALID_ARITY; |
| 699 return; | 699 return; |
| 700 } | 700 } |
| 701 /* | |
| 702 * Okay this is ugly but should work, use the NodePtr address | |
| 703 * to forge the ID | |
| 704 */ | |
| 705 if (cur->type != XML_NAMESPACE_DECL) | |
| 706 doc = cur->doc; | |
| 707 else { | |
| 708 xmlNsPtr ns = (xmlNsPtr) cur; | |
| 709 | |
| 710 if (ns->context != NULL) | |
| 711 doc = ns->context; | |
| 712 else | |
| 713 doc = ctxt->context->doc; | |
| 714 | |
| 715 } | |
| 716 | 701 |
| 717 if (obj) | 702 if (obj) |
| 718 xmlXPathFreeObject(obj); | 703 xmlXPathFreeObject(obj); |
| 719 | 704 |
| 720 val = (long)((char *)cur - (char *)&base_address); | 705 val = (long)((char *)cur - (char *)&base_address); |
| 721 if (val >= 0) { | 706 if (val >= 0) { |
| 722 sprintf((char *)str, "idp%ld", val); | 707 snprintf((char *)str, sizeof(str), "idp%ld", val); |
| 723 } else { | 708 } else { |
| 724 sprintf((char *)str, "idm%ld", -val); | 709 snprintf((char *)str, sizeof(str), "idm%ld", -val); |
| 725 } | 710 } |
| 726 valuePush(ctxt, xmlXPathNewString(str)); | 711 valuePush(ctxt, xmlXPathNewString(str)); |
| 727 } | 712 } |
| 728 | 713 |
| 729 /** | 714 /** |
| 730 * xsltSystemPropertyFunction: | 715 * xsltSystemPropertyFunction: |
| 731 * @ctxt: the XPath Parser context | 716 * @ctxt: the XPath Parser context |
| 732 * @nargs: the number of arguments | 717 * @nargs: the number of arguments |
| 733 * | 718 * |
| 734 * Implement the system-property() XSLT function | 719 * Implement the system-property() XSLT function |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 xsltFormatNumberFunction); | 979 xsltFormatNumberFunction); |
| 995 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id", | 980 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id", |
| 996 xsltGenerateIdFunction); | 981 xsltGenerateIdFunction); |
| 997 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property", | 982 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property", |
| 998 xsltSystemPropertyFunction); | 983 xsltSystemPropertyFunction); |
| 999 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available", | 984 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available", |
| 1000 xsltElementAvailableFunction); | 985 xsltElementAvailableFunction); |
| 1001 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available", | 986 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available", |
| 1002 xsltFunctionAvailableFunction); | 987 xsltFunctionAvailableFunction); |
| 1003 } | 988 } |
| OLD | NEW |