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 |