Nikolay Sivov : kernel32: Added support for TIME_NOSECONDS, restructured EnumTimeFormats implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Nov 10 10:36:22 CST 2015


Module: wine
Branch: master
Commit: 49e5b9c2a4d42b547509c9cc74e5215957218718
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=49e5b9c2a4d42b547509c9cc74e5215957218718

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Nov 10 17:40:09 2015 +0300

kernel32: Added support for TIME_NOSECONDS, restructured EnumTimeFormats implementation.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 9ca3e07..e421f54 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 6fa2627..7b0212e 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));
 




More information about the wine-cvs mailing list