- Fixed bug #30630: Added a BSD based strtod function that is

locale-independent. (PHP part)
This commit is contained in:
Derick Rethans 2004-11-03 23:36:51 +00:00
parent dbf2c8abd5
commit 59651c4e58
8 changed files with 36 additions and 20 deletions

View File

@ -1280,7 +1280,7 @@ PHP_ADD_SOURCES(Zend, \
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c)
zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c)
if test -r "$abs_srcdir/Zend/zend_objects.c"; then
PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \

View File

@ -23,6 +23,7 @@
#include "php_soap.h"
#include "ext/libxml/php_libxml.h"
#include "zend_strtod.h"
/* zval type decode */
static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data);
@ -685,7 +686,7 @@ static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data)
errno = 0;
ret->value.lval = strtol(data->children->content, NULL, 0);
if (errno == ERANGE) { /* overflow */
ret->value.dval = strtod(data->children->content, NULL);
ret->value.dval = zend_strtod(data->children->content, NULL);
ret->type = IS_DOUBLE;
} else {
ret->type = IS_LONG;

View File

@ -303,7 +303,14 @@ php_sprintf_appenddouble(char **buffer, int *pos,
char *cvt;
register int i = 0, j = 0;
int sign, decpt, cvt_len;
char decimal_point = EG(float_separator)[0];
#ifdef HAVE_LOCALE_H
struct lconv lc;
char decimal_point;
localeconv_r(&lc);
decimal_point = (lc.decimal_point)[0];
#else
char decimal_point = '.';
#endif
PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n",
*buffer, pos, size, number, width, padding, alignment, fmt));

View File

@ -112,7 +112,7 @@ PHP_MINIT_FUNCTION(nl_langinfo);
PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case);
#ifdef HAVE_LOCALECONV
struct lconv *localeconv_r(struct lconv *out);
PHPAPI struct lconv *localeconv_r(struct lconv *out);
#endif
PHPAPI char *php_strtoupper(char *s, size_t len);

View File

@ -78,6 +78,7 @@
#endif
#include "zend_execute.h"
#include "zend_operators.h"
#include "zend_strtod.h"
#include "php_globals.h"
#include "basic_functions.h"
#include "scanf.h"
@ -1204,7 +1205,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format,
if (!(flags & SCAN_SUPPRESS)) {
double dvalue;
*end = '\0';
dvalue = strtod(buf, NULL);
dvalue = zend_strtod(buf, NULL);
if (numVars) {
current = args[objIndex++];
convert_to_double( *current );

View File

@ -136,7 +136,7 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *
#ifdef HAVE_LOCALECONV
/* {{{ localeconv_r
* glibc's localeconv is not reentrant, so lets make it so ... sorta */
struct lconv *localeconv_r(struct lconv *out)
PHPAPI struct lconv *localeconv_r(struct lconv *out)
{
struct lconv *res;
@ -3793,18 +3793,6 @@ PHP_FUNCTION(setlocale)
efree(args);
RETVAL_STRING(retval, 1);
if (cat == LC_NUMERIC || cat == LC_ALL) {
struct lconv lc;
localeconv_r(&lc);
EG(float_separator)[0] = (lc.decimal_point)[0];
if ((lc.decimal_point)[0] != '.') {
/* set locale back to C */
setlocale(LC_NUMERIC, "C");
}
}
return;
}

View File

@ -1,5 +1,5 @@
--TEST--
Locale settings affecting float parsing
Bug #12647 (Locale settings affecting float parsing)
--SKIPIF--
<?php # try to activate a german locale
if (setlocale(LC_NUMERIC, "de_DE", "de", "german", "ge") === FALSE) {
@ -12,7 +12,6 @@ if (setlocale(LC_NUMERIC, "de_DE", "de", "german", "ge") === FALSE) {
setlocale(LC_NUMERIC, "de_DE", "de", "german", "ge");
echo (float)"3.14", "\n";
?>
--EXPECT--
3,14

20
tests/lang/bug30638.phpt Normal file
View File

@ -0,0 +1,20 @@
--TEST--
Bug #30638 (localeconv returns wrong LC_NUMERIC settings)
--SKIPIF--
<?php # try to activate a german locale
if (setlocale(LC_NUMERIC, "de_DE", "de", "german", "ge") === FALSE) {
print "skip";
}
?>
--FILE--
<?php
# activate the german locale
setlocale(LC_NUMERIC, "de_DE", "de", "german", "ge");
$lc = localeconv();
printf("decimal_point: %s\n", $lc['decimal_point']);
printf("thousands_sep: %s\n", $lc['thousands_sep']);
?>
--EXPECT--
decimal_point: ,
thousands_sep: .