* libc/stdio/vfprintf.c (_VFPRINTF_R): Use actual length of
radix char instead of assuming length 1. * libc/stdlib/gdtoa-gethex.c: Remove use of USE_LOCALE. (gethex): Allow multibyte decimal point. Fix compiler warnings due to different signedness of pointer types. * libc/stdlib/strtod.c: Remove use of USE_LOCALE. (_strtod_r): Allow multibyte decimal point. * libc/stdlib/wcstod.c (_wcstod_r): Evaluate correct wide char endptr position if the decimal point is a multibyte char.
This commit is contained in:
parent
1a99b6f85a
commit
1c5e84dd08
@ -1,3 +1,15 @@
|
|||||||
|
2009-06-16 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* libc/stdio/vfprintf.c (_VFPRINTF_R): Use actual length of
|
||||||
|
radix char instead of assuming length 1.
|
||||||
|
* libc/stdlib/gdtoa-gethex.c: Remove use of USE_LOCALE.
|
||||||
|
(gethex): Allow multibyte decimal point.
|
||||||
|
Fix compiler warnings due to different signedness of pointer types.
|
||||||
|
* libc/stdlib/strtod.c: Remove use of USE_LOCALE.
|
||||||
|
(_strtod_r): Allow multibyte decimal point.
|
||||||
|
* libc/stdlib/wcstod.c (_wcstod_r): Evaluate correct wide char
|
||||||
|
endptr position if the decimal point is a multibyte char.
|
||||||
|
|
||||||
2009-06-16 Craig Howland <howland@LGSInnovations.com>
|
2009-06-16 Craig Howland <howland@LGSInnovations.com>
|
||||||
|
|
||||||
* libc/ctype/local.h (__locale_charset): Add arguments to
|
* libc/ctype/local.h (__locale_charset): Add arguments to
|
||||||
|
@ -553,6 +553,7 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
|
|||||||
char sign; /* sign prefix (' ', '+', '-', or \0) */
|
char sign; /* sign prefix (' ', '+', '-', or \0) */
|
||||||
#ifdef FLOATING_POINT
|
#ifdef FLOATING_POINT
|
||||||
char *decimal_point = _localeconv_r (data)->decimal_point;
|
char *decimal_point = _localeconv_r (data)->decimal_point;
|
||||||
|
size_t decp_len = strlen (decimal_point);
|
||||||
char softsign; /* temporary negative sign for floats */
|
char softsign; /* temporary negative sign for floats */
|
||||||
union { int i; _PRINTF_FLOAT_TYPE fp; } _double_ = {0};
|
union { int i; _PRINTF_FLOAT_TYPE fp; } _double_ = {0};
|
||||||
# define _fpvalue (_double_.fp)
|
# define _fpvalue (_double_.fp)
|
||||||
@ -1441,13 +1442,13 @@ number: if ((dprec = prec) >= 0)
|
|||||||
/* kludge for __dtoa irregularity */
|
/* kludge for __dtoa irregularity */
|
||||||
PRINT ("0", 1);
|
PRINT ("0", 1);
|
||||||
if (expt < ndig || flags & ALT) {
|
if (expt < ndig || flags & ALT) {
|
||||||
PRINT (decimal_point, 1);
|
PRINT (decimal_point, decp_len);
|
||||||
PAD (ndig - 1, zeroes);
|
PAD (ndig - 1, zeroes);
|
||||||
}
|
}
|
||||||
} else if (expt <= 0) {
|
} else if (expt <= 0) {
|
||||||
PRINT ("0", 1);
|
PRINT ("0", 1);
|
||||||
if (expt || ndig || flags & ALT) {
|
if (expt || ndig || flags & ALT) {
|
||||||
PRINT (decimal_point, 1);
|
PRINT (decimal_point, decp_len);
|
||||||
PAD (-expt, zeroes);
|
PAD (-expt, zeroes);
|
||||||
PRINT (cp, ndig);
|
PRINT (cp, ndig);
|
||||||
}
|
}
|
||||||
@ -1455,18 +1456,18 @@ number: if ((dprec = prec) >= 0)
|
|||||||
PRINT (cp, ndig);
|
PRINT (cp, ndig);
|
||||||
PAD (expt - ndig, zeroes);
|
PAD (expt - ndig, zeroes);
|
||||||
if (flags & ALT)
|
if (flags & ALT)
|
||||||
PRINT (decimal_point, 1);
|
PRINT (decimal_point, decp_len);
|
||||||
} else {
|
} else {
|
||||||
PRINT (cp, expt);
|
PRINT (cp, expt);
|
||||||
cp += expt;
|
cp += expt;
|
||||||
PRINT (decimal_point, 1);
|
PRINT (decimal_point, decp_len);
|
||||||
PRINT (cp, ndig - expt);
|
PRINT (cp, ndig - expt);
|
||||||
}
|
}
|
||||||
} else { /* 'a', 'A', 'e', or 'E' */
|
} else { /* 'a', 'A', 'e', or 'E' */
|
||||||
if (ndig > 1 || flags & ALT) {
|
if (ndig > 1 || flags & ALT) {
|
||||||
PRINT (cp, 1);
|
PRINT (cp, 1);
|
||||||
cp++;
|
cp++;
|
||||||
PRINT (decimal_point, 1);
|
PRINT (decimal_point, decp_len);
|
||||||
if (_fpvalue) {
|
if (_fpvalue) {
|
||||||
PRINT (cp, ndig - 1);
|
PRINT (cp, ndig - 1);
|
||||||
} else /* 0.[0..] */
|
} else /* 0.[0..] */
|
||||||
|
@ -35,10 +35,7 @@ THIS SOFTWARE.
|
|||||||
#include "mprec.h"
|
#include "mprec.h"
|
||||||
#include "gdtoa.h"
|
#include "gdtoa.h"
|
||||||
#include "gd_qnan.h"
|
#include "gd_qnan.h"
|
||||||
|
|
||||||
#ifdef USE_LOCALE
|
|
||||||
#include "locale.h"
|
#include "locale.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned char hexdig[256];
|
unsigned char hexdig[256];
|
||||||
|
|
||||||
@ -151,11 +148,10 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, sign),
|
|||||||
int esign, havedig, irv, k, n, nbits, up, zret;
|
int esign, havedig, irv, k, n, nbits, up, zret;
|
||||||
__ULong L, lostbits, *x;
|
__ULong L, lostbits, *x;
|
||||||
Long e, e1;
|
Long e, e1;
|
||||||
#ifdef USE_LOCALE
|
unsigned char *decimalpoint = (unsigned char *)
|
||||||
unsigned char decimalpoint = *localeconv()->decimal_point;
|
_localeconv_r (ptr)->decimal_point;
|
||||||
#else
|
size_t decp_len = strlen ((const char *) decimalpoint);
|
||||||
#define decimalpoint '.'
|
unsigned char decp_end = decimalpoint[decp_len - 1];
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!hexdig['0'])
|
if (!hexdig['0'])
|
||||||
hexdig_init();
|
hexdig_init();
|
||||||
@ -170,9 +166,10 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, sign),
|
|||||||
e = 0;
|
e = 0;
|
||||||
if (!hexdig[*s]) {
|
if (!hexdig[*s]) {
|
||||||
zret = 1;
|
zret = 1;
|
||||||
if (*s != decimalpoint)
|
if (strncmp ((const char *) s, (const char *) decimalpoint,
|
||||||
|
decp_len) != 0)
|
||||||
goto pcheck;
|
goto pcheck;
|
||||||
decpt = ++s;
|
decpt = (s += decp_len);
|
||||||
if (!hexdig[*s])
|
if (!hexdig[*s])
|
||||||
goto pcheck;
|
goto pcheck;
|
||||||
while(*s == '0')
|
while(*s == '0')
|
||||||
@ -184,8 +181,10 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, sign),
|
|||||||
}
|
}
|
||||||
while(hexdig[*s])
|
while(hexdig[*s])
|
||||||
s++;
|
s++;
|
||||||
if (*s == decimalpoint && !decpt) {
|
if (strncmp ((const char *) s, (const char *) decimalpoint,
|
||||||
decpt = ++s;
|
decp_len) == 0
|
||||||
|
&& !decpt) {
|
||||||
|
decpt = (s += decp_len);
|
||||||
while(hexdig[*s])
|
while(hexdig[*s])
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
@ -226,8 +225,12 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, sign),
|
|||||||
n = 0;
|
n = 0;
|
||||||
L = 0;
|
L = 0;
|
||||||
while(s1 > s0) {
|
while(s1 > s0) {
|
||||||
if (*--s1 == decimalpoint)
|
if (*--s1 == decp_end && s1 - decp_len + 1 >= s0
|
||||||
|
&& strncmp ((const char *) s1 - decp_len + 1,
|
||||||
|
(const char *) decimalpoint, decp_len) == 0) {
|
||||||
|
s1 -= decp_len - 1; /* Note the --s1 above! */
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (n == 32) {
|
if (n == 32) {
|
||||||
*x++ = L;
|
*x++ = L;
|
||||||
L = 0;
|
L = 0;
|
||||||
|
@ -122,9 +122,7 @@ THIS SOFTWARE.
|
|||||||
/* #include <fenv.h> */
|
/* #include <fenv.h> */
|
||||||
/* #endif */
|
/* #endif */
|
||||||
|
|
||||||
#ifdef USE_LOCALE
|
|
||||||
#include "locale.h"
|
#include "locale.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IEEE_Arith
|
#ifdef IEEE_Arith
|
||||||
#ifndef NO_IEEE_Scale
|
#ifndef NO_IEEE_Scale
|
||||||
@ -307,14 +305,11 @@ _DEFUN (_strtod_r, (ptr, s00, se),
|
|||||||
else if (nd < 16)
|
else if (nd < 16)
|
||||||
z = 10*z + c - '0';
|
z = 10*z + c - '0';
|
||||||
nd0 = nd;
|
nd0 = nd;
|
||||||
#ifdef USE_LOCALE
|
if (strncmp (s, _localeconv_r (ptr)->decimal_point,
|
||||||
if (c == *localeconv()->decimal_point)
|
strlen (_localeconv_r (ptr)->decimal_point)) == 0)
|
||||||
#else
|
|
||||||
if (c == '.')
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
decpt = 1;
|
decpt = 1;
|
||||||
c = *++s;
|
c = *(s += strlen (_localeconv_r (ptr)->decimal_point));
|
||||||
if (!nd) {
|
if (!nd) {
|
||||||
for(; c == '0'; c = *++s)
|
for(; c == '0'; c = *++s)
|
||||||
nz++;
|
nz++;
|
||||||
|
@ -116,8 +116,10 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
|
|||||||
#include <_ansi.h>
|
#include <_ansi.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
#include <locale.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
double
|
double
|
||||||
@ -167,9 +169,26 @@ _DEFUN (_wcstod_r, (ptr, nptr, endptr),
|
|||||||
* where it ended, count multibyte characters to find the
|
* where it ended, count multibyte characters to find the
|
||||||
* corresponding position in the wide char string.
|
* corresponding position in the wide char string.
|
||||||
*/
|
*/
|
||||||
if (endptr != NULL)
|
if (endptr != NULL) {
|
||||||
/* XXX Assume each wide char is one byte. */
|
/* The only valid multibyte char in a float converted by
|
||||||
|
strtod/wcstod is the radix char. What we do here is,
|
||||||
|
figure out if the radix char was in the valid leading
|
||||||
|
float sequence in the incoming string. If so, the
|
||||||
|
multibyte float string is strlen(radix char) - 1 bytes
|
||||||
|
longer than the incoming wide char string has characters.
|
||||||
|
To fix endptr, reposition end as if the radix char was
|
||||||
|
just one byte long. The resulting difference (end - buf)
|
||||||
|
is then equivalent to the number of valid wide characters
|
||||||
|
in the input string. */
|
||||||
|
len = strlen (_localeconv_r (ptr)->decimal_point);
|
||||||
|
if (len > 1) {
|
||||||
|
char *d = strstr (buf,
|
||||||
|
_localeconv_r (ptr)->decimal_point);
|
||||||
|
if (d && d < end)
|
||||||
|
end -= len - 1;
|
||||||
|
}
|
||||||
*endptr = (wchar_t *)nptr + (end - buf);
|
*endptr = (wchar_t *)nptr + (end - buf);
|
||||||
|
}
|
||||||
|
|
||||||
_free_r(ptr, buf);
|
_free_r(ptr, buf);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user