[MSVCRT_WINETEST] Sync with Wine Staging 2.9. CORE-13362
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 4 Jun 2017 01:50:58 +0000 (01:50 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 4 Jun 2017 01:50:58 +0000 (01:50 +0000)
svn path=/trunk/; revision=74882

rostests/winetests/msvcrt/cpp.c
rostests/winetests/msvcrt/file.c
rostests/winetests/msvcrt/misc.c
rostests/winetests/msvcrt/printf.c
rostests/winetests/msvcrt/scanf.c
rostests/winetests/msvcrt/string.c

index 490ddee..cf5e4c7 100644 (file)
@@ -969,7 +969,11 @@ static void test_rtti(void)
   void *child_class_sig0 = &child_class_sig0_vtbl[1];
   void *virtual_base_class_vtbl[2] = {&virtual_base_class_rtti.object_locator};
   int virtual_base_class_vbtbl[2] = {0, 0x100};
-  void *virtual_base_class[2] = {&virtual_base_class_vtbl[1], virtual_base_class_vbtbl};
+  struct {
+      void *virtual_base[2];
+      char data[0x110-sizeof(void*)];
+      void *vbthis;
+  } virtual_base_class = { {&virtual_base_class_vtbl[1], virtual_base_class_vbtbl} };
 
   static const char* e_name = "name";
   type_info *ti,*bti;
@@ -1082,7 +1086,7 @@ static void test_rtti(void)
   ok(casted == (char*)&child_class+4, "failed cast to child class (%p %p)\n", casted, &child_class);
 
   casted = p__RTDynamicCast(&virtual_base_class, 0, &virtual_base_class_rtti.type_info[0], &virtual_base_class_rtti.type_info[1], 0);
-  ok(casted == (char*)&virtual_base_class+0x110+sizeof(void*), "failed cast to child class (%p %p)\n", casted, &virtual_base_class);
+  ok(casted == &virtual_base_class.vbthis, "failed cast to child class (%p %p)\n", casted, &virtual_base_class);
 }
 
 struct _demangle {
index 9e2beee..2c356ea 100644 (file)
@@ -49,6 +49,8 @@ static HANDLE proc_handles[2];
 
 static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*);
 static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*);
+static errno_t (__cdecl *p__get_fmode)(int*);
+static errno_t (__cdecl *p__set_fmode)(int);
 
 static const char* get_base_name(const char *path)
 {
@@ -71,6 +73,8 @@ static void init(void)
     p_fopen_s = (void*)GetProcAddress(hmod, "fopen_s");
     p__wfopen_s = (void*)GetProcAddress(hmod, "_wfopen_s");
     __pioinfo = (void*)GetProcAddress(hmod, "__pioinfo");
+    p__get_fmode = (void*)GetProcAddress(hmod, "_get_fmode");
+    p__set_fmode = (void*)GetProcAddress(hmod, "_set_fmode");
 }
 
 static void test_filbuf( void )
@@ -2386,6 +2390,59 @@ static void test_close(void)
     DeleteFileA( "fdopen.tst" );
 }
 
