mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Wed May 1 09:10:04 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* time/strftime.c: Use canonical autoconf nugget for time.h+sys/time.h include. Mon Apr 29 02:48:26 1996 Ulrich Drepper <drepper@cygnus.com> * ctype/ctype-info.c: (__ctype_width): New variable. (__ctype_names): Initialize correctly without offset. * locale/C-collate.c, locale/C-ctype.c, locale/C-messages.c, locale/C-monetary.c, locale/C-numeric.c, locale/C-time.c: Change copyright. * locale/C-ctype.c (_nl_C_LC_CTYPE_class32): Correct endianess for initialization value. * locale/lc-ctype.c (current): Add parameter for offset. (__ctype32_b, __ctype_width): Add initialization for these variables. * locale/programs/charmap.c: Finish support for WIDTH information. (new_width): New function. * locale/programs/charset.h (width_rule): new data structure. (charset_t): Add elements for width information. * locale/programs/ld-ctype.c (locale_ctype_t): Add element for width information. (allocate_arrays): Add new argument for charset. (ctype_finish): Make sure all characters named in charset width table are known to name table. (ctype_output): Correct handling of class and map name information and write out width information. (find_idx): Prepare for being called with NULL pointer as TABLE argument. This means only allocate name entry. (allocate_arrays): Correct handling of array element -1. Because EOF == -1 the value of element 127 must *not* be mirrored here. Fill width information from charset tables. * locale/programs/localedef.c (main): Correct loop over all categories after change of order from Thu Mar 28 14:22:51 1996. Add new charset argument to call of `write_all_categories'. * locale/programs/locales.h (ctype_finish, ctype_output): New charset argument. * locale/programs/locfile.c (write_all_categories): Call `ctype_output' with additional argument charset. * posix/getconf.c (vars): Add _POSIX_SYNC_IO, _POSIX_ASYNC_IO, and _POSIX_PRIO_IO definitions. * posix/posix2_lim.h: Add definition of _POSIX2_CHARCLASS_NAME_MAX and CHARCLASS_NAME_MAX. * posix/unistd.h: Document _POSIX_SYNC_IO, _POSIX_ASYNC_IO, and _POSIX_PRIO_IO. * stdlib/grouping.h: Prepare for use in wide string functions. * stdlib/stdlib.h: Correct prototypes for __strto*_internal functions. * stdlib/strtod.c: Extend for use as `wcsto{f,d,ld}'. * stdlib/strtol.c: Extend for use as `wcsto{l,ul,q,uq}'. * string/strcoll.c: Extend for use as `wcscoll'. * string/strxfrm.c: Extend for use as `wcsxfrm'. * sysdeps/generic/confname.h: Add definition of _PC_SYNC_IO, _PC_ASYNC_IO, _PC_PRIO_IO and _SC_CHARCLASS_NAME_MAX. * sysdeps/generic/stpncpy.c: Correct return value. * sysdeps/posix/fpathconf.c: Add handling of _PC_SYNC_IO, _PC_ASYNC_IO, and _PC_PRIO_IO. * sysdeps/posix/sysconf.c: Add handling of _SC_REALTIME_SIGNALS, _SC_PRIORITY_SCHEDULING, _SC_TIMERS, _SC_ASYNCHRONOUS_IO, _SC_PRIORITIZED_IO, _SC_SYNCHRONIZED_IO, _SC_FSYNC, _SC_MAPPED_FILES, _SC_MEMLOCK, _SC_MEMLOCK_RANGE, _SC_MEMORY_PROTECTION, _SC_MESSAGE_PASSING, _SC_SEMAPHORES, _SC_SHARED_MEMORY_OBJECTS, and _SC_CHARCLASS_NAME_MAX. * sysdeps/stub/sysconf.c: Ditto. * sysdeps/unix/sysv/sysv4/sysconf.c: Ditto. * sysdeps/unix/sysv/linux/Dist: Add sys/sysctl.h. * sysdeps/unix/sysv/linux/Makefile [subdir == misc] (sysdep_routines): Add s_sysctl and sysctl. * sysdeps/unix/sysv/linux/sys/mman.h: Add declaration of mremap. * sysdeps/unix/sysv/linux/sys/socket.h: New file. Wrapper around kernel header. * sysdeps/unix/sysv/linux/sys/sysctl.h: New file. Define interface to `sysctl' function. * sysdeps/unix/sysv/linux/syscalls.list: Add mremap and _sysctl. * sysdeps/unix/sysv/linux/sysconf.c: Add handling of _SC_CHARCLASS_NAME_MAX. * sysdeps/unix/sysv/linux/sysctl.c: new file. Implement caller of _sysctl system call. * sysvipc/Makefile (routines): Add ftok. * sysvipc/ftok.c: use variable `proj_id' not `id'. Patch by David Mosberger-Tang. * wcsmbs/Makefile (routines): Add wcpcpy, wcpncpy, wcstol, wcstoul, wcstoq, wcstouq, wcstod, wcstold, wcstof, wcscoll, wcsxfrm, wcwidth, and wcswidth. * wcsmbs/wchar.h: Add declarations for wcpcpy, wcpncpy, wcstol, wcstoul, wcstoq, wcstouq, wcstod, wcstold, wcstof, wcscoll, wcsxfrm, wcwidth, and wcswidth. Declare internal interfaces for wcsto* functions. [OPTIMIZE]: Define inline functions for wcsto* functions to call internal interface functions. * wcsmbs/wcpcpy.c, wcsmbs/wcpncpy.c: New files. Implement non- standard function equivalent to stpcpy/stpncpy. * wcsmbs/wcscoll.c: Implement `wcscoll' function by using `strcoll' implementation. * wcsmbs/wcscpy.c, wcsmbs/wcsncpy.c: Use wint_t instead of wchar_t. * wcsmbs/wcstod.c: Implement `wcstod' function by using `strtod' implementation. * wcsmbs/wcstof.c: Same for `wcstof'. * wcsmbs/wcstold.c: Same for `strtold'. * wcsmbs/wcstol.c: Implement `wcstol' function by using `strtol' implementation. * wcsmbs/wcstoq.c: Same for `wcstoq'. * wcsmbs/wcstoul.c: Same for `wcstoul'. * wcsmbs/wcstouq.c: Same for `wcstouq'. * wcsmbs/wcswidth.c: Implement `wcswidth' function from X/Open CAE. * wcsmbs/wcwidth.c: Ditto for `wcwidth'. * wcsmbs/wcwidth.h: Common function for definitions of above two functions. * wcsmbs/wcsxfrm.c: Implement `wcsxfrm function by using `strxfrm implementation. * wctype/wctype.c: Remove case for `wctype_t' being 16 bit type. * wctype/wctype.h (wint_t): Protect against multiple definition. (wctype_t): Always define as `unsigned long int'. * wctype.h: New file. Wrapper around wctype/wctype.h. * hurd/hurdstartup.c (_hurd_split_args): Function removed. (_hurd_startup): Use argz functions. * hurd/hurdexec.c: Use argz functions.
This commit is contained in:
126
stdlib/strtod.c
126
stdlib/strtod.c
@ -1,6 +1,6 @@
|
||||
/* Read decimal floating point numbers.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Contributed by Ulrich Drepper.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@ -15,18 +15,39 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Configuration part. These macros are defined by `strtold.c' and `strtof.c'
|
||||
to produce the `long double' and `float' versions of the reader. */
|
||||
/* Configuration part. These macros are defined by `strtold.c',
|
||||
`strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the
|
||||
`long double' and `float' versions of the reader. */
|
||||
#ifndef FLOAT
|
||||
#define FLOAT double
|
||||
#define FLT DBL
|
||||
#define STRTOF strtod
|
||||
#define MPN2FLOAT __mpn_construct_double
|
||||
#define FLOAT_HUGE_VAL HUGE_VAL
|
||||
# define FLOAT double
|
||||
# define FLT DBL
|
||||
# ifdef USE_WIDE_CHAR
|
||||
# define STRTOF wcstod
|
||||
# else
|
||||
# define STRTOF strtod
|
||||
# endif
|
||||
# define MPN2FLOAT __mpn_construct_double
|
||||
# define FLOAT_HUGE_VAL HUGE_VAL
|
||||
#endif
|
||||
|
||||
#ifdef USE_WIDE_CHAR
|
||||
# include <wctype.h>
|
||||
# include <wchar.h>
|
||||
# define STRING_TYPE wchar_t
|
||||
# define CHAR_TYPE wint_t
|
||||
# define L_(Ch) L##Ch
|
||||
# define ISSPACE(Ch) iswspace (Ch)
|
||||
# define TOLOWER(Ch) towlower (Ch)
|
||||
#else
|
||||
# define STRING_TYPE char
|
||||
# define CHAR_TYPE char
|
||||
# define L_(Ch) Ch
|
||||
# define ISSPACE(Ch) isspace (Ch)
|
||||
# define TOLOWER(Ch) tolower (Ch)
|
||||
#endif
|
||||
/* End of configuration part. */
|
||||
|
||||
@ -103,8 +124,9 @@ static const mp_limb _tens_in_limb[MAX_DIG_PER_LIMB + 1] =
|
||||
#define NDIG (MAX_10_EXP - MIN_10_EXP + 2 * MANT_DIG)
|
||||
#define RETURN_LIMB_SIZE howmany (MANT_DIG, BITS_PER_MP_LIMB)
|
||||
|
||||
#define RETURN(val,end) \
|
||||
do { if (endptr != 0) *endptr = (char *) (end); return val; } while (0)
|
||||
#define RETURN(val,end) \
|
||||
do { if (endptr != NULL) *endptr = (STRING_TYPE *) (end); \
|
||||
return val; } while (0)
|
||||
|
||||
/* Maximum size necessary for mpn integers to hold floating point numbers. */
|
||||
#define MPNSIZE (howmany (MAX_EXP + 2 * MANT_DIG, BITS_PER_MP_LIMB) \
|
||||
@ -206,8 +228,8 @@ round_and_return (mp_limb *retval, int exponent, int negative,
|
||||
character od the string that is not part of the integer as the function
|
||||
value. If the EXPONENT is small enough to be taken as an additional
|
||||
factor for the resulting number (see code) multiply by it. */
|
||||
static inline const char *
|
||||
str_to_mpn (const char *str, int digcnt, mp_limb *n, mp_size_t *nsize,
|
||||
static inline const STRING_TYPE *
|
||||
str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb *n, mp_size_t *nsize,
|
||||
int *exponent)
|
||||
{
|
||||
/* Number of digits for actual limb. */
|
||||
@ -239,9 +261,9 @@ str_to_mpn (const char *str, int digcnt, mp_limb *n, mp_size_t *nsize,
|
||||
/* There might be thousands separators or radix characters in the string.
|
||||
But these all can be ignored because we know the format of the number
|
||||
is correct and we have an exact number of characters to read. */
|
||||
while (!isdigit (*str))
|
||||
while (*str < L_('0') || *str > L_('9'))
|
||||
++str;
|
||||
low = low * 10 + *str++ - '0';
|
||||
low = low * 10 + *str++ - L_('0');
|
||||
++cnt;
|
||||
}
|
||||
while (--digcnt > 0);
|
||||
@ -311,8 +333,8 @@ __mpn_lshift_1 (mp_limb *ptr, mp_size_t size, unsigned int count, mp_limb limb)
|
||||
ERANGE and return HUGE_VAL with the approriate sign. */
|
||||
FLOAT
|
||||
INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
const char *nptr;
|
||||
char **endptr;
|
||||
const STRING_TYPE *nptr;
|
||||
STRING_TYPE **endptr;
|
||||
int group;
|
||||
{
|
||||
int negative; /* The sign of the number. */
|
||||
@ -330,15 +352,15 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
int bits;
|
||||
|
||||
/* Running pointer after the last character processed in the string. */
|
||||
const char *cp, *tp;
|
||||
const STRING_TYPE *cp, *tp;
|
||||
/* Start of significant part of the number. */
|
||||
const char *startp, *start_of_digits;
|
||||
const STRING_TYPE *startp, *start_of_digits;
|
||||
/* Points at the character following the integer and fractional digits. */
|
||||
const char *expp;
|
||||
const STRING_TYPE *expp;
|
||||
/* Total number of digit and number of digits in integer part. */
|
||||
int dig_no, int_no, lead_zero;
|
||||
/* Contains the last character read. */
|
||||
char c;
|
||||
CHAR_TYPE c;
|
||||
|
||||
/* The radix character of the current locale. */
|
||||
wchar_t decimal;
|
||||
@ -386,32 +408,33 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
/* Ignore leading white space. */
|
||||
do
|
||||
c = *++cp;
|
||||
while (isspace (c));
|
||||
while (ISSPACE (c));
|
||||
|
||||
/* Get sign of the result. */
|
||||
if (c == '-')
|
||||
if (c == L_('-'))
|
||||
{
|
||||
negative = 1;
|
||||
c = *++cp;
|
||||
}
|
||||
else if (c == '+')
|
||||
else if (c == L_('+'))
|
||||
c = *++cp;
|
||||
|
||||
/* Return 0.0 if no legal string is found.
|
||||
No character is used even if a sign was found. */
|
||||
if (!isdigit (c) && (c != decimal || !isdigit (cp[1])))
|
||||
if ((c < L_('0') || c > L_('9'))
|
||||
&& (c != decimal || cp[1] < L_('0') || cp[1] > L_('9')))
|
||||
RETURN (0.0, nptr);
|
||||
|
||||
/* Record the start of the digits, in case we will check their grouping. */
|
||||
start_of_digits = startp = cp;
|
||||
|
||||
/* Ignore leading zeroes. This helps us to avoid useless computations. */
|
||||
while (c == '0' || (thousands != L'\0' && c == thousands))
|
||||
while (c == L_('0') || (thousands != L'\0' && c == thousands))
|
||||
c = *++cp;
|
||||
|
||||
/* If no other digit but a '0' is found the result is 0.0.
|
||||
Return current read pointer. */
|
||||
if (!isdigit (c) && c != decimal)
|
||||
if ((c < L_('0') || c > L_('9')) && c != decimal)
|
||||
{
|
||||
tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping);
|
||||
/* If TP is at the start of the digits, there was no correctly
|
||||
@ -428,7 +451,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
so we can check all the grouping separators. */
|
||||
grouping)
|
||||
{
|
||||
if (isdigit (c))
|
||||
if (c >= L_('0') && c <= L_('9'))
|
||||
++dig_no;
|
||||
else if (thousands == L'\0' || c != thousands)
|
||||
/* Not a digit or separator: end of the integer part. */
|
||||
@ -458,7 +481,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
cp = tp;
|
||||
dig_no = 0;
|
||||
for (tp = startp; tp < cp; ++tp)
|
||||
if (isdigit (*tp))
|
||||
if (*tp >= L_('0') && *tp <= L_('9'))
|
||||
++dig_no;
|
||||
|
||||
int_no = dig_no;
|
||||
@ -481,31 +504,35 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
/* Read the fractional digits. A special case are the 'american style'
|
||||
numbers like `16.' i.e. with decimal but without trailing digits. */
|
||||
if (c == decimal)
|
||||
while (isdigit (c = *++cp))
|
||||
{
|
||||
if (c != '0' && lead_zero == -1)
|
||||
lead_zero = dig_no - int_no;
|
||||
++dig_no;
|
||||
}
|
||||
{
|
||||
c = *++cp;
|
||||
while (c >= L_('0') && c <= L_('9'))
|
||||
{
|
||||
if (c != L_('0') && lead_zero == -1)
|
||||
lead_zero = dig_no - int_no;
|
||||
++dig_no;
|
||||
c = *++cp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember start of exponent (if any). */
|
||||
expp = cp;
|
||||
|
||||
/* Read exponent. */
|
||||
if (tolower (c) == 'e')
|
||||
if (TOLOWER (c) == L_('e'))
|
||||
{
|
||||
int exp_negative = 0;
|
||||
|
||||
c = *++cp;
|
||||
if (c == '-')
|
||||
if (c == L_('-'))
|
||||
{
|
||||
exp_negative = 1;
|
||||
c = *++cp;
|
||||
}
|
||||
else if (c == '+')
|
||||
else if (c == L_('+'))
|
||||
c = *++cp;
|
||||
|
||||
if (isdigit (c))
|
||||
if (c >= L_('0') && c <= L_('9'))
|
||||
{
|
||||
int exp_limit;
|
||||
|
||||
@ -532,16 +559,16 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
/* Accept all following digits as part of the exponent. */
|
||||
do
|
||||
++cp;
|
||||
while (isdigit (*cp));
|
||||
while (*cp >= L_('0') && *cp <= L_('9'));
|
||||
|
||||
RETURN (retval, cp);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
exponent += c - '0';
|
||||
exponent += c - L_('0');
|
||||
c = *++cp;
|
||||
}
|
||||
while (isdigit (c));
|
||||
while (c >= L_('0') && c <= L_('9'));
|
||||
|
||||
if (exp_negative)
|
||||
exponent = -exponent;
|
||||
@ -553,7 +580,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
/* We don't want to have to work with trailing zeroes after the radix. */
|
||||
if (dig_no > int_no)
|
||||
{
|
||||
while (expp[-1] == '0')
|
||||
while (expp[-1] == L_('0'))
|
||||
{
|
||||
--expp;
|
||||
--dig_no;
|
||||
@ -565,7 +592,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
|
||||
/* The whole string is parsed. Store the address of the next character. */
|
||||
if (endptr)
|
||||
*endptr = (char *) cp;
|
||||
*endptr = (STRING_TYPE *) cp;
|
||||
|
||||
if (dig_no == 0)
|
||||
return 0.0;
|
||||
@ -573,7 +600,8 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
if (lead_zero)
|
||||
{
|
||||
/* Find the decimal point */
|
||||
while (*startp != decimal) startp++;
|
||||
while (*startp != decimal)
|
||||
++startp;
|
||||
startp += lead_zero + 1;
|
||||
exponent -= lead_zero;
|
||||
dig_no -= lead_zero;
|
||||
@ -1131,8 +1159,8 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
|
||||
FLOAT
|
||||
STRTOF (nptr, endptr)
|
||||
const char *nptr;
|
||||
char **endptr;
|
||||
const STRING_TYPE *nptr;
|
||||
STRING_TYPE **endptr;
|
||||
{
|
||||
return INTERNAL (STRTOF) (nptr, endptr, 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user