-- v4: msvcp140: Call into fopen from _Fiopen. ucrtbase: Handle utf-8 in _fsopen. msvcp140/tests: Add tests for _Fiopen. msvcp120/tests: Add tests for _Fiopen. ucrtbase/tests: Add tests for _fsopen. msvcr120/tests: Add tests for _fsopen.
From: Daniel Lehman dlehman25@gmail.com
--- dlls/msvcr120/tests/msvcr120.c | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 6d9f37ad5b2..e50fa43be04 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -26,6 +26,7 @@ #include <fenv.h> #include <limits.h> #include <wctype.h> +#include <share.h>
#include <windef.h> #include <winbase.h> @@ -233,6 +234,10 @@ static struct tm* (__cdecl *p_gmtime32)(__time32_t*); static errno_t (__cdecl *p_gmtime32_s)(struct tm*, __time32_t*); static struct tm* (__cdecl *p_gmtime64)(__time64_t*); static errno_t (__cdecl *p_gmtime64_s)(struct tm*, __time64_t*); +static FILE * (__cdecl *p__fsopen)(const char *, const char *, int); +static FILE * (__cdecl *p__wfsopen)(const wchar_t *, const wchar_t *, int); +static int (_cdecl *p_fclose)(FILE *); +static int (_cdecl *p__unlink)(const char *);
/* make sure we use the correct errno */ #undef errno @@ -319,6 +324,11 @@ static BOOL init(void) SET(p_feholdexcept, "feholdexcept"); SET(p_feupdateenv, "feupdateenv");
+ SET(p__fsopen, "_fsopen"); + SET(p__wfsopen, "_wfsopen"); + SET(p_fclose, "fclose"); + SET(p__unlink, "_unlink"); + SET(p__clearfp, "_clearfp"); SET(p_vsscanf, "vsscanf"); SET(p__Cbuild, "_Cbuild"); @@ -1825,6 +1835,46 @@ static void test_gmtime64(void) tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); }
+static void test__fsopen(void) +{ + int i; + FILE *f; + wchar_t wpath[MAX_PATH]; + static const struct { + const char *loc; + const char *path; + } tests[] = { + { "German", "t\xe4\xcf\xf6\xdf.txt" }, + { "Turkish", "t\xd0\xf0\xdd\xde\xfd\xfe.txt" }, + { "Arabic", "t\xca\x8c.txt" }, + { "Japanese", "t\xb8\xd5.txt" }, + { "Chinese", "t\x81\x40\xfd\x71.txt" }, + }; + + for(i=0; i<ARRAY_SIZE(tests); i++) { + if(!p_setlocale(LC_ALL, tests[i].loc)) { + win_skip("skipping locale %s\n", tests[i].loc); + continue; + } + + if(!MultiByteToWideChar(CP_ACP, 0, tests[i].path, -1, wpath, MAX_PATH)) { + win_skip("failed to convert %s with locale %s\n", tests[i].path, tests[i].loc); + continue; + } + + f = p__fsopen(tests[i].path, "w", SH_DENYNO); + ok(!!f, "failed to create %s with locale %s\n", tests[i].path, tests[i].loc); + p_fclose(f); + + f = p__wfsopen(wpath, L"r", SH_DENYNO); + ok(!!f, "failed to open %s with locale %s\n", tests[i].path, tests[i].loc); + p_fclose(f); + + p__unlink(tests[i].path); + } + p_setlocale(LC_ALL, "C"); +} + START_TEST(msvcr120) { if (!init()) return; @@ -1850,4 +1900,5 @@ START_TEST(msvcr120) test_StructuredTaskCollection(); test_strcmp(); test_gmtime64(); + test__fsopen(); }
From: Daniel Lehman dlehman25@gmail.com
--- dlls/ucrtbase/tests/file.c | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index 9bfb7af3384..ef3b5bfca33 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -18,6 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <stdarg.h> +#include <locale.h> +#include <share.h> + +#include <windef.h> +#include <winbase.h> +#include <winnls.h> #include "wine/test.h"
static void test_std_stream_buffering(void) @@ -162,9 +169,54 @@ static void test_std_stream_open(void) close(fd); }
+static void test_fopen(void) +{ + int i; + FILE *f; + wchar_t wpath[MAX_PATH]; + static const struct { + const char *loc; + const char *path; + int is_todo; + } tests[] = { + { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt", TRUE }, + { "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt", TRUE }, + { "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt", TRUE }, + { "Arabic.utf8", "t\xd8\xaa\xda\x86.txt", TRUE }, + { "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt", TRUE }, + { "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt", TRUE }, + }; + + for(i=0; i<ARRAY_SIZE(tests); i++) { + if(!setlocale(LC_ALL, tests[i].loc)) { + win_skip("skipping locale %s\n", tests[i].loc); + continue; + } + + memset(wpath, 0, sizeof(wpath)); + if(!MultiByteToWideChar(CP_UTF8, 0, tests[i].path, -1, wpath, MAX_PATH)) { + win_skip("failed to convert %s with locale %s\n", tests[i].path, tests[i].loc); + continue; + } + + f = _fsopen(tests[i].path, "w", SH_DENYNO); + ok(!!f, "failed to create %s with locale %s\n", tests[i].path, tests[i].loc); + fclose(f); + + f = _wfsopen(wpath, L"r", SH_DENYNO); + todo_wine_if(tests[i].is_todo) + ok(!!f, "failed to open %s with locale %s\n", tests[i].path, tests[i].loc); + if(f) fclose(f); + + unlink(tests[i].path); + } + setlocale(LC_ALL, "C"); +} + START_TEST(file) { test_std_stream_buffering(); test_iobuf_layout(); test_std_stream_open(); + test_fopen(); }
From: Daniel Lehman dlehman25@gmail.com
--- dlls/msvcp120/tests/msvcp120.c | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c index c7de814a384..062822ca39f 100644 --- a/dlls/msvcp120/tests/msvcp120.c +++ b/dlls/msvcp120/tests/msvcp120.c @@ -17,12 +17,14 @@ */
#include <locale.h> +#include <share.h> #include <stdio.h> #include <math.h> #include <limits.h>
#include "wine/test.h" #include "winbase.h" +#include "winnls.h"
DWORD expect_idx; static int vector_alloc_count; @@ -210,6 +212,8 @@ static BOOL compare_float(float f, float g, unsigned int ulps) static char* (__cdecl *p_setlocale)(int, const char*); static int (__cdecl *p__setmbcp)(int); static int (__cdecl *p__ismbblead)(unsigned int); +static int (__cdecl *p_fclose)(FILE*); +static int (__cdecl *p__unlink)(const char*);
static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*); static int (__cdecl *p_xtime_get)(xtime*, int); @@ -423,6 +427,21 @@ static void (__thiscall *p_vector_base_v4__Internal_resize)(
static const BYTE *p_byte_reverse_table;
+typedef enum { + OPENMODE_in = 0x01, + OPENMODE_out = 0x02, + OPENMODE_ate = 0x04, + OPENMODE_app = 0x08, + OPENMODE_trunc = 0x10, + OPENMODE__Nocreate = 0x40, + OPENMODE__Noreplace = 0x80, + OPENMODE_binary = 0x20, + OPENMODE_mask = 0xff +} IOSB_openmode; + +static FILE* (__cdecl *p__Fiopen_wchar)(const wchar_t*, int, int); +static FILE* (__cdecl *p__Fiopen)(const char*, int, int); + static HMODULE msvcp; #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y) #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0) @@ -584,6 +603,10 @@ static BOOL init(void) "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00P6AXPEAX0@ZP6AX1PEBX0@Z3@Z"); SET(p__Syserror_map, "?_Syserror_map@std@@YAPEBDH@Z"); + SET(p__Fiopen_wchar, + "?_Fiopen@std@@YAPEAU_iobuf@@PEB_WHH@Z"); + SET(p__Fiopen, + "?_Fiopen@std@@YAPEAU_iobuf@@PEBDHH@Z"); } else { SET(p_tr2_sys__File_size, "?_File_size@sys@tr2@std@@YA_KPBD@Z"); @@ -659,6 +682,10 @@ static BOOL init(void) "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KAII@Z"); SET(p__Syserror_map, "?_Syserror_map@std@@YAPBDH@Z"); + SET(p__Fiopen_wchar, + "?_Fiopen@std@@YAPAU_iobuf@@PB_WHH@Z"); + SET(p__Fiopen, + "?_Fiopen@std@@YAPAU_iobuf@@PBDHH@Z"); #ifdef __i386__ SET(p_i386_Thrd_current, "_Thrd_current"); @@ -821,6 +848,8 @@ static BOOL init(void) p_setlocale = (void*)GetProcAddress(hdll, "setlocale"); p__setmbcp = (void*)GetProcAddress(hdll, "_setmbcp"); p__ismbblead = (void*)GetProcAddress(hdll, "_ismbblead"); + p_fclose = (void*)GetProcAddress(hdll, "fclose"); + p__unlink = (void*)GetProcAddress(hdll, "_unlink");
hdll = GetModuleHandleA("kernel32.dll"); pCreateSymbolicLinkA = (void*)GetProcAddress(hdll, "CreateSymbolicLinkA"); @@ -3343,6 +3372,47 @@ static void test_data_exports(void) } }
+static void test__Fiopen(void) +{ + int i; + FILE *f; + wchar_t wpath[MAX_PATH]; + static const struct { + const char *loc; + const char *path; + } tests[] = { + { "German", "t\xe4\xcf\xf6\xdf.txt" }, + { "Turkish", "t\xd0\xf0\xdd\xde\xfd\xfe.txt" }, + { "Arabic", "t\xca\x8c.txt" }, + { "Japanese", "t\xb8\xd5.txt" }, + { "Chinese", "t\x81\x40\xfd\x71.txt" }, + }; + + for(i=0; i<ARRAY_SIZE(tests); i++) { + if(!p_setlocale(LC_ALL, tests[i].loc)) { + win_skip("skipping locale %s\n", tests[i].loc); + continue; + } + + memset(wpath, 0, sizeof(wpath)); + if(!MultiByteToWideChar(CP_ACP, 0, tests[i].path, -1, wpath, MAX_PATH)) { + win_skip("failed to convert %s with locale %s\n", tests[i].path, tests[i].loc); + continue; + } + + f = p__Fiopen(tests[i].path, OPENMODE_out, SH_DENYNO); + ok(!!f, "failed to create %s with locale %s\n", tests[i].path, tests[i].loc); + p_fclose(f); + + f = p__Fiopen_wchar(wpath, OPENMODE_in, SH_DENYNO); + ok(!!f, "failed to open %s with locale %s\n", wine_dbgstr_w(wpath), tests[i].loc); + p_fclose(f); + + p__unlink(tests[i].path); + } + p_setlocale(LC_ALL, "C"); +} + START_TEST(msvcp120) { if(!init()) return; @@ -3390,6 +3460,8 @@ START_TEST(msvcp120)
test_data_exports();
+ test__Fiopen(); + free_expect_struct(); TlsFree(expect_idx); FreeLibrary(msvcp);
From: Daniel Lehman dlehman25@gmail.com
--- dlls/msvcp140/tests/msvcp140.c | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c index faf4c214801..284061e6aa9 100644 --- a/dlls/msvcp140/tests/msvcp140.c +++ b/dlls/msvcp140/tests/msvcp140.c @@ -18,6 +18,8 @@
#include <errno.h> #include <stdio.h> +#include <locale.h> +#include <share.h>
#include "windef.h" #include "winbase.h" @@ -253,6 +255,24 @@ static ULONG (__cdecl *p__Winerror_message)(ULONG, char*, ULONG); static int (__cdecl *p__Winerror_map)(int); static const char* (__cdecl *p__Syserror_map)(int err);
+typedef enum { + OPENMODE_in = 0x01, + OPENMODE_out = 0x02, + OPENMODE_ate = 0x04, + OPENMODE_app = 0x08, + OPENMODE_trunc = 0x10, + OPENMODE__Nocreate = 0x40, + OPENMODE__Noreplace = 0x80, + OPENMODE_binary = 0x20, + OPENMODE_mask = 0xff +} IOSB_openmode; +static FILE* (__cdecl *p__Fiopen_wchar)(const wchar_t*, int, int); +static FILE* (__cdecl *p__Fiopen)(const char*, int, int); + +static char* (__cdecl *p_setlocale)(int, const char*); +static int (__cdecl *p_fclose)(FILE*); +static int (__cdecl *p__unlink)(const char*); + static BOOLEAN (WINAPI *pCreateSymbolicLinkW)(const WCHAR *, const WCHAR *, DWORD);
static HMODULE msvcp; @@ -291,6 +311,9 @@ static BOOL init(void) SET(p__Release_chore, "?_Release_chore@details@Concurrency@@YAXPEAU_Threadpool_chore@12@@Z"); SET(p__Winerror_message, "?_Winerror_message@std@@YAKKPEADK@Z"); SET(p__Syserror_map, "?_Syserror_map@std@@YAPEBDH@Z"); + + SET(p__Fiopen_wchar, "?_Fiopen@std@@YAPEAU_iobuf@@PEB_WHH@Z"); + SET(p__Fiopen, "?_Fiopen@std@@YAPEAU_iobuf@@PEBDHH@Z"); } else { #ifdef __arm__ SET(p_task_continuation_context_ctor, "??0task_continuation_context@Concurrency@@AAA@XZ"); @@ -322,6 +345,9 @@ static BOOL init(void) SET(p__Release_chore, "?_Release_chore@details@Concurrency@@YAXPAU_Threadpool_chore@12@@Z"); SET(p__Winerror_message, "?_Winerror_message@std@@YAKKPADK@Z"); SET(p__Syserror_map, "?_Syserror_map@std@@YAPBDH@Z"); + + SET(p__Fiopen_wchar, "?_Fiopen@std@@YAPAU_iobuf@@PB_WHH@Z"); + SET(p__Fiopen, "?_Fiopen@std@@YAPAU_iobuf@@PBDHH@Z"); }
SET(p__Mtx_init, "_Mtx_init"); @@ -365,6 +391,11 @@ static BOOL init(void) hdll = GetModuleHandleA("kernel32.dll"); pCreateSymbolicLinkW = (void*)GetProcAddress(hdll, "CreateSymbolicLinkW");
+ hdll = GetModuleHandleA("ucrtbase.dll"); + p_setlocale = (void*)GetProcAddress(hdll, "setlocale"); + p_fclose = (void*)GetProcAddress(hdll, "fclose"); + p__unlink = (void*)GetProcAddress(hdll, "_unlink"); + init_thiscall_thunk(); return TRUE; } @@ -1670,6 +1701,50 @@ static void test__Mtx(void) p__Mtx_destroy(mtx); }
+static void test__Fiopen(void) +{ + int i; + FILE *f; + wchar_t wpath[MAX_PATH]; + static const struct { + const char *loc; + const char *path; + int is_todo; + } tests[] = { + { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt", TRUE }, + { "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt", TRUE }, + { "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt", TRUE }, + { "Arabic.utf8", "t\xd8\xaa\xda\x86.txt", TRUE }, + { "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt", TRUE }, + { "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt", TRUE }, + }; + + for(i=0; i<ARRAY_SIZE(tests); i++) { + if(!p_setlocale(LC_ALL, tests[i].loc)) { + win_skip("skipping locale %s\n", tests[i].loc); + continue; + } + + memset(wpath, 0, sizeof(wpath)); + if(!MultiByteToWideChar(CP_UTF8, 0, tests[i].path, -1, wpath, MAX_PATH)) { + win_skip("failed to convert %s with locale %s\n", tests[i].path, tests[i].loc); + continue; + } + + f = p__Fiopen(tests[i].path, OPENMODE_out, SH_DENYNO); + ok(!!f, "failed to create %s with locale %s\n", tests[i].path, tests[i].loc); + p_fclose(f); + + f = p__Fiopen_wchar(wpath, OPENMODE_in, SH_DENYNO); + todo_wine_if(tests[i].is_todo) + ok(!!f, "failed to open %s with locale %s\n", wine_dbgstr_w(wpath), tests[i].loc); + if(f) p_fclose(f); + + p__unlink(tests[i].path); + } + p_setlocale(LC_ALL, "C"); +} + START_TEST(msvcp140) { if(!init()) return; @@ -1698,5 +1773,6 @@ START_TEST(msvcp140) test_cnd(); test_Copy_file(); test__Mtx(); + test__Fiopen(); FreeLibrary(msvcp); }
From: Daniel Lehman dlehman25@gmail.com
--- dlls/msvcp140/tests/msvcp140.c | 10 +++++----- dlls/msvcrt/data.c | 20 ++++++++++++++------ dlls/ucrtbase/tests/file.c | 16 +++++++--------- 3 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c index 284061e6aa9..250ead1bc76 100644 --- a/dlls/msvcp140/tests/msvcp140.c +++ b/dlls/msvcp140/tests/msvcp140.c @@ -1712,11 +1712,11 @@ static void test__Fiopen(void) int is_todo; } tests[] = { { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt", TRUE }, - { "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt", TRUE }, - { "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt", TRUE }, - { "Arabic.utf8", "t\xd8\xaa\xda\x86.txt", TRUE }, - { "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt", TRUE }, - { "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt", TRUE }, + { "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt" }, + { "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt" }, + { "Arabic.utf8", "t\xd8\xaa\xda\x86.txt" }, + { "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt" }, + { "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt" }, };
for(i=0; i<ARRAY_SIZE(tests); i++) { diff --git a/dlls/msvcrt/data.c b/dlls/msvcrt/data.c index 6e764e52eae..5dd113b1c5a 100644 --- a/dlls/msvcrt/data.c +++ b/dlls/msvcrt/data.c @@ -60,6 +60,8 @@ int MSVCRT_app_type = 0; char* MSVCRT__pgmptr = NULL; WCHAR* MSVCRT__wpgmptr = NULL;
+unsigned int CDECL ___lc_codepage_func(void); + static char **build_argv( WCHAR **wargv ) { int argc; @@ -299,12 +301,18 @@ int CDECL _get_osplatform(int *pValue) /* INTERNAL: Create a wide string from an ascii string */ wchar_t *msvcrt_wstrdupa(const char *str) { - const unsigned int len = strlen(str) + 1 ; - wchar_t *wstr = malloc(len* sizeof (wchar_t)); - if (!wstr) - return NULL; - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,str,len,wstr,len); - return wstr; + const unsigned int len = strlen(str) + 1 ; + wchar_t *wstr = malloc(len*sizeof (wchar_t)); + if(!wstr) + return NULL; + +#if _MSVCR_VER >= 140 + MultiByteToWideChar(___lc_codepage_func() == CP_UTF8 ? CP_UTF8 : CP_ACP, + MB_PRECOMPOSED,str,len,wstr,len); +#else + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,str,len,wstr,len); +#endif + return wstr; }
/********************************************************************* diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index ef3b5bfca33..6bf7189a707 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -177,14 +177,13 @@ static void test_fopen(void) static const struct { const char *loc; const char *path; - int is_todo; } tests[] = { - { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt", TRUE }, - { "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt", TRUE }, - { "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt", TRUE }, - { "Arabic.utf8", "t\xd8\xaa\xda\x86.txt", TRUE }, - { "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt", TRUE }, - { "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt", TRUE }, + { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt" }, + { "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt" }, + { "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt" }, + { "Arabic.utf8", "t\xd8\xaa\xda\x86.txt" }, + { "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt" }, + { "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt" }, };
for(i=0; i<ARRAY_SIZE(tests); i++) { @@ -204,9 +203,8 @@ static void test_fopen(void) fclose(f);
f = _wfsopen(wpath, L"r", SH_DENYNO); - todo_wine_if(tests[i].is_todo) ok(!!f, "failed to open %s with locale %s\n", tests[i].path, tests[i].loc); - if(f) fclose(f); + fclose(f);
unlink(tests[i].path); }
From: Daniel Lehman dlehman25@gmail.com
--- dlls/msvcp140/tests/msvcp140.c | 6 ++-- dlls/msvcp90/ios.c | 56 ++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c index 250ead1bc76..72a74076621 100644 --- a/dlls/msvcp140/tests/msvcp140.c +++ b/dlls/msvcp140/tests/msvcp140.c @@ -1709,9 +1709,8 @@ static void test__Fiopen(void) static const struct { const char *loc; const char *path; - int is_todo; } tests[] = { - { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt", TRUE }, + { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt" }, { "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt" }, { "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt" }, { "Arabic.utf8", "t\xd8\xaa\xda\x86.txt" }, @@ -1736,9 +1735,8 @@ static void test__Fiopen(void) p_fclose(f);
f = p__Fiopen_wchar(wpath, OPENMODE_in, SH_DENYNO); - todo_wine_if(tests[i].is_todo) ok(!!f, "failed to open %s with locale %s\n", wine_dbgstr_w(wpath), tests[i].loc); - if(f) p_fclose(f); + p_fclose(f);
p__unlink(tests[i].path); } diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c index 5b791cd4345..d854892172f 100644 --- a/dlls/msvcp90/ios.c +++ b/dlls/msvcp90/ios.c @@ -3266,6 +3266,61 @@ FILE* __cdecl _Fiopen_wchar(const wchar_t *name, int mode, int prot)
/* ?_Fiopen@std@@YAPAU_iobuf@@PBDHH@Z */ /* ?_Fiopen@std@@YAPEAU_iobuf@@PEBDHH@Z */ +#if _MSVCP_VER >= 140 +FILE* __cdecl _Fiopen(const char *name, int mode, int prot) +{ + static const struct { + int mode; + const char str[4]; + const char str_bin[4]; + } str_mode[] = { + {OPENMODE_out, "w", "wb"}, + {OPENMODE_out|OPENMODE_app, "a", "ab"}, + {OPENMODE_app, "a", "ab"}, + {OPENMODE_out|OPENMODE_trunc, "w", "wb"}, + {OPENMODE_in, "r", "rb"}, + {OPENMODE_in|OPENMODE_out, "r+", "r+b"}, + {OPENMODE_in|OPENMODE_out|OPENMODE_trunc, "w+", "w+b"}, + {OPENMODE_in|OPENMODE_out|OPENMODE_app, "a+", "a+b"}, + {OPENMODE_in|OPENMODE_app, "a+", "a+b"} + }; + + int real_mode = mode & ~(OPENMODE_ate|OPENMODE__Nocreate|OPENMODE__Noreplace|OPENMODE_binary); + size_t mode_idx; + FILE *f = NULL; + + TRACE("(%s %d %d)\n", debugstr_a(name), mode, prot); + + for(mode_idx=0; mode_idx<ARRAY_SIZE(str_mode); mode_idx++) + if(str_mode[mode_idx].mode == real_mode) + break; + if(mode_idx == ARRAY_SIZE(str_mode)) + return NULL; + + if((mode & OPENMODE__Nocreate) && !(f = fopen(name, "r"))) + return NULL; + else if(f) + fclose(f); + + if((mode & OPENMODE__Noreplace) && (mode & (OPENMODE_out|OPENMODE_app)) + && (f = fopen(name, "r"))) { + fclose(f); + return NULL; + } + + f = _fsopen(name, (mode & OPENMODE_binary) ? str_mode[mode_idx].str_bin + : str_mode[mode_idx].str, prot); + if(!f) + return NULL; + + if((mode & OPENMODE_ate) && fseek(f, 0, SEEK_END)) { + fclose(f); + return NULL; + } + + return f; +} +#else FILE* __cdecl _Fiopen(const char *name, int mode, int prot) { wchar_t nameW[FILENAME_MAX]; @@ -3281,6 +3336,7 @@ FILE* __cdecl _Fiopen(const char *name, int mode, int prot) #endif return _Fiopen_wchar(nameW, mode, prot); } +#endif
/* ?__Fiopen@std@@YAPAU_iobuf@@PBDH@Z */ /* ?__Fiopen@std@@YAPEAU_iobuf@@PEBDH@Z */
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149797
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: win.c:4070: Test failed: Expected active window 0000000003F50150, got 0000000000000000. win.c:4071: Test failed: Expected focus window 0000000003F50150, got 0000000000000000.
Piotr Caban (@piotr) commented about dlls/msvcr120/tests/msvcr120.c:
{ "German", "t\xe4\xcf\xf6\xdf.txt" },
{ "Turkish", "t\xd0\xf0\xdd\xde\xfd\xfe.txt" },
{ "Arabic", "t\xca\x8c.txt" },
{ "Japanese", "t\xb8\xd5.txt" },
{ "Chinese", "t\x81\x40\xfd\x71.txt" },
- };
- for(i=0; i<ARRAY_SIZE(tests); i++) {
if(!p_setlocale(LC_ALL, tests[i].loc)) {
win_skip("skipping locale %s\n", tests[i].loc);
continue;
}
if(!MultiByteToWideChar(CP_ACP, 0, tests[i].path, -1, wpath, MAX_PATH)) {
win_skip("failed to convert %s with locale %s\n", tests[i].path, tests[i].loc);
continue;
MultiByteToWideChar should never fail here. ```suggestion:-2+1 ok(MultiByteToWideChar(CP_ACP, 0, tests[i].path, -1, wpath, MAX_PATH), "MultiByteToWideChar failed: %lx\n", GetLastError()); ```
Piotr Caban (@piotr) commented about dlls/ucrtbase/tests/file.c:
+static void test_fopen(void) +{
- int i;
- FILE *f;
- wchar_t wpath[MAX_PATH];
- static const struct {
const char *loc;
const char *path;
int is_todo;
- } tests[] = {
{ "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt", TRUE },
{ "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt", TRUE },
{ "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt", TRUE },
{ "Arabic.utf8", "t\xd8\xaa\xda\x86.txt", TRUE },
{ "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt", TRUE },
{ "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt", TRUE },
It would be good to also add a test for non utf-8 locale. It will confirm that CP_ACP should be used in other cases.
Piotr Caban (@piotr) commented about dlls/msvcrt/data.c:
- return NULL;
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,str,len,wstr,len);
- return wstr;
- const unsigned int len = strlen(str) + 1 ;
- wchar_t *wstr = malloc(len*sizeof (wchar_t));
- if(!wstr)
return NULL;
+#if _MSVCR_VER >= 140
- MultiByteToWideChar(___lc_codepage_func() == CP_UTF8 ? CP_UTF8 : CP_ACP,
MB_PRECOMPOSED,str,len,wstr,len);
+#else
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,str,len,wstr,len);
+#endif
- return wstr;
}
`msvcrt_wstrdupa` is used in more functions. You will either need to add tests for other functions (like e.g. `_putenv`) or introduce new helper for file functions.
Piotr Caban (@piotr) commented about dlls/msvcp90/ios.c:
/* ?_Fiopen@std@@YAPAU_iobuf@@PBDHH@Z */ /* ?_Fiopen@std@@YAPEAU_iobuf@@PEBDHH@Z */ +#if _MSVCP_VER >= 140
Is there any reason to make this change version specific? I would expect that `_Fiopen` should use `_fsopen` in all versions of msvcp.
Piotr Caban (@piotr) commented about dlls/ucrtbase/tests/file.c:
fclose(f); f = _wfsopen(wpath, L"r", SH_DENYNO);
todo_wine_if(tests[i].is_todo) ok(!!f, "failed to open %s with locale %s\n", tests[i].path, tests[i].loc);
if(f) fclose(f);
fclose(f); unlink(tests[i].path);
`unlink` also needs to be changed to support UTF-8 encoding - otherwise you will fail to delete some files. Please also check `unlink` result.
Piotr Caban (@piotr) commented about dlls/msvcp140/tests/msvcp140.c:
int is_todo; } tests[] = { { "German.utf8", "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt", TRUE },
{ "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt", TRUE },
{ "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt", TRUE },
{ "Arabic.utf8", "t\xd8\xaa\xda\x86.txt", TRUE },
{ "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt", TRUE },
{ "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt", TRUE },
{ "Polish.utf8", "t\xc4\x99\xc5\x9b\xc4\x87.txt" },
{ "Turkish.utf8", "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt" },
{ "Arabic.utf8", "t\xd8\xaa\xda\x86.txt" },
{ "Japanese.utf8", "t\xe3\x82\xaf\xe3\x83\xa4.txt" },
{ "Chinese.utf8", "t\xe4\xb8\x82\xe9\xbd\xab.txt" },
The patch is not fixing the tests - you probably have some files left from earlier tries on your filesystem.
On Wed Nov 20 07:06:40 2024 +0000, Daniel Lehman wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/6680/diffs?diff_id=144221&start_sha=86ca683bded74abf0bcaab69d11a3e14ccae7ec0#bd88c62f9f4e92b31b94de87a025d8d918f00733_3408_3392)
sorry, not sure i follow. i was trying to do something like these tests: https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/gdi32/tests/font.c#L2... https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/shell32/tests/shellol... https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/kernel32/tests/enviro... https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/kernel32/tests/path.c...
how should i change the test?
On Sat Nov 23 22:07:15 2024 +0000, Daniel Lehman wrote:
sorry, not sure i follow. i was trying to do something like these tests: https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/gdi32/tests/font.c#L2... https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/shell32/tests/shellol... https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/kernel32/tests/enviro... https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/kernel32/tests/path.c... how should i change the test?
You have already changed that part.
On Mon Nov 25 10:10:45 2024 +0000, Piotr Caban wrote:
You have already changed that part.
yeah, i removed the CP_ACP tests, which kinda followed the pattern in the above links, in response to the previous comment (https://gitlab.winehq.org/wine/wine/-/merge_requests/6680#note_86493)
but i think the comment below (https://gitlab.winehq.org/wine/wine/-/merge_requests/6680#note_88140) you want them back?
i'd assume the tests should be in a different form, but not sure exactly what you're looking for
On Tue Nov 26 04:48:52 2024 +0000, Daniel Lehman wrote:
yeah, i removed the CP_ACP tests, which kinda followed the pattern in the above links, in response to the previous comment (https://gitlab.winehq.org/wine/wine/-/merge_requests/6680#note_86493) but i think the comment below (https://gitlab.winehq.org/wine/wine/-/merge_requests/6680#note_88140) you want them back? i'd assume the tests should be in a different form, but not sure exactly what you're looking for
The comment was about ucrtbase tests. You're only testing utf-8 case there.