Piotr Caban : msvcrt: Added _strtoui64 implementation.

Alexandre Julliard julliard at winehq.org
Mon Mar 29 09:57:59 CDT 2010


Module: wine
Branch: master
Commit: 9a8fe9679b3edd928107c6831015b53eebf3eb46
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9a8fe9679b3edd928107c6831015b53eebf3eb46

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Mar 29 00:04:32 2010 +0200

msvcrt: Added _strtoui64 implementation.

---

 dlls/msvcr80/msvcr80.spec  |    4 +-
 dlls/msvcr90/msvcr90.spec  |    4 +-
 dlls/msvcrt/msvcrt.spec    |    4 +-
 dlls/msvcrt/string.c       |   74 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/tests/string.c |   49 ++++++++++++++++++++++++++++-
 5 files changed, 127 insertions(+), 8 deletions(-)

diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index e44ad0f..541cf68 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -961,8 +961,8 @@
 @ cdecl _strtoi64(str ptr long) msvcrt._strtoi64
 @ cdecl _strtoi64_l(str ptr long ptr) msvcrt._strtoi64_l
 @ stub _strtol_l
-@ stub _strtoui64
-@ stub _strtoui64_l
+@ cdecl _strtoui64(str ptr long) msvcrt._strtoui64
+@ cdecl _strtoui64_l(str ptr long ptr) msvcrt._strtoui64_l
 @ stub _strtoul_l
 @ cdecl _strupr(str) msvcrt._strupr
 @ stub _strupr_l
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 1cec19c..296466a 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -947,8 +947,8 @@
 @ cdecl _strtoi64(str ptr long) msvcrt._strtoi64
 @ cdecl _strtoi64_l(str ptr long ptr) msvcrt._strtoi64_l
 @ stub _strtol_l
-@ stub _strtoui64
-@ stub _strtoui64_l
+@ cdecl _strtoui64(str ptr long) msvcrt._strtoui64
+@ cdecl _strtoui64_l(str ptr long ptr) msvcrt._strtoui64_l
 @ stub _strtoul_l
 @ cdecl _strupr(str) msvcrt._strupr
 @ stub _strupr_l
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index d25bcc4..2b6be16 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -894,8 +894,8 @@
 @ cdecl _strtoi64(str ptr long) MSVCRT_strtoi64
 @ cdecl _strtoi64_l(str ptr long ptr) MSVCRT_strtoi64_l
 # stub _strtol_l
-# stub _strtoui64
-# stub _strtoui64_l
+@ cdecl _strtoui64(str ptr long) MSVCRT_strtoui64
+@ cdecl _strtoui64_l(str ptr long ptr) MSVCRT_strtoui64_l
 # stub _strtoul_l
 @ cdecl _strupr(str) ntdll._strupr
 # stub _strupr_l
diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c
index d64cd45..5432a30 100644
--- a/dlls/msvcrt/string.c
+++ b/dlls/msvcrt/string.c
@@ -407,3 +407,77 @@ __int64 CDECL MSVCRT_strtoi64(const char *nptr, char **endptr, int base)
 {
     return MSVCRT_strtoi64_l(nptr, endptr, base, NULL);
 }
+
+/*********************************************************************
+ *  _strtoui64_l (MSVCR90.@)
+ *
+ * FIXME: locale parameter is ignored
+ */
+unsigned __int64 CDECL MSVCRT_strtoui64_l(const char *nptr, char **endptr, int base, MSVCRT__locale_t locale)
+{
+    BOOL negative = FALSE;
+    unsigned __int64 ret = 0;
+
+    TRACE("(%s %p %d %p)\n", nptr, endptr, base, locale);
+
+    if(!nptr || base<0 || base>36 || base==1) {
+        MSVCRT_invalid_parameter(NULL, NULL, NULL, 0, NULL);
+        return 0;
+    }
+
+    while(isspace(*nptr)) nptr++;
+
+    if(*nptr == '-') {
+        negative = TRUE;
+        nptr++;
+    } else if(*nptr == '+')
+        nptr++;
+
+    if((base==0 || base==16) && *nptr=='0' && tolower(*(nptr+1))=='x') {
+        base = 16;
+        nptr += 2;
+    }
+
+    if(base == 0) {
+        if(*nptr=='0')
+            base = 8;
+        else
+            base = 10;
+    }
+
+    while(*nptr) {
+        char cur = tolower(*nptr);
+        int v;
+
+        if(isdigit(cur)) {
+            if(cur >= '0'+base)
+                break;
+            v = *nptr-'0';
+        } else {
+            if(cur<'a' || cur>='a'+base-10)
+                break;
+            v = cur-'a'+10;
+        }
+
+        nptr++;
+
+        if(ret>MSVCRT_UI64_MAX/base || ret*base>MSVCRT_UI64_MAX-v) {
+            ret = MSVCRT_UI64_MAX;
+            *MSVCRT__errno() = ERANGE;
+        } else
+            ret = ret*base + v;
+    }
+
+    if(endptr)
+        *endptr = (char*)nptr;
+
+    return negative ? -ret : ret;
+}
+
+/*********************************************************************
+ *  _strtoui64 (MSVCR90.@)
+ */
+unsigned __int64 CDECL MSVCRT_strtoui64(const char *nptr, char **endptr, int base)
+{
+    return MSVCRT_strtoui64_l(nptr, endptr, base, NULL);
+}
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index 87c8460..a4926d9 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -55,6 +55,7 @@ static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wc
 static int (__cdecl *p_wcsupr_s)(wchar_t *str, size_t size);
 static size_t (__cdecl *p_strnlen)(const char *, size_t);
 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
