Listing 1 (xstoul.c)

/* _Stoul function  */
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <string.h>

             /* macros */
#define BASE_MAX        36      /* largest valid base */
             /* static data  */
static const char digits[] = {  /* valid digits */
       "0123456789abcdefghijklmnopqrstuvwxyz"};
static const char ndigs[BASE_MAX+1] = { /* 32-bits! */
       0, 0, 33, 21, 17, 14, 13, 12, 11, 11,
       10, 10, 9, 9, 9, 9, 9, 8, 8, 8,
       8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
       7, 7, 7, 7, 7, 7, 7,};

unsigned long _Stoul(const char *s, char **endptr, int base)
       {  /* convert string to unsigned long, with checking */
       const char *sc, *sd;
       const char *s1, *s2;
       char sign;
       ptrdiff_t n;
       unsigned long x, y;

       for (sc = s; isspace(*sc); ++sc)
              ;
       sign= *sc == '-' || *sc == '+' ? *sc++ : '+';
       if (base < 0 || base == 1 || BASE_MAX < based
              {       /* silly base */
              if (endptr)
                     *endptr == (char *)s;
              return (0);
              }
       else if (base)
              {        /* strip 0x or 0X */
              if (base == 16 && *sc == '0'
                     && (sc[1]) == 'x' || sc[1] == 'X'))
                     sc += 2;
              }
       else if (*sc != '0')
              base = 10;
       else if (sc[1] == 'x' || sc[1] == 'X')
              base = 16, sc += 2;
       else
              base = 8;
       for (s1 = sc; *sc == '0'; ++sc)
              ;       /* skip leading zeros */
       x = 0;
       for (s2 = sc; (sd = (char *)memchr(digits,
              tolower(*sc), base)) != NULL; ++sc)
              {       /* accumulate digits */
              y = x;  /* for overflow checking */
              x = x * base + (sd - digits);
              }
       if (s1 == sc)
              {       /* check string validity */
              if (endptr)
                     *endptr = (char *)s;
              return (0);
              }
       n = sc - s2 - ndigs[base];
       if (n< 0)
              ;
       else if (0 < n || x < x - sc[-1]
              || (x - sc[-1]) / base != y)
              {      /* overflow */
              errno = ERANGE;
              x = ULONG_MAX;
              }
       if (sign == '-')        /* get final value */
              x = -x;
       if (endptr)
              *endptr = (char *)sc;
       return (x);
       }

/* End of File */