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