charstod.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * The authors of this software are Rob Pike and Ken Thompson.
  3. * Copyright (c) 2002 by Lucent Technologies.
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose without fee is hereby granted, provided that this entire notice
  6. * is included in all copies of any software which is or includes a copy
  7. * or modification of this software and in all copies of the supporting
  8. * documentation for such software.
  9. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
  10. * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
  11. * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
  12. * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
  13. */
  14. #include <stdarg.h>
  15. #include <string.h>
  16. #include "utf.h"
  17. #include "fmt.h"
  18. #include "fmtdef.h"
  19. /*
  20. * Reads a floating-point number by interpreting successive characters
  21. * returned by (*f)(vp). The last call it makes to f terminates the
  22. * scan, so is not a character in the number. It may therefore be
  23. * necessary to back up the input stream up one byte after calling charstod.
  24. */
  25. double
  26. fmtcharstod(int(*f)(void*), void *vp)
  27. {
  28. double num, dem;
  29. int neg, eneg, dig, exp, c;
  30. num = 0;
  31. neg = 0;
  32. dig = 0;
  33. exp = 0;
  34. eneg = 0;
  35. c = (*f)(vp);
  36. while(c == ' ' || c == '\t')
  37. c = (*f)(vp);
  38. if(c == '-' || c == '+'){
  39. if(c == '-')
  40. neg = 1;
  41. c = (*f)(vp);
  42. }
  43. while(c >= '0' && c <= '9'){
  44. num = num*10 + c-'0';
  45. c = (*f)(vp);
  46. }
  47. if(c == '.')
  48. c = (*f)(vp);
  49. while(c >= '0' && c <= '9'){
  50. num = num*10 + c-'0';
  51. dig++;
  52. c = (*f)(vp);
  53. }
  54. if(c == 'e' || c == 'E'){
  55. c = (*f)(vp);
  56. if(c == '-' || c == '+'){
  57. if(c == '-'){
  58. dig = -dig;
  59. eneg = 1;
  60. }
  61. c = (*f)(vp);
  62. }
  63. while(c >= '0' && c <= '9'){
  64. exp = exp*10 + c-'0';
  65. c = (*f)(vp);
  66. }
  67. }
  68. exp -= dig;
  69. if(exp < 0){
  70. exp = -exp;
  71. eneg = !eneg;
  72. }
  73. dem = __fmtpow10(exp);
  74. if(eneg)
  75. num /= dem;
  76. else
  77. num *= dem;
  78. if(neg)
  79. return -num;
  80. return num;
  81. }