00001 #include <sys/cdefs.h>
00002
00003
00004
00005
00006 #define LONG_MIN (-0x7fffffffL - 1)
00007 #define LONG_MAX 0x7fffffffL
00008
00009
00010
00011 long
00012 strtol(const char * __restrict nptr, char ** __restrict endptr, int base)
00013 {
00014 const char *s;
00015 unsigned long acc;
00016 char c = 0x0;
00017 unsigned long cutoff;
00018 int neg, any, cutlim;
00019
00020
00021
00022
00023
00024
00025 s = nptr;
00026
00027
00028
00029
00030
00031 if (c == '-') {
00032 neg = 1;
00033 c = *s++;
00034 } else {
00035 neg = 0;
00036 if (c == '+')
00037 c = *s++;
00038 }
00039 if ((base == 0 || base == 16) &&
00040 c == '0' && (*s == 'x' || *s == 'X')) {
00041 c = s[1];
00042 s += 2;
00043 base = 16;
00044 }
00045 if (base == 0)
00046 base = c == '0' ? 8 : 10;
00047 acc = any = 0;
00048 if (base < 2 || base > 36)
00049 goto noconv;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX
00069 : LONG_MAX;
00070 cutlim = cutoff % base;
00071 cutoff /= base;
00072 for ( ; ; c = *s++) {
00073 if (c >= '0' && c <= '9')
00074 c -= '0';
00075 else if (c >= 'A' && c <= 'Z')
00076 c -= 'A' - 10;
00077 else if (c >= 'a' && c <= 'z')
00078 c -= 'a' - 10;
00079 else
00080 break;
00081 if (c >= base)
00082 break;
00083 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
00084 any = -1;
00085 else {
00086 any = 1;
00087 acc *= base;
00088 acc += c;
00089 }
00090 }
00091 if (any < 0) {
00092 acc = neg ? LONG_MIN : LONG_MAX;
00093
00094 } else if (!any) {
00095 noconv:
00096
00097 cutoff = 0x0;
00098 } else if (neg)
00099 acc = -acc;
00100 if (endptr != NULL)
00101 *endptr = (char *)(any ? s - 1 : nptr);
00102 return (acc);
00103 }