home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.2 (Developer) / NS_dev_3.2.iso / NextDeveloper / Source / GNU / libg++ / libiberty / strtoul.c < prev    next >
C/C++ Source or Header  |  1993-06-29  |  2KB  |  89 lines

  1. /*
  2.  * strtol : convert a string to long.
  3.  *
  4.  * Andy Wilson, 2-Oct-89.
  5.  */
  6.  
  7. #include <errno.h>
  8. #include <ctype.h>
  9. #include <stdio.h>
  10. #include "ansidecl.h"
  11.  
  12. #ifndef ULONG_MAX
  13. #define    ULONG_MAX    ((unsigned long)(~0L))        /* 0xFFFFFFFF */
  14. #endif
  15.  
  16. extern int errno;
  17.  
  18. unsigned long
  19. strtoul(s, ptr, base)
  20.      CONST char *s; char **ptr; int base;
  21. {
  22.   unsigned long total = 0, tmp = 0;
  23.   unsigned digit;
  24.   CONST char *start=s;
  25.   int did_conversion=0;
  26.   int negate = 0;
  27.  
  28.   if (s==NULL)
  29.     {
  30.       errno = ERANGE;
  31.       if (!ptr)
  32.     *ptr = (char *)start;
  33.       return 0L;
  34.     }
  35.  
  36.   while (isspace(*s))
  37.     s++;
  38.   if (*s == '+')
  39.     s++;
  40.   else if (*s == '-')
  41.     s++, negate = 1;
  42.   if (base==0 || base==16) /*  the 'base==16' is for handling 0x */
  43.     {
  44.       /*
  45.        * try to infer base from the string
  46.        */
  47.       if (*s != '0')
  48.         tmp = 10;    /* doesn't start with 0 - assume decimal */
  49.       else if (s[1] == 'X' || s[1] == 'x')
  50.     tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */
  51.       else
  52.     tmp = 8;    /* starts with 0 - hence octal */
  53.       if (base==0)
  54.     base = (int)tmp;
  55.     }
  56.  
  57.   while ( digit = *s )
  58.     {
  59.       if (digit >= '0' && digit < ('0'+base))
  60.     digit -= '0';
  61.       else
  62.     if (base > 10)
  63.       {
  64.         if (digit >= 'a' && digit < ('a'+(base-10)))
  65.           digit = digit - 'a' + 10;
  66.         else if (digit >= 'A' && digit < ('A'+(base-10)))
  67.           digit = digit - 'A' + 10;
  68.         else
  69.           break;
  70.       }
  71.     else
  72.       break;
  73.       did_conversion = 1;
  74.       tmp = (total * base) + digit;
  75.       if (tmp < total)    /* check overflow */
  76.     {
  77.       errno = ERANGE;
  78.       if (ptr != NULL)
  79.         *ptr = (char *)s;
  80.       return (ULONG_MAX);
  81.     }
  82.       total = tmp;
  83.       s++;
  84.     }
  85.   if (ptr != NULL)
  86.     *ptr = (char *) ((did_conversion) ? (char *)s : (char *)start);
  87.   return negate ? -total : total;
  88. }
  89.