- 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:
parent
215bd9a70b
commit
b9208137c1
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue