Piotr Caban : msvcrt: Added _gmtime32_s and _gmtime64_s implementation.
Alexandre Julliard
julliard at winehq.org
Fri Aug 27 11:11:18 CDT 2010
Module: wine
Branch: master
Commit: 6467c8325fc9cf55f7d066d618495ba1fd5a8bc5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6467c8325fc9cf55f7d066d618495ba1fd5a8bc5
Author: Piotr Caban <piotr at codeweavers.com>
Date: Fri Aug 27 01:46:09 2010 +0200
msvcrt: Added _gmtime32_s and _gmtime64_s implementation.
---
dlls/msvcr100/msvcr100.spec | 4 +-
dlls/msvcr80/msvcr80.spec | 4 +-
dlls/msvcr90/msvcr90.spec | 4 +-
dlls/msvcrt/msvcrt.spec | 4 +-
dlls/msvcrt/tests/time.c | 30 +++++++++++++-
dlls/msvcrt/time.c | 94 ++++++++++++++++++++++++++++++++-----------
6 files changed, 107 insertions(+), 33 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index a6b8ec0..5e8680b 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -719,9 +719,9 @@
@ stub _getws_s
@ cdecl -i386 _global_unwind2(ptr) msvcrt._global_unwind2
@ cdecl _gmtime32(ptr) msvcrt._gmtime32
-@ stub _gmtime32_s
+@ cdecl _gmtime32_s(ptr ptr) msvcrt._gmtime32_s
@ cdecl _gmtime64(ptr) msvcrt._gmtime64
-@ stub _gmtime64_s
+@ cdecl _gmtime64_s(ptr ptr) msvcrt._gmtime64_s
@ cdecl _heapadd(ptr long) msvcrt._heapadd
@ cdecl _heapchk() msvcrt._heapchk
@ cdecl _heapmin() msvcrt._heapmin
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index ae2a1f8..f47bd83 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -566,9 +566,9 @@
@ stub _getws_s
@ cdecl -i386 _global_unwind2(ptr) msvcrt._global_unwind2
@ cdecl _gmtime32(ptr) msvcrt._gmtime32
-@ stub _gmtime32_s
+@ cdecl _gmtime32_s(ptr ptr) msvcrt._gmtime32_s
@ cdecl _gmtime64(ptr) msvcrt._gmtime64
-@ stub _gmtime64_s
+@ cdecl _gmtime64_s(ptr ptr) msvcrt._gmtime64_s
@ cdecl _heapadd(ptr long) msvcrt._heapadd
@ cdecl _heapchk() msvcrt._heapchk
@ cdecl _heapmin() msvcrt._heapmin
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 7000c2d..fbe5458 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -554,9 +554,9 @@
@ stub _getws_s
@ cdecl -i386 _global_unwind2(ptr) msvcrt._global_unwind2
@ cdecl _gmtime32(ptr) msvcrt._gmtime32
-@ stub _gmtime32_s
+@ cdecl _gmtime32_s(ptr ptr) msvcrt._gmtime32_s
@ cdecl _gmtime64(ptr) msvcrt._gmtime64
-@ stub _gmtime64_s
+@ cdecl _gmtime64_s(ptr ptr) msvcrt._gmtime64_s
@ cdecl _heapadd(ptr long) msvcrt._heapadd
@ cdecl _heapchk() msvcrt._heapchk
@ cdecl _heapmin() msvcrt._heapmin
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 2ace243..93bbfd7 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -499,9 +499,9 @@
@ cdecl _getws(ptr) MSVCRT__getws
@ cdecl -i386 _global_unwind2(ptr)
@ cdecl _gmtime32(ptr) MSVCRT__gmtime32
-# stub _gmtime32_s
+@ cdecl _gmtime32_s(ptr ptr) MSVCRT__gmtime32_s
@ cdecl _gmtime64(ptr) MSVCRT__gmtime64
-# stub _gmtime64_s
+@ cdecl _gmtime64_s(ptr ptr) MSVCRT__gmtime64_s
@ cdecl _heapadd (ptr long)
@ cdecl _heapchk()
@ cdecl _heapmin()
diff --git a/dlls/msvcrt/tests/time.c b/dlls/msvcrt/tests/time.c
index 78d8e09..b11ecf7 100644
--- a/dlls/msvcrt/tests/time.c
+++ b/dlls/msvcrt/tests/time.c
@@ -35,6 +35,7 @@
static __time32_t (__cdecl *p_mkgmtime32)(struct tm*);
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);
@@ -43,6 +44,7 @@ static void init(void)
HMODULE hmod = GetModuleHandleA("msvcrt.dll");
p_gmtime32 = (void*)GetProcAddress(hmod, "_gmtime32");
+ p_gmtime32_s = (void*)GetProcAddress(hmod, "_gmtime32_s");
p_mkgmtime32 = (void*)GetProcAddress(hmod, "_mkgmtime32");
p_strtime_s = (void*)GetProcAddress(hmod, "_strtime_s");
p_strdate_s = (void*)GetProcAddress(hmod, "_strdate_s");
@@ -71,13 +73,21 @@ static void test_ctime(void)
static void test_gmtime(void)
{
__time32_t valid, gmt;
- struct tm* gmt_tm;
+ struct tm* gmt_tm, gmt_tm_s;
+ errno_t err;
if(!p_gmtime32) {
win_skip("Skipping _gmtime32 tests\n");
return;
}
+ gmt_tm = p_gmtime32(NULL);
+ ok(gmt_tm == NULL, "gmt_tm != NULL\n");
+
+ gmt = -1;
+ gmt_tm = p_gmtime32(&gmt);
+ ok(gmt_tm == NULL, "gmt_tm != NULL\n");
+
gmt = valid = 0;
gmt_tm = p_gmtime32(&gmt);
if(!gmt_tm) {
@@ -133,6 +143,24 @@ static void test_gmtime(void)
gmt_tm->tm_isdst = 1;
gmt = p_mkgmtime32(gmt_tm);
ok(gmt == valid, "gmt = %u\n", gmt);
+
+ if(!p_gmtime32_s) {
+ win_skip("Skipping _gmtime32_s tests\n");
+ return;
+ }
+
+ errno = 0;
+ gmt = 0;
+ err = p_gmtime32_s(NULL, &gmt);
+ ok(err == EINVAL, "err = %d\n", err);
+ ok(errno == EINVAL, "errno = %d\n", errno);
+
+ errno = 0;
+ gmt = -1;
+ err = p_gmtime32_s(&gmt_tm_s, &gmt);
+ ok(err == EINVAL, "err = %d\n", err);
+ ok(errno == EINVAL, "errno = %d\n", errno);
+ ok(gmt_tm_s.tm_year == -1, "tm_year = %d\n", gmt_tm_s.tm_year);
}
static void test_mktime(void)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c
index 5044203..54bbd74 100644
--- a/dlls/msvcrt/time.c
+++ b/dlls/msvcrt/time.c
@@ -232,37 +232,78 @@ struct MSVCRT_tm* CDECL MSVCRT_localtime(const MSVCRT___time32_t* secs)
/*********************************************************************
* _gmtime64 (MSVCRT.@)
*/
-struct MSVCRT_tm* CDECL MSVCRT__gmtime64(const MSVCRT___time64_t* secs)
+int CDECL MSVCRT__gmtime64_s(struct MSVCRT_tm *res, const MSVCRT___time64_t *secs)
{
- thread_data_t * const data = msvcrt_get_thread_data();
- int i;
- FILETIME ft;
- SYSTEMTIME st;
+ int i;
+ FILETIME ft;
+ SYSTEMTIME st;
+ ULONGLONG time;
+
+ if(!res || !secs || *secs<0) {
+ if(res) {
+ res->tm_sec = -1;
+ res->tm_min = -1;
+ res->tm_hour = -1;
+ res->tm_mday = -1;
+ res->tm_year = -1;
+ res->tm_mon = -1;
+ res->tm_wday = -1;
+ res->tm_yday = -1;
+ res->tm_isdst = -1;
+ }
+
+ *MSVCRT__errno() = MSVCRT_EINVAL;
+ return MSVCRT_EINVAL;
+ }
- ULONGLONG time = *secs * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
+ time = *secs * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
- ft.dwHighDateTime = (UINT)(time >> 32);
- ft.dwLowDateTime = (UINT)time;
+ ft.dwHighDateTime = (UINT)(time >> 32);
+ ft.dwLowDateTime = (UINT)time;
- FileTimeToSystemTime(&ft, &st);
+ FileTimeToSystemTime(&ft, &st);
+
+ res->tm_sec = st.wSecond;
+ res->tm_min = st.wMinute;
+ res->tm_hour = st.wHour;
+ res->tm_mday = st.wDay;
+ res->tm_year = st.wYear - 1900;
+ res->tm_mon = st.wMonth - 1;
+ res->tm_wday = st.wDayOfWeek;
+ for (i = res->tm_yday = 0; i < st.wMonth - 1; i++) {
+ res->tm_yday += MonthLengths[IsLeapYear(st.wYear)][i];
+ }
+
+ res->tm_yday += st.wDay - 1;
+ res->tm_isdst = 0;
+
+ return 0;
+}
- if (st.wYear < 1970) return NULL;
+/*********************************************************************
+ * _gmtime64 (MSVCRT.@)
+ */
+struct MSVCRT_tm* CDECL MSVCRT__gmtime64(const MSVCRT___time64_t *secs)
+{
+ thread_data_t * const data = msvcrt_get_thread_data();
- data->time_buffer.tm_sec = st.wSecond;
- data->time_buffer.tm_min = st.wMinute;
- data->time_buffer.tm_hour = st.wHour;
- data->time_buffer.tm_mday = st.wDay;
- data->time_buffer.tm_year = st.wYear - 1900;
- data->time_buffer.tm_mon = st.wMonth - 1;
- data->time_buffer.tm_wday = st.wDayOfWeek;
- for (i = data->time_buffer.tm_yday = 0; i < st.wMonth - 1; i++) {
- data->time_buffer.tm_yday += MonthLengths[IsLeapYear(st.wYear)][i];
- }
+ if(MSVCRT__gmtime64_s(&data->time_buffer, secs))
+ return NULL;
+ return &data->time_buffer;
+}
- data->time_buffer.tm_yday += st.wDay - 1;
- data->time_buffer.tm_isdst = 0;
+/*********************************************************************
+ * _gmtime32_s (MSVCRT.@)
+ */
+int CDECL MSVCRT__gmtime32_s(struct MSVCRT_tm *res, const MSVCRT___time32_t *secs)
+{
+ MSVCRT___time64_t secs64;
- return &data->time_buffer;
+ if(secs) {
+ secs64 = *secs;
+ return MSVCRT__gmtime64_s(res, &secs64);
+ }
+ return MSVCRT__gmtime64_s(res, NULL);
}
/*********************************************************************
@@ -270,7 +311,12 @@ struct MSVCRT_tm* CDECL MSVCRT__gmtime64(const MSVCRT___time64_t* secs)
*/
struct MSVCRT_tm* CDECL MSVCRT__gmtime32(const MSVCRT___time32_t* secs)
{
- MSVCRT___time64_t secs64 = *secs;
+ MSVCRT___time64_t secs64;
+
+ if(!secs)
+ return NULL;
+
+ secs64 = *secs;
return MSVCRT__gmtime64( &secs64 );
}
More information about the wine-cvs
mailing list