]> granicus.if.org Git - php/commitdiff
- make %f locale aware again
authorHannes Magnusson <bjori@php.net>
Mon, 18 Dec 2006 09:25:32 +0000 (09:25 +0000)
committerHannes Magnusson <bjori@php.net>
Mon, 18 Dec 2006 09:25:32 +0000 (09:25 +0000)
- fix precision loss with %F (noticed by Sebastian Nohn)
- add new tests

ext/standard/formatted_print.c
ext/standard/tests/strings/sprintf_f_2.phpt [new file with mode: 0755]
ext/standard/tests/strings/sprintf_f_3.phpt [new file with mode: 0755]
main/snprintf.c

index d3536397b3d9a3dba9d15205e15bf224524379a8..d9031841fe8ff31719a083a1e44944629e9e72a9 100644 (file)
@@ -222,15 +222,13 @@ php_sprintf_appenddouble(char **buffer, int *pos,
        }
 
        switch (fmt) {          
-               case 'F':
-                       fmt = 'f';
-                       /* break is missing */
                case 'e':
                        if (precision) {
                                precision--;
                        }
                case 'E':
                case 'f':
+               case 'F':
                        s = ap_php_conv_fp(fmt, number, 0, precision,
                                                &is_negative, &num_buf[1], &s_len);
                        if (is_negative) {
diff --git a/ext/standard/tests/strings/sprintf_f_2.phpt b/ext/standard/tests/strings/sprintf_f_2.phpt
new file mode 100755 (executable)
index 0000000..f79a234
--- /dev/null
@@ -0,0 +1,115 @@
+--TEST--
+sprintf #2
+--FILE--
+<?php
+var_dump(sprintf("%.3F", 100.426));
+var_dump(sprintf("%.2F", 100.426));
+var_dump(sprintf("%d",   100.426));
+var_dump(sprintf("%d",   100.9));
+var_dump(sprintf("%o",   100.426));
+var_dump(sprintf("%o",   100.9));
+
+/* copy & paste from the docs */
+
+/* example#1: Argument swapping */
+$num = 100.1;
+$location = "world";
+
+$format = 'There are %d monkeys in the %s';
+var_dump(sprintf($format, $num, $location));
+
+/* example#2: Argument swapping */
+$format = 'The %s contains %d monkeys';
+var_dump(sprintf($format, $num, $location));
+
+/* example#3: Argument swapping */
+$format = 'The %2$s contains %1$d monkeys';
+var_dump(sprintf($format, $num, $location));
+
+/* example#4: Argument swapping */
+$format = 'The %2$s contains %1$d monkeys.
+    That\'s a nice %2$s full of %1$d monkeys.';
+var_dump(sprintf($format, $num, $location));
+
+/* example#5: various examples */
+$n =  43951789;
+$u = -43951789;
+$c = 65; // ASCII 65 is 'A'
+
+// notice the double %%, this prints a literal '%' character
+var_dump(sprintf("%%b = '%b'", $n)); // binary representation
+var_dump(sprintf("%%c = '%c'", $c)); // print the ascii character, same as chr() function
+var_dump(sprintf("%%d = '%d'", $n)); // standard integer representation
+var_dump(sprintf("%%e = '%e'", $n)); // scientific notation
+var_dump(sprintf("%%u = '%u'", $n)); // unsigned integer representation of a positive integer
+var_dump(sprintf("%%u = '%u'", $u)); // unsigned integer representation of a negative integer
+var_dump(sprintf("%%f = '%f'", $n)); // floating point representation
+var_dump(sprintf("%%o = '%o'", $n)); // octal representation
+var_dump(sprintf("%%s = '%s'", $n)); // string representation
+var_dump(sprintf("%%x = '%x'", $n)); // hexadecimal representation (lower-case)
+var_dump(sprintf("%%X = '%X'", $n)); // hexadecimal representation (upper-case)
+
+var_dump(sprintf("%%+d = '%+d'", $n)); // sign specifier on a positive integer
+var_dump(sprintf("%%+d = '%+d'", $u)); // sign specifier on a negative integer
+
+
+/* example#6: string specifiers */
+$s = 'monkey';
+$t = 'many monkeys';
+
+var_dump(sprintf("[%s]",      $s)); // standard string output
+var_dump(sprintf("[%10s]",    $s)); // right-justification with spaces
+var_dump(sprintf("[%-10s]",   $s)); // left-justification with spaces
+var_dump(sprintf("[%010s]",   $s)); // zero-padding works on strings too
+var_dump(sprintf("[%'#10s]",  $s)); // use the custom padding character '#'
+var_dump(sprintf("[%10.10s]", $t)); // left-justification but with a cutoff of 10 characters
+
+/* example#7: zero-padded integers */
+var_dump(sprintf("%04d-%02d-%02d", 2006, 12, 18));
+
+/* example#8: formatting currency */
+$money1 = 68.75;
+$money2 = 54.35;
+$money = $money1 + $money2;
+var_dump(sprintf("%01.2f", $money)); // output "123.10"
+
+/* example#9: scientific notation */
+$number = 362525200;
+var_dump(sprintf("%.3e", $number)); // outputs 3.63e+8
+?>
+--EXPECT--
+
+string(7) "100.426"
+string(6) "100.43"
+string(3) "100"
+string(3) "100"
+string(3) "144"
+string(3) "144"
+string(34) "There are 100 monkeys in the world"
+string(28) "The 100.1 contains 0 monkeys"
+string(30) "The world contains 100 monkeys"
+string(76) "The world contains 100 monkeys.
+    That's a nice world full of 100 monkeys."
+string(33) "%b = '10100111101010011010101101'"
+string(8) "%c = 'A'"
+string(15) "%d = '43951789'"
+string(17) "%e = '4.39518e+7'"
+string(15) "%u = '43951789'"
+string(17) "%u = '4251015507'"
+string(22) "%f = '43951789.000000'"
+string(16) "%o = '247523255'"
+string(15) "%s = '43951789'"
+string(14) "%x = '29ea6ad'"
+string(14) "%X = '29EA6AD'"
+string(17) "%+d = '+43951789'"
+string(17) "%+d = '-43951789'"
+string(8) "[monkey]"
+string(12) "[    monkey]"
+string(12) "[monkey    ]"
+string(12) "[0000monkey]"
+string(12) "[####monkey]"
+string(12) "[many monke]"
+string(10) "2006-12-18"
+string(6) "123.10"
+string(7) "3.63e+8"
diff --git a/ext/standard/tests/strings/sprintf_f_3.phpt b/ext/standard/tests/strings/sprintf_f_3.phpt
new file mode 100755 (executable)
index 0000000..1db2214
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+sprintf #2
+--INI--
+error_reporting=6143
+--SKIPIF--
+<?php if(false == setlocale(LC_NUMERIC, "is_IS", "is_IS.UTF-8")) print "skip icelandic locale not supported"; ?>
+--FILE--
+<?php
+setlocale(LC_NUMERIC, "is_IS", "is_IS.UTF-8");
+var_dump(sprintf("%.3f", 100.426));
+var_dump(sprintf("%.2f", 100.426));
+var_dump(sprintf("%f'",  100.426));
+
+$money1 = 68.75;
+$money2 = 54.35;
+$money = $money1 + $money2;
+var_dump(sprintf("%01.2f", $money));
+var_dump(sprintf("%.3e", $money));
+?>
+--EXPECT--
+string(7) "100,426"
+string(6) "100,43"
+string(11) "100,426000'"
+string(6) "123,10"
+string(7) "1.23e+2"
index 3dd2ebf93fff62d50d0e8f7f079abe3ee779b17e..30f99c575b4a3748f5d1c18974407efa89563c68 100644 (file)
@@ -363,12 +363,20 @@ char * ap_php_conv_fp(register char format, register double num,
        register char *s = buf;
        register char *p, *p_orig;
        int decimal_point;
+       char dec_point = '.';
+
+       if (format == 'f') {
+               struct lconv *lconv;
+               lconv = localeconv();
+               dec_point = *lconv->decimal_point;
+               format = 'F';
+       }
 
        if (precision >= NDIG - 1) {
                precision = NDIG - 2;
        }
 
-       if (format == 'f')
+       if (format == 'F')
                p_orig = p = bsd_fcvt(num, precision, &decimal_point, is_negative);
        else                                            /* either e or E format */
                p_orig = p = bsd_ecvt(num, precision + 1, &decimal_point, is_negative);
@@ -383,16 +391,16 @@ char * ap_php_conv_fp(register char format, register double num,
                free(p_orig);
                return (buf);
        }
-       if (format == 'f') {
+       if (format == 'F') {
                if (decimal_point <= 0) {
                        if (num != 0 || precision > 0) {
                                *s++ = '0';
                                if (precision > 0) {
-                                       *s++ = '.';
+                                       *s++ = dec_point;
                                        while (decimal_point++ < 0)
                                                *s++ = '0';
                                } else if (add_dp) {
-                                       *s++ = '.';
+                                       *s++ = dec_point;
                                }
                        }
                } else {
@@ -405,7 +413,7 @@ char * ap_php_conv_fp(register char format, register double num,
                                *s++ = '0';
                        }
                        if (precision > 0 || add_dp) {
-                               *s++ = '.';
+                               *s++ = dec_point;
                        }
                }
        } else {
@@ -420,7 +428,7 @@ char * ap_php_conv_fp(register char format, register double num,
        while (*p)
                *s++ = *p++;
 
-       if (format != 'f') {
+       if (format != 'F') {
                char temp[EXPONENT_LENGTH];             /* for exponent conversion */
                int t_len;
                bool_int exponent_is_negative;