[MSVCRT_WINETEST]
authorChristoph von Wittich <christoph_vw@reactos.org>
Sat, 29 May 2010 09:22:07 +0000 (09:22 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Sat, 29 May 2010 09:22:07 +0000 (09:22 +0000)
partial sync to wine 1.2 RC2

svn path=/trunk/; revision=47402

rostests/winetests/msvcrt/data.c
rostests/winetests/msvcrt/environ.c
rostests/winetests/msvcrt/headers.c
rostests/winetests/msvcrt/scanf.c
rostests/winetests/msvcrt/string.c
rostests/winetests/msvcrt/time.c

index a27ca27..7061124 100644 (file)
@@ -74,7 +74,8 @@ static void test_initvar( HMODULE hmsvcrt )
     int *pp_winmajor = (int*)GetProcAddress(hmsvcrt, "_winmajor");
     int *pp_winminor = (int*)GetProcAddress(hmsvcrt, "_winminor");
     int *pp_osver    = (int*)GetProcAddress(hmsvcrt, "_osver");
     int *pp_winmajor = (int*)GetProcAddress(hmsvcrt, "_winmajor");
     int *pp_winminor = (int*)GetProcAddress(hmsvcrt, "_winminor");
     int *pp_osver    = (int*)GetProcAddress(hmsvcrt, "_osver");
-    unsigned int winver, winmajor, winminor, osver;
+    int *pp_osplatform = (int*)GetProcAddress(hmsvcrt, "_osplatform");
+    unsigned int winver, winmajor, winminor, osver, osplatform;
 
     if( !( pp_winmajor && pp_winminor && pp_winver)) {
         win_skip("_winver variables are not available\n");
 
     if( !( pp_winmajor && pp_winminor && pp_winver)) {
         win_skip("_winver variables are not available\n");
@@ -91,16 +92,20 @@ static void test_initvar( HMODULE hmsvcrt )
     ok( winver == ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion),
             "Wrong value for _winver %02x expected %02x\n",
             winver, ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion));
     ok( winver == ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion),
             "Wrong value for _winver %02x expected %02x\n",
             winver, ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion));
-    if( !pp_osver) {
+    if( !pp_osver || !pp_osplatform ) {
         win_skip("_osver variables are not available\n");
         return;
     }
     osver = *pp_osver;
         win_skip("_osver variables are not available\n");
         return;
     }
     osver = *pp_osver;
+    osplatform = *pp_osplatform;
     ok( osver == (osvi.dwBuildNumber & 0xffff) ||
             ((osvi.dwBuildNumber >> 24) == osvi.dwMajorVersion &&
                  ((osvi.dwBuildNumber >> 16) & 0xff) == osvi.dwMinorVersion), /* 95/98/ME */
             "Wrong value for _osver %04x expected %04x\n",
             osver, osvi.dwBuildNumber);
     ok( osver == (osvi.dwBuildNumber & 0xffff) ||
             ((osvi.dwBuildNumber >> 24) == osvi.dwMajorVersion &&
                  ((osvi.dwBuildNumber >> 16) & 0xff) == osvi.dwMinorVersion), /* 95/98/ME */
             "Wrong value for _osver %04x expected %04x\n",
             osver, osvi.dwBuildNumber);
+    ok(osplatform == osvi.dwPlatformId,
+            "Wrong value for _osplatform %x exprected %x\n",
+            osplatform, osvi.dwPlatformId);
 }
 
 START_TEST(data)
 }
 
 START_TEST(data)
index 6175e14..336238c 100644 (file)
@@ -42,6 +42,15 @@ static const char *a_very_long_env_string =
  "/usr/lib/mingw32/3.4.2/;"
  "/usr/lib/";
 
  "/usr/lib/mingw32/3.4.2/;"
  "/usr/lib/";
 
