Home
       strtoul.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       strtoul.c (851B)
       ---
            1 #include <ctype.h>
            2 #include <errno.h>
            3 #include <limits.h>
            4 #include <stdlib.h>
            5 #include <string.h>
            6 
            7 #include "../libc.h"
            8 
            9 #undef strtoul
           10 
           11 unsigned long
           12 strtoul(const char * restrict ptr, char ** restrict end, int base)
           13 {
           14         int d, sign = 1;
           15         unsigned long n;
           16         char *t, *s = (char *) ptr;
           17 
           18         if (end)
           19                 *end = s;
           20 
           21         while (isspace(*s))
           22                 ++s;
           23 
           24         switch (*s) {
           25         case '-':
           26                 sign = -1;
           27         case '+':
           28                 ++s;
           29         }
           30 
           31         if (base == 0) {
           32                 if (*s == '0')
           33                         base = toupper(s[1]) == 'X' ? 16 : 8;
           34                 else
           35                         base = 10;
           36         }
           37         if (base == 16 && *s == '0' && toupper(s[1]) == 'X')
           38                 s += 2;
           39 
           40         n = 0;
           41         for (t = s; (d = _dtoi(*t)) < base; ++t) {
           42                 if (n > ULONG_MAX/base)
           43                         goto overflow;
           44                 n *= base;
           45                 if (d > ULONG_MAX - n)
           46                         goto overflow;
           47                 n += d;
           48         }
           49 
           50         if (end && t != s)
           51                 *end = t;
           52 
           53         return n*sign;
           54 
           55 overflow:
           56         if (end)
           57                 *end = t;
           58         errno = ERANGE;
           59 
           60         return ULONG_MAX;
           61 }