Main Page | Alphabetical List | Class List | File List | Class Members | File Members

strtoul.h

Go to the documentation of this file.
00001 #ifndef __STRTOUL_H__
00002 #define __STRTOUL_H__
00003 
00043 #include <nlibc.h>
00044 #include <assert.h>
00045 #include <ctype.h>
00046 #include <errno.h>
00047 #include <limits.h>
00048 
00049 //---------------------------------------------------------------------------------------------
00109 #ifndef __HAS_MAIN
00110 extern unsigned long strtoul(const char *nptr, char **endptr, int base);
00111 #else
00112 #if !defined(__cflow_processed) || defined(_uses_strtoul_strtoul_h)
00113 unsigned long strtoul(const char *nptr, char **endptr, int base)
00114 {
00115         const char *s;
00116         unsigned long acc, cutoff;
00117         int c;
00118         int neg, any_consumed, cutlim;
00119         int len;
00120 
00121         assert(nptr != NULL);
00122         /* endptr may be NULL */
00123 
00124         /*
00125          * expand compacted string to char array for easy 
00126          * handling
00127          */
00128         len = strlen( nptr );
00129         s = stringexpand( nptr, len );
00130 
00131         /*
00132          * Skip white space and pick up leading +/- sign if any.
00133          * If base is 0, allow 0x for hex and 0 for octal, else
00134          * assume decimal; if base is already 16, allow 0x.
00135          */
00136         do {
00137                 c = (unsigned char) *s++;
00138         } while (isspace(c));
00139         if (c == '-') {
00140                 neg = 1;
00141                 c = *s++;
00142         } else {
00143                 neg = 0;
00144                 if (c == '+')
00145                         c = *s++;
00146         }
00147         if ((base == 0 || base == 16) &&
00148             c == '0' && (*s == 'x' || *s == 'X')) {
00149                 c = s[1];
00150                 s += 2;
00151                 base = 16;
00152         }
00153         if (base == 0)
00154                 base = c == '0' ? 8 : 10;
00155 
00156         /*
00157          * See strtol for comments as to the logic used.
00158          */
00159         cutoff = ULONG_MAX / (unsigned long)base;
00160         cutlim = (int)(ULONG_MAX % (unsigned long)base);
00161         for (acc = 0, any_consumed = 0;; c = (unsigned char) *s++) {
00162                 if (isdigit(c))
00163                         c -= '0';
00164                 else if (isalpha(c))
00165                         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
00166                 else
00167                         break;
00168                 if (c >= base)
00169                         break;
00170                 if (any_consumed < 0)
00171                         continue;
00172                 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
00173                         any_consumed = -1;
00174                         acc = ULONG_MAX;
00175                         errno = ERANGE;
00176                 } else {
00177                         any_consumed = 1;
00178                         acc *= (unsigned long)base;
00179                         acc += c;
00180                 }
00181         }
00182         if( neg && any_consumed > 0 )
00183                 acc = - (long) acc;             /* LM -- Add a cast. */
00184         if (endptr != 0)
00185                 /* LINTED interface specification */
00186                 *endptr = (char *)(any_consumed ? s - 1 : nptr);
00187         return (acc);
00188 }
00189 #endif // _uses_strtoul_strtoul_h
00190 #endif // Has Main
00191 
00192 #define strtoull(nptr, endptr, base)  strtoul(nptr, endptr, base)
00193 
00194 #endif // __STRTOUL_H__

Generated on Fri Jul 14 10:51:32 2006 for nlibc by doxygen 1.3.5