1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-02-15 11:52:15 +02:00

Sync with gnulib.

This commit is contained in:
Jim Meyering
2003-10-15 07:26:36 +00:00
parent 7edceab01c
commit c8043fb655
4 changed files with 62 additions and 24 deletions

View File

@@ -27,6 +27,8 @@
# define __strtol strtol
# define __strtol_t long int
# define __xstrtol xstrtol
# define STRTOL_T_MINIMUM LONG_MIN
# define STRTOL_T_MAXIMUM LONG_MAX
#endif
/* Some pre-ANSI implementations (e.g. SunOS 4)
@@ -47,6 +49,15 @@ extern int errno;
/* The extra casts work around common compiler bugs. */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
: (t) 0))
#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
#ifndef STRTOL_T_MINIMUM
# define STRTOL_T_MINIMUM TYPE_MINIMUM (__strtol_t)
# define STRTOL_T_MAXIMUM TYPE_MAXIMUM (__strtol_t)
#endif
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
# define IN_CTYPE_DOMAIN(c) 1
@@ -66,24 +77,30 @@ intmax_t strtoimax ();
uintmax_t strtoumax ();
#endif
static int
static strtol_error
bkm_scale (__strtol_t *x, int scale_factor)
{
__strtol_t product = *x * scale_factor;
if (*x != product / scale_factor)
return 1;
*x = product;
return 0;
if (TYPE_SIGNED (__strtol_t) && *x < STRTOL_T_MINIMUM / scale_factor)
{
*x = STRTOL_T_MINIMUM;
return LONGINT_OVERFLOW;
}
if (STRTOL_T_MAXIMUM / scale_factor < *x)
{
*x = STRTOL_T_MAXIMUM;
return LONGINT_OVERFLOW;
}
*x *= scale_factor;
return LONGINT_OK;
}
static int
static strtol_error
bkm_scale_by_power (__strtol_t *x, int base, int power)
{
strtol_error err = LONGINT_OK;
while (power--)
if (bkm_scale (x, base))
return 1;
return 0;
err |= bkm_scale (x, base);
return err;
}
/* FIXME: comment. */
@@ -95,6 +112,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
char *t_ptr;
char **p;
__strtol_t tmp;
strtol_error err = LONGINT_OK;
assert (0 <= strtol_base && strtol_base <= 36);
@@ -111,8 +129,6 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
errno = 0;
tmp = __strtol (s, p, strtol_base);
if (errno != 0)
return LONGINT_OVERFLOW;
if (*p == s)
{
@@ -123,6 +139,12 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
else
return LONGINT_INVALID;
}
else if (errno != 0)
{
if (errno != ERANGE)
return LONGINT_INVALID;
err = LONGINT_OVERFLOW;
}
/* Let valid_suffixes == NULL mean `allow any suffix'. */
/* FIXME: update all callers except the ones that allow suffixes
@@ -130,19 +152,19 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
if (!valid_suffixes)
{
*val = tmp;
return LONGINT_OK;
return err;
}
if (**p != '\0')
{
int base = 1024;
int suffixes = 1;
int overflow;
strtol_error overflow;
if (!strchr (valid_suffixes, **p))
{
*val = tmp;
return LONGINT_INVALID_SUFFIX_CHAR;
return err | LONGINT_INVALID_SUFFIX_CHAR;
}
if (strchr (valid_suffixes, '0'))
@@ -225,18 +247,18 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
default:
*val = tmp;
return LONGINT_INVALID_SUFFIX_CHAR;
return err | LONGINT_INVALID_SUFFIX_CHAR;
break;
}
if (overflow)
return LONGINT_OVERFLOW;
(*p) += suffixes;
err |= overflow;
*p += suffixes;
if (**p)
err |= LONGINT_INVALID_SUFFIX_CHAR;
}
*val = tmp;
return LONGINT_OK;
return err;
}
#ifdef TESTING_XSTRTO

View File

@@ -32,7 +32,16 @@
# ifndef _STRTOL_ERROR
enum strtol_error
{
LONGINT_OK, LONGINT_INVALID, LONGINT_INVALID_SUFFIX_CHAR, LONGINT_OVERFLOW
LONGINT_OK = 0,
/* These two values can be ORed together, to indicate that both
errors occurred. */
LONGINT_OVERFLOW = 1,
LONGINT_INVALID_SUFFIX_CHAR = 2,
LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW = (LONGINT_INVALID_SUFFIX_CHAR
| LONGINT_OVERFLOW),
LONGINT_INVALID = 4
};
typedef enum strtol_error strtol_error;
# endif
@@ -49,7 +58,7 @@ _DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
{ \
switch ((Err)) \
{ \
case LONGINT_OK: \
default: \
abort (); \
\
case LONGINT_INVALID: \
@@ -58,6 +67,7 @@ _DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
break; \
\
case LONGINT_INVALID_SUFFIX_CHAR: \
case LONGINT_INVALID_SUFFIX_CHAR | LONGINT_OVERFLOW: \
error ((Exit_code), 0, "invalid character following %s in `%s'", \
(Argument_type_string), (Str)); \
break; \

View File

@@ -1,4 +1,6 @@
#define __strtol strtoul
#define __strtol_t unsigned long int
#define __xstrtol xstrtoul
#define STRTOL_T_MINIMUM 0
#define STRTOL_T_MAXIMUM ULONG_MAX
#include "xstrtol.c"

View File

@@ -30,4 +30,8 @@
#define __strtol strtoumax
#define __strtol_t uintmax_t
#define __xstrtol xstrtoumax
#ifdef UINTMAX_MAX
# define STRTOL_T_MINIMUM 0
# define STRTOL_T_MAXIMUM UINTMAX_MAX
#endif
#include "xstrtol.c"