strtol.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include <lib9.h>
  2. #define LONG_MAX 2147483647L
  3. #define LONG_MIN -2147483648L
  4. long
  5. strtol(char *nptr, char **endptr, int base)
  6. {
  7. char *p;
  8. long n, nn;
  9. int c, ovfl, v, neg, ndig;
  10. p = nptr;
  11. neg = 0;
  12. n = 0;
  13. ndig = 0;
  14. ovfl = 0;
  15. /*
  16. * White space
  17. */
  18. for(;;p++){
  19. switch(*p){
  20. case ' ':
  21. case '\t':
  22. case '\n':
  23. case '\f':
  24. case '\r':
  25. case '\v':
  26. continue;
  27. }
  28. break;
  29. }
  30. /*
  31. * Sign
  32. */
  33. if(*p=='-' || *p=='+')
  34. if(*p++ == '-')
  35. neg = 1;
  36. /*
  37. * Base
  38. */
  39. if(base==0){
  40. if(*p != '0')
  41. base = 10;
  42. else{
  43. base = 8;
  44. if(p[1]=='x' || p[1]=='X'){
  45. p += 2;
  46. base = 16;
  47. }
  48. }
  49. }else if(base==16 && *p=='0'){
  50. if(p[1]=='x' || p[1]=='X')
  51. p += 2;
  52. }else if(base<0 || 36<base)
  53. goto Return;
  54. /*
  55. * Non-empty sequence of digits
  56. */
  57. for(;; p++,ndig++){
  58. c = *p;
  59. v = base;
  60. if('0'<=c && c<='9')
  61. v = c - '0';
  62. else if('a'<=c && c<='z')
  63. v = c - 'a' + 10;
  64. else if('A'<=c && c<='Z')
  65. v = c - 'A' + 10;
  66. if(v >= base)
  67. break;
  68. nn = n*base + v;
  69. if(nn < n)
  70. ovfl = 1;
  71. n = nn;
  72. }
  73. Return:
  74. if(ndig == 0)
  75. p = nptr;
  76. if(endptr)
  77. *endptr = p;
  78. if(ovfl){
  79. if(neg)
  80. return LONG_MIN;
  81. return LONG_MAX;
  82. }
  83. if(neg)
  84. return -n;
  85. return n;
  86. }