From b9208137c15b1c244159e04385c722defc180a3a Mon Sep 17 00:00:00 2001 From: Michael Stefaniuc Date: Tue, 14 Jun 2005 11:39:32 +0000 Subject: [PATCH] - 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. --- dlls/oleaut32/tests/vartest.c | 39 +++++++++++++++++++++++++++ dlls/oleaut32/varformat.c | 51 ++++++++++++++++++++++++----------- 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c index bd4538a553d..5e5509e0efd 100644 --- a/dlls/oleaut32/tests/vartest.c +++ b/dlls/oleaut32/tests/vartest.c @@ -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 */ diff --git a/dlls/oleaut32/varformat.c b/dlls/oleaut32/varformat.c index a0fe61bf518..f5f8247b751 100644 --- a/dlls/oleaut32/varformat.c +++ b/dlls/oleaut32/varformat.c @@ -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 */