oleaut32: Add support for longer currency symbols.

Signed-off-by: Francois Gouget <fgouget@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Francois Gouget 2021-08-08 00:49:01 +02:00 committed by Alexandre Julliard
parent 9bd3e3fbe9
commit fc5e603cd3
3 changed files with 30 additions and 33 deletions

View File

@ -2439,10 +2439,10 @@ static void test_VarParseNumFromStrMisc(void)
/* Windows 8.1 incorrectly doubles the right-to-left mark: /* Windows 8.1 incorrectly doubles the right-to-left mark:
* "\x62f.\x645.\x200f\x200f 5" * "\x62f.\x645.\x200f\x200f 5"
*/ */
todo_wine ok(hres == S_OK || broken(hres == DISP_E_TYPEMISMATCH), "returned %08x\n", hres); ok(hres == S_OK || broken(hres == DISP_E_TYPEMISMATCH), "returned %08x\n", hres);
if (hres == S_OK) if (hres == S_OK)
{ {
todo_wine EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,6,0,0); EXPECT(1,NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_CURRENCY,6,0,0);
EXPECT2(5,FAILDIG); EXPECT2(5,FAILDIG);
} }

View File

@ -1499,6 +1499,19 @@ HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
return S_OK; return S_OK;
} }
/* The localised characters that make up a valid number */
typedef struct tagVARIANT_NUMBER_CHARS
{
WCHAR cNegativeSymbol;
WCHAR cPositiveSymbol;
WCHAR cDecimalPoint;
WCHAR cDigitSeparator;
DWORD sCurrencyLen;
WCHAR sCurrency[8];
WCHAR cCurrencyDecimalPoint;
WCHAR cCurrencyDigitSeparator;
} VARIANT_NUMBER_CHARS;
#define GET_NUMBER_TEXT(fld,name) \ #define GET_NUMBER_TEXT(fld,name) \
buff[0] = 0; \ buff[0] = 0; \
if (!GetLocaleInfoW(lcid, lctype|fld, buff, 2)) \ if (!GetLocaleInfoW(lcid, lctype|fld, buff, 2)) \
@ -1510,7 +1523,7 @@ HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
/* Get the valid number characters for an lcid */ /* Get the valid number characters for an lcid */
static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags) static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags)
{ {
static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',0,'$',0,'.',',' }; static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',0,1,{'$',0},'.',',' };
LCTYPE lctype = dwFlags & LOCALE_NOUSEROVERRIDE; LCTYPE lctype = dwFlags & LOCALE_NOUSEROVERRIDE;
WCHAR buff[4]; WCHAR buff[4];
@ -1522,17 +1535,16 @@ static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID
GET_NUMBER_TEXT(LOCALE_SMONDECIMALSEP, cCurrencyDecimalPoint); GET_NUMBER_TEXT(LOCALE_SMONDECIMALSEP, cCurrencyDecimalPoint);
GET_NUMBER_TEXT(LOCALE_SMONTHOUSANDSEP, cCurrencyDigitSeparator); GET_NUMBER_TEXT(LOCALE_SMONTHOUSANDSEP, cCurrencyDigitSeparator);
/* Local currency symbols are often 2 characters */ if (!GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, lpChars->sCurrency, ARRAY_SIZE(lpChars->sCurrency)))
lpChars->cCurrencyLocal2 = '\0';
switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, ARRAY_SIZE(buff)))
{ {
case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
case 2: lpChars->cCurrencyLocal = buff[0]; WARN("buffer too small for LOCALE_SCURRENCY\n");
break; *lpChars->sCurrency = 0;
default: WARN("buffer too small for LOCALE_SCURRENCY\n");
} }
TRACE("lcid 0x%x, cCurrencyLocal=%d,%d %s\n", lcid, lpChars->cCurrencyLocal, if (!*lpChars->sCurrency)
lpChars->cCurrencyLocal2, wine_dbgstr_w(buff)); wcscpy(lpChars->sCurrency, L"$");
lpChars->sCurrencyLen = wcslen(lpChars->sCurrency);
TRACE("lcid 0x%x, sCurrency=%u %s\n", lcid, lpChars->sCurrencyLen, wine_dbgstr_w(lpChars->sCurrency));
} }
/* Number Parsing States */ /* Number Parsing States */
@ -1656,12 +1668,11 @@ HRESULT WINAPI VarParseNumFromStr(const OLECHAR *lpszStr, LCID lcid, ULONG dwFla
} }
else if (pNumprs->dwInFlags & NUMPRS_CURRENCY && else if (pNumprs->dwInFlags & NUMPRS_CURRENCY &&
!(pNumprs->dwOutFlags & NUMPRS_CURRENCY) && !(pNumprs->dwOutFlags & NUMPRS_CURRENCY) &&
*lpszStr == chars.cCurrencyLocal && wcsncmp(lpszStr, chars.sCurrency, chars.sCurrencyLen) == 0)
(!chars.cCurrencyLocal2 || lpszStr[1] == chars.cCurrencyLocal2))
{ {
pNumprs->dwOutFlags |= NUMPRS_CURRENCY; pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
cchUsed += chars.cCurrencyLocal2 ? 2 : 1; cchUsed += chars.sCurrencyLen;
lpszStr += chars.cCurrencyLocal2 ? 2 : 1; lpszStr += chars.sCurrencyLen;
/* Only accept currency characters */ /* Only accept currency characters */
chars.cDecimalPoint = chars.cCurrencyDecimalPoint; chars.cDecimalPoint = chars.cCurrencyDecimalPoint;
} }
@ -1972,12 +1983,11 @@ HRESULT WINAPI VarParseNumFromStr(const OLECHAR *lpszStr, LCID lcid, ULONG dwFla
pNumprs->dwOutFlags |= NUMPRS_NEG; pNumprs->dwOutFlags |= NUMPRS_NEG;
} }
else if (pNumprs->dwInFlags & NUMPRS_CURRENCY && else if (pNumprs->dwInFlags & NUMPRS_CURRENCY &&
*lpszStr == chars.cCurrencyLocal && wcsncmp(lpszStr, chars.sCurrency, chars.sCurrencyLen) == 0)
(!chars.cCurrencyLocal2 || lpszStr[1] == chars.cCurrencyLocal2))
{ {
pNumprs->dwOutFlags |= NUMPRS_CURRENCY; pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
cchUsed += chars.cCurrencyLocal2 ? 2 : 1; cchUsed += chars.sCurrencyLen;
lpszStr += chars.cCurrencyLocal2 ? 2 : 1; lpszStr += chars.sCurrencyLen;
} }
else else
break; break;

