summaryrefslogtreecommitdiff
path: root/sc/source/core/tool/interpr4.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/tool/interpr4.cxx')
-rw-r--r--sc/source/core/tool/interpr4.cxx71
1 files changed, 41 insertions, 30 deletions
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 5c326001ff02..d248211fa7fe 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1,7 +1,7 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ *
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
@@ -198,11 +198,11 @@ double ScInterpreter::GetValueCellValue( const ScAddress& rPos, const ScValueCel
/** Convert string content to numeric value.
-
- Converted are only integer numbers including exponent, and ISO 8601 dates
- and times in their extended formats with separators. Anything else,
- especially fractional numeric values with decimal separators or dates other
- than ISO 8601 would be locale dependent and is a no-no. Leading and
+
+ Converted are only integer numbers including exponent, and ISO 8601 dates
+ and times in their extended formats with separators. Anything else,
+ especially fractional numeric values with decimal separators or dates other
+ than ISO 8601 would be locale dependent and is a no-no. Leading and
trailing blanks are ignored.
The following ISO 8601 formats are converted:
@@ -217,13 +217,13 @@ double ScInterpreter::GetValueCellValue( const ScAddress& rPos, const ScValueCel
hh:mm:ss,s
hh:mm:ss.s
- The century CC may not be omitted and the two-digit year setting is not
- taken into account. Instead of the T date and time separator exactly one
+ The century CC may not be omitted and the two-digit year setting is not
+ taken into account. Instead of the T date and time separator exactly one
blank may be used.
- If a date is given, it must be a valid Gregorian calendar date. In this
+ If a date is given, it must be a valid Gregorian calendar date. In this
case the optional time must be in the range 00:00 to 23:59:59.99999...
- If only time is given, it may have any value for hours, taking elapsed time
+ If only time is given, it may have any value for hours, taking elapsed time
into account; minutes and seconds are limited to the value 59 as well.
*/
@@ -231,16 +231,22 @@ double ScInterpreter::ConvertStringToValue( const String& rStr )
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ConvertStringToValue" );
double fValue = 0.0;
+ if (mnStringNoValueError == errCellNoValue)
+ {
+ // Requested that all strings result in 0, error handled by caller.
+ SetError( mnStringNoValueError);
+ return fValue;
+ }
::rtl::OUString aStr( rStr);
rtl_math_ConversionStatus eStatus;
sal_Int32 nParseEnd;
- // Decimal and group separator 0 => only integer and possibly exponent,
+ // Decimal and group separator 0 => only integer and possibly exponent,
// stops at first non-digit non-sign.
fValue = ::rtl::math::stringToDouble( aStr, 0, 0, &eStatus, &nParseEnd);
sal_Int32 nLen;
if (eStatus == rtl_math_ConversionStatus_Ok && nParseEnd < (nLen = aStr.getLength()))
{
- // Not at string end, check for trailing blanks or switch to date or
+ // Not at string end, check for trailing blanks or switch to date or
// time parsing or bail out.
const sal_Unicode* const pStart = aStr.getStr();
const sal_Unicode* p = pStart + nParseEnd;
@@ -264,8 +270,8 @@ double ScInterpreter::ConvertStringToValue( const String& rStr )
nCurFmtType = (bDate ? NUMBERFORMAT_DATE : NUMBERFORMAT_TIME);
nUnit[eState-1] = aStr.copy( 0, nParseEnd).toInt32();
const sal_Unicode* pLastStart = p;
- // Ensure there's no preceding sign. Negative dates
- // currently aren't handled correctly. Also discard
+ // Ensure there's no preceding sign. Negative dates
+ // currently aren't handled correctly. Also discard
// +CCYY-MM-DD
p = pStart;
while (p < pStop && *p == ' ')
@@ -293,12 +299,12 @@ double ScInterpreter::ConvertStringToValue( const String& rStr )
SetError( mnStringNoValueError);
}
pLastStart = p + 1; // hypothetical next start
- // Delimiters must match, a trailing delimiter
+ // Delimiters must match, a trailing delimiter
// yields an invalid date/time.
switch (eState)
{
case month:
- // Month must be followed by separator and
+ // Month must be followed by separator and
// day, no trailing blanks.
if (*p != '-' || (p+1 == pStop))
SetError( mnStringNoValueError);
@@ -306,11 +312,11 @@ double ScInterpreter::ConvertStringToValue( const String& rStr )
case day:
if ((*p != 'T' || (p+1 == pStop)) && *p != ' ')
SetError( mnStringNoValueError);
- // Take one blank as a valid delimiter
+ // Take one blank as a valid delimiter
// between date and time.
break;
case hour:
- // Hour must be followed by separator and
+ // Hour must be followed by separator and
// minute, no trailing blanks.
if (*p != ':' || (p+1 == pStop))
SetError( mnStringNoValueError);
@@ -372,13 +378,13 @@ double ScInterpreter::ConvertStringToValue( const String& rStr )
{
if (bDate && nUnit[day] == 0)
nUnit[day] = 1;
- double fFraction = (nUnit[fraction] <= 0 ? 0.0 :
+ double fFraction = (nUnit[fraction] <= 0 ? 0.0 :
::rtl::math::pow10Exp( nUnit[fraction],
static_cast<int>( -ceil( log10( static_cast<double>( nUnit[fraction]))))));
- fValue = (bDate ? GetDateSerial(
- sal::static_int_cast<INT16>(nUnit[year]),
- sal::static_int_cast<INT16>(nUnit[month]),
- sal::static_int_cast<INT16>(nUnit[day]),
+ fValue = (bDate ? GetDateSerial(
+ sal::static_int_cast<INT16>(nUnit[year]),
+ sal::static_int_cast<INT16>(nUnit[month]),
+ sal::static_int_cast<INT16>(nUnit[day]),
true) : 0.0);
fValue += ((nUnit[hour] * 3600) + (nUnit[minute] * 60) + nUnit[second] + fFraction) / 86400.0;
}
@@ -454,7 +460,7 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCel
case CELLTYPE_STRING:
case CELLTYPE_EDIT:
{
- // SUM(A1:A2) differs from A1+A2. No good. But people insist on
+ // SUM(A1:A2) differs from A1+A2. No good. But people insist on
// it ... #i5658#
String aStr;
if ( eType == CELLTYPE_STRING )
@@ -1230,7 +1236,7 @@ void ScInterpreter::DoubleRefToVars( const ScToken* p,
ScDBRangeBase* ScInterpreter::PopDoubleRef()
{
if (!sp)
- {
+ {
SetError(errUnknownStackVariable);
return NULL;
}
@@ -1247,9 +1253,9 @@ ScDBRangeBase* ScInterpreter::PopDoubleRef()
SCCOL nCol1, nCol2;
SCROW nRow1, nRow2;
SCTAB nTab1, nTab2;
- DoubleRefToVars(static_cast<ScToken*>(p),
+ DoubleRefToVars(static_cast<ScToken*>(p),
nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, false);
-
+
return new ScDBInternalRange(pDok,
ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
}
@@ -3720,8 +3726,8 @@ StackVar ScInterpreter::Interpret()
default : PushError( errUnknownOpCode); break;
}
- // If the function signalled that it pushed a subroutine on the
- // instruction code stack instead of a result, continue with
+ // If the function signalled that it pushed a subroutine on the
+ // instruction code stack instead of a result, continue with
// execution of the subroutine.
if (sp > nStackBase && pStack[sp-1]->GetOpCode() == ocCall)
{
@@ -3964,5 +3970,10 @@ StackVar ScInterpreter::Interpret()
while( maxsp-- )
(*p++)->DecRef();
- return xResult->GetType();
+ StackVar eType = xResult->GetType();
+ if (eType == svMatrix)
+ // Results are immutable in case they would be reused as input for new
+ // interpreters.
+ static_cast<ScToken*>(xResult.operator->())->GetMatrix()->SetImmutable( true);
+ return eType;
}