aharvey                                  Fri, 03 Dec 2010 10:10:08 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=305937

Log:
Implement FR #53457 (number_format must support more than one character for
thousands separator).

Bug: http://bugs.php.net/53457 (Assigned) number_format must support more than 
one character for thousands separator
      
Changed paths:
    U   php/php-src/trunk/NEWS
    U   php/php-src/trunk/UPGRADING
    U   php/php-src/trunk/ext/standard/math.c
    U   php/php-src/trunk/ext/standard/php_math.h
    A   php/php-src/trunk/ext/standard/tests/math/number_format_multichar.phpt

Modified: php/php-src/trunk/NEWS
===================================================================
--- php/php-src/trunk/NEWS      2010-12-03 09:34:35 UTC (rev 305936)
+++ php/php-src/trunk/NEWS      2010-12-03 10:10:08 UTC (rev 305937)
@@ -112,6 +112,10 @@
     getallheaders(), apache_request_headers() and apache_response_headers()
   . Improved performance of FastCGI request parsing.

+- Improved core functions:
+  . number_format() no longer truncates multibyte decimal points and thousand
+    separators to the first byte. FR #53457. (Adam)
+
 - Improved CURL extension:
   . Added support for CURLOPT_MAX_RECV_SPEED_LARGE and
     CURLOPT_MAX_SEND_SPEED_LARGE. FR #51815. (Pierrick)

Modified: php/php-src/trunk/UPGRADING
===================================================================
--- php/php-src/trunk/UPGRADING 2010-12-03 09:34:35 UTC (rev 305936)
+++ php/php-src/trunk/UPGRADING 2010-12-03 10:10:08 UTC (rev 305937)
@@ -133,6 +133,8 @@
   behavior follows the recommendations of Unicode Technical Report #36.
 - htmlspecialchars_decode/html_entity_decode now decode ' if the document
   type is ENT_XML1, ENT_XHTML, or ENT_HTML5.
+- number_format() no longer truncates multibyte decimal points and thousand
+  separators to the first byte.
 - The third parameter ($matches) to preg_match_all() is now optional. If
   omitted, the function will simply return the number of times the pattern was
   matched in the subject and will have no other side effects.

Modified: php/php-src/trunk/ext/standard/math.c
===================================================================
--- php/php-src/trunk/ext/standard/math.c       2010-12-03 09:34:35 UTC (rev 
305936)
+++ php/php-src/trunk/ext/standard/math.c       2010-12-03 10:10:08 UTC (rev 
305937)
@@ -1082,6 +1082,11 @@
 */
 PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char 
thousand_sep)
 {
+       return _php_math_number_format_ex(d, dec, &dec_point, 1, &thousand_sep, 
1);
+}
+
+PHPAPI char *_php_math_number_format_ex(double d, int dec, char *dec_point, 
size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len)
+{
        char *tmpbuf = NULL, *resbuf;
        char *s, *t;  /* source, target */
        char *dp;
@@ -1121,7 +1126,7 @@

        /* allow for thousand separators */
        if (thousand_sep) {
-               integral += (integral-1) / 3;
+               integral += thousand_sep_len * ((integral-1) / 3);
        }

        reslen = integral;
@@ -1130,7 +1135,7 @@
                reslen += dec;

                if (dec_point) {
-                       reslen++;
+                       reslen += dec_point_len;
                }
        }

@@ -1166,7 +1171,8 @@

                /* add decimal point */
                if (dec_point) {
-                       *t-- = dec_point;
+                       t -= dec_point_len;
+                       memcpy(t + 1, dec_point, dec_point_len);
                }
        }

@@ -1175,7 +1181,8 @@
        while(s >= tmpbuf) {
                *t-- = *s--;
                if (thousand_sep && (++count%3)==0 && s>=tmpbuf) {
-                       *t-- = thousand_sep;
+                       t -= thousand_sep_len;
+                       memcpy(t + 1, thousand_sep, thousand_sep_len);
                }
        }

@@ -1212,21 +1219,17 @@
                RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, 
thousand_sep_chr), 0);
                break;
        case 4:
-               if (dec_point != NULL) {
-                       if (dec_point_len) {
-                               dec_point_chr = dec_point[0];
-                       } else {
-                               dec_point_chr = 0;
-                       }
+               if (dec_point == NULL) {
+                       dec_point = &dec_point_chr;
+                       dec_point_len = 1;
                }
-               if (thousand_sep != NULL) {
-                       if (thousand_sep_len) {
-                               thousand_sep_chr = thousand_sep[0];
-                       } else {
-                               thousand_sep_chr = 0;
-                       }
+
+               if (thousand_sep == NULL) {
+                       thousand_sep = &thousand_sep_chr;
+                       thousand_sep_len = 1;
                }
-               RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, 
thousand_sep_chr), 0);
+
+               RETURN_STRING(_php_math_number_format_ex(num, dec, dec_point, 
dec_point_len, thousand_sep, thousand_sep_len), 0);
                break;
        default:
                WRONG_PARAM_COUNT;

Modified: php/php-src/trunk/ext/standard/php_math.h
===================================================================
--- php/php-src/trunk/ext/standard/php_math.h   2010-12-03 09:34:35 UTC (rev 
305936)
+++ php/php-src/trunk/ext/standard/php_math.h   2010-12-03 10:10:08 UTC (rev 
305937)
@@ -22,7 +22,8 @@
 #ifndef PHP_MATH_H
 #define PHP_MATH_H

-PHPAPI char *_php_math_number_format(double, int, char , char);
+PHPAPI char *_php_math_number_format(double, int, char, char);
+PHPAPI char *_php_math_number_format_ex(double, int, char *, size_t, char *, 
size_t);
 PHPAPI char * _php_math_longtobase(zval *arg, int base);
 PHPAPI long _php_math_basetolong(zval *arg, int base);
 PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret);

Added: php/php-src/trunk/ext/standard/tests/math/number_format_multichar.phpt
===================================================================
--- php/php-src/trunk/ext/standard/tests/math/number_format_multichar.phpt      
                        (rev 0)
+++ php/php-src/trunk/ext/standard/tests/math/number_format_multichar.phpt      
2010-12-03 10:10:08 UTC (rev 305937)
@@ -0,0 +1,77 @@
+--TEST--
+Test number_format() - multiple character separator support
+--FILE--
+<?php
+$values = array(1234.5678,
+                               -1234.5678,
+                               1234.6578e4,
+                               -1234.56789e4,
+                               0x1234CDEF,
+                               02777777777,
+                               "123456789",
+                               "123.456789",
+                               "12.3456789e1",
+                               null,
+                               true,
+                               false);
+
+echo " number_format tests.....multiple character decimal point\n";
+for ($i = 0; $i < count($values); $i++) {
+       $res = number_format($values[$i], 2, '&#183;', ' ');
+       var_dump($res);
+}
+
+echo "\n number_format tests.....multiple character thousand separator\n";
+for ($i = 0; $i < count($values); $i++) {
+       $res = number_format($values[$i], 2, '.' , '&thinsp;');
+       var_dump($res);
+}
+
+echo "\n number_format tests.....multiple character decimal and thousep\n";
+for ($i = 0; $i < count($values); $i++) {
+       $res = number_format($values[$i], 2, '&#183;' , '&thinsp;');
+       var_dump($res);
+}
+?>
+--EXPECTF--
+ number_format tests.....multiple character decimal point
+string(13) "1 234&#183;57"
+string(14) "-1 234&#183;57"
+string(18) "12 346 578&#183;00"
+string(19) "-12 345 678&#183;90"
+string(19) "305 450 479&#183;00"
+string(19) "402 653 183&#183;00"
+string(19) "123 456 789&#183;00"
+string(11) "123&#183;46"
+string(11) "123&#183;46"
+string(9) "0&#183;00"
+string(9) "1&#183;00"
+string(9) "0&#183;00"
+
+ number_format tests.....multiple character thousand separator
+string(15) "1&thinsp;234.57"
+string(16) "-1&thinsp;234.57"
+string(27) "12&thinsp;346&thinsp;578.00"
+string(28) "-12&thinsp;345&thinsp;678.90"
+string(28) "305&thinsp;450&thinsp;479.00"
+string(28) "402&thinsp;653&thinsp;183.00"
+string(28) "123&thinsp;456&thinsp;789.00"
+string(6) "123.46"
+string(6) "123.46"
+string(4) "0.00"
+string(4) "1.00"
+string(4) "0.00"
+
+ number_format tests.....multiple character decimal and thousep
+string(20) "1&thinsp;234&#183;57"
+string(21) "-1&thinsp;234&#183;57"
+string(32) "12&thinsp;346&thinsp;578&#183;00"
+string(33) "-12&thinsp;345&thinsp;678&#183;90"
+string(33) "305&thinsp;450&thinsp;479&#183;00"
+string(33) "402&thinsp;653&thinsp;183&#183;00"
+string(33) "123&thinsp;456&thinsp;789&#183;00"
+string(11) "123&#183;46"
+string(11) "123&#183;46"
+string(9) "0&#183;00"
+string(9) "1&#183;00"
+string(9) "0&#183;00"

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to