"Fossies" - the Fresh Open Source Software Archive

Member "cvs-1.11.23/lib/strtoul.c" (4 Apr 2005, 1980 Bytes) of package /linux/misc/old/cvs-1.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "strtoul.c" see the Fossies "Dox" file reference documentation.

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