libroot/posix: Switch back to using glibc's string/float-integer conversion routines.
This reverts commit 7174197a8d
and all following changes to the related musl files.
(Besides just the reverts, though, it also uses glibc's
strtol-related routines even outside wchar_t.)
musl's behavior of only parsing POSIX-locale strings here may
be technically conformat, but in conjunction with a filled-in
"localeconv", produces behavior that glib does not expect,
and thus in locales with separators other than '.' and ',' as
in POSIX (or EN) locales, it doesn't work properly.
Fixes the main problem in #19582.
This commit is contained in:
@@ -34,6 +34,13 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
random_r.c
|
||||
seed48.c
|
||||
srand48.c
|
||||
strtod.c
|
||||
strtold.c
|
||||
strtof.c
|
||||
strtol.c
|
||||
strtoll.c
|
||||
strtoul.c
|
||||
strtoull.c
|
||||
|
||||
# These are nonstandard but were declared in BeOS's headers.
|
||||
erand48_r.c
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
/* The actual implementation for all floating point sizes is in strtod.c.
|
||||
These macros tell it to produce the `float' version, `strtof'. */
|
||||
|
||||
#define FLOAT float
|
||||
#define FLT FLT
|
||||
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define STRTOF __strtof_l
|
||||
#else
|
||||
# define STRTOF strtof
|
||||
#endif
|
||||
#define MPN2FLOAT __mpn_construct_float
|
||||
#define FLOAT_HUGE_VAL HUGE_VALF
|
||||
#define SET_MANTISSA(flt, mant) \
|
||||
do { union ieee754_float u; \
|
||||
u.f = (flt); \
|
||||
if ((mant & 0x7fffff) == 0) \
|
||||
mant = 0x400000; \
|
||||
u.ieee.mantissa = (mant) & 0x7fffff; \
|
||||
(flt) = u.f; \
|
||||
} while (0)
|
||||
|
||||
#include "strtod.c"
|
||||
@@ -0,0 +1,556 @@
|
||||
/* Convert string representation of a number into an integer value.
|
||||
Copyright (C) 1991,92,94,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# define USE_NUMBER_GROUPING
|
||||
# define STDC_HEADERS
|
||||
# define HAVE_LIMITS_H
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stddef.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <locale.h>
|
||||
#else
|
||||
# ifndef NULL
|
||||
# define NULL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_NUMBER_GROUPING
|
||||
# include "../locale/localeinfo.h"
|
||||
#endif
|
||||
|
||||
/* Nonzero if we are defining `strtoul' or `strtoull', operating on
|
||||
unsigned integers. */
|
||||
#ifndef UNSIGNED
|
||||
# define UNSIGNED 0
|
||||
# define INT LONG int
|
||||
#else
|
||||
# define INT unsigned LONG int
|
||||
#endif
|
||||
|
||||
/* Determine the name. */
|
||||
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# if UNSIGNED
|
||||
# ifdef USE_WIDE_CHAR
|
||||
# ifdef QUAD
|
||||
# define strtol __wcstoull_l
|
||||
# else
|
||||
# define strtol __wcstoul_l
|
||||
# endif
|
||||
# else
|
||||
# ifdef QUAD
|
||||
# define strtol __strtoull_l
|
||||
# else
|
||||
# define strtol __strtoul_l
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
# ifdef USE_WIDE_CHAR
|
||||
# ifdef QUAD
|
||||
# define strtol __wcstoll_l
|
||||
# else
|
||||
# define strtol __wcstol_l
|
||||
# endif
|
||||
# else
|
||||
# ifdef QUAD
|
||||
# define strtol __strtoll_l
|
||||
# else
|
||||
# define strtol __strtol_l
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# if UNSIGNED
|
||||
# ifdef USE_WIDE_CHAR
|
||||
# ifdef QUAD
|
||||
# define strtol wcstoull
|
||||
# else
|
||||
# define strtol wcstoul
|
||||
# endif
|
||||
# else
|
||||
# ifdef QUAD
|
||||
# define strtol strtoull
|
||||
# else
|
||||
# define strtol strtoul
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
# ifdef USE_WIDE_CHAR
|
||||
# ifdef QUAD
|
||||
# define strtol wcstoll
|
||||
# else
|
||||
# define strtol wcstol
|
||||
# endif
|
||||
# else
|
||||
# ifdef QUAD
|
||||
# define strtol strtoll
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If QUAD is defined, we are defining `strtoll' or `strtoull',
|
||||
operating on `long long int's. */
|
||||
#ifdef QUAD
|
||||
# define LONG long long
|
||||
# define STRTOL_LONG_MIN LONG_LONG_MIN
|
||||
# define STRTOL_LONG_MAX LONG_LONG_MAX
|
||||
# define STRTOL_ULONG_MAX ULONG_LONG_MAX
|
||||
# if __GNUC__ == 2 && __GNUC_MINOR__ < 7
|
||||
/* Work around gcc bug with using this constant. */
|
||||
static const unsigned long long int maxquad = ULONG_LONG_MAX;
|
||||
# undef STRTOL_ULONG_MAX
|
||||
# define STRTOL_ULONG_MAX maxquad
|
||||
# endif
|
||||
#else
|
||||
# define LONG long
|
||||
|
||||
# ifndef ULONG_MAX
|
||||
# define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
|
||||
# endif
|
||||
# ifndef LONG_MAX
|
||||
# define LONG_MAX ((long int) (ULONG_MAX >> 1))
|
||||
# endif
|
||||
# define STRTOL_LONG_MIN LONG_MIN
|
||||
# define STRTOL_LONG_MAX LONG_MAX
|
||||
# define STRTOL_ULONG_MAX ULONG_MAX
|
||||
#endif
|
||||
|
||||
|
||||
/* We use this code also for the extended locale handling where the
|
||||
function gets as an additional argument the locale which has to be
|
||||
used. To access the values we have to redefine the _NL_CURRENT
|
||||
macro. */
|
||||
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# undef _NL_CURRENT
|
||||
# define _NL_CURRENT(category, item) \
|
||||
(current->values[_NL_ITEM_INDEX (item)].string)
|
||||
# define LOCALE_PARAM , loc
|
||||
# define LOCALE_PARAM_DECL __locale_t loc;
|
||||
#else
|
||||
# define LOCALE_PARAM
|
||||
# define LOCALE_PARAM_DECL
|
||||
#endif
|
||||
|
||||
#if defined _LIBC || defined HAVE_WCHAR_H
|
||||
# include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_WIDE_CHAR
|
||||
# include <wctype.h>
|
||||
# define L_(Ch) L##Ch
|
||||
# define UCHAR_TYPE wint_t
|
||||
# define STRING_TYPE wchar_t
|
||||
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define ISSPACE(Ch) __iswspace_l ((Ch), loc)
|
||||
# define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
|
||||
# define TOUPPER(Ch) __towupper_l ((Ch), loc)
|
||||
# else
|
||||
# define ISSPACE(Ch) iswspace (Ch)
|
||||
# define ISALPHA(Ch) iswalpha (Ch)
|
||||
# define TOUPPER(Ch) towupper (Ch)
|
||||
# endif
|
||||
# else
|
||||
# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
|
||||
# define IN_CTYPE_DOMAIN(c) 1
|
||||
# else
|
||||
# define IN_CTYPE_DOMAIN(c) isascii(c)
|
||||
# endif
|
||||
# define L_(Ch) Ch
|
||||
# define UCHAR_TYPE unsigned char
|
||||
# define STRING_TYPE char
|
||||
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define ISSPACE(Ch) __isspace_l ((Ch), loc)
|
||||
# define ISALPHA(Ch) __isalpha_l ((Ch), loc)
|
||||
# define TOUPPER(Ch) __toupper_l ((Ch), loc)
|
||||
# else
|
||||
# define ISSPACE(Ch) (IN_CTYPE_DOMAIN (Ch) && isspace (Ch))
|
||||
# define ISALPHA(Ch) (IN_CTYPE_DOMAIN (Ch) && isalpha (Ch))
|
||||
# define TOUPPER(Ch) (IN_CTYPE_DOMAIN (Ch) ? toupper (Ch) : (Ch))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
# define INTERNAL(X) INTERNAL1(X)
|
||||
# define INTERNAL1(X) __##X##_internal
|
||||
# define WEAKNAME(X) WEAKNAME1(X)
|
||||
#else
|
||||
# define INTERNAL(X) __/**/X/**/_internal
|
||||
#endif
|
||||
|
||||
#ifdef USE_NUMBER_GROUPING
|
||||
/* This file defines a function to check for correct grouping. */
|
||||
# include "grouping.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
|
||||
If BASE is 0 the base is determined by the presence of a leading
|
||||
zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
|
||||
If BASE is < 2 or > 36, it is reset to 10.
|
||||
If ENDPTR is not NULL, a pointer to the character after the last
|
||||
one converted is stored in *ENDPTR. */
|
||||
|
||||
INT
|
||||
INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM)
|
||||
const STRING_TYPE *nptr;
|
||||
STRING_TYPE **endptr;
|
||||
int base;
|
||||
int group;
|
||||
LOCALE_PARAM_DECL
|
||||
{
|
||||
int negative;
|
||||
register unsigned LONG int cutoff;
|
||||
register unsigned int cutlim;
|
||||
register unsigned LONG int i;
|
||||
register const STRING_TYPE *s;
|
||||
register UCHAR_TYPE c;
|
||||
const STRING_TYPE *save, *end;
|
||||
int overflow;
|
||||
#ifndef USE_WIDE_CHAR
|
||||
size_t cnt;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NUMBER_GROUPING
|
||||
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
struct locale_data *current = loc->__locales[LC_NUMERIC];
|
||||
# endif
|
||||
/* The thousands character of the current locale. */
|
||||
# ifdef USE_WIDE_CHAR
|
||||
wchar_t thousands = L'\0';
|
||||
# else
|
||||
const char *thousands = NULL;
|
||||
size_t thousands_len = 0;
|
||||
# endif
|
||||
/* The numeric grouping specification of the current locale,
|
||||
in the format described in <locale.h>. */
|
||||
const char *grouping;
|
||||
|
||||
if (__builtin_expect (group, 0))
|
||||
{
|
||||
grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
|
||||
if (*grouping <= 0 || *grouping == CHAR_MAX)
|
||||
grouping = NULL;
|
||||
else
|
||||
{
|
||||
/* Figure out the thousands separator character. */
|
||||
# ifdef USE_WIDE_CHAR
|
||||
# ifdef _LIBC
|
||||
thousands = _NL_CURRENT_WORD (LC_NUMERIC,
|
||||
_NL_NUMERIC_THOUSANDS_SEP_WC);
|
||||
# endif
|
||||
if (thousands == L'\0')
|
||||
grouping = NULL;
|
||||
# else
|
||||
# ifdef _LIBC
|
||||
thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
|
||||
# endif
|
||||
if (*thousands == '\0')
|
||||
{
|
||||
thousands = NULL;
|
||||
grouping = NULL;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
}
|
||||
else
|
||||
grouping = NULL;
|
||||
#endif
|
||||
|
||||
if (base < 0 || base == 1 || base > 36 || nptr == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
save = s = nptr;
|
||||
|
||||
/* Skip white space. */
|
||||
while (ISSPACE (*s))
|
||||
++s;
|
||||
if (__builtin_expect (*s == L_('\0'), 0))
|
||||
goto noconv;
|
||||
|
||||
/* Check for a sign. */
|
||||
negative = 0;
|
||||
if (*s == L_('-'))
|
||||
{
|
||||
negative = 1;
|
||||
++s;
|
||||
}
|
||||
else if (*s == L_('+'))
|
||||
++s;
|
||||
|
||||
/* Recognize number prefix and if BASE is zero, figure it out ourselves. */
|
||||
if (*s == L_('0'))
|
||||
{
|
||||
if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
|
||||
{
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
else if (base == 0)
|
||||
base = 8;
|
||||
}
|
||||
else if (base == 0)
|
||||
base = 10;
|
||||
|
||||
/* Save the pointer so we can check later if anything happened. */
|
||||
save = s;
|
||||
|
||||
#ifdef USE_NUMBER_GROUPING
|
||||
if (base != 10)
|
||||
grouping = NULL;
|
||||
|
||||
if (__builtin_expect (grouping != NULL, 0))
|
||||
{
|
||||
# ifndef USE_WIDE_CHAR
|
||||
thousands_len = strlen (thousands);
|
||||
# endif
|
||||
|
||||
/* Find the end of the digit string and check its grouping. */
|
||||
end = s;
|
||||
if (
|
||||
# ifdef USE_WIDE_CHAR
|
||||
*s != thousands
|
||||
# else
|
||||
({ for (cnt = 0; cnt < thousands_len; ++cnt)
|
||||
if (thousands[cnt] != end[cnt])
|
||||
break;
|
||||
cnt < thousands_len; })
|
||||
# endif
|
||||
)
|
||||
{
|
||||
for (c = *end; c != L_('\0'); c = *++end)
|
||||
if (((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
|
||||
# ifdef USE_WIDE_CHAR
|
||||
&& c != thousands
|
||||
# else
|
||||
&& ({ for (cnt = 0; cnt < thousands_len; ++cnt)
|
||||
if (thousands[cnt] != end[cnt])
|
||||
break;
|
||||
cnt < thousands_len; })
|
||||
# endif
|
||||
&& (!ISALPHA (c)
|
||||
|| (int) (TOUPPER (c) - L_('A') + 10) >= base))
|
||||
break;
|
||||
|
||||
end = correctly_grouped_prefix (s, end, thousands, grouping);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
end = NULL;
|
||||
|
||||
cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
|
||||
cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
|
||||
|
||||
overflow = 0;
|
||||
i = 0;
|
||||
c = *s;
|
||||
if (sizeof (long int) != sizeof (LONG int))
|
||||
{
|
||||
unsigned long int j = 0;
|
||||
unsigned long int jmax = ULONG_MAX / base;
|
||||
|
||||
for (;c != L_('\0'); c = *++s)
|
||||
{
|
||||
if (s == end)
|
||||
break;
|
||||
if (c >= L_('0') && c <= L_('9'))
|
||||
c -= L_('0');
|
||||
#ifdef USE_NUMBER_GROUPING
|
||||
# ifdef USE_WIDE_CHAR
|
||||
else if (grouping && c == thousands)
|
||||
continue;
|
||||
# else
|
||||
else if (thousands_len)
|
||||
{
|
||||
for (cnt = 0; cnt < thousands_len; ++cnt)
|
||||
if (thousands[cnt] != s[cnt])
|
||||
break;
|
||||
if (cnt == thousands_len)
|
||||
{
|
||||
s += thousands_len - 1;
|
||||
continue;
|
||||
}
|
||||
if (ISALPHA (c))
|
||||
c = TOUPPER (c) - L_('A') + 10;
|
||||
else
|
||||
break;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
else if (ISALPHA (c))
|
||||
c = TOUPPER (c) - L_('A') + 10;
|
||||
else
|
||||
break;
|
||||
if ((int) c >= base)
|
||||
break;
|
||||
/* Note that we never can have an overflow. */
|
||||
else if (j >= jmax)
|
||||
{
|
||||
/* We have an overflow. Now use the long representation. */
|
||||
i = (unsigned LONG int) j;
|
||||
goto use_long;
|
||||
}
|
||||
else
|
||||
j = j * (unsigned long int) base + c;
|
||||
}
|
||||
|
||||
i = (unsigned LONG int) j;
|
||||
}
|
||||
else
|
||||
for (;c != L_('\0'); c = *++s)
|
||||
{
|
||||
if (s == end)
|
||||
break;
|
||||
if (c >= L_('0') && c <= L_('9'))
|
||||
c -= L_('0');
|
||||
#ifdef USE_NUMBER_GROUPING
|
||||
# ifdef USE_WIDE_CHAR
|
||||
else if (grouping && c == thousands)
|
||||
continue;
|
||||
# else
|
||||
else if (thousands_len)
|
||||
{
|
||||
for (cnt = 0; cnt < thousands_len; ++cnt)
|
||||
if (thousands[cnt] != s[cnt])
|
||||
break;
|
||||
if (cnt == thousands_len)
|
||||
{
|
||||
s += thousands_len - 1;
|
||||
continue;
|
||||
}
|
||||
if (ISALPHA (c))
|
||||
c = TOUPPER (c) - L_('A') + 10;
|
||||
else
|
||||
break;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
else if (ISALPHA (c))
|
||||
c = TOUPPER (c) - L_('A') + 10;
|
||||
else
|
||||
break;
|
||||
if ((int) c >= base)
|
||||
break;
|
||||
/* Check for overflow. */
|
||||
if (i > cutoff || (i == cutoff && c > cutlim))
|
||||
overflow = 1;
|
||||
else
|
||||
{
|
||||
use_long:
|
||||
i *= (unsigned LONG int) base;
|
||||
i += c;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if anything actually happened. */
|
||||
if (s == save)
|
||||
goto noconv;
|
||||
|
||||
/* Store in ENDPTR the address of one character
|
||||
past the last character we converted. */
|
||||
if (endptr != NULL)
|
||||
*endptr = (STRING_TYPE *) s;
|
||||
|
||||
#if !UNSIGNED
|
||||
/* Check for a value that is within the range of
|
||||
`unsigned LONG int', but outside the range of `LONG int'. */
|
||||
if (overflow == 0
|
||||
&& i > (negative
|
||||
? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
|
||||
: (unsigned LONG int) STRTOL_LONG_MAX))
|
||||
overflow = 1;
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (overflow, 0))
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
#if UNSIGNED
|
||||
return STRTOL_ULONG_MAX;
|
||||
#else
|
||||
return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the result of the appropriate sign. */
|
||||
return negative ? -i : i;
|
||||
|
||||
noconv:
|
||||
/* We must handle a special case here: the base is 0 or 16 and the
|
||||
first two characters are '0' and 'x', but the rest are no
|
||||
hexadecimal digits. This is no error case. We return 0 and
|
||||
ENDPTR points to the `x`. */
|
||||
if (endptr != NULL)
|
||||
{
|
||||
if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
|
||||
&& save[-2] == L_('0'))
|
||||
*endptr = (STRING_TYPE *) &save[-1];
|
||||
else
|
||||
/* There was no number to convert. */
|
||||
*endptr = (STRING_TYPE *) nptr;
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/* External user entry point. */
|
||||
|
||||
#if _LIBC - 0 == 0
|
||||
# undef PARAMS
|
||||
# if defined (__STDC__) && __STDC__
|
||||
# define PARAMS(Args) Args
|
||||
# else
|
||||
# define PARAMS(Args) ()
|
||||
# endif
|
||||
|
||||
/* Prototype. */
|
||||
INT strtol PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr, int base));
|
||||
#endif
|
||||
|
||||
|
||||
INT
|
||||
#ifdef weak_function
|
||||
weak_function
|
||||
#endif
|
||||
strtol (nptr, endptr, base LOCALE_PARAM)
|
||||
const STRING_TYPE *nptr;
|
||||
STRING_TYPE **endptr;
|
||||
int base;
|
||||
LOCALE_PARAM_DECL
|
||||
{
|
||||
return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
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., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* There is no `long double' type, use the `double' implementations. */
|
||||
long double
|
||||
__strtold_internal (const char *nptr, char **endptr, int group)
|
||||
{
|
||||
return __strtod_internal (nptr, endptr, group);
|
||||
}
|
||||
|
||||
long double
|
||||
strtold (const char *nptr, char **endptr)
|
||||
{
|
||||
return __strtod_internal (nptr, endptr, 0);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#define QUAD 1
|
||||
#include "strtol.c"
|
||||
@@ -0,0 +1,2 @@
|
||||
#define UNSIGNED 1
|
||||
#include "strtol.c"
|
||||
@@ -0,0 +1,3 @@
|
||||
#define UNSIGNED 1
|
||||
#define QUAD 1
|
||||
#include "strtol.c"
|
||||
@@ -0,0 +1 @@
|
||||
localedata
|
||||
@@ -24,6 +24,13 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
|
||||
MergeObject <$(architecture)>posix_gnu_wcsmbs.o :
|
||||
wcsmbsload.c
|
||||
wcstod.c
|
||||
wcstof.c
|
||||
wcstol.c
|
||||
wcstoll.c
|
||||
wcstold.c
|
||||
wcstoul.c
|
||||
wcstoull.c
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
libc {
|
||||
GLIBC_2.0 {
|
||||
# functions used in inline functions or macros
|
||||
__wcsto*_internal; __mbrlen; __mbrtowc;
|
||||
|
||||
# b*
|
||||
btowc;
|
||||
|
||||
# w*
|
||||
wcpcpy; wcpncpy; wcrtomb; wcscat; wcschr; wcscmp; wcscoll;
|
||||
wcscpy; wcscspn; wcsdup; wcslen; wcsncat; wcsncmp;
|
||||
wcsncpy; wcsnrtombs; wcspbrk; wcsrchr; wcsrtombs; wcsspn; wcsstr;
|
||||
wcstod; wcstof; wcstok; wcstol; wcstold; wcstoq; wcstoul;
|
||||
wcstouq; wcswidth; wcsxfrm; wctob;
|
||||
|
||||
wmemchr; wmemcmp; wmemcpy; wmemmove; wmemset;
|
||||
}
|
||||
GLIBC_2.1 {
|
||||
# w*
|
||||
wcscasecmp; wcsncasecmp; wcsnlen; wcstoll;
|
||||
wcstoimax; wcstoumax; wcstoull; wcswcs; wmemrtombs; wmemrtowcs;
|
||||
}
|
||||
GLIBC_2.2 {
|
||||
# w*
|
||||
wcschrnul; wmempcpy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <[email protected]>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
|
||||
/* The actual implementation for all floating point sizes is in strtod.c. */
|
||||
|
||||
#define USE_WIDE_CHAR 1
|
||||
|
||||
#include <stdlib/strtod.c>
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <[email protected]>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
|
||||
/* The actual implementation for all floating point sizes is in strtod.c.
|
||||
These macros tell it to produce the `float' version, `wcstof'. */
|
||||
|
||||
#define FLOAT float
|
||||
#define FLT FLT
|
||||
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define STRTOF __wcstof_l
|
||||
#else
|
||||
# define STRTOF wcstof
|
||||
#endif
|
||||
#define MPN2FLOAT __mpn_construct_float
|
||||
#define FLOAT_HUGE_VAL HUGE_VALF
|
||||
#define USE_WIDE_CHAR 1
|
||||
#define SET_MANTISSA(flt, mant) \
|
||||
do { union ieee754_float u; \
|
||||
u.f = (flt); \
|
||||
if ((mant & 0x7fffff) == 0) \
|
||||
mant = 0x400000; \
|
||||
u.ieee.mantissa = (mant) & 0x7fffff; \
|
||||
(flt) = u.f; \
|
||||
} while (0)
|
||||
|
||||
#include <stdlib/strtod.c>
|
||||
@@ -0,0 +1,23 @@
|
||||
/* Function to parse a `long int' from text.
|
||||
Copyright (C) 1996, 1997, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <[email protected]>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define USE_WIDE_CHAR 1
|
||||
|
||||
#include <stdlib/strtol.c>
|
||||
@@ -0,0 +1,62 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <[email protected]>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <math.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
/* The actual implementation for all floating point sizes is in strtod.c.
|
||||
These macros tell it to produce the `long double' version, `wcstold'. */
|
||||
|
||||
# define FLOAT long double
|
||||
# define FLT LDBL
|
||||
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
|
||||
# define STRTOF __wcstold_l
|
||||
# else
|
||||
# define STRTOF wcstold
|
||||
# endif
|
||||
# define MPN2FLOAT __mpn_construct_long_double
|
||||
# define FLOAT_HUGE_VAL HUGE_VALL
|
||||
# define USE_WIDE_CHAR 1
|
||||
# define SET_MANTISSA(flt, mant) \
|
||||
do { union ieee854_long_double u; \
|
||||
u.d = (flt); \
|
||||
if ((mant & 0x7fffffffffffffffULL) == 0) \
|
||||
mant = 0x4000000000000000ULL; \
|
||||
u.ieee.mantissa0 = (((mant) >> 32) & 0x7fffffff) | 0x80000000; \
|
||||
u.ieee.mantissa1 = (mant) & 0xffffffff; \
|
||||
(flt) = u.d; \
|
||||
} while (0)
|
||||
|
||||
# include <stdlib/strtod.c>
|
||||
#else
|
||||
/* There is no `long double' type, use the `double' implementations. */
|
||||
long double
|
||||
__wcstold_internal (const wchar_t *nptr, wchar_t **endptr, int group)
|
||||
{
|
||||
return __wcstod_internal (nptr, endptr, group);
|
||||
}
|
||||
libc_hidden_def (__wcstold_internal)
|
||||
|
||||
long double
|
||||
wcstold (const wchar_t *nptr, wchar_t **endptr)
|
||||
{
|
||||
return __wcstod_internal (nptr, endptr, 0);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Function to parse a `long long int' from text.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <[email protected]>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define QUAD 1
|
||||
|
||||
#include "wcstol.c"
|
||||
|
||||
weak_alias (wcstoll, wcstoq)
|
||||
@@ -0,0 +1,23 @@
|
||||
/* Function to parse an `unsigned long int' from text.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <[email protected]>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define UNSIGNED 1
|
||||
|
||||
#include "wcstol.c"
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Function to parse an `unsigned long long int' from text.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <[email protected]>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define QUAD 1
|
||||
|
||||
#include "wcstoul.c"
|
||||
|
||||
weak_alias (wcstoull, wcstouq)
|
||||
@@ -10,7 +10,6 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
<$(architecture)>posix_musl_crypt.o
|
||||
<$(architecture)>posix_musl_complex.o
|
||||
<$(architecture)>posix_musl_dirent.o
|
||||
<$(architecture)>posix_musl_internal.o
|
||||
<$(architecture)>posix_musl_math.o
|
||||
<$(architecture)>posix_musl_misc.o
|
||||
<$(architecture)>posix_musl_prng.o
|
||||
@@ -31,7 +30,6 @@ for arch in $(TARGET_ARCHS) {
|
||||
HaikuSubInclude crypt ;
|
||||
HaikuSubInclude complex ;
|
||||
HaikuSubInclude dirent ;
|
||||
HaikuSubInclude internal ;
|
||||
HaikuSubInclude misc ;
|
||||
HaikuSubInclude prng ;
|
||||
HaikuSubInclude regex ;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
SubDir HAIKU_TOP src system libroot posix musl internal ;
|
||||
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) .. include ] ;
|
||||
UseHeaders [ FDirName $(SUBDIR) .. internal ] ;
|
||||
|
||||
local architectureObject ;
|
||||
for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
on $(architectureObject) {
|
||||
local architecture = $(TARGET_PACKAGING_ARCH) ;
|
||||
|
||||
MergeObject <$(architecture)>posix_musl_internal.o :
|
||||
floatscan.c
|
||||
intscan.c
|
||||
shgetc.c
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -1,509 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "shgetc.h"
|
||||
#include "floatscan.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
|
||||
#define LD_B1B_DIG 2
|
||||
#define LD_B1B_MAX 9007199, 254740991
|
||||
#define KMAX 128
|
||||
|
||||
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
|
||||
|
||||
#define LD_B1B_DIG 3
|
||||
#define LD_B1B_MAX 18, 446744073, 709551615
|
||||
#define KMAX 2048
|
||||
|
||||
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
|
||||
|
||||
#define LD_B1B_DIG 4
|
||||
#define LD_B1B_MAX 10384593, 717069655, 257060992, 658440191
|
||||
#define KMAX 2048
|
||||
|
||||
#else
|
||||
#error Unsupported long double representation
|
||||
#endif
|
||||
|
||||
#define MASK (KMAX-1)
|
||||
|
||||
static long long scanexp(FILE *f, int pok)
|
||||
{
|
||||
int c;
|
||||
int x;
|
||||
long long y;
|
||||
int neg = 0;
|
||||
|
||||
c = shgetc(f);
|
||||
if (c=='+' || c=='-') {
|
||||
neg = (c=='-');
|
||||
c = shgetc(f);
|
||||
if (c-'0'>=10U && pok) shunget(f);
|
||||
}
|
||||
if (c-'0'>=10U) {
|
||||
shunget(f);
|
||||
return LLONG_MIN;
|
||||
}
|
||||
for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f))
|
||||
x = 10*x + c-'0';
|
||||
for (y=x; c-'0'<10U && y<LLONG_MAX/100; c = shgetc(f))
|
||||
y = 10*y + c-'0';
|
||||
for (; c-'0'<10U; c = shgetc(f));
|
||||
shunget(f);
|
||||
return neg ? -y : y;
|
||||
}
|
||||
|
||||
|
||||
static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int pok)
|
||||
{
|
||||
uint32_t x[KMAX];
|
||||
static const uint32_t th[] = { LD_B1B_MAX };
|
||||
int i, j, k, a, z;
|
||||
long long lrp=0, dc=0;
|
||||
long long e10=0;
|
||||
int lnz = 0;
|
||||
int gotdig = 0, gotrad = 0;
|
||||
int rp;
|
||||
int e2;
|
||||
int emax = -emin-bits+3;
|
||||
int denormal = 0;
|
||||
long double y;
|
||||
long double frac=0;
|
||||
long double bias=0;
|
||||
static const int p10s[] = { 10, 100, 1000, 10000,
|
||||
100000, 1000000, 10000000, 100000000 };
|
||||
|
||||
j=0;
|
||||
k=0;
|
||||
|
||||
/* Don't let leading zeros consume buffer space */
|
||||
for (; c=='0'; c = shgetc(f)) gotdig=1;
|
||||
if (c=='.') {
|
||||
gotrad = 1;
|
||||
for (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--;
|
||||
}
|
||||
|
||||
x[0] = 0;
|
||||
for (; c-'0'<10U || c=='.'; c = shgetc(f)) {
|
||||
if (c == '.') {
|
||||
if (gotrad) break;
|
||||
gotrad = 1;
|
||||
lrp = dc;
|
||||
} else if (k < KMAX-3) {
|
||||
dc++;
|
||||
if (c!='0') lnz = dc;
|
||||
if (j) x[k] = x[k]*10 + c-'0';
|
||||
else x[k] = c-'0';
|
||||
if (++j==9) {
|
||||
k++;
|
||||
j=0;
|
||||
}
|
||||
gotdig=1;
|
||||
} else {
|
||||
dc++;
|
||||
if (c!='0') {
|
||||
lnz = (KMAX-4)*9;
|
||||
x[KMAX-4] |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!gotrad) lrp=dc;
|
||||
|
||||
if (gotdig && (c|32)=='e') {
|
||||
e10 = scanexp(f, pok);
|
||||
if (e10 == LLONG_MIN) {
|
||||
if (pok) {
|
||||
shunget(f);
|
||||
} else {
|
||||
shlim(f, 0);
|
||||
return 0;
|
||||
}
|
||||
e10 = 0;
|
||||
}
|
||||
lrp += e10;
|
||||
} else if (c>=0) {
|
||||
shunget(f);
|
||||
}
|
||||
if (!gotdig) {
|
||||
errno = EINVAL;
|
||||
shlim(f, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Handle zero specially to avoid nasty special cases later */
|
||||
if (!x[0]) return sign * 0.0;
|
||||
|
||||
/* Optimize small integers (w/no exponent) and over/under-flow */
|
||||
if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0))
|
||||
return sign * (long double)x[0];
|
||||
if (lrp > -emin/2) {
|
||||
errno = ERANGE;
|
||||
return sign * LDBL_MAX * LDBL_MAX;
|
||||
}
|
||||
if (lrp < emin-2*LDBL_MANT_DIG) {
|
||||
errno = ERANGE;
|
||||
return sign * LDBL_MIN * LDBL_MIN;
|
||||
}
|
||||
|
||||
/* Align incomplete final B1B digit */
|
||||
if (j) {
|
||||
for (; j<9; j++) x[k]*=10;
|
||||
k++;
|
||||
j=0;
|
||||
}
|
||||
|
||||
a = 0;
|
||||
z = k;
|
||||
e2 = 0;
|
||||
rp = lrp;
|
||||
|
||||
/* Optimize small to mid-size integers (even in exp. notation) */
|
||||
if (lnz<9 && lnz<=rp && rp < 18) {
|
||||
if (rp == 9) return sign * (long double)x[0];
|
||||
if (rp < 9) return sign * (long double)x[0] / p10s[8-rp];
|
||||
{
|
||||
int bitlim = bits-3*(int)(rp-9);
|
||||
if (bitlim>30 || x[0]>>bitlim==0)
|
||||
return sign * (long double)x[0] * p10s[rp-10];
|
||||
}
|
||||
}
|
||||
|
||||
/* Drop trailing zeros */
|
||||
for (; !x[z-1]; z--);
|
||||
|
||||
/* Align radix point to B1B digit boundary */
|
||||
if (rp % 9) {
|
||||
int rpm9 = rp>=0 ? rp%9 : rp%9+9;
|
||||
int p10 = p10s[8-rpm9];
|
||||
uint32_t carry = 0;
|
||||
for (k=a; k!=z; k++) {
|
||||
uint32_t tmp = x[k] % p10;
|
||||
x[k] = x[k]/p10 + carry;
|
||||
carry = 1000000000/p10 * tmp;
|
||||
if (k==a && !x[k]) {
|
||||
a = (a+1 & MASK);
|
||||
rp -= 9;
|
||||
}
|
||||
}
|
||||
if (carry) x[z++] = carry;
|
||||
rp += 9-rpm9;
|
||||
}
|
||||
|
||||
/* Upscale until desired number of bits are left of radix point */
|
||||
while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a]<th[0])) {
|
||||
uint32_t carry = 0;
|
||||
e2 -= 29;
|
||||
for (k=(z-1 & MASK); ; k=(k-1 & MASK)) {
|
||||
uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
|
||||
if (tmp > 1000000000) {
|
||||
carry = tmp / 1000000000;
|
||||
x[k] = tmp % 1000000000;
|
||||
} else {
|
||||
carry = 0;
|
||||
x[k] = tmp;
|
||||
}
|
||||
if (k==(z-1 & MASK) && k!=a && !x[k]) z = k;
|
||||
if (k==a) break;
|
||||
}
|
||||
if (carry) {
|
||||
rp += 9;
|
||||
a = (a-1 & MASK);
|
||||
if (a == z) {
|
||||
z = (z-1 & MASK);
|
||||
x[z-1 & MASK] |= x[z];
|
||||
}
|
||||
x[a] = carry;
|
||||
}
|
||||
}
|
||||
|
||||
/* Downscale until exactly number of bits are left of radix point */
|
||||
for (;;) {
|
||||
uint32_t carry = 0;
|
||||
int sh = 1;
|
||||
for (i=0; i<LD_B1B_DIG; i++) {
|
||||
k = (a+i & MASK);
|
||||
if (k == z || x[k] < th[i]) {
|
||||
i=LD_B1B_DIG;
|
||||
break;
|
||||
}
|
||||
if (x[a+i & MASK] > th[i]) break;
|
||||
}
|
||||
if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break;
|
||||
/* FIXME: find a way to compute optimal sh */
|
||||
if (rp > 9+9*LD_B1B_DIG) sh = 9;
|
||||
e2 += sh;
|
||||
for (k=a; k!=z; k=(k+1 & MASK)) {
|
||||
uint32_t tmp = x[k] & (1<<sh)-1;
|
||||
x[k] = (x[k]>>sh) + carry;
|
||||
carry = (1000000000>>sh) * tmp;
|
||||
if (k==a && !x[k]) {
|
||||
a = (a+1 & MASK);
|
||||
i--;
|
||||
rp -= 9;
|
||||
}
|
||||
}
|
||||
if (carry) {
|
||||
if ((z+1 & MASK) != a) {
|
||||
x[z] = carry;
|
||||
z = (z+1 & MASK);
|
||||
} else x[z-1 & MASK] |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assemble desired bits into floating point variable */
|
||||
for (y=i=0; i<LD_B1B_DIG; i++) {
|
||||
if ((a+i & MASK)==z) x[(z=(z+1 & MASK))-1] = 0;
|
||||
y = 1000000000.0L * y + x[a+i & MASK];
|
||||
}
|
||||
|
||||
y *= sign;
|
||||
|
||||
/* Limit precision for denormal results */
|
||||
if (bits > LDBL_MANT_DIG+e2-emin) {
|
||||
bits = LDBL_MANT_DIG+e2-emin;
|
||||
if (bits<0) bits=0;
|
||||
denormal = 1;
|
||||
}
|
||||
|
||||
/* Calculate bias term to force rounding, move out lower bits */
|
||||
if (bits < LDBL_MANT_DIG) {
|
||||
bias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y);
|
||||
frac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits));
|
||||
y -= frac;
|
||||
y += bias;
|
||||
}
|
||||
|
||||
/* Process tail of decimal input so it can affect rounding */
|
||||
if ((a+i & MASK) != z) {
|
||||
uint32_t t = x[a+i & MASK];
|
||||
if (t < 500000000 && (t || (a+i+1 & MASK) != z))
|
||||
frac += 0.25*sign;
|
||||
else if (t > 500000000)
|
||||
frac += 0.75*sign;
|
||||
else if (t == 500000000) {
|
||||
if ((a+i+1 & MASK) == z)
|
||||
frac += 0.5*sign;
|
||||
else
|
||||
frac += 0.75*sign;
|
||||
}
|
||||
if (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1))
|
||||
frac++;
|
||||
}
|
||||
|
||||
y += frac;
|
||||
y -= bias;
|
||||
|
||||
if ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) {
|
||||
if (fabsl(y) >= 2/LDBL_EPSILON) {
|
||||
if (denormal && bits==LDBL_MANT_DIG+e2-emin)
|
||||
denormal = 0;
|
||||
y *= 0.5;
|
||||
e2++;
|
||||
}
|
||||
if (e2+LDBL_MANT_DIG>emax || (denormal && frac))
|
||||
errno = ERANGE;
|
||||
}
|
||||
|
||||
return scalbnl(y, e2);
|
||||
}
|
||||
|
||||
static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok)
|
||||
{
|
||||
uint32_t x = 0;
|
||||
long double y = 0;
|
||||
long double scale = 1;
|
||||
long double bias = 0;
|
||||
int gottail = 0, gotrad = 0, gotdig = 0;
|
||||
long long rp = 0;
|
||||
long long dc = 0;
|
||||
long long e2 = 0;
|
||||
int d;
|
||||
int c;
|
||||
|
||||
c = shgetc(f);
|
||||
|
||||
/* Skip leading zeros */
|
||||
for (; c=='0'; c = shgetc(f)) gotdig = 1;
|
||||
|
||||
if (c=='.') {
|
||||
gotrad = 1;
|
||||
c = shgetc(f);
|
||||
/* Count zeros after the radix point before significand */
|
||||
for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1;
|
||||
}
|
||||
|
||||
for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) {
|
||||
if (c=='.') {
|
||||
if (gotrad) break;
|
||||
rp = dc;
|
||||
gotrad = 1;
|
||||
} else {
|
||||
gotdig = 1;
|
||||
if (c > '9') d = (c|32)+10-'a';
|
||||
else d = c-'0';
|
||||
if (dc<8) {
|
||||
x = x*16 + d;
|
||||
} else if (dc < LDBL_MANT_DIG/4+1) {
|
||||
y += d*(scale/=16);
|
||||
} else if (d && !gottail) {
|
||||
y += 0.5*scale;
|
||||
gottail = 1;
|
||||
}
|
||||
dc++;
|
||||
}
|
||||
}
|
||||
if (!gotdig) {
|
||||
shunget(f);
|
||||
if (pok) {
|
||||
shunget(f);
|
||||
if (gotrad) shunget(f);
|
||||
} else {
|
||||
shlim(f, 0);
|
||||
}
|
||||
return sign * 0.0;
|
||||
}
|
||||
if (!gotrad) rp = dc;
|
||||
while (dc<8) x *= 16, dc++;
|
||||
if ((c|32)=='p') {
|
||||
e2 = scanexp(f, pok);
|
||||
if (e2 == LLONG_MIN) {
|
||||
if (pok) {
|
||||
shunget(f);
|
||||
} else {
|
||||
shlim(f, 0);
|
||||
return 0;
|
||||
}
|
||||
e2 = 0;
|
||||
}
|
||||
} else {
|
||||
shunget(f);
|
||||
}
|
||||
e2 += 4*rp - 32;
|
||||
|
||||
if (!x) return sign * 0.0;
|
||||
if (e2 > -emin) {
|
||||
errno = ERANGE;
|
||||
return sign * LDBL_MAX * LDBL_MAX;
|
||||
}
|
||||
if (e2 < emin-2*LDBL_MANT_DIG) {
|
||||
errno = ERANGE;
|
||||
return sign * LDBL_MIN * LDBL_MIN;
|
||||
}
|
||||
|
||||
while (x < 0x80000000) {
|
||||
if (y>=0.5) {
|
||||
x += x + 1;
|
||||
y += y - 1;
|
||||
} else {
|
||||
x += x;
|
||||
y += y;
|
||||
}
|
||||
e2--;
|
||||
}
|
||||
|
||||
if (bits > 32+e2-emin) {
|
||||
bits = 32+e2-emin;
|
||||
if (bits<0) bits=0;
|
||||
}
|
||||
|
||||
if (bits < LDBL_MANT_DIG)
|
||||
bias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign);
|
||||
|
||||
if (bits<32 && y && !(x&1)) x++, y=0;
|
||||
|
||||
y = bias + sign*(long double)x + sign*y;
|
||||
y -= bias;
|
||||
|
||||
if (!y) errno = ERANGE;
|
||||
|
||||
return scalbnl(y, e2);
|
||||
}
|
||||
|
||||
long double __floatscan(FILE *f, int prec, int pok)
|
||||
{
|
||||
int sign = 1;
|
||||
size_t i;
|
||||
int bits;
|
||||
int emin;
|
||||
int c;
|
||||
|
||||
switch (prec) {
|
||||
case 0:
|
||||
bits = FLT_MANT_DIG;
|
||||
emin = FLT_MIN_EXP-bits;
|
||||
break;
|
||||
case 1:
|
||||
bits = DBL_MANT_DIG;
|
||||
emin = DBL_MIN_EXP-bits;
|
||||
break;
|
||||
case 2:
|
||||
bits = LDBL_MANT_DIG;
|
||||
emin = LDBL_MIN_EXP-bits;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (isspace((c=shgetc(f))));
|
||||
|
||||
if (c=='+' || c=='-') {
|
||||
sign -= 2*(c=='-');
|
||||
c = shgetc(f);
|
||||
}
|
||||
|
||||
for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
|
||||
if (i<7) c = shgetc(f);
|
||||
if (i==3 || i==8 || (i>3 && pok)) {
|
||||
if (i!=8) {
|
||||
shunget(f);
|
||||
if (pok) for (; i>3; i--) shunget(f);
|
||||
}
|
||||
return sign * INFINITY;
|
||||
}
|
||||
if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++)
|
||||
if (i<2) c = shgetc(f);
|
||||
if (i==3) {
|
||||
if (shgetc(f) != '(') {
|
||||
shunget(f);
|
||||
return NAN;
|
||||
}
|
||||
for (i=1; ; i++) {
|
||||
c = shgetc(f);
|
||||
if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_')
|
||||
continue;
|
||||
if (c==')') return NAN;
|
||||
shunget(f);
|
||||
if (!pok) {
|
||||
errno = EINVAL;
|
||||
shlim(f, 0);
|
||||
return 0;
|
||||
}
|
||||
while (i--) shunget(f);
|
||||
return NAN;
|
||||
}
|
||||
return NAN;
|
||||
}
|
||||
|
||||
if (i) {
|
||||
shunget(f);
|
||||
errno = EINVAL;
|
||||
shlim(f, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c=='0') {
|
||||
c = shgetc(f);
|
||||
if ((c|32) == 'x')
|
||||
return hexfloat(f, bits, emin, sign, pok);
|
||||
shunget(f);
|
||||
c = '0';
|
||||
}
|
||||
|
||||
return decfloat(f, c, bits, emin, sign, pok);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef FLOATSCAN_H
|
||||
#define FLOATSCAN_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
hidden long double __floatscan(FILE *, int, int);
|
||||
|
||||
#endif
|
||||
@@ -1,100 +0,0 @@
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include "shgetc.h"
|
||||
|
||||
/* Lookup table for digit values. -1==255>=36 -> invalid */
|
||||
static const unsigned char table[] = { -1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
|
||||
25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
|
||||
25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
};
|
||||
|
||||
unsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long lim)
|
||||
{
|
||||
const unsigned char *val = table+1;
|
||||
int c, neg=0;
|
||||
unsigned x;
|
||||
unsigned long long y;
|
||||
if (base > 36 || base == 1) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
while (isspace((c=shgetc(f))));
|
||||
if (c=='+' || c=='-') {
|
||||
neg = -(c=='-');
|
||||
c = shgetc(f);
|
||||
}
|
||||
if ((base == 0 || base == 16) && c=='0') {
|
||||
c = shgetc(f);
|
||||
if ((c|32)=='x') {
|
||||
c = shgetc(f);
|
||||
if (val[c]>=16) {
|
||||
shunget(f);
|
||||
if (pok) shunget(f);
|
||||
else shlim(f, 0);
|
||||
return 0;
|
||||
}
|
||||
base = 16;
|
||||
} else if (base == 0) {
|
||||
base = 8;
|
||||
}
|
||||
} else {
|
||||
if (base == 0) base = 10;
|
||||
if (val[c] >= base) {
|
||||
shunget(f);
|
||||
shlim(f, 0);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (base == 10) {
|
||||
for (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f))
|
||||
x = x*10 + (c-'0');
|
||||
for (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f))
|
||||
y = y*10 + (c-'0');
|
||||
if (c-'0'>=10U) goto done;
|
||||
} else if (!(base & base-1)) {
|
||||
int bs = "\0\1\2\4\7\3\6\5"[(0x17*base)>>5&7];
|
||||
for (x=0; val[c]<base && x<=UINT_MAX/32; c=shgetc(f))
|
||||
x = x<<bs | val[c];
|
||||
for (y=x; val[c]<base && y<=ULLONG_MAX>>bs; c=shgetc(f))
|
||||
y = y<<bs | val[c];
|
||||
} else {
|
||||
for (x=0; val[c]<base && x<=UINT_MAX/36-1; c=shgetc(f))
|
||||
x = x*base + val[c];
|
||||
for (y=x; val[c]<base && y<=ULLONG_MAX/base && base*y<=ULLONG_MAX-val[c]; c=shgetc(f))
|
||||
y = y*base + val[c];
|
||||
}
|
||||
if (val[c]<base) {
|
||||
for (; val[c]<base; c=shgetc(f));
|
||||
errno = ERANGE;
|
||||
y = lim;
|
||||
if (lim&1) neg = 0;
|
||||
}
|
||||
done:
|
||||
shunget(f);
|
||||
if (y>=lim) {
|
||||
if (!(lim&1) && !neg) {
|
||||
errno = ERANGE;
|
||||
return lim-1;
|
||||
} else if (y>lim) {
|
||||
errno = ERANGE;
|
||||
return lim;
|
||||
}
|
||||
}
|
||||
return (y^neg)-neg;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef INTSCAN_H
|
||||
#define INTSCAN_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
hidden unsigned long long __intscan(FILE *, unsigned, int, unsigned long long);
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
#include "shgetc.h"
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#define __toread toread
|
||||
static int __toread(FILE *f)
|
||||
{
|
||||
f->mode |= f->mode-1;
|
||||
if (f->wpos != f->wbase) f->write(f, 0, 0);
|
||||
f->wpos = f->wbase = f->wend = 0;
|
||||
if (f->flags & F_NORD) {
|
||||
f->flags |= F_ERR;
|
||||
return EOF;
|
||||
}
|
||||
f->rpos = f->rend = f->buf + f->buf_size;
|
||||
return (f->flags & F_EOF) ? EOF : 0;
|
||||
}
|
||||
|
||||
#define __uflow uflow
|
||||
static int __uflow(FILE *f)
|
||||
{
|
||||
unsigned char c;
|
||||
if (!__toread(f) && f->read(f, &c, 1)==1) return c;
|
||||
return EOF;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The shcnt field stores the number of bytes read so far, offset by
|
||||
* the value of buf-rpos at the last function call (__shlim or __shgetc),
|
||||
* so that between calls the inline shcnt macro can add rpos-buf to get
|
||||
* the actual count. */
|
||||
|
||||
void __shlim(FILE *f, off_t lim)
|
||||
{
|
||||
f->shlim = lim;
|
||||
f->shcnt = f->buf - f->rpos;
|
||||
/* If lim is nonzero, rend must be a valid pointer. */
|
||||
if (lim && f->rend - f->rpos > lim)
|
||||
f->shend = f->rpos + lim;
|
||||
else
|
||||
f->shend = f->rend;
|
||||
}
|
||||
|
||||
int __shgetc(FILE *f)
|
||||
{
|
||||
int c;
|
||||
off_t cnt = shcnt(f);
|
||||
if (f->shlim && cnt >= f->shlim || (c=__uflow(f)) < 0) {
|
||||
f->shcnt = f->buf - f->rpos + cnt;
|
||||
f->shend = f->rpos;
|
||||
f->shlim = -1;
|
||||
return EOF;
|
||||
}
|
||||
cnt++;
|
||||
if (f->shlim && f->rend - f->rpos > f->shlim - cnt)
|
||||
f->shend = f->rpos + (f->shlim - cnt);
|
||||
else
|
||||
f->shend = f->rend;
|
||||
f->shcnt = f->buf - f->rpos + cnt;
|
||||
if (f->rpos <= f->buf) f->rpos[-1] = c;
|
||||
return c;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#include "stdio_impl.h"
|
||||
|
||||
/* Scan helper "stdio" functions for use by scanf-family and strto*-family
|
||||
* functions. These accept either a valid stdio FILE, or a minimal pseudo
|
||||
* FILE whose buffer pointers point into a null-terminated string. In the
|
||||
* latter case, the sh_fromstring macro should be used to setup the FILE;
|
||||
* the rest of the structure can be left uninitialized.
|
||||
*
|
||||
* To begin using these functions, shlim must first be called on the FILE
|
||||
* to set a field width limit, or 0 for no limit. For string pseudo-FILEs,
|
||||
* a nonzero limit is not valid and produces undefined behavior. After that,
|
||||
* shgetc, shunget, and shcnt are valid as long as no other stdio functions
|
||||
* are called on the stream.
|
||||
*
|
||||
* When used with a real FILE object, shunget has only one byte of pushback
|
||||
* available. Further shunget (up to a limit of the stdio UNGET buffer size)
|
||||
* will adjust the position but will not restore the data to be read again.
|
||||
* This functionality is needed for the wcsto*-family functions, where it's
|
||||
* okay because the FILE will be discarded immediately anyway. When used
|
||||
* with string pseudo-FILEs, shunget has unlimited pushback, back to the
|
||||
* beginning of the string. */
|
||||
|
||||
hidden void __shlim(FILE *, off_t);
|
||||
hidden int __shgetc(FILE *);
|
||||
|
||||
#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf))
|
||||
#define shlim(f, lim) __shlim((f), (lim))
|
||||
#define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : __shgetc(f))
|
||||
#define shunget(f) ((f)->shlim>=0 ? (void)(f)->rpos-- : (void)0)
|
||||
|
||||
#define sh_fromstring(f, s) \
|
||||
((f)->buf = (f)->rpos = (void *)(s), (f)->rend = (void*)-1)
|
||||
@@ -1,112 +0,0 @@
|
||||
#ifndef _STDIO_IMPL_H
|
||||
#define _STDIO_IMPL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "features.h"
|
||||
|
||||
#define UNGET 8
|
||||
|
||||
#define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0)
|
||||
#define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0)
|
||||
#define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0)
|
||||
|
||||
#define F_PERM 1
|
||||
#define F_NORD 4
|
||||
#define F_NOWR 8
|
||||
#define F_EOF 16
|
||||
#define F_ERR 32
|
||||
#define F_SVB 64
|
||||
#define F_APP 128
|
||||
|
||||
struct _IO_FILE {
|
||||
unsigned flags;
|
||||
unsigned char *rpos, *rend;
|
||||
int (*close)(FILE *);
|
||||
unsigned char *wend, *wpos;
|
||||
unsigned char *mustbezero_1;
|
||||
unsigned char *wbase;
|
||||
size_t (*read)(FILE *, unsigned char *, size_t);
|
||||
size_t (*write)(FILE *, const unsigned char *, size_t);
|
||||
off_t (*seek)(FILE *, off_t, int);
|
||||
unsigned char *buf;
|
||||
size_t buf_size;
|
||||
FILE *prev, *next;
|
||||
int fd;
|
||||
int pipe_pid;
|
||||
long lockcount;
|
||||
int mode;
|
||||
volatile int lock;
|
||||
int lbf;
|
||||
void *cookie;
|
||||
off_t off;
|
||||
char *getln_buf;
|
||||
void *mustbezero_2;
|
||||
unsigned char *shend;
|
||||
off_t shlim, shcnt;
|
||||
FILE *prev_locked, *next_locked;
|
||||
struct __locale_struct *locale;
|
||||
};
|
||||
|
||||
extern hidden FILE *volatile __stdin_used;
|
||||
extern hidden FILE *volatile __stdout_used;
|
||||
extern hidden FILE *volatile __stderr_used;
|
||||
|
||||
hidden int __lockfile(FILE *);
|
||||
hidden void __unlockfile(FILE *);
|
||||
|
||||
hidden size_t __stdio_read(FILE *, unsigned char *, size_t);
|
||||
hidden size_t __stdio_write(FILE *, const unsigned char *, size_t);
|
||||
hidden size_t __stdout_write(FILE *, const unsigned char *, size_t);
|
||||
hidden off_t __stdio_seek(FILE *, off_t, int);
|
||||
hidden int __stdio_close(FILE *);
|
||||
|
||||
hidden int __toread(FILE *);
|
||||
hidden int __towrite(FILE *);
|
||||
|
||||
hidden void __stdio_exit(void);
|
||||
hidden void __stdio_exit_needed(void);
|
||||
|
||||
#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303)
|
||||
__attribute__((visibility("protected")))
|
||||
#endif
|
||||
int __overflow(FILE *, int), __uflow(FILE *);
|
||||
|
||||
hidden int __fseeko(FILE *, off_t, int);
|
||||
hidden int __fseeko_unlocked(FILE *, off_t, int);
|
||||
hidden off_t __ftello(FILE *);
|
||||
hidden off_t __ftello_unlocked(FILE *);
|
||||
hidden size_t __fwritex(const unsigned char *, size_t, FILE *);
|
||||
hidden int __putc_unlocked(int, FILE *);
|
||||
|
||||
hidden FILE *__fdopen(int, const char *);
|
||||
hidden int __fmodeflags(const char *);
|
||||
|
||||
hidden FILE *__ofl_add(FILE *f);
|
||||
hidden FILE **__ofl_lock(void);
|
||||
hidden void __ofl_unlock(void);
|
||||
|
||||
struct __pthread;
|
||||
hidden void __register_locked_file(FILE *, struct __pthread *);
|
||||
hidden void __unlist_locked_file(FILE *);
|
||||
hidden void __do_orphaned_stdio_locks(void);
|
||||
|
||||
#define MAYBE_WAITERS 0x40000000
|
||||
|
||||
hidden void __getopt_msg(const char *, const char *, const char *, size_t);
|
||||
|
||||
#define feof(f) ((f)->flags & F_EOF)
|
||||
#define ferror(f) ((f)->flags & F_ERR)
|
||||
|
||||
#define getc_unlocked(f) \
|
||||
( ((f)->rpos != (f)->rend) ? *(f)->rpos++ : __uflow((f)) )
|
||||
|
||||
#define putc_unlocked(c, f) \
|
||||
( (((unsigned char)(c)!=(f)->lbf && (f)->wpos!=(f)->wend)) \
|
||||
? *(f)->wpos++ = (unsigned char)(c) \
|
||||
: __overflow((f),(unsigned char)(c)) )
|
||||
|
||||
/* Caller-allocated FILE * operations */
|
||||
hidden FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);
|
||||
hidden int __fclose_ca(FILE *);
|
||||
|
||||
#endif
|
||||
@@ -12,11 +12,6 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
ecvt.c
|
||||
fcvt.c
|
||||
gcvt.c
|
||||
|
||||
strtod.c
|
||||
strtol.c
|
||||
wcstod.c
|
||||
wcstol.c
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include "shgetc.h"
|
||||
#include "floatscan.h"
|
||||
#include "stdio_impl.h"
|
||||
|
||||
static long double strtox(const char *s, char **p, int prec)
|
||||
{
|
||||
FILE f;
|
||||
sh_fromstring(&f, s);
|
||||
shlim(&f, 0);
|
||||
{
|
||||
long double y = __floatscan(&f, prec, 1);
|
||||
off_t cnt = shcnt(&f);
|
||||
if (p) *p = cnt ? (char *)s + cnt : (char *)s;
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
float strtof(const char *restrict s, char **restrict p)
|
||||
{
|
||||
return strtox(s, p, 0);
|
||||
}
|
||||
|
||||
double strtod(const char *restrict s, char **restrict p)
|
||||
{
|
||||
return strtox(s, p, 1);
|
||||
}
|
||||
|
||||
long double strtold(const char *restrict s, char **restrict p)
|
||||
{
|
||||
return strtox(s, p, 2);
|
||||
}
|
||||
|
||||
#ifdef __HAIKU__
|
||||
weak_alias(strtof, __strtof_internal);
|
||||
weak_alias(strtod, __strtod_internal);
|
||||
weak_alias(strtold, __strtold_internal);
|
||||
#endif
|
||||
@@ -1,46 +0,0 @@
|
||||
#include "stdio_impl.h"
|
||||
#include "intscan.h"
|
||||
#include "shgetc.h"
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim)
|
||||
{
|
||||
FILE f;
|
||||
sh_fromstring(&f, s);
|
||||
shlim(&f, 0);
|
||||
{
|
||||
unsigned long long y = __intscan(&f, base, 1, lim);
|
||||
if (p) {
|
||||
size_t cnt = shcnt(&f);
|
||||
*p = (char *)s + cnt;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long strtoull(const char *restrict s, char **restrict p, int base)
|
||||
{
|
||||
return strtox(s, p, base, ULLONG_MAX);
|
||||
}
|
||||
|
||||
long long strtoll(const char *restrict s, char **restrict p, int base)
|
||||
{
|
||||
return strtox(s, p, base, LLONG_MIN);
|
||||
}
|
||||
|
||||
unsigned long strtoul(const char *restrict s, char **restrict p, int base)
|
||||
{
|
||||
return strtox(s, p, base, ULONG_MAX);
|
||||
}
|
||||
|
||||
long strtol(const char *restrict s, char **restrict p, int base)
|
||||
{
|
||||
return strtox(s, p, base, 0UL+LONG_MIN);
|
||||
}
|
||||
|
||||
weak_alias(strtol, __strtol_internal);
|
||||
weak_alias(strtoul, __strtoul_internal);
|
||||
weak_alias(strtoll, __strtoll_internal);
|
||||
weak_alias(strtoull, __strtoull_internal);
|
||||
@@ -1,72 +0,0 @@
|
||||
#include "shgetc.h"
|
||||
#include "floatscan.h"
|
||||
#include "stdio_impl.h"
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
/* This read function heavily cheats. It knows:
|
||||
* (1) len will always be 1
|
||||
* (2) non-ascii characters don't matter */
|
||||
|
||||
static size_t do_read(FILE *f, unsigned char *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
const wchar_t *wcs = f->cookie;
|
||||
|
||||
if (!wcs[0]) wcs=L"@";
|
||||
for (i=0; i<f->buf_size && wcs[i]; i++)
|
||||
f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
|
||||
f->rpos = f->buf;
|
||||
f->rend = f->buf + i;
|
||||
f->cookie = (void *)(wcs+i);
|
||||
|
||||
if (i && len) {
|
||||
*buf = *f->rpos++;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long double wcstox(const wchar_t *s, wchar_t **p, int prec)
|
||||
{
|
||||
wchar_t *t = (wchar_t *)s;
|
||||
unsigned char buf[64];
|
||||
FILE f = {0};
|
||||
f.flags = 0;
|
||||
f.rpos = f.rend = f.buf = buf + 4;
|
||||
f.buf_size = sizeof buf - 4;
|
||||
f.lock = -1;
|
||||
f.read = do_read;
|
||||
while (iswspace(*t)) t++;
|
||||
f.cookie = (void *)t;
|
||||
shlim(&f, 0);
|
||||
{
|
||||
long double y = __floatscan(&f, prec, 1);
|
||||
if (p) {
|
||||
size_t cnt = shcnt(&f);
|
||||
*p = cnt ? t + cnt : (wchar_t *)s;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
float wcstof(const wchar_t *restrict s, wchar_t **restrict p)
|
||||
{
|
||||
return wcstox(s, p, 0);
|
||||
}
|
||||
|
||||
double wcstod(const wchar_t *restrict s, wchar_t **restrict p)
|
||||
{
|
||||
return wcstox(s, p, 1);
|
||||
}
|
||||
|
||||
long double wcstold(const wchar_t *restrict s, wchar_t **restrict p)
|
||||
{
|
||||
return wcstox(s, p, 2);
|
||||
}
|
||||
|
||||
#ifdef __HAIKU__
|
||||
weak_alias(wcstof, __wcstof_internal);
|
||||
weak_alias(wcstod, __wcstod_internal);
|
||||
weak_alias(wcstold, __wcstold_internal);
|
||||
#endif
|
||||
@@ -1,90 +0,0 @@
|
||||
#include "stdio_impl.h"
|
||||
#include "intscan.h"
|
||||
#include "shgetc.h"
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
|
||||
/* This read function heavily cheats. It knows:
|
||||
* (1) len will always be 1
|
||||
* (2) non-ascii characters don't matter */
|
||||
|
||||
static size_t do_read(FILE *f, unsigned char *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
const wchar_t *wcs = f->cookie;
|
||||
|
||||
if (!wcs[0]) wcs=L"@";
|
||||
for (i=0; i<f->buf_size && wcs[i]; i++)
|
||||
f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
|
||||
f->rpos = f->buf;
|
||||
f->rend = f->buf + i;
|
||||
f->cookie = (void *)(wcs+i);
|
||||
|
||||
if (i && len) {
|
||||
*buf = *f->rpos++;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim)
|
||||
{
|
||||
wchar_t *t = (wchar_t *)s;
|
||||
unsigned char buf[64];
|
||||
FILE f = {0};
|
||||
f.flags = 0;
|
||||
f.rpos = f.rend = f.buf = buf + 4;
|
||||
f.buf_size = sizeof buf - 4;
|
||||
f.lock = -1;
|
||||
f.read = do_read;
|
||||
while (iswspace(*t)) t++;
|
||||
f.cookie = (void *)t;
|
||||
shlim(&f, 0);
|
||||
{
|
||||
unsigned long long y = __intscan(&f, base, 1, lim);
|
||||
if (p) {
|
||||
size_t cnt = shcnt(&f);
|
||||
*p = cnt ? t + cnt : (wchar_t *)s;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
||||
{
|
||||
return wcstox(s, p, base, ULLONG_MAX);
|
||||
}
|
||||
|
||||
long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
||||
{
|
||||
return wcstox(s, p, base, LLONG_MIN);
|
||||
}
|
||||
|
||||
unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
||||
{
|
||||
return wcstox(s, p, base, ULONG_MAX);
|
||||
}
|
||||
|
||||
long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
||||
{
|
||||
return wcstox(s, p, base, 0UL+LONG_MIN);
|
||||
}
|
||||
|
||||
intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
||||
{
|
||||
return wcstoll(s, p, base);
|
||||
}
|
||||
|
||||
uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base)
|
||||
{
|
||||
return wcstoull(s, p, base);
|
||||
}
|
||||
|
||||
#ifdef __HAIKU__
|
||||
weak_alias(wcstol, __wcstol_internal);
|
||||
weak_alias(wcstoul, __wcstoul_internal);
|
||||
weak_alias(wcstoll, __wcstoll_internal);
|
||||
weak_alias(wcstoull, __wcstoull_internal);
|
||||
#endif
|
||||
Reference in New Issue
Block a user