Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

strtol.c File Reference

#include <ctype.h>
#include <errno.h>
#include <limits.h>

Include dependency graph for strtol.c:

Go to the source code of this file.

Functions

long strtol (const char *nptr, char **endptr, register int base)


Function Documentation

long strtol const char *  nptr,
char **  endptr,
register int  base
 

Definition at line 53 of file strtol.c.

00054 {
00055         register const char *s;
00056         register long acc, cutoff;
00057         register int c;
00058         register int neg, any, cutlim;
00059 
00060         /*
00061          * Skip white space and pick up leading +/- sign if any.
00062          * If base is 0, allow 0x for hex and 0 for octal, else
00063          * assume decimal; if base is already 16, allow 0x.
00064          */
00065         s = nptr;
00066         do {
00067                 c = (unsigned char) *s++;
00068         } while (isspace(c));
00069         if (c == '-') {
00070                 neg = 1;
00071                 c = *s++;
00072         } else {
00073                 neg = 0;
00074                 if (c == '+')
00075                         c = *s++;
00076         }
00077         if ((base == 0 || base == 16) &&
00078             c == '0' && (*s == 'x' || *s == 'X')) {
00079                 c = s[1];
00080                 s += 2;
00081                 base = 16;
00082         }
00083         if (base == 0)
00084                 base = c == '0' ? 8 : 10;
00085 
00086         /*
00087          * Compute the cutoff value between legal numbers and illegal
00088          * numbers.  That is the largest legal value, divided by the
00089          * base.  An input number that is greater than this value, if
00090          * followed by a legal input character, is too big.  One that
00091          * is equal to this value may be valid or not; the limit
00092          * between valid and invalid numbers is then based on the last
00093          * digit.  For instance, if the range for longs is
00094          * [-2147483648..2147483647] and the input base is 10,
00095          * cutoff will be set to 214748364 and cutlim to either
00096          * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
00097          * a value > 214748364, or equal but the next digit is > 7 (or 8),
00098          * the number is too big, and we will return a range error.
00099          *
00100          * Set any if any `digits' consumed; make it negative to indicate
00101          * overflow.
00102          */
00103         cutoff = neg ? LONG_MIN : LONG_MAX;
00104         cutlim = cutoff % base;
00105         cutoff /= base;
00106         if (neg) {
00107                 if (cutlim > 0) {
00108                         cutlim -= base;
00109                         cutoff += 1;
00110                 }
00111                 cutlim = -cutlim;
00112         }
00113         for (acc = 0, any = 0;; c = (unsigned char) *s++) {
00114                 if (isdigit(c))
00115                         c -= '0';
00116                 else if (isalpha(c))
00117                         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
00118                 else
00119                         break;
00120                 if (c >= base)
00121                         break;
00122                 if (any < 0)
00123                         continue;
00124                 if (neg) {
00125                         if ((acc < cutoff || acc == cutoff) && c > cutlim) {
00126                                 any = -1;
00127                                 acc = LONG_MIN;
00128                                 errno = ERANGE;
00129                         } else {
00130                                 any = 1;
00131                                 acc *= base;
00132                                 acc -= c;
00133                         }
00134                 } else {
00135                         if ((acc > cutoff || acc == cutoff) && c > cutlim) {
00136                                 any = -1;
00137                                 acc = LONG_MAX;
00138                                 errno = ERANGE;
00139                         } else {
00140                                 any = 1;
00141                                 acc *= base;
00142                                 acc += c;
00143                         }
00144                 }
00145         }
00146         if (endptr != 0)
00147                 *endptr = (char *) (any ? s - 1 : nptr);
00148         return (acc);
00149 }


Generated on Wed Jan 14 12:59:13 2004 for RTL-lwIP-0.4 by doxygen 1.3.4