home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / ansi / stdlib / strtoull.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-24  |  1.7 KB  |  77 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
  3. #include <limits.h>
  4. #include <ctype.h>
  5. #include <errno.h>
  6. #include <stdlib.h>
  7. #include <libc/unconst.h>
  8.  
  9. /*
  10.  * Convert a string to an unsigned long long integer.
  11.  *
  12.  * Ignores `locale' stuff.  Assumes that the upper and lower case
  13.  * alphabets and digits are each contiguous.
  14.  */
  15. unsigned long long
  16. strtoull(const char *nptr, char **endptr, int base)
  17. {
  18.   const char *s = nptr;
  19.   unsigned long long acc;
  20.   int c;
  21.   unsigned long long cutoff;
  22.   int neg = 0, any, cutlim;
  23.  
  24.   /*
  25.    * See strtol for comments as to the logic used.
  26.    */
  27.   do {
  28.     c = *s++;
  29.   } while (isspace(c));
  30.   if (c == '-')
  31.   {
  32.     neg = 1;
  33.     c = *s++;
  34.   }
  35.   else if (c == '+')
  36.     c = *s++;
  37.   if ((base == 0 || base == 16) &&
  38.       c == '0' && (*s == 'x' || *s == 'X'))
  39.   {
  40.     c = s[1];
  41.     s += 2;
  42.     base = 16;
  43.   }
  44.   if (base == 0)
  45.     base = c == '0' ? 8 : 10;
  46.   cutoff = (unsigned long long)ULLONG_MAX / base;
  47.   cutlim = (unsigned long long)ULLONG_MAX % base;
  48.   for (acc = 0, any = 0;; c = *s++)
  49.   {
  50.     if (isdigit(c))
  51.       c -= '0';
  52.     else if (isalpha(c))
  53.       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
  54.     else
  55.       break;
  56.     if (c >= base)
  57.       break;
  58.     if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
  59.       any = -1;
  60.     else {
  61.       any = 1;
  62.       acc *= base;
  63.       acc += c;
  64.     }
  65.   }
  66.   if (any < 0)
  67.   {
  68.     acc = ULLONG_MAX;
  69.     errno = ERANGE;
  70.   }
  71.   else if (neg)
  72.     acc = -acc;
  73.   if (endptr != 0)
  74.     *endptr = any ? unconst(s, char *) - 1 : unconst(nptr, char *);
  75.   return acc;
  76. }
  77.