mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 04:48:36 +00:00
msvcrt: Fix strncmp return value.
Some programs, such as Final Fantasy IV (3D remake), expect strncmp to return exactly +/-1 when the strings are not equal. Signed-off-by: Shaun Ren <sren@codeweavers.com>
This commit is contained in:
parent
1b3f61d7a5
commit
6d2a9af43b
2
configure
vendored
2
configure
vendored
|
@ -21745,7 +21745,9 @@ wine_fn_config_makefile dlls/msvcr120 enable_msvcr120
|
|||
wine_fn_config_makefile dlls/msvcr120/tests enable_tests
|
||||
wine_fn_config_makefile dlls/msvcr120_app enable_msvcr120_app
|
||||
wine_fn_config_makefile dlls/msvcr70 enable_msvcr70
|
||||
wine_fn_config_makefile dlls/msvcr70/tests enable_tests
|
||||
wine_fn_config_makefile dlls/msvcr71 enable_msvcr71
|
||||
wine_fn_config_makefile dlls/msvcr71/tests enable_tests
|
||||
wine_fn_config_makefile dlls/msvcr80 enable_msvcr80
|
||||
wine_fn_config_makefile dlls/msvcr80/tests enable_tests
|
||||
wine_fn_config_makefile dlls/msvcr90 enable_msvcr90
|
||||
|
|
|
@ -2851,7 +2851,9 @@ WINE_CONFIG_MAKEFILE(dlls/msvcr120)
|
|||
WINE_CONFIG_MAKEFILE(dlls/msvcr120/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/msvcr120_app)
|
||||
WINE_CONFIG_MAKEFILE(dlls/msvcr70)
|
||||
WINE_CONFIG_MAKEFILE(dlls/msvcr70/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/msvcr71)
|
||||
WINE_CONFIG_MAKEFILE(dlls/msvcr71/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/msvcr80)
|
||||
WINE_CONFIG_MAKEFILE(dlls/msvcr80/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/msvcr90)
|
||||
|
|
|
@ -237,6 +237,9 @@ static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t,_locale_t);
|
|||
static char* (__cdecl *p_setlocale)(int, const char*);
|
||||
static size_t (__cdecl *p___strncnt)(const char*, size_t);
|
||||
|
||||
static int (__cdecl *p_strcmp)(const char *, const char *);
|
||||
static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
|
||||
|
||||
/* make sure we use the correct errno */
|
||||
#undef errno
|
||||
#define errno (*p_errno())
|
||||
|
@ -277,6 +280,9 @@ static BOOL init(void)
|
|||
SET(p_CurrentScheduler_Detach, "?Detach@CurrentScheduler@Concurrency@@SAXXZ");
|
||||
SET(p_CurrentScheduler_Id, "?Id@CurrentScheduler@Concurrency@@SAIXZ");
|
||||
|
||||
SET(p_strcmp, "strcmp");
|
||||
SET(p_strncmp, "strncmp");
|
||||
|
||||
if(sizeof(void*) == 8) { /* 64-bit initialization */
|
||||
SET(pSpinWait_ctor_yield, "??0?$_SpinWait@$00@details@Concurrency@@QEAA@P6AXXZ@Z");
|
||||
SET(pSpinWait_dtor, "??_F?$_SpinWait@$00@details@Concurrency@@QEAAXXZ");
|
||||
|
@ -1106,6 +1112,46 @@ static void test___strncnt(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_strcmp(void)
|
||||
{
|
||||
int ret = p_strcmp( "abc", "abcd" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "", "abc" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "abc", "ab\xa0" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xb0", "ab\xa0" );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xc2", "ab\xc2" );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
|
||||
ret = p_strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
#ifdef _WIN64
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
#else
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == 0 - 'a', "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == 'c' - 0xa0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 0xb0 - 0xa0, "wrong ret %d\n", ret );
|
||||
#endif
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abd", 0 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abc", 12 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
}
|
||||
|
||||
START_TEST(msvcr100)
|
||||
{
|
||||
if (!init())
|
||||
|
@ -1126,4 +1172,5 @@ START_TEST(msvcr100)
|
|||
test__memicmp_l();
|
||||
test_setlocale();
|
||||
test___strncnt();
|
||||
test_strcmp();
|
||||
}
|
||||
|
|
|
@ -52,6 +52,9 @@ static unsigned int (CDECL *p__CurrentScheduler__Id)(void);
|
|||
static Context* (__cdecl *p_Context_CurrentContext)(void);
|
||||
static _Context* (__cdecl *p__Context__CurrentContext)(_Context*);
|
||||
|
||||
static int (__cdecl *p_strcmp)(const char *, const char *);
|
||||
static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
|
||||
|
||||
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(module,y)
|
||||
#define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
|
||||
|
||||
|
@ -84,6 +87,9 @@ static BOOL init(void)
|
|||
SET(p_Context_CurrentContext, "?CurrentContext@Context@Concurrency@@SAPAV12@XZ");
|
||||
}
|
||||
|
||||
SET(p_strcmp, "strcmp");
|
||||
SET(p_strncmp, "strncmp");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -192,6 +198,37 @@ static void test_CurrentContext(void)
|
|||
ok(ret == &_ctx, "expected %p, got %p\n", &_ctx, ret);
|
||||
}
|
||||
|
||||
static void test_strcmp(void)
|
||||
{
|
||||
int ret = p_strcmp( "abc", "abcd" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "", "abc" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "abc", "ab\xa0" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xb0", "ab\xa0" );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xc2", "ab\xc2" );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
|
||||
ret = p_strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abd", 0 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abc", 12 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
}
|
||||
|
||||
START_TEST(msvcr110)
|
||||
{
|
||||
if (!init()) return;
|
||||
|
@ -199,4 +236,5 @@ START_TEST(msvcr110)
|
|||
test_setlocale();
|
||||
test___strncnt();
|
||||
test_CurrentContext();
|
||||
test_strcmp();
|
||||
}
|
||||
|
|
|
@ -220,6 +220,8 @@ static float (__cdecl *p_nexttowardf)(float, double);
|
|||
static double (__cdecl *p_nexttowardl)(double, double);
|
||||
static wctrans_t (__cdecl *p_wctrans)(const char*);
|
||||
static wint_t (__cdecl *p_towctrans)(wint_t, wctrans_t);
|
||||
static int (__cdecl *p_strcmp)(const char *, const char *);
|
||||
static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
|
||||
|
||||
/* make sure we use the correct errno */
|
||||
#undef errno
|
||||
|
@ -306,6 +308,8 @@ static BOOL init(void)
|
|||
SET(p_wctrans, "wctrans");
|
||||
SET(p_towctrans, "towctrans");
|
||||
SET(p__Context__CurrentContext, "?_CurrentContext@_Context@details@Concurrency@@SA?AV123@XZ");
|
||||
SET(p_strcmp, "strcmp");
|
||||
SET(p_strncmp, "strncmp");
|
||||
if(sizeof(void*) == 8) { /* 64-bit initialization */
|
||||
SET(p__StructuredTaskCollection_ctor,
|
||||
"??0_StructuredTaskCollection@details@Concurrency@@QEAA@PEAV_CancellationTokenState@12@@Z");
|
||||
|
@ -1591,6 +1595,37 @@ static void test_StructuredTaskCollection(void)
|
|||
CloseHandle(chore_evt2);
|
||||
}
|
||||
|
||||
static void test_strcmp(void)
|
||||
{
|
||||
int ret = p_strcmp( "abc", "abcd" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "", "abc" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "abc", "ab\xa0" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xb0", "ab\xa0" );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xc2", "ab\xc2" );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
|
||||
ret = p_strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abd", 0 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abc", 12 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
}
|
||||
|
||||
START_TEST(msvcr120)
|
||||
{
|
||||
if (!init()) return;
|
||||
|
@ -1614,4 +1649,5 @@ START_TEST(msvcr120)
|
|||
test_towctrans();
|
||||
test_CurrentContext();
|
||||
test_StructuredTaskCollection();
|
||||
test_strcmp();
|
||||
}
|
||||
|
|
4
dlls/msvcr70/tests/Makefile.in
Normal file
4
dlls/msvcr70/tests/Makefile.in
Normal file
|
@ -0,0 +1,4 @@
|
|||
TESTDLL = msvcr70.dll
|
||||
|
||||
C_SRCS = \
|
||||
msvcr70.c
|
87
dlls/msvcr70/tests/msvcr70.c
Normal file
87
dlls/msvcr70/tests/msvcr70.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2022 Shaun Ren for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <errno.h>
|
||||
#include "wine/test.h"
|
||||
|
||||
static int (__cdecl *p_strcmp)(const char *, const char *);
|
||||
static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
|
||||
|
||||
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hcrt,y)
|
||||
#define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
|
||||
static BOOL init(void)
|
||||
{
|
||||
HMODULE hcrt;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hcrt = LoadLibraryA("msvcr70.dll");
|
||||
if (!hcrt) {
|
||||
win_skip("msvcr70.dll not installed (got %ld)\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SET(p_strcmp, "strcmp");
|
||||
SET(p_strncmp, "strncmp");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_strcmp(void)
|
||||
{
|
||||
int ret = p_strcmp( "abc", "abcd" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "", "abc" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "abc", "ab\xa0" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xb0", "ab\xa0" );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xc2", "ab\xc2" );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
|
||||
ret = p_strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abd", 0 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abc", 12 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
}
|
||||
|
||||
START_TEST(msvcr70)
|
||||
{
|
||||
if(!init())
|
||||
return;
|
||||
|
||||
test_strcmp();
|
||||
}
|
4
dlls/msvcr71/tests/Makefile.in
Normal file
4
dlls/msvcr71/tests/Makefile.in
Normal file
|
@ -0,0 +1,4 @@
|
|||
TESTDLL = msvcr71.dll
|
||||
|
||||
C_SRCS = \
|
||||
msvcr71.c
|
87
dlls/msvcr71/tests/msvcr71.c
Normal file
87
dlls/msvcr71/tests/msvcr71.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2022 Shaun Ren for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <errno.h>
|
||||
#include "wine/test.h"
|
||||
|
||||
static int (__cdecl *p_strcmp)(const char *, const char *);
|
||||
static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
|
||||
|
||||
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hcrt,y)
|
||||
#define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
|
||||
static BOOL init(void)
|
||||
{
|
||||
HMODULE hcrt;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hcrt = LoadLibraryA("msvcr71.dll");
|
||||
if (!hcrt) {
|
||||
win_skip("msvcr71.dll not installed (got %ld)\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SET(p_strcmp, "strcmp");
|
||||
SET(p_strncmp, "strncmp");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_strcmp(void)
|
||||
{
|
||||
int ret = p_strcmp( "abc", "abcd" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "", "abc" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "abc", "ab\xa0" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xb0", "ab\xa0" );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xc2", "ab\xc2" );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
|
||||
ret = p_strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abd", 0 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abc", 12 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
}
|
||||
|
||||
START_TEST(msvcr71)
|
||||
{
|
||||
if(!init())
|
||||
return;
|
||||
|
||||
test_strcmp();
|
||||
}
|
|
@ -60,6 +60,8 @@ static ioinfo **__pioinfo;
|
|||
static int (__cdecl *p__open)(const char *, int, ...);
|
||||
static int (__cdecl *p__close)(int);
|
||||
static intptr_t (__cdecl *p__get_osfhandle)(int);
|
||||
static int (__cdecl *p_strcmp)(const char *, const char *);
|
||||
static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
|
||||
|
||||
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hcrt,y)
|
||||
#define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
|
||||
|
@ -79,6 +81,9 @@ static BOOL init(void)
|
|||
SET(p__close,"_close");
|
||||
SET(p__get_osfhandle, "_get_osfhandle");
|
||||
|
||||
SET(p_strcmp, "strcmp");
|
||||
SET(p_strncmp, "strncmp");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -139,10 +144,51 @@ static void test_ioinfo_flags(void)
|
|||
free(tempf);
|
||||
}
|
||||
|
||||
static void test_strcmp(void)
|
||||
{
|
||||
int ret = p_strcmp( "abc", "abcd" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "", "abc" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "abc", "ab\xa0" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xb0", "ab\xa0" );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xc2", "ab\xc2" );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
|
||||
ret = p_strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
#ifdef _WIN64
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
#else
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == 0 - 'a', "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == 'c' - 0xa0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 0xb0 - 0xa0, "wrong ret %d\n", ret );
|
||||
#endif
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abd", 0 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abc", 12 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
}
|
||||
|
||||
START_TEST(msvcr80)
|
||||
{
|
||||
if(!init())
|
||||
return;
|
||||
|
||||
test_ioinfo_flags();
|
||||
test_strcmp();
|
||||
}
|
||||
|
|
|
@ -171,6 +171,8 @@ static int (__cdecl *p____mb_cur_max_l_func)(_locale_t locale);
|
|||
static _locale_t (__cdecl *p__create_locale)(int, const char*);
|
||||
static void (__cdecl *p__free_locale)(_locale_t);
|
||||
static _locale_t (__cdecl *p__get_current_locale)(void);
|
||||
static int (__cdecl *p_strcmp)(const char *, const char *);
|
||||
static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
|
||||
|
||||
struct __lc_time_data {
|
||||
const char *short_wday[7];
|
||||
|
@ -471,6 +473,8 @@ static BOOL init(void)
|
|||
SET(p__create_locale, "_create_locale");
|
||||
SET(p__free_locale, "_free_locale");
|
||||
SET(p__get_current_locale, "_get_current_locale");
|
||||
SET(p_strcmp, "strcmp");
|
||||
SET(p_strncmp, "strncmp");
|
||||
|
||||
if (sizeof(void *) == 8)
|
||||
{
|
||||
|
@ -2441,6 +2445,46 @@ static void test_ioinfo_flags(void)
|
|||
free(tempf);
|
||||
}
|
||||
|
||||
static void test_strcmp(void)
|
||||
{
|
||||
int ret = p_strcmp( "abc", "abcd" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "", "abc" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "abc", "ab\xa0" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xb0", "ab\xa0" );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = p_strcmp( "ab\xc2", "ab\xc2" );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
|
||||
ret = p_strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
#ifdef _WIN64
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
#else
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == 0 - 'a', "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == 'c' - 0xa0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 0xb0 - 0xa0, "wrong ret %d\n", ret );
|
||||
#endif
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abd", 0 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "abc", 12 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
}
|
||||
|
||||
START_TEST(msvcr90)
|
||||
{
|
||||
if(!init())
|
||||
|
@ -2483,4 +2527,5 @@ START_TEST(msvcr90)
|
|||
test____mb_cur_max_l_func();
|
||||
test__get_current_locale();
|
||||
test_ioinfo_flags();
|
||||
test_strcmp();
|
||||
}
|
||||
|
|
|
@ -3292,7 +3292,14 @@ int __cdecl strncmp(const char *str1, const char *str2, size_t len)
|
|||
{
|
||||
if (!len) return 0;
|
||||
while (--len && *str1 && *str1 == *str2) { str1++; str2++; }
|
||||
|
||||
#if defined(_WIN64) || defined(_UCRT) || _MSVCR_VER == 70 || _MSVCR_VER == 71 || _MSVCR_VER >= 110
|
||||
if ((unsigned char)*str1 > (unsigned char)*str2) return 1;
|
||||
if ((unsigned char)*str1 < (unsigned char)*str2) return -1;
|
||||
return 0;
|
||||
#else
|
||||
return (unsigned char)*str1 - (unsigned char)*str2;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -662,12 +662,21 @@ static void test_strcmp(void)
|
|||
|
||||
ret = p_strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
#ifdef _WIN64
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == 0 - 'a' || ret == -1, "wrong ret %d\n", ret );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == 'c' - 0xa0 || ret == -1, "wrong ret %d\n", ret );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 0xb0 - 0xa0 || ret == 1, "wrong ret %d\n", ret );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
#else
|
||||
ret = p_strncmp( "", "abc", 3 );
|
||||
ok( ret == 0 - 'a', "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == 'c' - 0xa0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 0xb0 - 0xa0, "wrong ret %d\n", ret );
|
||||
#endif
|
||||
ret = p_strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = p_strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
|
|
|
@ -602,6 +602,37 @@ static void test__mbbtype_l(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_strcmp(void)
|
||||
{
|
||||
int ret = strcmp( "abc", "abcd" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = strcmp( "", "abc" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = strcmp( "abc", "ab\xa0" );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = strcmp( "ab\xb0", "ab\xa0" );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = strcmp( "ab\xc2", "ab\xc2" );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
|
||||
ret = strncmp( "abc", "abcd", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = strncmp( "", "abc", 3 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = strncmp( "abc", "ab\xa0", 4 );
|
||||
ok( ret == -1, "wrong ret %d\n", ret );
|
||||
ret = strncmp( "ab\xb0", "ab\xa0", 3 );
|
||||
ok( ret == 1, "wrong ret %d\n", ret );
|
||||
ret = strncmp( "ab\xb0", "ab\xa0", 2 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = strncmp( "ab\xc2", "ab\xc2", 3 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = strncmp( "abc", "abd", 0 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
ret = strncmp( "abc", "abc", 12 );
|
||||
ok( ret == 0, "wrong ret %d\n", ret );
|
||||
}
|
||||
|
||||
START_TEST(string)
|
||||
{
|
||||
ok(_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
|
||||
|
@ -619,4 +650,5 @@ START_TEST(string)
|
|||
test_wcsnicmp();
|
||||
test_SpecialCasing();
|
||||
test__mbbtype_l();
|
||||
test_strcmp();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue