clean up SbiScanner::NextSym() a little, fdo#70319 follow-up
Number recognition was suboptimal and didn't properly resync scan positions after having detected an error. Change-Id: I278fdaaf17ed40560785deaaad0e3412a249d90a
This commit is contained in:
parent
f85c494b53
commit
66a96c8274
@ -576,10 +576,12 @@ namespace
|
|||||||
CPPUNIT_ASSERT(errors == 0);
|
CPPUNIT_ASSERT(errors == 0);
|
||||||
|
|
||||||
symbols = getSymbols(source2, errors);
|
symbols = getSymbols(source2, errors);
|
||||||
CPPUNIT_ASSERT(symbols.size() == 2);
|
CPPUNIT_ASSERT(symbols.size() == 3);
|
||||||
CPPUNIT_ASSERT(symbols[0].number == 1.23);
|
CPPUNIT_ASSERT(symbols[0].number == 1.2);
|
||||||
CPPUNIT_ASSERT(symbols[0].type == SbxDOUBLE);
|
CPPUNIT_ASSERT(symbols[0].type == SbxDOUBLE);
|
||||||
CPPUNIT_ASSERT(symbols[1].text == cr);
|
CPPUNIT_ASSERT(rtl::math::round( symbols[1].number, 12) == rtl::math::round( .3, 12));
|
||||||
|
CPPUNIT_ASSERT(symbols[1].type == SbxDOUBLE);
|
||||||
|
CPPUNIT_ASSERT(symbols[2].text == cr);
|
||||||
CPPUNIT_ASSERT(errors == 1);
|
CPPUNIT_ASSERT(errors == 1);
|
||||||
|
|
||||||
symbols = getSymbols(source3, errors);
|
symbols = getSymbols(source3, errors);
|
||||||
@ -627,10 +629,11 @@ namespace
|
|||||||
CPPUNIT_ASSERT(errors == 0);
|
CPPUNIT_ASSERT(errors == 0);
|
||||||
|
|
||||||
symbols = getSymbols(source9, errors);
|
symbols = getSymbols(source9, errors);
|
||||||
CPPUNIT_ASSERT(symbols.size() == 2);
|
CPPUNIT_ASSERT(symbols.size() == 3);
|
||||||
CPPUNIT_ASSERT(symbols[0].number == 12000);
|
CPPUNIT_ASSERT(symbols[0].number == 12);
|
||||||
CPPUNIT_ASSERT(symbols[0].type == SbxDOUBLE);
|
CPPUNIT_ASSERT(symbols[0].type == SbxDOUBLE);
|
||||||
CPPUNIT_ASSERT(symbols[1].text == cr);
|
CPPUNIT_ASSERT(symbols[1].text == OUString("dE3"));
|
||||||
|
CPPUNIT_ASSERT(symbols[2].text == cr);
|
||||||
CPPUNIT_ASSERT(errors == 1);
|
CPPUNIT_ASSERT(errors == 1);
|
||||||
|
|
||||||
symbols = getSymbols(source10, errors);
|
symbols = getSymbols(source10, errors);
|
||||||
@ -647,16 +650,16 @@ namespace
|
|||||||
CPPUNIT_ASSERT(symbols[1].text == cr);
|
CPPUNIT_ASSERT(symbols[1].text == cr);
|
||||||
CPPUNIT_ASSERT(errors == 0);
|
CPPUNIT_ASSERT(errors == 0);
|
||||||
|
|
||||||
/* FIXME: SbiScanner::NextSym() is total crap, the result of scanning
|
|
||||||
* "12e++3" should be something different than this.. */
|
|
||||||
symbols = getSymbols(source12, errors);
|
symbols = getSymbols(source12, errors);
|
||||||
CPPUNIT_ASSERT(symbols.size() == 4);
|
CPPUNIT_ASSERT(symbols.size() == 6);
|
||||||
CPPUNIT_ASSERT(symbols[0].number == 12);
|
CPPUNIT_ASSERT(symbols[0].number == 12);
|
||||||
CPPUNIT_ASSERT(symbols[0].type == SbxDOUBLE);
|
CPPUNIT_ASSERT(symbols[0].type == SbxDOUBLE);
|
||||||
CPPUNIT_ASSERT(symbols[1].text == OUString("+"));
|
CPPUNIT_ASSERT(symbols[1].text == OUString("e"));
|
||||||
CPPUNIT_ASSERT(symbols[2].number == 3);
|
CPPUNIT_ASSERT(symbols[2].text == OUString("+"));
|
||||||
CPPUNIT_ASSERT(symbols[2].type == SbxINTEGER);
|
CPPUNIT_ASSERT(symbols[3].text == OUString("+"));
|
||||||
CPPUNIT_ASSERT(symbols[3].text == cr);
|
CPPUNIT_ASSERT(symbols[4].number == 3);
|
||||||
|
CPPUNIT_ASSERT(symbols[4].type == SbxINTEGER);
|
||||||
|
CPPUNIT_ASSERT(symbols[5].text == cr);
|
||||||
CPPUNIT_ASSERT(errors == 1);
|
CPPUNIT_ASSERT(errors == 1);
|
||||||
|
|
||||||
symbols = getSymbols(source13, errors);
|
symbols = getSymbols(source13, errors);
|
||||||
|
@ -302,12 +302,12 @@ bool SbiScanner::NextSym()
|
|||||||
(nCol + 1 < aLine.getLength() && aLine[nCol] == '.' && theBasicCharClass::get().isDigit(aLine[nCol + 1] & 0xFF)))
|
(nCol + 1 < aLine.getLength() && aLine[nCol] == '.' && theBasicCharClass::get().isDigit(aLine[nCol + 1] & 0xFF)))
|
||||||
{
|
{
|
||||||
short exp = 0;
|
short exp = 0;
|
||||||
short comma = 0;
|
short dec = 0;
|
||||||
short ndig = 0;
|
|
||||||
short ncdig = 0;
|
|
||||||
eScanType = SbxDOUBLE;
|
eScanType = SbxDOUBLE;
|
||||||
|
bool bScanError = false;
|
||||||
bool bBufOverflow = false;
|
bool bBufOverflow = false;
|
||||||
while(nCol < aLine.getLength() && strchr("0123456789.DEde", aLine[nCol]))
|
// All this because of 'D' or 'd' floating point type, sigh..
|
||||||
|
while(!bScanError && nCol < aLine.getLength() && strchr("0123456789.DEde", aLine[nCol]))
|
||||||
{
|
{
|
||||||
// from 4.1.1996: buffer full? -> go on scanning empty
|
// from 4.1.1996: buffer full? -> go on scanning empty
|
||||||
if( (p-buf) == (BUF_SIZE-1) )
|
if( (p-buf) == (BUF_SIZE-1) )
|
||||||
@ -319,64 +319,84 @@ bool SbiScanner::NextSym()
|
|||||||
// point or exponent?
|
// point or exponent?
|
||||||
if(aLine[nCol] == '.')
|
if(aLine[nCol] == '.')
|
||||||
{
|
{
|
||||||
if( ++comma > 1 )
|
if( ++dec > 1 )
|
||||||
{
|
bScanError = true;
|
||||||
++pLine; ++nCol; continue;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
*p++ = '.';
|
||||||
*p = '.';
|
|
||||||
++p, ++pLine, ++nCol;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(strchr("DdEe", aLine[nCol]))
|
else if(strchr("DdEe", aLine[nCol]))
|
||||||
{
|
{
|
||||||
if (++exp > 1)
|
if (++exp > 1)
|
||||||
|
bScanError = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p++ = 'E';
|
||||||
|
if (nCol + 1 < aLine.getLength() && (aLine[nCol+1] == '+' || aLine[nCol+1] == '-'))
|
||||||
{
|
{
|
||||||
++pLine; ++nCol; continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*p = 'E';
|
|
||||||
++p, ++pLine, ++nCol;
|
|
||||||
|
|
||||||
if(aLine[nCol] == '+')
|
|
||||||
++pLine, ++nCol;
|
++pLine, ++nCol;
|
||||||
else if(aLine[nCol] == '-')
|
if( (p-buf) == (BUF_SIZE-1) )
|
||||||
{
|
{
|
||||||
*p = '-';
|
bBufOverflow = true;
|
||||||
++p, ++pLine, ++nCol;
|
continue;
|
||||||
|
}
|
||||||
|
*p++ = aLine[nCol];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*p = aLine[nCol];
|
*p++ = aLine[nCol];
|
||||||
++p, ++pLine, ++nCol;
|
|
||||||
if( comma && !exp ) ++ncdig;
|
|
||||||
}
|
}
|
||||||
if (!exp) ++ndig;
|
++pLine, ++nCol;
|
||||||
}
|
}
|
||||||
*p = 0;
|
*p = 0;
|
||||||
aSym = p; bNumber = true;
|
aSym = p; bNumber = true;
|
||||||
|
|
||||||
if( comma > 1 || exp > 1 )
|
// For bad characters, scan and parse errors generate only one error.
|
||||||
{ aError = OUString('.');
|
SbError nError = 0;
|
||||||
GenError( SbERR_BAD_CHAR_IN_NUMBER ); }
|
if (bScanError)
|
||||||
|
{
|
||||||
|
--pLine, --nCol;
|
||||||
|
aError = OUString( aLine[nCol]);
|
||||||
|
nError = SbERR_BAD_CHAR_IN_NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
|
rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
|
||||||
const sal_Unicode* pParseEnd = buf;
|
const sal_Unicode* pParseEnd = buf;
|
||||||
nVal = rtl_math_uStringToDouble( buf, buf+(p-buf), '.', ',', &eStatus, &pParseEnd );
|
nVal = rtl_math_uStringToDouble( buf, buf+(p-buf), '.', ',', &eStatus, &pParseEnd );
|
||||||
if (eStatus != rtl_math_ConversionStatus_Ok || pParseEnd != buf+(p-buf))
|
if (pParseEnd != buf+(p-buf))
|
||||||
GenError( SbERR_MATH_OVERFLOW );
|
{
|
||||||
|
// e.g. "12e" or "12e+", or with bScanError "12d"+"E".
|
||||||
|
sal_Int32 nChars = buf+(p-buf) - pParseEnd;
|
||||||
|
pLine -= nChars;
|
||||||
|
nCol -= nChars;
|
||||||
|
// For bScanError, pLine and nCol were already decremented, just
|
||||||
|
// add that character to the parse end.
|
||||||
|
if (bScanError)
|
||||||
|
++nChars;
|
||||||
|
// Copy error position from original string, not the buffer
|
||||||
|
// replacement where "12dE" => "12EE".
|
||||||
|
aError = aLine.copy( nCol, nChars);
|
||||||
|
nError = SbERR_BAD_CHAR_IN_NUMBER;
|
||||||
|
}
|
||||||
|
else if (eStatus != rtl_math_ConversionStatus_Ok)
|
||||||
|
{
|
||||||
|
// Keep the scan error and character at position, if any.
|
||||||
|
if (!nError)
|
||||||
|
nError = SbERR_MATH_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
ndig = ndig - comma;
|
if (nError)
|
||||||
if( !comma && !exp )
|
GenError( nError );
|
||||||
|
|
||||||
|
if( !dec && !exp )
|
||||||
{
|
{
|
||||||
if( nVal >= SbxMININT && nVal <= SbxMAXINT )
|
if( nVal >= SbxMININT && nVal <= SbxMAXINT )
|
||||||
eScanType = SbxINTEGER;
|
eScanType = SbxINTEGER;
|
||||||
else
|
else if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
|
||||||
if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
|
|
||||||
eScanType = SbxLONG;
|
eScanType = SbxLONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bBufOverflow )
|
if( bBufOverflow )
|
||||||
GenError( SbERR_MATH_OVERFLOW );
|
GenError( SbERR_MATH_OVERFLOW );
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user