| OLD | NEW |
| 1 /* | 1 /* |
| 2 * numbers.c: Implementation of the XSLT number functions | 2 * numbers.c: Implementation of the XSLT number 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> | 10 * Bjorn Reese <breese@users.sourceforge.net> |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 if ((i > 0) && (groupingCharacter != 0) && | 186 if ((i > 0) && (groupingCharacter != 0) && |
| 187 (digitsPerGroup > 0) && | 187 (digitsPerGroup > 0) && |
| 188 ((i % digitsPerGroup) == 0)) { | 188 ((i % digitsPerGroup) == 0)) { |
| 189 if (pointer - groupingCharacterLen < temp_string) { | 189 if (pointer - groupingCharacterLen < temp_string) { |
| 190 i = -1; /* flag error */ | 190 i = -1; /* flag error */ |
| 191 break; | 191 break; |
| 192 } | 192 } |
| 193 pointer -= groupingCharacterLen; | 193 pointer -= groupingCharacterLen; |
| 194 xmlCopyCharMultiByte(pointer, groupingCharacter); | 194 xmlCopyCharMultiByte(pointer, groupingCharacter); |
| 195 } | 195 } |
| 196 » | 196 |
| 197 val = digit_zero + (int)fmod(number, 10.0); | 197 val = digit_zero + (int)fmod(number, 10.0); |
| 198 if (val < 0x80) { /* shortcut if ASCII */ | 198 if (val < 0x80) { /* shortcut if ASCII */ |
| 199 if (pointer <= temp_string) { /* Check enough room */ | 199 if (pointer <= temp_string) { /* Check enough room */ |
| 200 i = -1; | 200 i = -1; |
| 201 break; | 201 break; |
| 202 } | 202 } |
| 203 *(--pointer) = val; | 203 *(--pointer) = val; |
| 204 } | 204 } |
| 205 else { | 205 else { |
| 206 » /* | 206 » /* |
| 207 * Here we have a multibyte character. It's a little messy, | 207 * Here we have a multibyte character. It's a little messy, |
| 208 * because until we generate the char we don't know how long | 208 * because until we generate the char we don't know how long |
| 209 * it is. So, we generate it into the buffer temp_char, then | 209 * it is. So, we generate it into the buffer temp_char, then |
| 210 * copy from there into temp_string. | 210 * copy from there into temp_string. |
| 211 */ | 211 */ |
| 212 len = xmlCopyCharMultiByte(temp_char, val); | 212 len = xmlCopyCharMultiByte(temp_char, val); |
| 213 if ( (pointer - len) < temp_string ) { | 213 if ( (pointer - len) < temp_string ) { |
| 214 i = -1; | 214 i = -1; |
| 215 break; | 215 break; |
| 216 } | 216 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 234 char temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 1]; | 234 char temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 1]; |
| 235 char *pointer; | 235 char *pointer; |
| 236 int i; | 236 int i; |
| 237 char *alpha_list; | 237 char *alpha_list; |
| 238 double alpha_size = (double)(sizeof(alpha_upper_list) - 1); | 238 double alpha_size = (double)(sizeof(alpha_upper_list) - 1); |
| 239 | 239 |
| 240 /* Build buffer from back */ | 240 /* Build buffer from back */ |
| 241 pointer = &temp_string[sizeof(temp_string)]; | 241 pointer = &temp_string[sizeof(temp_string)]; |
| 242 *(--pointer) = 0; | 242 *(--pointer) = 0; |
| 243 alpha_list = (is_upper) ? alpha_upper_list : alpha_lower_list; | 243 alpha_list = (is_upper) ? alpha_upper_list : alpha_lower_list; |
| 244 | 244 |
| 245 for (i = 1; i < (int)sizeof(temp_string); i++) { | 245 for (i = 1; i < (int)sizeof(temp_string); i++) { |
| 246 number--; | 246 number--; |
| 247 *(--pointer) = alpha_list[((int)fmod(number, alpha_size))]; | 247 *(--pointer) = alpha_list[((int)fmod(number, alpha_size))]; |
| 248 number /= alpha_size; | 248 number /= alpha_size; |
| 249 if (fabs(number) < 1.0) | 249 if (fabs(number) < 1.0) |
| 250 break; /* for */ | 250 break; /* for */ |
| 251 } | 251 } |
| 252 xmlBufferCCat(buffer, pointer); | 252 xmlBufferCCat(buffer, pointer); |
| 253 } | 253 } |
| 254 | 254 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 | 330 |
| 331 tokens->start = NULL; | 331 tokens->start = NULL; |
| 332 tokens->tokens[0].separator = NULL; | 332 tokens->tokens[0].separator = NULL; |
| 333 tokens->end = NULL; | 333 tokens->end = NULL; |
| 334 | 334 |
| 335 /* | 335 /* |
| 336 * Insert initial non-alphanumeric token. | 336 * Insert initial non-alphanumeric token. |
| 337 * There is always such a token in the list, even if NULL | 337 * There is always such a token in the list, even if NULL |
| 338 */ | 338 */ |
| 339 while (! (IS_LETTER(val=xmlStringCurrentChar(NULL, format+ix, &len)) || | 339 while (! (IS_LETTER(val=xmlStringCurrentChar(NULL, format+ix, &len)) || |
| 340 » IS_DIGIT(val)) ) { | 340 » IS_DIGIT(val)) ) { |
| 341 if (format[ix] == 0) /* if end of format string */ | 341 if (format[ix] == 0) /* if end of format string */ |
| 342 break; /* while */ | 342 break; /* while */ |
| 343 ix += len; | 343 ix += len; |
| 344 } | 344 } |
| 345 if (ix > 0) | 345 if (ix > 0) |
| 346 tokens->start = xmlStrndup(format, ix); | 346 tokens->start = xmlStrndup(format, ix); |
| 347 | 347 |
| 348 | 348 |
| 349 for (tokens->nTokens = 0; tokens->nTokens < MAX_TOKENS; | 349 for (tokens->nTokens = 0; tokens->nTokens < MAX_TOKENS; |
| 350 tokens->nTokens++) { | 350 tokens->nTokens++) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 * Handle final non-alphanumeric token | 527 * Handle final non-alphanumeric token |
| 528 */ | 528 */ |
| 529 if (tokens->end != NULL) | 529 if (tokens->end != NULL) |
| 530 xmlBufferCat(buffer, tokens->end); | 530 xmlBufferCat(buffer, tokens->end); |
| 531 | 531 |
| 532 } | 532 } |
| 533 | 533 |
| 534 static int | 534 static int |
| 535 xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context, | 535 xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context, |
| 536 xmlNodePtr node, | 536 xmlNodePtr node, |
| 537 » » » const xmlChar *count, | 537 » » » xsltCompMatchPtr countPat, |
| 538 » » » const xmlChar *from, | 538 » » » xsltCompMatchPtr fromPat, |
| 539 double *array, | 539 double *array, |
| 540 xmlDocPtr doc, | 540 xmlDocPtr doc, |
| 541 xmlNodePtr elem) | 541 xmlNodePtr elem) |
| 542 { | 542 { |
| 543 int amount = 0; | 543 int amount = 0; |
| 544 int cnt = 0; | 544 int cnt = 0; |
| 545 xmlNodePtr cur; | 545 xmlNodePtr cur; |
| 546 xsltCompMatchPtr countPat = NULL; | |
| 547 xsltCompMatchPtr fromPat = NULL; | |
| 548 | 546 |
| 549 if (count != NULL) | |
| 550 countPat = xsltCompilePattern(count, doc, elem, NULL, context); | |
| 551 if (from != NULL) | |
| 552 fromPat = xsltCompilePattern(from, doc, elem, NULL, context); | |
| 553 | |
| 554 /* select the starting node */ | 547 /* select the starting node */ |
| 555 switch (node->type) { | 548 switch (node->type) { |
| 556 case XML_ELEMENT_NODE: | 549 case XML_ELEMENT_NODE: |
| 557 cur = node; | 550 cur = node; |
| 558 break; | 551 break; |
| 559 case XML_ATTRIBUTE_NODE: | 552 case XML_ATTRIBUTE_NODE: |
| 560 cur = ((xmlAttrPtr) node)->parent; | 553 cur = ((xmlAttrPtr) node)->parent; |
| 561 break; | 554 break; |
| 562 case XML_TEXT_NODE: | 555 case XML_TEXT_NODE: |
| 563 case XML_PI_NODE: | 556 case XML_PI_NODE: |
| 564 case XML_COMMENT_NODE: | 557 case XML_COMMENT_NODE: |
| 565 cur = node->parent; | 558 cur = node->parent; |
| 566 break; | 559 break; |
| 567 default: | 560 default: |
| 568 cur = NULL; | 561 cur = NULL; |
| 569 break; | 562 break; |
| 570 } | 563 } |
| 571 | 564 |
| 572 while (cur != NULL) { | 565 while (cur != NULL) { |
| 573 /* process current node */ | 566 /* process current node */ |
| 574 » if (count == NULL) { | 567 » if (countPat == NULL) { |
| 575 if ((node->type == cur->type) && | 568 if ((node->type == cur->type) && |
| 576 /* FIXME: must use expanded-name instead of local name */ | 569 /* FIXME: must use expanded-name instead of local name */ |
| 577 xmlStrEqual(node->name, cur->name)) { | 570 xmlStrEqual(node->name, cur->name)) { |
| 578 if ((node->ns == cur->ns) || | 571 if ((node->ns == cur->ns) || |
| 579 ((node->ns != NULL) && | 572 ((node->ns != NULL) && |
| 580 (cur->ns != NULL) && | 573 (cur->ns != NULL) && |
| 581 (xmlStrEqual(node->ns->href, | 574 (xmlStrEqual(node->ns->href, |
| 582 cur->ns->href) ))) | 575 cur->ns->href) ))) |
| 583 cnt++; | 576 cnt++; |
| 584 } | 577 } |
| 585 } else { | 578 } else { |
| 586 if (xsltTestCompMatchList(context, cur, countPat)) | 579 if (xsltTestCompMatchList(context, cur, countPat)) |
| 587 cnt++; | 580 cnt++; |
| 588 } | 581 } |
| 589 » if ((from != NULL) && | 582 » if ((fromPat != NULL) && |
| 590 xsltTestCompMatchList(context, cur, fromPat)) { | 583 xsltTestCompMatchList(context, cur, fromPat)) { |
| 591 break; /* while */ | 584 break; /* while */ |
| 592 } | 585 } |
| 593 | 586 |
| 594 /* Skip to next preceding or ancestor */ | 587 /* Skip to next preceding or ancestor */ |
| 595 if ((cur->type == XML_DOCUMENT_NODE) || | 588 if ((cur->type == XML_DOCUMENT_NODE) || |
| 596 #ifdef LIBXML_DOCB_ENABLED | 589 #ifdef LIBXML_DOCB_ENABLED |
| 597 (cur->type == XML_DOCB_DOCUMENT_NODE) || | 590 (cur->type == XML_DOCB_DOCUMENT_NODE) || |
| 598 #endif | 591 #endif |
| 599 (cur->type == XML_HTML_DOCUMENT_NODE)) | 592 (cur->type == XML_HTML_DOCUMENT_NODE)) |
| 600 break; /* while */ | 593 break; /* while */ |
| 601 | 594 |
| 602 while ((cur->prev != NULL) && ((cur->prev->type == XML_DTD_NODE) || | 595 while ((cur->prev != NULL) && ((cur->prev->type == XML_DTD_NODE) || |
| 603 (cur->prev->type == XML_XINCLUDE_START) || | 596 (cur->prev->type == XML_XINCLUDE_START) || |
| 604 (cur->prev->type == XML_XINCLUDE_END))) | 597 (cur->prev->type == XML_XINCLUDE_END))) |
| 605 cur = cur->prev; | 598 cur = cur->prev; |
| 606 if (cur->prev != NULL) { | 599 if (cur->prev != NULL) { |
| 607 for (cur = cur->prev; cur->last != NULL; cur = cur->last); | 600 for (cur = cur->prev; cur->last != NULL; cur = cur->last); |
| 608 } else { | 601 } else { |
| 609 cur = cur->parent; | 602 cur = cur->parent; |
| 610 } | 603 } |
| 611 | 604 |
| 612 } | 605 } |
| 613 | 606 |
| 614 array[amount++] = (double) cnt; | 607 array[amount++] = (double) cnt; |
| 615 | 608 |
| 616 if (countPat != NULL) | |
| 617 xsltFreeCompMatchList(countPat); | |
| 618 if (fromPat != NULL) | |
| 619 xsltFreeCompMatchList(fromPat); | |
| 620 return(amount); | 609 return(amount); |
| 621 } | 610 } |
| 622 | 611 |
| 623 static int | 612 static int |
| 624 xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context, | 613 xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context, |
| 625 xmlNodePtr node, | 614 xmlNodePtr node, |
| 626 » » » » const xmlChar *count, | 615 » » » » xsltCompMatchPtr countPat, |
| 627 » » » » const xmlChar *from, | 616 » » » » xsltCompMatchPtr fromPat, |
| 628 double *array, | 617 double *array, |
| 629 int max, | 618 int max, |
| 630 xmlDocPtr doc, | 619 xmlDocPtr doc, |
| 631 xmlNodePtr elem) | 620 xmlNodePtr elem) |
| 632 { | 621 { |
| 633 int amount = 0; | 622 int amount = 0; |
| 634 int cnt; | 623 int cnt; |
| 635 xmlNodePtr ancestor; | 624 xmlNodePtr ancestor; |
| 636 xmlNodePtr preceding; | 625 xmlNodePtr preceding; |
| 637 xmlXPathParserContextPtr parser; | 626 xmlXPathParserContextPtr parser; |
| 638 xsltCompMatchPtr countPat; | |
| 639 xsltCompMatchPtr fromPat; | |
| 640 | 627 |
| 641 if (count != NULL) | |
| 642 countPat = xsltCompilePattern(count, doc, elem, NULL, context); | |
| 643 else | |
| 644 countPat = NULL; | |
| 645 if (from != NULL) | |
| 646 fromPat = xsltCompilePattern(from, doc, elem, NULL, context); | |
| 647 else | |
| 648 fromPat = NULL; | |
| 649 context->xpathCtxt->node = node; | 628 context->xpathCtxt->node = node; |
| 650 parser = xmlXPathNewParserContext(NULL, context->xpathCtxt); | 629 parser = xmlXPathNewParserContext(NULL, context->xpathCtxt); |
| 651 if (parser) { | 630 if (parser) { |
| 652 /* ancestor-or-self::*[count] */ | 631 /* ancestor-or-self::*[count] */ |
| 653 for (ancestor = node; | 632 for (ancestor = node; |
| 654 (ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE); | 633 (ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE); |
| 655 ancestor = xmlXPathNextAncestor(parser, ancestor)) { | 634 ancestor = xmlXPathNextAncestor(parser, ancestor)) { |
| 656 » | 635 |
| 657 » if ((from != NULL) && | 636 » if ((fromPat != NULL) && |
| 658 xsltTestCompMatchList(context, ancestor, fromPat)) | 637 xsltTestCompMatchList(context, ancestor, fromPat)) |
| 659 break; /* for */ | 638 break; /* for */ |
| 660 » | 639 |
| 661 » if ((count == NULL && node->type == ancestor->type && | 640 » if ((countPat == NULL && node->type == ancestor->type && |
| 662 xmlStrEqual(node->name, ancestor->name)) || | 641 xmlStrEqual(node->name, ancestor->name)) || |
| 663 xsltTestCompMatchList(context, ancestor, countPat)) { | 642 xsltTestCompMatchList(context, ancestor, countPat)) { |
| 664 /* count(preceding-sibling::*) */ | 643 /* count(preceding-sibling::*) */ |
| 665 cnt = 0; | 644 cnt = 0; |
| 666 for (preceding = ancestor; | 645 for (preceding = ancestor; |
| 667 preceding != NULL; | 646 preceding != NULL; |
| 668 » » preceding = | 647 » » preceding = |
| 669 xmlXPathNextPrecedingSibling(parser, preceding)) { | 648 xmlXPathNextPrecedingSibling(parser, preceding)) { |
| 670 » » if (count == NULL) { | 649 » » if (countPat == NULL) { |
| 671 if ((preceding->type == ancestor->type) && | 650 if ((preceding->type == ancestor->type) && |
| 672 xmlStrEqual(preceding->name, ancestor->name)){ | 651 xmlStrEqual(preceding->name, ancestor->name)){ |
| 673 if ((preceding->ns == ancestor->ns) || | 652 if ((preceding->ns == ancestor->ns) || |
| 674 ((preceding->ns != NULL) && | 653 ((preceding->ns != NULL) && |
| 675 (ancestor->ns != NULL) && | 654 (ancestor->ns != NULL) && |
| 676 (xmlStrEqual(preceding->ns->href, | 655 (xmlStrEqual(preceding->ns->href, |
| 677 ancestor->ns->href) ))) | 656 ancestor->ns->href) ))) |
| 678 cnt++; | 657 cnt++; |
| 679 } | 658 } |
| 680 } else { | 659 } else { |
| 681 if (xsltTestCompMatchList(context, preceding, | 660 if (xsltTestCompMatchList(context, preceding, |
| 682 countPat)) | 661 countPat)) |
| 683 cnt++; | 662 cnt++; |
| 684 } | 663 } |
| 685 } | 664 } |
| 686 array[amount++] = (double)cnt; | 665 array[amount++] = (double)cnt; |
| 687 if (amount >= max) | 666 if (amount >= max) |
| 688 break; /* for */ | 667 break; /* for */ |
| 689 } | 668 } |
| 690 } | 669 } |
| 691 xmlXPathFreeParserContext(parser); | 670 xmlXPathFreeParserContext(parser); |
| 692 } | 671 } |
| 693 xsltFreeCompMatchList(countPat); | |
| 694 xsltFreeCompMatchList(fromPat); | |
| 695 return amount; | 672 return amount; |
| 696 } | 673 } |
| 697 | 674 |
| 698 static int | 675 static int |
| 699 xsltNumberFormatGetValue(xmlXPathContextPtr context, | 676 xsltNumberFormatGetValue(xmlXPathContextPtr context, |
| 700 xmlNodePtr node, | 677 xmlNodePtr node, |
| 701 const xmlChar *value, | 678 const xmlChar *value, |
| 702 double *number) | 679 double *number) |
| 703 { | 680 { |
| 704 int amount = 0; | 681 int amount = 0; |
| 705 xmlBufferPtr pattern; | 682 xmlBufferPtr pattern; |
| 706 xmlXPathObjectPtr obj; | 683 xmlXPathObjectPtr obj; |
| 707 | 684 |
| 708 pattern = xmlBufferCreate(); | 685 pattern = xmlBufferCreate(); |
| 709 if (pattern != NULL) { | 686 if (pattern != NULL) { |
| 710 xmlBufferCCat(pattern, "number("); | 687 xmlBufferCCat(pattern, "number("); |
| 711 xmlBufferCat(pattern, value); | 688 xmlBufferCat(pattern, value); |
| 712 xmlBufferCCat(pattern, ")"); | 689 xmlBufferCCat(pattern, ")"); |
| 713 context->node = node; | 690 context->node = node; |
| 714 obj = xmlXPathEvalExpression(xmlBufferContent(pattern), | 691 obj = xmlXPathEvalExpression(xmlBufferContent(pattern), |
| 715 context); | 692 context); |
| 716 if (obj != NULL) { | 693 if (obj != NULL) { |
| 717 *number = obj->floatval; | 694 *number = obj->floatval; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 node, | 743 node, |
| 767 data->value, | 744 data->value, |
| 768 &number); | 745 &number); |
| 769 if (amount == 1) { | 746 if (amount == 1) { |
| 770 xsltNumberFormatInsertNumbers(data, | 747 xsltNumberFormatInsertNumbers(data, |
| 771 &number, | 748 &number, |
| 772 1, | 749 1, |
| 773 &tokens, | 750 &tokens, |
| 774 output); | 751 output); |
| 775 } | 752 } |
| 776 » | 753 |
| 777 } else if (data->level) { | 754 } else if (data->level) { |
| 778 » | 755 |
| 779 if (xmlStrEqual(data->level, (const xmlChar *) "single")) { | 756 if (xmlStrEqual(data->level, (const xmlChar *) "single")) { |
| 780 amount = xsltNumberFormatGetMultipleLevel(ctxt, | 757 amount = xsltNumberFormatGetMultipleLevel(ctxt, |
| 781 node, | 758 node, |
| 782 » » » » » » data->count, | 759 » » » » » » data->countPat, |
| 783 » » » » » » data->from, | 760 » » » » » » data->fromPat, |
| 784 &number, | 761 &number, |
| 785 1, | 762 1, |
| 786 data->doc, | 763 data->doc, |
| 787 data->node); | 764 data->node); |
| 788 if (amount == 1) { | 765 if (amount == 1) { |
| 789 xsltNumberFormatInsertNumbers(data, | 766 xsltNumberFormatInsertNumbers(data, |
| 790 &number, | 767 &number, |
| 791 1, | 768 1, |
| 792 &tokens, | 769 &tokens, |
| 793 output); | 770 output); |
| 794 } | 771 } |
| 795 } else if (xmlStrEqual(data->level, (const xmlChar *) "multiple")) { | 772 } else if (xmlStrEqual(data->level, (const xmlChar *) "multiple")) { |
| 796 double numarray[1024]; | 773 double numarray[1024]; |
| 797 int max = sizeof(numarray)/sizeof(numarray[0]); | 774 int max = sizeof(numarray)/sizeof(numarray[0]); |
| 798 amount = xsltNumberFormatGetMultipleLevel(ctxt, | 775 amount = xsltNumberFormatGetMultipleLevel(ctxt, |
| 799 node, | 776 node, |
| 800 » » » » » » data->count, | 777 » » » » » » data->countPat, |
| 801 » » » » » » data->from, | 778 » » » » » » data->fromPat, |
| 802 numarray, | 779 numarray, |
| 803 max, | 780 max, |
| 804 data->doc, | 781 data->doc, |
| 805 data->node); | 782 data->node); |
| 806 if (amount > 0) { | 783 if (amount > 0) { |
| 807 xsltNumberFormatInsertNumbers(data, | 784 xsltNumberFormatInsertNumbers(data, |
| 808 numarray, | 785 numarray, |
| 809 amount, | 786 amount, |
| 810 &tokens, | 787 &tokens, |
| 811 output); | 788 output); |
| 812 } | 789 } |
| 813 } else if (xmlStrEqual(data->level, (const xmlChar *) "any")) { | 790 } else if (xmlStrEqual(data->level, (const xmlChar *) "any")) { |
| 814 amount = xsltNumberFormatGetAnyLevel(ctxt, | 791 amount = xsltNumberFormatGetAnyLevel(ctxt, |
| 815 node, | 792 node, |
| 816 » » » » » » data->count, | 793 » » » » » » data->countPat, |
| 817 » » » » » » data->from, | 794 » » » » » » data->fromPat, |
| 818 » » » » » » &number, | 795 » » » » » » &number, |
| 819 data->doc, | 796 data->doc, |
| 820 data->node); | 797 data->node); |
| 821 if (amount > 0) { | 798 if (amount > 0) { |
| 822 xsltNumberFormatInsertNumbers(data, | 799 xsltNumberFormatInsertNumbers(data, |
| 823 &number, | 800 &number, |
| 824 1, | 801 1, |
| 825 &tokens, | 802 &tokens, |
| 826 output); | 803 output); |
| 827 } | 804 } |
| 828 } | 805 } |
| 829 } | 806 } |
| 830 /* Insert number as text node */ | 807 /* Insert number as text node */ |
| 831 xsltCopyTextString(ctxt, ctxt->insert, xmlBufferContent(output), 0); | 808 xsltCopyTextString(ctxt, ctxt->insert, xmlBufferContent(output), 0); |
| 832 | 809 |
| 833 if (tokens.start != NULL) | 810 if (tokens.start != NULL) |
| 834 xmlFree(tokens.start); | 811 xmlFree(tokens.start); |
| 835 if (tokens.end != NULL) | 812 if (tokens.end != NULL) |
| 836 xmlFree(tokens.end); | 813 xmlFree(tokens.end); |
| 837 for (i = 0;i < tokens.nTokens;i++) { | 814 for (i = 0;i < tokens.nTokens;i++) { |
| 838 if (tokens.tokens[i].separator != NULL) | 815 if (tokens.tokens[i].separator != NULL) |
| 839 xmlFree(tokens.tokens[i].separator); | 816 xmlFree(tokens.tokens[i].separator); |
| 840 } | 817 } |
| 841 | 818 |
| 842 XSLT_NUMBER_FORMAT_END: | 819 XSLT_NUMBER_FORMAT_END: |
| 843 if (tempformat == 1) { | 820 if (tempformat == 1) { |
| 844 /* The format need to be recomputed each time */ | 821 /* The format need to be recomputed each time */ |
| 845 data->format = NULL; | 822 data->format = NULL; |
| 846 } | 823 } |
| 847 if (output != NULL) | 824 if (output != NULL) |
| 848 xmlBufferFree(output); | 825 xmlBufferFree(output); |
| 849 } | 826 } |
| 850 | 827 |
| 851 static int | 828 static int |
| 852 xsltFormatNumberPreSuffix(xsltDecimalFormatPtr self, xmlChar **format, xsltForma
tNumberInfoPtr info) | 829 xsltFormatNumberPreSuffix(xsltDecimalFormatPtr self, xmlChar **format, xsltForma
tNumberInfoPtr info) |
| 853 { | 830 { |
| 854 int count=0; /* will hold total length of prefix/suffix */ | 831 int count=0; /* will hold total length of prefix/suffix */ |
| 855 int len; | 832 int len; |
| 856 | 833 |
| 857 while (1) { | 834 while (1) { |
| 858 » /* | 835 » /* |
| 859 » * prefix / suffix ends at end of string or at | 836 » * prefix / suffix ends at end of string or at |
| 860 » * first 'special' character | 837 » * first 'special' character |
| 861 */ | 838 */ |
| 862 if (**format == 0) | 839 if (**format == 0) |
| 863 return count; | 840 return count; |
| 864 /* if next character 'escaped' just count it */ | 841 /* if next character 'escaped' just count it */ |
| 865 if (**format == SYMBOL_QUOTE) { | 842 if (**format == SYMBOL_QUOTE) { |
| 866 if (*++(*format) == 0) | 843 if (*++(*format) == 0) |
| 867 return -1; | 844 return -1; |
| 868 } | 845 } |
| 869 else if (IS_SPECIAL(self, *format)) | 846 else if (IS_SPECIAL(self, *format)) |
| 870 return count; | 847 return count; |
| 871 /* | 848 /* |
| 872 * else treat percent/per-mille as special cases, | 849 * else treat percent/per-mille as special cases, |
| 873 » * depending on whether +ve or -ve | 850 » * depending on whether +ve or -ve |
| 874 */ | 851 */ |
| 875 else { | 852 else { |
| 876 /* | 853 /* |
| 877 » * for +ve prefix/suffix, allow only a | 854 » * for +ve prefix/suffix, allow only a |
| 878 » * single occurence of either | 855 » * single occurence of either |
| 879 */ | 856 */ |
| 880 if (xsltUTF8Charcmp(*format, self->percent) == 0) { | 857 if (xsltUTF8Charcmp(*format, self->percent) == 0) { |
| 881 if (info->is_multiplier_set) | 858 if (info->is_multiplier_set) |
| 882 return -1; | 859 return -1; |
| 883 info->multiplier = 100; | 860 info->multiplier = 100; |
| 884 info->is_multiplier_set = TRUE; | 861 info->is_multiplier_set = TRUE; |
| 885 } else if (xsltUTF8Charcmp(*format, self->permille) == 0) { | 862 } else if (xsltUTF8Charcmp(*format, self->permille) == 0) { |
| 886 if (info->is_multiplier_set) | 863 if (info->is_multiplier_set) |
| 887 return -1; | 864 return -1; |
| 888 info->multiplier = 1000; | 865 info->multiplier = 1000; |
| 889 info->is_multiplier_set = TRUE; | 866 info->is_multiplier_set = TRUE; |
| 890 } | 867 } |
| 891 } | 868 } |
| 892 » | 869 |
| 893 if ((len=xsltUTF8Size(*format)) < 1) | 870 if ((len=xsltUTF8Size(*format)) < 1) |
| 894 return -1; | 871 return -1; |
| 895 count += len; | 872 count += len; |
| 896 *format += len; | 873 *format += len; |
| 897 } | 874 } |
| 898 } | 875 } |
| 899 » | 876 |
| 900 /** | 877 /** |
| 901 * xsltFormatNumberConversion: | 878 * xsltFormatNumberConversion: |
| 902 * @self: the decimal format | 879 * @self: the decimal format |
| 903 * @format: the format requested | 880 * @format: the format requested |
| 904 * @number: the value to format | 881 * @number: the value to format |
| 905 * @result: the place to ouput the result | 882 * @result: the place to ouput the result |
| 906 * | 883 * |
| 907 * format-number() uses the JDK 1.1 DecimalFormat class: | 884 * format-number() uses the JDK 1.1 DecimalFormat class: |
| 908 * | 885 * |
| 909 * http://java.sun.com/products/jdk/1.1/docs/api/java.text.DecimalFormat.html | 886 * http://java.sun.com/products/jdk/1.1/docs/api/java.text.DecimalFormat.html |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 xmlXPathError status = XPATH_EXPRESSION_OK; | 925 xmlXPathError status = XPATH_EXPRESSION_OK; |
| 949 xmlBufferPtr buffer; | 926 xmlBufferPtr buffer; |
| 950 xmlChar *the_format, *prefix = NULL, *suffix = NULL; | 927 xmlChar *the_format, *prefix = NULL, *suffix = NULL; |
| 951 xmlChar *nprefix, *nsuffix = NULL; | 928 xmlChar *nprefix, *nsuffix = NULL; |
| 952 xmlChar pchar; | 929 xmlChar pchar; |
| 953 int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length; | 930 int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length; |
| 954 double scale; | 931 double scale; |
| 955 int j, len; | 932 int j, len; |
| 956 int self_grouping_len; | 933 int self_grouping_len; |
| 957 xsltFormatNumberInfo format_info; | 934 xsltFormatNumberInfo format_info; |
| 958 /* | 935 /* |
| 959 * delayed_multiplier allows a 'trailing' percent or | 936 * delayed_multiplier allows a 'trailing' percent or |
| 960 * permille to be treated as suffix | 937 * permille to be treated as suffix |
| 961 */ | 938 */ |
| 962 int delayed_multiplier = 0; | 939 int delayed_multiplier = 0; |
| 963 /* flag to show no -ve format present for -ve number */ | 940 /* flag to show no -ve format present for -ve number */ |
| 964 char default_sign = 0; | 941 char default_sign = 0; |
| 965 /* flag to show error found, should use default format */ | 942 /* flag to show error found, should use default format */ |
| 966 char found_error = 0; | 943 char found_error = 0; |
| 967 | 944 |
| 968 if (xmlStrlen(format) <= 0) { | 945 if (xmlStrlen(format) <= 0) { |
| 969 xsltTransformError(NULL, NULL, NULL, | 946 xsltTransformError(NULL, NULL, NULL, |
| 970 "xsltFormatNumberConversion : " | 947 "xsltFormatNumberConversion : " |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 format_info.group = -1; | 983 format_info.group = -1; |
| 1007 format_info.multiplier = 1; | 984 format_info.multiplier = 1; |
| 1008 format_info.add_decimal = FALSE; | 985 format_info.add_decimal = FALSE; |
| 1009 format_info.is_multiplier_set = FALSE; | 986 format_info.is_multiplier_set = FALSE; |
| 1010 format_info.is_negative_pattern = FALSE; | 987 format_info.is_negative_pattern = FALSE; |
| 1011 | 988 |
| 1012 the_format = format; | 989 the_format = format; |
| 1013 | 990 |
| 1014 /* | 991 /* |
| 1015 * First we process the +ve pattern to get percent / permille, | 992 * First we process the +ve pattern to get percent / permille, |
| 1016 * as well as main format | 993 * as well as main format |
| 1017 */ | 994 */ |
| 1018 prefix = the_format; | 995 prefix = the_format; |
| 1019 prefix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info); | 996 prefix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info); |
| 1020 if (prefix_length < 0) { | 997 if (prefix_length < 0) { |
| 1021 found_error = 1; | 998 found_error = 1; |
| 1022 goto OUTPUT_NUMBER; | 999 goto OUTPUT_NUMBER; |
| 1023 } | 1000 } |
| 1024 | 1001 |
| 1025 /* | 1002 /* |
| 1026 * Here we process the "number" part of the format. It gets | 1003 * Here we process the "number" part of the format. It gets |
| 1027 * a little messy because of the percent/per-mille - if that | 1004 * a little messy because of the percent/per-mille - if that |
| 1028 * appears at the end, it may be part of the suffix instead | 1005 * appears at the end, it may be part of the suffix instead |
| 1029 * of part of the number, so the variable delayed_multiplier | 1006 * of part of the number, so the variable delayed_multiplier |
| 1030 * is used to handle it | 1007 * is used to handle it |
| 1031 */ | 1008 */ |
| 1032 self_grouping_len = xmlStrlen(self->grouping); | 1009 self_grouping_len = xmlStrlen(self->grouping); |
| 1033 while ((*the_format != 0) && | 1010 while ((*the_format != 0) && |
| 1034 (xsltUTF8Charcmp(the_format, self->decimalPoint) != 0) && | 1011 (xsltUTF8Charcmp(the_format, self->decimalPoint) != 0) && |
| 1035 (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) { | 1012 (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) { |
| 1036 » | 1013 |
| 1037 if (delayed_multiplier != 0) { | 1014 if (delayed_multiplier != 0) { |
| 1038 format_info.multiplier = delayed_multiplier; | 1015 format_info.multiplier = delayed_multiplier; |
| 1039 format_info.is_multiplier_set = TRUE; | 1016 format_info.is_multiplier_set = TRUE; |
| 1040 delayed_multiplier = 0; | 1017 delayed_multiplier = 0; |
| 1041 } | 1018 } |
| 1042 if (xsltUTF8Charcmp(the_format, self->digit) == 0) { | 1019 if (xsltUTF8Charcmp(the_format, self->digit) == 0) { |
| 1043 if (format_info.integer_digits > 0) { | 1020 if (format_info.integer_digits > 0) { |
| 1044 found_error = 1; | 1021 found_error = 1; |
| 1045 goto OUTPUT_NUMBER; | 1022 goto OUTPUT_NUMBER; |
| 1046 } | 1023 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1064 } | 1041 } |
| 1065 delayed_multiplier = 100; | 1042 delayed_multiplier = 100; |
| 1066 } else if (xsltUTF8Charcmp(the_format, self->permille) == 0) { | 1043 } else if (xsltUTF8Charcmp(the_format, self->permille) == 0) { |
| 1067 if (format_info.is_multiplier_set) { | 1044 if (format_info.is_multiplier_set) { |
| 1068 found_error = 1; | 1045 found_error = 1; |
| 1069 goto OUTPUT_NUMBER; | 1046 goto OUTPUT_NUMBER; |
| 1070 } | 1047 } |
| 1071 delayed_multiplier = 1000; | 1048 delayed_multiplier = 1000; |
| 1072 } else | 1049 } else |
| 1073 break; /* while */ | 1050 break; /* while */ |
| 1074 » | 1051 |
| 1075 if ((len=xsltUTF8Size(the_format)) < 1) { | 1052 if ((len=xsltUTF8Size(the_format)) < 1) { |
| 1076 found_error = 1; | 1053 found_error = 1; |
| 1077 goto OUTPUT_NUMBER; | 1054 goto OUTPUT_NUMBER; |
| 1078 } | 1055 } |
| 1079 the_format += len; | 1056 the_format += len; |
| 1080 | 1057 |
| 1081 } | 1058 } |
| 1082 | 1059 |
| 1083 /* We have finished the integer part, now work on fraction */ | 1060 /* We have finished the integer part, now work on fraction */ |
| 1084 if (xsltUTF8Charcmp(the_format, self->decimalPoint) == 0) { | 1061 if (xsltUTF8Charcmp(the_format, self->decimalPoint) == 0) { |
| 1085 format_info.add_decimal = TRUE; | 1062 format_info.add_decimal = TRUE; |
| 1086 the_format += xsltUTF8Size(the_format); /* Skip over the decimal */ | 1063 the_format += xsltUTF8Size(the_format); /* Skip over the decimal */ |
| 1087 } | 1064 } |
| 1088 | 1065 |
| 1089 while (*the_format != 0) { | 1066 while (*the_format != 0) { |
| 1090 » | 1067 |
| 1091 if (xsltUTF8Charcmp(the_format, self->zeroDigit) == 0) { | 1068 if (xsltUTF8Charcmp(the_format, self->zeroDigit) == 0) { |
| 1092 if (format_info.frac_hash != 0) { | 1069 if (format_info.frac_hash != 0) { |
| 1093 found_error = 1; | 1070 found_error = 1; |
| 1094 goto OUTPUT_NUMBER; | 1071 goto OUTPUT_NUMBER; |
| 1095 } | 1072 } |
| 1096 format_info.frac_digits++; | 1073 format_info.frac_digits++; |
| 1097 } else if (xsltUTF8Charcmp(the_format, self->digit) == 0) { | 1074 } else if (xsltUTF8Charcmp(the_format, self->digit) == 0) { |
| 1098 format_info.frac_hash++; | 1075 format_info.frac_hash++; |
| 1099 } else if (xsltUTF8Charcmp(the_format, self->percent) == 0) { | 1076 } else if (xsltUTF8Charcmp(the_format, self->percent) == 0) { |
| 1100 if (format_info.is_multiplier_set) { | 1077 if (format_info.is_multiplier_set) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1128 goto OUTPUT_NUMBER; | 1105 goto OUTPUT_NUMBER; |
| 1129 } | 1106 } |
| 1130 the_format += len; | 1107 the_format += len; |
| 1131 if (delayed_multiplier != 0) { | 1108 if (delayed_multiplier != 0) { |
| 1132 format_info.multiplier = delayed_multiplier; | 1109 format_info.multiplier = delayed_multiplier; |
| 1133 delayed_multiplier = 0; | 1110 delayed_multiplier = 0; |
| 1134 format_info.is_multiplier_set = TRUE; | 1111 format_info.is_multiplier_set = TRUE; |
| 1135 } | 1112 } |
| 1136 } | 1113 } |
| 1137 | 1114 |
| 1138 /* | 1115 /* |
| 1139 * If delayed_multiplier is set after processing the | 1116 * If delayed_multiplier is set after processing the |
| 1140 * "number" part, should be in suffix | 1117 * "number" part, should be in suffix |
| 1141 */ | 1118 */ |
| 1142 if (delayed_multiplier != 0) { | 1119 if (delayed_multiplier != 0) { |
| 1143 the_format -= len; | 1120 the_format -= len; |
| 1144 delayed_multiplier = 0; | 1121 delayed_multiplier = 0; |
| 1145 } | 1122 } |
| 1146 | 1123 |
| 1147 suffix = the_format; | 1124 suffix = the_format; |
| 1148 suffix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info); | 1125 suffix_length = xsltFormatNumberPreSuffix(self, &the_format, &format_info); |
| 1149 if ( (suffix_length < 0) || | 1126 if ( (suffix_length < 0) || |
| 1150 » ((*the_format != 0) && | 1127 » ((*the_format != 0) && |
| 1151 (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) ) { | 1128 (xsltUTF8Charcmp(the_format, self->patternSeparator) != 0)) ) { |
| 1152 found_error = 1; | 1129 found_error = 1; |
| 1153 goto OUTPUT_NUMBER; | 1130 goto OUTPUT_NUMBER; |
| 1154 } | 1131 } |
| 1155 | 1132 |
| 1156 /* | 1133 /* |
| 1157 * We have processed the +ve prefix, number part and +ve suffix. | 1134 * We have processed the +ve prefix, number part and +ve suffix. |
| 1158 * If the number is -ve, we must substitute the -ve prefix / suffix | 1135 * If the number is -ve, we must substitute the -ve prefix / suffix |
| 1159 */ | 1136 */ |
| 1160 if (number < 0) { | 1137 if (number < 0) { |
| 1161 /* | 1138 /* |
| 1162 * Note that j is the number of UTF8 chars before the separator, | 1139 * Note that j is the number of UTF8 chars before the separator, |
| 1163 * not the number of bytes! (bug 151975) | 1140 * not the number of bytes! (bug 151975) |
| 1164 */ | 1141 */ |
| 1165 j = xmlUTF8Strloc(format, self->patternSeparator); | 1142 j = xmlUTF8Strloc(format, self->patternSeparator); |
| 1166 if (j < 0) { | 1143 if (j < 0) { |
| 1167 /* No -ve pattern present, so use default signing */ | 1144 /* No -ve pattern present, so use default signing */ |
| 1168 default_sign = 1; | 1145 default_sign = 1; |
| 1169 } | 1146 } |
| 1170 else { | 1147 else { |
| 1171 /* Skip over pattern separator (accounting for UTF8) */ | 1148 /* Skip over pattern separator (accounting for UTF8) */ |
| 1172 the_format = (xmlChar *)xmlUTF8Strpos(format, j + 1); | 1149 the_format = (xmlChar *)xmlUTF8Strpos(format, j + 1); |
| 1173 » /* | 1150 » /* |
| 1174 » * Flag changes interpretation of percent/permille | 1151 » * Flag changes interpretation of percent/permille |
| 1175 » * in -ve pattern | 1152 » * in -ve pattern |
| 1176 */ | 1153 */ |
| 1177 format_info.is_negative_pattern = TRUE; | 1154 format_info.is_negative_pattern = TRUE; |
| 1178 format_info.is_multiplier_set = FALSE; | 1155 format_info.is_multiplier_set = FALSE; |
| 1179 | 1156 |
| 1180 /* First do the -ve prefix */ | 1157 /* First do the -ve prefix */ |
| 1181 nprefix = the_format; | 1158 nprefix = the_format; |
| 1182 » nprefix_length = xsltFormatNumberPreSuffix(self, | 1159 » nprefix_length = xsltFormatNumberPreSuffix(self, |
| 1183 » » » » » &the_format, &format_info); | 1160 » » » » » &the_format, &format_info); |
| 1184 if (nprefix_length<0) { | 1161 if (nprefix_length<0) { |
| 1185 found_error = 1; | 1162 found_error = 1; |
| 1186 goto OUTPUT_NUMBER; | 1163 goto OUTPUT_NUMBER; |
| 1187 } | 1164 } |
| 1188 | 1165 |
| 1189 while (*the_format != 0) { | 1166 while (*the_format != 0) { |
| 1190 if ( (xsltUTF8Charcmp(the_format, (self)->percent) == 0) || | 1167 if ( (xsltUTF8Charcmp(the_format, (self)->percent) == 0) || |
| 1191 (xsltUTF8Charcmp(the_format, (self)->permille)== 0) ) { | 1168 (xsltUTF8Charcmp(the_format, (self)->permille)== 0) ) { |
| 1192 if (format_info.is_multiplier_set) { | 1169 if (format_info.is_multiplier_set) { |
| 1193 found_error = 1; | 1170 found_error = 1; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1207 the_format += len; | 1184 the_format += len; |
| 1208 } | 1185 } |
| 1209 if (delayed_multiplier != 0) { | 1186 if (delayed_multiplier != 0) { |
| 1210 format_info.is_multiplier_set = FALSE; | 1187 format_info.is_multiplier_set = FALSE; |
| 1211 the_format -= len; | 1188 the_format -= len; |
| 1212 } | 1189 } |
| 1213 | 1190 |
| 1214 /* Finally do the -ve suffix */ | 1191 /* Finally do the -ve suffix */ |
| 1215 if (*the_format != 0) { | 1192 if (*the_format != 0) { |
| 1216 nsuffix = the_format; | 1193 nsuffix = the_format; |
| 1217 » » nsuffix_length = xsltFormatNumberPreSuffix(self, | 1194 » » nsuffix_length = xsltFormatNumberPreSuffix(self, |
| 1218 &the_format, &format_info); | 1195 &the_format, &format_info); |
| 1219 if (nsuffix_length < 0) { | 1196 if (nsuffix_length < 0) { |
| 1220 found_error = 1; | 1197 found_error = 1; |
| 1221 goto OUTPUT_NUMBER; | 1198 goto OUTPUT_NUMBER; |
| 1222 } | 1199 } |
| 1223 } | 1200 } |
| 1224 else | 1201 else |
| 1225 nsuffix_length = 0; | 1202 nsuffix_length = 0; |
| 1226 if (*the_format != 0) { | 1203 if (*the_format != 0) { |
| 1227 found_error = 1; | 1204 found_error = 1; |
| 1228 goto OUTPUT_NUMBER; | 1205 goto OUTPUT_NUMBER; |
| 1229 } | 1206 } |
| 1230 /* | 1207 /* |
| 1231 * Here's another Java peculiarity: | 1208 * Here's another Java peculiarity: |
| 1232 * if -ve prefix/suffix == +ve ones, discard & use default | 1209 * if -ve prefix/suffix == +ve ones, discard & use default |
| 1233 */ | 1210 */ |
| 1234 if ((nprefix_length != prefix_length) || | 1211 if ((nprefix_length != prefix_length) || |
| 1235 » » (nsuffix_length != suffix_length) || | 1212 » » (nsuffix_length != suffix_length) || |
| 1236 » » ((nprefix_length > 0) && | 1213 » » ((nprefix_length > 0) && |
| 1237 (xmlStrncmp(nprefix, prefix, prefix_length) !=0 )) || | 1214 (xmlStrncmp(nprefix, prefix, prefix_length) !=0 )) || |
| 1238 » » ((nsuffix_length > 0) && | 1215 » » ((nsuffix_length > 0) && |
| 1239 (xmlStrncmp(nsuffix, suffix, suffix_length) !=0 ))) { | 1216 (xmlStrncmp(nsuffix, suffix, suffix_length) !=0 ))) { |
| 1240 » » prefix = nprefix; | 1217 » » prefix = nprefix; |
| 1241 prefix_length = nprefix_length; | 1218 prefix_length = nprefix_length; |
| 1242 suffix = nsuffix; | 1219 suffix = nsuffix; |
| 1243 suffix_length = nsuffix_length; | 1220 suffix_length = nsuffix_length; |
| 1244 } /* else { | 1221 } /* else { |
| 1245 default_sign = 1; | 1222 default_sign = 1; |
| 1246 } | 1223 } |
| 1247 */ | 1224 */ |
| 1248 } | 1225 } |
| 1249 } | 1226 } |
| 1250 | 1227 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1276 prefix += len; | 1253 prefix += len; |
| 1277 j += len - 1; /* length of symbol less length of quote */ | 1254 j += len - 1; /* length of symbol less length of quote */ |
| 1278 } else | 1255 } else |
| 1279 xmlBufferAdd(buffer, &pchar, 1); | 1256 xmlBufferAdd(buffer, &pchar, 1); |
| 1280 } | 1257 } |
| 1281 | 1258 |
| 1282 /* Next do the integer part of the number */ | 1259 /* Next do the integer part of the number */ |
| 1283 number = fabs(number) * (double)format_info.multiplier; | 1260 number = fabs(number) * (double)format_info.multiplier; |
| 1284 scale = pow(10.0, (double)(format_info.frac_digits + format_info.frac_hash))
; | 1261 scale = pow(10.0, (double)(format_info.frac_digits + format_info.frac_hash))
; |
| 1285 number = floor((scale * number + 0.5)) / scale; | 1262 number = floor((scale * number + 0.5)) / scale; |
| 1286 if ((self->grouping != NULL) && | 1263 if ((self->grouping != NULL) && |
| 1287 (self->grouping[0] != 0)) { | 1264 (self->grouping[0] != 0)) { |
| 1288 » | 1265 |
| 1289 len = xmlStrlen(self->grouping); | 1266 len = xmlStrlen(self->grouping); |
| 1290 pchar = xsltGetUTF8Char(self->grouping, &len); | 1267 pchar = xsltGetUTF8Char(self->grouping, &len); |
| 1291 xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0], | 1268 xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0], |
| 1292 format_info.integer_digits, | 1269 format_info.integer_digits, |
| 1293 format_info.group, | 1270 format_info.group, |
| 1294 pchar, len); | 1271 pchar, len); |
| 1295 } else | 1272 } else |
| 1296 xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0], | 1273 xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0], |
| 1297 format_info.integer_digits, | 1274 format_info.integer_digits, |
| 1298 format_info.group, | 1275 format_info.group, |
| 1299 ',', 1); | 1276 ',', 1); |
| 1300 | 1277 |
| 1301 /* Special case: java treats '.#' like '.0', '.##' like '.0#', etc. */ | 1278 /* Special case: java treats '.#' like '.0', '.##' like '.0#', etc. */ |
| 1302 if ((format_info.integer_digits + format_info.integer_hash + | 1279 if ((format_info.integer_digits + format_info.integer_hash + |
| 1303 format_info.frac_digits == 0) && (format_info.frac_hash > 0)) { | 1280 format_info.frac_digits == 0) && (format_info.frac_hash > 0)) { |
| 1304 ++format_info.frac_digits; | 1281 ++format_info.frac_digits; |
| 1305 --format_info.frac_hash; | 1282 --format_info.frac_hash; |
| 1306 } | 1283 } |
| 1307 | 1284 |
| 1308 /* Add leading zero, if required */ | 1285 /* Add leading zero, if required */ |
| 1309 if ((floor(number) == 0) && | 1286 if ((floor(number) == 0) && |
| 1310 (format_info.integer_digits + format_info.frac_digits == 0)) { | 1287 (format_info.integer_digits + format_info.frac_digits == 0)) { |
| 1311 xmlBufferAdd(buffer, self->zeroDigit, xsltUTF8Size(self->zeroDigit)); | 1288 xmlBufferAdd(buffer, self->zeroDigit, xsltUTF8Size(self->zeroDigit)); |
| 1312 } | 1289 } |
| 1313 | 1290 |
| 1314 /* Next the fractional part, if required */ | 1291 /* Next the fractional part, if required */ |
| 1315 if (format_info.frac_digits + format_info.frac_hash == 0) { | 1292 if (format_info.frac_digits + format_info.frac_hash == 0) { |
| 1316 if (format_info.add_decimal) | 1293 if (format_info.add_decimal) |
| 1317 » xmlBufferAdd(buffer, self->decimalPoint, | 1294 » xmlBufferAdd(buffer, self->decimalPoint, |
| 1318 » » » xsltUTF8Size(self->decimalPoint)); | 1295 » » » xsltUTF8Size(self->decimalPoint)); |
| 1319 } | 1296 } |
| 1320 else { | 1297 else { |
| 1321 number -= floor(number); | 1298 number -= floor(number); |
| 1322 if ((number != 0) || (format_info.frac_digits != 0)) { | 1299 if ((number != 0) || (format_info.frac_digits != 0)) { |
| 1323 xmlBufferAdd(buffer, self->decimalPoint, | 1300 xmlBufferAdd(buffer, self->decimalPoint, |
| 1324 » » » xsltUTF8Size(self->decimalPoint)); | 1301 » » » xsltUTF8Size(self->decimalPoint)); |
| 1325 number = floor(scale * number + 0.5); | 1302 number = floor(scale * number + 0.5); |
| 1326 for (j = format_info.frac_hash; j > 0; j--) { | 1303 for (j = format_info.frac_hash; j > 0; j--) { |
| 1327 if (fmod(number, 10.0) >= 1.0) | 1304 if (fmod(number, 10.0) >= 1.0) |
| 1328 break; /* for */ | 1305 break; /* for */ |
| 1329 number /= 10.0; | 1306 number /= 10.0; |
| 1330 } | 1307 } |
| 1331 xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0], | 1308 xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0], |
| 1332 format_info.frac_digits + j, | 1309 format_info.frac_digits + j, |
| 1333 0, 0, 0); | 1310 0, 0, 0); |
| 1334 } | 1311 } |
| 1335 } | 1312 } |
| 1336 /* Put the suffix into the buffer */ | 1313 /* Put the suffix into the buffer */ |
| 1337 for (j = 0; j < suffix_length; j++) { | 1314 for (j = 0; j < suffix_length; j++) { |
| 1338 if ((pchar = *suffix++) == SYMBOL_QUOTE) { | 1315 if ((pchar = *suffix++) == SYMBOL_QUOTE) { |
| 1339 len = xsltUTF8Size(suffix); | 1316 len = xsltUTF8Size(suffix); |
| 1340 xmlBufferAdd(buffer, suffix, len); | 1317 xmlBufferAdd(buffer, suffix, len); |
| 1341 suffix += len; | 1318 suffix += len; |
| 1342 j += len - 1; /* length of symbol less length of escape */ | 1319 j += len - 1; /* length of symbol less length of escape */ |
| 1343 } else | 1320 } else |
| 1344 xmlBufferAdd(buffer, &pchar, 1); | 1321 xmlBufferAdd(buffer, &pchar, 1); |
| 1345 } | 1322 } |
| 1346 | 1323 |
| 1347 *result = xmlStrdup(xmlBufferContent(buffer)); | 1324 *result = xmlStrdup(xmlBufferContent(buffer)); |
| 1348 xmlBufferFree(buffer); | 1325 xmlBufferFree(buffer); |
| 1349 return status; | 1326 return status; |
| 1350 } | 1327 } |
| 1351 | 1328 |
| OLD | NEW |