Commit 41ab8251 authored by Andrew Nguyen's avatar Andrew Nguyen Committed by Alexandre Julliard

msvcrt: Implement _strlwr_s.

parent bcfaf467
...@@ -1142,7 +1142,7 @@ ...@@ -1142,7 +1142,7 @@
@ stub _stricoll_l @ stub _stricoll_l
@ cdecl _strlwr(str) msvcrt._strlwr @ cdecl _strlwr(str) msvcrt._strlwr
@ stub _strlwr_l @ stub _strlwr_l
@ stub _strlwr_s @ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
@ stub _strlwr_s_l @ stub _strlwr_s_l
@ stub _strncoll @ stub _strncoll
@ stub _strncoll_l @ stub _strncoll_l
......
...@@ -996,7 +996,7 @@ ...@@ -996,7 +996,7 @@
@ stub _stricoll_l @ stub _stricoll_l
@ cdecl _strlwr(str) msvcrt._strlwr @ cdecl _strlwr(str) msvcrt._strlwr
@ stub _strlwr_l @ stub _strlwr_l
@ stub _strlwr_s @ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
@ stub _strlwr_s_l @ stub _strlwr_s_l
@ stub _strncoll @ stub _strncoll
@ stub _strncoll_l @ stub _strncoll_l
......
...@@ -982,7 +982,7 @@ ...@@ -982,7 +982,7 @@
@ stub _stricoll_l @ stub _stricoll_l
@ cdecl _strlwr(str) msvcrt._strlwr @ cdecl _strlwr(str) msvcrt._strlwr
@ stub _strlwr_l @ stub _strlwr_l
@ stub _strlwr_s @ cdecl _strlwr_s(ptr long) msvcrt._strlwr_s
@ stub _strlwr_s_l @ stub _strlwr_s_l
@ stub _strncoll @ stub _strncoll
@ stub _strncoll_l @ stub _strncoll_l
......
...@@ -917,7 +917,7 @@ ...@@ -917,7 +917,7 @@
# stub _stricoll_l # stub _stricoll_l
@ cdecl _strlwr(str) ntdll._strlwr @ cdecl _strlwr(str) ntdll._strlwr
# stub _strlwr_l # stub _strlwr_l
# stub _strlwr_s @ cdecl _strlwr_s(ptr long)
# stub _strlwr_s_l # stub _strlwr_s_l
@ stub _strncoll #(str str long) @ stub _strncoll #(str str long)
# stub _strncoll_l # stub _strncoll_l
......
...@@ -51,6 +51,41 @@ char* CDECL _strdup(const char* str) ...@@ -51,6 +51,41 @@ char* CDECL _strdup(const char* str)
} }
/********************************************************************* /*********************************************************************
* _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.@) * _strnset (MSVCRT.@)
*/ */
char* CDECL MSVCRT__strnset(char* str, int value, MSVCRT_size_t len) char* CDECL MSVCRT__strnset(char* str, int value, MSVCRT_size_t len)
......
...@@ -60,6 +60,7 @@ static int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t); ...@@ -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 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_gcvt_s)(char*,size_t,double,int);
static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,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 int *p__mb_cur_max;
static unsigned char *p_mbctype; static unsigned char *p_mbctype;
...@@ -1370,6 +1371,63 @@ static void test__itoa_s(void) ...@@ -1370,6 +1371,63 @@ static void test__itoa_s(void)
buffer); 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) START_TEST(string)
{ {
char mem[100]; char mem[100];
...@@ -1396,6 +1454,7 @@ START_TEST(string) ...@@ -1396,6 +1454,7 @@ START_TEST(string)
pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s"); pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s");
p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s"); p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s");
p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_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, /* MSVCRT memcpy behaves like memmove for overlapping moves,
MFC42 CString::Insert seems to rely on that behaviour */ MFC42 CString::Insert seems to rely on that behaviour */
...@@ -1431,4 +1490,5 @@ START_TEST(string) ...@@ -1431,4 +1490,5 @@ START_TEST(string)
test_mbstowcs(); test_mbstowcs();
test_gcvt(); test_gcvt();
test__itoa_s(); test__itoa_s();
test__strlwr_s();
} }
...@@ -48,6 +48,7 @@ errno_t __cdecl strerror_s(char*,size_t,int); ...@@ -48,6 +48,7 @@ errno_t __cdecl strerror_s(char*,size_t,int);
int __cdecl _stricmp(const char*,const char*); int __cdecl _stricmp(const char*,const char*);
int __cdecl _stricoll(const char*,const char*); int __cdecl _stricoll(const char*,const char*);
char* __cdecl _strlwr(char*); char* __cdecl _strlwr(char*);
errno_t __cdecl _strlwr_s(char*,size_t);
int __cdecl _strnicmp(const char*,const char*,size_t); int __cdecl _strnicmp(const char*,const char*,size_t);
char* __cdecl _strnset(char*,int,size_t); char* __cdecl _strnset(char*,int,size_t);
char* __cdecl _strrev(char*); char* __cdecl _strrev(char*);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment