msvcrt: Implement _strlwr_s.
This commit is contained in:
parent
bcfaf467b5
commit
41ab825126
|
@ -1142,7 +1142,7 @@
|
|||
@ stub _stricoll_l
|
||||
@ cdecl _strlwr(str) msvcrt._strlwr
|
||||
@ stub _strlwr_l
|
||||
@ stub _strlwr_s
|
||||
@ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
|
||||
@ stub _strlwr_s_l
|
||||
@ stub _strncoll
|
||||
@ stub _strncoll_l
|
||||
|
|
|
@ -996,7 +996,7 @@
|
|||
@ stub _stricoll_l
|
||||
@ cdecl _strlwr(str) msvcrt._strlwr
|
||||
@ stub _strlwr_l
|
||||
@ stub _strlwr_s
|
||||
@ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
|
||||
@ stub _strlwr_s_l
|
||||
@ stub _strncoll
|
||||
@ stub _strncoll_l
|
||||
|
|
|
@ -982,7 +982,7 @@
|
|||
@ stub _stricoll_l
|
||||
@ cdecl _strlwr(str) msvcrt._strlwr
|
||||
@ stub _strlwr_l
|
||||
@ stub _strlwr_s
|
||||
@ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
|
||||
@ stub _strlwr_s_l
|
||||
@ stub _strncoll
|
||||
@ stub _strncoll_l
|
||||
|
|
|
@ -917,7 +917,7 @@
|
|||
# stub _stricoll_l
|
||||
@ cdecl _strlwr(str) ntdll._strlwr
|
||||
# stub _strlwr_l
|
||||
# stub _strlwr_s
|
||||
@ cdecl _strlwr_s(ptr long)
|
||||
# stub _strlwr_s_l
|
||||
@ stub _strncoll #(str str long)
|
||||
# stub _strncoll_l
|
||||
|
|
|
@ -50,6 +50,41 @@ char* CDECL _strdup(const char* str)
|
|||
else return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _strlwr_s (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _strlwr_s(char *str, MSVCRT_size_t len)
|
||||
{
|
||||
char *ptr = str;
|
||||
|
||||
if (!str || !len)
|
||||
{
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return MSVCRT_EINVAL;
|
||||
}
|
||||
|
||||
while (len && *ptr)
|
||||
{
|
||||
len--;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
{
|
||||
str[0] = '\0';
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return MSVCRT_EINVAL;
|
||||
}
|
||||
|
||||
while (*str)
|
||||
{
|
||||
*str = tolower(*str);
|
||||
str++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _strnset (MSVCRT.@)
|
||||
*/
|
||||
|
|
|
@ -60,6 +60,7 @@ 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 errno_t (__cdecl *p_gcvt_s)(char*,size_t,double,int);
|
||||
static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
|
||||
static errno_t (__cdecl *p_strlwr_s)(char*,size_t);
|
||||
static int *p__mb_cur_max;
|
||||
static unsigned char *p_mbctype;
|
||||
|
||||
|
@ -1370,6 +1371,63 @@ static void test__itoa_s(void)
|
|||
buffer);
|
||||
}
|
||||
|
||||
static void test__strlwr_s(void)
|
||||
{
|
||||
errno_t ret;
|
||||
char buffer[20];
|
||||
|
||||
if (!p_strlwr_s)
|
||||
{
|
||||
win_skip("Skipping _strlwr_s tests\n");
|
||||
return;
|
||||
}
|
||||
|
||||
errno = EBADF;
|
||||
ret = p_strlwr_s(NULL, 0);
|
||||
ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
|
||||
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
|
||||
|
||||
errno = EBADF;
|
||||
ret = p_strlwr_s(NULL, sizeof(buffer));
|
||||
ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
|
||||
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
|
||||
|
||||
errno = EBADF;
|
||||
ret = p_strlwr_s(buffer, 0);
|
||||
ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
|
||||
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
|
||||
|
||||
strcpy(buffer, "GoRrIsTeR");
|
||||
errno = EBADF;
|
||||
ret = p_strlwr_s(buffer, 5);
|
||||
ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
|
||||
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
|
||||
ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")),
|
||||
"Expected the output buffer to be \"gorrIsTeR\"\n");
|
||||
|
||||
strcpy(buffer, "GoRrIsTeR");
|
||||
errno = EBADF;
|
||||
ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR") - 1);
|
||||
ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
|
||||
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
|
||||
ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")),
|
||||
"Expected the output buffer to be \"gorrIsTeR\"\n");
|
||||
|
||||
strcpy(buffer, "GoRrIsTeR");
|
||||
ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR"));
|
||||
ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret);
|
||||
ok(!strcmp(buffer, "gorrister"),
|
||||
"Expected the output buffer to be \"gorrister\", got \"%s\"\n",
|
||||
buffer);
|
||||
|
||||
memcpy(buffer, "GoRrIsTeR\0ELLEN", sizeof("GoRrIsTeR\0ELLEN"));
|
||||
ret = p_strlwr_s(buffer, sizeof(buffer));
|
||||
ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret);
|
||||
ok(!memcmp(buffer, "gorrister\0ELLEN", sizeof("gorrister\0ELLEN")),
|
||||
"Expected the output buffer to be \"gorrister\\0ELLEN\", got \"%s\"\n",
|
||||
buffer);
|
||||
}
|
||||
|
||||
START_TEST(string)
|
||||
{
|
||||
char mem[100];
|
||||
|
@ -1396,6 +1454,7 @@ START_TEST(string)
|
|||
pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s");
|
||||
p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s");
|
||||
p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s");
|
||||
p_strlwr_s = (void *)GetProcAddress(hMsvcrt, "_strlwr_s");
|
||||
|
||||
/* MSVCRT memcpy behaves like memmove for overlapping moves,
|
||||
MFC42 CString::Insert seems to rely on that behaviour */
|
||||
|
@ -1431,4 +1490,5 @@ START_TEST(string)
|
|||
test_mbstowcs();
|
||||
test_gcvt();
|
||||
test__itoa_s();
|
||||
test__strlwr_s();
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ errno_t __cdecl strerror_s(char*,size_t,int);
|
|||
int __cdecl _stricmp(const char*,const char*);
|
||||
int __cdecl _stricoll(const char*,const char*);
|
||||
char* __cdecl _strlwr(char*);
|
||||
errno_t __cdecl _strlwr_s(char*,size_t);
|
||||
int __cdecl _strnicmp(const char*,const char*,size_t);
|
||||
char* __cdecl _strnset(char*,int,size_t);
|
||||
char* __cdecl _strrev(char*);
|
||||
|
|
Loading…
Reference in New Issue