Module: wine Branch: master Commit: b6bf69ef804146f81b803719a72d8c6afde184ba URL: https://source.winehq.org/git/wine.git/?a=commit;h=b6bf69ef804146f81b803719a...
Author: Alexandre Julliard julliard@winehq.org Date: Tue May 3 10:35:27 2022 +0200
kernel32: Reimplement GetNumberFormatA().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/lcformat.c | 90 ------------------------------------------------ dlls/kernel32/locale.c | 53 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 90 deletions(-)
diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c index 7f112767880..a38edcc7758 100644 --- a/dlls/kernel32/lcformat.c +++ b/dlls/kernel32/lcformat.c @@ -986,96 +986,6 @@ INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime, lpFormat, lpTimeStr, cchOut); }
-/************************************************************************** - * GetNumberFormatA (KERNEL32.@) - * - * Format a number string for a given locale. - * - * PARAMS - * lcid [I] Locale to format for - * dwFlags [I] LOCALE_ flags from "winnls.h" - * lpszValue [I] String to format - * lpFormat [I] Formatting overrides - * lpNumberStr [O] Destination for formatted string - * cchOut [I] Size of lpNumberStr, or 0 to calculate the resulting size - * - * NOTES - * - lpszValue can contain only '0' - '9', '-' and '.'. - * - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will - * be formatted according to the format details returned by GetLocaleInfoA(). - * - This function rounds the number string if the number of decimals exceeds the - * locales normal number of decimal places. - * - If cchOut is 0, this function does not write to lpNumberStr. - * - The ANSI version of this function fails if lcid is Unicode only. - * - * RETURNS - * Success: The number of character written to lpNumberStr, or that would - * have been written, if cchOut is 0. - * Failure: 0. Use GetLastError() to determine the cause. - */ -INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags, - LPCSTR lpszValue, const NUMBERFMTA *lpFormat, - LPSTR lpNumberStr, int cchOut) -{ - DWORD cp = CP_ACP; - WCHAR szDec[8], szGrp[8], szIn[128], szOut[128]; - NUMBERFMTW fmt; - const NUMBERFMTW *pfmt = NULL; - INT iRet; - - TRACE("(0x%04lx,0x%08lx,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue), - lpFormat, lpNumberStr, cchOut); - - if (NLS_IsUnicodeOnlyLcid(lcid)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - if (!(dwFlags & LOCALE_USE_CP_ACP)) - { - const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags); - if (!node) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - cp = node->dwCodePage; - } - - if (lpFormat) - { - memcpy(&fmt, lpFormat, sizeof(fmt)); - pfmt = &fmt; - if (lpFormat->lpDecimalSep) - { - MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec)); - fmt.lpDecimalSep = szDec; - } - if (lpFormat->lpThousandSep) - { - MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp)); - fmt.lpThousandSep = szGrp; - } - } - - if (lpszValue) - MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn)); - - if (cchOut > (int) ARRAY_SIZE(szOut)) - cchOut = ARRAY_SIZE(szOut); - - szOut[0] = '\0'; - - iRet = GetNumberFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt, - lpNumberStr ? szOut : NULL, cchOut); - - if (szOut[0] && lpNumberStr) - WideCharToMultiByte(cp, 0, szOut, -1, lpNumberStr, cchOut, 0, 0); - return iRet; -} - /* Number parsing state flags */ #define NF_ISNEGATIVE 0x1 /* '-' found */ #define NF_ISREAL 0x2 /* '.' found */ diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index 2187d3e2883..c6cbec870e2 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -411,6 +411,59 @@ int WINAPI SetCalendarInfoA( LCID lcid, CALID id, CALTYPE type, LPCSTR data ) }
+/************************************************************************** + * GetNumberFormatA (KERNEL32.@) + */ +int WINAPI GetNumberFormatA( LCID lcid, DWORD flags, const char *value, + const NUMBERFMTA *format, char *buffer, int len ) +{ + UINT cp = get_lcid_codepage( lcid, flags ); + WCHAR input[128], output[128]; + int ret; + + TRACE( "(0x%04lx,0x%08lx,%s,%p,%p,%d)\n", lcid, flags, debugstr_a(value), format, buffer, len ); + + if (len < 0 || (len && !buffer) || !value) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + MultiByteToWideChar( cp, 0, value, -1, input, ARRAY_SIZE(input) ); + + if (len > (int)ARRAY_SIZE(output)) len = ARRAY_SIZE(output); + + if (format) + { + NUMBERFMTW fmt; + WCHAR fmt_decimal[4], fmt_thousand[4]; + + if (flags & LOCALE_NOUSEROVERRIDE) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } + if (!format->lpDecimalSep || !format->lpThousandSep) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + MultiByteToWideChar( cp, 0, format->lpDecimalSep, -1, fmt_decimal, ARRAY_SIZE(fmt_decimal) ); + MultiByteToWideChar( cp, 0, format->lpThousandSep, -1, fmt_thousand, ARRAY_SIZE(fmt_thousand) ); + fmt.NumDigits = format->NumDigits; + fmt.LeadingZero = format->LeadingZero; + fmt.Grouping = format->Grouping; + fmt.NegativeOrder = format->NegativeOrder; + fmt.lpDecimalSep = fmt_decimal; + fmt.lpThousandSep = fmt_thousand; + ret = GetNumberFormatW( lcid, flags, input, &fmt, output, len ); + } + else ret = GetNumberFormatW( lcid, flags, input, NULL, output, len ); + + if (ret) ret = WideCharToMultiByte( cp, 0, output, -1, buffer, len, 0, 0 ); + return ret; +} + + /****************************************************************************** * GetGeoInfoA (KERNEL32.@) */