summaryrefslogtreecommitdiff
path: root/sc/source/core/tool/interpr1.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/tool/interpr1.cxx')
-rw-r--r--sc/source/core/tool/interpr1.cxx160
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);
}
}
}