+static void test_system(void)
+{
+    int ret = system(NULL);
+    ok(ret == 1, "Expected system to return 1, got %d\n", ret);
+
+    ret = system("echo OK");
+    ok(ret == 0, "Expected system to return 0, got %d\n", ret);
+}
+
 START_TEST(environ)
 {
     ok( _putenv("cat=") == 0, "_putenv failed on deletion of nonexistent environment variable\n" );
 START_TEST(environ)
 {
     ok( _putenv("cat=") == 0, "_putenv failed on deletion of nonexistent environment variable\n" );
@@ -54,4 +63,6 @@ START_TEST(environ)
     ok( _putenv(a_very_long_env_string) == 0, "_putenv failed for long environment string\n");
 
     ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" );
     ok( _putenv(a_very_long_env_string) == 0, "_putenv failed for long environment string\n");
 
     ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" );
+
+    test_system();
 }
 }
index 80c614b..c39948d 100644 (file)
@@ -68,7 +68,7 @@
 #define MSVCRT(x)    MSVCRT_##x
 #define OFFSET(T,F) ((unsigned int)((char *)&((struct T *)0L)->F - (char *)0L))
 #define CHECK_SIZE(e) ok(sizeof(e) == sizeof(MSVCRT(e)), "Element has different sizes\n")
 #define MSVCRT(x)    MSVCRT_##x
 #define OFFSET(T,F) ((unsigned int)((char *)&((struct T *)0L)->F - (char *)0L))
 #define CHECK_SIZE(e) ok(sizeof(e) == sizeof(MSVCRT(e)), "Element has different sizes\n")
-#define CHECK_TYPE(t) { TYPEOF(t) a = 0; TYPEOF(MSVCRT(t)) b = 0; a = b; CHECK_SIZE(t); }
+#define CHECK_TYPE(t) { TYPEOF(t) a = 0; TYPEOF(MSVCRT(t)) b = a; a = b; CHECK_SIZE(t); }
 #define CHECK_STRUCT(s) ok(sizeof(struct s) == sizeof(struct MSVCRT(s)), "Struct has different sizes\n")
 #define CHECK_FIELD(s,e) ok(OFFSET(s,e) == OFFSET(MSVCRT(s),e), "Bad offset\n")
 #define CHECK_DEF(d) ok(d == MSVCRT_##d, "Defines (MSVCRT_)" #d " are different: %d vs. %d\n", d, MSVCRT_##d)
 #define CHECK_STRUCT(s) ok(sizeof(struct s) == sizeof(struct MSVCRT(s)), "Struct has different sizes\n")
 #define CHECK_FIELD(s,e) ok(OFFSET(s,e) == OFFSET(MSVCRT(s),e), "Bad offset\n")
 #define CHECK_DEF(d) ok(d == MSVCRT_##d, "Defines (MSVCRT_)" #d " are different: %d vs. %d\n", d, MSVCRT_##d)
index 0ec89ff..e9cb987 100644 (file)
@@ -198,7 +198,49 @@ static void test_sscanf( void )
     ok(number_so_far == 4, "%%n yielded wrong result: %d\n", number_so_far);
 }
 
     ok(number_so_far == 4, "%%n yielded wrong result: %d\n", number_so_far);
 }
 
+static void test_sscanf_s(void)
+{
+    int (__cdecl *psscanf_s)(const char*,const char*,...);
+    HMODULE hmod = GetModuleHandleA("msvcrt.dll");
+    int i, ret;
+    char buf[100];
+
+    psscanf_s = (void*)GetProcAddress(hmod, "sscanf_s");
+    if(!psscanf_s) {
+        win_skip("sscanf_s not available\n");
+        return;
+    }
+
+    ret = psscanf_s("123", "%d", &i);
+    ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+    ok(i == 123, "i = %d\n", i);
+
+    ret = psscanf_s("123", "%s", buf, 100);
+    ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+    ok(!strcmp("123", buf), "buf = %s\n", buf);
+
+    ret = psscanf_s("123", "%s", buf, 3);
+    ok(ret == 0, "Wrong number of arguments read: %d\n", ret);
+    ok(buf[0]=='\0', "buf = %s\n", buf);
+
+    buf[0] = 'a';
+    ret = psscanf_s("123", "%3c", buf, 2);
+    ok(ret == 0, "Wrong number of arguments read: %d\n", ret);
+    ok(buf[0]=='\0', "buf = %s\n", buf);
+
+    i = 1;
+    ret = psscanf_s("123 123", "%s %d", buf, 2, &i);
+    ok(ret == 0, "Wrong number of arguments read: %d\n", ret);
+    ok(i==1, "i = %d\n", i);
+
+    i = 1;
+    ret = psscanf_s("123 123", "%d %s", &i, buf, 2);
+    ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+    ok(i==123, "i = %d\n", i);
+}
+
 START_TEST(scanf)
 {
     test_sscanf();
 START_TEST(scanf)
 {
     test_sscanf();
+    test_sscanf_s();
 }
 }