View File

@ -101,19 +101,6 @@
#define VAR_BOOLYESNO 0x0800 /* Convert bool to "Yes"/"No" */ #define VAR_BOOLYESNO 0x0800 /* Convert bool to "Yes"/"No" */
#define VAR_NEGATIVE 0x1000 /* Number is negative */ #define VAR_NEGATIVE 0x1000 /* Number is negative */
/* The localised characters that make up a valid number */
typedef struct tagVARIANT_NUMBER_CHARS
{
WCHAR cNegativeSymbol;
WCHAR cPositiveSymbol;
WCHAR cDecimalPoint;
WCHAR cDigitSeparator;
WCHAR cCurrencyLocal;
WCHAR cCurrencyLocal2;
WCHAR cCurrencyDecimalPoint;
WCHAR cCurrencyDigitSeparator;
} VARIANT_NUMBER_CHARS;
unsigned int get_type_size(ULONG*, VARTYPE) DECLSPEC_HIDDEN; unsigned int get_type_size(ULONG*, VARTYPE) DECLSPEC_HIDDEN;
HRESULT VARIANT_ClearInd(VARIANTARG *) DECLSPEC_HIDDEN; HRESULT VARIANT_ClearInd(VARIANTARG *) DECLSPEC_HIDDEN;
BOOL get_date_format(LCID, DWORD, const SYSTEMTIME *, BOOL get_date_format(LCID, DWORD, const SYSTEMTIME *,