diff options
Diffstat (limited to 'sc/source/core/tool/interpr1.cxx')
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 160 |
1 files changed, 136 insertions, 24 deletions
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 73fc350328c0..8257afad926c 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -77,6 +77,8 @@ #define SC_DOUBLE_MAXVALUE 1.7e307 +static const sal_uInt64 n2power48 = SAL_CONST_UINT64( 281474976710656); // 2^48 + IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 ) IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 ) @@ -1449,6 +1451,107 @@ void ScInterpreter::ScNot() } +void ScInterpreter::ScBitAnd() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitAnd" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double num1 = ::rtl::math::approxFloor( GetDouble()); + double num2 = ::rtl::math::approxFloor( GetDouble()); + if ( (num1 >= n2power48) || (num1 < 0) || + (num2 >= n2power48) || (num2 < 0)) + PushIllegalArgument(); + else + PushDouble ((sal_uInt64) num1 & (sal_uInt64) num2); +} + + +void ScInterpreter::ScBitOr() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitOr" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double num1 = ::rtl::math::approxFloor( GetDouble()); + double num2 = ::rtl::math::approxFloor( GetDouble()); + if ( (num1 >= n2power48) || (num1 < 0) || + (num2 >= n2power48) || (num2 < 0)) + PushIllegalArgument(); + else + PushDouble ((sal_uInt64) num1 | (sal_uInt64) num2); +} + + +void ScInterpreter::ScBitXor() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitXor" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double num1 = ::rtl::math::approxFloor( GetDouble()); + double num2 = ::rtl::math::approxFloor( GetDouble()); + if ( (num1 >= n2power48) || (num1 < 0) || + (num2 >= n2power48) || (num2 < 0)) + PushIllegalArgument(); + else + PushDouble ((sal_uInt64) num1 ^ (sal_uInt64) num2); +} + + +void ScInterpreter::ScBitLshift() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitLshift" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double fShift = ::rtl::math::approxFloor( GetDouble()); + double num = ::rtl::math::approxFloor( GetDouble()); + if ((num >= n2power48) || (num < 0)) + PushIllegalArgument(); + else + { + double fRes; + if (fShift < 0) + fRes = ::rtl::math::approxFloor( num / pow( 2.0, -fShift)); + else if (fShift == 0) + fRes = num; + else + fRes = num * pow( 2.0, fShift); + PushDouble( fRes); + } +} + + +void ScInterpreter::ScBitRshift() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitRshift" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double fShift = ::rtl::math::approxFloor( GetDouble()); + double num = ::rtl::math::approxFloor( GetDouble()); + if ((num >= n2power48) || (num < 0)) + PushIllegalArgument(); + else + { + double fRes; + if (fShift < 0) + fRes = num * pow( 2.0, -fShift); + else if (fShift == 0) + fRes = num; + else + fRes = ::rtl::math::approxFloor( num / pow( 2.0, fShift)); + PushDouble( fRes); + } +} + + void ScInterpreter::ScPi() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPi" ); @@ -1912,7 +2015,6 @@ void ScInterpreter::ScCell() PushIllegalParameter(); else { - String aFuncResult; ScBaseCell* pCell = GetCell( aCellPos ); ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::GetLocale(), ocCell); @@ -1933,12 +2035,14 @@ void ScInterpreter::ScCell() else if( aInfoType.EqualsAscii( "ADDRESS" ) ) { // address formatted as [['FILENAME'#]$TABLE.]$COL$ROW sal_uInt16 nFlags = (aCellPos.Tab() == aPos.Tab()) ? (SCA_ABS) : (SCA_ABS_3D); - aCellPos.Format( aFuncResult, nFlags, pDok, pDok->GetAddressConvention() ); - PushString( aFuncResult ); + rtl::OUString aStr; + aCellPos.Format( aStr, nFlags, pDok, pDok->GetAddressConvention() ); + PushString(aStr); } else if( aInfoType.EqualsAscii( "FILENAME" ) ) { // file name and table name: 'FILENAME'#$TABLE SCTAB nTab = aCellPos.Tab(); + rtl::OUString aFuncResult; if( nTab < pDok->GetTableCount() ) { if( pDok->GetLinkMode( nTab ) == SC_LINK_VALUE ) @@ -1948,13 +2052,15 @@ void ScInterpreter::ScCell() SfxObjectShell* pShell = pDok->GetDocumentShell(); if( pShell && pShell->GetMedium() ) { - aFuncResult = (sal_Unicode) '\''; + rtl::OUStringBuffer aBuf; + aBuf.append(sal_Unicode('\'')); const INetURLObject& rURLObj = pShell->GetMedium()->GetURLObject(); - aFuncResult += String( rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ); - aFuncResult.AppendAscii( "'#$" ); - String aTabName; + aBuf.append(rURLObj.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS)); + aBuf.appendAscii("'#$"); + rtl::OUString aTabName; pDok->GetName( nTab, aTabName ); - aFuncResult += aTabName; + aBuf.append(aTabName); + aFuncResult = aBuf.makeStringAndClear(); } } } @@ -1963,14 +2069,16 @@ void ScInterpreter::ScCell() else if( aInfoType.EqualsAscii( "COORD" ) ) { // address, lotus 1-2-3 formatted: $TABLE:$COL$ROW // Yes, passing tab as col is intentional! + rtl::OUStringBuffer aFuncResult; + rtl::OUString aCellStr; ScAddress( static_cast<SCCOL>(aCellPos.Tab()), 0, 0 ).Format( - aFuncResult, (SCA_COL_ABSOLUTE|SCA_VALID_COL), NULL, pDok->GetAddressConvention() ); - aFuncResult += ':'; - String aCellStr; + aCellStr, (SCA_COL_ABSOLUTE|SCA_VALID_COL), NULL, pDok->GetAddressConvention() ); + aFuncResult.append(aCellStr); + aFuncResult.append(sal_Unicode(':')); aCellPos.Format( aCellStr, (SCA_COL_ABSOLUTE|SCA_VALID_COL|SCA_ROW_ABSOLUTE|SCA_VALID_ROW), NULL, pDok->GetAddressConvention() ); - aFuncResult += aCellStr; - PushString( aFuncResult ); + aFuncResult.append(aCellStr); + PushString( aFuncResult.makeStringAndClear() ); } // *** CELL PROPERTIES *** @@ -1978,19 +2086,21 @@ void ScInterpreter::ScCell() { // contents of the cell, no formatting if( pCell && pCell->HasStringData() ) { - GetCellString( aFuncResult, pCell ); - PushString( aFuncResult ); + String aStr; + GetCellString( aStr, pCell ); + PushString( aStr ); } else PushDouble( GetCellValue( aCellPos, pCell ) ); } else if( aInfoType.EqualsAscii( "TYPE" ) ) { // b = blank; l = string (label); v = otherwise (value) + sal_Unicode c; if( HasCellStringData( pCell ) ) - aFuncResult = 'l'; + c = 'l'; else - aFuncResult = HasCellValueData( pCell ) ? 'v' : 'b'; - PushString( aFuncResult ); + c = HasCellValueData( pCell ) ? 'v' : 'b'; + PushString( rtl::OUString(c) ); } else if( aInfoType.EqualsAscii( "WIDTH" ) ) { // column width (rounded off as count of zero characters in standard font and size) @@ -2011,6 +2121,7 @@ void ScInterpreter::ScCell() } else if( aInfoType.EqualsAscii( "PREFIX" ) ) { // ' = left; " = right; ^ = centered + sal_Unicode c = 0; if( HasCellStringData( pCell ) ) { const SvxHorJustifyItem* pJustAttr = (const SvxHorJustifyItem*) @@ -2019,13 +2130,13 @@ void ScInterpreter::ScCell() { case SVX_HOR_JUSTIFY_STANDARD: case SVX_HOR_JUSTIFY_LEFT: - case SVX_HOR_JUSTIFY_BLOCK: aFuncResult = '\''; break; - case SVX_HOR_JUSTIFY_CENTER: aFuncResult = '^'; break; - case SVX_HOR_JUSTIFY_RIGHT: aFuncResult = '"'; break; - case SVX_HOR_JUSTIFY_REPEAT: aFuncResult = '\\'; break; + case SVX_HOR_JUSTIFY_BLOCK: c = '\''; break; + case SVX_HOR_JUSTIFY_CENTER: c = '^'; break; + case SVX_HOR_JUSTIFY_RIGHT: c = '"'; break; + case SVX_HOR_JUSTIFY_REPEAT: c = '\\'; break; } } - PushString( aFuncResult ); + PushString( rtl::OUString(c) ); } else if( aInfoType.EqualsAscii( "PROTECT" ) ) { // 1 = cell locked @@ -2037,6 +2148,7 @@ void ScInterpreter::ScCell() // *** FORMATTING *** else if( aInfoType.EqualsAscii( "FORMAT" ) ) { // specific format code for standard formats + String aFuncResult; sal_uLong nFormat = pDok->GetNumberFormat( aCellPos ); bool bAppendPrec = true; sal_uInt16 nPrec, nLeading; @@ -6620,7 +6732,7 @@ void ScInterpreter::ScIndirect() } while (false); - PushIllegalArgument(); + PushError( errNoRef); } } } |