index a7b3404..f6c0e2c 100644 (file)
@@ -27,6 +27,7 @@
 #include <mbctype.h>
 #include <locale.h>
 #include <errno.h>
 #include <mbctype.h>
 #include <locale.h>
 #include <errno.h>
+#include <limits.h>
 
 static char *buf_to_string(const unsigned char *bin, int len, int nr)
 {
 
 static char *buf_to_string(const unsigned char *bin, int len, int nr)
 {
@@ -52,6 +53,11 @@ static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src);
 static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count);
 static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc);
 static int (__cdecl *p_wcsupr_s)(wchar_t *str, size_t size);
 static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count);
 static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc);
 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 int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t);
+static int (__cdecl *pmbstowcs_s)(size_t*,wchar_t*,size_t,const char*,size_t);
 static int *p__mb_cur_max;
 static unsigned char *p_mbctype;
 
 static int *p__mb_cur_max;
 static unsigned char *p_mbctype;
 
@@ -911,6 +917,325 @@ static void test_strtol(void)
     ok(errno == ERANGE, "wrong errno %d\n", errno);
 }
 
     ok(errno == ERANGE, "wrong errno %d\n", errno);
 }
 
+static void test_strnlen(void)
+{
+    static const char str[] = "string";
+    size_t res;
+
+    if(!p_strnlen) {
+        win_skip("strnlen not found\n");
+        return;
+    }
+
+    res = p_strnlen(str, 20);
+    ok(res == 6, "Returned length = %d\n", (int)res);
+
+    res = p_strnlen(str, 3);
+    ok(res == 3, "Returned length = %d\n", (int)res);
+
+    res = p_strnlen(NULL, 0);
+    ok(res == 0, "Returned length = %d\n", (int)res);
+}
+
+static void test__strtoi64(void)
+{
+    static const char no1[] = "31923";
+    static const char no2[] = "-213312";
+    static const char no3[] = "12aa";
+    static const char no4[] = "abc12";
+    static const char overflow[] = "99999999999999999999";
+    static const char neg_overflow[] = "-99999999999999999999";
+    static const char hex[] = "0x123";
+    static const char oct[] = "000123";
+    static const char blanks[] = "        12 212.31";
+
+    __int64 res;
+    unsigned __int64 ures;
+    char *endpos;
+
+    if(!p_strtoi64 || !p_strtoui64) {
+        win_skip("_strtoi64 or _strtoui64 not found\n");
+        return;
+    }
+
+    errno = 0xdeadbeef;
+    res = p_strtoi64(no1, NULL, 10);
+    ok(res == 31923, "res != 31923\n");
+    res = p_strtoi64(no2, NULL, 10);
+    ok(res == -213312, "res != -213312\n");
+    res = p_strtoi64(no3, NULL, 10);
+    ok(res == 12, "res != 12\n");
+    res = p_strtoi64(no4, &endpos, 10);
+    ok(res == 0, "res != 0\n");
+    ok(endpos == no4, "Scanning was not stopped on first character\n");
+    res = p_strtoi64(hex, &endpos, 10);
+    ok(res == 0, "res != 0\n");
+    ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos);
+    res = p_strtoi64(oct, &endpos, 10);
+    ok(res == 123, "res != 123\n");
+    ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos);
+    res = p_strtoi64(blanks, &endpos, 10);
+    ok(res == 12, "res != 12");
+    ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos);
+    ok(errno == 0xdeadbeef, "errno = %x\n", errno);
+
+    errno = 0xdeadbeef;
+    res = p_strtoi64(overflow, &endpos, 10);
+    ok(res == _I64_MAX, "res != _I64_MAX\n");
+    ok(endpos == overflow+strlen(overflow), "Incorrect endpos (%p-%p)\n", overflow, endpos);
+    ok(errno == ERANGE, "errno = %x\n", errno);
+
+    errno = 0xdeadbeef;
+    res = p_strtoi64(neg_overflow, &endpos, 10);
+    ok(res == _I64_MIN, "res != _I64_MIN\n");
+    ok(endpos == neg_overflow+strlen(neg_overflow), "Incorrect endpos (%p-%p)\n", neg_overflow, endpos);
+    ok(errno == ERANGE, "errno = %x\n", errno);
+
+    errno = 0xdeadbeef;
+    res = p_strtoi64(no1, &endpos, 16);
+    ok(res == 203043, "res != 203043\n");
+    ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos);
+    res = p_strtoi64(no2, &endpos, 16);
+    ok(res == -2175762, "res != -2175762\n");
+    ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos);
+    res = p_strtoi64(no3, &endpos, 16);
+    ok(res == 4778, "res != 4778\n");
+    ok(endpos == no3+strlen(no3), "Incorrect endpos (%p-%p)\n", no3, endpos);
+    res = p_strtoi64(no4, &endpos, 16);
+    ok(res == 703506, "res != 703506\n");
+    ok(endpos == no4+strlen(no4), "Incorrect endpos (%p-%p)\n", no4, endpos);
+    res = p_strtoi64(hex, &endpos, 16);
+    ok(res == 291, "res != 291\n");
+    ok(endpos == hex+strlen(hex), "Incorrect endpos (%p-%p)\n", hex, endpos);
+    res = p_strtoi64(oct, &endpos, 16);
+    ok(res == 291, "res != 291\n");
+    ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos);
+    res = p_strtoi64(blanks, &endpos, 16);
+    ok(res == 18, "res != 18\n");
+    ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos);
+    ok(errno == 0xdeadbeef, "errno = %x\n", errno);
+
+    errno = 0xdeadbeef;
+    res = p_strtoi64(hex, &endpos, 36);
+    ok(res == 1541019, "res != 1541019\n");
+    ok(endpos == hex+strlen(hex), "Incorrect endpos (%p-%p)\n", hex, endpos);
+    ok(errno == 0xdeadbeef, "errno = %x\n", errno);
+
+    errno = 0xdeadbeef;
+    res = p_strtoi64(no1, &endpos, 0);
+    ok(res == 31923, "res != 31923\n");
+    ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos);
+    res = p_strtoi64(no2, &endpos, 0);
+    ok(res == -213312, "res != -213312\n");
+    ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos);
+    res = p_strtoi64(no3, &endpos, 10);
+    ok(res == 12, "res != 12\n");
+    ok(endpos == no3+2, "Incorrect endpos (%p-%p)\n", no3, endpos);
+    res = p_strtoi64(no4, &endpos, 10);
+    ok(res == 0, "res != 0\n");
+    ok(endpos == no4, "Incorrect endpos (%p-%p)\n", no4, endpos);
+    res = p_strtoi64(hex, &endpos, 10);
+    ok(res == 0, "res != 0\n");
+    ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos);
+    res = p_strtoi64(oct, &endpos, 10);
+    ok(res == 123, "res != 123\n");
+    ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos);
+    res = p_strtoi64(blanks, &endpos, 10);
+    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);
+}
+
+static inline BOOL almost_equal(double d1, double d2) {
+    if(d1-d2>-1e-30 && d1-d2<1e-30)
+        return TRUE;
+    return FALSE;
+}
+
+static void test__strtod(void)
+{
+    const char double1[] = "12.1";
+    const char double2[] = "-13.721";
+    const char double3[] = "INF";
+    const char double4[] = ".21e12";
+    const char double5[] = "214353e-3";
+    const char overflow[] = "1d9999999999999999999";
+
+    char *end;
+    double d;
+
+    d = strtod(double1, &end);
+    ok(almost_equal(d, 12.1), "d = %lf\n", d);
+    ok(end == double1+4, "incorrect end (%d)\n", end-double1);
+
+    d = strtod(double2, &end);
+    ok(almost_equal(d, -13.721), "d = %lf\n", d);
+    ok(end == double2+7, "incorrect end (%d)\n", end-double2);
+
+    d = strtod(double3, &end);
+    ok(almost_equal(d, 0), "d = %lf\n", d);
+    ok(end == double3, "incorrect end (%d)\n", end-double3);
+
+    d = strtod(double4, &end);
+    ok(almost_equal(d, 210000000000.0), "d = %lf\n", d);
+    ok(end == double4+6, "incorrect end (%d)\n", end-double4);
+
+    d = strtod(double5, &end);
+    ok(almost_equal(d, 214.353), "d = %lf\n", d);
+    ok(end == double5+9, "incorrect end (%d)\n", end-double5);
+
+    d = strtod("12.1d2", NULL);
+    ok(almost_equal(d, 12.1e2), "d = %lf\n", d);
+
+    /* Set locale with non '.' decimal point (',') */
+    if(!setlocale(LC_ALL, "Polish")) {
+        win_skip("system with limited locales\n");
+        return;
+    }
+
+    d = strtod("12.1", NULL);
+    ok(almost_equal(d, 12.0), "d = %lf\n", d);
+
+    d = strtod("12,1", NULL);
+    ok(almost_equal(d, 12.1), "d = %lf\n", d);
+
+    setlocale(LC_ALL, "C");
+
+    /* Precision tests */
+    d = strtod("0.1", NULL);
+    ok(almost_equal(d, 0.1), "d = %lf\n", d);
+    d = strtod("-0.1", NULL);
+    ok(almost_equal(d, -0.1), "d = %lf\n", d);
+    d = strtod("0.1281832188491894198128921", NULL);
+    ok(almost_equal(d, 0.1281832188491894198128921), "d = %lf\n", d);
+    d = strtod("0.82181281288121", NULL);
+    ok(almost_equal(d, 0.82181281288121), "d = %lf\n", d);
+    d = strtod("21921922352523587651128218821", NULL);
+    ok(almost_equal(d, 21921922352523587651128218821.0), "d = %lf\n", d);
+    d = strtod("0.1d238", NULL);
+    ok(almost_equal(d, 0.1e238L), "d = %lf\n", d);
+    d = strtod("0.1D-4736", NULL);
+    ok(almost_equal(d, 0.1e-4736L), "d = %lf\n", d);
+
+    errno = 0xdeadbeef;
+    d = strtod(overflow, &end);
+    ok(errno == ERANGE, "errno = %x\n", errno);
+    ok(end == overflow+21, "incorrect end (%d)\n", end-overflow);
+
+    errno = 0xdeadbeef;
+    strtod("-1d309", NULL);
+    ok(errno == ERANGE, "errno = %x\n", errno);
+}
+
+static void test_mbstowcs(void)
+{
+    static const wchar_t wSimple[] = { 't','e','x','t',0 };
+    static const wchar_t wHiragana[] = { 0x3042,0x3043,0 };
+    static const char mSimple[] = "text";
+    static const char mHiragana[] = { 0x82,0xa0,0x82,0xa1,0 };
+
+    wchar_t wOut[6];
+    char mOut[6];
+    size_t ret;
+    int err;
+
+    wOut[4] = '!'; wOut[5] = '\0';
+    mOut[4] = '!'; mOut[5] = '\0';
+
+    ret = mbstowcs(NULL, mSimple, 0);
+    ok(ret == 4, "ret = %d\n", ret);
+
+    ret = mbstowcs(wOut, mSimple, 4);
+    ok(ret == 4, "ret = %d\n", ret);
+    ok(!memcmp(wOut, wSimple, 4*sizeof(wchar_t)), "wOut = %s\n", wine_dbgstr_w(wOut));
+    ok(wOut[4] == '!', "wOut[4] != \'!\'\n");
+
+    ret = wcstombs(NULL, wSimple, 0);
+    ok(ret == 4, "ret = %d\n", ret);
+
+    ret = wcstombs(mOut, wSimple, 6);
+    ok(ret == 4, "ret = %d\n", ret);
+    ok(!memcmp(mOut, mSimple, 5*sizeof(char)), "mOut = %s\n", mOut);
+
+    ret = wcstombs(mOut, wSimple, 2);
+    ok(ret == 2, "ret = %d\n", ret);
+    ok(!memcmp(mOut, mSimple, 5*sizeof(char)), "mOut = %s\n", mOut);
+
+    if(!setlocale(LC_ALL, "Japanese_Japan.932")) {
+        win_skip("Japanese_Japan.932 locale not available\n");
+        return;
+    }
+
+    ret = mbstowcs(wOut, mHiragana, 6);
+    ok(ret == 2, "ret = %d\n", ret);
+    ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut));
+
+    ret = wcstombs(mOut, wHiragana, 6);
+    ok(ret == 4, "ret = %d\n", ret);
+    ok(!memcmp(mOut, mHiragana, sizeof(mHiragana)), "mOut = %s\n", mOut);
+
+    if(!pmbstowcs_s || !pwcstombs_s) {
+        win_skip("mbstowcs_s or wcstombs_s not available\n");
+        return;
+    }
+
+    err = pmbstowcs_s(&ret, wOut, 6, mSimple, -1/*_TRUNCATE*/);
+    ok(err == 0, "err = %d\n", err);
+    ok(ret == 5, "ret = %d\n", (int)ret);
+    ok(!memcmp(wOut, wSimple, sizeof(wSimple)), "wOut = %s\n", wine_dbgstr_w(wOut));
+
+    err = pmbstowcs_s(&ret, wOut, 6, mHiragana, -1/*_TRUNCATE*/);
+    ok(err == 0, "err = %d\n", err);
+    ok(ret == 3, "ret = %d\n", (int)ret);
+    ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut));
+
+    err = pwcstombs_s(&ret, mOut, 6, wSimple, -1/*_TRUNCATE*/);
+    ok(err == 0, "err = %d\n", err);
+    ok(ret == 5, "ret = %d\n", (int)ret);
+    ok(!memcmp(mOut, mSimple, sizeof(mSimple)), "mOut = %s\n", mOut);
+
+    err = pwcstombs_s(&ret, mOut, 6, wHiragana, -1/*_TRUNCATE*/);
+    ok(err == 0, "err = %d\n", err);
+    ok(ret == 5, "ret = %d\n", (int)ret);
+    ok(!memcmp(mOut, mHiragana, sizeof(mHiragana)), "mOut = %s\n", mOut);
+}
+
 START_TEST(string)
 {
     char mem[100];
 START_TEST(string)
 {
     char mem[100];
@@ -930,6 +1255,11 @@ START_TEST(string)
     p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" );
     p_wcscpy_s = (void *)GetProcAddress( hMsvcrt,"wcscpy_s" );
     p_wcsupr_s = (void *)GetProcAddress( hMsvcrt,"_wcsupr_s" );
     p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" );
     p_wcscpy_s = (void *)GetProcAddress( hMsvcrt,"wcscpy_s" );
     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");
+    pmbstowcs_s = (void *) GetProcAddress(hMsvcrt, "mbstowcs_s");
+    pwcstombs_s = (void *) GetProcAddress(hMsvcrt, "wcstombs_s");
 
     /* MSVCRT memcpy behaves like memmove for overlapping moves,
        MFC42 CString::Insert seems to rely on that behaviour */
 
     /* MSVCRT memcpy behaves like memmove for overlapping moves,
        MFC42 CString::Insert seems to rely on that behaviour */
@@ -959,4 +1289,8 @@ START_TEST(string)
     test_wcscpy_s();
     test__wcsupr_s();
     test_strtol();
     test_wcscpy_s();
     test__wcsupr_s();
     test_strtol();
+    test_strnlen();
+    test__strtoi64();
+    test__strtod();
+    test_mbstowcs();
 }
 }
index ac782ca..7f0a80b 100644 (file)
@@ -54,20 +54,75 @@ static void test_ctime(void)
 }
 static void test_gmtime(void)
 {
 }
 static void test_gmtime(void)
 {
-    time_t gmt = 0;
-    struct tm* gmt_tm = gmtime(&gmt);
-    if(gmt_tm == 0)
-       {
-           ok(0,"gmtime() error\n");
-           return;
-       }
+    static __time32_t (__cdecl *p_mkgmtime32)(struct tm*);
+    static struct tm* (__cdecl *p_gmtime32)(__time32_t*);
+
+    HMODULE hmod = GetModuleHandleA("msvcrt.dll");
+    __time32_t valid, gmt;
+    struct tm* gmt_tm;
+
+    p_gmtime32 = (void*)GetProcAddress(hmod, "_gmtime32");
+    if(!p_gmtime32) {
+        win_skip("Skipping _gmtime32 tests\n");
+        return;
+    }
+
+    gmt = valid = 0;
+    gmt_tm = p_gmtime32(&gmt);
+    if(!gmt_tm) {
+        ok(0, "_gmtime32() failed\n");
+        return;
+    }
+
     ok(((gmt_tm->tm_year == 70) && (gmt_tm->tm_mon  == 0) && (gmt_tm->tm_yday  == 0) &&
     ok(((gmt_tm->tm_year == 70) && (gmt_tm->tm_mon  == 0) && (gmt_tm->tm_yday  == 0) &&
-       (gmt_tm->tm_mday ==  1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour  == 0) &&
-       (gmt_tm->tm_min  ==  0) && (gmt_tm->tm_sec  == 0) && (gmt_tm->tm_isdst == 0)),
-       "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
-       gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday, 
-       gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst); 
-  
+                (gmt_tm->tm_mday ==  1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour  == 0) &&
+                (gmt_tm->tm_min  ==  0) && (gmt_tm->tm_sec  == 0) && (gmt_tm->tm_isdst == 0)),
+            "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
+            gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday,
+            gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst);
+
+    p_mkgmtime32 = (void*)GetProcAddress(hmod, "_mkgmtime32");
+    if(!p_mkgmtime32) {
+        win_skip("Skipping _mkgmtime32 tests\n");
+        return;
+    }
+
+    gmt_tm->tm_wday = gmt_tm->tm_yday = 0;
+    gmt = p_mkgmtime32(gmt_tm);
+    ok(gmt == valid, "gmt = %u\n", gmt);
+    ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday);
+    ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday);
+
+    gmt_tm->tm_wday = gmt_tm->tm_yday = 0;
+    gmt_tm->tm_isdst = -1;
+    gmt = p_mkgmtime32(gmt_tm);
+    ok(gmt == valid, "gmt = %u\n", gmt);
+    ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday);
+    ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday);
+
+    gmt_tm->tm_wday = gmt_tm->tm_yday = 0;
+    gmt_tm->tm_isdst = 1;
+    gmt = p_mkgmtime32(gmt_tm);
+    ok(gmt == valid, "gmt = %u\n", gmt);
+    ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday);
+    ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday);
+
+    gmt = valid = 173921;
+    gmt_tm = p_gmtime32(&gmt);
+    if(!gmt_tm) {
+        ok(0, "_gmtime32() failed\n");
+        return;
+    }
+
+    gmt_tm->tm_isdst = -1;
+    gmt = p_mkgmtime32(gmt_tm);
+    ok(gmt == valid, "gmt = %u\n", gmt);
+    ok(gmt_tm->tm_wday == 6, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday);
+    ok(gmt_tm->tm_yday == 2, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday);
+
+    gmt_tm->tm_isdst = 1;
+    gmt = p_mkgmtime32(gmt_tm);
+    ok(gmt == valid, "gmt = %u\n", gmt);
 }
 
 static void test_mktime(void)
 }
 
 static void test_mktime(void)