msvcrt: Implement ecvt_s. (try 2)

Eryk Wieliczko ewdevel at gmail.com
Fri Dec 10 07:46:36 CST 2010


---
 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
-- 
1.7.0.4




More information about the wine-patches mailing list