Alexandre Julliard : kernelbase: Reimplement GetTimeFormatW/Ex() using get_locale_info().

Alexandre Julliard julliard at winehq.org
Wed May 4 16:14:43 CDT 2022


Module: wine
Branch: master
Commit: 1b127e24dc89a7b7f728004811016d1b7c4a2028
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1b127e24dc89a7b7f728004811016d1b7c4a2028

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed May  4 08:52:08 2022 +0200

kernelbase: Reimplement GetTimeFormatW/Ex() using get_locale_info().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/kernel32.spec     |   4 +-
 dlls/kernel32/lcformat.c        |  47 ------------
 dlls/kernelbase/kernelbase.spec |   4 +-
 dlls/kernelbase/locale.c        | 153 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 157 insertions(+), 51 deletions(-)

diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 7067dff6b25..ebe5559d615 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -870,8 +870,8 @@
 @ stdcall GetTickCount()
 @ stdcall -ret64 GetTickCount64()
 @ stdcall GetTimeFormatA(long long ptr str ptr long)
-@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long)
-@ stdcall GetTimeFormatW(long long ptr wstr ptr long)
+@ stdcall -import GetTimeFormatEx(wstr long ptr wstr ptr long)
+@ stdcall -import GetTimeFormatW(long long ptr wstr ptr long)
 @ stdcall -import GetTimeZoneInformation(ptr)
 @ stdcall -import GetTimeZoneInformationForYear(long ptr ptr)
 # @ stub GetUILanguageInfo
diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c
index dbe960abec4..21d14328449 100644
--- a/dlls/kernel32/lcformat.c
+++ b/dlls/kernel32/lcformat.c
@@ -830,50 +830,3 @@ INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
   return NLS_GetDateTimeFormatA(lcid, dwFlags|TIME_TIMEVARSONLY, lpTime,
                                 lpFormat, lpTimeStr, cchOut);
 }
-
-/******************************************************************************
- * GetTimeFormatEx [KERNEL32.@]
- *
- * Format a date for a given locale.
- *
- * PARAMS
- *  localename [I] Locale to format for
- *  flags      [I] LOCALE_ and TIME_ flags from "winnls.h"
- *  time       [I] Time to format
- *  format     [I] Formatting overrides
- *  outbuf     [O] Destination for formatted string
- *  bufsize    [I] Size of outbuf, or 0 to calculate the resulting size
- *
- * See GetTimeFormatA for notes.
- *
- * RETURNS
- *  Success: The number of characters written to outbuf, or that would have
- *           have been written if bufsize is 0.
- *  Failure: 0. Use GetLastError() to determine the cause.
- */
-INT WINAPI GetTimeFormatEx(LPCWSTR localename, DWORD flags,
-                           const SYSTEMTIME* time, LPCWSTR format,
-                           LPWSTR outbuf, INT bufsize)
-{
-  TRACE("(%s,0x%08lx,%p,%s,%p,%d)\n", debugstr_w(localename), flags, time,
-        debugstr_w(format), outbuf, bufsize);
-
-  return NLS_GetDateTimeFormatW(LocaleNameToLCID(localename, 0),
-                                flags | TIME_TIMEVARSONLY, time, format,
-                                outbuf, bufsize);
-}
-
-/******************************************************************************
- *		GetTimeFormatW	[KERNEL32.@]
- *
- * See GetTimeFormatA.
- */
-INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
-                          LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
-{
-  TRACE("(0x%04lx,0x%08lx,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
-        debugstr_w(lpFormat), lpTimeStr, cchOut);
-
-  return NLS_GetDateTimeFormatW(lcid, dwFlags|TIME_TIMEVARSONLY, lpTime,
-                                lpFormat, lpTimeStr, cchOut);
-}
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index 103054ed636..06744a79b1f 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -756,8 +756,8 @@
 @ stdcall GetTickCount()
 @ stdcall -ret64 GetTickCount64()
 @ stdcall GetTimeFormatA(long long ptr str ptr long) kernel32.GetTimeFormatA
-@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long) kernel32.GetTimeFormatEx
-@ stdcall GetTimeFormatW(long long ptr wstr ptr long) kernel32.GetTimeFormatW
+@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long)
+@ stdcall GetTimeFormatW(long long ptr wstr ptr long)
 @ stdcall GetTimeZoneInformation(ptr)
 @ stdcall GetTimeZoneInformationForYear(long ptr ptr)
 @ stdcall GetTokenInformation(long long ptr long ptr)
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 2f9fd8eaf4a..01ccd3cc6b6 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -6966,6 +6966,120 @@ static int get_date_format( const NLS_LOCALE_DATA *locale, DWORD flags, const SY
 }
 
 