+static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
 static _invalid_parameter_handler *p_invalid_parameter;
 static int *p__mb_cur_max;
 static unsigned char *p_mbctype;
@@ -959,10 +960,11 @@ static void test__strtoi64(void)
     static const char blanks[] = "        12 212.31";
 
     __int64 res;
+    unsigned __int64 ures;
     char *endpos;
 
-    if(!p_strtoi64) {
-        win_skip("_strtoi64 not found\n");
+    if(!p_strtoi64 || !p_strtoui64) {
+        win_skip("_strtoi64 or _strtoui64 not found\n");
         return;
     }
 
@@ -974,6 +976,12 @@ static void test__strtoi64(void)
         ok(res == 0, "res != 0\n");
         res = p_strtoi64(no1, NULL, 37);
         ok(res == 0, "res != 0\n");
+        ures = p_strtoui64(NULL, NULL, 10);
+        ok(ures == 0, "res = %d\n", (int)ures);
+        ures = p_strtoui64(no1, NULL, 1);
+        ok(ures == 0, "res = %d\n", (int)ures);
+        ures = p_strtoui64(no1, NULL, 37);
+        ok(ures == 0, "res = %d\n", (int)ures);
         ok(errno == 0xdeadbeef, "errno = %x\n", errno);
     }
 
@@ -1063,6 +1071,42 @@ static void test__strtoi64(void)
     ok(res == 12, "res != 12\n");
     ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos);
     ok(errno == 0xdeadbeef, "errno = %x\n", errno);
+
+    errno = 0xdeadbeef;
+    ures = p_strtoui64(no1, &endpos, 0);
+    ok(ures == 31923, "ures != 31923\n");
+    ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos);
+    ures = p_strtoui64(no2, &endpos, 0);
+    ok(ures == -213312, "ures != -213312\n");
+    ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos);
+    ures = p_strtoui64(no3, &endpos, 10);
+    ok(ures == 12, "ures != 12\n");
+    ok(endpos == no3+2, "Incorrect endpos (%p-%p)\n", no3, endpos);
+    ures = p_strtoui64(no4, &endpos, 10);
+    ok(ures == 0, "ures != 0\n");
+    ok(endpos == no4, "Incorrect endpos (%p-%p)\n", no4, endpos);
+    ures = p_strtoui64(hex, &endpos, 10);
+    ok(ures == 0, "ures != 0\n");
+    ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos);
+    ures = p_strtoui64(oct, &endpos, 10);
+    ok(ures == 123, "ures != 123\n");
+    ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos);
+    ures = p_strtoui64(blanks, &endpos, 10);
+    ok(ures == 12, "ures != 12\n");
+    ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos);
+    ok(errno == 0xdeadbeef, "errno = %x\n", errno);
+
+    errno = 0xdeadbeef;
+    ures = p_strtoui64(overflow, &endpos, 10);
+    ok(ures == _UI64_MAX, "ures != _UI64_MAX\n");
+    ok(endpos == overflow+strlen(overflow), "Incorrect endpos (%p-%p)\n", overflow, endpos);
+    ok(errno == ERANGE, "errno = %x\n", errno);
+
+    errno = 0xdeadbeef;
+    ures = p_strtoui64(neg_overflow, &endpos, 10);
+    ok(ures == 1, "ures != 1\n");
+    ok(endpos == neg_overflow+strlen(neg_overflow), "Incorrect endpos (%p-%p)\n", neg_overflow, endpos);
+    ok(errno == ERANGE, "errno = %x\n", errno);
 }
 
 START_TEST(string)
@@ -1089,6 +1133,7 @@ START_TEST(string)
     p_wcsupr_s = (void *)GetProcAddress( hMsvcrt,"_wcsupr_s" );
     p_strnlen = (void *)GetProcAddress( hMsvcrt,"strnlen" );
     p_strtoi64 = (void *) GetProcAddress(hMsvcrt, "_strtoi64");
+    p_strtoui64 = (void *) GetProcAddress(hMsvcrt, "_strtoui64");
 
     /* MSVCRT memcpy behaves like memmove for overlapping moves,
        MFC42 CString::Insert seems to rely on that behaviour */




More information about the wine-cvs mailing list