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@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 */