kernel32: Add GetNumberFormatEx.
Signed-off-by: Daniel Lehman <dlehman@esri.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
dab03054e0
commit
e9e538abff
|
@ -751,7 +751,7 @@
|
||||||
# @ stub GetNumaProximityNode
|
# @ stub GetNumaProximityNode
|
||||||
# @ stub GetNumaProximityNodeEx
|
# @ stub GetNumaProximityNodeEx
|
||||||
@ stdcall GetNumberFormatA(long long str ptr ptr long)
|
@ 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 GetNumberFormatW(long long wstr ptr ptr long)
|
||||||
@ stdcall GetNumberOfConsoleFonts()
|
@ stdcall GetNumberOfConsoleFonts()
|
||||||
@ stdcall GetNumberOfConsoleInputEvents(long ptr)
|
@ stdcall GetNumberOfConsoleInputEvents(long ptr)
|
||||||
|
|
|
@ -1344,6 +1344,25 @@ error:
|
||||||
return 0;
|
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.@)
|
* GetCurrencyFormatA (KERNEL32.@)
|
||||||
*
|
*
|
||||||
|
|
|
@ -99,6 +99,7 @@ static BOOL (WINAPI *pEnumSystemGeoID)(GEOCLASS, GEOID, GEO_ENUMPROC);
|
||||||
static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
|
static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
|
||||||
static BOOL (WINAPI *pGetThreadPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
|
static BOOL (WINAPI *pGetThreadPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
|
||||||
static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
|
static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
|
||||||
|
static INT (WINAPI *pGetNumberFormatEx)(LPCWSTR, DWORD, LPCWSTR, const NUMBERFMTW *, LPWSTR, int);
|
||||||
|
|
||||||
static void InitFunctionPointers(void)
|
static void InitFunctionPointers(void)
|
||||||
{
|
{
|
||||||
|
@ -129,6 +130,7 @@ static void InitFunctionPointers(void)
|
||||||
X(EnumSystemGeoID);
|
X(EnumSystemGeoID);
|
||||||
X(GetSystemPreferredUILanguages);
|
X(GetSystemPreferredUILanguages);
|
||||||
X(GetThreadPreferredUILanguages);
|
X(GetThreadPreferredUILanguages);
|
||||||
|
X(GetNumberFormatEx);
|
||||||
|
|
||||||
mod = GetModuleHandleA("ntdll");
|
mod = GetModuleHandleA("ntdll");
|
||||||
X(RtlUpcaseUnicodeChar);
|
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 {
|
struct comparestringa_entry {
|
||||||
LCID lcid;
|
LCID lcid;
|
||||||
DWORD flags;
|
DWORD flags;
|
||||||
|
@ -4850,6 +5034,7 @@ START_TEST(locale)
|
||||||
test_GetDateFormatW();
|
test_GetDateFormatW();
|
||||||
test_GetCurrencyFormatA(); /* Also tests the W version */
|
test_GetCurrencyFormatA(); /* Also tests the W version */
|
||||||
test_GetNumberFormatA(); /* Also tests the W version */
|
test_GetNumberFormatA(); /* Also tests the W version */
|
||||||
|
test_GetNumberFormatEx();
|
||||||
test_CompareStringA();
|
test_CompareStringA();
|
||||||
test_CompareStringW();
|
test_CompareStringW();
|
||||||
test_CompareStringEx();
|
test_CompareStringEx();
|
||||||
|
|
|
@ -265,7 +265,7 @@
|
||||||
@ stub GetNamedLocaleHashNode
|
@ stub GetNamedLocaleHashNode
|
||||||
@ stub GetNamedPipeAttribute
|
@ stub GetNamedPipeAttribute
|
||||||
@ stub GetNamedPipeClientComputerNameW
|
@ 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 GetNumberFormatW(long long wstr ptr ptr long) kernel32.GetNumberFormatW
|
||||||
@ stdcall GetOEMCP() kernel32.GetOEMCP
|
@ stdcall GetOEMCP() kernel32.GetOEMCP
|
||||||
@ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult
|
@ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult
|
||||||
|
|
Loading…
Reference in New Issue