mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:45:44 +00:00
Bug patch 2382 by Zavyalov Alexey. GetCurrencyFormatW() added superfluous group sign in negative numbers and reformatting code.
svn path=/trunk/; revision=28441
This commit is contained in:
parent
d708f1133e
commit
e2e96c6bc8
1 changed files with 341 additions and 261 deletions
|
@ -1355,290 +1355,370 @@ INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags,
|
|||
LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat,
|
||||
LPWSTR lpCurrencyStr, int cchOut)
|
||||
{
|
||||
static const BYTE NLS_NegCyFormats[16] =
|
||||
{
|
||||
CF_PARENS|CF_CY_LEFT, /* ($1.1) */
|
||||
CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT, /* -$1.1 */
|
||||
CF_MINUS_LEFT|CF_CY_LEFT, /* $-1.1 */
|
||||
CF_MINUS_RIGHT|CF_CY_LEFT, /* $1.1- */
|
||||
CF_PARENS|CF_CY_RIGHT, /* (1.1$) */
|
||||
CF_MINUS_LEFT|CF_CY_RIGHT, /* -1.1$ */
|
||||
CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT, /* 1.1-$ */
|
||||
CF_MINUS_RIGHT|CF_CY_RIGHT, /* 1.1$- */
|
||||
CF_MINUS_LEFT|CF_CY_RIGHT|CF_CY_SPACE, /* -1.1 $ */
|
||||
CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT|CF_CY_SPACE, /* -$ 1.1 */
|
||||
CF_MINUS_RIGHT|CF_CY_RIGHT|CF_CY_SPACE, /* 1.1 $- */
|
||||
CF_MINUS_RIGHT|CF_CY_LEFT|CF_CY_SPACE, /* $ 1.1- */
|
||||
CF_MINUS_LEFT|CF_CY_LEFT|CF_CY_SPACE, /* $ -1.1 */
|
||||
CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT|CF_CY_SPACE, /* 1.1- $ */
|
||||
CF_PARENS|CF_CY_LEFT|CF_CY_SPACE, /* ($ 1.1) */
|
||||
CF_PARENS|CF_CY_RIGHT|CF_CY_SPACE, /* (1.1 $) */
|
||||
};
|
||||
static const BYTE NLS_PosCyFormats[4] =
|
||||
{
|
||||
CF_CY_LEFT, /* $1.1 */
|
||||
CF_CY_RIGHT, /* 1.1$ */
|
||||
CF_CY_LEFT|CF_CY_SPACE, /* $ 1.1 */
|
||||
CF_CY_RIGHT|CF_CY_SPACE, /* 1.1 $ */
|
||||
};
|
||||
WCHAR szBuff[128], *szOut = szBuff + sizeof(szBuff) / sizeof(WCHAR) - 1;
|
||||
WCHAR szNegBuff[8];
|
||||
const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc, *lpszCy, *lpszCyStart;
|
||||
DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0, dwFmt;
|
||||
INT iRet;
|
||||
|
||||
TRACE("(0x%04lx,0x%08lx,%S,%p,%p,%d)\n", lcid, dwFlags, lpszValue,
|
||||
lpFormat, lpCurrencyStr, cchOut);
|
||||
|
||||
if(NLS_isSystemLocale(lcid))
|
||||
{
|
||||
lcid = NLS_getDefaultLocale(lcid);
|
||||
}
|
||||
else if(!IsValidLocale(lcid, 0))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lpszValue || cchOut < 0 || (cchOut > 0 && !lpCurrencyStr) ||
|
||||
(lpFormat && (dwFlags || !lpFormat->lpDecimalSep || !lpFormat->lpThousandSep ||
|
||||
!lpFormat->lpCurrencySymbol || lpFormat->NegativeOrder > 15 ||
|
||||
lpFormat->PositiveOrder > 3)))
|
||||
{
|
||||
GetCurrencyFormatW_Error:
|
||||
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lpFormat)
|
||||
{
|
||||
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
|
||||
|
||||
if (!node)
|
||||
goto GetCurrencyFormatW_Error;
|
||||
lpFormat = &node->cyfmt;
|
||||
lpszNegStart = lpszNeg = GetNegative(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLocaleInfoW(lcid, LOCALE_SNEGATIVESIGN|(dwFlags & LOCALE_NOUSEROVERRIDE),
|
||||
szNegBuff, sizeof(szNegBuff)/sizeof(WCHAR));
|
||||
lpszNegStart = lpszNeg = szNegBuff;
|
||||
}
|
||||
dwFlags &= (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP);
|
||||
|
||||
lpszNeg = lpszNeg + strlenW(lpszNeg) - 1;
|
||||
lpszCyStart = lpFormat->lpCurrencySymbol;
|
||||
lpszCy = lpszCyStart + strlenW(lpszCyStart) - 1;
|
||||
|
||||
/* Format the currency backwards into a temporary buffer */
|
||||
|
||||
szSrc = lpszValue;
|
||||
*szOut-- = '\0';
|
||||
|
||||
/* Check the number for validity */
|
||||
while (*szSrc)
|
||||
{
|
||||
if (*szSrc >= '0' && *szSrc <= '9')
|
||||
static const BYTE NLS_NegCyFormats[16] =
|
||||
{
|
||||
dwState |= NF_DIGITS;
|
||||
if (dwState & NF_ISREAL)
|
||||
dwDecimals++;
|
||||
CF_PARENS|CF_CY_LEFT, /* ($1.1) */
|
||||
CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT, /* -$1.1 */
|
||||
CF_MINUS_LEFT|CF_CY_LEFT, /* $-1.1 */
|
||||
CF_MINUS_RIGHT|CF_CY_LEFT, /* $1.1- */
|
||||
CF_PARENS|CF_CY_RIGHT, /* (1.1$) */
|
||||
CF_MINUS_LEFT|CF_CY_RIGHT, /* -1.1$ */
|
||||
CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT, /* 1.1-$ */
|
||||
CF_MINUS_RIGHT|CF_CY_RIGHT, /* 1.1$- */
|
||||
CF_MINUS_LEFT|CF_CY_RIGHT|CF_CY_SPACE, /* -1.1 $ */
|
||||
CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT|CF_CY_SPACE, /* -$ 1.1 */
|
||||
CF_MINUS_RIGHT|CF_CY_RIGHT|CF_CY_SPACE, /* 1.1 $- */
|
||||
CF_MINUS_RIGHT|CF_CY_LEFT|CF_CY_SPACE, /* $ 1.1- */
|
||||
CF_MINUS_LEFT|CF_CY_LEFT|CF_CY_SPACE, /* $ -1.1 */
|
||||
CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT|CF_CY_SPACE, /* 1.1- $ */
|
||||
CF_PARENS|CF_CY_LEFT|CF_CY_SPACE, /* ($ 1.1) */
|
||||
CF_PARENS|CF_CY_RIGHT|CF_CY_SPACE, /* (1.1 $) */
|
||||
};
|
||||
static const BYTE NLS_PosCyFormats[4] =
|
||||
{
|
||||
CF_CY_LEFT, /* $1.1 */
|
||||
CF_CY_RIGHT, /* 1.1$ */
|
||||
CF_CY_LEFT|CF_CY_SPACE, /* $ 1.1 */
|
||||
CF_CY_RIGHT|CF_CY_SPACE, /* 1.1 $ */
|
||||
};
|
||||
|
||||
WCHAR szBuff[128], *szOut = szBuff + sizeof(szBuff) / sizeof(WCHAR) - 1;
|
||||
WCHAR szNegBuff[8];
|
||||
const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc, *lpszCy, *lpszCyStart;
|
||||
DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0, dwFmt;
|
||||
INT iRet;
|
||||
|
||||
DPRINT1("GetCurrencyFormatW(0x%04lx,0x%08lx,%S,%p,%p,%d)\n",
|
||||
lcid,
|
||||
dwFlags,
|
||||
lpszValue,
|
||||
lpFormat,
|
||||
lpCurrencyStr,
|
||||
cchOut);
|
||||
|
||||
if(NLS_isSystemLocale(lcid))
|
||||
{
|
||||
lcid = NLS_getDefaultLocale(lcid);
|
||||
}
|
||||
else if (*szSrc == '-')
|
||||
else if(!IsValidLocale(lcid, 0))
|
||||
{
|
||||
if (dwState)
|
||||
goto GetCurrencyFormatW_Error; /* '-' not first character */
|
||||
dwState |= NF_ISNEGATIVE;
|
||||
}
|
||||
else if (*szSrc == '.')
|
||||
{
|
||||
if (dwState & NF_ISREAL)
|
||||
goto GetCurrencyFormatW_Error; /* More than one '.' */
|
||||
dwState |= NF_ISREAL;
|
||||
}
|
||||
else
|
||||
goto GetCurrencyFormatW_Error; /* Invalid char */
|
||||
szSrc++;
|
||||
}
|
||||
szSrc--; /* Point to last character */
|
||||
|
||||
if (!(dwState & NF_DIGITS))
|
||||
goto GetCurrencyFormatW_Error; /* No digits */
|
||||
|
||||
if (dwState & NF_ISNEGATIVE)
|
||||
dwFmt = NLS_NegCyFormats[lpFormat->NegativeOrder];
|
||||
else
|
||||
dwFmt = NLS_PosCyFormats[lpFormat->PositiveOrder];
|
||||
|
||||
/* Add any trailing negative or currency signs */
|
||||
if (dwFmt & CF_PARENS)
|
||||
*szOut-- = ')';
|
||||
|
||||
while (dwFmt & (CF_MINUS_RIGHT|CF_CY_RIGHT))
|
||||
{
|
||||
switch (dwFmt & (CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT))
|
||||
{
|
||||
case CF_MINUS_RIGHT:
|
||||
case CF_MINUS_RIGHT|CF_CY_RIGHT:
|
||||
while (lpszNeg >= lpszNegStart)
|
||||
*szOut-- = *lpszNeg--;
|
||||
dwFmt &= ~CF_MINUS_RIGHT;
|
||||
break;
|
||||
|
||||
case CF_CY_RIGHT:
|
||||
case CF_MINUS_BEFORE|CF_CY_RIGHT:
|
||||
case CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT:
|
||||
while (lpszCy >= lpszCyStart)
|
||||
*szOut-- = *lpszCy--;
|
||||
if (dwFmt & CF_CY_SPACE)
|
||||
*szOut-- = ' ';
|
||||
dwFmt &= ~(CF_CY_RIGHT|CF_MINUS_BEFORE);
|
||||
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 + strlenW(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--;
|
||||
}
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dwState & NF_ISREAL)
|
||||
if (!lpszValue || cchOut < 0 || (cchOut > 0 && !lpCurrencyStr) ||
|
||||
(lpFormat && (dwFlags || !lpFormat->lpDecimalSep || !lpFormat->lpThousandSep ||
|
||||
!lpFormat->lpCurrencySymbol || lpFormat->NegativeOrder > 15 ||
|
||||
lpFormat->PositiveOrder > 3)))
|
||||
{
|
||||
while (*szSrc != '.')
|
||||
{
|
||||
if (dwState & NF_ROUND)
|
||||
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lpFormat)
|
||||
{
|
||||
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
|
||||
|
||||
if (!node)
|
||||
{
|
||||
if (*szSrc == '9')
|
||||
*szOut-- = '0'; /* continue rounding */
|
||||
else
|
||||
{
|
||||
dwState &= ~NF_ROUND;
|
||||
*szOut-- = (*szSrc)+1;
|
||||
}
|
||||
szSrc--;
|
||||
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
lpFormat = &node->cyfmt;
|
||||
lpszNegStart = lpszNeg = GetNegative(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLocaleInfoW(lcid,
|
||||
LOCALE_SNEGATIVESIGN | (dwFlags & LOCALE_NOUSEROVERRIDE),
|
||||
szNegBuff,
|
||||
sizeof(szNegBuff)/sizeof(WCHAR));
|
||||
lpszNegStart = lpszNeg = szNegBuff;
|
||||
}
|
||||
|
||||
dwFlags &= (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP);
|
||||
|
||||
lpszNeg = lpszNeg + strlenW(lpszNeg) - 1;
|
||||
lpszCyStart = lpFormat->lpCurrencySymbol;
|
||||
lpszCy = lpszCyStart + strlenW(lpszCyStart) - 1;
|
||||
|
||||
/* Format the currency 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) // '-' not first character
|
||||
{
|
||||
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
dwState |= NF_ISNEGATIVE;
|
||||
}
|
||||
else if (*szSrc == '.')
|
||||
{
|
||||
if (dwState & NF_ISREAL) // More than one '.'
|
||||
{
|
||||
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
dwState |= NF_ISREAL;
|
||||
}
|
||||
else // Invalid char
|
||||
{
|
||||
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
szSrc++;
|
||||
} // while (*szSrc)
|
||||
|
||||
szSrc--; // Point to last character
|
||||
|
||||
if (!(dwState & NF_DIGITS)) // No digits
|
||||
{
|
||||
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sel fmt table
|
||||
dwFmt = (dwState & NF_ISNEGATIVE)?NLS_NegCyFormats[lpFormat->NegativeOrder]:
|
||||
NLS_PosCyFormats[lpFormat->PositiveOrder];
|
||||
|
||||
// Add any trailing negative or currency signs
|
||||
if (dwFmt & CF_PARENS)
|
||||
{
|
||||
*szOut-- = ')';
|
||||
}
|
||||
|
||||
while (dwFmt & (CF_MINUS_RIGHT|CF_CY_RIGHT))
|
||||
{
|
||||
switch (dwFmt & (CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT))
|
||||
{
|
||||
case CF_MINUS_RIGHT: // Add right negative sign
|
||||
case CF_MINUS_RIGHT|CF_CY_RIGHT:
|
||||
while (lpszNeg >= lpszNegStart)
|
||||
{
|
||||
*szOut-- = *lpszNeg--;
|
||||
}
|
||||
dwFmt &= ~CF_MINUS_RIGHT;
|
||||
break;
|
||||
|
||||
case CF_CY_RIGHT: // Add right currency sign
|
||||
case CF_MINUS_BEFORE|CF_CY_RIGHT:
|
||||
case CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT:
|
||||
while (lpszCy >= lpszCyStart)
|
||||
{
|
||||
*szOut-- = *lpszCy--;
|
||||
}
|
||||
if (dwFmt & CF_CY_SPACE)
|
||||
{
|
||||
*szOut-- = ' ';
|
||||
}
|
||||
dwFmt &= ~(CF_CY_RIGHT|CF_MINUS_BEFORE);
|
||||
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 + strlenW(lpFormat->lpDecimalSep) - 1;
|
||||
|
||||
if (dwDecimals <= lpFormat->NumDigits)
|
||||
{
|
||||
dwDecimals = lpFormat->NumDigits - dwDecimals;
|
||||
while (dwDecimals--)
|
||||
{
|
||||
*szOut-- = '0'; // Pad to correct number of dp
|
||||
}
|
||||
}
|
||||
else
|
||||
*szOut-- = *szSrc--; /* Write existing decimals */
|
||||
}
|
||||
szSrc--; /* Skip '.' */
|
||||
{
|
||||
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
|
||||
}
|
||||
} // if (!lpFormat->NumDigits)
|
||||
|
||||
dwGroupCount = lpFormat->Grouping;
|
||||
// FIXME: windows XP support complicated grouping ie: "2;3;0"
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Group sep string
|
||||
LPWSTR lpszGrp = lpFormat->lpThousandSep +
|
||||
strlenW(lpFormat->lpThousandSep) - 1;
|
||||
|
||||
while (lpszGrp >= lpFormat->lpThousandSep)
|
||||
{
|
||||
*szOut-- = *lpszGrp--; // Write grouping char
|
||||
}
|
||||
|
||||
dwCurrentGroupCount = 0;
|
||||
}
|
||||
}
|
||||
while (lpszDec >= lpFormat->lpDecimalSep)
|
||||
*szOut-- = *lpszDec--; /* Write decimal separator */
|
||||
}
|
||||
|
||||
dwGroupCount = lpFormat->Grouping;
|
||||
// Correct negative result, delete unnecessary group sep
|
||||
if(dwState & NF_ISNEGATIVE)
|
||||
{
|
||||
szOut += strlenW(lpFormat->lpThousandSep);
|
||||
}
|
||||
|
||||
/* 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--;
|
||||
*szOut-- = '1'; // e.g. .6 > 1.0
|
||||
}
|
||||
else
|
||||
*szOut-- = *szSrc--;
|
||||
|
||||
dwState |= NF_DIGITS_OUT;
|
||||
dwCurrentGroupCount++;
|
||||
if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount)
|
||||
else if (!(dwState & NF_DIGITS_OUT) && lpFormat->LeadingZero)
|
||||
{
|
||||
LPWSTR lpszGrp = lpFormat->lpThousandSep + strlenW(lpFormat->lpThousandSep) - 1;
|
||||
|
||||
while (lpszGrp >= lpFormat->lpThousandSep)
|
||||
*szOut-- = *lpszGrp--; /* Write grouping char */
|
||||
|
||||
dwCurrentGroupCount = 0;
|
||||
*szOut-- = '0'; // Add leading 0 if we have no digits before the decimal point
|
||||
}
|
||||
}
|
||||
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 or currency sign */
|
||||
while (dwFmt & (CF_MINUS_LEFT|CF_CY_LEFT))
|
||||
{
|
||||
switch (dwFmt & (CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT))
|
||||
// Add any leading negative or currency sign
|
||||
while (dwFmt & (CF_MINUS_LEFT|CF_CY_LEFT))
|
||||
{
|
||||
case CF_MINUS_LEFT:
|
||||
case CF_MINUS_LEFT|CF_CY_LEFT:
|
||||
while (lpszNeg >= lpszNegStart)
|
||||
*szOut-- = *lpszNeg--;
|
||||
dwFmt &= ~CF_MINUS_LEFT;
|
||||
break;
|
||||
switch (dwFmt & (CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT))
|
||||
{
|
||||
case CF_MINUS_LEFT: // Add left negative sign
|
||||
case CF_MINUS_LEFT|CF_CY_LEFT:
|
||||
while (lpszNeg >= lpszNegStart)
|
||||
{
|
||||
*szOut-- = *lpszNeg--;
|
||||
}
|
||||
dwFmt &= ~CF_MINUS_LEFT;
|
||||
break;
|
||||
|
||||
case CF_CY_LEFT:
|
||||
case CF_CY_LEFT|CF_MINUS_BEFORE:
|
||||
case CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT:
|
||||
if (dwFmt & CF_CY_SPACE)
|
||||
*szOut-- = ' ';
|
||||
while (lpszCy >= lpszCyStart)
|
||||
*szOut-- = *lpszCy--;
|
||||
dwFmt &= ~(CF_CY_LEFT|CF_MINUS_BEFORE);
|
||||
break;
|
||||
case CF_CY_LEFT: // Add left currency sign
|
||||
case CF_CY_LEFT|CF_MINUS_BEFORE:
|
||||
case CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT:
|
||||
if (dwFmt & CF_CY_SPACE)
|
||||
{
|
||||
*szOut-- = ' ';
|
||||
}
|
||||
while (lpszCy >= lpszCyStart)
|
||||
{
|
||||
*szOut-- = *lpszCy--;
|
||||
}
|
||||
dwFmt &= ~(CF_CY_LEFT|CF_MINUS_BEFORE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dwFmt & CF_PARENS)
|
||||
*szOut-- = '(';
|
||||
szOut++;
|
||||
|
||||
iRet = strlenW(szOut) + 1;
|
||||
if (cchOut)
|
||||
{
|
||||
if (iRet <= cchOut)
|
||||
memcpy(lpCurrencyStr, szOut, iRet * sizeof(WCHAR));
|
||||
else
|
||||
|
||||
// Add left bracket
|
||||
if (dwFmt & CF_PARENS)
|
||||
{
|
||||
memcpy(lpCurrencyStr, szOut, cchOut * sizeof(WCHAR));
|
||||
lpCurrencyStr[cchOut - 1] = '\0';
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
iRet = 0;
|
||||
*szOut-- = '(';
|
||||
}
|
||||
}
|
||||
return iRet;
|
||||
szOut++;
|
||||
|
||||
iRet = strlenW(szOut) + 1;
|
||||
if (cchOut)
|
||||
{
|
||||
if (iRet <= cchOut)
|
||||
{
|
||||
memcpy(lpCurrencyStr, szOut, iRet * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(lpCurrencyStr, szOut, cchOut * sizeof(WCHAR));
|
||||
lpCurrencyStr[cchOut - 1] = '\0';
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
iRet = 0;
|
||||
}
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/* FIXME: Everything below here needs to move somewhere else along with the
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue