1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "interpre.hxx"
22 #include <rangelst.hxx>
23 #include <sfx2/app.hxx>
24 #include <sfx2/docfile.hxx>
25 #include <sfx2/objsh.hxx>
26 #include <sfx2/docfilt.hxx>
27 #include <basic/sbmeth.hxx>
28 #include <basic/sbmod.hxx>
29 #include <basic/sbstar.hxx>
30 #include <basic/sbx.hxx>
31 #include <basic/sbxobj.hxx>
32 #include <basic/sbuno.hxx>
33 #include <svl/zforlist.hxx>
34 #include "svl/sharedstringpool.hxx"
39 #include <com/sun/star/table/XCellRange.hpp>
40 #include <com/sun/star/sheet/XSheetCellRange.hpp>
41 #include <comphelper/processfactory.hxx>
45 #include "formulacell.hxx"
46 #include "callform.hxx"
47 #include "addincol.hxx"
48 #include "document.hxx"
49 #include "dociter.hxx"
50 #include "docoptio.hxx"
51 #include "scmatrix.hxx"
52 #include "adiasync.hxx"
54 #include "cellsuno.hxx"
56 #include "rangeseq.hxx"
57 #include "addinlis.hxx"
58 #include "jumpmatrix.hxx"
59 #include "parclass.hxx"
60 #include "externalrefmgr.hxx"
61 #include "formula/FormulaCompiler.hxx"
62 #include "macromgr.hxx"
63 #include "doubleref.hxx"
64 #include "queryparam.hxx"
65 #include "tokenarray.hxx"
72 #include <basic/basmgr.hxx>
73 #include <vbahelper/vbaaccesshelper.hxx>
76 using namespace com::sun::star
;
77 using namespace formula
;
78 using ::std::auto_ptr
;
80 #define ADDIN_MAXSTRLEN 256
82 //-----------------------------static data -----------------
84 //-------------------------------------------------------------------------
85 // Funktionen fuer den Zugriff auf das Document
86 //-------------------------------------------------------------------------
89 void ScInterpreter::ReplaceCell( ScAddress
& rPos
)
91 size_t ListSize
= pDok
->aTableOpList
.size();
92 for ( size_t i
= 0; i
< ListSize
; ++i
)
94 ScInterpreterTableOpParams
* pTOp
= &pDok
->aTableOpList
[ i
];
95 if ( rPos
== pTOp
->aOld1
)
100 else if ( rPos
== pTOp
->aOld2
)
109 void ScInterpreter::ReplaceCell( SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
)
111 ScAddress
aCellPos( rCol
, rRow
, rTab
);
112 size_t ListSize
= pDok
->aTableOpList
.size();
113 for ( size_t i
= 0; i
< ListSize
; ++i
)
115 ScInterpreterTableOpParams
* pTOp
= &pDok
->aTableOpList
[ i
];
116 if ( aCellPos
== pTOp
->aOld1
)
118 rCol
= pTOp
->aNew1
.Col();
119 rRow
= pTOp
->aNew1
.Row();
120 rTab
= pTOp
->aNew1
.Tab();
123 else if ( aCellPos
== pTOp
->aOld2
)
125 rCol
= pTOp
->aNew2
.Col();
126 rRow
= pTOp
->aNew2
.Row();
127 rTab
= pTOp
->aNew2
.Tab();
134 bool ScInterpreter::IsTableOpInRange( const ScRange
& rRange
)
136 if ( rRange
.aStart
== rRange
.aEnd
)
137 return false; // not considered to be a range in TableOp sense
139 // we can't replace a single cell in a range
140 size_t ListSize
= pDok
->aTableOpList
.size();
141 for ( size_t i
= 0; i
< ListSize
; ++i
)
143 ScInterpreterTableOpParams
* pTOp
= &pDok
->aTableOpList
[ i
];
144 if ( rRange
.In( pTOp
->aOld1
) )
146 if ( rRange
.In( pTOp
->aOld2
) )
153 sal_uLong
ScInterpreter::GetCellNumberFormat( const ScAddress
& rPos
, ScRefCellValue
& rCell
)
159 nFormat
= pDok
->GetNumberFormat( rPos
);
164 if (rCell
.meType
== CELLTYPE_FORMULA
)
165 nErr
= rCell
.mpFormula
->GetErrCode();
168 nFormat
= pDok
->GetNumberFormat( rPos
);
176 /// Only ValueCell, formula cells already store the result rounded.
177 double ScInterpreter::GetValueCellValue( const ScAddress
& rPos
, double fOrig
)
179 if ( bCalcAsShown
&& fOrig
!= 0.0 )
181 sal_uLong nFormat
= pDok
->GetNumberFormat( rPos
);
182 fOrig
= pDok
->RoundValueAsShown( fOrig
, nFormat
);
187 sal_uInt16
ScInterpreter::GetCellErrCode( const ScRefCellValue
& rCell
)
189 return rCell
.meType
== CELLTYPE_FORMULA
? rCell
.mpFormula
->GetErrCode() : 0;
192 /** Convert string content to numeric value.
194 Converted are only integer numbers including exponent, and ISO 8601 dates
195 and times in their extended formats with separators. Anything else,
196 especially fractional numeric values with decimal separators or dates other
197 than ISO 8601 would be locale dependent and is a no-no. Leading and
198 trailing blanks are ignored.
200 The following ISO 8601 formats are converted:
205 CCYY-MM-DDThh:mm:ss,s
206 CCYY-MM-DDThh:mm:ss.s
212 The century CC may not be omitted and the two-digit year setting is not
213 taken into account. Instead of the T date and time separator exactly one
216 If a date is given, it must be a valid Gregorian calendar date. In this
217 case the optional time must be in the range 00:00 to 23:59:59.99999...
218 If only time is given, it may have any value for hours, taking elapsed time
219 into account; minutes and seconds are limited to the value 59 as well.
222 double ScInterpreter::ConvertStringToValue( const OUString
& rStr
)
225 // We keep this code until we provide a friendly way to convert string
226 // numbers into numbers in the UI.
228 if (mnStringNoValueError
== errCellNoValue
)
230 // Requested that all strings result in 0, error handled by caller.
231 SetError( mnStringNoValueError
);
235 if (GetGlobalConfig().mbEmptyStringAsZero
)
237 // The number scanner does not accept empty strings or strings
238 // containing only spaces, be on par in these cases with what was
239 // accepted in OOo and is in AOO (see also the else branch below) and
240 // convert to 0 to prevent interoperability nightmares.
243 else if (rStr
[0] == ' ')
245 const sal_Unicode
* p
= rStr
.getStr() + 1;
246 const sal_Unicode
* const pStop
= p
- 1 + rStr
.getLength();
247 while (p
< pStop
&& *p
== ' ')
254 sal_uInt32 nFIndex
= 0;
255 if (!pFormatter
->IsNumberFormat(rStr
, nFIndex
, fValue
))
257 SetError( mnStringNoValueError
);
263 if (mnStringNoValueError
== errCellNoValue
)
265 // Requested that all strings result in 0, error handled by caller.
266 SetError( mnStringNoValueError
);
269 OUString
aStr( rStr
);
270 rtl_math_ConversionStatus eStatus
;
272 // Decimal and group separator 0 => only integer and possibly exponent,
273 // stops at first non-digit non-sign.
274 fValue
= ::rtl::math::stringToDouble( aStr
, 0, 0, &eStatus
, &nParseEnd
);
276 if (eStatus
== rtl_math_ConversionStatus_Ok
&& nParseEnd
< (nLen
= aStr
.getLength()))
278 // Not at string end, check for trailing blanks or switch to date or
279 // time parsing or bail out.
280 const sal_Unicode
* const pStart
= aStr
.getStr();
281 const sal_Unicode
* p
= pStart
+ nParseEnd
;
282 const sal_Unicode
* const pStop
= pStart
+ nLen
;
286 while (p
< pStop
&& *p
== ' ')
289 SetError( mnStringNoValueError
);
294 bool bDate
= (*(p
-1) == '-');
295 enum State
{ year
= 0, month
, day
, hour
, minute
, second
, fraction
, done
, blank
, stop
};
296 sal_Int32 nUnit
[done
] = {0,0,0,0,0,0,0};
297 const sal_Int32 nLimit
[done
] = {0,12,31,0,59,59,0};
298 State eState
= (bDate
? month
: minute
);
299 nCurFmtType
= (bDate
? NUMBERFORMAT_DATE
: NUMBERFORMAT_TIME
);
300 nUnit
[eState
-1] = aStr
.copy( 0, nParseEnd
).toInt32();
301 const sal_Unicode
* pLastStart
= p
;
302 // Ensure there's no preceding sign. Negative dates
303 // currently aren't handled correctly. Also discard
306 while (p
< pStop
&& *p
== ' ')
308 if (p
< pStop
&& !CharClass::isAsciiDigit(*p
))
309 SetError( mnStringNoValueError
);
311 while (p
< pStop
&& !nGlobalError
&& eState
< blank
)
313 if (eState
== minute
)
314 nCurFmtType
|= NUMBERFORMAT_TIME
;
315 if (CharClass::isAsciiDigit(*p
))
317 // Maximum 2 digits per unit, except fractions.
318 if (p
- pLastStart
>= 2 && eState
!= fraction
)
319 SetError( mnStringNoValueError
);
321 else if (p
> pLastStart
)
323 // We had at least one digit.
326 nUnit
[eState
] = aStr
.copy( pLastStart
- pStart
, p
- pLastStart
).toInt32();
327 if (nLimit
[eState
] && nLimit
[eState
] < nUnit
[eState
])
328 SetError( mnStringNoValueError
);
330 pLastStart
= p
+ 1; // hypothetical next start
331 // Delimiters must match, a trailing delimiter
332 // yields an invalid date/time.
336 // Month must be followed by separator and
337 // day, no trailing blanks.
338 if (*p
!= '-' || (p
+1 == pStop
))
339 SetError( mnStringNoValueError
);
342 if ((*p
!= 'T' || (p
+1 == pStop
)) && *p
!= ' ')
343 SetError( mnStringNoValueError
);
344 // Take one blank as a valid delimiter
345 // between date and time.
348 // Hour must be followed by separator and
349 // minute, no trailing blanks.
350 if (*p
!= ':' || (p
+1 == pStop
))
351 SetError( mnStringNoValueError
);
354 if ((*p
!= ':' || (p
+1 == pStop
)) && *p
!= ' ')
355 SetError( mnStringNoValueError
);
360 if (((*p
!= ',' && *p
!= '.') || (p
+1 == pStop
)) && *p
!= ' ')
361 SetError( mnStringNoValueError
);
372 SetError( mnStringNoValueError
);
375 eState
= static_cast<State
>(eState
+ 1);
378 SetError( mnStringNoValueError
);
383 while (p
< pStop
&& *p
== ' ')
386 SetError( mnStringNoValueError
);
390 // Month without day, or hour without minute.
391 if (eState
== month
|| (eState
== day
&& p
<= pLastStart
) ||
392 eState
== hour
|| (eState
== minute
&& p
<= pLastStart
))
393 SetError( mnStringNoValueError
);
397 // Catch the very last unit at end of string.
398 if (p
> pLastStart
&& eState
< done
)
400 nUnit
[eState
] = aStr
.copy( pLastStart
- pStart
, p
- pLastStart
).toInt32();
401 if (nLimit
[eState
] && nLimit
[eState
] < nUnit
[eState
])
402 SetError( mnStringNoValueError
);
404 if (bDate
&& nUnit
[hour
] > 23)
405 SetError( mnStringNoValueError
);
408 if (bDate
&& nUnit
[day
] == 0)
410 double fFraction
= (nUnit
[fraction
] <= 0 ? 0.0 :
411 ::rtl::math::pow10Exp( nUnit
[fraction
],
412 static_cast<int>( -ceil( log10( static_cast<double>( nUnit
[fraction
]))))));
413 fValue
= (bDate
? GetDateSerial(
414 sal::static_int_cast
<sal_Int16
>(nUnit
[year
]),
415 sal::static_int_cast
<sal_Int16
>(nUnit
[month
]),
416 sal::static_int_cast
<sal_Int16
>(nUnit
[day
]),
418 fValue
+= ((nUnit
[hour
] * 3600) + (nUnit
[minute
] * 60) + nUnit
[second
] + fFraction
) / 86400.0;
424 SetError( mnStringNoValueError
);
433 double ScInterpreter::GetCellValue( const ScAddress
& rPos
, ScRefCellValue
& rCell
)
435 sal_uInt16 nErr
= nGlobalError
;
437 double nVal
= GetCellValueOrZero(rPos
, rCell
);
438 if ( !nGlobalError
|| nGlobalError
== errCellNoValue
)
443 double ScInterpreter::GetCellValueOrZero( const ScAddress
& rPos
, ScRefCellValue
& rCell
)
447 CellType eType
= rCell
.meType
;
450 case CELLTYPE_FORMULA
:
452 ScFormulaCell
* pFCell
= rCell
.mpFormula
;
453 sal_uInt16 nErr
= pFCell
->GetErrCode();
456 if (pFCell
->IsValue())
458 fValue
= pFCell
->GetValue();
459 pDok
->GetNumberFormatInfo( nCurFmtType
, nCurFmtIndex
,
464 fValue
= ConvertStringToValue(pFCell
->GetString().getString());
476 fValue
= rCell
.mfValue
;
477 nCurFmtIndex
= pDok
->GetNumberFormat( rPos
);
478 nCurFmtType
= pFormatter
->GetType( nCurFmtIndex
);
479 if ( bCalcAsShown
&& fValue
!= 0.0 )
480 fValue
= pDok
->RoundValueAsShown( fValue
, nCurFmtIndex
);
483 case CELLTYPE_STRING
:
486 // SUM(A1:A2) differs from A1+A2. No good. But people insist on
488 OUString aStr
= rCell
.getString(pDok
);
489 fValue
= ConvertStringToValue( aStr
);
493 fValue
= 0.0; // empty or broadcaster cell
500 void ScInterpreter::GetCellString( svl::SharedString
& rStr
, ScRefCellValue
& rCell
)
504 switch (rCell
.meType
)
506 case CELLTYPE_STRING
:
508 rStr
= mrStrPool
.intern(rCell
.getString(pDok
));
510 case CELLTYPE_FORMULA
:
512 ScFormulaCell
* pFCell
= rCell
.mpFormula
;
513 nErr
= pFCell
->GetErrCode();
514 if (pFCell
->IsValue())
516 double fVal
= pFCell
->GetValue();
517 sal_uLong nIndex
= pFormatter
->GetStandardFormat(
521 pFormatter
->GetInputLineString(fVal
, nIndex
, aStr
);
522 rStr
= mrStrPool
.intern(aStr
);
525 rStr
= pFCell
->GetString();
530 double fVal
= rCell
.mfValue
;
531 sal_uLong nIndex
= pFormatter
->GetStandardFormat(
535 pFormatter
->GetInputLineString(fVal
, nIndex
, aStr
);
536 rStr
= mrStrPool
.intern(aStr
);
540 rStr
= svl::SharedString::getEmptyString();
547 bool ScInterpreter::CreateDoubleArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
548 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, sal_uInt8
* pCellArr
)
551 // Old Add-Ins are hard limited to sal_uInt16 values.
552 #if MAXCOLCOUNT_DEFINE > USHRT_MAX
553 #error Add check for columns > USHRT_MAX!
555 if (nRow1
> USHRT_MAX
|| nRow2
> USHRT_MAX
)
558 sal_uInt16 nCount
= 0;
559 sal_uInt16
* p
= (sal_uInt16
*) pCellArr
;
560 *p
++ = static_cast<sal_uInt16
>(nCol1
);
561 *p
++ = static_cast<sal_uInt16
>(nRow1
);
562 *p
++ = static_cast<sal_uInt16
>(nTab1
);
563 *p
++ = static_cast<sal_uInt16
>(nCol2
);
564 *p
++ = static_cast<sal_uInt16
>(nRow2
);
565 *p
++ = static_cast<sal_uInt16
>(nTab2
);
566 sal_uInt16
* pCount
= p
;
568 sal_uInt16 nPos
= 14;
571 while (nTab
<= nTab2
)
575 while (nRow
<= nRow2
)
579 while (nCol
<= nCol2
)
583 ScRefCellValue aCell
;
584 aCell
.assign(*pDok
, aAdr
);
585 if (!aCell
.isEmpty())
590 switch (aCell
.meType
)
592 case CELLTYPE_VALUE
:
593 nVal
= GetValueCellValue(aAdr
, aCell
.mfValue
);
595 case CELLTYPE_FORMULA
:
596 if (aCell
.mpFormula
->IsValue())
598 nErr
= aCell
.mpFormula
->GetErrCode();
599 nVal
= aCell
.mpFormula
->GetValue();
610 if ((nPos
+ (4 * sizeof(sal_uInt16
)) + sizeof(double)) > MAXARRSIZE
)
612 *p
++ = static_cast<sal_uInt16
>(nCol
);
613 *p
++ = static_cast<sal_uInt16
>(nRow
);
614 *p
++ = static_cast<sal_uInt16
>(nTab
);
616 memcpy( p
, &nVal
, sizeof(double));
617 nPos
+= 8 + sizeof(double);
618 p
= (sal_uInt16
*) ( pCellArr
+ nPos
);
633 bool ScInterpreter::CreateStringArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
634 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
638 // Old Add-Ins are hard limited to sal_uInt16 values.
639 #if MAXCOLCOUNT_DEFINE > USHRT_MAX
640 #error Add check for columns > USHRT_MAX!
642 if (nRow1
> USHRT_MAX
|| nRow2
> USHRT_MAX
)
645 sal_uInt16 nCount
= 0;
646 sal_uInt16
* p
= (sal_uInt16
*) pCellArr
;
647 *p
++ = static_cast<sal_uInt16
>(nCol1
);
648 *p
++ = static_cast<sal_uInt16
>(nRow1
);
649 *p
++ = static_cast<sal_uInt16
>(nTab1
);
650 *p
++ = static_cast<sal_uInt16
>(nCol2
);
651 *p
++ = static_cast<sal_uInt16
>(nRow2
);
652 *p
++ = static_cast<sal_uInt16
>(nTab2
);
653 sal_uInt16
* pCount
= p
;
655 sal_uInt16 nPos
= 14;
657 while (nTab
<= nTab2
)
660 while (nRow
<= nRow2
)
663 while (nCol
<= nCol2
)
665 ScRefCellValue aCell
;
666 aCell
.assign(*pDok
, ScAddress(nCol
, nRow
, nTab
));
667 if (!aCell
.isEmpty())
672 switch (aCell
.meType
)
674 case CELLTYPE_STRING
:
676 aStr
= aCell
.getString(pDok
);
678 case CELLTYPE_FORMULA
:
679 if (!aCell
.mpFormula
->IsValue())
681 nErr
= aCell
.mpFormula
->GetErrCode();
682 aStr
= aCell
.mpFormula
->GetString().getString();
693 OString
aTmp(OUStringToOString(aStr
,
694 osl_getThreadTextEncoding()));
695 // In case the xub_StrLen will be longer than USHORT
696 // one day, and room for pad byte check.
697 if ( aTmp
.getLength() > ((sal_uInt16
)(~0)) - 2 )
699 // Append a 0-pad-byte if string length is not even
700 //! MUST be sal_uInt16 and not xub_StrLen
701 sal_uInt16 nStrLen
= (sal_uInt16
) aTmp
.getLength();
702 sal_uInt16 nLen
= ( nStrLen
+ 2 ) & ~1;
704 if (((sal_uLong
)nPos
+ (5 * sizeof(sal_uInt16
)) + nLen
) > MAXARRSIZE
)
706 *p
++ = static_cast<sal_uInt16
>(nCol
);
707 *p
++ = static_cast<sal_uInt16
>(nRow
);
708 *p
++ = static_cast<sal_uInt16
>(nTab
);
711 memcpy( p
, aTmp
.getStr(), nStrLen
+ 1);
712 nPos
+= 10 + nStrLen
+ 1;
713 sal_uInt8
* q
= ( pCellArr
+ nPos
);
716 p
= (sal_uInt16
*) ( pCellArr
+ nPos
);
731 bool ScInterpreter::CreateCellArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
732 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
736 // Old Add-Ins are hard limited to sal_uInt16 values.
737 #if MAXCOLCOUNT_DEFINE > USHRT_MAX
738 #error Add check for columns > USHRT_MAX!
740 if (nRow1
> USHRT_MAX
|| nRow2
> USHRT_MAX
)
743 sal_uInt16 nCount
= 0;
744 sal_uInt16
* p
= (sal_uInt16
*) pCellArr
;
745 *p
++ = static_cast<sal_uInt16
>(nCol1
);
746 *p
++ = static_cast<sal_uInt16
>(nRow1
);
747 *p
++ = static_cast<sal_uInt16
>(nTab1
);
748 *p
++ = static_cast<sal_uInt16
>(nCol2
);
749 *p
++ = static_cast<sal_uInt16
>(nRow2
);
750 *p
++ = static_cast<sal_uInt16
>(nTab2
);
751 sal_uInt16
* pCount
= p
;
753 sal_uInt16 nPos
= 14;
756 while (nTab
<= nTab2
)
760 while (nRow
<= nRow2
)
764 while (nCol
<= nCol2
)
767 ScRefCellValue aCell
;
768 aCell
.assign(*pDok
, aAdr
);
769 if (!aCell
.isEmpty())
772 sal_uInt16 nType
= 0; // 0 = Zahl; 1 = String
776 switch (aCell
.meType
)
778 case CELLTYPE_STRING
:
780 aStr
= aCell
.getString(pDok
);
783 case CELLTYPE_VALUE
:
784 nVal
= GetValueCellValue(aAdr
, aCell
.mfValue
);
786 case CELLTYPE_FORMULA
:
787 nErr
= aCell
.mpFormula
->GetErrCode();
788 if (aCell
.mpFormula
->IsValue())
789 nVal
= aCell
.mpFormula
->GetValue();
791 aStr
= aCell
.mpFormula
->GetString().getString();
799 if ((nPos
+ (5 * sizeof(sal_uInt16
))) > MAXARRSIZE
)
801 *p
++ = static_cast<sal_uInt16
>(nCol
);
802 *p
++ = static_cast<sal_uInt16
>(nRow
);
803 *p
++ = static_cast<sal_uInt16
>(nTab
);
809 if ((nPos
+ sizeof(double)) > MAXARRSIZE
)
811 memcpy( p
, &nVal
, sizeof(double));
812 nPos
+= sizeof(double);
816 OString
aTmp(OUStringToOString(aStr
,
817 osl_getThreadTextEncoding()));
818 // In case the xub_StrLen will be longer than USHORT
819 // one day, and room for pad byte check.
820 if ( aTmp
.getLength() > ((sal_uInt16
)(~0)) - 2 )
822 // Append a 0-pad-byte if string length is not even
823 //! MUST be sal_uInt16 and not xub_StrLen
824 sal_uInt16 nStrLen
= (sal_uInt16
) aTmp
.getLength();
825 sal_uInt16 nLen
= ( nStrLen
+ 2 ) & ~1;
826 if ( ((sal_uLong
)nPos
+ 2 + nLen
) > MAXARRSIZE
)
829 memcpy( p
, aTmp
.getStr(), nStrLen
+ 1);
830 nPos
+= 2 + nStrLen
+ 1;
831 sal_uInt8
* q
= ( pCellArr
+ nPos
);
836 p
= (sal_uInt16
*) ( pCellArr
+ nPos
);
850 //-----------------------------------------------------------------------------
852 //-----------------------------------------------------------------------------
855 // Also releases a TempToken if appropriate.
857 void ScInterpreter::PushWithoutError( FormulaToken
& r
)
859 if ( sp
>= MAXSTACK
)
860 SetError( errStackOverflow
);
863 nCurFmtType
= NUMBERFORMAT_UNDEFINED
;
868 pStack
[ sp
]->DecRef();
869 pStack
[ sp
] = (ScToken
*) &r
;
874 void ScInterpreter::Push( FormulaToken
& r
)
876 if ( sp
>= MAXSTACK
)
877 SetError( errStackOverflow
);
882 if (r
.GetType() == svError
)
884 r
.SetError( nGlobalError
);
885 PushWithoutError( r
);
888 PushWithoutError( *(new FormulaErrorToken( nGlobalError
)));
891 PushWithoutError( r
);
896 void ScInterpreter::PushTempToken( FormulaToken
* p
)
898 if ( sp
>= MAXSTACK
)
900 SetError( errStackOverflow
);
902 //! p is a dangling pointer hereafter!
909 if (p
->GetType() == svError
)
911 p
->SetError( nGlobalError
);
912 PushTempTokenWithoutError( p
);
917 //! p is a dangling pointer hereafter!
919 PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError
));
923 PushTempTokenWithoutError( p
);
928 void ScInterpreter::PushTempTokenWithoutError( FormulaToken
* p
)
931 if ( sp
>= MAXSTACK
)
933 SetError( errStackOverflow
);
934 //! p may be a dangling pointer hereafter!
942 pStack
[ sp
]->DecRef();
949 void ScInterpreter::PushTempToken( const FormulaToken
& r
)
951 if (!IfErrorPushError())
952 PushTempTokenWithoutError( r
.Clone());
956 void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString
,
957 const ScAddress
& rAddress
, short * pRetTypeExpr
, sal_uLong
* pRetIndexExpr
)
959 ScRefCellValue aCell
;
960 aCell
.assign(*pDok
, rAddress
);
961 if (aCell
.hasEmptyValue())
963 bool bInherited
= (aCell
.meType
== CELLTYPE_FORMULA
);
964 if (pRetTypeExpr
&& pRetIndexExpr
)
965 pDok
->GetNumberFormatInfo(*pRetTypeExpr
, *pRetIndexExpr
, rAddress
);
966 PushTempToken( new ScEmptyCellToken( bInherited
, bDisplayEmptyAsString
));
971 if (aCell
.meType
== CELLTYPE_FORMULA
)
972 nErr
= aCell
.mpFormula
->GetErrCode();
978 *pRetTypeExpr
= NUMBERFORMAT_UNDEFINED
;
982 else if (aCell
.hasString())
984 svl::SharedString aRes
;
985 GetCellString( aRes
, aCell
);
988 *pRetTypeExpr
= NUMBERFORMAT_TEXT
;
994 double fVal
= GetCellValue(rAddress
, aCell
);
997 *pRetTypeExpr
= nCurFmtType
;
999 *pRetIndexExpr
= nCurFmtIndex
;
1004 // Simply throw away TOS.
1006 void ScInterpreter::Pop()
1011 SetError(errUnknownStackVariable
);
1015 // Simply throw away TOS and set error code, used with ocIsError et al.
1017 void ScInterpreter::PopError()
1022 if (pStack
[sp
]->GetType() == svError
)
1023 nGlobalError
= pStack
[sp
]->GetError();
1026 SetError(errUnknownStackVariable
);
1030 FormulaTokenRef
ScInterpreter::PopToken()
1035 FormulaToken
* p
= pStack
[ sp
];
1036 if (p
->GetType() == svError
)
1037 nGlobalError
= p
->GetError();
1041 SetError(errUnknownStackVariable
);
1046 double ScInterpreter::PopDouble()
1048 nCurFmtType
= NUMBERFORMAT_NUMBER
;
1053 FormulaToken
* p
= pStack
[ sp
];
1054 switch (p
->GetType())
1057 nGlobalError
= p
->GetError();
1060 return p
->GetDouble();
1065 SetError( errIllegalArgument
);
1069 SetError( errUnknownStackVariable
);
1074 svl::SharedString
ScInterpreter::PopString()
1076 nCurFmtType
= NUMBERFORMAT_TEXT
;
1081 FormulaToken
* p
= pStack
[ sp
];
1082 switch (p
->GetType())
1085 nGlobalError
= p
->GetError();
1088 return p
->GetString();
1091 return svl::SharedString::getEmptyString();
1093 SetError( errIllegalArgument
);
1097 SetError( errUnknownStackVariable
);
1099 return svl::SharedString::getEmptyString();
1103 void ScInterpreter::ValidateRef( const ScSingleRefData
& rRef
)
1108 SingleRefToVars( rRef
, nCol
, nRow
, nTab
);
1112 void ScInterpreter::ValidateRef( const ScComplexRefData
& rRef
)
1114 ValidateRef( rRef
.Ref1
);
1115 ValidateRef( rRef
.Ref2
);
1119 void ScInterpreter::ValidateRef( const ScRefList
& rRefList
)
1121 ScRefList::const_iterator
it( rRefList
.begin());
1122 ScRefList::const_iterator
end( rRefList
.end());
1123 for ( ; it
!= end
; ++it
)
1130 void ScInterpreter::SingleRefToVars( const ScSingleRefData
& rRef
,
1131 SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
)
1133 if ( rRef
.IsColRel() )
1134 rCol
= aPos
.Col() + rRef
.Col();
1138 if ( rRef
.IsRowRel() )
1139 rRow
= aPos
.Row() + rRef
.Row();
1143 if ( rRef
.IsTabRel() )
1144 rTab
= aPos
.Tab() + rRef
.Tab();
1148 if( !ValidCol( rCol
) || rRef
.IsColDeleted() )
1149 SetError( errNoRef
), rCol
= 0;
1150 if( !ValidRow( rRow
) || rRef
.IsRowDeleted() )
1151 SetError( errNoRef
), rRow
= 0;
1152 if( !ValidTab( rTab
, pDok
->GetTableCount() - 1) || rRef
.IsTabDeleted() )
1153 SetError( errNoRef
), rTab
= 0;
1157 void ScInterpreter::PopSingleRef(SCCOL
& rCol
, SCROW
&rRow
, SCTAB
& rTab
)
1162 FormulaToken
* p
= pStack
[ sp
];
1163 switch (p
->GetType())
1166 nGlobalError
= p
->GetError();
1169 SingleRefToVars( static_cast<ScToken
*>(p
)->GetSingleRef(), rCol
, rRow
, rTab
);
1170 if ( !pDok
->aTableOpList
.empty() )
1171 ReplaceCell( rCol
, rRow
, rTab
);
1174 SetError( errIllegalParameter
);
1178 SetError( errUnknownStackVariable
);
1182 void ScInterpreter::PopSingleRef( ScAddress
& rAdr
)
1187 FormulaToken
* p
= pStack
[ sp
];
1188 switch (p
->GetType())
1191 nGlobalError
= p
->GetError();
1198 SingleRefToVars( static_cast<ScToken
*>(p
)->GetSingleRef(), nCol
, nRow
, nTab
);
1199 rAdr
.Set( nCol
, nRow
, nTab
);
1200 if ( !pDok
->aTableOpList
.empty() )
1201 ReplaceCell( rAdr
);
1205 SetError( errIllegalParameter
);
1209 SetError( errUnknownStackVariable
);
1213 void ScInterpreter::DoubleRefToVars( const ScToken
* p
,
1214 SCCOL
& rCol1
, SCROW
&rRow1
, SCTAB
& rTab1
,
1215 SCCOL
& rCol2
, SCROW
&rRow2
, SCTAB
& rTab2
,
1216 bool bDontCheckForTableOp
)
1218 const ScComplexRefData
& rCRef
= p
->GetDoubleRef();
1219 SingleRefToVars( rCRef
.Ref1
, rCol1
, rRow1
, rTab1
);
1220 SingleRefToVars( rCRef
.Ref2
, rCol2
, rRow2
, rTab2
);
1221 if ( !pDok
->aTableOpList
.empty() && !bDontCheckForTableOp
)
1223 ScRange
aRange( rCol1
, rRow1
, rTab1
, rCol2
, rRow2
, rTab2
);
1224 if ( IsTableOpInRange( aRange
) )
1225 SetError( errIllegalParameter
);
1229 ScDBRangeBase
* ScInterpreter::PopDBDoubleRef()
1231 StackVar eType
= GetStackType();
1235 SetError(errUnknownStackVariable
);
1245 PopDoubleRef(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, false);
1248 return new ScDBInternalRange(pDok
,
1249 ScRange(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
));
1252 case svExternalDoubleRef
:
1255 if (eType
== svMatrix
)
1258 PopExternalDoubleRef(pMat
);
1261 return new ScDBExternalRange(pDok
, pMat
);
1264 SetError( errIllegalParameter
);
1270 void ScInterpreter::PopDoubleRef(SCCOL
& rCol1
, SCROW
&rRow1
, SCTAB
& rTab1
,
1271 SCCOL
& rCol2
, SCROW
&rRow2
, SCTAB
& rTab2
,
1272 bool bDontCheckForTableOp
)
1277 FormulaToken
* p
= pStack
[ sp
];
1278 switch (p
->GetType())
1281 nGlobalError
= p
->GetError();
1284 DoubleRefToVars( static_cast<ScToken
*>(p
), rCol1
, rRow1
, rTab1
, rCol2
, rRow2
, rTab2
,
1285 bDontCheckForTableOp
);
1288 SetError( errIllegalParameter
);
1292 SetError( errUnknownStackVariable
);
1296 void ScInterpreter::DoubleRefToRange( const ScComplexRefData
& rCRef
,
1297 ScRange
& rRange
, bool bDontCheckForTableOp
)
1302 SingleRefToVars( rCRef
.Ref1
, nCol
, nRow
, nTab
);
1303 rRange
.aStart
.Set( nCol
, nRow
, nTab
);
1304 SingleRefToVars( rCRef
.Ref2
, nCol
, nRow
, nTab
);
1305 rRange
.aEnd
.Set( nCol
, nRow
, nTab
);
1306 if (! pDok
->aTableOpList
.empty() && !bDontCheckForTableOp
)
1308 if ( IsTableOpInRange( rRange
) )
1309 SetError( errIllegalParameter
);
1314 void ScInterpreter::PopDoubleRef( ScRange
& rRange
, short & rParam
, size_t & rRefInList
)
1318 formula::FormulaToken
* pToken
= pStack
[ sp
-1 ];
1319 ScToken
* p
= static_cast<ScToken
*>(pToken
);
1320 switch (pToken
->GetType())
1323 nGlobalError
= p
->GetError();
1327 DoubleRefToRange( p
->GetDoubleRef(), rRange
);
1331 const ScRefList
* pList
= p
->GetRefList();
1332 if (rRefInList
< pList
->size())
1334 DoubleRefToRange( (*pList
)[rRefInList
], rRange
);
1335 if (++rRefInList
< pList
->size())
1347 SetError( errIllegalParameter
);
1352 SetError( errIllegalParameter
);
1356 SetError( errUnknownStackVariable
);
1360 void ScInterpreter::PopDoubleRef( ScRange
& rRange
, bool bDontCheckForTableOp
)
1365 FormulaToken
* p
= pStack
[ sp
];
1366 switch (p
->GetType())
1369 nGlobalError
= p
->GetError();
1372 DoubleRefToRange( static_cast<ScToken
*>(p
)->GetDoubleRef(), rRange
, bDontCheckForTableOp
);
1375 SetError( errIllegalParameter
);
1379 SetError( errUnknownStackVariable
);
1382 void ScInterpreter::PopExternalSingleRef(sal_uInt16
& rFileId
, OUString
& rTabName
, ScSingleRefData
& rRef
)
1386 SetError(errUnknownStackVariable
);
1391 FormulaToken
* p
= pStack
[sp
];
1392 StackVar eType
= p
->GetType();
1394 if (eType
== svError
)
1396 nGlobalError
= p
->GetError();
1400 if (eType
!= svExternalSingleRef
)
1402 SetError( errIllegalParameter
);
1406 rFileId
= p
->GetIndex();
1407 rTabName
= p
->GetString().getString();
1408 rRef
= static_cast<ScToken
*>(p
)->GetSingleRef();
1411 void ScInterpreter::PopExternalSingleRef(ScExternalRefCache::TokenRef
& rToken
, ScExternalRefCache::CellFormat
* pFmt
)
1415 ScSingleRefData aData
;
1416 PopExternalSingleRef(nFileId
, aTabName
, aData
, rToken
, pFmt
);
1419 void ScInterpreter::PopExternalSingleRef(
1420 sal_uInt16
& rFileId
, OUString
& rTabName
, ScSingleRefData
& rRef
,
1421 ScExternalRefCache::TokenRef
& rToken
, ScExternalRefCache::CellFormat
* pFmt
)
1423 PopExternalSingleRef(rFileId
, rTabName
, rRef
);
1427 ScExternalRefManager
* pRefMgr
= pDok
->GetExternalRefManager();
1428 const OUString
* pFile
= pRefMgr
->getExternalFileName(rFileId
);
1431 SetError(errNoName
);
1435 if (rRef
.IsTabRel())
1437 OSL_FAIL("ScCompiler::GetToken: external single reference must have an absolute table reference!");
1442 ScAddress aAddr
= rRef
.toAbs(aPos
);
1443 ScExternalRefCache::CellFormat aFmt
;
1444 ScExternalRefCache::TokenRef xNew
= pRefMgr
->getSingleRefToken(
1445 rFileId
, rTabName
, aAddr
, &aPos
, NULL
, &aFmt
);
1458 void ScInterpreter::PopExternalDoubleRef(sal_uInt16
& rFileId
, OUString
& rTabName
, ScComplexRefData
& rRef
)
1462 SetError(errUnknownStackVariable
);
1467 FormulaToken
* p
= pStack
[sp
];
1468 StackVar eType
= p
->GetType();
1470 if (eType
== svError
)
1472 nGlobalError
= p
->GetError();
1476 if (eType
!= svExternalDoubleRef
)
1478 SetError( errIllegalParameter
);
1482 rFileId
= p
->GetIndex();
1483 rTabName
= p
->GetString().getString();
1484 rRef
= static_cast<ScToken
*>(p
)->GetDoubleRef();
1487 void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef
& rArray
)
1491 ScComplexRefData aData
;
1492 PopExternalDoubleRef(nFileId
, aTabName
, aData
);
1496 GetExternalDoubleRef(nFileId
, aTabName
, aData
, rArray
);
1501 void ScInterpreter::PopExternalDoubleRef(ScMatrixRef
& rMat
)
1503 ScExternalRefCache::TokenArrayRef pArray
;
1504 PopExternalDoubleRef(pArray
);
1508 // For now, we only support single range data for external
1509 // references, which means the array should only contain a
1510 // single matrix token.
1511 ScToken
* p
= static_cast<ScToken
*>(pArray
->First());
1512 if (!p
|| p
->GetType() != svMatrix
)
1513 SetError( errIllegalParameter
);
1516 rMat
= p
->GetMatrix();
1518 SetError( errUnknownVariable
);
1522 void ScInterpreter::GetExternalDoubleRef(
1523 sal_uInt16 nFileId
, const OUString
& rTabName
, const ScComplexRefData
& rData
, ScExternalRefCache::TokenArrayRef
& rArray
)
1525 ScExternalRefManager
* pRefMgr
= pDok
->GetExternalRefManager();
1526 const OUString
* pFile
= pRefMgr
->getExternalFileName(nFileId
);
1529 SetError(errNoName
);
1532 if (rData
.Ref1
.IsTabRel() || rData
.Ref2
.IsTabRel())
1534 OSL_FAIL("ScCompiler::GetToken: external double reference must have an absolute table reference!");
1539 ScComplexRefData
aData(rData
);
1540 ScRange aRange
= aData
.toAbs(aPos
);
1541 ScExternalRefCache::TokenArrayRef pArray
= pRefMgr
->getDoubleRefTokens(
1542 nFileId
, rTabName
, aRange
, &aPos
);
1546 SetError(errIllegalArgument
);
1550 ScToken
* pToken
= static_cast<ScToken
*>(pArray
->First());
1551 if (pToken
->GetType() != svMatrix
)
1553 SetError(errIllegalArgument
);
1559 // Can't handle more than one matrix per parameter.
1560 SetError( errIllegalArgument
);
1567 bool ScInterpreter::PopDoubleRefOrSingleRef( ScAddress
& rAdr
)
1569 switch ( GetStackType() )
1574 PopDoubleRef( aRange
, true );
1575 return DoubleRefToPosSingleRef( aRange
, rAdr
);
1579 PopSingleRef( rAdr
);
1584 SetError( errNoRef
);
1590 void ScInterpreter::PopDoubleRefPushMatrix()
1592 if ( GetStackType() == svDoubleRef
)
1594 ScMatrixRef pMat
= GetMatrix();
1598 PushIllegalParameter();
1601 SetError( errNoRef
);
1605 ScTokenMatrixMap
* ScInterpreter::CreateTokenMatrixMap()
1607 return new ScTokenMatrixMap
;
1611 bool ScInterpreter::ConvertMatrixParameters()
1613 sal_uInt16 nParams
= pCur
->GetParamCount();
1614 OSL_ENSURE( nParams
<= sp
, "ConvertMatrixParameters: stack/param count mismatch");
1615 SCSIZE nJumpCols
= 0, nJumpRows
= 0;
1616 for ( sal_uInt16 i
=1; i
<= nParams
&& i
<= sp
; ++i
)
1618 FormulaToken
* p
= pStack
[ sp
- i
];
1619 if ( p
->GetOpCode() != ocPush
&& p
->GetOpCode() != ocMissing
)
1621 OSL_FAIL( "ConvertMatrixParameters: not a push");
1625 switch ( p
->GetType() )
1630 case svExternalSingleRef
:
1638 if ( ScParameterClassification::GetParameterType( pCur
, nParams
- i
)
1639 == ScParameterClassification::Value
)
1640 { // only if single value expected
1641 ScMatrixRef pMat
= static_cast<ScToken
*>(p
)->GetMatrix();
1643 SetError( errUnknownVariable
);
1646 SCSIZE nCols
, nRows
;
1647 pMat
->GetDimensions( nCols
, nRows
);
1648 if ( nJumpCols
< nCols
)
1650 if ( nJumpRows
< nRows
)
1658 ScParameterClassification::Type eType
=
1659 ScParameterClassification::GetParameterType( pCur
, nParams
- i
);
1660 if ( eType
!= ScParameterClassification::Reference
&&
1661 eType
!= ScParameterClassification::ReferenceOrForceArray
)
1666 DoubleRefToVars( static_cast<const ScToken
*>( p
), nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
1667 // Make sure the map exists, created if not.
1668 GetTokenMatrixMap();
1669 ScMatrixRef pMat
= CreateMatrixFromDoubleRef( p
,
1670 nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
1673 if ( eType
== ScParameterClassification::Value
)
1674 { // only if single value expected
1675 if ( nJumpCols
< static_cast<SCSIZE
>(nCol2
- nCol1
+ 1) )
1676 nJumpCols
= static_cast<SCSIZE
>(nCol2
- nCol1
+ 1);
1677 if ( nJumpRows
< static_cast<SCSIZE
>(nRow2
- nRow1
+ 1) )
1678 nJumpRows
= static_cast<SCSIZE
>(nRow2
- nRow1
+ 1);
1680 ScToken
* pNew
= new ScMatrixToken( pMat
);
1682 pStack
[ sp
- i
] = pNew
;
1683 p
->DecRef(); // p may be dead now!
1688 case svExternalDoubleRef
:
1690 ScParameterClassification::Type eType
=
1691 ScParameterClassification::GetParameterType( pCur
, nParams
- i
);
1692 if (eType
== ScParameterClassification::Array
)
1694 sal_uInt16 nFileId
= p
->GetIndex();
1695 OUString aTabName
= p
->GetString().getString();
1696 const ScComplexRefData
& rRef
= static_cast<ScToken
*>(p
)->GetDoubleRef();
1697 ScExternalRefCache::TokenArrayRef pArray
;
1698 GetExternalDoubleRef(nFileId
, aTabName
, rRef
, pArray
);
1702 ScToken
* pTemp
= static_cast<ScToken
*>(pArray
->First());
1706 ScMatrixRef pMat
= pTemp
->GetMatrix();
1709 ScToken
* pNew
= new ScMatrixToken( pMat
);
1711 pStack
[ sp
- i
] = pNew
;
1712 p
->DecRef(); // p may be dead now!
1719 ScParameterClassification::Type eType
=
1720 ScParameterClassification::GetParameterType( pCur
, nParams
- i
);
1721 if ( eType
!= ScParameterClassification::Reference
&&
1722 eType
!= ScParameterClassification::ReferenceOrForceArray
)
1724 // can't convert to matrix
1725 SetError( errNoValue
);
1730 OSL_FAIL( "ConvertMatrixParameters: unknown parameter type");
1734 if( nJumpCols
&& nJumpRows
)
1736 short nPC
= aCode
.GetPC();
1737 short nStart
= nPC
- 1; // restart on current code (-1)
1738 short nNext
= nPC
; // next instruction after subroutine
1739 short nStop
= nPC
+ 1; // stop subroutine before reaching that
1740 FormulaTokenRef xNew
;
1741 ScTokenMatrixMap::const_iterator aMapIter
;
1742 if (pTokenMatrixMap
&& ((aMapIter
= pTokenMatrixMap
->find( pCur
)) !=
1743 pTokenMatrixMap
->end()))
1744 xNew
= (*aMapIter
).second
;
1747 ScJumpMatrix
* pJumpMat
= new ScJumpMatrix( nJumpCols
, nJumpRows
);
1748 pJumpMat
->SetAllJumps( 1.0, nStart
, nNext
, nStop
);
1749 // pop parameters and store in ScJumpMatrix, push in JumpMatrix()
1750 ScTokenVec
* pParams
= new ScTokenVec( nParams
);
1751 for ( sal_uInt16 i
=1; i
<= nParams
&& sp
> 0; ++i
)
1753 FormulaToken
* p
= pStack
[ --sp
];
1755 // store in reverse order such that a push may simply iterate
1756 (*pParams
)[ nParams
- i
] = p
;
1758 pJumpMat
->SetJumpParameters( pParams
);
1759 xNew
= new ScJumpMatrixToken( pJumpMat
);
1760 GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type( pCur
,
1763 PushTempToken( xNew
.get());
1764 // set continuation point of path for main code line
1765 aCode
.Jump( nNext
, nNext
);
1772 ScMatrixRef
ScInterpreter::PopMatrix()
1777 FormulaToken
* p
= pStack
[ sp
];
1778 switch (p
->GetType())
1781 nGlobalError
= p
->GetError();
1785 ScMatrix
* pMat
= static_cast<ScToken
*>(p
)->GetMatrix();
1787 pMat
->SetErrorInterpreter( this);
1789 SetError( errUnknownVariable
);
1793 SetError( errIllegalParameter
);
1797 SetError( errUnknownStackVariable
);
1801 sc::RangeMatrix
ScInterpreter::PopRangeMatrix()
1803 sc::RangeMatrix aRet
;
1806 switch (pStack
[sp
-1]->GetType())
1811 FormulaToken
* p
= pStack
[sp
];
1812 ScToken
* p2
= static_cast<ScToken
*>(p
);
1813 aRet
.mpMat
= p2
->GetMatrix();
1816 aRet
.mpMat
->SetErrorInterpreter(this);
1817 if (p2
->GetByte() == MATRIX_TOKEN_HAS_RANGE
)
1819 const ScComplexRefData
& rRef
= p2
->GetDoubleRef();
1820 if (!rRef
.Ref1
.IsColRel() && !rRef
.Ref1
.IsRowRel() && !rRef
.Ref2
.IsColRel() && !rRef
.Ref2
.IsRowRel())
1822 aRet
.mnCol1
= rRef
.Ref1
.Col();
1823 aRet
.mnRow1
= rRef
.Ref1
.Row();
1824 aRet
.mnTab1
= rRef
.Ref1
.Tab();
1825 aRet
.mnCol2
= rRef
.Ref2
.Col();
1826 aRet
.mnRow2
= rRef
.Ref2
.Row();
1827 aRet
.mnTab2
= rRef
.Ref2
.Tab();
1832 SetError( errUnknownVariable
);
1836 aRet
.mpMat
= PopMatrix();
1842 void ScInterpreter::QueryMatrixType(ScMatrixRef
& xMat
, short& rRetTypeExpr
, sal_uLong
& rRetIndexExpr
)
1846 ScMatrixValue nMatVal
= xMat
->Get(0, 0);
1847 ScMatValType nMatValType
= nMatVal
.nType
;
1848 if (ScMatrix::IsNonValueType( nMatValType
))
1850 if ( xMat
->IsEmptyPath( 0, 0))
1851 { // result of empty FALSE jump path
1852 FormulaTokenRef xRes
= new FormulaDoubleToken( 0.0);
1853 PushTempToken( new ScMatrixCellResultToken( xMat
, xRes
.get()));
1854 rRetTypeExpr
= NUMBERFORMAT_LOGICAL
;
1858 svl::SharedString
aStr( nMatVal
.GetString());
1859 FormulaTokenRef xRes
= new FormulaStringToken( aStr
);
1860 PushTempToken( new ScMatrixCellResultToken( xMat
, xRes
.get()));
1861 rRetTypeExpr
= NUMBERFORMAT_TEXT
;
1866 sal_uInt16 nErr
= GetDoubleErrorValue( nMatVal
.fVal
);
1867 FormulaTokenRef xRes
;
1869 xRes
= new FormulaErrorToken( nErr
);
1871 xRes
= new FormulaDoubleToken( nMatVal
.fVal
);
1872 PushTempToken( new ScMatrixCellResultToken( xMat
, xRes
.get()));
1873 if ( rRetTypeExpr
!= NUMBERFORMAT_LOGICAL
)
1874 rRetTypeExpr
= NUMBERFORMAT_NUMBER
;
1877 xMat
->SetErrorInterpreter( NULL
);
1880 SetError( errUnknownStackVariable
);
1884 void ScInterpreter::PushDouble(double nVal
)
1886 TreatDoubleError( nVal
);
1887 if (!IfErrorPushError())
1888 PushTempTokenWithoutError( new FormulaDoubleToken( nVal
) );
1892 void ScInterpreter::PushInt(int nVal
)
1894 if (!IfErrorPushError())
1895 PushTempTokenWithoutError( new FormulaDoubleToken( nVal
) );
1899 void ScInterpreter::PushStringBuffer( const sal_Unicode
* pString
)
1903 svl::SharedString aSS
= pDok
->GetSharedStringPool().intern(OUString(pString
));
1907 PushString(svl::SharedString::getEmptyString());
1910 void ScInterpreter::PushString( const OUString
& rStr
)
1912 PushString(pDok
->GetSharedStringPool().intern(rStr
));
1915 void ScInterpreter::PushString( const svl::SharedString
& rString
)
1917 if (!IfErrorPushError())
1918 PushTempTokenWithoutError( new FormulaStringToken( rString
) );
1922 void ScInterpreter::PushSingleRef(SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1924 if (!IfErrorPushError())
1926 ScSingleRefData aRef
;
1927 aRef
.InitAddress(ScAddress(nCol
,nRow
,nTab
));
1928 PushTempTokenWithoutError( new ScSingleRefToken( aRef
) );
1933 void ScInterpreter::PushDoubleRef(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1934 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
)
1936 if (!IfErrorPushError())
1938 ScComplexRefData aRef
;
1939 aRef
.InitRange(ScRange(nCol1
,nRow1
,nTab1
,nCol2
,nRow2
,nTab2
));
1940 PushTempTokenWithoutError( new ScDoubleRefToken( aRef
) );
1945 void ScInterpreter::PushExternalSingleRef(
1946 sal_uInt16 nFileId
, const OUString
& rTabName
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1948 if (!IfErrorPushError())
1950 ScSingleRefData aRef
;
1951 aRef
.InitAddress(ScAddress(nCol
,nRow
,nTab
));
1952 PushTempTokenWithoutError( new ScExternalSingleRefToken(nFileId
, rTabName
, aRef
)) ;
1957 void ScInterpreter::PushExternalDoubleRef(
1958 sal_uInt16 nFileId
, const OUString
& rTabName
,
1959 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
, SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
)
1961 if (!IfErrorPushError())
1963 ScComplexRefData aRef
;
1964 aRef
.InitRange(ScRange(nCol1
,nRow1
,nTab1
,nCol2
,nRow2
,nTab2
));
1965 PushTempTokenWithoutError( new ScExternalDoubleRefToken(nFileId
, rTabName
, aRef
) );
1969 void ScInterpreter::PushMatrix( const sc::RangeMatrix
& rMat
)
1971 if (!rMat
.isRangeValid())
1973 // Just push the matrix part only.
1974 PushMatrix(rMat
.mpMat
);
1978 rMat
.mpMat
->SetErrorInterpreter(NULL
);
1980 PushTempTokenWithoutError(new ScMatrixRangeToken(rMat
));
1983 void ScInterpreter::PushMatrix(const ScMatrixRef
& pMat
)
1985 pMat
->SetErrorInterpreter( NULL
);
1986 // No if (!IfErrorPushError()) because ScMatrix stores errors itself,
1987 // but with notifying ScInterpreter via nGlobalError, substituting it would
1988 // mean to inherit the error on all array elements in all following
1991 PushTempTokenWithoutError( new ScMatrixToken( pMat
) );
1995 void ScInterpreter::PushError( sal_uInt16 nError
)
1997 SetError( nError
); // only sets error if not already set
1998 PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError
));
2001 void ScInterpreter::PushParameterExpected()
2003 PushError( errParameterExpected
);
2007 void ScInterpreter::PushIllegalParameter()
2009 PushError( errIllegalParameter
);
2013 void ScInterpreter::PushIllegalArgument()
2015 PushError( errIllegalArgument
);
2019 void ScInterpreter::PushNA()
2021 PushError( NOTAVAILABLE
);
2025 void ScInterpreter::PushNoValue()
2027 PushError( errNoValue
);
2031 bool ScInterpreter::IsMissing()
2033 return sp
&& pStack
[sp
- 1]->GetType() == svMissing
;
2037 StackVar
ScInterpreter::GetRawStackType()
2042 eRes
= pStack
[sp
- 1]->GetType();
2046 SetError(errUnknownStackVariable
);
2053 StackVar
ScInterpreter::GetStackType()
2058 eRes
= pStack
[sp
- 1]->GetType();
2059 if( eRes
== svMissing
|| eRes
== svEmptyCell
)
2060 eRes
= svDouble
; // default!
2064 SetError(errUnknownStackVariable
);
2071 StackVar
ScInterpreter::GetStackType( sal_uInt8 nParam
)
2076 eRes
= pStack
[sp
- nParam
]->GetType();
2077 if( eRes
== svMissing
|| eRes
== svEmptyCell
)
2078 eRes
= svDouble
; // default!
2086 bool ScInterpreter::DoubleRefToPosSingleRef( const ScRange
& rRange
, ScAddress
& rAdr
)
2088 // Check for a singleton first - no implicit intersection for them.
2089 if( rRange
.aStart
== rRange
.aEnd
)
2091 rAdr
= rRange
.aStart
;
2099 bOk
= rRange
.aStart
.Tab() == rRange
.aEnd
.Tab();
2101 SetError( errIllegalArgument
);
2105 pJumpMatrix
->GetPos( nC
, nR
);
2106 rAdr
.SetCol( sal::static_int_cast
<SCCOL
>( rRange
.aStart
.Col() + nC
) );
2107 rAdr
.SetRow( sal::static_int_cast
<SCROW
>( rRange
.aStart
.Row() + nR
) );
2108 rAdr
.SetTab( rRange
.aStart
.Tab());
2109 bOk
= rRange
.aStart
.Col() <= rAdr
.Col() && rAdr
.Col() <=
2110 rRange
.aEnd
.Col() && rRange
.aStart
.Row() <= rAdr
.Row() &&
2111 rAdr
.Row() <= rRange
.aEnd
.Row();
2113 SetError( errNoValue
);
2118 SCCOL nMyCol
= aPos
.Col();
2119 SCROW nMyRow
= aPos
.Row();
2120 SCTAB nMyTab
= aPos
.Tab();
2124 nTab
= rRange
.aStart
.Tab();
2125 if ( rRange
.aStart
.Col() <= nMyCol
&& nMyCol
<= rRange
.aEnd
.Col() )
2127 nRow
= rRange
.aStart
.Row();
2128 if ( nRow
== rRange
.aEnd
.Row() )
2133 else if ( nTab
!= nMyTab
&& nTab
== rRange
.aEnd
.Tab()
2134 && rRange
.aStart
.Row() <= nMyRow
&& nMyRow
<= rRange
.aEnd
.Row() )
2141 else if ( rRange
.aStart
.Row() <= nMyRow
&& nMyRow
<= rRange
.aEnd
.Row() )
2143 nCol
= rRange
.aStart
.Col();
2144 if ( nCol
== rRange
.aEnd
.Col() )
2149 else if ( nTab
!= nMyTab
&& nTab
== rRange
.aEnd
.Tab()
2150 && rRange
.aStart
.Col() <= nMyCol
&& nMyCol
<= rRange
.aEnd
.Col() )
2159 if ( nTab
== rRange
.aEnd
.Tab() )
2161 else if ( nTab
<= nMyTab
&& nMyTab
<= rRange
.aEnd
.Tab() )
2166 rAdr
.Set( nCol
, nRow
, nTab
);
2169 SetError( errNoValue
);
2173 double ScInterpreter::GetDoubleFromMatrix(const ScMatrixRef
& pMat
)
2179 return pMat
->GetDouble( 0 );
2181 SCSIZE nCols
, nRows
, nC
, nR
;
2182 pMat
->GetDimensions( nCols
, nRows
);
2183 pJumpMatrix
->GetPos( nC
, nR
);
2184 if ( nC
< nCols
&& nR
< nRows
)
2185 return pMat
->GetDouble( nC
, nR
);
2187 SetError( errNoValue
);
2191 double ScInterpreter::GetDouble()
2194 switch( GetRawStackType() )
2200 nVal
= ConvertStringToValue( PopString().getString());
2205 PopSingleRef( aAdr
);
2206 ScRefCellValue aCell
;
2207 aCell
.assign(*pDok
, aAdr
);
2208 nVal
= GetCellValue(aAdr
, aCell
);
2212 { // generate position dependent SingleRef
2214 PopDoubleRef( aRange
);
2216 if ( !nGlobalError
&& DoubleRefToPosSingleRef( aRange
, aAdr
) )
2218 ScRefCellValue aCell
;
2219 aCell
.assign(*pDok
, aAdr
);
2220 nVal
= GetCellValue(aAdr
, aCell
);
2226 case svExternalSingleRef
:
2228 ScExternalRefCache::TokenRef pToken
;
2229 PopExternalSingleRef(pToken
);
2230 if (!nGlobalError
&& pToken
)
2231 nVal
= pToken
->GetDouble();
2234 case svExternalDoubleRef
:
2237 PopExternalDoubleRef(pMat
);
2241 nVal
= GetDoubleFromMatrix(pMat
);
2246 ScMatrixRef pMat
= PopMatrix();
2247 nVal
= GetDoubleFromMatrix(pMat
);
2261 SetError( errIllegalParameter
);
2264 if ( nFuncFmtType
== nCurFmtType
)
2265 nFuncFmtIndex
= nCurFmtIndex
;
2270 double ScInterpreter::GetDoubleWithDefault(double nDefault
)
2272 bool bMissing
= IsMissing();
2273 double nResultVal
= GetDouble();
2275 nResultVal
= nDefault
;
2280 svl::SharedString
ScInterpreter::GetString()
2282 switch (GetRawStackType())
2286 return svl::SharedString::getEmptyString();
2290 return svl::SharedString::getEmptyString();
2293 double fVal
= PopDouble();
2294 sal_uLong nIndex
= pFormatter
->GetStandardFormat(
2295 NUMBERFORMAT_NUMBER
,
2298 pFormatter
->GetInputLineString(fVal
, nIndex
, aStr
);
2299 return mrStrPool
.intern(aStr
);
2306 PopSingleRef( aAdr
);
2307 if (nGlobalError
== 0)
2309 ScRefCellValue aCell
;
2310 aCell
.assign(*pDok
, aAdr
);
2311 svl::SharedString aSS
;
2312 GetCellString(aSS
, aCell
);
2316 return svl::SharedString::getEmptyString();
2319 { // generate position dependent SingleRef
2321 PopDoubleRef( aRange
);
2323 if ( !nGlobalError
&& DoubleRefToPosSingleRef( aRange
, aAdr
) )
2325 ScRefCellValue aCell
;
2326 aCell
.assign(*pDok
, aAdr
);
2327 svl::SharedString aSS
;
2328 GetCellString(aSS
, aCell
);
2332 return svl::SharedString::getEmptyString();
2334 case svExternalSingleRef
:
2336 ScExternalRefCache::TokenRef pToken
;
2337 PopExternalSingleRef(pToken
);
2339 return svl::SharedString::getEmptyString();
2341 return pToken
->GetString();
2343 case svExternalDoubleRef
:
2346 PopExternalDoubleRef(pMat
);
2347 return GetStringFromMatrix(pMat
);
2351 ScMatrixRef pMat
= PopMatrix();
2352 return GetStringFromMatrix(pMat
);
2357 SetError( errIllegalArgument
);
2359 return svl::SharedString::getEmptyString();
2362 svl::SharedString
ScInterpreter::GetStringFromMatrix(const ScMatrixRef
& pMat
)
2366 else if ( !pJumpMatrix
)
2368 return pMat
->GetString( *pFormatter
, 0, 0);
2372 SCSIZE nCols
, nRows
, nC
, nR
;
2373 pMat
->GetDimensions( nCols
, nRows
);
2374 pJumpMatrix
->GetPos( nC
, nR
);
2375 if ( nC
< nCols
&& nR
< nRows
)
2377 return pMat
->GetString( *pFormatter
, nC
, nR
);
2380 SetError( errNoValue
);
2382 return svl::SharedString::getEmptyString();
2385 ScMatValType
ScInterpreter::GetDoubleOrStringFromMatrix(
2386 double& rDouble
, svl::SharedString
& rString
)
2390 rString
= svl::SharedString::getEmptyString();
2391 ScMatValType nMatValType
= SC_MATVAL_EMPTY
;
2394 StackVar eType
= GetStackType();
2395 if (eType
== svExternalDoubleRef
|| eType
== svExternalSingleRef
|| eType
== svMatrix
)
2402 SetError( errIllegalParameter
);
2406 ScMatrixValue nMatVal
;
2411 else if (!pJumpMatrix
)
2413 nMatVal
= pMat
->Get(0, 0);
2414 nMatValType
= nMatVal
.nType
;
2418 SCSIZE nCols
, nRows
, nC
, nR
;
2419 pMat
->GetDimensions( nCols
, nRows
);
2420 pJumpMatrix
->GetPos( nC
, nR
);
2421 if ( nC
< nCols
&& nR
< nRows
)
2423 nMatVal
= pMat
->Get( nC
, nR
);
2424 nMatValType
= nMatVal
.nType
;
2427 SetError( errNoValue
);
2430 if (nMatValType
== SC_MATVAL_VALUE
)
2431 rDouble
= nMatVal
.fVal
;
2432 else if (nMatValType
== SC_MATVAL_BOOLEAN
)
2434 rDouble
= nMatVal
.fVal
;
2435 nMatValType
= SC_MATVAL_VALUE
;
2438 rString
= nMatVal
.GetString();
2440 if (ScMatrix::IsValueType( nMatValType
))
2442 sal_uInt16 nError
= nMatVal
.GetError();
2451 void ScInterpreter::ScDBGet()
2453 bool bMissingField
= false;
2454 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2455 auto_ptr
<ScDBQueryParamBase
> pQueryParam( GetDBParams(bMissingField
) );
2456 SAL_WNODEPRECATED_DECLARATIONS_POP
2457 if (!pQueryParam
.get())
2459 // Failed to create query param.
2460 PushIllegalParameter();
2464 pQueryParam
->mbSkipString
= false;
2465 ScDBQueryDataIterator
aValIter(pDok
, pQueryParam
.release());
2466 ScDBQueryDataIterator::Value aValue
;
2467 if (!aValIter
.GetFirst(aValue
) || aValue
.mnError
)
2474 ScDBQueryDataIterator::Value aValNext
;
2475 if (aValIter
.GetNext(aValNext
) && !aValNext
.mnError
)
2477 // There should be only one unique match.
2478 PushIllegalArgument();
2482 if (aValue
.mbIsNumber
)
2483 PushDouble(aValue
.mfValue
);
2485 PushString(aValue
.maString
);
2489 void ScInterpreter::ScExternal()
2491 sal_uInt8 nParamCount
= GetByte();
2493 OUString
aFuncName( ScGlobal::pCharClass
->uppercase( pCur
->GetExternal() ) );
2494 FuncData
* pFuncData
= ScGlobal::GetFuncCollection()->findByName(aFuncName
);
2497 // Old binary non-UNO add-in function.
2498 // NOTE: parameter count is 1-based with the 0th "parameter" being the
2499 // return value, included in pFuncDatat->GetParamCount()
2500 if (nParamCount
< MAXFUNCPARAM
&& nParamCount
== pFuncData
->GetParamCount() - 1)
2502 ParamType eParamType
[MAXFUNCPARAM
];
2503 void* ppParam
[MAXFUNCPARAM
];
2504 double nVal
[MAXFUNCPARAM
];
2505 sal_Char
* pStr
[MAXFUNCPARAM
];
2506 sal_uInt8
* pCellArr
[MAXFUNCPARAM
];
2509 for (i
= 0; i
< MAXFUNCPARAM
; i
++)
2511 eParamType
[i
] = pFuncData
->GetParamType(i
);
2518 for (i
= nParamCount
; (i
> 0) && (nGlobalError
== 0); i
--)
2520 switch (eParamType
[i
])
2524 nVal
[i
-1] = GetDouble();
2525 ppParam
[i
] = &nVal
[i
-1];
2530 OString
aStr(OUStringToOString(GetString().getString(),
2531 osl_getThreadTextEncoding()));
2532 if ( aStr
.getLength() >= ADDIN_MAXSTRLEN
)
2533 SetError( errStringOverflow
);
2536 pStr
[i
-1] = new sal_Char
[ADDIN_MAXSTRLEN
];
2537 strncpy( pStr
[i
-1], aStr
.getStr(), ADDIN_MAXSTRLEN
);
2538 pStr
[i
-1][ADDIN_MAXSTRLEN
-1] = 0;
2539 ppParam
[i
] = pStr
[i
-1];
2543 case PTR_DOUBLE_ARR
:
2551 PopDoubleRef(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
2552 pCellArr
[i
-1] = new sal_uInt8
[MAXARRSIZE
];
2553 if (!CreateDoubleArr(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, pCellArr
[i
-1]))
2554 SetError(errCodeOverflow
);
2556 ppParam
[i
] = pCellArr
[i
-1];
2559 case PTR_STRING_ARR
:
2567 PopDoubleRef(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
2568 pCellArr
[i
-1] = new sal_uInt8
[MAXARRSIZE
];
2569 if (!CreateStringArr(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, pCellArr
[i
-1]))
2570 SetError(errCodeOverflow
);
2572 ppParam
[i
] = pCellArr
[i
-1];
2583 PopDoubleRef(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
2584 pCellArr
[i
-1] = new sal_uInt8
[MAXARRSIZE
];
2585 if (!CreateCellArr(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, pCellArr
[i
-1]))
2586 SetError(errCodeOverflow
);
2588 ppParam
[i
] = pCellArr
[i
-1];
2592 SetError(errIllegalParameter
);
2597 Pop(); // im Fehlerfall (sonst ist i==0) Parameter wegpoppen
2599 if (nGlobalError
== 0)
2601 if ( pFuncData
->GetAsyncType() == NONE
)
2603 switch ( eParamType
[0] )
2609 pFuncData
->Call(ppParam
);
2615 sal_Char
* pcErg
= new sal_Char
[ADDIN_MAXSTRLEN
];
2617 pFuncData
->Call(ppParam
);
2618 OUString
aUni( pcErg
, strlen(pcErg
), osl_getThreadTextEncoding() );
2624 PushError( errUnknownState
);
2629 // nach dem Laden Asyncs wieder anwerfen
2630 if ( rArr
.IsRecalcModeNormal() )
2631 rArr
.SetExclusiveRecalcModeOnLoad();
2632 // garantiert identischer Handle bei identischem Aufruf?!?
2633 // sonst schei*e ...
2636 pFuncData
->Call(ppParam
);
2637 sal_uLong nHandle
= sal_uLong( nErg
);
2638 if ( nHandle
>= 65536 )
2640 ScAddInAsync
* pAs
= ScAddInAsync::Get( nHandle
);
2643 pAs
= new ScAddInAsync(nHandle
, pFuncData
, pDok
);
2644 pMyFormulaCell
->StartListening( *pAs
);
2648 // falls per cut/copy/paste
2649 pMyFormulaCell
->StartListening( *pAs
);
2650 // in anderes Dokument?
2651 if ( !pAs
->HasDocument( pDok
) )
2652 pAs
->AddDocument( pDok
);
2654 if ( pAs
->IsValid() )
2656 switch ( pAs
->GetType() )
2659 PushDouble( pAs
->GetValue() );
2662 PushString( pAs
->GetString() );
2665 PushError( errUnknownState
);
2676 for (i
= 0; i
< MAXFUNCPARAM
; i
++)
2679 delete[] pCellArr
[i
];
2684 while( nParamCount
-- > 0)
2686 PushIllegalParameter();
2689 else if ( !( aUnoName
= ScGlobal::GetAddInCollection()->FindFunction(aFuncName
, false) ).isEmpty() )
2691 // bLocalFirst=false in FindFunction, cFunc should be the stored
2694 ScUnoAddInCall
aCall( *ScGlobal::GetAddInCollection(), aUnoName
, nParamCount
);
2696 if ( !aCall
.ValidParamCount() )
2697 SetError( errIllegalParameter
);
2699 if ( aCall
.NeedsCaller() && !GetError() )
2701 SfxObjectShell
* pShell
= pDok
->GetDocumentShell();
2703 aCall
.SetCallerFromObjectShell( pShell
);
2706 // use temporary model object (without document) to supply options
2707 aCall
.SetCaller( static_cast<beans::XPropertySet
*>(
2708 new ScDocOptionsObj( pDok
->GetDocOptions() ) ) );
2712 short nPar
= nParamCount
;
2713 while ( nPar
> 0 && !GetError() )
2715 --nPar
; // 0 .. (nParamCount-1)
2717 ScAddInArgumentType eType
= aCall
.GetArgType( nPar
);
2718 sal_uInt8 nStackType
= sal::static_int_cast
<sal_uInt8
>( GetStackType() );
2723 case SC_ADDINARG_INTEGER
:
2725 double fVal
= GetDouble();
2726 double fInt
= (fVal
>= 0.0) ? ::rtl::math::approxFloor( fVal
) :
2727 ::rtl::math::approxCeil( fVal
);
2728 if ( fInt
>= LONG_MIN
&& fInt
<= LONG_MAX
)
2729 aParam
<<= (sal_Int32
)fInt
;
2731 SetError(errIllegalArgument
);
2735 case SC_ADDINARG_DOUBLE
:
2736 aParam
<<= (double) GetDouble();
2739 case SC_ADDINARG_STRING
:
2740 aParam
<<= GetString().getString();
2743 case SC_ADDINARG_INTEGER_ARRAY
:
2744 switch( nStackType
)
2750 double fVal
= GetDouble();
2751 double fInt
= (fVal
>= 0.0) ? ::rtl::math::approxFloor( fVal
) :
2752 ::rtl::math::approxCeil( fVal
);
2753 if ( fInt
>= LONG_MIN
&& fInt
<= LONG_MAX
)
2755 sal_Int32 nIntVal
= (long)fInt
;
2756 uno::Sequence
<sal_Int32
> aInner( &nIntVal
, 1 );
2757 uno::Sequence
< uno::Sequence
<sal_Int32
> > aOuter( &aInner
, 1 );
2761 SetError(errIllegalArgument
);
2767 PopDoubleRef( aRange
);
2768 if (!ScRangeToSequence::FillLongArray( aParam
, pDok
, aRange
))
2769 SetError(errIllegalParameter
);
2773 if (!ScRangeToSequence::FillLongArray( aParam
, PopMatrix().get() ))
2774 SetError(errIllegalParameter
);
2778 SetError(errIllegalParameter
);
2782 case SC_ADDINARG_DOUBLE_ARRAY
:
2783 switch( nStackType
)
2789 double fVal
= GetDouble();
2790 uno::Sequence
<double> aInner( &fVal
, 1 );
2791 uno::Sequence
< uno::Sequence
<double> > aOuter( &aInner
, 1 );
2798 PopDoubleRef( aRange
);
2799 if (!ScRangeToSequence::FillDoubleArray( aParam
, pDok
, aRange
))
2800 SetError(errIllegalParameter
);
2804 if (!ScRangeToSequence::FillDoubleArray( aParam
, PopMatrix().get() ))
2805 SetError(errIllegalParameter
);
2809 SetError(errIllegalParameter
);
2813 case SC_ADDINARG_STRING_ARRAY
:
2814 switch( nStackType
)
2820 OUString aString
= GetString().getString();
2821 uno::Sequence
<OUString
> aInner( &aString
, 1 );
2822 uno::Sequence
< uno::Sequence
<OUString
> > aOuter( &aInner
, 1 );
2829 PopDoubleRef( aRange
);
2830 if (!ScRangeToSequence::FillStringArray( aParam
, pDok
, aRange
))
2831 SetError(errIllegalParameter
);
2835 if (!ScRangeToSequence::FillStringArray( aParam
, PopMatrix().get(), pFormatter
))
2836 SetError(errIllegalParameter
);
2840 SetError(errIllegalParameter
);
2844 case SC_ADDINARG_MIXED_ARRAY
:
2845 switch( nStackType
)
2852 if ( nStackType
== svDouble
)
2853 aElem
<<= (double) GetDouble();
2854 else if ( nStackType
== svString
)
2855 aElem
<<= GetString().getString();
2859 if ( PopDoubleRefOrSingleRef( aAdr
) )
2861 ScRefCellValue aCell
;
2862 aCell
.assign(*pDok
, aAdr
);
2863 if (aCell
.hasString())
2865 svl::SharedString aStr
;
2866 GetCellString(aStr
, aCell
);
2867 aElem
<<= aStr
.getString();
2870 aElem
<<= GetCellValue(aAdr
, aCell
);
2873 uno::Sequence
<uno::Any
> aInner( &aElem
, 1 );
2874 uno::Sequence
< uno::Sequence
<uno::Any
> > aOuter( &aInner
, 1 );
2881 PopDoubleRef( aRange
);
2882 if (!ScRangeToSequence::FillMixedArray( aParam
, pDok
, aRange
))
2883 SetError(errIllegalParameter
);
2887 if (!ScRangeToSequence::FillMixedArray( aParam
, PopMatrix().get() ))
2888 SetError(errIllegalParameter
);
2892 SetError(errIllegalParameter
);
2896 case SC_ADDINARG_VALUE_OR_ARRAY
:
2898 nStackType
= svMissing
;
2899 switch( nStackType
)
2902 aParam
<<= (double) GetDouble();
2905 aParam
<<= GetString().getString();
2910 if ( PopDoubleRefOrSingleRef( aAdr
) )
2912 ScRefCellValue aCell
;
2913 aCell
.assign(*pDok
, aAdr
);
2914 if (aCell
.hasString())
2916 svl::SharedString aStr
;
2917 GetCellString(aStr
, aCell
);
2918 aParam
<<= aStr
.getString();
2921 aParam
<<= GetCellValue(aAdr
, aCell
);
2928 PopDoubleRef( aRange
);
2929 if (!ScRangeToSequence::FillMixedArray( aParam
, pDok
, aRange
))
2930 SetError(errIllegalParameter
);
2934 if (!ScRangeToSequence::FillMixedArray( aParam
, PopMatrix().get() ))
2935 SetError(errIllegalParameter
);
2943 SetError(errIllegalParameter
);
2947 case SC_ADDINARG_CELLRANGE
:
2948 switch( nStackType
)
2953 PopSingleRef( aAdr
);
2954 ScRange
aRange( aAdr
);
2955 uno::Reference
<table::XCellRange
> xObj
=
2956 ScCellRangeObj::CreateRangeFromDoc( pDok
, aRange
);
2960 SetError(errIllegalParameter
);
2966 PopDoubleRef( aRange
);
2967 uno::Reference
<table::XCellRange
> xObj
=
2968 ScCellRangeObj::CreateRangeFromDoc( pDok
, aRange
);
2975 SetError(errIllegalParameter
);
2981 SetError(errIllegalParameter
);
2987 SetError(errIllegalParameter
);
2989 aCall
.SetParam( nPar
, aParam
);
2994 Pop(); // in case of error, remove remaining args
2998 aCall
.ExecuteCall();
3000 if ( aCall
.HasVarRes() ) // handle async functions
3002 if ( rArr
.IsRecalcModeNormal() )
3004 rArr
.SetExclusiveRecalcModeOnLoad();
3006 uno::Reference
<sheet::XVolatileResult
> xRes
= aCall
.GetVarRes();
3007 ScAddInListener
* pLis
= ScAddInListener::Get( xRes
);
3010 pLis
= ScAddInListener::CreateListener( xRes
, pDok
);
3011 pMyFormulaCell
->StartListening( *pLis
);
3015 pMyFormulaCell
->StartListening( *pLis
);
3016 if ( !pLis
->HasDocument( pDok
) )
3018 pLis
->AddDocument( pDok
);
3022 aCall
.SetResult( pLis
->GetResult() ); // use result from async
3025 if ( aCall
.GetErrCode() )
3027 PushError( aCall
.GetErrCode() );
3029 else if ( aCall
.HasMatrix() )
3031 ScMatrixRef xMat
= aCall
.GetMatrix();
3034 else if ( aCall
.HasString() )
3036 PushString( aCall
.GetString() );
3040 PushDouble( aCall
.GetValue() );
3044 PushError( GetError());
3048 while( nParamCount
-- > 0)
3052 PushError( errNoAddin
);
3057 void ScInterpreter::ScMissing()
3059 PushTempToken( new FormulaMissingToken
);
3062 #ifndef DISABLE_SCRIPTING
3064 static uno::Any
lcl_getSheetModule( const uno::Reference
<table::XCellRange
>& xCellRange
, ScDocument
* pDok
)
3066 uno::Reference
< sheet::XSheetCellRange
> xSheetRange( xCellRange
, uno::UNO_QUERY_THROW
);
3067 uno::Reference
< beans::XPropertySet
> xProps( xSheetRange
->getSpreadsheet(), uno::UNO_QUERY_THROW
);
3069 xProps
->getPropertyValue("CodeName") >>= sCodeName
;
3070 // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible
3071 // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there
3072 // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at
3073 // the document in the future could fix this, especially IF the switching of the vba mode takes care to
3074 // create the special document module objects if they don't exist.
3075 BasicManager
* pBasMgr
= pDok
->GetDocumentShell()->GetBasicManager();
3077 uno::Reference
< uno::XInterface
> xIf
;
3078 if ( pBasMgr
&& !pBasMgr
->GetName().isEmpty() )
3080 OUString
sProj( "Standard" );
3081 if ( !pDok
->GetDocumentShell()->GetBasicManager()->GetName().isEmpty() )
3083 sProj
= pDok
->GetDocumentShell()->GetBasicManager()->GetName();
3085 StarBASIC
* pBasic
= pDok
->GetDocumentShell()->GetBasicManager()->GetLib( sProj
);
3088 SbModule
* pMod
= pBasic
->FindModule( sCodeName
);
3091 xIf
= pMod
->GetUnoModule();
3095 return uno::makeAny( xIf
);
3098 static bool lcl_setVBARange( ScRange
& aRange
, ScDocument
* pDok
, SbxVariable
* pPar
)
3103 uno::Reference
< uno::XInterface
> xVBARange
;
3104 uno::Reference
<table::XCellRange
> xCellRange
= ScCellRangeObj::CreateRangeFromDoc( pDok
, aRange
);
3105 uno::Sequence
< uno::Any
> aArgs(2);
3106 aArgs
[0] = lcl_getSheetModule( xCellRange
, pDok
);
3107 aArgs
[1] = uno::Any( xCellRange
);
3108 xVBARange
= ooo::vba::createVBAUnoAPIServiceWithArgs( pDok
->GetDocumentShell(), "ooo.vba.excel.Range", aArgs
);
3109 if ( xVBARange
.is() )
3111 OUString
sDummy("A-Range");
3112 SbxObjectRef aObj
= GetSbUnoObject( sDummy
, uno::Any( xVBARange
) );
3113 SetSbUnoObjectDfltPropName( aObj
);
3114 bOk
= pPar
->PutObject( aObj
);
3117 catch( uno::Exception
& )
3125 void ScInterpreter::ScMacro()
3128 #ifdef DISABLE_SCRIPTING
3129 PushNoValue(); // ohne DocShell kein CallBasic
3132 SbxBase::ResetError();
3134 sal_uInt8 nParamCount
= GetByte();
3135 OUString
aMacro( pCur
->GetExternal() );
3137 SfxObjectShell
* pDocSh
= pDok
->GetDocumentShell();
3138 if ( !pDocSh
|| !pDok
->CheckMacroWarn() )
3140 PushNoValue(); // ohne DocShell kein CallBasic
3144 // keine Sicherheitsabfrage mehr vorneweg (nur CheckMacroWarn), das passiert im CallBasic
3146 // Wenn das Dok waehrend eines Basic-Calls geladen wurde,
3147 // ist das Sbx-Objekt evtl. nicht angelegt (?)
3148 // pDocSh->GetSbxObject();
3150 // Funktion ueber den einfachen Namen suchen,
3151 // dann aBasicStr, aMacroStr fuer SfxObjectShell::CallBasic zusammenbauen
3153 StarBASIC
* pRoot
= pDocSh
->GetBasic();
3154 SbxVariable
* pVar
= pRoot
->Find( aMacro
, SbxCLASS_METHOD
);
3155 if( !pVar
|| pVar
->GetType() == SbxVOID
|| !pVar
->ISA(SbMethod
) )
3157 PushError( errNoMacro
);
3161 bool bVolatileMacro
= false;
3162 SbMethod
* pMethod
= (SbMethod
*)pVar
;
3164 SbModule
* pModule
= pMethod
->GetModule();
3165 bool bUseVBAObjects
= pModule
->IsVBACompat();
3166 SbxObject
* pObject
= pModule
->GetParent();
3167 OSL_ENSURE(pObject
->IsA(TYPE(StarBASIC
)), "No Basic found!");
3168 OUString aMacroStr
= pObject
->GetName() + "." + pModule
->GetName() + "." + pMethod
->GetName();
3170 if (pObject
->GetParent())
3172 aBasicStr
= pObject
->GetParent()->GetName(); // Dokumentenbasic
3176 aBasicStr
= SFX_APP()->GetName(); // Applikationsbasic
3178 // Parameter-Array zusammenbauen
3180 SbxArrayRef refPar
= new SbxArray
;
3182 for( short i
= nParamCount
; i
&& bOk
; i
-- )
3184 SbxVariable
* pPar
= refPar
->Get( (sal_uInt16
) i
);
3185 sal_uInt8 nStackType
= sal::static_int_cast
<sal_uInt8
>( GetStackType() );
3186 switch( nStackType
)
3189 pPar
->PutDouble( GetDouble() );
3192 pPar
->PutString( GetString().getString() );
3194 case svExternalSingleRef
:
3196 ScExternalRefCache::TokenRef pToken
;
3197 PopExternalSingleRef(pToken
);
3198 if ( pToken
->GetType() == svString
)
3199 pPar
->PutString( pToken
->GetString().getString() );
3200 else if ( pToken
->GetType() == svDouble
)
3201 pPar
->PutDouble( pToken
->GetDouble() );
3204 SetError( errIllegalArgument
);
3212 PopSingleRef( aAdr
);
3213 if ( bUseVBAObjects
)
3215 ScRange
aRange( aAdr
);
3216 bOk
= lcl_setVBARange( aRange
, pDok
, pPar
);
3220 bOk
= SetSbxVariable( pPar
, aAdr
);
3232 PopDoubleRef( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
3233 if( nTab1
!= nTab2
)
3235 SetError( errIllegalParameter
);
3240 if ( bUseVBAObjects
)
3242 ScRange
aRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
3243 bOk
= lcl_setVBARange( aRange
, pDok
, pPar
);
3247 SbxDimArrayRef refArray
= new SbxDimArray
;
3248 refArray
->AddDim32( 1, nRow2
- nRow1
+ 1 );
3249 refArray
->AddDim32( 1, nCol2
- nCol1
+ 1 );
3250 ScAddress
aAdr( nCol1
, nRow1
, nTab1
);
3251 for( SCROW nRow
= nRow1
; bOk
&& nRow
<= nRow2
; nRow
++ )
3253 aAdr
.SetRow( nRow
);
3254 sal_Int32 nIdx
[ 2 ];
3255 nIdx
[ 0 ] = nRow
-nRow1
+1;
3256 for( SCCOL nCol
= nCol1
; bOk
&& nCol
<= nCol2
; nCol
++ )
3258 aAdr
.SetCol( nCol
);
3259 nIdx
[ 1 ] = nCol
-nCol1
+1;
3260 SbxVariable
* p
= refArray
->Get32( nIdx
);
3261 bOk
= SetSbxVariable( p
, aAdr
);
3264 pPar
->PutObject( refArray
);
3269 case svExternalDoubleRef
:
3272 ScMatrixRef pMat
= GetMatrix();
3274 if (pMat
&& !nGlobalError
)
3276 pMat
->GetDimensions(nC
, nR
);
3277 SbxDimArrayRef refArray
= new SbxDimArray
;
3278 refArray
->AddDim32( 1, static_cast<sal_Int32
>(nR
) );
3279 refArray
->AddDim32( 1, static_cast<sal_Int32
>(nC
) );
3280 for( SCSIZE nMatRow
= 0; nMatRow
< nR
; nMatRow
++ )
3282 sal_Int32 nIdx
[ 2 ];
3283 nIdx
[ 0 ] = static_cast<sal_Int32
>(nMatRow
+1);
3284 for( SCSIZE nMatCol
= 0; nMatCol
< nC
; nMatCol
++ )
3286 nIdx
[ 1 ] = static_cast<sal_Int32
>(nMatCol
+1);
3287 SbxVariable
* p
= refArray
->Get32( nIdx
);
3288 if (pMat
->IsString(nMatCol
, nMatRow
))
3290 p
->PutString( pMat
->GetString(nMatCol
, nMatRow
).getString() );
3294 p
->PutDouble( pMat
->GetDouble(nMatCol
, nMatRow
));
3298 pPar
->PutObject( refArray
);
3302 SetError( errIllegalParameter
);
3307 SetError( errIllegalParameter
);
3313 pDok
->LockTable( aPos
.Tab() );
3314 SbxVariableRef refRes
= new SbxVariable
;
3315 pDok
->IncMacroInterpretLevel();
3316 ErrCode eRet
= pDocSh
->CallBasic( aMacroStr
, aBasicStr
, refPar
, refRes
);
3317 pDok
->DecMacroInterpretLevel();
3318 pDok
->UnlockTable( aPos
.Tab() );
3320 ScMacroManager
* pMacroMgr
= pDok
->GetMacroManager();
3323 bVolatileMacro
= pMacroMgr
->GetUserFuncVolatile( pMethod
->GetName() );
3324 pMacroMgr
->AddDependentCell(pModule
->GetName(), pMyFormulaCell
);
3327 SbxDataType eResType
= refRes
->GetType();
3328 if( pVar
->GetError() )
3330 SetError( errNoValue
);
3332 if ( eRet
!= ERRCODE_NONE
)
3336 else if( eResType
>= SbxINTEGER
&& eResType
<= SbxDOUBLE
)
3338 PushDouble( refRes
->GetDouble() );
3340 else if ( eResType
& SbxARRAY
)
3342 SbxBase
* pElemObj
= refRes
->GetObject();
3343 SbxDimArray
* pDimArray
= PTR_CAST(SbxDimArray
,pElemObj
);
3344 short nDim
= pDimArray
->GetDims();
3345 if ( 1 <= nDim
&& nDim
<= 2 )
3347 sal_Int32 nCs
, nCe
, nRs
, nRe
;
3352 { // array( cols ) eine Zeile, mehrere Spalten
3353 pDimArray
->GetDim32( 1, nCs
, nCe
);
3354 nC
= static_cast<SCSIZE
>(nCe
- nCs
+ 1);
3361 { // array( rows, cols )
3362 pDimArray
->GetDim32( 1, nRs
, nRe
);
3363 nR
= static_cast<SCSIZE
>(nRe
- nRs
+ 1);
3364 pDimArray
->GetDim32( 2, nCs
, nCe
);
3365 nC
= static_cast<SCSIZE
>(nCe
- nCs
+ 1);
3369 ScMatrixRef pMat
= GetNewMat( nC
, nR
);
3374 for ( SCSIZE j
=0; j
< nR
; j
++ )
3376 sal_Int32 nIdx
[ 2 ];
3377 // bei eindimensionalem array( cols ) wird nIdx[1]
3378 // von SbxDimArray::Get ignoriert
3379 nIdx
[ nRowIdx
] = nRs
+ static_cast<sal_Int32
>(j
);
3380 for ( SCSIZE i
=0; i
< nC
; i
++ )
3382 nIdx
[ nColIdx
] = nCs
+ static_cast<sal_Int32
>(i
);
3383 pV
= pDimArray
->Get32( nIdx
);
3384 eType
= pV
->GetType();
3385 if ( eType
>= SbxINTEGER
&& eType
<= SbxDOUBLE
)
3387 pMat
->PutDouble( pV
->GetDouble(), i
, j
);
3391 pMat
->PutString(mrStrPool
.intern(pV
->GetOUString()), i
, j
);
3399 PushIllegalArgument();
3409 PushString( refRes
->GetOUString() );
3413 if (bVolatileMacro
&& meVolatileType
== NOT_VOLATILE
)
3414 meVolatileType
= VOLATILE_MACRO
;
3418 #ifndef DISABLE_SCRIPTING
3420 bool ScInterpreter::SetSbxVariable( SbxVariable
* pVar
, const ScAddress
& rPos
)
3423 ScRefCellValue aCell
;
3424 aCell
.assign(*pDok
, rPos
);
3425 if (!aCell
.isEmpty())
3429 switch (aCell
.meType
)
3431 case CELLTYPE_VALUE
:
3432 nVal
= GetValueCellValue(rPos
, aCell
.mfValue
);
3433 pVar
->PutDouble( nVal
);
3435 case CELLTYPE_STRING
:
3436 case CELLTYPE_EDIT
:
3437 pVar
->PutString(aCell
.getString(pDok
));
3439 case CELLTYPE_FORMULA
:
3440 nErr
= aCell
.mpFormula
->GetErrCode();
3443 if (aCell
.mpFormula
->IsValue())
3445 nVal
= aCell
.mpFormula
->GetValue();
3446 pVar
->PutDouble(aCell
.mpFormula
->GetValue());
3449 pVar
->PutString(aCell
.mpFormula
->GetString().getString());
3452 SetError( nErr
), bOk
= false;
3455 pVar
->PutDouble( 0.0 );
3459 pVar
->PutDouble( 0.0 );
3467 class FindByPointer
: ::std::unary_function
<ScInterpreterTableOpParams
, bool>
3469 const ScInterpreterTableOpParams
* mpTableOp
;
3471 FindByPointer(const ScInterpreterTableOpParams
* p
) : mpTableOp(p
) {}
3472 bool operator() (const ScInterpreterTableOpParams
& val
) const
3474 return &val
== mpTableOp
;
3480 void ScInterpreter::ScTableOp()
3482 sal_uInt8 nParamCount
= GetByte();
3483 if (nParamCount
!= 3 && nParamCount
!= 5)
3485 PushIllegalParameter();
3488 ScInterpreterTableOpParams
* pTableOp
= new ScInterpreterTableOpParams
;
3489 if (nParamCount
== 5)
3491 PopSingleRef( pTableOp
->aNew2
);
3492 PopSingleRef( pTableOp
->aOld2
);
3494 PopSingleRef( pTableOp
->aNew1
);
3495 PopSingleRef( pTableOp
->aOld1
);
3496 PopSingleRef( pTableOp
->aFormulaPos
);
3498 pTableOp
->bValid
= true;
3499 pDok
->aTableOpList
.push_back( pTableOp
);
3500 pDok
->IncInterpreterTableOpLevel();
3502 bool bReuseLastParams
= (pDok
->aLastTableOpParams
== *pTableOp
);
3503 if ( bReuseLastParams
)
3505 pTableOp
->aNotifiedFormulaPos
= pDok
->aLastTableOpParams
.aNotifiedFormulaPos
;
3506 pTableOp
->bRefresh
= true;
3507 for ( ::std::vector
< ScAddress
>::const_iterator
iBroadcast(
3508 pTableOp
->aNotifiedFormulaPos
.begin() );
3509 iBroadcast
!= pTableOp
->aNotifiedFormulaPos
.end();
3511 { // emulate broadcast and indirectly collect cell pointers
3512 ScRefCellValue aCell
;
3513 aCell
.assign(*pDok
, *iBroadcast
);
3514 if (aCell
.meType
== CELLTYPE_FORMULA
)
3515 aCell
.mpFormula
->SetTableOpDirty();
3519 { // broadcast and indirectly collect cell pointers and positions
3520 pDok
->SetTableOpDirty( pTableOp
->aOld1
);
3521 if ( nParamCount
== 5 )
3522 pDok
->SetTableOpDirty( pTableOp
->aOld2
);
3524 pTableOp
->bCollectNotifications
= false;
3526 ScRefCellValue aCell
;
3527 aCell
.assign(*pDok
, pTableOp
->aFormulaPos
);
3528 if (aCell
.meType
== CELLTYPE_FORMULA
)
3529 aCell
.mpFormula
->SetDirtyVar();
3530 if (aCell
.hasNumeric())
3532 PushDouble(GetCellValue(pTableOp
->aFormulaPos
, aCell
));
3536 svl::SharedString aCellString
;
3537 GetCellString(aCellString
, aCell
);
3538 PushString( aCellString
);
3541 boost::ptr_vector
< ScInterpreterTableOpParams
>::iterator itr
=
3542 ::std::find_if(pDok
->aTableOpList
.begin(), pDok
->aTableOpList
.end(), FindByPointer(pTableOp
));
3543 if (itr
!= pDok
->aTableOpList
.end())
3544 pTableOp
= pDok
->aTableOpList
.release(itr
).release();
3546 // set dirty again once more to be able to recalculate original
3547 for ( ::std::vector
< ScFormulaCell
* >::const_iterator
iBroadcast(
3548 pTableOp
->aNotifiedFormulaCells
.begin() );
3549 iBroadcast
!= pTableOp
->aNotifiedFormulaCells
.end();
3552 (*iBroadcast
)->SetTableOpDirty();
3555 // save these params for next incarnation
3556 if ( !bReuseLastParams
)
3557 pDok
->aLastTableOpParams
= *pTableOp
;
3559 if (aCell
.meType
== CELLTYPE_FORMULA
)
3561 aCell
.mpFormula
->SetDirtyVar();
3562 aCell
.mpFormula
->GetErrCode(); // recalculate original
3565 // Reset all dirty flags so next incarnation does really collect all cell
3566 // pointers during notifications and not just non-dirty ones, which may
3567 // happen if a formula cell is used by more than one TableOp block.
3568 for ( ::std::vector
< ScFormulaCell
* >::const_iterator
iBroadcast2(
3569 pTableOp
->aNotifiedFormulaCells
.begin() );
3570 iBroadcast2
!= pTableOp
->aNotifiedFormulaCells
.end();
3573 (*iBroadcast2
)->ResetTableOpDirtyVar();
3577 pDok
->DecInterpreterTableOpLevel();
3580 void ScInterpreter::ScDBArea()
3582 ScDBData
* pDBData
= pDok
->GetDBCollection()->getNamedDBs().findByIndex(pCur
->GetIndex());
3585 ScComplexRefData aRefData
;
3586 aRefData
.InitFlags();
3588 pDBData
->GetArea(aRange
);
3589 aRange
.aEnd
.SetTab(aRange
.aStart
.Tab());
3590 aRefData
.SetRange(aRange
, aPos
);
3591 PushTempToken( new ScDoubleRefToken( aRefData
) );
3594 PushError( errNoName
);
3598 void ScInterpreter::ScColRowNameAuto()
3600 ScComplexRefData
aRefData( static_cast<const ScToken
*>(pCur
)->GetDoubleRef() );
3601 ScRange aAbs
= aRefData
.toAbs(aPos
);
3602 if (!ValidRange(aAbs
))
3604 PushError( errNoRef
);
3611 // evtl. Begrenzung durch definierte ColRowNameRanges merken
3612 SCsCOL nCol2
= aAbs
.aEnd
.Col();
3613 SCsROW nRow2
= aAbs
.aEnd
.Row();
3614 // DataArea of the first cell
3615 nStartCol
= aAbs
.aStart
.Col();
3616 nStartRow
= aAbs
.aStart
.Row();
3617 aAbs
.aEnd
= aAbs
.aStart
; // Shrink to the top-left cell.
3620 // Expand to the data area. Only modify the end position.
3621 SCCOL nDACol1
= aAbs
.aStart
.Col(), nDACol2
= aAbs
.aEnd
.Col();
3622 SCROW nDARow1
= aAbs
.aStart
.Row(), nDARow2
= aAbs
.aEnd
.Row();
3623 pDok
->GetDataArea(aAbs
.aStart
.Tab(), nDACol1
, nDARow1
, nDACol2
, nDARow2
, true, false);
3624 aAbs
.aEnd
.SetCol(nDACol2
);
3625 aAbs
.aEnd
.SetRow(nDARow2
);
3628 //! korrespondiert mit ScCompiler::GetToken
3629 if ( aRefData
.Ref1
.IsColRel() )
3631 aAbs
.aEnd
.SetCol(nStartCol
);
3632 // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten
3633 if (aAbs
.aEnd
.Row() > nRow2
)
3634 aAbs
.aEnd
.SetRow(nRow2
);
3636 if ( aPos
.Col() == nStartCol
3637 && nStartRow
<= (nMyRow
= aPos
.Row()) && nMyRow
<= aAbs
.aEnd
.Row())
3638 { // Formel in gleicher Spalte und innerhalb des Range
3639 if ( nMyRow
== nStartRow
)
3640 { // direkt unter dem Namen den Rest nehmen
3642 if ( nStartRow
> MAXROW
)
3644 aAbs
.aStart
.SetRow(nStartRow
);
3647 { // weiter unten vom Namen bis zur Formelzelle
3648 aAbs
.aEnd
.SetRow(nMyRow
- 1);
3654 aAbs
.aEnd
.SetRow(nStartRow
);
3655 // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten
3656 if (aAbs
.aEnd
.Col() > nCol2
)
3657 aAbs
.aEnd
.SetCol(nCol2
);
3659 if ( aPos
.Row() == nStartRow
3660 && nStartCol
<= (nMyCol
= aPos
.Col()) && nMyCol
<= aAbs
.aEnd
.Col())
3661 { // Formel in gleicher Zeile und innerhalb des Range
3662 if ( nMyCol
== nStartCol
)
3663 { // direkt neben dem Namen den Rest nehmen
3665 if ( nStartCol
> MAXCOL
)
3667 aAbs
.aStart
.SetCol(nStartCol
);
3670 { // weiter rechts vom Namen bis zur Formelzelle
3671 aAbs
.aEnd
.SetCol(nMyCol
- 1);
3675 aRefData
.SetRange(aAbs
, aPos
);
3676 PushTempToken( new ScDoubleRefToken( aRefData
) );
3679 // --- internals ------------------------------------------------------------
3682 void ScInterpreter::ScTTT()
3683 { // Temporaerer Test-Tanz, zum auspropieren von Funktionen etc.
3684 sal_uInt8 nParamCount
= GetByte();
3685 // do something, nParamCount bei Pops runterzaehlen!
3688 while ( nParamCount
-- > 0)
3690 PushError(errNoValue
);
3693 // -------------------------------------------------------------------------
3696 ScInterpreter::ScInterpreter( ScFormulaCell
* pCell
, ScDocument
* pDoc
,
3697 const ScAddress
& rPos
, ScTokenArray
& r
) :
3702 mrStrPool(pDoc
->GetSharedStringPool()),
3703 pTokenMatrixMap( NULL
),
3704 pMyFormulaCell( pCell
),
3705 pFormatter( pDoc
->GetFormatTable() ),
3706 mnStringNoValueError( errNoValue
),
3707 bCalcAsShown( pDoc
->GetDocOptions().IsCalcAsShown() ),
3708 meVolatileType(r
.IsRecalcModeAlways() ? VOLATILE
: NOT_VOLATILE
)
3713 sal_uInt8 cMatFlag
= pMyFormulaCell
->GetMatrixFlag();
3714 bMatrixFormula
= ( cMatFlag
== MM_FORMULA
|| cMatFlag
== MM_FAKE
);
3717 bMatrixFormula
= false;
3719 if (!bGlobalStackInUse
)
3721 bGlobalStackInUse
= true;
3723 pGlobalStack
= new ScTokenStack
;
3724 pStackObj
= pGlobalStack
;
3728 pStackObj
= new ScTokenStack
;
3730 pStack
= pStackObj
->pPointer
;
3733 ScInterpreter::~ScInterpreter()
3737 if ( pStackObj
== pGlobalStack
)
3738 bGlobalStackInUse
= false;
3741 if (pTokenMatrixMap
)
3742 delete pTokenMatrixMap
;
3745 void ScInterpreter::SetGlobalConfig(const ScCalcConfig
& rConfig
)
3747 maGlobalConfig
= rConfig
;
3750 const ScCalcConfig
& ScInterpreter::GetGlobalConfig()
3752 return maGlobalConfig
;
3755 void ScInterpreter::GlobalExit()
3757 OSL_ENSURE(!bGlobalStackInUse
, "who is still using the TokenStack?");
3758 DELETEZ(pGlobalStack
);
3763 double applyImplicitIntersection(const sc::RangeMatrix
& rMat
, const ScAddress
& rPos
)
3765 if (rMat
.mnRow1
<= rPos
.Row() && rPos
.Row() <= rMat
.mnRow2
&& rMat
.mnCol1
== rMat
.mnCol2
)
3767 SCROW nOffset
= rPos
.Row() - rMat
.mnRow1
;
3768 return rMat
.mpMat
->GetDouble(0, nOffset
);
3771 if (rMat
.mnCol1
<= rPos
.Col() && rPos
.Col() <= rMat
.mnCol2
&& rMat
.mnRow1
== rMat
.mnRow2
)
3773 SCROW nOffset
= rPos
.Col() - rMat
.mnCol1
;
3774 return rMat
.mpMat
->GetDouble(nOffset
, 0);
3778 rtl::math::setNan(&fVal
);
3784 StackVar
ScInterpreter::Interpret()
3786 short nRetTypeExpr
= NUMBERFORMAT_UNDEFINED
;
3787 sal_uLong nRetIndexExpr
= 0;
3788 sal_uInt16 nErrorFunction
= 0;
3789 sal_uInt16 nErrorFunctionCount
= 0;
3790 sal_uInt16 nStackBase
;
3793 nStackBase
= sp
= maxsp
= 0;
3794 nRetFmtType
= NUMBERFORMAT_UNDEFINED
;
3795 nFuncFmtType
= NUMBERFORMAT_UNDEFINED
;
3796 nFuncFmtIndex
= nCurFmtIndex
= nRetFmtIndex
= 0;
3800 ScTokenMatrixMap::const_iterator aTokenMatrixMapIter
;
3802 // Once upon a time we used to have FP exceptions on, and there was a
3803 // Windows printer driver that kept switching off exceptions, so we had to
3804 // switch them back on again every time. Who knows if there isn't a driver
3805 // that keeps switching exceptions on, now that we run with exceptions off,
3806 // so reassure exceptions are really off.
3807 SAL_MATH_FPEXCEPTIONS_OFF();
3810 while( ( pCur
= aCode
.Next() ) != NULL
3811 && (!nGlobalError
|| nErrorFunction
<= nErrorFunctionCount
) )
3813 OpCode eOp
= pCur
->GetOpCode();
3814 cPar
= pCur
->GetByte();
3815 if ( eOp
== ocPush
)
3817 // RPN code push without error
3818 PushWithoutError( (FormulaToken
&) *pCur
);
3820 else if (pTokenMatrixMap
&&
3821 !(eOp
== ocIf
|| eOp
== ocIfError
|| eOp
== ocIfNA
|| eOp
== ocChose
) &&
3822 ((aTokenMatrixMapIter
= pTokenMatrixMap
->find( pCur
)) !=
3823 pTokenMatrixMap
->end()) &&
3824 (*aTokenMatrixMapIter
).second
->GetType() != svJumpMatrix
)
3826 // Path already calculated, reuse result.
3827 nStackBase
= sp
- pCur
->GetParamCount();
3828 if ( nStackBase
> sp
)
3829 nStackBase
= sp
; // underflow?!?
3831 PushTempToken( (*aTokenMatrixMapIter
).second
.get());
3835 // previous expression determines the current number format
3836 nCurFmtType
= nRetTypeExpr
;
3837 nCurFmtIndex
= nRetIndexExpr
;
3838 // default function's format, others are set if needed
3839 nFuncFmtType
= NUMBERFORMAT_NUMBER
;
3842 if ( eOp
== ocIf
|| eOp
== ocChose
|| eOp
== ocIfError
|| eOp
== ocIfNA
)
3843 nStackBase
= sp
; // don't mess around with the jumps
3846 // Convert parameters to matrix if in array/matrix formula and
3847 // parameters of function indicate doing so. Create JumpMatrix
3849 if ( MatrixParameterConversion() )
3851 eOp
= ocNone
; // JumpMatrix created
3855 nStackBase
= sp
- pCur
->GetParamCount();
3857 if ( nStackBase
> sp
)
3858 nStackBase
= sp
; // underflow?!?
3863 case ocClose
: // pushed by the compiler
3864 case ocMissing
: ScMissing(); break;
3865 case ocMacro
: ScMacro(); break;
3866 case ocDBArea
: ScDBArea(); break;
3867 case ocColRowNameAuto
: ScColRowNameAuto(); break;
3868 case ocIf
: ScIfJump(); break;
3869 case ocIfError
: ScIfError( false ); break;
3870 case ocIfNA
: ScIfError( true ); break;
3871 case ocChose
: ScChoseJump(); break;
3872 case ocAdd
: ScAdd(); break;
3873 case ocSub
: ScSub(); break;
3874 case ocMul
: ScMul(); break;
3875 case ocDiv
: ScDiv(); break;
3876 case ocAmpersand
: ScAmpersand(); break;
3877 case ocPow
: ScPow(); break;
3878 case ocEqual
: ScEqual(); break;
3879 case ocNotEqual
: ScNotEqual(); break;
3880 case ocLess
: ScLess(); break;
3881 case ocGreater
: ScGreater(); break;
3882 case ocLessEqual
: ScLessEqual(); break;
3883 case ocGreaterEqual
: ScGreaterEqual(); break;
3884 case ocAnd
: ScAnd(); break;
3885 case ocOr
: ScOr(); break;
3886 case ocXor
: ScXor(); break;
3887 case ocIntersect
: ScIntersect(); break;
3888 case ocRange
: ScRangeFunc(); break;
3889 case ocUnion
: ScUnionFunc(); break;
3890 case ocNot
: ScNot(); break;
3892 case ocNeg
: ScNeg(); break;
3893 case ocPercentSign
: ScPercentSign(); break;
3894 case ocPi
: ScPi(); break;
3895 case ocRandom
: ScRandom(); break;
3896 case ocTrue
: ScTrue(); break;
3897 case ocFalse
: ScFalse(); break;
3898 case ocGetActDate
: ScGetActDate(); break;
3899 case ocGetActTime
: ScGetActTime(); break;
3900 case ocNotAvail
: PushError( NOTAVAILABLE
); break;
3901 case ocDeg
: ScDeg(); break;
3902 case ocRad
: ScRad(); break;
3903 case ocSin
: ScSin(); break;
3904 case ocCos
: ScCos(); break;
3905 case ocTan
: ScTan(); break;
3906 case ocCot
: ScCot(); break;
3907 case ocArcSin
: ScArcSin(); break;
3908 case ocArcCos
: ScArcCos(); break;
3909 case ocArcTan
: ScArcTan(); break;
3910 case ocArcCot
: ScArcCot(); break;
3911 case ocSinHyp
: ScSinHyp(); break;
3912 case ocCosHyp
: ScCosHyp(); break;
3913 case ocTanHyp
: ScTanHyp(); break;
3914 case ocCotHyp
: ScCotHyp(); break;
3915 case ocArcSinHyp
: ScArcSinHyp(); break;
3916 case ocArcCosHyp
: ScArcCosHyp(); break;
3917 case ocArcTanHyp
: ScArcTanHyp(); break;
3918 case ocArcCotHyp
: ScArcCotHyp(); break;
3919 case ocCosecant
: ScCosecant(); break;
3920 case ocSecant
: ScSecant(); break;
3921 case ocCosecantHyp
: ScCosecantHyp(); break;
3922 case ocSecantHyp
: ScSecantHyp(); break;
3923 case ocExp
: ScExp(); break;
3924 case ocLn
: ScLn(); break;
3925 case ocLog10
: ScLog10(); break;
3926 case ocSqrt
: ScSqrt(); break;
3927 case ocFact
: ScFact(); break;
3928 case ocGetYear
: ScGetYear(); break;
3929 case ocGetMonth
: ScGetMonth(); break;
3930 case ocGetDay
: ScGetDay(); break;
3931 case ocGetDayOfWeek
: ScGetDayOfWeek(); break;
3932 case ocWeek
: ScGetWeekOfYear(); break;
3933 case ocEasterSunday
: ScEasterSunday(); break;
3934 case ocGetHour
: ScGetHour(); break;
3935 case ocGetMin
: ScGetMin(); break;
3936 case ocGetSec
: ScGetSec(); break;
3937 case ocPlusMinus
: ScPlusMinus(); break;
3938 case ocAbs
: ScAbs(); break;
3939 case ocInt
: ScInt(); break;
3940 case ocEven
: ScEven(); break;
3941 case ocOdd
: ScOdd(); break;
3942 case ocPhi
: ScPhi(); break;
3943 case ocGauss
: ScGauss(); break;
3944 case ocStdNormDist
: ScStdNormDist(); break;
3945 case ocFisher
: ScFisher(); break;
3946 case ocFisherInv
: ScFisherInv(); break;
3947 case ocIsEmpty
: ScIsEmpty(); break;
3948 case ocIsString
: ScIsString(); break;
3949 case ocIsNonString
: ScIsNonString(); break;
3950 case ocIsLogical
: ScIsLogical(); break;
3951 case ocType
: ScType(); break;
3952 case ocCell
: ScCell(); break;
3953 case ocIsRef
: ScIsRef(); break;
3954 case ocIsValue
: ScIsValue(); break;
3955 case ocIsFormula
: ScIsFormula(); break;
3956 case ocFormula
: ScFormula(); break;
3957 case ocIsNA
: ScIsNV(); break;
3958 case ocIsErr
: ScIsErr(); break;
3959 case ocIsError
: ScIsError(); break;
3960 case ocIsEven
: ScIsEven(); break;
3961 case ocIsOdd
: ScIsOdd(); break;
3962 case ocN
: ScN(); break;
3963 case ocGetDateValue
: ScGetDateValue(); break;
3964 case ocGetTimeValue
: ScGetTimeValue(); break;
3965 case ocCode
: ScCode(); break;
3966 case ocTrim
: ScTrim(); break;
3967 case ocUpper
: ScUpper(); break;
3968 case ocPropper
: ScPropper(); break;
3969 case ocLower
: ScLower(); break;
3970 case ocLen
: ScLen(); break;
3971 case ocT
: ScT(); break;
3972 case ocClean
: ScClean(); break;
3973 case ocValue
: ScValue(); break;
3974 case ocNumberValue
: ScNumberValue(); break;
3975 case ocChar
: ScChar(); break;
3976 case ocArcTan2
: ScArcTan2(); break;
3977 case ocMod
: ScMod(); break;
3978 case ocPower
: ScPower(); break;
3979 case ocRound
: ScRound(); break;
3980 case ocRoundUp
: ScRoundUp(); break;
3982 case ocRoundDown
: ScRoundDown(); break;
3983 case ocCeil
: ScCeil(); break;
3984 case ocFloor
: ScFloor(); break;
3985 case ocSumProduct
: ScSumProduct(); break;
3986 case ocSumSQ
: ScSumSQ(); break;
3987 case ocSumX2MY2
: ScSumX2MY2(); break;
3988 case ocSumX2DY2
: ScSumX2DY2(); break;
3989 case ocSumXMY2
: ScSumXMY2(); break;
3990 case ocLog
: ScLog(); break;
3991 case ocGCD
: ScGCD(); break;
3992 case ocLCM
: ScLCM(); break;
3993 case ocGetDate
: ScGetDate(); break;
3994 case ocGetTime
: ScGetTime(); break;
3995 case ocGetDiffDate
: ScGetDiffDate(); break;
3996 case ocGetDiffDate360
: ScGetDiffDate360(); break;
3997 case ocGetDateDif
: ScGetDateDif(); break;
3998 case ocMin
: ScMin( false ); break;
3999 case ocMinA
: ScMin( true ); break;
4000 case ocMax
: ScMax( false ); break;
4001 case ocMaxA
: ScMax( true ); break;
4002 case ocSum
: ScSum(); break;
4003 case ocProduct
: ScProduct(); break;
4004 case ocNPV
: ScNPV(); break;
4005 case ocIRR
: ScIRR(); break;
4006 case ocMIRR
: ScMIRR(); break;
4007 case ocISPMT
: ScISPMT(); break;
4008 case ocAverage
: ScAverage( false ); break;
4009 case ocAverageA
: ScAverage( true ); break;
4010 case ocCount
: ScCount(); break;
4011 case ocCount2
: ScCount2(); break;
4013 case ocVarS
: ScVar( false ); break;
4014 case ocVarA
: ScVar( true ); break;
4016 case ocVarP_MS
: ScVarP( false ); break;
4017 case ocVarPA
: ScVarP( true ); break;
4019 case ocStDevS
: ScStDev( false ); break;
4020 case ocStDevA
: ScStDev( true ); break;
4022 case ocStDevP_MS
: ScStDevP( false ); break;
4023 case ocStDevPA
: ScStDevP( true ); break;
4024 case ocBW
: ScBW(); break;
4025 case ocDIA
: ScDIA(); break;
4026 case ocGDA
: ScGDA(); break;
4027 case ocGDA2
: ScGDA2(); break;
4028 case ocVBD
: ScVDB(); break;
4029 case ocLaufz
: ScLaufz(); break;
4030 case ocLIA
: ScLIA(); break;
4031 case ocRMZ
: ScRMZ(); break;
4032 case ocColumns
: ScColumns(); break;
4033 case ocRows
: ScRows(); break;
4034 case ocTables
: ScTables(); break;
4035 case ocColumn
: ScColumn(); break;
4036 case ocRow
: ScRow(); break;
4037 case ocTable
: ScTable(); break;
4038 case ocZGZ
: ScZGZ(); break;
4039 case ocZW
: ScZW(); break;
4040 case ocZZR
: ScZZR(); break;
4041 case ocZins
: ScZins(); break;
4042 case ocFilterXML
: ScFilterXML(); break;
4043 case ocWebservice
: ScWebservice(); break;
4044 case ocZinsZ
: ScZinsZ(); break;
4045 case ocKapz
: ScKapz(); break;
4046 case ocKumZinsZ
: ScKumZinsZ(); break;
4047 case ocKumKapZ
: ScKumKapZ(); break;
4048 case ocEffektiv
: ScEffektiv(); break;
4049 case ocNominal
: ScNominal(); break;
4050 case ocSubTotal
: ScSubTotal(); break;
4051 case ocDBSum
: ScDBSum(); break;
4052 case ocDBCount
: ScDBCount(); break;
4053 case ocDBCount2
: ScDBCount2(); break;
4054 case ocDBAverage
: ScDBAverage(); break;
4055 case ocDBGet
: ScDBGet(); break;
4056 case ocDBMax
: ScDBMax(); break;
4057 case ocDBMin
: ScDBMin(); break;
4058 case ocDBProduct
: ScDBProduct(); break;
4059 case ocDBStdDev
: ScDBStdDev(); break;
4060 case ocDBStdDevP
: ScDBStdDevP(); break;
4061 case ocDBVar
: ScDBVar(); break;
4062 case ocDBVarP
: ScDBVarP(); break;
4063 case ocIndirect
: ScIndirect(); break;
4064 case ocAddress
: ScAddressFunc(); break;
4065 case ocMatch
: ScMatch(); break;
4066 case ocCountEmptyCells
: ScCountEmptyCells(); break;
4067 case ocCountIf
: ScCountIf(); break;
4068 case ocSumIf
: ScSumIf(); break;
4069 case ocAverageIf
: ScAverageIf(); break;
4070 case ocSumIfs
: ScSumIfs(); break;
4071 case ocAverageIfs
: ScAverageIfs(); break;
4072 case ocCountIfs
: ScCountIfs(); break;
4073 case ocLookup
: ScLookup(); break;
4074 case ocVLookup
: ScVLookup(); break;
4075 case ocHLookup
: ScHLookup(); break;
4076 case ocIndex
: ScIndex(); break;
4077 case ocMultiArea
: ScMultiArea(); break;
4078 case ocOffset
: ScOffset(); break;
4079 case ocAreas
: ScAreas(); break;
4080 case ocCurrency
: ScCurrency(); break;
4081 case ocReplace
: ScReplace(); break;
4082 case ocFixed
: ScFixed(); break;
4083 case ocFind
: ScFind(); break;
4084 case ocExact
: ScExact(); break;
4085 case ocLeft
: ScLeft(); break;
4086 case ocRight
: ScRight(); break;
4087 case ocSearch
: ScSearch(); break;
4088 case ocMid
: ScMid(); break;
4089 case ocText
: ScText(); break;
4090 case ocSubstitute
: ScSubstitute(); break;
4091 case ocRept
: ScRept(); break;
4092 case ocConcat
: ScConcat(); break;
4093 case ocMatValue
: ScMatValue(); break;
4094 case ocMatrixUnit
: ScEMat(); break;
4095 case ocMatDet
: ScMatDet(); break;
4096 case ocMatInv
: ScMatInv(); break;
4097 case ocMatMult
: ScMatMult(); break;
4098 case ocMatTrans
: ScMatTrans(); break;
4099 case ocMatRef
: ScMatRef(); break;
4100 case ocB
: ScB(); break;
4101 case ocNormDist
: ScNormDist(); break;
4103 case ocExpDist_MS
: ScExpDist(); break;
4105 case ocBinomDist_MS
: ScBinomDist(); break;
4106 case ocPoissonDist
:
4107 case ocPoissonDist_MS
: ScPoissonDist(); break;
4108 case ocKombin
: ScKombin(); break;
4109 case ocKombin2
: ScKombin2(); break;
4110 case ocVariationen
: ScVariationen(); break;
4111 case ocVariationen2
: ScVariationen2(); break;
4112 case ocHypGeomDist
: ScHypGeomDist(); break;
4113 case ocHypGeomDist_MS
: ScHypGeomDist_MS(); break;
4114 case ocLogNormDist
: ScLogNormDist(); break;
4115 case ocTDist
: ScTDist(); break;
4117 case ocFDist_RT
: ScFDist(); break;
4118 case ocFDist_LT
: ScFDist_LT(); break;
4120 case ocChiDist_MS
: ScChiDist(); break;
4121 case ocChiSqDist
: ScChiSqDist(); break;
4122 case ocChiSqDist_MS
: ScChiSqDist_MS(); break;
4123 case ocStandard
: ScStandard(); break;
4124 case ocAveDev
: ScAveDev(); break;
4125 case ocDevSq
: ScDevSq(); break;
4126 case ocKurt
: ScKurt(); break;
4127 case ocSchiefe
: ScSkew(); break;
4128 case ocSkewp
: ScSkewp(); break;
4129 case ocModalValue
: ScModalValue(); break;
4130 case ocMedian
: ScMedian(); break;
4131 case ocGeoMean
: ScGeoMean(); break;
4132 case ocHarMean
: ScHarMean(); break;
4134 case ocWeibull_MS
: ScWeibull(); break;
4136 case ocKritBinom
: ScCritBinom(); break;
4137 case ocNegBinomVert
: ScNegBinomDist(); break;
4138 case ocNoName
: ScNoName(); break;
4139 case ocBad
: ScBadName(); break;
4140 case ocZTest
: ScZTest(); break;
4141 case ocTTest
: ScTTest(); break;
4143 case ocFTest_MS
: ScFTest(); break;
4144 case ocRank
: ScRank(); break;
4145 case ocPercentile
: ScPercentile(); break;
4146 case ocPercentrank
: ScPercentrank(); break;
4147 case ocLarge
: ScLarge(); break;
4148 case ocSmall
: ScSmall(); break;
4149 case ocFrequency
: ScFrequency(); break;
4150 case ocQuartile
: ScQuartile(); break;
4151 case ocNormInv
: ScNormInv(); break;
4152 case ocSNormInv
: ScSNormInv(); break;
4154 case ocConfidence_N
: ScConfidence(); break;
4155 case ocConfidence_T
: ScConfidenceT(); break;
4156 case ocTrimMean
: ScTrimMean(); break;
4157 case ocProb
: ScProbability(); break;
4158 case ocCorrel
: ScCorrel(); break;
4160 case ocCovarianceP
: ScCovarianceP(); break;
4161 case ocCovarianceS
: ScCovarianceS(); break;
4162 case ocPearson
: ScPearson(); break;
4163 case ocRSQ
: ScRSQ(); break;
4164 case ocSTEYX
: ScSTEXY(); break;
4165 case ocSlope
: ScSlope(); break;
4166 case ocIntercept
: ScIntercept(); break;
4167 case ocTrend
: ScTrend(); break;
4168 case ocGrowth
: ScGrowth(); break;
4169 case ocRGP
: ScRGP(); break;
4170 case ocRKP
: ScRKP(); break;
4171 case ocForecast
: ScForecast(); break;
4172 case ocGammaLn
: ScLogGamma(); break;
4173 case ocGamma
: ScGamma(); break;
4174 case ocGammaDist
: ScGammaDist(); break;
4175 case ocGammaInv
: ScGammaInv(); break;
4177 case ocChiTest_MS
: ScChiTest(); break;
4179 case ocChiInv_MS
: ScChiInv(); break;
4181 case ocChiSqInv_MS
: ScChiSqInv(); break;
4182 case ocTInv
: ScTInv(); break;
4184 case ocFInv_RT
: ScFInv(); break;
4185 case ocFInv_LT
: ScFInv_LT(); break;
4186 case ocLogInv
: ScLogNormInv(); break;
4187 case ocBetaDist
: ScBetaDist(); break;
4188 case ocBetaDist_MS
: ScBetaDist_MS(); break;
4190 case ocBetaInv_MS
: ScBetaInv(); break;
4191 case ocExternal
: ScExternal(); break;
4192 case ocTableOp
: ScTableOp(); break;
4193 case ocStop
: break;
4194 case ocErrorType
: ScErrorType(); break;
4195 case ocCurrent
: ScCurrent(); break;
4196 case ocStyle
: ScStyle(); break;
4197 case ocDde
: ScDde(); break;
4198 case ocBase
: ScBase(); break;
4199 case ocDecimal
: ScDecimal(); break;
4200 case ocConvert
: ScConvert(); break;
4201 case ocEuroConvert
: ScEuroConvert(); break;
4202 case ocRoman
: ScRoman(); break;
4203 case ocArabic
: ScArabic(); break;
4204 case ocInfo
: ScInfo(); break;
4205 case ocHyperLink
: ScHyperLink(); break;
4206 case ocBahtText
: ScBahtText(); break;
4207 case ocGetPivotData
: ScGetPivotData(); break;
4208 case ocJis
: ScJis(); break;
4209 case ocAsc
: ScAsc(); break;
4210 case ocLenB
: ScLenB(); break;
4211 case ocRightB
: ScRightB(); break;
4212 case ocLeftB
: ScLeftB(); break;
4213 case ocMidB
: ScMidB(); break;
4214 case ocUnicode
: ScUnicode(); break;
4215 case ocUnichar
: ScUnichar(); break;
4216 case ocBitAnd
: ScBitAnd(); break;
4217 case ocBitOr
: ScBitOr(); break;
4218 case ocBitXor
: ScBitXor(); break;
4219 case ocBitRshift
: ScBitRshift(); break;
4220 case ocBitLshift
: ScBitLshift(); break;
4221 case ocTTT
: ScTTT(); break;
4222 case ocDebugVar
: ScDebugVar(); break;
4223 case ocNone
: nFuncFmtType
= NUMBERFORMAT_UNDEFINED
; break;
4224 default : PushError( errUnknownOpCode
); break;
4227 // If the function pushed a subroutine as result, continue with
4228 // execution of the subroutine.
4229 if (sp
> nStackBase
&& pStack
[sp
-1]->GetOpCode() == ocCall
4230 /* && pStack[sp-1]->GetType() == svSubroutine */)
4235 if (FormulaCompiler::IsOpCodeVolatile(eOp
))
4236 meVolatileType
= VOLATILE
;
4238 // Remember result matrix in case it could be reused.
4239 if (pTokenMatrixMap
&& sp
&& GetStackType() == svMatrix
)
4240 pTokenMatrixMap
->insert( ScTokenMatrixMap::value_type( pCur
,
4243 // outer function determines format of an expression
4244 if ( nFuncFmtType
!= NUMBERFORMAT_UNDEFINED
)
4246 nRetTypeExpr
= nFuncFmtType
;
4247 // inherit the format index only for currency formats
4248 nRetIndexExpr
= ( nFuncFmtType
== NUMBERFORMAT_CURRENCY
?
4249 nFuncFmtIndex
: 0 );
4253 // Need a clean stack environment for the JumpMatrix to work.
4254 if (nGlobalError
&& eOp
!= ocPush
&& sp
> nStackBase
+ 1)
4256 // Not all functions pop all parameters in case an error is
4257 // generated. Clean up stack. Assumes that every function pushes a
4258 // result, may be arbitrary in case of error.
4259 const FormulaToken
* pLocalResult
= pStack
[ sp
- 1 ];
4260 while (sp
> nStackBase
)
4262 PushTempToken( *pLocalResult
);
4269 sal_uInt8 nLevel
= 0;
4270 if ( GetStackType( ++nLevel
) == svJumpMatrix
)
4272 else if ( GetStackType( ++nLevel
) == svJumpMatrix
)
4276 if ( nLevel
== 1 || (nLevel
== 2 && aCode
.IsEndOfPath()) )
4277 bGotResult
= JumpMatrix( nLevel
);
4280 } while ( bGotResult
);
4283 // Functions that evaluate an error code and directly set nGlobalError to 0,
4284 // usage: switch( OpCode ) { CASE_OCERRFUNC statements; }
4285 #define CASE_OCERRFUNC \
4288 case ocErrorType : \
4292 case ocIsFormula : \
4293 case ocIsLogical : \
4295 case ocIsNonString : \
4313 if ( !nErrorFunctionCount
)
4314 { // count of errorcode functions in formula
4315 for ( FormulaToken
* t
= rArr
.FirstRPN(); t
; t
= rArr
.NextRPN() )
4317 switch ( t
->GetOpCode() )
4320 ++nErrorFunctionCount
;
4326 if ( nErrorFunction
>= nErrorFunctionCount
)
4327 ++nErrorFunction
; // that's it, error => terminate
4331 // End: obtain result
4335 pCur
= pStack
[ sp
-1 ];
4336 if( pCur
->GetOpCode() == ocPush
)
4338 switch( pCur
->GetType() )
4344 nGlobalError
= pCur
->GetError();
4347 if ( nFuncFmtType
== NUMBERFORMAT_UNDEFINED
)
4349 nRetTypeExpr
= NUMBERFORMAT_NUMBER
;
4354 nRetTypeExpr
= NUMBERFORMAT_TEXT
;
4360 PopSingleRef( aAdr
);
4362 PushCellResultToken( false, aAdr
,
4363 &nRetTypeExpr
, &nRetIndexExpr
);
4367 PopError(); // maybe #REF! takes precedence over #VALUE!
4368 PushError( errNoValue
);
4372 if ( bMatrixFormula
)
4373 { // create matrix for {=A1:A5}
4374 PopDoubleRefPushMatrix();
4375 ScMatrixRef xMat
= PopMatrix();
4376 QueryMatrixType(xMat
, nRetTypeExpr
, nRetIndexExpr
);
4381 PopDoubleRef( aRange
);
4383 if ( !nGlobalError
&& DoubleRefToPosSingleRef( aRange
, aAdr
))
4384 PushCellResultToken( false, aAdr
,
4385 &nRetTypeExpr
, &nRetIndexExpr
);
4389 case svExternalDoubleRef
:
4392 PopExternalDoubleRef(xMat
);
4393 QueryMatrixType(xMat
, nRetTypeExpr
, nRetIndexExpr
);
4398 sc::RangeMatrix aMat
= PopRangeMatrix();
4399 if (aMat
.isRangeValid())
4401 // This matrix represents a range reference. Apply implicit intersection.
4402 double fVal
= applyImplicitIntersection(aMat
, aPos
);
4403 if (rtl::math::isNan(fVal
))
4404 PushError(errCellNoValue
);
4409 // This is a normal matrix.
4410 QueryMatrixType(aMat
.mpMat
, nRetTypeExpr
, nRetIndexExpr
);
4413 case svExternalSingleRef
:
4415 ScExternalRefCache::TokenRef pToken
;
4416 ScExternalRefCache::CellFormat aFmt
;
4417 PopExternalSingleRef(pToken
, &aFmt
);
4421 PushTempToken(*pToken
);
4425 nFuncFmtType
= aFmt
.mnType
;
4426 nFuncFmtIndex
= aFmt
.mnIndex
;
4431 SetError( errUnknownStackVariable
);
4435 SetError( errUnknownStackVariable
);
4438 SetError( errNoCode
);
4440 if( nRetTypeExpr
!= NUMBERFORMAT_UNDEFINED
)
4442 nRetFmtType
= nRetTypeExpr
;
4443 nRetFmtIndex
= nRetIndexExpr
;
4445 else if( nFuncFmtType
!= NUMBERFORMAT_UNDEFINED
)
4447 nRetFmtType
= nFuncFmtType
;
4448 nRetFmtIndex
= nFuncFmtIndex
;
4451 nRetFmtType
= NUMBERFORMAT_NUMBER
;
4452 // inherit the format index only for currency formats
4453 if ( nRetFmtType
!= NUMBERFORMAT_CURRENCY
)
4456 if (nGlobalError
&& GetStackType() != svError
)
4457 PushError( nGlobalError
);
4459 // THE final result.
4460 xResult
= PopToken();
4462 xResult
= new FormulaErrorToken( errUnknownStackVariable
);
4464 // release tokens in expression stack
4465 FormulaToken
** p
= pStack
;
4469 StackVar eType
= xResult
->GetType();
4470 if (eType
== svMatrix
)
4471 // Results are immutable in case they would be reused as input for new
4473 static_cast<ScToken
*>(xResult
.get())->GetMatrix()->SetImmutable( true);
4477 svl::SharedString
ScInterpreter::GetStringResult() const
4479 return xResult
->GetString();
4482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */