Module: wine Branch: master Commit: 1ade6c2bc8e3e895992accf4aca098b0f8d0fb3b URL: http://source.winehq.org/git/wine.git/?a=commit;h=1ade6c2bc8e3e895992accf4ac...
Author: Eryk Wieliczko ewdevel@gmail.com Date: Fri Dec 10 14:46:36 2010 +0100
msvcrt: Implement ecvt_s.
---
dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/math.c | 66 +++++++++++++++++++++++++++++++++++++++++++ dlls/msvcrt/msvcrt.spec | 2 +- 5 files changed, 70 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 9f2a147..82606e2 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -583,7 +583,7 @@ @ cdecl _dup2(long long) msvcrt._dup2 @ cdecl _dupenv_s(ptr ptr str) msvcrt._dupenv_s @ cdecl _ecvt(double long ptr ptr) msvcrt._ecvt -@ stub _ecvt_s +@ cdecl _ecvt_s(str long double long ptr ptr) msvcrt._ecvt_s @ cdecl _encoded_null() msvcr90._encoded_null @ cdecl _endthread() msvcrt._endthread @ cdecl _endthreadex(long) msvcrt._endthreadex diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 1512347..e54eea6 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -423,7 +423,7 @@ @ cdecl _dup2(long long) msvcrt._dup2 @ cdecl _dupenv_s(ptr ptr str) msvcrt._dupenv_s @ cdecl _ecvt(double long ptr ptr) msvcrt._ecvt -@ stub _ecvt_s +@ cdecl _ecvt_s(str long double long ptr ptr) msvcrt._ecvt_s @ cdecl _encode_pointer(ptr) msvcr90._encode_pointer @ cdecl _encoded_null() msvcr90._encoded_null @ cdecl _endthread() msvcrt._endthread diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index feaf80e..5baee98 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -415,7 +415,7 @@ @ cdecl _dup2(long long) msvcrt._dup2 @ cdecl _dupenv_s(ptr ptr str) msvcrt._dupenv_s @ cdecl _ecvt(double long ptr ptr) msvcrt._ecvt -@ stub _ecvt_s +@ cdecl _ecvt_s(str long double long ptr ptr) msvcrt._ecvt_s @ cdecl _encode_pointer(ptr) MSVCR90_encode_pointer @ cdecl _encoded_null() @ cdecl _endthread() msvcrt._endthread diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 6fb0549..d2110cb 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -1104,6 +1104,72 @@ char * CDECL _ecvt( double number, int ndigits, int *decpt, int *sign ) return data->efcvt_buffer; }
+/********************************************************************* + * _ecvt_s (MSVCRT.@) + */ +int CDECL _ecvt_s( char *buffer, MSVCRT_size_t length, double number, int ndigits, int *decpt, int *sign ) +{ + int prec, len; + char *result; + const char infret[] = "1#INF"; + + if(!MSVCRT_CHECK_PMT(buffer != NULL) || !MSVCRT_CHECK_PMT(decpt != NULL) || !MSVCRT_CHECK_PMT(sign != NULL)) + { + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } + if(!MSVCRT_CHECK_PMT(length > 2) || !MSVCRT_CHECK_PMT(ndigits < (int)length - 1)) + { + *MSVCRT__errno() = MSVCRT_ERANGE; + return MSVCRT_ERANGE; + } + + /* special case - inf */ + if(number == HUGE_VAL || number == -HUGE_VAL) + { + memset(buffer, '0', ndigits); + memcpy(buffer, infret, min(ndigits, sizeof(infret) - 1 ) ); + buffer[ndigits] = '\0'; + (*decpt) = 1; + if(number == -HUGE_VAL) + (*sign) = 1; + else + (*sign) = 0; + return 0; + } + result = (char*)MSVCRT_malloc(max(ndigits + 7, 7)); + + if( number < 0) { + *sign = TRUE; + number = -number; + } else + *sign = FALSE; + /* handle cases with zero ndigits or less */ + prec = ndigits; + if( prec < 1) prec = 2; + len = snprintf(result, 80, "%.*le", prec - 1, number); + /* take the decimal "point away */ + if( prec != 1) + memmove( result + 1, result + 2, len - 1 ); + /* take the exponential "e" out */ + result[ prec] = '\0'; + /* read the exponent */ + sscanf( result + prec + 1, "%d", decpt); + (*decpt)++; + /* adjust for some border cases */ + if( result[0] == '0')/* value is zero */ + *decpt = 0; + /* handle cases with zero ndigits or less */ + if( ndigits < 1){ + if( result[ 0] >= '5') + (*decpt)++; + result[ 0] = '\0'; + } + memcpy( buffer, result, max(ndigits + 1, 1) ); + MSVCRT_free( result ); + return 0; +} + /*********************************************************************** * _fcvt (MSVCRT.@) */ diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 9fe5f64..ba8c9ea 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -378,7 +378,7 @@ @ cdecl _dup (long) MSVCRT__dup @ cdecl _dup2 (long long) MSVCRT__dup2 @ cdecl _ecvt(double long ptr ptr) -# stub _ecvt_s +@ cdecl _ecvt_s(str long double long ptr ptr) @ cdecl _endthread () @ cdecl _endthreadex(long) @ extern _environ MSVCRT__environ