• Apple里的strtol实现!


      1 static inline int
      2 isupper(char c)
      3 {
      4     return (c >= 'A' && c <= 'Z');
      5 }
      6 
      7 static inline int
      8 isalpha(char c)
      9 {
     10     return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
     11 }
     12 
     13 
     14 static inline int
     15 isspace(char c)
     16 {
     17     return (c == ' ' || c == '\t' || c == '\n' || c == '\12');
     18 }
     19 
     20 static inline int
     21 isdigit(char c)
     22 {
     23     return (c >= '0' && c <= '9');
     24 }
     25 
     26 /*
     27  * Convert a string to a long integer.
     28  *
     29  * Ignores `locale' stuff.  Assumes that the upper and lower case
     30  * alphabets and digits are each contiguous.
     31  */
     32 long
     33 strtol(nptr, endptr, base)
     34     const char *nptr;
     35     char **endptr;
     36     register int base;
     37 {
     38     register const char *s = nptr;
     39     register unsigned long acc;
     40     register int c;
     41     register unsigned long cutoff;
     42     register int neg = 0, any, cutlim;
     43 
     44     /*
     45      * Skip white space and pick up leading +/- sign if any.
     46      * If base is 0, allow 0x for hex and 0 for octal, else
     47      * assume decimal; if base is already 16, allow 0x.
     48      */
     49     do {
     50         c = *s++;
     51     } while (isspace(c));
     52     if (c == '-') {
     53         neg = 1;
     54         c = *s++;
     55     } else if (c == '+')
     56         c = *s++;
     57     if ((base == 0 || base == 16) &&
     58         c == '0' && (*s == 'x' || *s == 'X')) {
     59         c = s[1];
     60         s += 2;
     61         base = 16;
     62     } else if ((base == 0 || base == 2) &&
     63         c == '0' && (*s == 'b' || *s == 'B')) {
     64         c = s[1];
     65         s += 2;
     66         base = 2;
     67     }
     68     if (base == 0)
     69         base = c == '0' ? 8 : 10;
     70 
     71     /*
     72      * Compute the cutoff value between legal numbers and illegal
     73      * numbers.  That is the largest legal value, divided by the
     74      * base.  An input number that is greater than this value, if
     75      * followed by a legal input character, is too big.  One that
     76      * is equal to this value may be valid or not; the limit
     77      * between valid and invalid numbers is then based on the last
     78      * digit.  For instance, if the range for longs is
     79      * [-2147483648..2147483647] and the input base is 10,
     80      * cutoff will be set to 214748364 and cutlim to either
     81      * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
     82      * a value > 214748364, or equal but the next digit is > 7 (or 8),
     83      * the number is too big, and we will return a range error.
     84      *
     85      * Set any if any `digits' consumed; make it negative to indicate
     86      * overflow.
     87      */
     88     cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
     89     cutlim = cutoff % (unsigned long)base;
     90     cutoff /= (unsigned long)base;
     91     for (acc = 0, any = 0;; c = *s++) {
     92         if (isdigit(c))
     93             c -= '0';
     94         else if (isalpha(c))
     95             c -= isupper(c) ? 'A' - 10 : 'a' - 10;
     96         else
     97             break;
     98         if (c >= base)
     99             break;
    100         if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
    101             any = -1;
    102         else {
    103             any = 1;
    104             acc *= base;
    105             acc += c;
    106         }
    107     }
    108     if (any < 0) {
    109         acc = neg ? LONG_MIN : LONG_MAX;
    110 //        errno = ERANGE;
    111     } else if (neg)
    112         acc = -acc;
    113     if (endptr != 0)
    114         *endptr = (char *)(any ? s - 1 : nptr);
    115     return (acc);
    116 }
    117 
    118 /*
    119  * Convert a string to an unsigned long integer.
    120  *
    121  * Ignores `locale' stuff.  Assumes that the upper and lower case
    122  * alphabets and digits are each contiguous.
    123  */
    124 unsigned long
    125 strtoul(nptr, endptr, base)
    126     const char *nptr;
    127     char **endptr;
    128     register int base;
    129 {
    130     register const char *s = nptr;
    131     register unsigned long acc;
    132     register int c;
    133     register unsigned long cutoff;
    134     register int neg = 0, any, cutlim;
    135 
    136     /*
    137      * See strtol for comments as to the logic used.
    138      */
    139     do {
    140         c = *s++;
    141     } while (isspace(c));
    142     if (c == '-') {
    143         neg = 1;
    144         c = *s++;
    145     } else if (c == '+')
    146         c = *s++;
    147     if ((base == 0 || base == 16) &&
    148         c == '0' && (*s == 'x' || *s == 'X')) {
    149         c = s[1];
    150         s += 2;
    151         base = 16;
    152     } else if ((base == 0 || base == 2) &&
    153         c == '0' && (*s == 'b' || *s == 'B')) {
    154         c = s[1];
    155         s += 2;
    156         base = 2;
    157     }
    158     if (base == 0)
    159         base = c == '0' ? 8 : 10;
    160     cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
    161     cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
    162     for (acc = 0, any = 0;; c = *s++) {
    163         if (isdigit(c))
    164             c -= '0';
    165         else if (isalpha(c))
    166             c -= isupper(c) ? 'A' - 10 : 'a' - 10;
    167         else
    168             break;
    169         if (c >= base)
    170             break;
    171         if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
    172             any = -1;
    173         else {
    174             any = 1;
    175             acc *= base;
    176             acc += c;
    177         }
    178     }
    179     if (any < 0) {
    180         acc = ULONG_MAX;
    181 //        errno = ERANGE;
    182     } else if (neg)
    183         acc = -acc;
    184     if (endptr != 0)
    185         *endptr = (char *)(any ? s - 1 : nptr);
    186     return (acc);
    187 }
  • 相关阅读:
    java数组基础
    java异常处理机制
    java面向对象基础(四):抽象类和接口
    java面向对象基础(二)
    java类路径classpath和包
    java面向对象基础(一)
    Tomcat(二):tomcat配置文件server.xml详解和部署简介
    java集合框架(Collections Framework)
    java基础数据类型包装类
    String、StringBuilder和StringBuffer类
  • 原文地址:https://www.cnblogs.com/isaiah/p/2733227.html
Copyright © 2020-2023  润新知