+static void test__creat(void)
+{
+    int fd, pos, count, readonly, old_fmode = 0, have_fmode;
+    char buf[6], testdata[4] = {'a', '\n', 'b', '\n'};
+
+    have_fmode = p__get_fmode && p__set_fmode && !p__get_fmode(&old_fmode);
+    if (!have_fmode)
+        win_skip("_fmode can't be set, skipping mode tests\n");
+
+    if (have_fmode)
+        p__set_fmode(_O_TEXT);
+    fd = _creat("_creat.tst", 0);
+    ok(fd > 0, "_creat failed\n");
+    _write(fd, testdata, 4);
+    if (have_fmode) {
+        pos = _tell(fd);
+        ok(pos == 6, "expected pos 6 (text mode), got %d\n", pos);
+    }
+    ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n");
+    count = _read(fd, buf, 6);
+    ok(count == 4, "_read returned %d, expected 4\n", count);
+    count = count > 0 ? count > 4 ? 4 : count : 0;
+    ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n");
+    _close(fd);
+    readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY;
+    ok(readonly, "expected read-only file\n");
+    SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL);
+    DeleteFileA("_creat.tst");
+
+    if (have_fmode)
+        p__set_fmode(_O_BINARY);
+    fd = _creat("_creat.tst", _S_IREAD | _S_IWRITE);
+    ok(fd > 0, "_creat failed\n");
+    _write(fd, testdata, 4);
+    if (have_fmode) {
+        pos = _tell(fd);
+        ok(pos == 4, "expected pos 4 (binary mode), got %d\n", pos);
+    }
+    ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n");
+    count = _read(fd, buf, 6);
+    ok(count == 4, "_read returned %d, expected 4\n", count);
+    count = count > 0 ? count > 4 ? 4 : count : 0;
+    ok(memcmp(buf, testdata, count) == 0, "_read returned wrong contents\n");
+    _close(fd);
+    readonly = GetFileAttributesA("_creat.tst") & FILE_ATTRIBUTE_READONLY;
+    ok(!readonly, "expected rw file\n");
+    SetFileAttributesA("_creat.tst", FILE_ATTRIBUTE_NORMAL);
+    DeleteFileA("_creat.tst");
+
+    if (have_fmode)
+        p__set_fmode(old_fmode);
+}
+
 START_TEST(file)
 {
     int arg_c;
@@ -2453,6 +2510,7 @@ START_TEST(file)
     test__open_osfhandle();
     test_write_flush();
     test_close();
+    test__creat();
 
     /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
      * file contains lines in the correct order
index b7f5bdb..2aeff43 100644 (file)
@@ -58,6 +58,8 @@ static void (__cdecl *p_qsort_s)(void*, MSVCRT_size_t, MSVCRT_size_t,
 static double (__cdecl *p_atan)(double);
 static double (__cdecl *p_exp)(double);
 static double (__cdecl *p_tanh)(double);
+static void *(__cdecl *p_lfind_s)(const void*, const void*, unsigned int*,
+        size_t, int (__cdecl *)(void*, const void*, const void*), void*);
 
 static void init(void)
 {
@@ -75,6 +77,7 @@ static void init(void)
     p_atan = (void *)GetProcAddress(hmod, "atan");
     p_exp = (void *)GetProcAddress(hmod, "exp");
     p_tanh = (void *)GetProcAddress(hmod, "tanh");
+    p_lfind_s = (void *)GetProcAddress(hmod, "_lfind_s");
 }
 
 static void test_rand_s(void)
@@ -558,7 +561,7 @@ static void test_thread_handle_close(void)
     DWORD ret;
 
     /* _beginthread: handle is not closed on ExitThread and _endthreadex */
-    hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)0);
+    hThread = (HANDLE)_beginthread(test_thread_func, 0, NULL);
     ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
     WaitForSingleObject(hThread, INFINITE);
     ret = CloseHandle(hThread);
@@ -596,6 +599,74 @@ static void test_thread_handle_close(void)
     ok(ret, "ret = %d\n", ret);
 }
 
