mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 07:37:02 +00:00
kernelbase: Reimplement GetNumberFormatW/Ex() using get_locale_info().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
42afb693b1
commit
56099a3124
5 changed files with 270 additions and 272 deletions
|
@ -756,8 +756,8 @@
|
|||
@ stdcall GetNumaProximityNode(long ptr)
|
||||
@ stdcall -import GetNumaProximityNodeEx(long ptr)
|
||||
@ stdcall GetNumberFormatA(long long str ptr ptr long)
|
||||
@ stdcall GetNumberFormatEx(wstr long wstr ptr ptr long)
|
||||
@ stdcall GetNumberFormatW(long long wstr ptr ptr long)
|
||||
@ stdcall -import GetNumberFormatEx(wstr long wstr ptr ptr long)
|
||||
@ stdcall -import GetNumberFormatW(long long wstr ptr ptr long)
|
||||
@ stdcall GetNumberOfConsoleFonts()
|
||||
@ stdcall -import GetNumberOfConsoleInputEvents(long ptr)
|
||||
@ stdcall -import GetNumberOfConsoleMouseButtons(ptr)
|
||||
|
|
|
@ -993,274 +993,6 @@ INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
|
|||
#define NF_DIGITS_OUT 0x8 /* Digits before the '.' found */
|
||||
#define NF_ROUND 0x10 /* Number needs to be rounded */
|
||||
|
||||
/* Formatting options for Numbers */
|
||||
#define NLS_NEG_PARENS 0 /* "(1.1)" */
|
||||
#define NLS_NEG_LEFT 1 /* "-1.1" */
|
||||
#define NLS_NEG_LEFT_SPACE 2 /* "- 1.1" */
|
||||
#define NLS_NEG_RIGHT 3 /* "1.1-" */
|
||||
#define NLS_NEG_RIGHT_SPACE 4 /* "1.1 -" */
|
||||
|
||||
/**************************************************************************
|
||||
* GetNumberFormatW (KERNEL32.@)
|
||||
*
|
||||
* See GetNumberFormatA.
|
||||
*/
|
||||
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags,
|
||||
LPCWSTR lpszValue, const NUMBERFMTW *lpFormat,
|
||||
LPWSTR lpNumberStr, int cchOut)
|
||||
{
|
||||
WCHAR szBuff[128], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
|
||||
WCHAR szNegBuff[8];
|
||||
const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc;
|
||||
DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0;
|
||||
INT iRet;
|
||||
|
||||
TRACE("(0x%04lx,0x%08lx,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_w(lpszValue),
|
||||
lpFormat, lpNumberStr, cchOut);
|
||||
|
||||
lcid = ConvertDefaultLocale(lcid);
|
||||
if (!lpszValue || cchOut < 0 || (cchOut > 0 && !lpNumberStr) ||
|
||||
!IsValidLocale(lcid, 0) ||
|
||||
(lpFormat && (dwFlags || !lpFormat->lpDecimalSep || !lpFormat->lpThousandSep)))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!lpFormat)
|
||||
{
|
||||
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
|
||||
|
||||
if (!node)
|
||||
goto error;
|
||||
lpFormat = &node->fmt;
|
||||
lpszNegStart = lpszNeg = GetNegative(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLocaleInfoW(lcid, LOCALE_SNEGATIVESIGN|(dwFlags & LOCALE_NOUSEROVERRIDE),
|
||||
szNegBuff, ARRAY_SIZE(szNegBuff));
|
||||
lpszNegStart = lpszNeg = szNegBuff;
|
||||
}
|
||||
lpszNeg = lpszNeg + lstrlenW(lpszNeg) - 1;
|
||||
|
||||
dwFlags &= (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP);
|
||||
|
||||
/* Format the number backwards into a temporary buffer */
|
||||
|
||||
szSrc = lpszValue;
|
||||
*szOut-- = '\0';
|
||||
|
||||
/* Check the number for validity */
|
||||
while (*szSrc)
|
||||
{
|
||||
if (*szSrc >= '0' && *szSrc <= '9')
|
||||
{
|
||||
dwState |= NF_DIGITS;
|
||||
if (dwState & NF_ISREAL)
|
||||
dwDecimals++;
|
||||
}
|
||||
else if (*szSrc == '-')
|
||||
{
|
||||
if (dwState)
|
||||
goto error; /* '-' not first character */
|
||||
dwState |= NF_ISNEGATIVE;
|
||||
}
|
||||
else if (*szSrc == '.')
|
||||
{
|
||||
if (dwState & NF_ISREAL)
|
||||
goto error; /* More than one '.' */
|
||||
dwState |= NF_ISREAL;
|
||||
}
|
||||
else
|
||||
goto error; /* Invalid char */
|
||||
szSrc++;
|
||||
}
|
||||
szSrc--; /* Point to last character */
|
||||
|
||||
if (!(dwState & NF_DIGITS))
|
||||
goto error; /* No digits */
|
||||
|
||||
/* Add any trailing negative sign */
|
||||
if (dwState & NF_ISNEGATIVE)
|
||||
{
|
||||
switch (lpFormat->NegativeOrder)
|
||||
{
|
||||
case NLS_NEG_PARENS:
|
||||
*szOut-- = ')';
|
||||
break;
|
||||
case NLS_NEG_RIGHT:
|
||||
case NLS_NEG_RIGHT_SPACE:
|
||||
while (lpszNeg >= lpszNegStart)
|
||||
*szOut-- = *lpszNeg--;
|
||||
if (lpFormat->NegativeOrder == NLS_NEG_RIGHT_SPACE)
|
||||
*szOut-- = ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy all digits up to the decimal point */
|
||||
if (!lpFormat->NumDigits)
|
||||
{
|
||||
if (dwState & NF_ISREAL)
|
||||
{
|
||||
while (*szSrc != '.') /* Don't write any decimals or a separator */
|
||||
{
|
||||
if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
|
||||
dwState |= NF_ROUND;
|
||||
else
|
||||
dwState &= ~NF_ROUND;
|
||||
szSrc--;
|
||||
}
|
||||
szSrc--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LPWSTR lpszDec = lpFormat->lpDecimalSep + lstrlenW(lpFormat->lpDecimalSep) - 1;
|
||||
|
||||
if (dwDecimals <= lpFormat->NumDigits)
|
||||
{
|
||||
dwDecimals = lpFormat->NumDigits - dwDecimals;
|
||||
while (dwDecimals--)
|
||||
*szOut-- = '0'; /* Pad to correct number of dp */
|
||||
}
|
||||
else
|
||||
{
|
||||
dwDecimals -= lpFormat->NumDigits;
|
||||
/* Skip excess decimals, and determine if we have to round the number */
|
||||
while (dwDecimals--)
|
||||
{
|
||||
if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
|
||||
dwState |= NF_ROUND;
|
||||
else
|
||||
dwState &= ~NF_ROUND;
|
||||
szSrc--;
|
||||
}
|
||||
}
|
||||
|
||||
if (dwState & NF_ISREAL)
|
||||
{
|
||||
while (*szSrc != '.')
|
||||
{
|
||||
if (dwState & NF_ROUND)
|
||||
{
|
||||
if (*szSrc == '9')
|
||||
*szOut-- = '0'; /* continue rounding */
|
||||
else
|
||||
{
|
||||
dwState &= ~NF_ROUND;
|
||||
*szOut-- = (*szSrc)+1;
|
||||
}
|
||||
szSrc--;
|
||||
}
|
||||
else
|
||||
*szOut-- = *szSrc--; /* Write existing decimals */
|
||||
}
|
||||
szSrc--; /* Skip '.' */
|
||||
}
|
||||
|
||||
while (lpszDec >= lpFormat->lpDecimalSep)
|
||||
*szOut-- = *lpszDec--; /* Write decimal separator */
|
||||
}
|
||||
|
||||
dwGroupCount = lpFormat->Grouping == 32 ? 3 : lpFormat->Grouping;
|
||||
|
||||
/* Write the remaining whole number digits, including grouping chars */
|
||||
while (szSrc >= lpszValue && *szSrc >= '0' && *szSrc <= '9')
|
||||
{
|
||||
if (dwState & NF_ROUND)
|
||||
{
|
||||
if (*szSrc == '9')
|
||||
*szOut-- = '0'; /* continue rounding */
|
||||
else
|
||||
{
|
||||
dwState &= ~NF_ROUND;
|
||||
*szOut-- = (*szSrc)+1;
|
||||
}
|
||||
szSrc--;
|
||||
}
|
||||
else
|
||||
*szOut-- = *szSrc--;
|
||||
|
||||
dwState |= NF_DIGITS_OUT;
|
||||
dwCurrentGroupCount++;
|
||||
if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount && *szSrc != '-')
|
||||
{
|
||||
LPWSTR lpszGrp = lpFormat->lpThousandSep + lstrlenW(lpFormat->lpThousandSep) - 1;
|
||||
|
||||
while (lpszGrp >= lpFormat->lpThousandSep)
|
||||
*szOut-- = *lpszGrp--; /* Write grouping char */
|
||||
|
||||
dwCurrentGroupCount = 0;
|
||||
if (lpFormat->Grouping == 32)
|
||||
dwGroupCount = 2; /* Indic grouping: 3 then 2 */
|
||||
}
|
||||
}
|
||||
if (dwState & NF_ROUND)
|
||||
{
|
||||
*szOut-- = '1'; /* e.g. .6 > 1.0 */
|
||||
}
|
||||
else if (!(dwState & NF_DIGITS_OUT) && lpFormat->LeadingZero)
|
||||
*szOut-- = '0'; /* Add leading 0 if we have no digits before the decimal point */
|
||||
|
||||
/* Add any leading negative sign */
|
||||
if (dwState & NF_ISNEGATIVE)
|
||||
{
|
||||
switch (lpFormat->NegativeOrder)
|
||||
{
|
||||
case NLS_NEG_PARENS:
|
||||
*szOut-- = '(';
|
||||
break;
|
||||
case NLS_NEG_LEFT_SPACE:
|
||||
*szOut-- = ' ';
|
||||
/* Fall through */
|
||||
case NLS_NEG_LEFT:
|
||||
while (lpszNeg >= lpszNegStart)
|
||||
*szOut-- = *lpszNeg--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
szOut++;
|
||||
|
||||
iRet = lstrlenW(szOut) + 1;
|
||||
if (cchOut)
|
||||
{
|
||||
if (iRet <= cchOut)
|
||||
memcpy(lpNumberStr, szOut, iRet * sizeof(WCHAR));
|
||||
else
|
||||
{
|
||||
memcpy(lpNumberStr, szOut, cchOut * sizeof(WCHAR));
|
||||
lpNumberStr[cchOut - 1] = '\0';
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
iRet = 0;
|
||||
}
|
||||
}
|
||||
return iRet;
|
||||
|
||||
error:
|
||||
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
|
||||
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%08lx,%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);
|
||||
}
|
||||
|
||||
/* Formatting states for Currencies. We use flags to avoid code duplication. */
|
||||
#define CF_PARENS 0x1 /* Parentheses */
|
||||
#define CF_MINUS_LEFT 0x2 /* '-' to the left */
|
||||
|
|
|
@ -1460,15 +1460,30 @@ static void test_GetNumberFormatA(void)
|
|||
format.Grouping = 3;
|
||||
ret = GetNumberFormatA(lcid, 0, "235", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_str(ret, buffer, "235.0");
|
||||
ret = GetNumberFormatA(lcid, 0, "000235", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_str(ret, buffer, "235.0");
|
||||
|
||||
format.Grouping = 23;
|
||||
ret = GetNumberFormatA(lcid, 0, "123456789", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_str(ret, buffer, "1,234,567,89.0");
|
||||
|
||||
format.Grouping = 230;
|
||||
ret = GetNumberFormatA(lcid, 0, "123456789", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_str(ret, buffer, "1234,567,89.0");
|
||||
|
||||
/* Grouping of a negative number */
|
||||
format.NegativeOrder = NEG_LEFT;
|
||||
format.Grouping = 3;
|
||||
ret = GetNumberFormatA(lcid, 0, "-235", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_str(ret, buffer, "-235.0");
|
||||
ret = GetNumberFormatA(lcid, 0, "-000235", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_str(ret, buffer, "-235.0");
|
||||
|
||||
format.LeadingZero = 1; /* Always provide leading zero */
|
||||
ret = GetNumberFormatA(lcid, 0, ".5", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_str(ret, buffer, "0.5");
|
||||
ret = GetNumberFormatA(lcid, 0, "0000.5", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_str(ret, buffer, "0.5");
|
||||
|
||||
format.NegativeOrder = NEG_PARENS;
|
||||
ret = GetNumberFormatA(lcid, 0, "-1", &format, buffer, ARRAY_SIZE(buffer));
|
||||
|
@ -1640,6 +1655,14 @@ static void test_GetNumberFormatEx(void)
|
|||
format.LeadingZero = 1;
|
||||
ret = pGetNumberFormatEx(enW, 0, L".5", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_wstr(ret, buffer, L"0.5");
|
||||
ret = pGetNumberFormatEx(enW, 0, L"0.5", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_wstr(ret, buffer, L"0.5");
|
||||
|
||||
format.LeadingZero = 0;
|
||||
ret = pGetNumberFormatEx(enW, 0, L".5", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_wstr(ret, buffer, L".5");
|
||||
ret = pGetNumberFormatEx(enW, 0, L"0.5", &format, buffer, ARRAY_SIZE(buffer));
|
||||
expect_wstr(ret, buffer, L".5");
|
||||
|
||||
format.NegativeOrder = NEG_PARENS;
|
||||
ret = pGetNumberFormatEx(enW, 0, L"-1", &format, buffer, ARRAY_SIZE(buffer));
|
||||
|
|
|
@ -604,8 +604,8 @@
|
|||
@ stdcall GetNumaHighestNodeNumber(ptr)
|
||||
@ stdcall GetNumaNodeProcessorMaskEx(long ptr)
|
||||
@ stdcall GetNumaProximityNodeEx(long ptr)
|
||||
@ stdcall GetNumberFormatEx(wstr long wstr ptr ptr long) kernel32.GetNumberFormatEx
|
||||
@ stdcall GetNumberFormatW(long long wstr ptr ptr long) kernel32.GetNumberFormatW
|
||||
@ stdcall GetNumberFormatEx(wstr long wstr ptr ptr long)
|
||||
@ stdcall GetNumberFormatW(long long wstr ptr ptr long)
|
||||
@ stdcall GetNumberOfConsoleInputEvents(long ptr)
|
||||
@ stdcall GetNumberOfConsoleMouseButtons(ptr)
|
||||
@ stdcall GetOEMCP()
|
||||
|
|
|
@ -6449,3 +6449,246 @@ BOOL WINAPI SetUserGeoName(PWSTR geo_name)
|
|||
}
|
||||
return SetUserGeoID( geo->id );
|
||||
}
|
||||
|
||||
|
||||
static void grouping_to_string( UINT grouping, WCHAR *buffer )
|
||||
{
|
||||
WCHAR tmp[10], *p = tmp;
|
||||
|
||||
while (grouping)
|
||||
{
|
||||
*p++ = '0' + grouping % 10;
|
||||
grouping /= 10;
|
||||
}
|
||||
while (p > tmp)
|
||||
{
|
||||
*buffer++ = *(--p);
|
||||
if (p > tmp) *buffer++ = ';';
|
||||
}
|
||||
*buffer = 0;
|
||||
}
|
||||
|
||||
|
||||
static WCHAR *prepend_str( WCHAR *end, const WCHAR *str )
|
||||
{
|
||||
UINT len = wcslen( str );
|
||||
return memcpy( end - len, str, len * sizeof(WCHAR) );
|
||||
}
|
||||
|
||||
|
||||
/* format a positive number with decimal part; helper for get_number_format */
|
||||
static WCHAR *format_number( WCHAR *end, const WCHAR *value, const WCHAR *decimal_sep,
|
||||
const WCHAR *thousand_sep, const WCHAR *grouping, UINT digits, BOOL lzero )
|
||||
{
|
||||
const WCHAR *frac = NULL;
|
||||
BOOL round = FALSE;
|
||||
UINT i, len = 0;
|
||||
|
||||
*(--end) = 0;
|
||||
|
||||
for (i = 0; value[i]; i++)
|
||||
{
|
||||
if (value[i] >= '0' && value[i] <= '9') continue;
|
||||
if (value[i] != '.') return NULL;
|
||||
if (frac) return NULL;
|
||||
frac = value + i + 1;
|
||||
}
|
||||
|
||||
/* format fractional part */
|
||||
|
||||
len = frac ? wcslen( frac ) : 0;
|
||||
|
||||
if (len > digits)
|
||||
{
|
||||
round = frac[digits] >= '5';
|
||||
len = digits;
|
||||
}
|
||||
while (digits > len)
|
||||
{
|
||||
(*--end) = '0';
|
||||
digits--;
|
||||
}
|
||||
while (len)
|
||||
{
|
||||
WCHAR ch = frac[--len];
|
||||
if (round)
|
||||
{
|
||||
if (ch != '9')
|
||||
{
|
||||
ch++;
|
||||
round = FALSE;
|
||||
}
|
||||
else ch = '0';
|
||||
}
|
||||
*(--end) = ch;
|
||||
}
|
||||
if (*end) end = prepend_str( end, decimal_sep );
|
||||
|
||||
/* format integer part */
|
||||
|
||||
len = frac ? frac - value - 1 : wcslen( value );
|
||||
|
||||
while (len && *value == '0')
|
||||
{
|
||||
value++;
|
||||
len--;
|
||||
}
|
||||
if (len) lzero = FALSE;
|
||||
|
||||
while (len)
|
||||
{
|
||||
UINT limit = *grouping == '0' ? ~0u : *grouping - '0';
|
||||
while (len && limit--)
|
||||
{
|
||||
WCHAR ch = value[--len];
|
||||
if (round)
|
||||
{
|
||||
if (ch != '9')
|
||||
{
|
||||
ch++;
|
||||
round = FALSE;
|
||||
}
|
||||
else ch = '0';
|
||||
}
|
||||
*(--end) = ch;
|
||||
}
|
||||
if (len) end = prepend_str( end, thousand_sep );
|
||||
if (grouping[1] == ';') grouping += 2;
|
||||
}
|
||||
if (round) *(--end) = '1';
|
||||
else if (lzero) *(--end) = '0';
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
static int get_number_format( const NLS_LOCALE_DATA *locale, DWORD flags, const WCHAR *value,
|
||||
const NUMBERFMTW *format, WCHAR *buffer, int len )
|
||||
{
|
||||
WCHAR *num, fmt_decimal[4], fmt_thousand[4], fmt_neg[5], grouping[20], output[256];
|
||||
const WCHAR *decimal_sep = fmt_decimal, *thousand_sep = fmt_thousand;
|
||||
DWORD digits, lzero, order;
|
||||
int ret = 0;
|
||||
BOOL negative = (*value == '-');
|
||||
|
||||
flags &= LOCALE_NOUSEROVERRIDE;
|
||||
|
||||
if (!format)
|
||||
{
|
||||
get_locale_info( locale, 0, LOCALE_SGROUPING | flags, grouping, ARRAY_SIZE(grouping) );
|
||||
get_locale_info( locale, 0, LOCALE_SDECIMAL | flags, fmt_decimal, ARRAY_SIZE(fmt_decimal) );
|
||||
get_locale_info( locale, 0, LOCALE_STHOUSAND | flags, fmt_thousand, ARRAY_SIZE(fmt_thousand) );
|
||||
get_locale_info( locale, 0, LOCALE_IDIGITS | LOCALE_RETURN_NUMBER | flags,
|
||||
(WCHAR *)&digits, sizeof(DWORD)/sizeof(WCHAR) );
|
||||
get_locale_info( locale, 0, LOCALE_ILZERO | LOCALE_RETURN_NUMBER | flags,
|
||||
(WCHAR *)&lzero, sizeof(DWORD)/sizeof(WCHAR) );
|
||||
get_locale_info( locale, 0, LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER | flags,
|
||||
(WCHAR *)&order, sizeof(DWORD)/sizeof(WCHAR) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_FLAGS );
|
||||
return 0;
|
||||
}
|
||||
decimal_sep = format->lpDecimalSep;
|
||||
thousand_sep = format->lpThousandSep;
|
||||
grouping_to_string( format->Grouping, grouping );
|
||||
digits = format->NumDigits;
|
||||
lzero = format->LeadingZero;
|
||||
order = format->NegativeOrder;
|
||||
if (!decimal_sep || !thousand_sep)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (negative)
|
||||
{
|
||||
value++;
|
||||
get_locale_info( locale, 0, LOCALE_SNEGATIVESIGN | flags, fmt_neg, ARRAY_SIZE(fmt_neg) );
|
||||
}
|
||||
|
||||
if (!(num = format_number( output + ARRAY_SIZE(output) - 6, value,
|
||||
decimal_sep, thousand_sep, grouping, digits, lzero )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (negative)
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case 0: /* (1.1) */
|
||||
num = prepend_str( num, L"(" );
|
||||
wcscat( num, L")" );
|
||||
break;
|
||||
case 2: /* - 1.1 */
|
||||
num = prepend_str( num, L" " );
|
||||
/* fall through */
|
||||
case 1: /* -1.1 */
|
||||
num = prepend_str( num, fmt_neg );
|
||||
break;
|
||||
case 4: /* 1.1 - */
|
||||
wcscat( num, L" " );
|
||||
/* fall through */
|
||||
case 3: /* 1.1- */
|
||||
wcscat( num, fmt_neg );
|
||||
break;
|
||||
default:
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret = wcslen( num ) + 1;
|
||||
if (!len) return ret;
|
||||
lstrcpynW( buffer, num, len );
|
||||
if (ret > len)
|
||||
{
|
||||
SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetNumberFormatW (kernelbase.@)
|
||||
*/
|
||||
int WINAPI GetNumberFormatW( LCID lcid, DWORD flags, const WCHAR *value,
|
||||
const NUMBERFMTW *format, WCHAR *buffer, int len )
|
||||
{
|
||||
const NLS_LOCALE_DATA *locale = NlsValidateLocale( &lcid, 0 );
|
||||
|
||||
if (len < 0 || (len && !buffer) || !value || !locale)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRACE( "(%04lx,%lx,%s,%p,%p,%d)\n", lcid, flags, debugstr_w(value), format, buffer, len );
|
||||
return get_number_format( locale, flags, value, format, buffer, len );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* GetNumberFormatEx (kernelbase.@)
|
||||
*/
|
||||
int WINAPI GetNumberFormatEx( const WCHAR *name, DWORD flags, const WCHAR *value,
|
||||
const NUMBERFMTW *format, WCHAR *buffer, int len )
|
||||
{
|
||||
LCID lcid;
|
||||
const NLS_LOCALE_DATA *locale = get_locale_by_name( name, &lcid );
|
||||
|
||||
if (len < 0 || (len && !buffer) || !value || !locale)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRACE( "(%s,%lx,%s,%p,%p,%d)\n", debugstr_w(name), flags, debugstr_w(value), format, buffer, len );
|
||||
return get_number_format( locale, flags, value, format, buffer, len );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue