| OLD | NEW |
| 1 #define IN_LIBEXSLT | 1 #define IN_LIBEXSLT |
| 2 #include "libexslt/libexslt.h" | 2 #include "libexslt/libexslt.h" |
| 3 | 3 |
| 4 #if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) | 4 #if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) |
| 5 #include <win32config.h> | 5 #include <win32config.h> |
| 6 #else | 6 #else |
| 7 #include "config.h" | 7 #include "config.h" |
| 8 #endif | 8 #endif |
| 9 | 9 |
| 10 #include <libxml/tree.h> | 10 #include <libxml/tree.h> |
| 11 #include <libxml/xpath.h> | 11 #include <libxml/xpath.h> |
| 12 #include <libxml/xpathInternals.h> | 12 #include <libxml/xpathInternals.h> |
| 13 #include <libxml/parser.h> | 13 #include <libxml/parser.h> |
| 14 #include <libxml/encoding.h> | 14 #include <libxml/encoding.h> |
| 15 #include <libxml/uri.h> | 15 #include <libxml/uri.h> |
| 16 | 16 |
| 17 #include <libxslt/xsltconfig.h> | 17 #include <libxslt/xsltconfig.h> |
| 18 #include <libxslt/xsltutils.h> | 18 #include <libxslt/xsltutils.h> |
| 19 #include <libxslt/xsltInternals.h> | 19 #include <libxslt/xsltInternals.h> |
| 20 #include <libxslt/extensions.h> | 20 #include <libxslt/extensions.h> |
| 21 | 21 |
| 22 #include "exslt.h" | 22 #include "exslt.h" |
| 23 | 23 |
| 24 /** | 24 /** |
| 25 * exsltStrTokenizeFunction: | 25 * exsltStrTokenizeFunction: |
| 26 * @ctxt: an XPath parser context | 26 * @ctxt: an XPath parser context |
| 27 * @nargs: the number of arguments | 27 * @nargs: the number of arguments |
| 28 * | 28 * |
| 29 * Splits up a string on the characters of the delimiter string and returns a | 29 * Splits up a string on the characters of the delimiter string and returns a |
| 30 * node set of token elements, each containing one token from the string. | 30 * node set of token elements, each containing one token from the string. |
| 31 */ | 31 */ |
| 32 static void | 32 static void |
| 33 exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs) | 33 exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs) |
| 34 { | 34 { |
| 35 xsltTransformContextPtr tctxt; | 35 xsltTransformContextPtr tctxt; |
| 36 xmlChar *str, *delimiters, *cur; | 36 xmlChar *str, *delimiters, *cur; |
| 37 const xmlChar *token, *delimiter; | 37 const xmlChar *token, *delimiter; |
| 38 xmlNodePtr node; | 38 xmlNodePtr node; |
| 39 xmlDocPtr container; | 39 xmlDocPtr container; |
| 40 xmlXPathObjectPtr ret = NULL; | 40 xmlXPathObjectPtr ret = NULL; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 (const xmlChar *) "token", token); | 99 (const xmlChar *) "token", token); |
| 100 xmlAddChild((xmlNodePtr) container, node); | 100 xmlAddChild((xmlNodePtr) container, node); |
| 101 xmlXPathNodeSetAddUnique(ret->nodesetval, node); | 101 xmlXPathNodeSetAddUnique(ret->nodesetval, node); |
| 102 *cur = *delimiter; /* restore the changed byte */ | 102 *cur = *delimiter; /* restore the changed byte */ |
| 103 token = cur + clen; | 103 token = cur + clen; |
| 104 break; | 104 break; |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 } | 107 } |
| 108 if (token != cur) { | 108 if (token != cur) { |
| 109 » » node = xmlNewDocRawNode(container, NULL, | 109 » » node = xmlNewDocRawNode(container, NULL, |
| 110 (const xmlChar *) "token", token); | 110 (const xmlChar *) "token", token); |
| 111 xmlAddChild((xmlNodePtr) container, node); | 111 xmlAddChild((xmlNodePtr) container, node); |
| 112 xmlXPathNodeSetAddUnique(ret->nodesetval, node); | 112 xmlXPathNodeSetAddUnique(ret->nodesetval, node); |
| 113 } | 113 } |
| 114 /* | 114 /* |
| 115 * Mark it as a function result in order to avoid garbage | 115 * Mark it as a function result in order to avoid garbage |
| 116 * collecting of tree fragments | 116 * collecting of tree fragments |
| 117 */ | 117 */ |
| 118 xsltExtensionInstructionResultRegister(tctxt, ret); | 118 xsltExtensionInstructionResultRegister(tctxt, ret); |
| 119 } | 119 } |
| 120 } | 120 } |
| 121 | 121 |
| 122 fail: | 122 fail: |
| 123 if (str != NULL) | 123 if (str != NULL) |
| 124 xmlFree(str); | 124 xmlFree(str); |
| 125 if (delimiters != NULL) | 125 if (delimiters != NULL) |
| 126 xmlFree(delimiters); | 126 xmlFree(delimiters); |
| 127 if (ret != NULL) | 127 if (ret != NULL) |
| 128 valuePush(ctxt, ret); | 128 valuePush(ctxt, ret); |
| 129 else | 129 else |
| 130 valuePush(ctxt, xmlXPathNewNodeSet(NULL)); | 130 valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
| 131 } | 131 } |
| 132 | 132 |
| 133 /** | 133 /** |
| 134 * exsltStrSplitFunction: | 134 * exsltStrSplitFunction: |
| 135 * @ctxt: an XPath parser context | 135 * @ctxt: an XPath parser context |
| 136 * @nargs: the number of arguments | 136 * @nargs: the number of arguments |
| 137 * | 137 * |
| 138 * Splits up a string on a delimiting string and returns a node set of token | 138 * Splits up a string on a delimiting string and returns a node set of token |
| 139 * elements, each containing one token from the string. | 139 * elements, each containing one token from the string. |
| 140 */ | 140 */ |
| 141 static void | 141 static void |
| 142 exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) { | 142 exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) { |
| 143 xsltTransformContextPtr tctxt; | 143 xsltTransformContextPtr tctxt; |
| 144 xmlChar *str, *delimiter, *cur; | 144 xmlChar *str, *delimiter, *cur; |
| 145 const xmlChar *token; | 145 const xmlChar *token; |
| 146 xmlNodePtr node; | 146 xmlNodePtr node; |
| 147 xmlDocPtr container; | 147 xmlDocPtr container; |
| 148 xmlXPathObjectPtr ret = NULL; | 148 xmlXPathObjectPtr ret = NULL; |
| 149 int delimiterLength; | 149 int delimiterLength; |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 | 328 |
| 329 ret = (xmlChar *) xmlURIUnescapeString((const char *)str,0,NULL); | 329 ret = (xmlChar *) xmlURIUnescapeString((const char *)str,0,NULL); |
| 330 if (!xmlCheckUTF8(ret)) { | 330 if (!xmlCheckUTF8(ret)) { |
| 331 /* FIXME: instead of throwing away the whole URI, we should | 331 /* FIXME: instead of throwing away the whole URI, we should |
| 332 only discard the invalid sequence(s). How to do that? */ | 332 only discard the invalid sequence(s). How to do that? */ |
| 333 xmlXPathReturnEmptyString(ctxt); | 333 xmlXPathReturnEmptyString(ctxt); |
| 334 xmlFree(str); | 334 xmlFree(str); |
| 335 xmlFree(ret); | 335 xmlFree(ret); |
| 336 return; | 336 return; |
| 337 } | 337 } |
| 338 | 338 |
| 339 xmlXPathReturnString(ctxt, ret); | 339 xmlXPathReturnString(ctxt, ret); |
| 340 | 340 |
| 341 if (str != NULL) | 341 if (str != NULL) |
| 342 xmlFree(str); | 342 xmlFree(str); |
| 343 } | 343 } |
| 344 | 344 |
| 345 /** | 345 /** |
| 346 * exsltStrPaddingFunction: | 346 * exsltStrPaddingFunction: |
| 347 * @ctxt: an XPath parser context | 347 * @ctxt: an XPath parser context |
| 348 * @nargs: the number of arguments | 348 * @nargs: the number of arguments |
| 349 * | 349 * |
| 350 * Creates a padding string of a certain length. | 350 * Creates a padding string of a certain length. |
| 351 */ | 351 */ |
| 352 static void | 352 static void |
| 353 exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) { | 353 exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) { |
| 354 int number, str_len = 0; | 354 int number, str_len = 0, str_size = 0; |
| 355 xmlChar *str = NULL, *ret = NULL, *tmp; | 355 xmlChar *str = NULL, *ret = NULL; |
| 356 | 356 |
| 357 if ((nargs < 1) || (nargs > 2)) { | 357 if ((nargs < 1) || (nargs > 2)) { |
| 358 xmlXPathSetArityError(ctxt); | 358 xmlXPathSetArityError(ctxt); |
| 359 return; | 359 return; |
| 360 } | 360 } |
| 361 | 361 |
| 362 if (nargs == 2) { | 362 if (nargs == 2) { |
| 363 str = xmlXPathPopString(ctxt); | 363 str = xmlXPathPopString(ctxt); |
| 364 str_len = xmlUTF8Strlen(str); | 364 str_len = xmlUTF8Strlen(str); |
| 365 str_size = xmlStrlen(str); |
| 365 } | 366 } |
| 366 if (str_len == 0) { | 367 if (str_len == 0) { |
| 367 if (str != NULL) xmlFree(str); | 368 if (str != NULL) xmlFree(str); |
| 368 str = xmlStrdup((const xmlChar *) " "); | 369 str = xmlStrdup((const xmlChar *) " "); |
| 369 str_len = 1; | 370 str_len = 1; |
| 371 str_size = 1; |
| 370 } | 372 } |
| 371 | 373 |
| 372 number = (int) xmlXPathPopNumber(ctxt); | 374 number = (int) xmlXPathPopNumber(ctxt); |
| 373 | 375 |
| 374 if (number <= 0) { | 376 if (number <= 0) { |
| 375 xmlXPathReturnEmptyString(ctxt); | 377 xmlXPathReturnEmptyString(ctxt); |
| 376 xmlFree(str); | 378 xmlFree(str); |
| 377 return; | 379 return; |
| 378 } | 380 } |
| 379 | 381 |
| 380 while (number >= str_len) { | 382 while (number >= str_len) { |
| 381 » ret = xmlStrncat(ret, str, str_len); | 383 » ret = xmlStrncat(ret, str, str_size); |
| 382 number -= str_len; | 384 number -= str_len; |
| 383 } | 385 } |
| 384 tmp = xmlUTF8Strndup (str, number); | 386 if (number > 0) { |
| 385 ret = xmlStrcat(ret, tmp); | 387 » str_size = xmlUTF8Strsize(str, number); |
| 386 if (tmp != NULL) | 388 » ret = xmlStrncat(ret, str, str_size); |
| 387 » xmlFree (tmp); | 389 } |
| 388 | 390 |
| 389 xmlXPathReturnString(ctxt, ret); | 391 xmlXPathReturnString(ctxt, ret); |
| 390 | 392 |
| 391 if (str != NULL) | 393 if (str != NULL) |
| 392 xmlFree(str); | 394 xmlFree(str); |
| 393 } | 395 } |
| 394 | 396 |
| 395 /** | 397 /** |
| 396 * exsltStrAlignFunction: | 398 * exsltStrAlignFunction: |
| 397 * @ctxt: an XPath parser context | 399 * @ctxt: an XPath parser context |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 int right_start; | 440 int right_start; |
| 439 | 441 |
| 440 ret = xmlUTF8Strndup (padding, left); | 442 ret = xmlUTF8Strndup (padding, left); |
| 441 ret = xmlStrcat (ret, str); | 443 ret = xmlStrcat (ret, str); |
| 442 | 444 |
| 443 right_start = xmlUTF8Strsize (padding, left + str_l); | 445 right_start = xmlUTF8Strsize (padding, left + str_l); |
| 444 ret = xmlStrcat (ret, padding + right_start); | 446 ret = xmlStrcat (ret, padding + right_start); |
| 445 } else { | 447 } else { |
| 446 int str_s; | 448 int str_s; |
| 447 | 449 |
| 448 » str_s = xmlStrlen (str); | 450 » str_s = xmlUTF8Strsize(padding, str_l); |
| 449 ret = xmlStrdup (str); | 451 ret = xmlStrdup (str); |
| 450 ret = xmlStrcat (ret, padding + str_s); | 452 ret = xmlStrcat (ret, padding + str_s); |
| 451 } | 453 } |
| 452 } | 454 } |
| 453 | 455 |
| 454 xmlXPathReturnString (ctxt, ret); | 456 xmlXPathReturnString (ctxt, ret); |
| 455 | 457 |
| 456 xmlFree(str); | 458 xmlFree(str); |
| 457 xmlFree(padding); | 459 xmlFree(padding); |
| 458 xmlFree(alignment); | 460 xmlFree(alignment); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 | 500 |
| 499 xmlFree(tmp); | 501 xmlFree(tmp); |
| 500 } | 502 } |
| 501 | 503 |
| 502 xmlXPathFreeObject (obj); | 504 xmlXPathFreeObject (obj); |
| 503 | 505 |
| 504 xmlXPathReturnString(ctxt, ret); | 506 xmlXPathReturnString(ctxt, ret); |
| 505 } | 507 } |
| 506 | 508 |
| 507 /** | 509 /** |
| 508 * exsltStrReplaceInternal: | 510 * exsltStrReturnString: |
| 509 * @str: string to modify | 511 * @ctxt: an XPath parser context |
| 510 * @searchStr: string to find | 512 * @str: a string |
| 511 * @replaceStr: string to replace occurrences of searchStr | 513 * @len: length of string |
| 512 * | 514 * |
| 513 * Search and replace string function used by exsltStrReplaceFunction | 515 * Returns a string as a node set. |
| 514 */ | 516 */ |
| 515 static xmlChar* | 517 static int |
| 516 exsltStrReplaceInternal(const xmlChar* str, const xmlChar* searchStr, | 518 exsltStrReturnString(xmlXPathParserContextPtr ctxt, const xmlChar *str, |
| 517 const xmlChar* replaceStr) | 519 int len) |
| 518 { | 520 { |
| 519 const xmlChar *curr, *next; | 521 xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); |
| 520 xmlChar *ret = NULL; | 522 xmlDocPtr container; |
| 521 int searchStrSize; | 523 xmlNodePtr text_node; |
| 522 | 524 xmlXPathObjectPtr ret; |
| 523 curr = str; | 525 |
| 524 searchStrSize = xmlStrlen(searchStr); | 526 container = xsltCreateRVT(tctxt); |
| 525 | 527 if (container == NULL) { |
| 526 do { | 528 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); |
| 527 next = xmlStrstr(curr, searchStr); | 529 return(-1); |
| 528 if (next == NULL) { | 530 } |
| 529 ret = xmlStrcat (ret, curr); | 531 xsltRegisterLocalRVT(tctxt, container); |
| 530 break; | 532 |
| 531 } | 533 text_node = xmlNewTextLen(str, len); |
| 532 | 534 if (text_node == NULL) { |
| 533 ret = xmlStrncat (ret, curr, next - curr); | 535 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); |
| 534 ret = xmlStrcat (ret, replaceStr); | 536 return(-1); |
| 535 curr = next + searchStrSize; | 537 } |
| 536 } while (*curr != 0); | 538 xmlAddChild((xmlNodePtr) container, text_node); |
| 537 | 539 |
| 538 return ret; | 540 ret = xmlXPathNewNodeSet(text_node); |
| 541 if (ret == NULL) { |
| 542 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); |
| 543 return(-1); |
| 544 } |
| 545 |
| 546 xsltExtensionInstructionResultRegister(tctxt, ret); |
| 547 valuePush(ctxt, ret); |
| 548 |
| 549 return(0); |
| 539 } | 550 } |
| 551 |
| 540 /** | 552 /** |
| 541 * exsltStrReplaceFunction: | 553 * exsltStrReplaceFunction: |
| 542 * @ctxt: an XPath parser context | 554 * @ctxt: an XPath parser context |
| 543 * @nargs: the number of arguments | 555 * @nargs: the number of arguments |
| 544 * | 556 * |
| 545 * Takes a string, and two node sets and returns the string with all strings in | 557 * Takes a string, and two node sets and returns the string with all strings in |
| 546 * the first node set replaced by all strings in the second node set. | 558 * the first node set replaced by all strings in the second node set. |
| 547 */ | 559 */ |
| 548 static void | 560 static void |
| 549 exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) { | 561 exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) { |
| 550 xmlChar *str = NULL, *searchStr = NULL, *replaceStr = NULL; | 562 int i, i_empty, n, slen0, rlen0, *slen, *rlen; |
| 551 xmlNodeSetPtr replaceSet = NULL, searchSet = NULL; | 563 void *mem = NULL; |
| 552 xmlChar *ret = NULL, *retSwap = NULL; | 564 const xmlChar *src, *start; |
| 553 int i; | 565 xmlChar *string, *search_str = NULL, *replace_str = NULL; |
| 566 xmlChar **search, **replace; |
| 567 xmlNodeSetPtr search_set = NULL, replace_set = NULL; |
| 568 xmlBufferPtr buf; |
| 554 | 569 |
| 555 if (nargs != 3) { | 570 if (nargs != 3) { |
| 556 xmlXPathSetArityError(ctxt); | 571 xmlXPathSetArityError(ctxt); |
| 557 return; | 572 return; |
| 558 } | 573 } |
| 559 | 574 |
| 560 /* pull out replace argument */ | 575 /* get replace argument */ |
| 576 |
| 577 if (!xmlXPathStackIsNodeSet(ctxt)) |
| 578 replace_str = xmlXPathPopString(ctxt); |
| 579 else |
| 580 replace_set = xmlXPathPopNodeSet(ctxt); |
| 581 |
| 582 if (xmlXPathCheckError(ctxt)) |
| 583 goto fail_replace; |
| 584 |
| 585 /* get search argument */ |
| 586 |
| 561 if (!xmlXPathStackIsNodeSet(ctxt)) { | 587 if (!xmlXPathStackIsNodeSet(ctxt)) { |
| 562 replaceStr = xmlXPathPopString(ctxt); | 588 search_str = xmlXPathPopString(ctxt); |
| 563 } | 589 n = 1; |
| 564 » » else { | 590 } |
| 565 replaceSet = xmlXPathPopNodeSet(ctxt); | 591 else { |
| 566 if (xmlXPathCheckError(ctxt)) { | 592 search_set = xmlXPathPopNodeSet(ctxt); |
| 567 xmlXPathSetTypeError(ctxt); | 593 n = search_set != NULL ? search_set->nodeNr : 0; |
| 568 goto fail; | 594 } |
| 569 } | 595 |
| 570 } | 596 if (xmlXPathCheckError(ctxt)) |
| 571 | 597 goto fail_search; |
| 572 /* behavior driven by search argument from here on */ | 598 |
| 573 if (!xmlXPathStackIsNodeSet(ctxt)) { | 599 /* get string argument */ |
| 574 searchStr = xmlXPathPopString(ctxt); | 600 |
| 575 str = xmlXPathPopString(ctxt); | 601 string = xmlXPathPopString(ctxt); |
| 576 | 602 if (xmlXPathCheckError(ctxt)) |
| 577 if (replaceStr == NULL) { | 603 goto fail_string; |
| 578 xmlXPathSetTypeError(ctxt); | 604 |
| 579 goto fail; | 605 /* check for empty search node list */ |
| 580 } | 606 |
| 581 | 607 if (n <= 0) { |
| 582 ret = exsltStrReplaceInternal(str, searchStr, replaceStr); | 608 exsltStrReturnString(ctxt, string, xmlStrlen(string)); |
| 583 } | 609 goto done_empty_search; |
| 584 » » else { | 610 } |
| 585 searchSet = xmlXPathPopNodeSet(ctxt); | 611 |
| 586 if (searchSet == NULL || xmlXPathCheckError(ctxt)) { | 612 /* allocate memory for string pointer and length arrays */ |
| 587 xmlXPathSetTypeError(ctxt); | 613 |
| 588 goto fail; | 614 if (n == 1) { |
| 589 } | 615 search = &search_str; |
| 590 | 616 replace = &replace_str; |
| 591 str = xmlXPathPopString(ctxt); | 617 slen = &slen0; |
| 592 ret = xmlStrdup(str); | 618 rlen = &rlen0; |
| 593 | 619 } |
| 594 for (i = 0; i < searchSet->nodeNr; i++) { | 620 else { |
| 595 » searchStr = xmlXPathCastNodeToString(searchSet->nodeTab[i]); | 621 mem = xmlMalloc(2 * n * (sizeof(const xmlChar *) + sizeof(int))); |
| 596 | 622 if (mem == NULL) { |
| 597 if (replaceSet != NULL) { | 623 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); |
| 598 replaceStr = NULL; | 624 goto fail_malloc; |
| 599 if (i < replaceSet->nodeNr) { | 625 } |
| 600 replaceStr = xmlXPathCastNodeToString(replaceSet->nodeTab[i]); | 626 search = (xmlChar **) mem; |
| 601 } | 627 replace = search + n; |
| 602 | 628 slen = (int *) (replace + n); |
| 603 retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); | 629 rlen = slen + n; |
| 604 | 630 } |
| 605 if (replaceStr != NULL) { | 631 |
| 606 xmlFree(replaceStr); | 632 /* process arguments */ |
| 607 replaceStr = NULL; | 633 |
| 608 } | 634 i_empty = -1; |
| 635 |
| 636 for (i=0; i<n; ++i) { |
| 637 if (search_set != NULL) { |
| 638 search[i] = xmlXPathCastNodeToString(search_set->nodeTab[i]); |
| 639 if (search[i] == NULL) { |
| 640 n = i; |
| 641 goto fail_process_args; |
| 642 } |
| 643 } |
| 644 |
| 645 slen[i] = xmlStrlen(search[i]); |
| 646 if (i_empty < 0 && slen[i] == 0) |
| 647 i_empty = i; |
| 648 |
| 649 if (replace_set != NULL) { |
| 650 if (i < replace_set->nodeNr) { |
| 651 replace[i] = xmlXPathCastNodeToString(replace_set->nodeTab[i]); |
| 652 if (replace[i] == NULL) { |
| 653 n = i + 1; |
| 654 goto fail_process_args; |
| 655 } |
| 656 } |
| 657 else |
| 658 replace[i] = NULL; |
| 609 } | 659 } |
| 610 else { | 660 else { |
| 611 retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); | 661 if (i == 0) |
| 612 } | 662 replace[i] = replace_str; |
| 613 | 663 else |
| 614 » » » » xmlFree(ret); | 664 replace[i] = NULL; |
| 615 if (searchStr != NULL) { | 665 } |
| 616 xmlFree(searchStr); | 666 |
| 617 searchStr = NULL; | 667 if (replace[i] == NULL) |
| 618 } | 668 rlen[i] = 0; |
| 619 | 669 else |
| 620 » » » » ret = retSwap; | 670 rlen[i] = xmlStrlen(replace[i]); |
| 621 » » » } | 671 } |
| 622 | 672 |
| 623 if (replaceSet != NULL) | 673 if (i_empty >= 0 && rlen[i_empty] == 0) |
| 624 xmlXPathFreeNodeSet(replaceSet); | 674 i_empty = -1; |
| 625 | 675 |
| 626 if (searchSet != NULL) | 676 /* replace operation */ |
| 627 xmlXPathFreeNodeSet(searchSet); | 677 |
| 628 » » } | 678 buf = xmlBufferCreate(); |
| 629 | 679 if (buf == NULL) { |
| 630 xmlXPathReturnString(ctxt, ret); | 680 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); |
| 631 | 681 goto fail_buffer; |
| 632 fail: | 682 } |
| 633 if (replaceStr != NULL) | 683 src = string; |
| 634 xmlFree(replaceStr); | 684 start = string; |
| 635 | 685 |
| 636 if (searchStr != NULL) | 686 while (*src != 0) { |
| 637 xmlFree(searchStr); | 687 int max_len = 0, i_match = 0; |
| 638 | 688 |
| 639 if (str != NULL) | 689 for (i=0; i<n; ++i) { |
| 640 xmlFree(str); | 690 if (*src == search[i][0] && |
| 691 slen[i] > max_len && |
| 692 xmlStrncmp(src, search[i], slen[i]) == 0) |
| 693 { |
| 694 i_match = i; |
| 695 max_len = slen[i]; |
| 696 } |
| 697 } |
| 698 |
| 699 if (max_len == 0) { |
| 700 if (i_empty >= 0 && start < src) { |
| 701 if (xmlBufferAdd(buf, start, src - start) || |
| 702 xmlBufferAdd(buf, replace[i_empty], rlen[i_empty])) |
| 703 { |
| 704 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); |
| 705 goto fail_buffer_add; |
| 706 } |
| 707 start = src; |
| 708 } |
| 709 |
| 710 src += xmlUTF8Size(src); |
| 711 } |
| 712 else { |
| 713 if ((start < src && |
| 714 xmlBufferAdd(buf, start, src - start)) || |
| 715 (rlen[i_match] && |
| 716 xmlBufferAdd(buf, replace[i_match], rlen[i_match]))) |
| 717 { |
| 718 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); |
| 719 goto fail_buffer_add; |
| 720 } |
| 721 |
| 722 src += slen[i_match]; |
| 723 start = src; |
| 724 } |
| 725 } |
| 726 |
| 727 if (start < src && xmlBufferAdd(buf, start, src - start)) { |
| 728 xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR); |
| 729 goto fail_buffer_add; |
| 730 } |
| 731 |
| 732 /* create result node set */ |
| 733 |
| 734 exsltStrReturnString(ctxt, xmlBufferContent(buf), xmlBufferLength(buf)); |
| 735 |
| 736 /* clean up */ |
| 737 |
| 738 fail_buffer_add: |
| 739 xmlBufferFree(buf); |
| 740 |
| 741 fail_buffer: |
| 742 fail_process_args: |
| 743 if (search_set != NULL) { |
| 744 for (i=0; i<n; ++i) |
| 745 xmlFree(search[i]); |
| 746 } |
| 747 if (replace_set != NULL) { |
| 748 for (i=0; i<n; ++i) { |
| 749 if (replace[i] != NULL) |
| 750 xmlFree(replace[i]); |
| 751 } |
| 752 } |
| 753 |
| 754 if (mem != NULL) |
| 755 xmlFree(mem); |
| 756 |
| 757 fail_malloc: |
| 758 done_empty_search: |
| 759 xmlFree(string); |
| 760 |
| 761 fail_string: |
| 762 if (search_set != NULL) |
| 763 xmlXPathFreeNodeSet(search_set); |
| 764 else |
| 765 xmlFree(search_str); |
| 766 |
| 767 fail_search: |
| 768 if (replace_set != NULL) |
| 769 xmlXPathFreeNodeSet(replace_set); |
| 770 else |
| 771 xmlFree(replace_str); |
| 772 |
| 773 fail_replace: |
| 774 return; |
| 641 } | 775 } |
| 642 | 776 |
| 643 /** | 777 /** |
| 644 * exsltStrRegister: | 778 * exsltStrRegister: |
| 645 * | 779 * |
| 646 * Registers the EXSLT - Strings module | 780 * Registers the EXSLT - Strings module |
| 647 */ | 781 */ |
| 648 | 782 |
| 649 void | 783 void |
| 650 exsltStrRegister (void) { | 784 exsltStrRegister (void) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 (const xmlChar *) "padding", | 833 (const xmlChar *) "padding", |
| 700 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, | 834 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, |
| 701 exsltStrPaddingFunction) | 835 exsltStrPaddingFunction) |
| 702 && !xmlXPathRegisterFuncNS(ctxt, | 836 && !xmlXPathRegisterFuncNS(ctxt, |
| 703 (const xmlChar *) "align", | 837 (const xmlChar *) "align", |
| 704 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, | 838 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, |
| 705 exsltStrAlignFunction) | 839 exsltStrAlignFunction) |
| 706 && !xmlXPathRegisterFuncNS(ctxt, | 840 && !xmlXPathRegisterFuncNS(ctxt, |
| 707 (const xmlChar *) "concat", | 841 (const xmlChar *) "concat", |
| 708 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, | 842 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, |
| 709 exsltStrConcatFunction) | 843 exsltStrConcatFunction)) { |
| 710 && !xmlXPathRegisterFuncNS(ctxt, | |
| 711 (const xmlChar *) "replace", | |
| 712 (const xmlChar *) EXSLT_STRINGS_NAMESPACE, | |
| 713 exsltStrReplaceFunction)) { | |
| 714 return 0; | 844 return 0; |
| 715 } | 845 } |
| 716 return -1; | 846 return -1; |
| 717 } | 847 } |
| OLD | NEW |