charstod.c 1.6 KB

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