msvcrt: Implement _strlwr_s.

This commit is contained in:
Andrew Nguyen 2010-10-11 05:25:23 -05:00 committed by Alexandre Julliard
parent bcfaf467b5
commit 41ab825126
7 changed files with 100 additions and 4 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.@)
*/

View File

@ -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();
}

View File

@ -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*);