charstod.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <u.h>
  2. #include <libc.h>
  3. /*
  4. * Reads a floating-point number by interpreting successive characters
  5. * returned by (*f)(vp). The last call it makes to f terminates the
  6. * scan, so is not a character in the number. It may therefore be
  7. * necessary to back up the input stream up one byte after calling charstod.
  8. */
  9. #define ADVANCE *s++ = c; if(s>=e) return NaN(); c = (*f)(vp)
  10. double
  11. charstod(int(*f)(void*), void *vp)
  12. {
  13. char str[400], *s, *e, *start;
  14. int c;
  15. s = str;
  16. e = str + sizeof str - 1;
  17. c = (*f)(vp);
  18. while(c == ' ' || c == '\t')
  19. c = (*f)(vp);
  20. if(c == '-' || c == '+'){
  21. ADVANCE;
  22. }
  23. start = s;
  24. while(c >= '0' && c <= '9'){
  25. ADVANCE;
  26. }
  27. if(c == '.'){
  28. ADVANCE;
  29. while(c >= '0' && c <= '9'){
  30. ADVANCE;
  31. }
  32. }
  33. if(s > start && (c == 'e' || c == 'E')){
  34. ADVANCE;
  35. if(c == '-' || c == '+'){
  36. ADVANCE;
  37. }
  38. while(c >= '0' && c <= '9'){
  39. ADVANCE;
  40. }
  41. }else if(s == start && (c == 'i' || c == 'I')){
  42. ADVANCE;
  43. if(c != 'n' && c != 'N')
  44. return NaN();
  45. ADVANCE;
  46. if(c != 'f' && c != 'F')
  47. return NaN();
  48. ADVANCE;
  49. if(c != 'i' && c != 'I')
  50. return NaN();
  51. ADVANCE;
  52. if(c != 'n' && c != 'N')
  53. return NaN();
  54. ADVANCE;
  55. if(c != 'i' && c != 'I')
  56. return NaN();
  57. ADVANCE;
  58. if(c != 't' && c != 'T')
  59. return NaN();
  60. ADVANCE;
  61. if(c != 'y' && c != 'Y')
  62. return NaN();
  63. ADVANCE; /* so caller can back up uniformly */
  64. USED(c);
  65. }else if(s == str && (c == 'n' || c == 'N')){
  66. ADVANCE;
  67. if(c != 'a' && c != 'A')
  68. return NaN();
  69. ADVANCE;
  70. if(c != 'n' && c != 'N')
  71. return NaN();
  72. ADVANCE; /* so caller can back up uniformly */
  73. USED(c);
  74. }
  75. *s = 0;
  76. return strtod(str, &s);
  77. }