* ada-lex.l (HIGH_BYTE_POSN, is_digit_in_base, digit_to_int)
authorDaniel Jacobowitz <drow@false.org>
Thu, 21 Sep 2006 13:50:51 +0000 (13:50 +0000)
committerDaniel Jacobowitz <drow@false.org>
Thu, 21 Sep 2006 13:50:51 +0000 (13:50 +0000)
(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/ChangeLog
gdb/ada-lex.l
gdb/defs.h
gdb/utils.c

index 1ff1fa6b47694a1b5770f1b1516cc1997f713dfe..6b84a4b14d71438887ed283c06c164405cac713b 100644 (file)
@@ -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.
index b25264cadadced26c4d9fd28813dcc737497e8be..7ece1090c967cf8f9a7ac8dffed83fdd2768f944 100644 (file)
@@ -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
index c9d55041fb915056ab2d8303e14e040856b08e85..f7dfbacabd9f327e4c7452dc2a5f23d3a45190b8 100644 (file)
@@ -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 *);
index 6c4afb7daac784c6abec995ac6f6fef4dd6bce56..cf5ef19b9d9b78e85d84b884010acaac182b37b0 100644 (file)
@@ -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;
+}