+static int __cdecl _lfind_s_comp(void *ctx, const void *l, const void *r)
+{
+    *(int *)ctx = 0xdeadc0de;
+    return *(int *)l - *(int *)r;
+}
+
+static void test__lfind_s(void)
+{
+    static const int tests[] = {9000, 8001, 7002, 6003, 1003, 5004, 4005, 3006, 2007};
+    unsigned int num;
+    void *found;
+    int ctx;
+    int key;
+
+    if (!p_lfind_s)
+    {
+        win_skip("_lfind_s is not available\n");
+        return;
+    }
+
+    key = 1234;
+    num = sizeof(tests)/sizeof(tests[0]);
+
+    errno = 0xdeadbeef;
+    found = p_lfind_s(NULL, tests, &num, sizeof(int), _lfind_s_comp, NULL);
+    ok(errno == EINVAL, "errno = %d\n", errno);
+    ok(!found, "Expected NULL, got %p\n", found);
+
+    errno = 0xdeadbeef;
+    found = p_lfind_s(&key, NULL, &num, sizeof(int), _lfind_s_comp, NULL);
+    ok(errno == EINVAL, "errno = %d\n", errno);
+    ok(!found, "Expected NULL, got %p\n", found);
+
+    errno = 0xdeadbeef;
+    found = p_lfind_s(&key, tests, &num, 0, _lfind_s_comp, NULL);
+    ok(errno == EINVAL, "errno = %d\n", errno);
+    ok(!found, "Expected NULL, got %p\n", found);
+
+    errno = 0xdeadbeef;
+    found = p_lfind_s(&key, tests, &num, sizeof(int), NULL, NULL);
+    ok(errno == EINVAL, "errno = %d\n", errno);
+    ok(!found, "Expected NULL, got %p\n", found);
+
+    ctx = -1;
+    key = 9000;
+    errno = 0xdeadbeef;
+    found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
+    ok(errno == 0xdeadbeef, "errno = %d\n", errno);
+    ok(found == tests, "Expected %p, got %p\n", tests, found);
+    ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
+
+    ctx = -1;
+    key = 2007;
+    errno = 0xdeadbeef;
+    found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
+    ok(errno == 0xdeadbeef, "errno = %d\n", errno);
+    ok(found == tests+8, "Expected %p, got %p\n", tests+8, found);
+    ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
+
+    ctx = -1;
+    key = 1234;
+    errno = 0xdeadbeef;
+    found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
+    ok(errno == 0xdeadbeef, "errno = %d\n", errno);
+    ok(!found, "Expected NULL, got %p\n", found);
+    ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
+}
+
 START_TEST(misc)
 {
     int arg_c;
@@ -625,4 +696,5 @@ START_TEST(misc)
     test_qsort_s();
     test_math_functions();
     test_thread_handle_close();
+    test__lfind_s();
 }
index 295c6dd..f9b3fc9 100644 (file)
@@ -27,6 +27,7 @@
  
 #include <stdio.h>
 #include <errno.h>
+#include <locale.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -768,6 +769,39 @@ static void test_sprintf( void )
     r = sprintf(buffer, format, INFINITY);
     ok(r==10, "r = %d\n", r);
     ok(!strcmp(buffer, "0000001.#J"), "failed: \"%s\"\n", buffer);
+
+    format = "%c";
+    r = sprintf(buffer, format, 'a');
+    ok(r==1, "r = %d\n", r);
+    ok(!strcmp(buffer, "a"), "failed: \"%s\"\n", buffer);
+    r = sprintf(buffer, format, 0xa082);
+    ok(r==1, "r = %d\n", r);
+    ok(!strcmp(buffer, "\x82"), "failed: \"%s\"\n", buffer);
+
+    format = "%C";
+    r = sprintf(buffer, format, 'a');
+    ok(r==1, "r = %d\n", r);
+    ok(!strcmp(buffer, "a"), "failed: \"%s\"\n", buffer);
+    r = sprintf(buffer, format, 0x3042);
+    ok(r==0, "r = %d\n", r);
+    ok(!strcmp(buffer, ""), "failed: \"%s\"\n", buffer);
+
+    if(!setlocale(LC_ALL, "Japanese_Japan.932")) {
+        win_skip("Japanese_Japan.932 locale not available\n");
+        return;
+    }
+
+    format = "%c";
+    r = sprintf(buffer, format, 0xa082);
+    ok(r==1, "r = %d\n", r);
+    ok(!strcmp(buffer, "\x82"), "failed: \"%s\"\n", buffer);
+
+    format = "%C";
+    r = sprintf(buffer, format, 0x3042);
+    ok(r==2, "r = %d\n", r);
+    ok(!strcmp(buffer, "\x82\xa0"), "failed: \"%s\"\n", buffer);
+
+    setlocale(LC_ALL, "C");
 }
 
 static void test_swprintf( void )
