* ada-lex.l (HIGH_BYTE_POSN, is_digit_in_base, digit_to_int)
(strtoulst): Moved to ... * utils.c (HIGH_BYTE_POSN, is_digit_in_base, digit_to_int) (strtoulst): ... here. Enhanced to behave more similarly to strtoul. * defs.h (strtoulst): New prototype.
This commit is contained in:
parent
c96fc75e9e
commit
253c8abb67
4 changed files with 110 additions and 62 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2006-09-21 Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
|
* ada-lex.l (HIGH_BYTE_POSN, is_digit_in_base, digit_to_int)
|
||||||
|
(strtoulst): Moved to ...
|
||||||
|
* utils.c (HIGH_BYTE_POSN, is_digit_in_base, digit_to_int)
|
||||||
|
(strtoulst): ... here. Enhanced to behave more similarly
|
||||||
|
to strtoul.
|
||||||
|
* defs.h (strtoulst): New prototype.
|
||||||
|
|
||||||
2006-09-21 Daniel Jacobowitz <dan@codesourcery.com>
|
2006-09-21 Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
* Makefile.in (memattr_h, memattr.o): Update.
|
* Makefile.in (memattr_h, memattr.o): Update.
|
||||||
|
|
|
@ -296,68 +296,6 @@ canonicalizeNumeral (char *s1, const char *s2)
|
||||||
s1[0] = '\000';
|
s1[0] = '\000';
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
|
|
||||||
|
|
||||||
/* True (non-zero) iff DIGIT is a valid digit in radix BASE,
|
|
||||||
where 2 <= BASE <= 16. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
is_digit_in_base (unsigned char digit, int base)
|
|
||||||
{
|
|
||||||
if (!isxdigit (digit))
|
|
||||||
return 0;
|
|
||||||
if (base <= 10)
|
|
||||||
return (isdigit (digit) && digit < base + '0');
|
|
||||||
else
|
|
||||||
return (isdigit (digit) || tolower (digit) < base - 10 + 'a');
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
digit_to_int (unsigned char c)
|
|
||||||
{
|
|
||||||
if (isdigit (c))
|
|
||||||
return c - '0';
|
|
||||||
else
|
|
||||||
return tolower (c) - 'a' + 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* As for strtoul, but for ULONGEST results. */
|
|
||||||
|
|
||||||
ULONGEST
|
|
||||||
strtoulst (const char *num, const char **trailer, int base)
|
|
||||||
{
|
|
||||||
unsigned int high_part;
|
|
||||||
ULONGEST result;
|
|
||||||
int i;
|
|
||||||
unsigned char lim;
|
|
||||||
|
|
||||||
if (base < 2 || base > 16)
|
|
||||||
{
|
|
||||||
errno = EINVAL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lim = base - 1 + '0';
|
|
||||||
|
|
||||||
result = high_part = 0;
|
|
||||||
for (i = 0; is_digit_in_base (num[i], base); i += 1)
|
|
||||||
{
|
|
||||||
result = result*base + digit_to_int (num[i]);
|
|
||||||
high_part = high_part*base + (unsigned int) (result >> HIGH_BYTE_POSN);
|
|
||||||
result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
|
|
||||||
if (high_part > 0xff)
|
|
||||||
{
|
|
||||||
errno = ERANGE;
|
|
||||||
result = high_part = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trailer != NULL)
|
|
||||||
*trailer = &num[i];
|
|
||||||
|
|
||||||
return result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interprets the prefix of NUM that consists of digits of the given BASE
|
/* Interprets the prefix of NUM that consists of digits of the given BASE
|
||||||
as an integer of that BASE, with the string EXP as an exponent.
|
as an integer of that BASE, with the string EXP as an exponent.
|
||||||
Puts value in yylval, and returns INT, if the string is valid. Causes
|
Puts value in yylval, and returns INT, if the string is valid. Causes
|
||||||
|
|
|
@ -415,6 +415,8 @@ extern char *xfullpath (const char *);
|
||||||
extern unsigned long gnu_debuglink_crc32 (unsigned long crc,
|
extern unsigned long gnu_debuglink_crc32 (unsigned long crc,
|
||||||
unsigned char *buf, size_t len);
|
unsigned char *buf, size_t len);
|
||||||
|
|
||||||
|
ULONGEST strtoulst (const char *num, const char **trailer, int base);
|
||||||
|
|
||||||
/* From demangle.c */
|
/* From demangle.c */
|
||||||
|
|
||||||
extern void set_demangling_style (char *);
|
extern void set_demangling_style (char *);
|
||||||
|
|
99
gdb/utils.c
99
gdb/utils.c
|
@ -3139,3 +3139,102 @@ dummy_obstack_deallocate (void *object, void *data)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The bit offset of the highest byte in a ULONGEST, for overflow
|
||||||
|
checking. */
|
||||||
|
|
||||||
|
#define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
|
||||||
|
|
||||||
|
/* True (non-zero) iff DIGIT is a valid digit in radix BASE,
|
||||||
|
where 2 <= BASE <= 36. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_digit_in_base (unsigned char digit, int base)
|
||||||
|
{
|
||||||
|
if (!isalnum (digit))
|
||||||
|
return 0;
|
||||||
|
if (base <= 10)
|
||||||
|
return (isdigit (digit) && digit < base + '0');
|
||||||
|
else
|
||||||
|
return (isdigit (digit) || tolower (digit) < base - 10 + 'a');
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
digit_to_int (unsigned char c)
|
||||||
|
{
|
||||||
|
if (isdigit (c))
|
||||||
|
return c - '0';
|
||||||
|
else
|
||||||
|
return tolower (c) - 'a' + 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* As for strtoul, but for ULONGEST results. */
|
||||||
|
|
||||||
|
ULONGEST
|
||||||
|
strtoulst (const char *num, const char **trailer, int base)
|
||||||
|
{
|
||||||
|
unsigned int high_part;
|
||||||
|
ULONGEST result;
|
||||||
|
int minus = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
/* Skip leading whitespace. */
|
||||||
|
while (isspace (num[i]))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
/* Handle prefixes. */
|
||||||
|
if (num[i] == '+')
|
||||||
|
i++;
|
||||||
|
else if (num[i] == '-')
|
||||||
|
{
|
||||||
|
minus = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base == 0 || base == 16)
|
||||||
|
{
|
||||||
|
if (num[i] == '0' && (num[i + 1] == 'x' || num[i + 1] == 'X'))
|
||||||
|
{
|
||||||
|
i += 2;
|
||||||
|
if (base == 0)
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base == 0 && num[i] == '0')
|
||||||
|
base = 8;
|
||||||
|
|
||||||
|
if (base == 0)
|
||||||
|
base = 10;
|
||||||
|
|
||||||
|
if (base < 2 || base > 36)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = high_part = 0;
|
||||||
|
for (; is_digit_in_base (num[i], base); i += 1)
|
||||||
|
{
|
||||||
|
result = result * base + digit_to_int (num[i]);
|
||||||
|
high_part = high_part * base + (unsigned int) (result >> HIGH_BYTE_POSN);
|
||||||
|
result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
|
||||||
|
if (high_part > 0xff)
|
||||||
|
{
|
||||||
|
errno = ERANGE;
|
||||||
|
result = ~ (ULONGEST) 0;
|
||||||
|
high_part = 0;
|
||||||
|
minus = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trailer != NULL)
|
||||||
|
*trailer = &num[i];
|
||||||
|
|
||||||
|
result = result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
|
||||||
|
if (minus)
|
||||||
|
return -result;
|
||||||
|
else
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue