msvcrt: Added _gmtime32_s and _gmtime64_s implementation.
This commit is contained in:
parent
471bad1ee8
commit
6467c8325f
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
ULONGLONG time = *secs * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
|
||||
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;
|
||||
}
|
||||
|
||||
ft.dwHighDateTime = (UINT)(time >> 32);
|
||||
ft.dwLowDateTime = (UINT)time;
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return MSVCRT_EINVAL;
|
||||
}
|
||||
|
||||
FileTimeToSystemTime(&ft, &st);
|
||||
time = *secs * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
|
||||
|
||||
if (st.wYear < 1970) return NULL;
|
||||
ft.dwHighDateTime = (UINT)(time >> 32);
|
||||
ft.dwLowDateTime = (UINT)time;
|
||||
|
||||
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];
|
||||
}
|
||||
FileTimeToSystemTime(&ft, &st);
|
||||
|
||||
data->time_buffer.tm_yday += st.wDay - 1;
|
||||
data->time_buffer.tm_isdst = 0;
|
||||
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];
|
||||
}
|
||||
|
||||
return &data->time_buffer;
|
||||
res->tm_yday += st.wDay - 1;
|
||||
res->tm_isdst = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _gmtime64 (MSVCRT.@)
|
||||
*/
|
||||
struct MSVCRT_tm* CDECL MSVCRT__gmtime64(const MSVCRT___time64_t *secs)
|
||||
{
|
||||
thread_data_t * const data = msvcrt_get_thread_data();
|
||||
|
||||
if(MSVCRT__gmtime64_s(&data->time_buffer, secs))
|
||||
return NULL;
|
||||
return &data->time_buffer;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _gmtime32_s (MSVCRT.@)
|
||||
*/
|
||||
int CDECL MSVCRT__gmtime32_s(struct MSVCRT_tm *res, const MSVCRT___time32_t *secs)
|
||||
{
|
||||
MSVCRT___time64_t secs64;
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue