[PATCH 3/4] kernel32: Added support for TIME_NOSECONDS, restructured EnumTimeFormats implementation

Nikolay Sivov nsivov at codeweavers.com
Tue Nov 10 07:52:43 CST 2015


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/kernel32/lcformat.c     | 109 ++++++++++++++++++++++++++++---------------
 dlls/kernel32/tests/locale.c |   7 +--
 2 files changed, 74 insertions(+), 42 deletions(-)

diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c
index 686964f..56990b4 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_PARAMETER);
-        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 b34767b..7b0212e 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -3506,28 +3506,25 @@ 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));
 
         /* EnumTimeFormatsA doesn't support this flag */
         ret = EnumTimeFormatsA(enum_datetime_procA, lcid, TIME_NOSECONDS);
-    todo_wine {
         ok(!ret && GetLastError() == ERROR_INVALID_FLAGS, "EnumTimeFormatsA(TIME_NOSECONDS) ret %d, error %d\n", ret,
             GetLastError());
 
         ret = EnumTimeFormatsA(NULL, lcid, TIME_NOSECONDS);
         ok(!ret && GetLastError() == ERROR_INVALID_FLAGS, "EnumTimeFormatsA(TIME_NOSECONDS) ret %d, error %d\n", ret,
             GetLastError());
-    }
+
         /* And it's not supported by GetLocaleInfoA either */
         ret = GetLocaleInfoA(lcid, LOCALE_SSHORTTIME, buf, sizeof(buf)/sizeof(buf[0]));
         ok(!ret && GetLastError() == ERROR_INVALID_FLAGS, "GetLocaleInfoA(LOCALE_SSHORTTIME) ret %d, error %d\n", ret,
-- 
2.6.2




More information about the wine-patches mailing list