Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(511)

Side by Side Diff: third_party/libxslt/libxslt/numbers.c

Issue 1193533007: Upgrade to libxml 2.9.2 and libxslt 1.1.28 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: to numbered version, update readme Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698