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