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, '·', ' '); + 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, '.' , ' '); + 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, '·' , ' '); + var_dump($res); +} +?> +--EXPECTF-- + number_format tests.....multiple character decimal point +string(13) "1 234·57" +string(14) "-1 234·57" +string(18) "12 346 578·00" +string(19) "-12 345 678·90" +string(19) "305 450 479·00" +string(19) "402 653 183·00" +string(19) "123 456 789·00" +string(11) "123·46" +string(11) "123·46" +string(9) "0·00" +string(9) "1·00" +string(9) "0·00" + + number_format tests.....multiple character thousand separator +string(15) "1 234.57" +string(16) "-1 234.57" +string(27) "12 346 578.00" +string(28) "-12 345 678.90" +string(28) "305 450 479.00" +string(28) "402 653 183.00" +string(28) "123 456 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 234·57" +string(21) "-1 234·57" +string(32) "12 346 578·00" +string(33) "-12 345 678·90" +string(33) "305 450 479·00" +string(33) "402 653 183·00" +string(33) "123 456 789·00" +string(11) "123·46" +string(11) "123·46" +string(9) "0·00" +string(9) "1·00" +string(9) "0·00"
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php