Skip to content

Commit b6000b7

Browse files
committed
Add support for %h and %H in printf()
These are locale-independent variants of %g and %G. Closes phpGH-5436.
1 parent a01b6e5 commit b6000b7

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,11 @@ PHP 8.0 UPGRADE NOTES
535535
compile-time warnings and replay them on the next include, even if it is
536536
served from cache.
537537

538+
- Standard:
539+
. printf() and friends how support the %h and %H format specifiers. These
540+
are the same as %g and %G, but always use "." as the decimal separator,
541+
rather than determining it through the LC_NUMERIC locale.
542+
538543
- Zip:
539544
. Extension updated to version 1.19.0
540545
. New ZipArchive::lastId property to get index value of last added entry.

ext/standard/formatted_print.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -281,17 +281,25 @@ php_sprintf_appenddouble(zend_string **buffer, size_t *pos,
281281

282282
case 'g':
283283
case 'G':
284+
case 'h':
285+
case 'H':
286+
{
284287
if (precision == 0)
285288
precision = 1;
286-
/*
287-
* * We use &num_buf[ 1 ], so that we have room for the sign
288-
*/
289+
290+
char decimal_point = '.';
291+
if (fmt == 'g' || fmt == 'G') {
289292
#ifdef ZTS
290-
localeconv_r(&lconv);
293+
localeconv_r(&lconv);
291294
#else
292-
lconv = localeconv();
295+
lconv = localeconv();
293296
#endif
294-
s = php_gcvt(number, precision, LCONV_DECIMAL_POINT, (fmt == 'G')?'E':'e', &num_buf[1]);
297+
decimal_point = LCONV_DECIMAL_POINT;
298+
}
299+
300+
char exp_char = fmt == 'G' || fmt == 'H' ? 'E' : 'e';
301+
/* We use &num_buf[ 1 ], so that we have room for the sign. */
302+
s = php_gcvt(number, precision, decimal_point, exp_char, &num_buf[1]);
295303
is_negative = 0;
296304
if (*s == '-') {
297305
is_negative = 1;
@@ -303,6 +311,7 @@ php_sprintf_appenddouble(zend_string **buffer, size_t *pos,
303311

304312
s_len = strlen(s);
305313
break;
314+
}
306315
}
307316

308317
php_sprintf_appendstring(buffer, pos, s, width, 0, padding,
@@ -562,12 +571,14 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n
562571
width, padding, alignment);
563572
break;
564573

565-
case 'g':
566-
case 'G':
567574
case 'e':
568575
case 'E':
569576
case 'f':
570577
case 'F':
578+
case 'g':
579+
case 'G':
580+
case 'h':
581+
case 'H':
571582
php_sprintf_appenddouble(&result, &outpos,
572583
zval_get_double(tmp),
573584
width, padding, alignment,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
sprintf() %h and %H specifiers
3+
--SKIPIF--
4+
<?php
5+
if (!setlocale(LC_ALL, "de_DE.utf8")) die("skip de_DE.utf8 locale not available");
6+
?>
7+
--FILE--
8+
<?php
9+
10+
setlocale(LC_ALL, "de_DE.utf8");
11+
$f = 1.25;
12+
printf("%g %G %h %H\n", $f, $f, $f, $f);
13+
$f = 0.00000125;
14+
printf("%g %G %h %H\n", $f, $f, $f, $f);
15+
16+
?>
17+
--EXPECT--
18+
1,25 1,25 1.25 1.25
19+
1,25e-6 1,25E-6 1.25e-6 1.25E-6

0 commit comments

Comments
 (0)