From 60866103145d52121d5ac1f4c1501c0849d87191 Mon Sep 17 00:00:00 2001 From: Andrew Nguyen Date: Mon, 11 Oct 2010 05:25:05 -0500 Subject: [PATCH] msvcrt: Implement _localtime32_s. --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/tests/time.c | 54 +++++++++++++++++++++++++++++++++++++ dlls/msvcrt/time.c | 20 ++++++++++++++ include/msvcrt/time.h | 1 + 7 files changed, 79 insertions(+), 4 deletions(-) diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index ace6201eeb9..042437e7fc7 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -847,7 +847,7 @@ @ cdecl -i386 _local_unwind2(ptr long) msvcrt._local_unwind2 @ cdecl -i386 _local_unwind4(ptr ptr long) msvcrt._local_unwind4 @ cdecl _localtime32(ptr) msvcrt._localtime32 -@ stub _localtime32_s +@ cdecl _localtime32_s(ptr ptr) msvcrt._localtime32_s @ cdecl _localtime64(ptr) msvcrt._localtime64 @ cdecl _localtime64_s(ptr ptr) msvcrt._localtime64_s @ cdecl _lock(long) msvcrt._lock diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 3c03f09ca4f..c1d18d6ac97 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -693,7 +693,7 @@ @ cdecl -i386 _local_unwind2(ptr long) msvcrt._local_unwind2 @ cdecl -i386 _local_unwind4(ptr ptr long) msvcrt._local_unwind4 @ cdecl _localtime32(ptr) msvcrt._localtime32 -@ stub _localtime32_s +@ cdecl _localtime32_s(ptr ptr) msvcrt._localtime32_s @ cdecl _localtime64(ptr) msvcrt._localtime64 @ cdecl _localtime64_s(ptr ptr) msvcrt._localtime64_s @ cdecl _lock(long) msvcrt._lock diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 5917bccf146..6d5d5186550 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -681,7 +681,7 @@ @ cdecl -i386 _local_unwind2(ptr long) msvcrt._local_unwind2 @ cdecl -i386 _local_unwind4(ptr ptr long) msvcrt._local_unwind4 @ cdecl _localtime32(ptr) msvcrt._localtime32 -@ stub _localtime32_s +@ cdecl _localtime32_s(ptr ptr) msvcrt._localtime32_s @ cdecl _localtime64(ptr) msvcrt._localtime64 @ cdecl _localtime64_s(ptr ptr) msvcrt._localtime64_s @ cdecl _lock(long) msvcrt._lock diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 8f3a318b2f9..e628e489efe 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -620,7 +620,7 @@ @ cdecl -i386 _local_unwind2(ptr long) @ cdecl -i386 _local_unwind4(ptr ptr long) @ cdecl _localtime32(ptr) MSVCRT__localtime32 -# stub _localtime32_s +@ cdecl _localtime32_s(ptr ptr) @ cdecl _localtime64(ptr) MSVCRT__localtime64 @ cdecl _localtime64_s(ptr ptr) @ cdecl _lock(long) diff --git a/dlls/msvcrt/tests/time.c b/dlls/msvcrt/tests/time.c index 38e06c20765..a56f53c196f 100644 --- a/dlls/msvcrt/tests/time.c +++ b/dlls/msvcrt/tests/time.c @@ -40,6 +40,7 @@ static struct tm* (__cdecl *p_gmtime32)(__time32_t*); static errno_t (__cdecl *p_gmtime32_s)(struct tm*, __time32_t*); static errno_t (__cdecl *p_strtime_s)(char*,size_t); static errno_t (__cdecl *p_strdate_s)(char*,size_t); +static errno_t (__cdecl *p_localtime32_s)(struct tm*, __time32_t*); static errno_t (__cdecl *p_localtime64_s)(struct tm*, __time64_t*); static void init(void) @@ -51,6 +52,7 @@ static void init(void) p_mkgmtime32 = (void*)GetProcAddress(hmod, "_mkgmtime32"); p_strtime_s = (void*)GetProcAddress(hmod, "_strtime_s"); p_strdate_s = (void*)GetProcAddress(hmod, "_strdate_s"); + p_localtime32_s = (void*)GetProcAddress(hmod, "_localtime32_s"); p_localtime64_s = (void*)GetProcAddress(hmod, "_localtime64_s"); } @@ -425,6 +427,57 @@ static void test_wstrtime(void) ok(count == 3, "Wrong format: count = %d, should be 3\n", count); } +static void test_localtime32_s(void) +{ + struct tm tm; + __time32_t time; + errno_t err; + + if (!p_localtime32_s) + { + win_skip("Skipping _localtime32_s tests\n"); + return; + } + + errno = EBADF; + err = p_localtime32_s(NULL, NULL); + ok(err == EINVAL, "Expected _localtime32_s to return EINVAL, got %d\n", err); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + errno = EBADF; + time = 0x12345678; + err = p_localtime32_s(NULL, &time); + ok(err == EINVAL, "Expected _localtime32_s to return EINVAL, got %d\n", err); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + memset(&tm, 0, sizeof(tm)); + errno = EBADF; + err = p_localtime32_s(&tm, NULL); + ok(err == EINVAL, "Expected _localtime32_s to return EINVAL, got %d\n", err); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + ok(tm.tm_sec == -1 && tm.tm_min == -1 && tm.tm_hour == -1 && + tm.tm_mday == -1 && tm.tm_mon == -1 && tm.tm_year == -1 && + tm.tm_wday == -1 && tm.tm_yday == -1 && tm.tm_isdst == -1, + "Expected tm structure members to be initialized to -1, got " + "(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n", tm.tm_sec, tm.tm_min, + tm.tm_hour, tm.tm_mday, tm.tm_mon, tm.tm_year, tm.tm_wday, tm.tm_yday, + tm.tm_isdst); + + memset(&tm, 0, sizeof(tm)); + time = -1; + errno = EBADF; + err = p_localtime32_s(&tm, &time); + ok(err == EINVAL, "Expected _localtime32_s to return EINVAL, got %d\n", err); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + ok(tm.tm_sec == -1 && tm.tm_min == -1 && tm.tm_hour == -1 && + tm.tm_mday == -1 && tm.tm_mon == -1 && tm.tm_year == -1 && + tm.tm_wday == -1 && tm.tm_yday == -1 && tm.tm_isdst == -1, + "Expected tm structure members to be initialized to -1, got " + "(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n", tm.tm_sec, tm.tm_min, + tm.tm_hour, tm.tm_mday, tm.tm_mon, tm.tm_year, tm.tm_wday, tm.tm_yday, + tm.tm_isdst); +} + static void test_localtime64_s(void) { struct tm tm; @@ -502,5 +555,6 @@ START_TEST(time) test_strtime(); test_wstrdate(); test_wstrtime(); + test_localtime32_s(); test_localtime64_s(); } diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index ae2463c1d23..9d5962572e3 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -259,6 +259,26 @@ struct MSVCRT_tm* CDECL MSVCRT__localtime32(const MSVCRT___time32_t* secs) return MSVCRT__localtime64( &secs64 ); } +/********************************************************************* + * _localtime32_s (MSVCRT.@) + */ +int CDECL _localtime32_s(struct MSVCRT_tm *time, const MSVCRT___time32_t *secs) +{ + MSVCRT___time64_t secs64; + + if (!time || !secs || *secs < 0) + { + if (time) + write_invalid_msvcrt_tm(time); + + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } + + secs64 = *secs; + return _localtime64_s(time, &secs64); +} + /********************************************************************* * localtime (MSVCRT.@) */ diff --git a/include/msvcrt/time.h b/include/msvcrt/time.h index 194b47c2ca2..3a5e22f26c2 100644 --- a/include/msvcrt/time.h +++ b/include/msvcrt/time.h @@ -103,6 +103,7 @@ double __cdecl _difftime64(__time64_t,__time64_t); struct tm* __cdecl _gmtime32(const __time32_t*); struct tm* __cdecl _gmtime64(const __time64_t*); struct tm* __cdecl _localtime32(const __time32_t*); +errno_t __cdecl _localtime32_s(struct tm*, const __time64_t*); struct tm* __cdecl _localtime64(const __time64_t*); errno_t __cdecl _localtime64_s(struct tm*, const __time64_t*); __time32_t __cdecl _mktime32(struct tm*);