1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] If strtoll is not present, check for strtoimax and use it where available.

If neither is present, define own strtoll.
This commit is contained in:
hniksic 2005-08-11 14:18:56 -07:00
parent 47aa191838
commit f25d593c16
7 changed files with 156 additions and 116 deletions

View File

@ -1,3 +1,7 @@
2005-08-11 Hrvoje Niksic <hniksic@xemacs.org>
* configure.in: Check for strtoll and strtoimax.
2005-07-08 Hrvoje Niksic <hniksic@xemacs.org>
* configure.in: Remove -Wno-implicit from default GCC warning

View File

@ -205,7 +205,7 @@ AC_FUNC_ALLOCA
AC_FUNC_MMAP
AC_FUNC_FSEEKO
AC_CHECK_FUNCS(strptime timegm snprintf vsnprintf vasprintf drand48)
AC_CHECK_FUNCS(usleep ftello sigblock sigsetjmp)
AC_CHECK_FUNCS(strtoll strtoimax usleep ftello sigblock sigsetjmp)
dnl We expect to have these functions on Unix-like systems configure
dnl runs on. The defines are provided to get them in config.h.in so

View File

@ -1,3 +1,10 @@
2005-08-11 Hrvoje Niksic <hniksic@xemacs.org>
* cmpt.c (strtoll): Define it if missing on the system and if Wget
needs it.
* mswindows.c (str_to_int64): Move to cmpt.c and rename to strtoll.
2005-08-10 Hrvoje Niksic <hniksic@xemacs.org>
* host.c (print_address): Always use inet_ntop when IPv6 is

View File

@ -1266,3 +1266,128 @@ timegm (struct tm *t)
return (time_t) secs;
}
#endif /* HAVE_TIMEGM */
#ifdef NEED_STRTOLL
/* strtoll is required by C99 and used by Wget only on systems with
LFS. Unfortunately, some systems have LFS, but no strtoll or
equivalent. These include HPUX 11.0 and Windows.
We use #ifdef NEED_STRTOLL instead of #ifndef HAVE_STRTOLL because
of the systems which have a suitable replacement (e.g. _strtoi64 on
Windows), on which Wget's str_to_wgint is instructed to use that
instead. */
static inline int
char_value (char c, int base)
{
int value;
if (c < '0')
return -1;
if ('0' <= c && c <= '9')
value = c - '0';
else if ('a' <= c && c <= 'z')
value = c - 'a' + 10;
else if ('A' <= c && c <= 'Z')
value = c - 'A' + 10;
else
return -1;
if (value >= base)
return -1;
return value;
}
#define LL strtoll_return /* long long or __int64 */
/* These constants assume 64-bit strtoll_return. */
/* A roundabout way of writing 2**63-1 = 9223372036854775807 */
#define STRTOLL_OVERFLOW (((LL) 1 << 62) - 1 + ((LL) 1 << 62))
/* A roundabout way of writing -2**63 = -9223372036854775808 */
#define STRTOLL_UNDERFLOW (-STRTOLL_OVERFLOW - 1)
/* A strtoll replacement for systems that have LFS but don't supply
strtoll. The headers typedef strtoll_return to long long or to
__int64. */
strtoll_return
strtoll (const char *nptr, char **endptr, int base)
{
strtoll_return result = 0;
bool negative;
if (base != 0 && (base < 2 || base > 36))
{
errno = EINVAL;
return 0;
}
while (*nptr == ' ' || *nptr == '\t')
++nptr;
if (*nptr == '-')
{
negative = true;
++nptr;
}
else if (*nptr == '+')
{
negative = false;
++nptr;
}
else
negative = false;
/* If base is 0, determine the real base based on the beginning on
the number; octal numbers begin with "0", hexadecimal with "0x",
and the others are considered octal. */
if (*nptr == '0')
{
if ((base == 0 || base == 16)
&&
(*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
{
base = 16;
nptr += 2;
}
else if (base == 0)
base = 8;
}
else if (base == 0)
base = 10;
if (!negative)
{
/* Parse positive number, checking for overflow. */
int val;
for (; (val = char_value (*nptr, base)) != -1; ++nptr)
{
strtoll_return newresult = base * result + val;
if (newresult < result)
{
result = STRTOLL_OVERFLOW;
errno = ERANGE;
break;
}
result = newresult;
}
}
else
{
/* Parse negative number, checking for underflow. */
int val;
for (; (val = char_value (*nptr, base)) != -1; ++nptr)
{
strtoll_return newresult = base * result - val;
if (newresult > result)
{
result = STRTOLL_UNDERFLOW;
errno = ERANGE;
break;
}
result = newresult;
}
}
if (endptr)
*endptr = (char *) nptr;
return result;
}
#endif /* NEED_STRTOLL */

View File

@ -72,116 +72,6 @@ xsleep (double seconds)
#endif /* not HAVE_USLEEP */
}
#if !defined(HAVE_STRTOLL) && !defined(HAVE__STRTOI64)
static inline int
char_value (char c, int base)
{
int value;
if (c < '0')
return -1;
if ('0' <= c && c <= '9')
value = c - '0';
else if ('a' <= c && c <= 'z')
value = c - 'a' + 10;
else if ('A' <= c && c <= 'Z')
value = c - 'A' + 10;
else
return -1;
if (value >= base)
return -1;
return value;
}
/* A fairly simple strtoll replacement for MS VC versions that don't
supply _strtoi64. */
__int64
str_to_int64 (const char *nptr, char **endptr, int base)
{
#define INT64_OVERFLOW 9223372036854775807I64
#define INT64_UNDERFLOW (-INT64_OVERFLOW - 1)
__int64 result = 0;
bool negative;
if (base != 0 && (base < 2 || base > 36))
{
errno = EINVAL;
return 0;
}
while (*nptr == ' ' || *nptr == '\t')
++nptr;
if (*nptr == '-')
{
negative = true;
++nptr;
}
else if (*nptr == '+')
{
negative = false;
++nptr;
}
else
negative = false;
/* If base is 0, determine the real base based on the beginning on
the number; octal numbers begin with "0", hexadecimal with "0x",
and the others are considered octal. */
if (*nptr == '0')
{
if ((base == 0 || base == 16)
&&
(*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
{
base = 16;
nptr += 2;
}
else if (base == 0)
base = 8;
}
else if (base == 0)
base = 10;
if (!negative)
{
/* Parse positive number, checking for overflow. */
int val;
for (; (val = char_value (*nptr, base)) != -1; ++nptr)
{
__int64 newresult = base * result + val;
if (newresult < result)
{
result = INT64_OVERFLOW;
errno = ERANGE;
break;
}
result = newresult;
}
}
else
{
/* Parse negative number, checking for underflow. */
int val;
for (; (val = char_value (*nptr, base)) != -1; ++nptr)
{
__int64 newresult = base * result - val;
if (newresult > result)
{
result = INT64_UNDERFLOW;
errno = ERANGE;
break;
}
result = newresult;
}
}
if (endptr)
*endptr = (char *) nptr;
return result;
}
#endif
void
windows_main (int *argc, char **argv, char **exec_name)
{

View File

@ -86,15 +86,16 @@ typedef __int64 wgint;
#define SIZEOF_WGINT 8
#define WGINT_MAX LL (9223372036854775807)
/* str_to_wgint is a function with the semantics of strtol, but which
works on wgint. */
/* str_to_wgint is a function with the semantics of strtol[l], but
which works on wgint. */
#if defined HAVE_STRTOLL
# define str_to_wgint strtoll
#elif defined HAVE__STRTOI64
# define str_to_wgint _strtoi64
#else
__int64 str_to_int64 (const char *, char **, int);
# define str_to_wgint str_to_int64
# define str_to_wgint strtoll
# define NEED_STRTOLL
# define strtoll_return __int64
#endif
/* Windows has no symlink, therefore no lstat. Without symlinks lstat

View File

@ -133,11 +133,24 @@ typedef off_t wgint;
# define str_to_wgint strtol
# define WGINT_MAX LONG_MAX
# else
# define str_to_wgint strtoll
# define WGINT_MAX LLONG_MAX
# ifdef HAVE_STRTOLL
# define str_to_wgint strtoll
# elif HAVE_STRTOIMAX
# define str_to_wgint strtoimax
# else
# define str_to_wgint strtoll
# define NEED_STRTOLL
# define strtoll_return long long
# endif
# endif
#endif
/* Declare our strtoll replacement. */
#ifdef NEED_STRTOLL
strtoll_return strtoll (const char *, char **, int);
#endif
/* Now define a large integral type useful for storing sizes of *sums*
of downloads, such as the value of the --quota option. This should
be a type able to hold 2G+ values even on systems without large