From 42afb693b10dee9a06fcadb204560490a24f1754 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 3 May 2022 10:35:45 +0200 Subject: [PATCH] kernel32: Reimplement GetCurrencyFormatA(). Signed-off-by: Alexandre Julliard --- dlls/kernel32/lcformat.c | 95 ---------------------------------------- dlls/kernel32/locale.c | 56 +++++++++++++++++++++++ 2 files changed, 56 insertions(+), 95 deletions(-) diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c index a38edcc7758..de31db5c113 100644 --- a/dlls/kernel32/lcformat.c +++ b/dlls/kernel32/lcformat.c @@ -1261,101 +1261,6 @@ INT WINAPI GetNumberFormatEx(LPCWSTR name, DWORD flags, return GetNumberFormatW(lcid, flags, value, format, number, numout); } -/************************************************************************** - * GetCurrencyFormatA (KERNEL32.@) - * - * Format a currency 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 - * lpCurrencyStr [O] Destination for formatted string - * cchOut [I] Size of lpCurrencyStr, 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 currency if the number of decimals exceeds the - * locales number of currency decimal places. - * - If cchOut is 0, this function does not write to lpCurrencyStr. - * - 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 GetCurrencyFormatA(LCID lcid, DWORD dwFlags, - LPCSTR lpszValue, const CURRENCYFMTA *lpFormat, - LPSTR lpCurrencyStr, int cchOut) -{ - DWORD cp = CP_ACP; - WCHAR szDec[8], szGrp[8], szCy[8], szIn[128], szOut[128]; - CURRENCYFMTW fmt; - const CURRENCYFMTW *pfmt = NULL; - INT iRet; - - TRACE("(0x%04lx,0x%08lx,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue), - lpFormat, lpCurrencyStr, 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 (lpFormat->lpCurrencySymbol) - { - MultiByteToWideChar(cp, 0, lpFormat->lpCurrencySymbol, -1, szCy, ARRAY_SIZE(szCy)); - fmt.lpCurrencySymbol = szCy; - } - } - - 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 = GetCurrencyFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt, - lpCurrencyStr ? szOut : NULL, cchOut); - - if (szOut[0] && lpCurrencyStr) - WideCharToMultiByte(cp, 0, szOut, -1, lpCurrencyStr, cchOut, 0, 0); - return iRet; -} - /* Formatting states for Currencies. We use flags to avoid code duplication. */ #define CF_PARENS 0x1 /* Parentheses */ #define CF_MINUS_LEFT 0x2 /* '-' to the left */ diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index c6cbec870e2..16aa0bdd2aa 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -464,6 +464,62 @@ int WINAPI GetNumberFormatA( LCID lcid, DWORD flags, const char *value, } +/************************************************************************** + * GetCurrencyFormatA (KERNEL32.@) + */ +int WINAPI GetCurrencyFormatA( LCID lcid, DWORD flags, const char *value, + const CURRENCYFMTA *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) + { + CURRENCYFMTW fmt; + WCHAR fmt_decimal[4], fmt_thousand[4], fmt_symbol[13]; + + if (flags & LOCALE_NOUSEROVERRIDE) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } + if (!format->lpDecimalSep || !format->lpThousandSep || !format->lpCurrencySymbol) + { + 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) ); + MultiByteToWideChar( cp, 0, format->lpCurrencySymbol, -1, fmt_symbol, ARRAY_SIZE(fmt_symbol) ); + fmt.NumDigits = format->NumDigits; + fmt.LeadingZero = format->LeadingZero; + fmt.Grouping = format->Grouping; + fmt.NegativeOrder = format->NegativeOrder; + fmt.PositiveOrder = format->PositiveOrder; + fmt.lpDecimalSep = fmt_decimal; + fmt.lpThousandSep = fmt_thousand; + fmt.lpCurrencySymbol = fmt_symbol; + ret = GetCurrencyFormatW( lcid, flags, input, &fmt, output, len ); + } + else ret = GetCurrencyFormatW( lcid, flags, input, NULL, output, len ); + + if (ret) ret = WideCharToMultiByte( cp, 0, output, -1, buffer, len, 0, 0 ); + return ret; +} + + /****************************************************************************** * GetGeoInfoA (KERNEL32.@) */