strtol.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #define LONG_MAX 2147483647L
  12. #define LONG_MIN -2147483648L
  13. int32_t
  14. strtol(const char *nptr, char **endptr, int base)
  15. {
  16. char *p;
  17. int32_t n, nn, m;
  18. int c, ovfl, v, neg, ndig;
  19. p = nptr;
  20. neg = 0;
  21. n = 0;
  22. ndig = 0;
  23. ovfl = 0;
  24. /*
  25. * White space
  26. */
  27. for(;; p++) {
  28. switch(*p) {
  29. case ' ':
  30. case '\t':
  31. case '\n':
  32. case '\f':
  33. case '\r':
  34. case '\v':
  35. continue;
  36. }
  37. break;
  38. }
  39. /*
  40. * Sign
  41. */
  42. if(*p=='-' || *p=='+')
  43. if(*p++ == '-')
  44. neg = 1;
  45. /*
  46. * Base
  47. */
  48. if(base==0) {
  49. base = 10;
  50. if(*p == '0') {
  51. base = 8;
  52. if(p[1]=='x' || p[1]=='X') {
  53. p += 2;
  54. base = 16;
  55. }
  56. }
  57. } else
  58. if(base==16 && *p=='0'){
  59. if(p[1]=='x' || p[1]=='X')
  60. p += 2;
  61. } else
  62. if(base<0 || 36<base)
  63. goto Return;
  64. /*
  65. * Non-empty sequence of digits
  66. */
  67. m = LONG_MAX/base;
  68. for(;; p++,ndig++){
  69. c = *p;
  70. v = base;
  71. if('0'<=c && c<='9')
  72. v = c - '0';
  73. else
  74. if('a'<=c && c<='z')
  75. v = c - 'a' + 10;
  76. else
  77. if('A'<=c && c<='Z')
  78. v = c - 'A' + 10;
  79. if(v >= base)
  80. break;
  81. if(n > m)
  82. ovfl = 1;
  83. nn = n*base + v;
  84. if(nn < n)
  85. ovfl = 1;
  86. n = nn;
  87. }
  88. Return:
  89. if(ndig == 0)
  90. p = nptr;
  91. if(endptr)
  92. *endptr = (char*)p;
  93. if(ovfl){
  94. if(neg)
  95. return LONG_MIN;
  96. return LONG_MAX;
  97. }
  98. if(neg)
  99. return -n;
  100. return n;
  101. }