Commit b9208137 authored by Michael Stefaniuc's avatar Michael Stefaniuc Committed by Alexandre Julliard

- Fix VarFormat for formats that mix '0' and '#' in the whole number

part. - Fix VarFormat for negative exponent formats. - Add tests for the above + a couple of "todo_wine"'s.
parent 215bd9a7
......@@ -1711,6 +1711,45 @@ static void test_VarFormat(void)
/* Numeric values are converted to strings then output */
VARFMT(VT_I1,V_I1,1,"<&>&",S_OK,"1");
/* Number formats */
VARFMT(VT_I4,V_I4,1,"#00000000",S_OK,"00000001");
VARFMT(VT_I4,V_I4,1,"000###",S_OK,"000001");
VARFMT(VT_I4,V_I4,1,"#00##00#0",S_OK,"00000001");
VARFMT(VT_I4,V_I4,1,"1#####0000",S_OK,"10001");
VARFMT(VT_I4,V_I4,17,"#0",S_OK,"17");
VARFMT(VT_I4,V_I4,4711,"#0",S_OK,"4711");
VARFMT(VT_I4,V_I4,17,"#00",S_OK,"17");
VARFMT(VT_I4,V_I4,17,"#000",S_OK,"017");
VARFMT(VT_I4,V_I4,17,"#0.00",S_OK,"17.00");
VARFMT(VT_I4,V_I4,17,"#0000.00",S_OK,"0017.00");
VARFMT(VT_I4,V_I4,17,"#.00",S_OK,"17.00");
VARFMT(VT_R8,V_R8,1.7,"#.00",S_OK,"1.70");
VARFMT(VT_R8,V_R8,.17,"#.00",S_OK,".17");
VARFMT(VT_I4,V_I4,17,"#3",S_OK,"173");
VARFMT(VT_I4,V_I4,17,"#33",S_OK,"1733");
VARFMT(VT_I4,V_I4,17,"#3.33",S_OK,"173.33");
VARFMT(VT_I4,V_I4,17,"#3333.33",S_OK,"173333.33");
VARFMT(VT_I4,V_I4,17,"#.33",S_OK,"17.33");
VARFMT(VT_R8,V_R8,.17,"#.33",S_OK,".33");
VARFMT(VT_R8,V_R8,1.7,"0.0000E-000",S_OK,"1.7000E000");
VARFMT(VT_R8,V_R8,1.7,"0.0000e-1",S_OK,"1.7000e01");
VARFMT(VT_R8,V_R8,86.936849,"#0.000000000000e-000",S_OK,"86.936849000000e000");
todo_wine {
/* rounding */
VARFMT(VT_R8,V_R8,1.7,"#0",S_OK,"2");
VARFMT(VT_R8,V_R8,1.7,"#.33",S_OK,"2.33");
VARFMT(VT_R8,V_R8,1.7,"#3",S_OK,"23");
VARFMT(VT_R8,V_R8,1.73245,"0.0000E+000",S_OK,"1.7325E+000");
VARFMT(VT_R8,V_R8,9.9999999,"#0.000000",S_OK,"10.000000");
/* handling of numbers > 0 with exponent format */
VARFMT(VT_R8,V_R8,1.7,"0.0000e+0#",S_OK,"1.7000e+0");
VARFMT(VT_R8,V_R8,100.0001e+0,"0.0000E+0",S_OK,"1.0000E+2");
VARFMT(VT_R8,V_R8,1000001,"0.0000e+1",S_OK,"1.0000e+61");
VARFMT(VT_R8,V_R8,100.0001e+25,"0.0000e+0",S_OK,"1.0000e+27");
VARFMT(VT_R8,V_R8,450.0001e+43,"#000.0000e+0",S_OK,"4500.0010e+42");
}
/* 'out' is not cleared */
out = (BSTR)0x1;
pVarFormat(&in,NULL,fd,fw,flags,&out); /* Would crash if out is cleared */
......
......@@ -1183,13 +1183,14 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
/* Number formatting state flags */
#define NUM_WROTE_DEC 0x01 /* Written the decimal separator */
#define NUM_WRITE_ON 0x02 /* Started to write the number */
/* Format a variant using a number format */
static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
LPBYTE rgbTok, ULONG dwFlags,
BSTR *pbstrOut, LCID lcid)
{
BYTE rgbDig[256];
BYTE rgbDig[256], *prgbDig;
NUMPARSE np;
int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0;
WCHAR buff[256], *pBuff = buff;
......@@ -1240,7 +1241,7 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
/* An exactly represented real number e.g. 1.024 */
wholeNumberDigits = np.cDig + np.nPwr10;
fractionalDigits = np.cDig - wholeNumberDigits;
divisor10 = np.cDig - wholeNumberDigits;
divisor10 = 0;
}
}
else if (np.nPwr10 == 0)
......@@ -1306,6 +1307,7 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
}
pToken = (const BYTE*)numHeader + sizeof(FMT_NUMBER_HEADER);
prgbDig = rgbDig;
while (SUCCEEDED(hRes) && *pToken != FMT_GEN_END)
{
......@@ -1411,21 +1413,32 @@ VARIANT_FormatNumber_Bool:
TRACE("write %d fractional digits or skip\n", pToken[1]);
for (count = 0; count < fractionalDigits; count++)
pBuff[count] = '0' + rgbDig[wholeNumberDigits + count];
for (count = 0; count < fractionalDigits; count++, prgbDig++)
pBuff[count] = '0' + *prgbDig;
pBuff += fractionalDigits;
}
else
{
int count;
int count, count_max;
TRACE("write %d digits or skip\n", pToken[1]);
if (wholeNumberDigits > 1 || rgbDig[0] > 0)
numHeader->whole -= pToken[1];
count_max = wholeNumberDigits - numHeader->whole;
if (count_max < 0)
count_max = 0;
if (dwState & NUM_WRITE_ON) {
for (count = 0; count < pToken[1] - count_max; count++)
*pBuff++ = '0'; /* Write zeros, don't skip */
}
if (wholeNumberDigits > 1 || *prgbDig > 0)
{
TRACE("write %d whole number digits\n", wholeNumberDigits);
for (count = 0; count < wholeNumberDigits; count++)
*pBuff++ = '0' + rgbDig[count];
TRACE("write %d whole number digits\n", count_max);
for (count = 0; count < count_max; count++, prgbDig++) {
*pBuff++ = '0' + *prgbDig;
wholeNumberDigits--;
dwState |= NUM_WRITE_ON;
}
TRACE("write %d whole trailing 0's\n", multiplier10);
for (count = 0; count < multiplier10; count++)
*pBuff++ = '0'; /* Write trailing zeros for multiplied values */
......@@ -1441,8 +1454,8 @@ VARIANT_FormatNumber_Bool:
TRACE("write %d fractional digits or 0's\n", pToken[1]);
for (count = 0; count < fractionalDigits; count++)
pBuff[count] = '0' + rgbDig[wholeNumberDigits + count];
for (count = 0; count < fractionalDigits; count++, prgbDig++)
pBuff[count] = '0' + *prgbDig;
pBuff += fractionalDigits;
if (pToken[1] > fractionalDigits)
{
......@@ -1453,20 +1466,28 @@ VARIANT_FormatNumber_Bool:
}
else
{
int count;
int count, count_max;
TRACE("write %d digits or 0's\n", pToken[1]);
dwState |= NUM_WRITE_ON;
numHeader->whole -= pToken[1];
count_max = wholeNumberDigits + multiplier10 - numHeader->whole;
if (pToken[1] > (wholeNumberDigits + multiplier10))
{
count = pToken[1] - (wholeNumberDigits + multiplier10);
if (count_max > 0)
count = pToken[1] - (wholeNumberDigits + multiplier10);
else
count = pToken[1];
TRACE("write %d leading zeros\n", count);
while(count--)
*pBuff++ = '0'; /* Write leading zeros for missing digits */
}
TRACE("write %d whole number digits\n", wholeNumberDigits);
for (count = 0; count < wholeNumberDigits; count++)
*pBuff++ = '0' + rgbDig[count];
for (count = 0; count < count_max - multiplier10; count++, prgbDig++) {
*pBuff++ = '0' + *prgbDig;
wholeNumberDigits--;
}
TRACE("write %d whole trailing 0's\n", multiplier10);
for (count = 0; count < multiplier10; count++)
*pBuff++ = '0'; /* Write trailing zeros for multiplied values */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment