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 |