Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.1 KiB

  1. /***
  2. *wcstod.c - convert wide char string to floating point number
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Convert character string to floating point number
  8. *
  9. *Revision History:
  10. * 06-15-92 KRS Created from strtod.c.
  11. * 11-06-92 KRS Fix bugs in wctomb() loop.
  12. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  13. * 02-07-94 CFW POSIXify.
  14. * 09-06-94 CFW Replace MTHREAD with _MT.
  15. * 01-10-95 CFW Debug CRT allocs.
  16. * 04-01-96 BWT POSIX work.
  17. * 02-19-01 GB added _alloca and Check for return value of _malloc_crt
  18. *
  19. *******************************************************************************/
  20. #include <cruntime.h>
  21. #include <internal.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <errno.h>
  26. #include <math.h>
  27. #include <dbgint.h>
  28. #include <stdlib.h>
  29. #include <malloc.h>
  30. #include <fltintrn.h>
  31. /***
  32. *double wcstod(nptr, endptr) - convert wide string to double
  33. *
  34. *Purpose:
  35. * wcstod recognizes an optional string of tabs and spaces,
  36. * then an optional sign, then a string of digits optionally
  37. * containing a decimal point, then an optional e or E followed
  38. * by an optionally signed integer, and converts all this to
  39. * to a floating point number. The first unrecognized
  40. * character ends the string, and is pointed to by endptr.
  41. *
  42. *Entry:
  43. * nptr - pointer to wide string to convert
  44. *
  45. *Exit:
  46. * returns value of wide character string
  47. * wchar_t **endptr - if not NULL, points to character which stopped
  48. * the scan
  49. *
  50. *Exceptions:
  51. *
  52. *******************************************************************************/
  53. double __cdecl wcstod (
  54. const wchar_t *nptr,
  55. REG2 wchar_t **endptr
  56. )
  57. {
  58. #ifdef _MT
  59. struct _flt answerstruct;
  60. #endif
  61. FLT answer;
  62. double tmp;
  63. unsigned int flags;
  64. REG1 wchar_t *ptr = (wchar_t *) nptr;
  65. char * cptr;
  66. int malloc_flag = 0;
  67. int retval, len;
  68. int clen = 0;
  69. /* scan past leading space/tab characters */
  70. while (iswspace(*ptr))
  71. ptr++;
  72. __try{
  73. cptr = (char *)_alloca((wcslen(ptr)+1) * sizeof(wchar_t));
  74. }
  75. __except(1){ //EXCEPTION_EXECUTE_HANDLER
  76. _resetstkoflw();
  77. if ((cptr = (char *)_malloc_crt((wcslen(ptr)+1) * sizeof(wchar_t))) == NULL)
  78. {
  79. errno = ENOMEM;
  80. return 0.0;
  81. }
  82. malloc_flag = 1;
  83. }
  84. // UNDONE: check for errors
  85. for (len = 0; ptr[len]; len++)
  86. {
  87. if ((retval = wctomb(cptr+len,ptr[len]))<=0)
  88. break;
  89. clen += retval;
  90. }
  91. cptr[clen++] = '\0';
  92. /* let _fltin routine do the rest of the work */
  93. #ifdef _MT
  94. /* ok to take address of stack variable here; fltin2 knows to use ss */
  95. answer = _fltin2( &answerstruct, cptr, clen, 0, 0);
  96. #else
  97. answer = _fltin(cptr, clen, 0, 0);
  98. #endif
  99. if (malloc_flag)
  100. _free_crt(cptr);
  101. if ( endptr != NULL )
  102. *endptr = (wchar_t *) ptr + answer->nbytes;
  103. /* UNDONE: assumes no multi-byte chars in string */
  104. flags = answer->flags;
  105. if ( flags & (512 | 64)) {
  106. /* no digits found or invalid format:
  107. ANSI says return 0.0, and *endptr = nptr */
  108. tmp = 0.0;
  109. if ( endptr != NULL )
  110. *endptr = (wchar_t *) nptr;
  111. }
  112. else if ( flags & (128 | 1) ) {
  113. if ( *ptr == '-' )
  114. tmp = -HUGE_VAL; /* negative overflow */
  115. else
  116. tmp = HUGE_VAL; /* positive overflow */
  117. errno = ERANGE;
  118. }
  119. else if ( flags & 256 ) {
  120. tmp = 0.0; /* underflow */
  121. errno = ERANGE;
  122. }
  123. else
  124. tmp = answer->dval;
  125. return(tmp);
  126. }