Browse Source

* 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.
gdb_6_6-branch
Daniel Jacobowitz 20 years ago
parent
commit
253c8abb67
  1. 9
      gdb/ChangeLog
  2. 62
      gdb/ada-lex.l
  3. 2
      gdb/defs.h
  4. 99
      gdb/utils.c

9
gdb/ChangeLog

@ -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>
* Makefile.in (memattr_h, memattr.o): Update.

62
gdb/ada-lex.l

@ -296,68 +296,6 @@ canonicalizeNumeral (char *s1, const char *s2)
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
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

2
gdb/defs.h

@ -415,6 +415,8 @@ extern char *xfullpath (const char *);
extern unsigned long gnu_debuglink_crc32 (unsigned long crc,
unsigned char *buf, size_t len);
ULONGEST strtoulst (const char *num, const char **trailer, int base);
/* From demangle.c */
extern void set_demangling_style (char *);

99
gdb/utils.c

@ -3139,3 +3139,102 @@ dummy_obstack_deallocate (void *object, void *data)
{
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…
Cancel
Save