kernel32: Add GetNumberFormatEx.

Signed-off-by: Daniel Lehman <dlehman@esri.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Daniel Lehman 2016-08-15 10:54:20 -07:00 committed by Alexandre Julliard
parent dab03054e0
commit e9e538abff
4 changed files with 206 additions and 2 deletions

View File

@ -751,7 +751,7 @@
# @ stub GetNumaProximityNode
# @ stub GetNumaProximityNodeEx
@ stdcall GetNumberFormatA(long long str ptr ptr long)
# @ stub GetNumberFormatEx
@ stdcall GetNumberFormatEx(wstr long wstr ptr ptr long)
@ stdcall GetNumberFormatW(long long wstr ptr ptr long)
@ stdcall GetNumberOfConsoleFonts()
@ stdcall GetNumberOfConsoleInputEvents(long ptr)

View File

@ -1344,6 +1344,25 @@ error:
return 0;
}
/**************************************************************************
* GetNumberFormatEx (KERNEL32.@)
*/
INT WINAPI GetNumberFormatEx(LPCWSTR name, DWORD flags,
LPCWSTR value, const NUMBERFMTW *format,
LPWSTR number, int numout)
{
LCID lcid;
TRACE("(%s,0x%08x,%s,%p,%p,%d)\n", debugstr_w(name), flags,
debugstr_w(value), format, number, numout);
lcid = LocaleNameToLCID(name, 0);
if (!lcid)
return 0;
return GetNumberFormatW(lcid, flags, value, format, number, numout);
}
/**************************************************************************
* GetCurrencyFormatA (KERNEL32.@)
*

View File

@ -99,6 +99,7 @@ static BOOL (WINAPI *pEnumSystemGeoID)(GEOCLASS, GEOID, GEO_ENUMPROC);
static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
static BOOL (WINAPI *pGetThreadPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
static INT (WINAPI *pGetNumberFormatEx)(LPCWSTR, DWORD, LPCWSTR, const NUMBERFMTW *, LPWSTR, int);
static void InitFunctionPointers(void)
{
@ -129,6 +130,7 @@ static void InitFunctionPointers(void)
X(EnumSystemGeoID);
X(GetSystemPreferredUILanguages);
X(GetThreadPreferredUILanguages);
X(GetNumberFormatEx);
mod = GetModuleHandleA("ntdll");
X(RtlUpcaseUnicodeChar);
@ -1590,6 +1592,188 @@ static void test_GetNumberFormatA(void)
}
}
static void test_GetNumberFormatEx(void)
{
int ret;
NUMBERFMTW format;
static WCHAR dotW[] = {'.',0};
static WCHAR commaW[] = {',',0};
static const WCHAR enW[] = {'e','n','-','U','S',0};
static const WCHAR frW[] = {'f','r','-','F','R',0};
static const WCHAR bogusW[] = {'b','o','g','u','s',0};
WCHAR buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
if (!pGetNumberFormatEx)
{
win_skip("GetNumberFormatEx is not available.\n");
return;
}
STRINGSW("23",""); /* NULL output, length > 0 --> Error */
ret = pGetNumberFormatEx(enW, 0, input, NULL, NULL, COUNTOF(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("23,53",""); /* Invalid character --> Error */
ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("--",""); /* Double '-' --> Error */
ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("0-",""); /* Trailing '-' --> Error */
ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("0..",""); /* Double '.' --> Error */
ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW(" 0.1",""); /* Leading space --> Error */
ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("1234","1"); /* Length too small --> Write up to length chars */
ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, 2);
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
STRINGSW("23",""); /* Bogus locale --> Error */
ret = pGetNumberFormatEx(bogusW, NUO, input, NULL, buffer, COUNTOF(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
memset(&format, 0, sizeof(format));
STRINGSW("2353",""); /* Format and flags given --> Error */
ret = pGetNumberFormatEx(enW, NUO, input, &format, buffer, COUNTOF(buffer));
ok( !ret, "Expected ret == 0, got %d\n", ret);
ok( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
STRINGSW("2353",""); /* Invalid format --> Error */
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("2353","2,353.00"); /* Valid number */
ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("-2353","-2,353.00"); /* Valid negative number */
ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("-353","-353.00"); /* test for off by one error in grouping */
ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("2353.1","2,353.10"); /* Valid real number */
ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("2353.111","2,353.11"); /* Too many DP --> Truncated */
ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("2353.119","2,353.12"); /* Too many DP --> Rounded */
ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NumDigits = 0; /* No decimal separator */
format.LeadingZero = 0;
format.Grouping = 0; /* No grouping char */
format.NegativeOrder = 0;
format.lpDecimalSep = dotW;
format.lpThousandSep = commaW;
STRINGSW("2353","2353"); /* No decimal or grouping chars expected */
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
STRINGSW("2353","2353.0");
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.Grouping = 2; /* Group by 100's */
STRINGSW("2353","23,53.0");
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("235","235.0"); /* Grouping of a positive number */
format.Grouping = 3;
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("-235","-235.0"); /* Grouping of a negative number */
format.NegativeOrder = NEG_LEFT;
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.LeadingZero = 1; /* Always provide leading zero */
STRINGSW(".5","0.5");
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_PARENS;
STRINGSW("-1","(1.0)");
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_LEFT;
STRINGSW("-1","-1.0");
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_LEFT_SPACE;
STRINGSW("-1","- 1.0");
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_RIGHT;
STRINGSW("-1","1.0-");
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_RIGHT_SPACE;
STRINGSW("-1","1.0 -");
ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
if (pIsValidLocaleName(frW))
{
STRINGSW("-12345","-12 345,00"); /* Try French formatting */
Expected[3] = 160; /* Non breaking space */
ret = pGetNumberFormatEx(frW, NUO, input, NULL, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
}
}
struct comparestringa_entry {
LCID lcid;
DWORD flags;
@ -4850,6 +5034,7 @@ START_TEST(locale)
test_GetDateFormatW();
test_GetCurrencyFormatA(); /* Also tests the W version */
test_GetNumberFormatA(); /* Also tests the W version */
test_GetNumberFormatEx();
test_CompareStringA();
test_CompareStringW();
test_CompareStringEx();

View File

@ -265,7 +265,7 @@
@ stub GetNamedLocaleHashNode
@ stub GetNamedPipeAttribute
@ stub GetNamedPipeClientComputerNameW
@ stub GetNumberFormatEx
@ stdcall GetNumberFormatEx(wstr long wstr ptr ptr long) kernel32.GetNumberFormatEx
@ stdcall GetNumberFormatW(long long wstr ptr ptr long) kernel32.GetNumberFormatW
@ stdcall GetOEMCP() kernel32.GetOEMCP
@ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult