From 49e5b9c2a4d42b547509c9cc74e5215957218718 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 10 Nov 2015 17:40:09 +0300 Subject: [PATCH] kernel32: Added support for TIME_NOSECONDS, restructured EnumTimeFormats implementation. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/kernel32/lcformat.c | 109 ++++++++++++++++++++++++++++--------------- dlls/kernel32/tests/locale.c | 4 +- 2 files changed, 73 insertions(+), 40 deletions(-) diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c index 9ca3e070423..e421f54669c 100644 --- a/dlls/kernel32/lcformat.c +++ b/dlls/kernel32/lcformat.c @@ -1920,69 +1920,104 @@ BOOL WINAPI EnumDateFormatsExEx(DATEFMT_ENUMPROCEXEX proc, const WCHAR *locale, return NLS_EnumDateFormats(&ctxt); } -/************************************************************************** - * EnumTimeFormatsA (KERNEL32.@) - * - * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle - * LOCALE_NOUSEROVERRIDE here as well? - */ -BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags) -{ - char buf[256]; +struct enumtimeformats_context { + enum enum_callback_type type; /* callback kind */ + union { + TIMEFMT_ENUMPROCW callback; /* user callback pointer */ + } u; + LCID lcid; /* locale of interest */ + DWORD flags; + BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */ +}; - if (flags & ~LOCALE_USE_CP_ACP) - { - SetLastError(ERROR_INVALID_FLAGS); - return FALSE; - } +static BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt) +{ + WCHAR bufW[256]; + char bufA[256]; + LCTYPE lctype; + INT ret; - if (!proc) + if (!ctxt->u.callback) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - switch (flags & ~LOCALE_USE_CP_ACP) + switch (ctxt->flags & ~LOCALE_USE_CP_ACP) { case 0: - if (GetLocaleInfoA(lcid, LOCALE_STIMEFORMAT | (flags & LOCALE_USE_CP_ACP), buf, 256)) - proc(buf); + lctype = LOCALE_STIMEFORMAT; + break; + case TIME_NOSECONDS: + lctype = LOCALE_SSHORTTIME; break; - default: - FIXME("Unknown time format (%d)\n", flags); + FIXME("Unknown time format (%d)\n", ctxt->flags); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } + + lctype |= ctxt->flags & LOCALE_USE_CP_ACP; + if (ctxt->unicode) + ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, sizeof(bufW)/sizeof(bufW[0])); + else + ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, sizeof(bufA)/sizeof(bufA[0])); + + if (ret) + { + switch (ctxt->type) + { + case CALLBACK_ENUMPROC: + ctxt->u.callback(ctxt->unicode ? bufW : (WCHAR*)bufA); + break; + default: + ; + } + } + return TRUE; } /************************************************************************** - * EnumTimeFormatsW (KERNEL32.@) + * EnumTimeFormatsA (KERNEL32.@) + * + * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle + * LOCALE_NOUSEROVERRIDE here as well? */ -BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags) +BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags) { - WCHAR buf[256]; + struct enumtimeformats_context ctxt; - if (!proc) + /* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */ + if (flags & ~LOCALE_USE_CP_ACP) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(ERROR_INVALID_FLAGS); return FALSE; } - switch (flags & ~LOCALE_USE_CP_ACP) - { - case 0: - if (GetLocaleInfoW(lcid, LOCALE_STIMEFORMAT | (flags & LOCALE_USE_CP_ACP), buf, 256)) - proc(buf); - break; + ctxt.type = CALLBACK_ENUMPROC; + ctxt.u.callback = (TIMEFMT_ENUMPROCW)proc; + ctxt.lcid = lcid; + ctxt.flags = flags; + ctxt.unicode = FALSE; - default: - FIXME("Unknown time format (%d)\n", flags); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - return TRUE; + return NLS_EnumTimeFormats(&ctxt); +} + +/************************************************************************** + * EnumTimeFormatsW (KERNEL32.@) + */ +BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags) +{ + struct enumtimeformats_context ctxt; + + ctxt.type = CALLBACK_ENUMPROC; + ctxt.u.callback = proc; + ctxt.lcid = lcid; + ctxt.flags = flags; + ctxt.unicode = TRUE; + + return NLS_EnumTimeFormats(&ctxt); } struct enumcalendar_context { diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 6fa2627bf18..7b0212e228c 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -3506,15 +3506,13 @@ static void test_EnumTimeFormatsW(void) date_fmt_bufW[0] = 0; ret = EnumTimeFormatsW(enum_datetime_procW, lcid, TIME_NOSECONDS); if (!ret && GetLastError() == ERROR_INVALID_FLAGS) - skip("EnumTimeFormatsW doesn't support TIME_NOSECONDS\n"); + win_skip("EnumTimeFormatsW doesn't support TIME_NOSECONDS\n"); else { char buf[256]; - todo_wine ok(ret, "EnumTimeFormatsW(TIME_NOSECONDS) error %d\n", GetLastError()); ret = GetLocaleInfoW(lcid, LOCALE_SSHORTTIME, bufW, sizeof(bufW)/sizeof(bufW[0])); ok(ret, "GetLocaleInfoW(LOCALE_SSHORTTIME) error %d\n", GetLastError()); - todo_wine ok(!lstrcmpW(date_fmt_bufW, bufW), "expected \"%s\" got \"%s\"\n", wine_dbgstr_w(date_fmt_bufW), wine_dbgstr_w(bufW)); -- 2.11.4.GIT