- 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.
This commit is contained in:
Michael Stefaniuc 2005-06-14 11:39:32 +00:00 committed by Alexandre Julliard
parent 215bd9a70b
commit b9208137c1
2 changed files with 75 additions and 15 deletions

View File

@ -1711,6 +1711,45 @@ static void test_VarFormat(void)
/* Numeric values are converted to strings then output */ /* Numeric values are converted to strings then output */
VARFMT(VT_I1,V_I1,1,"<&>&",S_OK,"1"); 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' is not cleared */
out = (BSTR)0x1; out = (BSTR)0x1;
pVarFormat(&in,NULL,fd,fw,flags,&out); /* Would crash if out is cleared */ pVarFormat(&in,NULL,fd,fw,flags,&out); /* Would crash if out is cleared */

View File

@ -1183,13 +1183,14 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
/* Number formatting state flags */ /* Number formatting state flags */
#define NUM_WROTE_DEC 0x01 /* Written the decimal separator */ #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 */ /* Format a variant using a number format */
static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat, static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
LPBYTE rgbTok, ULONG dwFlags, LPBYTE rgbTok, ULONG dwFlags,
BSTR *pbstrOut, LCID lcid) BSTR *pbstrOut, LCID lcid)
{ {
BYTE rgbDig[256]; BYTE rgbDig[256], *prgbDig;
NUMPARSE np; NUMPARSE np;
int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0; int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0;
WCHAR buff[256], *pBuff = buff; 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 */ /* An exactly represented real number e.g. 1.024 */
wholeNumberDigits = np.cDig + np.nPwr10; wholeNumberDigits = np.cDig + np.nPwr10;
fractionalDigits = np.cDig - wholeNumberDigits; fractionalDigits = np.cDig - wholeNumberDigits;
divisor10 = np.cDig - wholeNumberDigits; divisor10 = 0;
} }
} }
else if (np.nPwr10 == 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); pToken = (const BYTE*)numHeader + sizeof(FMT_NUMBER_HEADER);
prgbDig = rgbDig;
while (SUCCEEDED(hRes) && *pToken != FMT_GEN_END) while (SUCCEEDED(hRes) && *pToken != FMT_GEN_END)
{ {
@ -1411,21 +1413,32 @@ VARIANT_FormatNumber_Bool:
TRACE("write %d fractional digits or skip\n", pToken[1]); TRACE("write %d fractional digits or skip\n", pToken[1]);
for (count = 0; count < fractionalDigits; count++) for (count = 0; count < fractionalDigits; count++, prgbDig++)
pBuff[count] = '0' + rgbDig[wholeNumberDigits + count]; pBuff[count] = '0' + *prgbDig;
pBuff += fractionalDigits; pBuff += fractionalDigits;
} }
else else
{ {
int count; int count, count_max;
TRACE("write %d digits or skip\n", pToken[1]); 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); TRACE("write %d whole number digits\n", count_max);
for (count = 0; count < wholeNumberDigits; count++) for (count = 0; count < count_max; count++, prgbDig++) {
*pBuff++ = '0' + rgbDig[count]; *pBuff++ = '0' + *prgbDig;
wholeNumberDigits--;
dwState |= NUM_WRITE_ON;
}
TRACE("write %d whole trailing 0's\n", multiplier10); TRACE("write %d whole trailing 0's\n", multiplier10);
for (count = 0; count < multiplier10; count++) for (count = 0; count < multiplier10; count++)
*pBuff++ = '0'; /* Write trailing zeros for multiplied values */ *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]); TRACE("write %d fractional digits or 0's\n", pToken[1]);
for (count = 0; count < fractionalDigits; count++) for (count = 0; count < fractionalDigits; count++, prgbDig++)
pBuff[count] = '0' + rgbDig[wholeNumberDigits + count]; pBuff[count] = '0' + *prgbDig;
pBuff += fractionalDigits; pBuff += fractionalDigits;
if (pToken[1] > fractionalDigits) if (pToken[1] > fractionalDigits)
{ {
@ -1453,20 +1466,28 @@ VARIANT_FormatNumber_Bool:
} }
else else
{ {
int count; int count, count_max;
TRACE("write %d digits or 0's\n", pToken[1]); 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)) if (pToken[1] > (wholeNumberDigits + multiplier10))
{ {
if (count_max > 0)
count = pToken[1] - (wholeNumberDigits + multiplier10); count = pToken[1] - (wholeNumberDigits + multiplier10);
else
count = pToken[1];
TRACE("write %d leading zeros\n", count); TRACE("write %d leading zeros\n", count);
while(count--) while(count--)
*pBuff++ = '0'; /* Write leading zeros for missing digits */ *pBuff++ = '0'; /* Write leading zeros for missing digits */
} }
TRACE("write %d whole number digits\n", wholeNumberDigits); TRACE("write %d whole number digits\n", wholeNumberDigits);
for (count = 0; count < wholeNumberDigits; count++) for (count = 0; count < count_max - multiplier10; count++, prgbDig++) {
*pBuff++ = '0' + rgbDig[count]; *pBuff++ = '0' + *prgbDig;
wholeNumberDigits--;
}
TRACE("write %d whole trailing 0's\n", multiplier10); TRACE("write %d whole trailing 0's\n", multiplier10);
for (count = 0; count < multiplier10; count++) for (count = 0; count < multiplier10; count++)
*pBuff++ = '0'; /* Write trailing zeros for multiplied values */ *pBuff++ = '0'; /* Write trailing zeros for multiplied values */