@@ -911,7 +945,7 @@ static void test_fcvt(void)
 {
     char *str;
     int dec=100, sign=100;
-    
+
     /* Numbers less than 1.0 with different precisions */
     str = _fcvt(0.0001, 1, &dec, &sign );
     ok( 0 == strcmp(str,""), "bad return '%s'\n", str);
index 6cb85fa..1d1f28e 100644 (file)
@@ -251,6 +251,10 @@ static void test_sscanf( void )
     ok(ret == 2, "got %d\n", ret);
     ok(!strcmp(buffer, "test"), "buf %s\n", buffer);
     ok(!strcmp(buffer1, "value\xda"), "buf %s\n", buffer1);
+
+    ret = sscanf("\x81\x82test", "\x81%\x82%s", buffer);
+    ok(ret == 1, "got %d\n", ret);
+    ok(!strcmp(buffer, "test"), "buf = %s\n", buffer);
 }
 
 static void test_sscanf_s(void)
@@ -299,6 +303,8 @@ static void test_swscanf( void )
     wchar_t buffer[100];
     int result, ret;
     static const WCHAR formatd[] = {'%','d',0};
+    const WCHAR format2[] = {'a',0x1234,'%',0x1234,'%','c',0};
+    WCHAR c;
 
     /* check WEOF */
     /* WEOF is an unsigned short -1 but swscanf returns int
@@ -308,6 +314,14 @@ static void test_swscanf( void )
     /* msvcrt returns 0 but should return -1 (later versions do) */
     ok( ret == (short)WEOF || broken(ret == 0),
         "swscanf returns %x instead of %x\n", ret, WEOF );
+
+    buffer[0] = 'a';
+    buffer[1] = 0x1234;
+    buffer[2] = 0x1234;
+    buffer[3] = 'b';
+    ret = swscanf(buffer, format2, &c);
+    ok(ret == 1, "swscanf returned %d\n", ret);
+    ok(c == 'b', "c = %x\n", c);
 }
 
 START_TEST(scanf)
index 8e78695..a59ed91 100644 (file)
@@ -2827,11 +2827,21 @@ static void test__stricmp(void)
 static void test__wcstoi64(void)
 {
     static const WCHAR digit[] = { '9', 0 };
+    static const WCHAR space[] = { ' ', 0 };
     static const WCHAR stock[] = { 0x3231, 0 }; /* PARENTHESIZED IDEOGRAPH STOCK */
+    static const WCHAR cjk_1[] = { 0x4e00, 0 }; /* CJK Ideograph, First */
     static const WCHAR tamil[] = { 0x0bef, 0 }; /* TAMIL DIGIT NINE */
     static const WCHAR thai[]  = { 0x0e59, 0 }; /* THAI DIGIT NINE */
     static const WCHAR fullwidth[] = { 0xff19, 0 }; /* FULLWIDTH DIGIT NINE */
+    static const WCHAR superscript1[] = { 0xb9, 0 }; /* SUPERSCRIPT ONE */
+    static const WCHAR minus_0x91[]  = { '-', 0x0e50, 'x', 0xff19, '1', 0 };
+    static const WCHAR plus_071[]  = { '+', 0x0e50, 0xff17, '1', 0 };
     static const WCHAR hex[] = { 0xff19, 'f', 0x0e59, 0xff46, 0 };
+    static const WCHAR zeros[] = {
+        0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xc66, 0xce6,
+        0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x17e0, 0x1810, 0xff10
+    };
+    int i;
 
     __int64 res;
     unsigned __int64 ures;
@@ -2844,21 +2854,33 @@ static void test__wcstoi64(void)
 
     res = p_wcstoi64(digit, NULL, 10);
     ok(res == 9, "res != 9\n");
+    res = p_wcstoi64(space, &endpos, 0);
+    ok(endpos == space, "endpos != space\n");
     res = p_wcstoi64(stock, &endpos, 10);
     ok(res == 0, "res != 0\n");
     ok(endpos == stock, "Incorrect endpos (%p-%p)\n", stock, endpos);
+    res = p_wcstoi64(cjk_1, NULL, 0);
+    ok(res == 0, "res != 0\n");
     res = p_wcstoi64(tamil, &endpos, 10);
     ok(res == 0, "res != 0\n");
     ok(endpos == tamil, "Incorrect endpos (%p-%p)\n", tamil, endpos);
     res = p_wcstoi64(thai, NULL, 10);
-    todo_wine ok(res == 9, "res != 9\n");
+    ok(res == 9, "res != 9\n");
     res = p_wcstoi64(fullwidth, NULL, 10);
-    todo_wine ok(res == 9, "res != 9\n");
+    ok(res == 9, "res != 9\n");
+    res = p_wcstoi64(superscript1, NULL, 10);
+    ok(res == 0, "res != 0\n");
     res = p_wcstoi64(hex, NULL, 16);
-    todo_wine ok(res == 0x9f9, "res != 0x9f9\n");
+    ok(res == 0x9f9, "res != 0x9f9\n");
+    res = p_wcstoi64(minus_0x91, NULL, 0);
+    ok(res == -0x91, "res != -0x91\n");
+    res = p_wcstoi64(plus_071, NULL, 0);
+    ok(res == 071, "res != 071\n");
 
     ures = p_wcstoui64(digit, NULL, 10);
     ok(ures == 9, "ures != 9\n");
+    ures = p_wcstoui64(space, &endpos, 0);
+    ok(endpos == space, "endpos != space\n");
     ures = p_wcstoui64(stock, &endpos, 10);
     ok(ures == 0, "ures != 0\n");
     ok(endpos == stock, "Incorrect endpos (%p-%p)\n", stock, endpos);
@@ -2866,11 +2888,25 @@ static void test__wcstoi64(void)
     ok(ures == 0, "ures != 0\n");
     ok(endpos == tamil, "Incorrect endpos (%p-%p)\n", tamil, endpos);
     ures = p_wcstoui64(thai, NULL, 10);
-    todo_wine ok(ures == 9, "ures != 9\n");
+    ok(ures == 9, "ures != 9\n");
     ures = p_wcstoui64(fullwidth, NULL, 10);
-    todo_wine ok(ures == 9, "ures != 9\n");
+    ok(ures == 9, "ures != 9\n");
+    ures = p_wcstoui64(superscript1, NULL, 10);
+    ok(ures == 0, "ures != 0\n");
     ures = p_wcstoui64(hex, NULL, 16);
-    todo_wine ok(ures == 0x9f9, "ures != 0x9f9\n");
+    ok(ures == 0x9f9, "ures != 0x9f9\n");
+    ures = p_wcstoui64(plus_071, NULL, 0);
+    ok(ures == 071, "ures != 071\n");
+
+    /* Test various unicode digits */
+    for (i = 0; i < sizeof(zeros) / sizeof(zeros[0]); ++i) {
+        WCHAR tmp[] = {zeros[i] + 4, zeros[i], zeros[i] + 5, 0};
+        res = p_wcstoi64(tmp, NULL, 0);
+        ok(res == 405, "with zero = U+%04X: got %d, expected 405\n", zeros[i], (int)res);
+        tmp[1] = zeros[i] + 10;
+        res = p_wcstoi64(tmp, NULL, 16);
+        ok(res == 4, "with zero = U+%04X: got %d, expected 4\n", zeros[i], (int)res);
+    }
 
     return;
 }