+static int get_time_format( const NLS_LOCALE_DATA *locale, DWORD flags, const SYSTEMTIME *systime,
+                            const WCHAR *format, WCHAR *buffer, int len )
+{
+    DWORD override = flags & LOCALE_NOUSEROVERRIDE;
+    WCHAR *p, *last, fmt[80], output[256];
+    SYSTEMTIME time;
+    int i, ret, val, count;
+    BOOL skip = FALSE;
+
+    if (!format)
+    {
+        get_locale_info( locale, 0, LOCALE_STIMEFORMAT | override, fmt, ARRAY_SIZE(fmt) );
+        format = fmt;
+    }
+    else if (override)
+    {
+        SetLastError( ERROR_INVALID_FLAGS );
+        return 0;
+    }
+
+    if (systime)
+    {
+        time = *systime;
+        if (time.wMilliseconds > 999 || time.wSecond > 59 || time.wMinute > 59 || time.wHour > 23)
+        {
+            SetLastError( ERROR_INVALID_PARAMETER );
+            return 0;
+        }
+    }
+    else GetLocalTime( &time );
+
+    for (p = last = output; *format; format += count)
+    {
+        count = get_pattern_len( format, L"Hhmst" );
+
+        switch (*format)
+        {
+        case '\'':
+            for (i = 1; i < count; i++)
+            {
+                if (format[i] == '\'') i++;
+                if (!skip && i < count) *p++ = format[i];
+            }
+            continue;
+
+        case 'H':
+            val = time.wHour;
+            break;
+
+        case 'h':
+            val = time.wHour;
+            if (!(flags & TIME_FORCE24HOURFORMAT))
+            {
+                val %= 12;
+                if (!val) val = 12;
+            }
+            break;
+
+        case 'm':
+            if (flags & TIME_NOMINUTESORSECONDS)
+            {
+                p = last;
+                skip = TRUE;
+                continue;
+            }
+            val = time.wMinute;
+            break;
+
+        case 's':
+            if (flags & (TIME_NOMINUTESORSECONDS | TIME_NOSECONDS))
+            {
+                p = last;
+                skip = TRUE;
+                continue;
+            }
+            val = time.wSecond;
+            break;
+
+        case 't':
+            if (flags & TIME_NOTIMEMARKER)
+            {
+                p = last;
+                skip = TRUE;
+                continue;
+            }
+            val = time.wHour < 12 ? LOCALE_S1159 : LOCALE_S2359;
+            ret = get_locale_info( locale, 0, val | override, p, output + ARRAY_SIZE(output) - p );
+            p += (count > 1) ? ret - 1 : 1;
+            skip = FALSE;
+            continue;
+
+        default:
+            if (!skip || *format == ' ') *p++ = *format;
+            continue;
+        }
+
+        p += swprintf( p, output + ARRAY_SIZE(output) - p, L"%.*u", min( 2, count ), val );
+        last = p;
+        skip = FALSE;
+    }
+    *p++ = 0;
+    ret = p - output;
+
+    if (!len) return ret;
+    lstrcpynW( buffer, output, len );
+    if (ret > len)
+    {
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        return 0;
+    }
+    return ret;
+}
+
+
 /**************************************************************************
  *	GetNumberFormatW  (kernelbase.@)
  */
@@ -7081,3 +7195,42 @@ int WINAPI GetDateFormatEx( const WCHAR *name, DWORD flags, const SYSTEMTIME *sy
     TRACE( "(%s,%lx,%p,%s,%p,%d)\n", debugstr_w(name), flags, systime, debugstr_w(format), buffer, len );
     return get_date_format( locale, flags, systime, format, buffer, len );
 }
+
+
+/***********************************************************************
+ *	GetTimeFormatW  (kernelbase.@)
+ */
+int WINAPI GetTimeFormatW( LCID lcid, DWORD flags, const SYSTEMTIME *systime,
+                            const WCHAR *format, WCHAR *buffer, int len )
+{
+    const NLS_LOCALE_DATA *locale = NlsValidateLocale( &lcid, 0 );
+
+    if (len < 0 || (len && !buffer) || !locale)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+
+    TRACE( "(%04lx,%lx,%p,%s,%p,%d)\n", lcid, flags, systime, debugstr_w(format), buffer, len );
+    return get_time_format( locale, flags, systime, format, buffer, len );
+}
+
+
+/***********************************************************************
+ *	GetTimeFormatEx  (kernelbase.@)
+ */
+int WINAPI GetTimeFormatEx( const WCHAR *name, DWORD flags, const SYSTEMTIME *systime,
+                            const WCHAR *format, WCHAR *buffer, int len )
+{
+    LCID lcid;
+    const NLS_LOCALE_DATA *locale = get_locale_by_name( name, &lcid );
+
+    if (len < 0 || (len && !buffer) || !locale)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+
+    TRACE( "(%s,%lx,%p,%s,%p,%d)\n", debugstr_w(name), flags, systime, debugstr_w(format), buffer, len );
+    return get_time_format( locale, flags, systime, format, buffer, len );
+}




More information about the wine-cvs mailing list