[PATCH 2/2] oleaut32: Fix VarParseNumFromStr()'s handling of currency decimals.
Francois Gouget
fgouget at codeweavers.com
Sat Aug 7 17:49:04 CDT 2021
They have no default, flag the value as a monetary amount, are
unaffected by the presence / absence of a currency symbol, and are
incompatible with hexadecimal / octal numbers.
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
dlls/oleaut32/tests/vartest.c | 32 ++++++------------
dlls/oleaut32/variant.c | 61 ++++++++++++++++++++++++-----------
2 files changed, 51 insertions(+), 42 deletions(-)
diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c
index 6dddc79e829..f6149005179 100644
--- a/dlls/oleaut32/tests/vartest.c
+++ b/dlls/oleaut32/tests/vartest.c
@@ -1548,11 +1548,8 @@ static void test_VarParseNumFromStrEn(void)
/* Only integers are allowed when using an alternative radix */
CONVERT("&ha.2", NUMPRS_HEX_OCT|NUMPRS_DECIMAL);
- if (broken(1)) /* FIXME Reenable once Wine is less broken */
EXPECT(1,NUMPRS_HEX_OCT|NUMPRS_DECIMAL,NUMPRS_HEX_OCT,3,4,0);
- todo_wine ok(np.dwOutFlags == NUMPRS_HEX_OCT, "Got dwOutFlags=%08x\n", np.dwOutFlags);
- EXPECTRGB(0,10);
- todo_wine EXPECTRGB(1,FAILDIG);
+ EXPECT2(10,FAILDIG);
/* Except if it looks like a plain decimal number */
CONVERT("01.2", NUMPRS_HEX_OCT|NUMPRS_DECIMAL);
@@ -2318,9 +2315,8 @@ static void test_VarParseNumFromStrMisc(void)
/* But not for their monetary equivalents */
hres = wconvert_str(L"~1", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
- todo_wine EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY,NUMPRS_DECIMAL|NUMPRS_CURRENCY,2,0,-1);
- todo_wine EXPECTRGB(0,1);
- EXPECTRGB(1,FAILDIG);
+ EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY,NUMPRS_DECIMAL|NUMPRS_CURRENCY,2,0,-1);
+ EXPECT2(1,FAILDIG);
hres = wconvert_str(L"1~", ARRAY_SIZE(rgb), NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
EXPECT(1,NUMPRS_THOUSANDS|NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_THOUSANDS|NUMPRS_CURRENCY,2,0,0);
@@ -2355,11 +2351,8 @@ static void test_VarParseNumFromStrMisc(void)
EXPECTRGB(2,FAILDIG);
hres = wconvert_str(L"1,2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
- if (broken(1)) /* FIXME Reenable once Wine is less broken */
EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
- todo_wine ok(np.dwOutFlags == (NUMPRS_DECIMAL|NUMPRS_CURRENCY), "Got dwOutFlags=%08x\n", np.dwOutFlags);
- EXPECTRGB(0,1);
- todo_wine EXPECTRGB(1,2);
+ EXPECT2(1,2);
EXPECTRGB(2,FAILDIG);
hres = wconvert_str(L"1.2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
@@ -2368,11 +2361,8 @@ static void test_VarParseNumFromStrMisc(void)
EXPECTRGB(2,FAILDIG);
hres = wconvert_str(L"1,2", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
- if (broken(1)) /* FIXME Reenable once Wine is less broken */
EXPECT(2,NUMPRS_DECIMAL|NUMPRS_CURRENCY|NUMPRS_USE_ALL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
- todo_wine ok(np.dwOutFlags == (NUMPRS_DECIMAL|NUMPRS_CURRENCY), "Got dwOutFlags=%08x\n", np.dwOutFlags);
- EXPECTRGB(0,1);
- todo_wine EXPECTRGB(1,2);
+ EXPECT2(1,2);
EXPECTRGB(2,FAILDIG);
hres = wconvert_str(L"1.2,3", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_CURRENCY, &np, rgb, LOCALE_USER_DEFAULT, 0);
@@ -2381,11 +2371,8 @@ static void test_VarParseNumFromStrMisc(void)
EXPECTRGB(2,FAILDIG);
hres = wconvert_str(L"1,2.3", ARRAY_SIZE(rgb), NUMPRS_DECIMAL, &np, rgb, LOCALE_USER_DEFAULT, 0);
- if (broken(1)) /* FIXME Reenable once Wine is less broken */
EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,3,0,-1);
- todo_wine ok(np.dwOutFlags == (NUMPRS_DECIMAL|NUMPRS_CURRENCY), "Got dwOutFlags=%08x\n", np.dwOutFlags);
- EXPECTRGB(0,1);
- todo_wine EXPECTRGB(1,2);
+ EXPECT2(1,2);
EXPECTRGB(2,FAILDIG);
@@ -2394,10 +2381,9 @@ static void test_VarParseNumFromStrMisc(void)
*/
SetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONDECIMALSEP, L"$");
hres = wconvert_str(L"1$99", ARRAY_SIZE(rgb), NUMPRS_DECIMAL|NUMPRS_USE_ALL, &np, rgb, LOCALE_USER_DEFAULT, 0);
- todo_wine EXPECT(3,NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,4,0,-2);
- EXPECTRGB(0,1);
- todo_wine EXPECTRGB(1,9);
- todo_wine EXPECTRGB(2,9);
+ EXPECT(3,NUMPRS_DECIMAL|NUMPRS_USE_ALL,NUMPRS_DECIMAL|NUMPRS_CURRENCY,4,0,-2);
+ EXPECT2(1,9);
+ EXPECTRGB(2,9);
EXPECTRGB(3,FAILDIG);
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index fe4bdb41ed2..09c6f9dcad6 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -1523,7 +1523,7 @@ typedef struct tagVARIANT_NUMBER_CHARS
/* Get the valid number characters for an lcid */
static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags)
{
- static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',0,1,{'$',0},'.',',' };
+ static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',0,1,{'$',0},0,',' };
LCTYPE lctype = dwFlags & LOCALE_NOUSEROVERRIDE;
WCHAR buff[4];
@@ -1630,7 +1630,31 @@ HRESULT WINAPI VarParseNumFromStr(const OLECHAR *lpszStr, LCID lcid, ULONG dwFla
/* First consume all the leading symbols and space from the string */
while (1)
{
- if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && iswspace(*lpszStr))
+ if (pNumprs->dwInFlags & NUMPRS_DECIMAL &&
+ (*lpszStr == chars.cDecimalPoint ||
+ *lpszStr == chars.cCurrencyDecimalPoint))
+ {
+ pNumprs->dwOutFlags |= NUMPRS_DECIMAL;
+ if (*lpszStr == chars.cCurrencyDecimalPoint &&
+ chars.cDecimalPoint != chars.cCurrencyDecimalPoint)
+ pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
+ cchUsed++;
+ lpszStr++;
+
+ /* If we have no digits so far, skip leading zeros */
+ if (!pNumprs->cDig)
+ {
+ while (lpszStr[1] == '0')
+ {
+ dwState |= B_LEADING_ZERO;
+ cchUsed++;
+ lpszStr++;
+ pNumprs->nPwr10--;
+ }
+ }
+ break;
+ }
+ else if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && iswspace(*lpszStr))
{
pNumprs->dwOutFlags |= NUMPRS_LEADING_WHITE;
do
@@ -1673,8 +1697,6 @@ HRESULT WINAPI VarParseNumFromStr(const OLECHAR *lpszStr, LCID lcid, ULONG dwFla
pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
cchUsed += chars.sCurrencyLen;
lpszStr += chars.sCurrencyLen;
- /* Only accept currency characters */
- chars.cDecimalPoint = chars.cCurrencyDecimalPoint;
}
else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == '(' &&
!(pNumprs->dwOutFlags & NUMPRS_PARENS))
@@ -1687,27 +1709,24 @@ HRESULT WINAPI VarParseNumFromStr(const OLECHAR *lpszStr, LCID lcid, ULONG dwFla
break;
}
- if (!(pNumprs->dwOutFlags & NUMPRS_CURRENCY))
- {
- /* Only accept non-currency characters */
- chars.cCurrencyDecimalPoint = chars.cDecimalPoint;
- }
-
- if ((*lpszStr == '&' && (*(lpszStr+1) == 'H' || *(lpszStr+1) == 'h')) &&
- pNumprs->dwInFlags & NUMPRS_HEX_OCT)
+ if (!(pNumprs->dwOutFlags & NUMPRS_DECIMAL))
{
+ if ((*lpszStr == '&' && (*(lpszStr+1) == 'H' || *(lpszStr+1) == 'h')) &&
+ pNumprs->dwInFlags & NUMPRS_HEX_OCT)
+ {
dwState |= B_PROCESSING_HEX;
pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
cchUsed=cchUsed+2;
lpszStr=lpszStr+2;
- }
- else if ((*lpszStr == '&' && (*(lpszStr+1) == 'O' || *(lpszStr+1) == 'o')) &&
- pNumprs->dwInFlags & NUMPRS_HEX_OCT)
- {
+ }
+ else if ((*lpszStr == '&' && (*(lpszStr+1) == 'O' || *(lpszStr+1) == 'o')) &&
+ pNumprs->dwInFlags & NUMPRS_HEX_OCT)
+ {
dwState |= B_PROCESSING_OCT;
pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
cchUsed=cchUsed+2;
lpszStr=lpszStr+2;
+ }
}
/* Strip Leading zeros */
@@ -1796,11 +1815,15 @@ HRESULT WINAPI VarParseNumFromStr(const OLECHAR *lpszStr, LCID lcid, ULONG dwFla
pNumprs->dwOutFlags |= NUMPRS_THOUSANDS|NUMPRS_CURRENCY;
cchUsed++;
}
- else if (*lpszStr == chars.cDecimalPoint &&
- pNumprs->dwInFlags & NUMPRS_DECIMAL &&
- !(pNumprs->dwOutFlags & (NUMPRS_DECIMAL|NUMPRS_EXPONENT)))
+ else if (pNumprs->dwInFlags & NUMPRS_DECIMAL &&
+ (*lpszStr == chars.cDecimalPoint ||
+ *lpszStr == chars.cCurrencyDecimalPoint) &&
+ !(pNumprs->dwOutFlags & (NUMPRS_HEX_OCT|NUMPRS_DECIMAL|NUMPRS_EXPONENT)))
{
pNumprs->dwOutFlags |= NUMPRS_DECIMAL;
+ if (*lpszStr == chars.cCurrencyDecimalPoint &&
+ chars.cDecimalPoint != chars.cCurrencyDecimalPoint)
+ pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
cchUsed++;
/* If we have no digits so far, skip leading zeros */
--
2.20.1
More information about the wine-devel
mailing list