From bfe02fc747611b6f7bb70ae1f2bbba175eb7382d Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Fri, 27 Sep 2019 09:28:26 -0500 Subject: [PATCH] msvcrt: Implement %T format for strftime. Signed-off-by: Andrew Eikum Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- dlls/msvcrt/tests/time.c | 5 +++++ dlls/msvcrt/time.c | 12 ++++++++++++ dlls/ucrtbase/tests/misc.c | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/dlls/msvcrt/tests/time.c b/dlls/msvcrt/tests/time.c index 2b1c781b059..fea7ca19db4 100644 --- a/dlls/msvcrt/tests/time.c +++ b/dlls/msvcrt/tests/time.c @@ -608,6 +608,11 @@ static void test_strftime(void) gmt_tm = p_gmtime(&gmt); ok(gmt_tm != NULL, "gmtime failed\n"); + errno = 0xdeadbeef; + retA = p_strftime(bufA, 256, "%T", gmt_tm); + ok(retA == 0, "expected 0, got %ld\n", retA); + ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno); + errno = 0xdeadbeef; retA = p_strftime(NULL, 0, "copy", gmt_tm); ok(retA == 0, "expected 0, got %ld\n", retA); diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index e6493b09aff..b7d11e0543a 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -1193,6 +1193,18 @@ static MSVCRT_size_t strftime_helper(char *str, MSVCRT_size_t max, const char *f if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, 59)) return 0; break; +#if _MSVCR_VER>=140 + case 'T': + if(!strftime_int(str, &ret, max, mstm->tm_hour, alternate ? 0 : 2, 0, 23)) + return 0; + str[ret++] = ':'; + if(!strftime_int(str, &ret, max, mstm->tm_min, alternate ? 0 : 2, 0, 59)) + return 0; + str[ret++] = ':'; + if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, 59)) + return 0; + break; +#endif case 'w': if(!strftime_int(str, &ret, max, mstm->tm_wday, 0, 0, 6)) return 0; diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 4da6abff73e..bb0c2e3a0a2 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -136,6 +136,7 @@ static int (CDECL *p_fesetround)(int); static void (CDECL *p___setusermatherr)(MSVCRT_matherr_func); static int* (CDECL *p_errno)(void); static char* (CDECL *p_asctime)(const struct tm *); +static size_t (__cdecl *p_strftime)(char *, size_t, const char *, const struct tm *); static void (CDECL *p_exit)(int); static int (CDECL *p__crt_atexit)(void (CDECL*)(void)); static int (__cdecl *p_crt_at_quick_exit)(void (__cdecl *func)(void)); @@ -499,6 +500,7 @@ static BOOL init(void) p___setusermatherr = (void*)GetProcAddress(module, "__setusermatherr"); p_errno = (void*)GetProcAddress(module, "_errno"); p_asctime = (void*)GetProcAddress(module, "asctime"); + p_strftime = (void*)GetProcAddress(module, "strftime"); p__crt_atexit = (void*)GetProcAddress(module, "_crt_atexit"); p_exit = (void*)GetProcAddress(module, "exit"); p_crt_at_quick_exit = (void*)GetProcAddress(module, "_crt_at_quick_exit"); @@ -887,6 +889,21 @@ static void test_asctime(void) ok(!strcmp(ret, "Thu Jan 1 00:00:00 1970\n"), "asctime returned %s\n", ret); } +static void test_strftime(void) +{ + const struct tm epoch = { 0, 0, 0, 1, 0, 70, 4, 0, 0 }; + char bufA[256]; + size_t retA; + + retA = p_strftime(bufA, sizeof(bufA), "%T", &epoch); + ok(retA == 8, "expected 8, got %d\n", (int)retA); + ok(!strcmp(bufA, "00:00:00"), "got %s\n", bufA); + + retA = p_strftime(bufA, sizeof(bufA), "%#T", &epoch); + ok(retA == 5, "expected 5, got %d\n", (int)retA); + ok(!strcmp(bufA, "0:0:0"), "got %s\n", bufA); +} + static LONG* get_failures_counter(HANDLE *map) { *map = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, @@ -1132,6 +1149,7 @@ START_TEST(misc) test_isblank(); test_math_errors(); test_asctime(); + test_strftime(); test_exit(arg_v[0]); test_quick_exit(arg_v[0]); test__stat32();