diff options
author | Dmitry Stogov <dmitry@php.net> | 2006-12-19 11:54:38 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2006-12-19 11:54:38 +0000 |
commit | c43fc2afc8fbd3e1fe6a86ac29f8ff81febe79f0 (patch) | |
tree | d6c3c4d229c933050bc8c936c8834a18d964f360 /main/snprintf.c | |
parent | 39a7719f859a0a01b7f8fa47c35df77901e25ef0 (diff) | |
download | php-git-c43fc2afc8fbd3e1fe6a86ac29f8ff81febe79f0.tar.gz |
Fixed bug #39815 (SOAP double encoding is not locale-independent)
Diffstat (limited to 'main/snprintf.c')
-rw-r--r-- | main/snprintf.c | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/main/snprintf.c b/main/snprintf.c index 28ff0f3231..6f07022383 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -115,23 +115,20 @@ static char * __cvt(double value, int ndigit, int *decpt, int *sign, int fmode, return(s); } -char *bsd_ecvt(double value, int ndigit, int *decpt, int *sign) +static inline char *php_ecvt(double value, int ndigit, int *decpt, int *sign) { return(__cvt(value, ndigit, decpt, sign, 0, 1)); } -char *bsd_fcvt(double value, int ndigit, int *decpt, int *sign) +static inline char *php_fcvt(double value, int ndigit, int *decpt, int *sign) { return(__cvt(value, ndigit, decpt, sign, 1, 1)); } -char *bsd_gcvt(double value, int ndigit, char *buf) +PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf) { char *digits, *dst, *src; int i, decpt, sign; - struct lconv *lconv; - - lconv = localeconv(); digits = zend_dtoa(value, 2, ndigit, &decpt, &sign, NULL); if (decpt == 9999) { @@ -161,7 +158,7 @@ char *bsd_gcvt(double value, int ndigit, char *buf) sign = 0; src = digits; *dst++ = *src++; - *dst++ = *lconv->decimal_point; + *dst++ = dec_point; if (*src == '\0') { *dst++ = '0'; } else { @@ -169,7 +166,7 @@ char *bsd_gcvt(double value, int ndigit, char *buf) *dst++ = *src++; } while (*src != '\0'); } - *dst++ = 'e'; + *dst++ = exponent; if (sign) *dst++ = '-'; else @@ -190,7 +187,7 @@ char *bsd_gcvt(double value, int ndigit, char *buf) } else if (decpt < 0) { /* standard format 0. */ *dst++ = '0'; /* zero before decimal point */ - *dst++ = *lconv->decimal_point; + *dst++ = dec_point; do { *dst++ = '0'; } while (++decpt < 0); @@ -210,7 +207,7 @@ char *bsd_gcvt(double value, int ndigit, char *buf) if (*src != '\0') { if (src == digits) *dst++ = '0'; /* zero before decimal point */ - *dst++ = *lconv->decimal_point; + *dst++ = dec_point; for (i = decpt; digits[i] != '\0'; i++) { *dst++ = digits[i]; } @@ -357,29 +354,21 @@ char * ap_php_conv_10(register wide_int num, register bool_int is_unsigned, * The sign is returned in the is_negative argument (and is not placed * in buf). */ -char * ap_php_conv_fp(register char format, register double num, - boolean_e add_dp, int precision, bool_int * is_negative, char *buf, int *len) +PHPAPI char * php_conv_fp(register char format, register double num, + boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, int *len) { 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') - p_orig = p = bsd_fcvt(num, precision, &decimal_point, is_negative); + p_orig = p = php_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); + p_orig = p = php_ecvt(num, precision + 1, &decimal_point, is_negative); /* * Check for Infinity and NaN @@ -595,6 +584,8 @@ static int format_converter(register buffy * odp, const char *fmt, char num_buf[NUM_BUF_SIZE]; char char_buf[2]; /* for printing %% and %<unknown> */ + struct lconv *lconv = NULL; + /* * Flag variables */ @@ -930,6 +921,7 @@ static int format_converter(register buffy * odp, const char *fmt, case 'f': + case 'F': case 'e': case 'E': switch(modifier) { @@ -950,8 +942,12 @@ static int format_converter(register buffy * odp, const char *fmt, s = "inf"; s_len = 3; } else { - s = ap_php_conv_fp(*fmt, fp_num, alternate_form, + if (!lconv) { + lconv = localeconv(); + } + s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form, (adjust_precision == NO) ? FLOAT_DIGITS : precision, + (*fmt == 'f')?(*lconv->decimal_point):'.', &is_negative, &num_buf[1], &s_len); if (is_negative) prefix_char = '-'; @@ -998,7 +994,10 @@ static int format_converter(register buffy * odp, const char *fmt, /* * * We use &num_buf[ 1 ], so that we have room for the sign */ - s = bsd_gcvt(fp_num, precision, &num_buf[1]); + if (!lconv) { + lconv = localeconv(); + } + s = php_gcvt(fp_num, precision, *lconv->decimal_point, (*fmt == 'G')?'E':'e', &num_buf[1]); if (*s == '-') prefix_char = *s++; else if (print_sign) @@ -1010,8 +1009,6 @@ static int format_converter(register buffy * odp, const char *fmt, if (alternate_form && (q = strchr(s, '.')) == NULL) s[s_len++] = '.'; - if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL) - *q = 'E'; break; |