Kaydet (Commit) 78f25d56 authored tarafından Arnaud Versini's avatar Arnaud Versini Kaydeden (comit) Stephan Bergmann

Basic : Partially rewrite hex and octal constant reading.

Change-Id: I42f72e7b1ca897aba71950841f90b501cf3b6dc2
Signed-off-by: 's avatarStephan Bergmann <sbergman@redhat.com>
üst 1fac7166
...@@ -417,17 +417,14 @@ bool SbiScanner::NextSym() ...@@ -417,17 +417,14 @@ bool SbiScanner::NextSym()
else if(nCol < aLine.getLength() && aLine[nCol] == '&') else if(nCol < aLine.getLength() && aLine[nCol] == '&')
{ {
++pLine; ++nCol; ++pLine; ++nCol;
sal_Unicode cmp1[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', 0 };
sal_Unicode cmp2[] = { '0', '1', '2', '3', '4', '5', '6', '7', 0 };
sal_Unicode *cmp = cmp1;
sal_Unicode base = 16; sal_Unicode base = 16;
sal_Unicode ndig = 8; sal_Unicode xch = aLine[nCol];
sal_Unicode xch = aLine[nCol] & 0xFF;
++pLine; ++nCol; ++pLine; ++nCol;
switch( toupper( xch ) ) switch( rtl::toAsciiUpperCase( xch ) )
{ {
case 'O': case 'O':
cmp = cmp2; base = 8; ndig = 11; break; base = 8;
break;
case 'H': case 'H':
break; break;
default : default :
...@@ -439,40 +436,34 @@ bool SbiScanner::NextSym() ...@@ -439,40 +436,34 @@ bool SbiScanner::NextSym()
bNumber = true; bNumber = true;
// Hex literals are signed Integers ( as defined by basic // Hex literals are signed Integers ( as defined by basic
// e.g. -2,147,483,648 through 2,147,483,647 (signed) // e.g. -2,147,483,648 through 2,147,483,647 (signed)
sal_uInt32 lu = 0; sal_uInt64 lu = 0;
bool bBufOverflow = false; bool bOverflow = false;
while(nCol < aLine.getLength() && theBasicCharClass::get().isAlphaNumeric(aLine[nCol] & 0xFF, bCompatible)) while(nCol < aLine.getLength() && theBasicCharClass::get().isAlphaNumeric(aLine[nCol], bCompatible))
{ {
sal_Unicode ch = sal::static_int_cast< sal_Unicode >( sal_Unicode ch = rtl::toAsciiUpperCase(aLine[nCol]);
toupper(aLine[nCol] & 0xFF));
++pLine; ++nCol; ++pLine; ++nCol;
// from 4.1.1996: buffer full, go on scanning empty if( ((base == 16 ) && rtl::isAsciiHexDigit( ch ) ) ||
if( (p-buf) == (BUF_SIZE-1) ) ((base == 8) && rtl::isAsciiOctalDigit( ch )))
bBufOverflow = true; {
else if( OUString( cmp ).indexOf( ch ) != -1 ) int i = ch - '0';
*p++ = ch; if( i > 9 ) i -= 7;
lu = ( lu * base ) + i;
if( lu > SAL_MAX_UINT32 )
{
bOverflow = true;
}
}
else else
{ {
aError = OUString(ch); aError = OUString(ch);
GenError( SbERR_BAD_CHAR_IN_NUMBER ); GenError( SbERR_BAD_CHAR_IN_NUMBER );
} }
} }
*p = 0;
for( p = buf; *p; ++p )
{
int i = (*p & 0xFF) - '0';
if( i > 9 ) i -= 7;
lu = ( lu * base ) + i;
if( !ndig-- )
{
GenError( SbERR_MATH_OVERFLOW ); break;
}
}
if(nCol < aLine.getLength() && aLine[nCol] == '&') ++pLine, ++nCol; if(nCol < aLine.getLength() && aLine[nCol] == '&') ++pLine, ++nCol;
sal_Int32 ls = static_cast<sal_Int32>(lu); sal_Int32 ls = static_cast<sal_Int32>(lu);
nVal = (double) ls; nVal = (double) ls;
eScanType = ( ls >= SbxMININT && ls <= SbxMAXINT ) ? SbxINTEGER : SbxLONG; eScanType = ( ls >= SbxMININT && ls <= SbxMAXINT ) ? SbxINTEGER : SbxLONG;
if( bBufOverflow ) if( bOverflow )
GenError( SbERR_MATH_OVERFLOW ); GenError( SbERR_MATH_OVERFLOW );
} }
......
...@@ -148,6 +148,21 @@ inline bool isAsciiHexDigit(sal_uInt32 code) ...@@ -148,6 +148,21 @@ inline bool isAsciiHexDigit(sal_uInt32 code)
return isAsciiCanonicHexDigit(code) || (code >= 'a' && code <= 'f'); return isAsciiCanonicHexDigit(code) || (code >= 'a' && code <= 'f');
} }
/** Check for ASCII octal digit character.
@param code A Unicode code point.
@return True if code is an ASCII octal digit character (ASCII '0'--'7').
@since LibreOffice 4.5
*/
inline bool isAsciiOctalDigit(sal_uInt32 code)
{
assert(code <= 0x10FFFF);
return code >= '0' && code <= '7';
}
/** Convert a character, if ASCII, to upper case. /** Convert a character, if ASCII, to upper case.
@param code A Unicode code point. @param code A Unicode code point.
......
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