Module: wine Branch: master Commit: f7197663c998d989c6ecf26ddc8c09208fff873c URL: http://source.winehq.org/git/wine.git/?a=commit;h=f7197663c998d989c6ecf26ddc...
Author: Piotr Caban piotr@codeweavers.com Date: Mon Apr 26 12:33:38 2010 +0200
msvcrt: Added wcstod_l implementation.
It's almost a copy of strtod_l.
---
dlls/msvcrt/msvcrt.spec | 1 + dlls/msvcrt/wcs.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 0 deletions(-)
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 156ab2e..81e07a7 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1413,3 +1413,4 @@ @ cdecl _create_locale(long str) @ cdecl _free_locale(ptr) @ cdecl _configthreadlocale(long) +@ cdecl _wcstod_l(wstr ptr) MSVCRT__wcstod_l diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 21d0d28..94c638b 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -18,6 +18,9 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + #include <limits.h> #include <stdio.h> #include <math.h> @@ -120,6 +123,110 @@ INT CDECL MSVCRT__wcsupr_s( MSVCRT_wchar_t* str, MSVCRT_size_t n ) }
/********************************************************************* + * _wcstod_l - not exported in native msvcrt + */ +double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end, + MSVCRT__locale_t locale) +{ + unsigned __int64 d=0, hlp; + int exp=0, sign=1; + const MSVCRT_wchar_t *p; + double ret; + + if(!str) { + MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0); + *MSVCRT__errno() = MSVCRT_EINVAL; + return 0; + } + + if(!locale) + locale = get_locale(); + + p = str; + while(isspaceW(*p)) + p++; + + if(*p == '-') { + sign = -1; + p++; + } else if(*p == '+') + p++; + + while(isdigitW(*p)) { + hlp = d*10+*(p++)-'0'; + if(d>MSVCRT_UI64_MAX/10 || hlp<d) { + exp++; + break; + } else + d = hlp; + } + while(isdigitW(*p)) { + exp++; + p++; + } + if(*p == *locale->locinfo->lconv->decimal_point) + p++; + + while(isdigitW(*p)) { + hlp = d*10+*(p++)-'0'; + if(d>MSVCRT_UI64_MAX/10 || hlp<d) + break; + + d = hlp; + exp--; + } + while(isdigitW(*p)) + p++; + + if(p == str) { + if(end) + *end = (MSVCRT_wchar_t*)str; + return 0.0; + } + + if(*p=='e' || *p=='E' || *p=='d' || *p=='D') { + int e=0, s=1; + + p++; + if(*p == '-') { + s = -1; + p++; + } else if(*p == '+') + p++; + + if(isdigitW(*p)) { + while(isdigitW(*p)) { + if(e>INT_MAX/10 || (e=e*10+*p-'0')<0) + e = INT_MAX; + p++; + } + e *= s; + + if(exp<0 && e<0 && exp+e>=0) exp = INT_MIN; + else if(exp>0 && e>0 && exp+e<0) exp = INT_MAX; + else exp += e; + } else { + if(*p=='-' || *p=='+') + p--; + p--; + } + } + + if(exp>0) + ret = (double)sign*d*pow(10, exp); + else + ret = (double)sign*d/pow(10, -exp); + + if((d && ret==0.0) || isinf(ret)) + *MSVCRT__errno() = MSVCRT_ERANGE; + + if(end) + *end = (MSVCRT_wchar_t*)p; + + return ret; +} + +/********************************************************************* * wcstod (MSVCRT.@) */ double CDECL MSVCRT_wcstod(const MSVCRT_wchar_t* lpszStr, MSVCRT_wchar_t** end)