1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: interpr4.cxx,v $
10 * $Revision: 1.57.92.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
33 // INCLUDE ---------------------------------------------------------------
35 #include <rangelst.hxx>
36 #include <sfx2/app.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <sfx2/objsh.hxx>
39 #include <sfx2/docfilt.hxx>
40 #include <basic/sbmeth.hxx>
41 #include <basic/sbmod.hxx>
42 #include <basic/sbstar.hxx>
43 #include <basic/sbx.hxx>
44 #include <basic/sbxobj.hxx>
45 #include <basic/sbuno.hxx>
46 #include <svtools/zforlist.hxx>
47 #include <tools/urlobj.hxx>
48 #include <rtl/logfile.hxx>
53 #include <com/sun/star/table/XCellRange.hpp>
54 #include <comphelper/processfactory.hxx>
56 #include "interpre.hxx"
58 #include "dbcolect.hxx"
60 #include "callform.hxx"
61 #include "addincol.hxx"
62 #include "document.hxx"
63 #include "dociter.hxx"
64 #include "docoptio.hxx"
65 #include "scmatrix.hxx"
66 #include "adiasync.hxx"
68 #include "cellsuno.hxx"
70 #include "rangeseq.hxx"
71 #include "addinlis.hxx"
72 #include "jumpmatrix.hxx"
73 #include "parclass.hxx"
74 #include "externalrefmgr.hxx"
75 #include "formula/FormulaCompiler.hxx"
76 #include "macromgr.hxx"
83 #include <vbahelper/vbahelper.hxx>
84 #include <basic/basmgr.hxx>
86 using namespace com::sun::star
;
87 using namespace formula
;
89 #define ADDIN_MAXSTRLEN 256
91 // Implementiert in ui\miscdlgs\teamdlg.cxx
93 extern void ShowTheTeam();
95 extern BOOL bOderSo
; // in GLOBAL.CXX
97 //-----------------------------static data -----------------
100 ScSpew
ScInterpreter::theSpew
;
103 //-------------------------------------------------------------------------
104 // Funktionen fuer den Zugriff auf das Document
105 //-------------------------------------------------------------------------
108 void ScInterpreter::ReplaceCell( ScAddress
& rPos
)
110 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ReplaceCell" );
111 ScInterpreterTableOpParams
* pTOp
= pDok
->aTableOpList
.First();
114 if ( rPos
== pTOp
->aOld1
)
119 else if ( rPos
== pTOp
->aOld2
)
125 pTOp
= pDok
->aTableOpList
.Next();
130 void ScInterpreter::ReplaceCell( SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
)
132 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ReplaceCell" );
133 ScAddress
aCellPos( rCol
, rRow
, rTab
);
134 ScInterpreterTableOpParams
* pTOp
= pDok
->aTableOpList
.First();
137 if ( aCellPos
== pTOp
->aOld1
)
139 rCol
= pTOp
->aNew1
.Col();
140 rRow
= pTOp
->aNew1
.Row();
141 rTab
= pTOp
->aNew1
.Tab();
144 else if ( aCellPos
== pTOp
->aOld2
)
146 rCol
= pTOp
->aNew2
.Col();
147 rRow
= pTOp
->aNew2
.Row();
148 rTab
= pTOp
->aNew2
.Tab();
152 pTOp
= pDok
->aTableOpList
.Next();
157 BOOL
ScInterpreter::IsTableOpInRange( const ScRange
& rRange
)
159 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::IsTableOpInRange" );
160 if ( rRange
.aStart
== rRange
.aEnd
)
161 return FALSE
; // not considered to be a range in TableOp sense
163 // we can't replace a single cell in a range
164 ScInterpreterTableOpParams
* pTOp
= pDok
->aTableOpList
.First();
167 if ( rRange
.In( pTOp
->aOld1
) )
169 if ( rRange
.In( pTOp
->aOld2
) )
171 pTOp
= pDok
->aTableOpList
.Next();
177 ULONG
ScInterpreter::GetCellNumberFormat( const ScAddress
& rPos
, const ScBaseCell
* pCell
)
179 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellNumberFormat" );
184 if ( pCell
->GetCellType() == CELLTYPE_FORMULA
)
185 nErr
= ((ScFormulaCell
*)pCell
)->GetErrCode();
188 nFormat
= pDok
->GetNumberFormat( rPos
);
189 if ( pCell
->GetCellType() == CELLTYPE_FORMULA
190 && ((nFormat
% SV_COUNTRY_LANGUAGE_OFFSET
) == 0) )
191 nFormat
= ((ScFormulaCell
*)pCell
)->GetStandardFormat( *pFormatter
,
196 nFormat
= pDok
->GetNumberFormat( rPos
);
204 // nur ValueCell, Formelzellen speichern das Ergebnis bereits gerundet
205 double ScInterpreter::GetValueCellValue( const ScAddress
& rPos
, const ScValueCell
* pCell
)
207 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetValueCellValue" );
208 double fVal
= pCell
->GetValue();
209 if ( bCalcAsShown
&& fVal
!= 0.0 )
211 ULONG nFormat
= pDok
->GetNumberFormat( rPos
);
212 fVal
= pDok
->RoundValueAsShown( fVal
, nFormat
);
218 double ScInterpreter::GetCellValue( const ScAddress
& rPos
, const ScBaseCell
* pCell
,
219 bool bNoValueAsError
, bool bBlankAsZero
)
221 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellValue" );
222 USHORT nErr
= nGlobalError
;
224 double nVal
= GetCellValueOrZero( rPos
, pCell
, bBlankAsZero
);
226 // no global error. good.
228 else if (nGlobalError
== errCellNoValue
)
229 // Internal cell-no-value error. If the caller wants to treat no
230 // value as error, then we need to translate this to a legitimate
231 // error number (#VALUE!). If not, we should re-assign the prior error
233 nGlobalError
= bNoValueAsError
? errNoValue
: nErr
;
238 double ScInterpreter::GetCellValueOrZero( const ScAddress
& rPos
, const ScBaseCell
* pCell
, bool bBlankAsZero
)
240 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellValueOrZero" );
244 CellType eType
= pCell
->GetCellType();
247 case CELLTYPE_FORMULA
:
249 ScFormulaCell
* pFCell
= (ScFormulaCell
*) pCell
;
250 USHORT nErr
= pFCell
->GetErrCode();
253 if (pFCell
->IsValue())
255 fValue
= pFCell
->GetValue();
256 pDok
->GetNumberFormatInfo( nCurFmtType
, nCurFmtIndex
,
262 pFCell
->GetString(aStr
);
263 sal_uInt32 nFIndex
= 0;
264 if (!pFormatter
->IsNumberFormat(aStr
, nFIndex
, fValue
))
266 SetError(errCellNoValue
);
280 fValue
= ((ScValueCell
*)pCell
)->GetValue();
281 nCurFmtIndex
= pDok
->GetNumberFormat( rPos
);
282 nCurFmtType
= pFormatter
->GetType( nCurFmtIndex
);
283 if ( bCalcAsShown
&& fValue
!= 0.0 )
284 fValue
= pDok
->RoundValueAsShown( fValue
, nCurFmtIndex
);
287 case CELLTYPE_STRING
:
289 #if 1 /* JEG : re-enable because compatibility is more important than consistency for this */
290 // Xcl does it, but SUM(A1:A2) differs from A1+A2. No good.
293 if ( eType
== CELLTYPE_STRING
)
294 ((ScStringCell
*)pCell
)->GetString( aStr
);
296 ((ScEditCell
*)pCell
)->GetString( aStr
);
297 sal_uInt32 nFIndex
= 0; // damit default Land/Spr.
298 if ( !pFormatter
->IsNumberFormat( aStr
, nFIndex
, fValue
) )
300 SetError(errCellNoValue
); /* CellNoValue is not really an error */
308 SetError(errCellNoValue
);
318 void ScInterpreter::GetCellString( String
& rStr
, const ScBaseCell
* pCell
)
320 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellString" );
324 switch (pCell
->GetCellType())
326 case CELLTYPE_STRING
:
327 ((ScStringCell
*) pCell
)->GetString(rStr
);
330 ((ScEditCell
*) pCell
)->GetString(rStr
);
332 case CELLTYPE_FORMULA
:
334 ScFormulaCell
* pFCell
= (ScFormulaCell
*) pCell
;
335 nErr
= pFCell
->GetErrCode();
336 if (pFCell
->IsValue())
338 double fVal
= pFCell
->GetValue();
339 ULONG nIndex
= pFormatter
->GetStandardFormat(
342 pFormatter
->GetInputLineString(fVal
, nIndex
, rStr
);
345 pFCell
->GetString(rStr
);
350 double fVal
= ((ScValueCell
*) pCell
)->GetValue();
351 ULONG nIndex
= pFormatter
->GetStandardFormat(
354 pFormatter
->GetInputLineString(fVal
, nIndex
, rStr
);
358 rStr
= ScGlobal::GetEmptyString();
363 rStr
= ScGlobal::GetEmptyString();
367 static sal_Bool
lcl_IsHalfWidthKatakana ( const String
& rString
)
369 sal_Int32 nLen
= rString
.Len();
371 for ( sal_Int32 i
= 0; i
< nLen
; ++i
)
373 if ( rString
.GetChar(i
) < 0xFF00 || rString
.GetChar(i
) > 0xFFEF )
380 static sal_Bool
lcl_IsFullWidthKatakana ( const String
& rString
)
382 sal_Int32 nLen
= rString
.Len();
384 for ( sal_Int32 i
= 0; i
< nLen
; ++i
)
386 if ( rString
.GetChar(i
) < 0x30A0 || rString
.GetChar(i
) > 0x30FF )
393 static sal_Bool
lcl_IsFullWidthHiragana ( const String
& rString
)
395 sal_Int32 nLen
= rString
.Len();
397 for ( sal_Int32 i
= 0; i
< nLen
; ++i
)
399 if ( rString
.GetChar(i
) < 0x3040 || rString
.GetChar(i
) > 0x309F )
406 static sal_uInt16
lcl_GetKanaType ( const String rText
)
408 sal_uInt16 aKanaType
= 0;
410 if ( lcl_IsHalfWidthKatakana ( rText
) )
412 else if ( lcl_IsFullWidthKatakana ( rText
) )
414 else if ( lcl_IsFullWidthHiragana ( rText
) )
420 static void lcl_ConvertToKatakana( ScDocument
* pDoc
, String
& rStr
)
422 sal_uInt16 nKanaType
= lcl_GetKanaType(rStr
);
423 sal_Int32 nType
= com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA
;
427 // half-width katakana or full-width alphabet.
428 nType
= com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH
;
431 // full-width hiragana.
432 nType
= com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA
;
436 // full-width katakana. no need to convert this.
439 utl::TransliterationWrapper
aTranslitarationWrapper( pDoc
->GetServiceManager(), nType
);
440 com::sun::star::uno::Sequence
<sal_Int32
> aOffsets
;
441 rStr
= aTranslitarationWrapper
.transliterate( rStr
, LANGUAGE_JAPANESE
, 0, rStr
.Len(), &aOffsets
);
444 static void lcl_GetPhoneticString ( ScDocument
*pDoc
, String
& rStr
, const ScBaseCell
* pCell
)
446 ScPhonetic aPhonetic
;
448 switch (pCell
->GetCellType())
450 case CELLTYPE_STRING
:
451 static_cast<const ScStringCell
*>(pCell
)->GetString(aBaseString
);
452 static_cast<const ScAsianStringCell
*>(pCell
)->GetPhonetic(aPhonetic
);
455 static_cast<const ScEditCell
*>(pCell
)->GetString(aBaseString
);
456 static_cast<const ScAsianEditCell
*>(pCell
)->GetPhonetic(aPhonetic
);
459 // Not a supported cell type.
463 if (aPhonetic
.IsEmpty())
464 // No phonetic string exists. Bail out.
467 const String
& rPhoneticString
= aPhonetic
.GetString();
468 PhoneticPortionVec portions
= aPhonetic
.GetPortions();
469 sal_uInt16 nPortionCount
= portions
.size();
472 if ( nPortionCount
> 0 )
475 for ( sal_uInt16 idx
= 0; idx
< nPortionCount
; ++idx
)
477 const PhoneticPortion
& portion
= portions
[idx
];
479 // Get the end position in the phonetic text.
480 sal_uInt16 nPhEndPos
= idx
< nPortionCount
-1 ? portions
[idx
+1].mncpa
: rPhoneticString
.Len();
482 tmpString
+= aBaseString
.Copy(pos
, portion
.mncpm
- pos
);
483 pos
= portion
.mncpm
+ portion
.mnccm
;
484 tmpString
+= rPhoneticString
.Copy(portion
.mncpa
, nPhEndPos
- portion
.mncpa
);
486 if ( pos
< aBaseString
.Len() )
487 tmpString
+= aBaseString
.Copy(pos
, aBaseString
.Len() - pos
);
491 tmpString
= rPhoneticString
;
495 switch ( lcl_GetKanaType ( rPhoneticString
))
498 nType
= com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH
;
501 nType
= com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA
;
504 nType
= com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA
;
507 nType
= com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA
;
511 utl::TransliterationWrapper
aTranslitarationWrapper( pDoc
->GetServiceManager(), nType
);
512 com::sun::star::uno::Sequence
<sal_Int32
> aOffsets
;
513 rStr
= aTranslitarationWrapper
.transliterate( tmpString
, LANGUAGE_JAPANESE
, 0, tmpString
.Len(), &aOffsets
);
516 void ScInterpreter::GetCellPhoneticString( String
& rStr
, const ScBaseCell
* pCell
)
521 switch ( pCell
->GetCellType() )
523 case CELLTYPE_STRING
:
524 if ( static_cast<const ScStringCell
*>(pCell
)->HasPhonetic() )
525 lcl_GetPhoneticString(pDok
, rStr
, pCell
);
528 static_cast<const ScStringCell
*>(pCell
)->GetString(rStr
);
529 lcl_ConvertToKatakana(pDok
, rStr
);
533 if ( static_cast<const ScEditCell
*>(pCell
)->HasPhonetic() )
534 lcl_GetPhoneticString(pDok
, rStr
, pCell
);
537 static_cast<const ScEditCell
*>(pCell
)->GetString(rStr
);
538 lcl_ConvertToKatakana(pDok
, rStr
);
542 rStr
= ScGlobal::GetEmptyString();
547 rStr
= ScGlobal::GetEmptyString();
551 BOOL
ScInterpreter::CreateDoubleArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
552 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
, BYTE
* pCellArr
)
554 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateDoubleArr" );
555 #if SC_ROWLIMIT_MORE_THAN_64K
559 USHORT
* p
= (USHORT
*) pCellArr
;
560 *p
++ = static_cast<USHORT
>(nCol1
);
561 *p
++ = static_cast<USHORT
>(nRow1
);
562 *p
++ = static_cast<USHORT
>(nTab1
);
563 *p
++ = static_cast<USHORT
>(nCol2
);
564 *p
++ = static_cast<USHORT
>(nRow2
);
565 *p
++ = static_cast<USHORT
>(nTab2
);
571 while (nTab
<= nTab2
)
575 while (nRow
<= nRow2
)
579 while (nCol
<= nCol2
)
582 ScBaseCell
* pCell
= pDok
->GetCell( aAdr
);
588 switch ( pCell
->GetCellType() )
590 case CELLTYPE_VALUE
:
591 nVal
= GetValueCellValue( aAdr
, (ScValueCell
*)pCell
);
593 case CELLTYPE_FORMULA
:
594 if (((ScFormulaCell
*)pCell
)->IsValue())
596 nErr
= ((ScFormulaCell
*)pCell
)->GetErrCode();
597 nVal
= ((ScFormulaCell
*)pCell
)->GetValue();
608 if ((nPos
+ (4 * sizeof(USHORT
)) + sizeof(double)) > MAXARRSIZE
)
610 *p
++ = static_cast<USHORT
>(nCol
);
611 *p
++ = static_cast<USHORT
>(nRow
);
612 *p
++ = static_cast<USHORT
>(nTab
);
614 memcpy( p
, &nVal
, sizeof(double));
615 nPos
+= 8 + sizeof(double);
616 p
= (USHORT
*) ( pCellArr
+ nPos
);
631 BOOL
ScInterpreter::CreateStringArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
632 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
635 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateStringArr" );
636 #if SC_ROWLIMIT_MORE_THAN_64K
640 USHORT
* p
= (USHORT
*) pCellArr
;
641 *p
++ = static_cast<USHORT
>(nCol1
);
642 *p
++ = static_cast<USHORT
>(nRow1
);
643 *p
++ = static_cast<USHORT
>(nTab1
);
644 *p
++ = static_cast<USHORT
>(nCol2
);
645 *p
++ = static_cast<USHORT
>(nRow2
);
646 *p
++ = static_cast<USHORT
>(nTab2
);
651 while (nTab
<= nTab2
)
654 while (nRow
<= nRow2
)
657 while (nCol
<= nCol2
)
660 pDok
->GetCell(nCol
, nRow
, nTab
, pCell
);
666 switch ( pCell
->GetCellType() )
668 case CELLTYPE_STRING
:
669 ((ScStringCell
*)pCell
)->GetString(aStr
);
672 ((ScEditCell
*)pCell
)->GetString(aStr
);
674 case CELLTYPE_FORMULA
:
675 if (!((ScFormulaCell
*)pCell
)->IsValue())
677 nErr
= ((ScFormulaCell
*)pCell
)->GetErrCode();
678 ((ScFormulaCell
*)pCell
)->GetString(aStr
);
689 ByteString
aTmp( aStr
, osl_getThreadTextEncoding() );
690 // In case the xub_StrLen will be longer than USHORT
691 // one day, and room for pad byte check.
692 if ( aTmp
.Len() > ((USHORT
)(~0)) - 2 )
694 // Append a 0-pad-byte if string length is not even
695 //! MUST be USHORT and not xub_StrLen
696 USHORT nStrLen
= (USHORT
) aTmp
.Len();
697 USHORT nLen
= ( nStrLen
+ 2 ) & ~1;
699 if (((ULONG
)nPos
+ (5 * sizeof(USHORT
)) + nLen
) > MAXARRSIZE
)
701 *p
++ = static_cast<USHORT
>(nCol
);
702 *p
++ = static_cast<USHORT
>(nRow
);
703 *p
++ = static_cast<USHORT
>(nTab
);
706 memcpy( p
, aTmp
.GetBuffer(), nStrLen
+ 1);
707 nPos
+= 10 + nStrLen
+ 1;
708 BYTE
* q
= ( pCellArr
+ nPos
);
711 p
= (USHORT
*) ( pCellArr
+ nPos
);
726 BOOL
ScInterpreter::CreateCellArr(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
727 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
730 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateCellArr" );
731 #if SC_ROWLIMIT_MORE_THAN_64K
735 USHORT
* p
= (USHORT
*) pCellArr
;
736 *p
++ = static_cast<USHORT
>(nCol1
);
737 *p
++ = static_cast<USHORT
>(nRow1
);
738 *p
++ = static_cast<USHORT
>(nTab1
);
739 *p
++ = static_cast<USHORT
>(nCol2
);
740 *p
++ = static_cast<USHORT
>(nRow2
);
741 *p
++ = static_cast<USHORT
>(nTab2
);
747 while (nTab
<= nTab2
)
751 while (nRow
<= nRow2
)
755 while (nCol
<= nCol2
)
758 ScBaseCell
* pCell
= pDok
->GetCell( aAdr
);
762 USHORT nType
= 0; // 0 = Zahl; 1 = String
766 switch ( pCell
->GetCellType() )
768 case CELLTYPE_STRING
:
769 ((ScStringCell
*)pCell
)->GetString(aStr
);
773 ((ScEditCell
*)pCell
)->GetString(aStr
);
776 case CELLTYPE_VALUE
:
777 nVal
= GetValueCellValue( aAdr
, (ScValueCell
*)pCell
);
779 case CELLTYPE_FORMULA
:
780 nErr
= ((ScFormulaCell
*)pCell
)->GetErrCode();
781 if (((ScFormulaCell
*)pCell
)->IsValue())
782 nVal
= ((ScFormulaCell
*)pCell
)->GetValue();
784 ((ScFormulaCell
*)pCell
)->GetString(aStr
);
792 if ((nPos
+ (5 * sizeof(USHORT
))) > MAXARRSIZE
)
794 *p
++ = static_cast<USHORT
>(nCol
);
795 *p
++ = static_cast<USHORT
>(nRow
);
796 *p
++ = static_cast<USHORT
>(nTab
);
802 if ((nPos
+ sizeof(double)) > MAXARRSIZE
)
804 memcpy( p
, &nVal
, sizeof(double));
805 nPos
+= sizeof(double);
809 ByteString
aTmp( aStr
, osl_getThreadTextEncoding() );
810 // In case the xub_StrLen will be longer than USHORT
811 // one day, and room for pad byte check.
812 if ( aTmp
.Len() > ((USHORT
)(~0)) - 2 )
814 // Append a 0-pad-byte if string length is not even
815 //! MUST be USHORT and not xub_StrLen
816 USHORT nStrLen
= (USHORT
) aTmp
.Len();
817 USHORT nLen
= ( nStrLen
+ 2 ) & ~1;
818 if ( ((ULONG
)nPos
+ 2 + nLen
) > MAXARRSIZE
)
821 memcpy( p
, aTmp
.GetBuffer(), nStrLen
+ 1);
822 nPos
+= 2 + nStrLen
+ 1;
823 BYTE
* q
= ( pCellArr
+ nPos
);
828 p
= (USHORT
*) ( pCellArr
+ nPos
);
842 //-----------------------------------------------------------------------------
844 //-----------------------------------------------------------------------------
847 // Also releases a TempToken if appropriate.
849 void ScInterpreter::PushWithoutError( FormulaToken
& r
)
851 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushWithoutError" );
852 if ( sp
>= MAXSTACK
)
853 SetError( errStackOverflow
);
856 nCurFmtType
= NUMBERFORMAT_UNDEFINED
;
861 pStack
[ sp
]->DecRef();
862 pStack
[ sp
] = (ScToken
*) &r
;
867 void ScInterpreter::Push( FormulaToken
& r
)
869 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Push" );
870 if ( sp
>= MAXSTACK
)
871 SetError( errStackOverflow
);
876 if (r
.GetType() == svError
)
878 r
.SetError( nGlobalError
);
879 PushWithoutError( r
);
882 PushWithoutError( *(new FormulaErrorToken( nGlobalError
)));
885 PushWithoutError( r
);
890 void ScInterpreter::PushTempToken( FormulaToken
* p
)
892 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushTempToken" );
893 if ( sp
>= MAXSTACK
)
895 SetError( errStackOverflow
);
897 //! p is a dangling pointer hereafter!
904 if (p
->GetType() == svError
)
906 p
->SetError( nGlobalError
);
907 PushTempTokenWithoutError( p
);
912 //! p is a dangling pointer hereafter!
914 PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError
));
918 PushTempTokenWithoutError( p
);
923 void ScInterpreter::PushTempTokenWithoutError( FormulaToken
* p
)
925 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushTempTokenWithoutError" );
927 if ( sp
>= MAXSTACK
)
929 SetError( errStackOverflow
);
930 //! p may be a dangling pointer hereafter!
938 pStack
[ sp
]->DecRef();
945 void ScInterpreter::PushTempToken( const FormulaToken
& r
)
947 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushTempToken" );
948 if (!IfErrorPushError())
949 PushTempTokenWithoutError( r
.Clone());
953 void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString
,
954 const ScAddress
& rAddress
, short * pRetTypeExpr
, ULONG
* pRetIndexExpr
)
956 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushCellResultToken" );
957 ScBaseCell
* pCell
= pDok
->GetCell( rAddress
);
958 if (!pCell
|| pCell
->HasEmptyData())
960 if (pRetTypeExpr
&& pRetIndexExpr
)
961 pDok
->GetNumberFormatInfo( *pRetTypeExpr
, *pRetIndexExpr
, rAddress
, pCell
);
962 bool bInherited
= (GetCellType( pCell
) == CELLTYPE_FORMULA
);
963 PushTempToken( new ScEmptyCellToken( bInherited
, bDisplayEmptyAsString
));
967 if ((nErr
= pCell
->GetErrorCode()) != 0)
971 *pRetTypeExpr
= NUMBERFORMAT_UNDEFINED
;
975 else if (pCell
->HasStringData())
978 GetCellString( aRes
, pCell
);
981 *pRetTypeExpr
= NUMBERFORMAT_TEXT
;
987 double fVal
= GetCellValue( rAddress
, pCell
);
990 *pRetTypeExpr
= nCurFmtType
;
992 *pRetIndexExpr
= nCurFmtIndex
;
997 // Simply throw away TOS.
999 void ScInterpreter::Pop()
1001 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Pop" );
1005 SetError(errUnknownStackVariable
);
1009 // Simply throw away TOS and set error code, used with ocIsError et al.
1011 void ScInterpreter::PopError()
1013 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopError" );
1017 if (pStack
[sp
]->GetType() == svError
)
1018 nGlobalError
= pStack
[sp
]->GetError();
1021 SetError(errUnknownStackVariable
);
1025 FormulaTokenRef
ScInterpreter::PopToken()
1027 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopToken" );
1031 FormulaToken
* p
= pStack
[ sp
];
1032 if (p
->GetType() == svError
)
1033 nGlobalError
= p
->GetError();
1037 SetError(errUnknownStackVariable
);
1042 double ScInterpreter::PopDouble()
1044 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDouble" );
1045 nCurFmtType
= NUMBERFORMAT_NUMBER
;
1050 FormulaToken
* p
= pStack
[ sp
];
1051 switch (p
->GetType())
1054 nGlobalError
= p
->GetError();
1057 return p
->GetDouble();
1062 SetError( errIllegalArgument
);
1066 SetError( errUnknownStackVariable
);
1071 const String
& ScInterpreter::PopString()
1073 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopString" );
1074 nCurFmtType
= NUMBERFORMAT_TEXT
;
1079 FormulaToken
* p
= pStack
[ sp
];
1080 switch (p
->GetType())
1083 nGlobalError
= p
->GetError();
1086 return p
->GetString();
1089 return EMPTY_STRING
;
1091 SetError( errIllegalArgument
);
1095 SetError( errUnknownStackVariable
);
1096 return EMPTY_STRING
;
1100 void ScInterpreter::ValidateRef( const ScSingleRefData
& rRef
)
1102 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ValidateRef" );
1106 SingleRefToVars( rRef
, nCol
, nRow
, nTab
);
1110 void ScInterpreter::ValidateRef( const ScComplexRefData
& rRef
)
1112 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ValidateRef" );
1113 ValidateRef( rRef
.Ref1
);
1114 ValidateRef( rRef
.Ref2
);
1118 void ScInterpreter::ValidateRef( const ScRefList
& rRefList
)
1120 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ValidateRef" );
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 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::SingleRefToVars" );
1134 if ( rRef
.IsColRel() )
1135 rCol
= aPos
.Col() + rRef
.nRelCol
;
1138 if ( rRef
.IsRowRel() )
1139 rRow
= aPos
.Row() + rRef
.nRelRow
;
1142 if ( rRef
.IsTabRel() )
1143 rTab
= aPos
.Tab() + rRef
.nRelTab
;
1146 if( !ValidCol( rCol
) || rRef
.IsColDeleted() )
1147 SetError( errNoRef
), rCol
= 0;
1148 if( !ValidRow( rRow
) || rRef
.IsRowDeleted() )
1149 SetError( errNoRef
), rRow
= 0;
1150 if( !ValidTab( rTab
, pDok
->GetTableCount() - 1) || rRef
.IsTabDeleted() )
1151 SetError( errNoRef
), rTab
= 0;
1155 void ScInterpreter::PopSingleRef(SCCOL
& rCol
, SCROW
&rRow
, SCTAB
& rTab
)
1157 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopSingleRef" );
1161 FormulaToken
* p
= pStack
[ sp
];
1162 switch (p
->GetType())
1165 nGlobalError
= p
->GetError();
1168 SingleRefToVars( static_cast<ScToken
*>(p
)->GetSingleRef(), rCol
, rRow
, rTab
);
1169 if ( pDok
->aTableOpList
.Count() > 0 )
1170 ReplaceCell( rCol
, rRow
, rTab
);
1173 SetError( errIllegalParameter
);
1177 SetError( errUnknownStackVariable
);
1181 void ScInterpreter::PopSingleRef( ScAddress
& rAdr
)
1183 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopSingleRef" );
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
.Count() > 0 )
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 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DoubleRefToVars" );
1219 const ScComplexRefData
& rCRef
= p
->GetDoubleRef();
1220 SingleRefToVars( rCRef
.Ref1
, rCol1
, rRow1
, rTab1
);
1221 SingleRefToVars( rCRef
.Ref2
, rCol2
, rRow2
, rTab2
);
1222 if ( pDok
->aTableOpList
.Count() > 0 && !bDontCheckForTableOp
)
1224 ScRange
aRange( rCol1
, rRow1
, rTab1
, rCol2
, rRow2
, rTab2
);
1225 if ( IsTableOpInRange( aRange
) )
1226 SetError( errIllegalParameter
);
1231 void ScInterpreter::PopDoubleRef(SCCOL
& rCol1
, SCROW
&rRow1
, SCTAB
& rTab1
,
1232 SCCOL
& rCol2
, SCROW
&rRow2
, SCTAB
& rTab2
,
1233 BOOL bDontCheckForTableOp
)
1235 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRef" );
1239 FormulaToken
* p
= pStack
[ sp
];
1240 switch (p
->GetType())
1243 nGlobalError
= p
->GetError();
1246 DoubleRefToVars( static_cast<ScToken
*>(p
), rCol1
, rRow1
, rTab1
, rCol2
, rRow2
, rTab2
,
1247 bDontCheckForTableOp
);
1250 SetError( errIllegalParameter
);
1254 SetError( errUnknownStackVariable
);
1258 void ScInterpreter::DoubleRefToRange( const ScComplexRefData
& rCRef
,
1259 ScRange
& rRange
, BOOL bDontCheckForTableOp
)
1261 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DoubleRefToRange" );
1265 SingleRefToVars( rCRef
.Ref1
, nCol
, nRow
, nTab
);
1266 rRange
.aStart
.Set( nCol
, nRow
, nTab
);
1267 SingleRefToVars( rCRef
.Ref2
, nCol
, nRow
, nTab
);
1268 rRange
.aEnd
.Set( nCol
, nRow
, nTab
);
1269 if ( pDok
->aTableOpList
.Count() > 0 && !bDontCheckForTableOp
)
1271 if ( IsTableOpInRange( rRange
) )
1272 SetError( errIllegalParameter
);
1277 void ScInterpreter::PopDoubleRef( ScRange
& rRange
, short & rParam
, size_t & rRefInList
)
1279 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRef" );
1282 formula::FormulaToken
* pToken
= pStack
[ sp
-1 ];
1283 ScToken
* p
= static_cast<ScToken
*>(pToken
);
1284 switch (pToken
->GetType())
1287 nGlobalError
= p
->GetError();
1291 DoubleRefToRange( p
->GetDoubleRef(), rRange
);
1295 const ScRefList
* pList
= p
->GetRefList();
1296 if (rRefInList
< pList
->size())
1298 DoubleRefToRange( (*pList
)[rRefInList
], rRange
);
1299 if (++rRefInList
< pList
->size())
1311 SetError( errIllegalParameter
);
1316 SetError( errIllegalParameter
);
1320 SetError( errUnknownStackVariable
);
1324 void ScInterpreter::PopDoubleRef( ScRange
& rRange
, BOOL bDontCheckForTableOp
)
1326 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRef" );
1330 FormulaToken
* p
= pStack
[ sp
];
1331 switch (p
->GetType())
1334 nGlobalError
= p
->GetError();
1337 DoubleRefToRange( static_cast<ScToken
*>(p
)->GetDoubleRef(), rRange
, bDontCheckForTableOp
);
1340 SetError( errIllegalParameter
);
1344 SetError( errUnknownStackVariable
);
1348 BOOL
ScInterpreter::PopDoubleRefOrSingleRef( ScAddress
& rAdr
)
1350 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRefOrSingleRef" );
1351 switch ( GetStackType() )
1356 PopDoubleRef( aRange
, TRUE
);
1357 return DoubleRefToPosSingleRef( aRange
, rAdr
);
1362 PopSingleRef( rAdr
);
1368 SetError( errNoRef
);
1374 void ScInterpreter::PopDoubleRefPushMatrix()
1376 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRefPushMatrix" );
1377 if ( GetStackType() == svDoubleRef
)
1379 ScMatrixRef pMat
= GetMatrix();
1383 PushIllegalParameter();
1386 SetError( errNoRef
);
1390 ScTokenMatrixMap
* ScInterpreter::CreateTokenMatrixMap()
1392 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateTokenMatrixMap" );
1393 return new ScTokenMatrixMap
;
1397 bool ScInterpreter::ConvertMatrixParameters()
1399 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ConvertMatrixParameters" );
1400 USHORT nParams
= pCur
->GetParamCount();
1401 DBG_ASSERT( nParams
<= sp
, "ConvertMatrixParameters: stack/param count mismatch");
1402 SCSIZE nJumpCols
= 0, nJumpRows
= 0;
1403 for ( USHORT i
=1; i
<= nParams
&& i
<= sp
; ++i
)
1405 FormulaToken
* p
= pStack
[ sp
- i
];
1406 if ( p
->GetOpCode() != ocPush
)
1408 DBG_ERRORFILE( "ConvertMatrixParameters: not a push");
1412 switch ( p
->GetType() )
1424 if ( ScParameterClassification::GetParameterType( pCur
, nParams
- i
)
1425 == ScParameterClassification::Value
)
1426 { // only if single value expected
1427 ScMatrixRef pMat
= static_cast<ScToken
*>(p
)->GetMatrix();
1429 SetError( errUnknownVariable
);
1432 SCSIZE nCols
, nRows
;
1433 pMat
->GetDimensions( nCols
, nRows
);
1434 if ( nJumpCols
< nCols
)
1436 if ( nJumpRows
< nRows
)
1444 ScParameterClassification::Type eType
=
1445 ScParameterClassification::GetParameterType( pCur
, nParams
- i
);
1446 if ( eType
!= ScParameterClassification::Reference
)
1451 DoubleRefToVars( static_cast<const ScToken
*>( p
), nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
1452 // Make sure the map exists, created if not.
1453 GetTokenMatrixMap();
1454 ScMatrixRef pMat
= CreateMatrixFromDoubleRef( p
,
1455 nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
1458 if ( eType
== ScParameterClassification::Value
)
1459 { // only if single value expected
1460 if ( nJumpCols
< static_cast<SCSIZE
>(nCol2
- nCol1
+ 1) )
1461 nJumpCols
= static_cast<SCSIZE
>(nCol2
- nCol1
+ 1);
1462 if ( nJumpRows
< static_cast<SCSIZE
>(nRow2
- nRow1
+ 1) )
1463 nJumpRows
= static_cast<SCSIZE
>(nRow2
- nRow1
+ 1);
1465 ScToken
* pNew
= new ScMatrixToken( pMat
);
1467 pStack
[ sp
- i
] = pNew
;
1468 p
->DecRef(); // p may be dead now!
1475 ScParameterClassification::Type eType
=
1476 ScParameterClassification::GetParameterType( pCur
, nParams
- i
);
1477 if ( eType
!= ScParameterClassification::Reference
)
1479 // can't convert to matrix
1480 SetError( errNoValue
);
1485 DBG_ERRORFILE( "ConvertMatrixParameters: unknown parameter type");
1489 if( nJumpCols
&& nJumpRows
)
1491 short nPC
= aCode
.GetPC();
1492 short nStart
= nPC
- 1; // restart on current code (-1)
1493 short nNext
= nPC
; // next instruction after subroutine
1494 short nStop
= nPC
+ 1; // stop subroutine before reaching that
1495 FormulaTokenRef xNew
;
1496 ScTokenMatrixMap::const_iterator aMapIter
;
1497 if (pTokenMatrixMap
&& ((aMapIter
= pTokenMatrixMap
->find( pCur
)) !=
1498 pTokenMatrixMap
->end()))
1499 xNew
= (*aMapIter
).second
;
1502 ScJumpMatrix
* pJumpMat
= new ScJumpMatrix( nJumpCols
, nJumpRows
);
1503 pJumpMat
->SetAllJumps( 1.0, nStart
, nNext
, nStop
);
1504 // pop parameters and store in ScJumpMatrix, push in JumpMatrix()
1505 ScTokenVec
* pParams
= new ScTokenVec( nParams
);
1506 for ( USHORT i
=1; i
<= nParams
&& sp
> 0; ++i
)
1508 FormulaToken
* p
= pStack
[ --sp
];
1510 // store in reverse order such that a push may simply iterate
1511 (*pParams
)[ nParams
- i
] = p
;
1513 pJumpMat
->SetJumpParameters( pParams
);
1514 xNew
= new ScJumpMatrixToken( pJumpMat
);
1515 GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type( pCur
,
1518 PushTempToken( xNew
);
1519 // set continuation point of path for main code line
1520 aCode
.Jump( nNext
, nNext
);
1527 ScMatrixRef
ScInterpreter::PopMatrix()
1529 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopMatrix" );
1533 FormulaToken
* p
= pStack
[ sp
];
1534 switch (p
->GetType())
1537 nGlobalError
= p
->GetError();
1541 ScMatrix
* pMat
= static_cast<ScToken
*>(p
)->GetMatrix();
1543 pMat
->SetErrorInterpreter( this);
1545 SetError( errUnknownVariable
);
1549 SetError( errIllegalParameter
);
1553 SetError( errUnknownStackVariable
);
1558 void ScInterpreter::PushDouble(double nVal
)
1560 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushDouble" );
1561 TreatDoubleError( nVal
);
1562 if (!IfErrorPushError())
1563 PushTempTokenWithoutError( new FormulaDoubleToken( nVal
) );
1567 void ScInterpreter::PushInt(int nVal
)
1569 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushInt" );
1570 if (!IfErrorPushError())
1571 PushTempTokenWithoutError( new FormulaDoubleToken( nVal
) );
1575 void ScInterpreter::PushStringBuffer( const sal_Unicode
* pString
)
1577 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushStringBuffer" );
1579 PushString( String( pString
) );
1581 PushString( EMPTY_STRING
);
1585 void ScInterpreter::PushString( const String
& rString
)
1587 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushString" );
1588 if (!IfErrorPushError())
1589 PushTempTokenWithoutError( new FormulaStringToken( rString
) );
1593 void ScInterpreter::PushSingleRef(SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1595 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushSingleRef" );
1596 if (!IfErrorPushError())
1598 ScSingleRefData aRef
;
1603 PushTempTokenWithoutError( new ScSingleRefToken( aRef
) );
1608 void ScInterpreter::PushDoubleRef(SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
1609 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
)
1611 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushDoubleRef" );
1612 if (!IfErrorPushError())
1614 ScComplexRefData aRef
;
1616 aRef
.Ref1
.nCol
= nCol1
;
1617 aRef
.Ref1
.nRow
= nRow1
;
1618 aRef
.Ref1
.nTab
= nTab1
;
1619 aRef
.Ref2
.nCol
= nCol2
;
1620 aRef
.Ref2
.nRow
= nRow2
;
1621 aRef
.Ref2
.nTab
= nTab2
;
1622 PushTempTokenWithoutError( new ScDoubleRefToken( aRef
) );
1627 void ScInterpreter::PushMatrix(ScMatrix
* pMat
)
1629 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushMatrix" );
1630 pMat
->SetErrorInterpreter( NULL
);
1631 // No if (!IfErrorPushError()) because ScMatrix stores errors itself,
1632 // but with notifying ScInterpreter via nGlobalError, substituting it would
1633 // mean to inherit the error on all array elements in all following
1636 PushTempTokenWithoutError( new ScMatrixToken( pMat
) );
1640 void ScInterpreter::PushError( USHORT nError
)
1642 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushError" );
1643 SetError( nError
); // only sets error if not already set
1644 PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError
));
1647 void ScInterpreter::PushParameterExpected()
1649 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushParameterExpected" );
1650 PushError( errParameterExpected
);
1654 void ScInterpreter::PushIllegalParameter()
1656 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushIllegalParameter" );
1657 PushError( errIllegalParameter
);
1661 void ScInterpreter::PushIllegalArgument()
1663 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushIllegalArgument" );
1664 PushError( errIllegalArgument
);
1668 void ScInterpreter::PushNA()
1670 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushNA" );
1671 PushError( NOTAVAILABLE
);
1675 void ScInterpreter::PushNoValue()
1677 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushNoValue" );
1678 PushError( errNoValue
);
1682 BOOL
ScInterpreter::IsMissing()
1684 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::IsMissing" );
1685 return sp
&& pStack
[sp
- 1]->GetType() == svMissing
;
1689 StackVar
ScInterpreter::GetRawStackType()
1691 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetRawStackType" );
1695 eRes
= pStack
[sp
- 1]->GetType();
1699 SetError(errUnknownStackVariable
);
1706 StackVar
ScInterpreter::GetStackType()
1708 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetStackType" );
1712 eRes
= pStack
[sp
- 1]->GetType();
1713 if( eRes
== svMissing
|| eRes
== svEmptyCell
)
1714 eRes
= svDouble
; // default!
1718 SetError(errUnknownStackVariable
);
1725 StackVar
ScInterpreter::GetStackType( BYTE nParam
)
1727 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetStackType" );
1731 eRes
= pStack
[sp
- nParam
]->GetType();
1732 if( eRes
== svMissing
|| eRes
== svEmptyCell
)
1733 eRes
= svDouble
; // default!
1741 BOOL
ScInterpreter::DoubleRefToPosSingleRef( const ScRange
& rRange
, ScAddress
& rAdr
)
1743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DoubleRefToPosSingleRef" );
1744 // Check for a singleton first - no implicit intersection for them.
1745 if( rRange
.aStart
== rRange
.aEnd
)
1747 rAdr
= rRange
.aStart
;
1755 bOk
= rRange
.aStart
.Tab() == rRange
.aEnd
.Tab();
1757 SetError( errIllegalArgument
);
1761 pJumpMatrix
->GetPos( nC
, nR
);
1762 rAdr
.SetCol( sal::static_int_cast
<SCCOL
>( rRange
.aStart
.Col() + nC
) );
1763 rAdr
.SetRow( sal::static_int_cast
<SCROW
>( rRange
.aStart
.Row() + nR
) );
1764 rAdr
.SetTab( rRange
.aStart
.Tab());
1765 bOk
= rRange
.aStart
.Col() <= rAdr
.Col() && rAdr
.Col() <=
1766 rRange
.aEnd
.Col() && rRange
.aStart
.Row() <= rAdr
.Row() &&
1767 rAdr
.Row() <= rRange
.aEnd
.Row();
1769 SetError( errNoValue
);
1774 SCCOL nMyCol
= aPos
.Col();
1775 SCROW nMyRow
= aPos
.Row();
1776 SCTAB nMyTab
= aPos
.Tab();
1780 nTab
= rRange
.aStart
.Tab();
1781 if ( rRange
.aStart
.Col() <= nMyCol
&& nMyCol
<= rRange
.aEnd
.Col() )
1783 nRow
= rRange
.aStart
.Row();
1784 if ( nRow
== rRange
.aEnd
.Row() )
1789 else if ( nTab
!= nMyTab
&& nTab
== rRange
.aEnd
.Tab()
1790 && rRange
.aStart
.Row() <= nMyRow
&& nMyRow
<= rRange
.aEnd
.Row() )
1797 else if ( rRange
.aStart
.Row() <= nMyRow
&& nMyRow
<= rRange
.aEnd
.Row() )
1799 nCol
= rRange
.aStart
.Col();
1800 if ( nCol
== rRange
.aEnd
.Col() )
1805 else if ( nTab
!= nMyTab
&& nTab
== rRange
.aEnd
.Tab()
1806 && rRange
.aStart
.Col() <= nMyCol
&& nMyCol
<= rRange
.aEnd
.Col() )
1815 if ( nTab
== rRange
.aEnd
.Tab() )
1817 else if ( nTab
<= nMyTab
&& nMyTab
<= rRange
.aEnd
.Tab() )
1822 rAdr
.Set( nCol
, nRow
, nTab
);
1825 SetError( errNoValue
);
1830 double ScInterpreter::GetDouble( bool bNoValueAsError
, bool bBlankAsZero
)
1832 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDouble" );
1834 switch( GetRawStackType() )
1841 String
aStr(PopString());
1842 sal_uInt32 nFIndex
= 0; // damit default Land/Spr.
1843 if(!pFormatter
->IsNumberFormat( aStr
, nFIndex
, nVal
) )
1845 SetError( errIllegalArgument
); //! fit to ScN()
1853 PopSingleRef( aAdr
);
1854 ScBaseCell
* pCell
= GetCell( aAdr
);
1855 nVal
= GetCellValue( aAdr
, pCell
, bNoValueAsError
, bBlankAsZero
);
1859 { // generate position dependent SingleRef
1861 PopDoubleRef( aRange
);
1863 if ( !nGlobalError
&& DoubleRefToPosSingleRef( aRange
, aAdr
) )
1865 ScBaseCell
* pCell
= GetCell( aAdr
);
1866 nVal
= GetCellValue( aAdr
, pCell
);
1874 ScMatrixRef pMat
= PopMatrix();
1877 else if ( !pJumpMatrix
)
1878 nVal
= pMat
->GetDouble( 0 );
1881 SCSIZE nCols
, nRows
, nC
, nR
;
1882 pMat
->GetDimensions( nCols
, nRows
);
1883 pJumpMatrix
->GetPos( nC
, nR
);
1884 if ( nC
< nCols
&& nR
< nRows
)
1885 nVal
= pMat
->GetDouble( nC
, nR
);
1888 SetError( errNoValue
);
1905 SetError( errIllegalParameter
);
1908 if ( nFuncFmtType
== nCurFmtType
)
1909 nFuncFmtIndex
= nCurFmtIndex
;
1914 double ScInterpreter::GetDoubleWithDefault(double nDefault
)
1916 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDoubleWithDefault" );
1917 bool bMissing
= IsMissing();
1918 double nResultVal
= GetDouble();
1920 nResultVal
= nDefault
;
1925 const String
& ScInterpreter::GetString()
1927 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetString" );
1928 switch (GetRawStackType())
1932 return EMPTY_STRING
;
1937 return EMPTY_STRING
;
1941 double fVal
= PopDouble();
1942 ULONG nIndex
= pFormatter
->GetStandardFormat(
1943 NUMBERFORMAT_NUMBER
,
1945 pFormatter
->GetInputLineString(fVal
, nIndex
, aTempStr
);
1955 PopSingleRef( aAdr
);
1956 if (nGlobalError
== 0)
1958 ScBaseCell
* pCell
= GetCell( aAdr
);
1959 GetCellString( aTempStr
, pCell
);
1963 return EMPTY_STRING
;
1967 { // generate position dependent SingleRef
1969 PopDoubleRef( aRange
);
1971 if ( !nGlobalError
&& DoubleRefToPosSingleRef( aRange
, aAdr
) )
1973 ScBaseCell
* pCell
= GetCell( aAdr
);
1974 GetCellString( aTempStr
, pCell
);
1978 return EMPTY_STRING
;
1983 ScMatrixRef pMat
= PopMatrix();
1986 else if ( !pJumpMatrix
)
1988 aTempStr
= pMat
->GetString( *pFormatter
, 0, 0);
1993 SCSIZE nCols
, nRows
, nC
, nR
;
1994 pMat
->GetDimensions( nCols
, nRows
);
1995 pJumpMatrix
->GetPos( nC
, nR
);
1996 if ( nC
< nCols
&& nR
< nRows
)
1998 aTempStr
= pMat
->GetString( *pFormatter
, nC
, nR
);
2002 SetError( errNoValue
);
2008 SetError( errIllegalArgument
);
2010 return EMPTY_STRING
;
2015 ScMatValType
ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble
,
2018 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDoubleOrStringFromMatrix" );
2019 ScMatValType nMatValType
= SC_MATVAL_EMPTY
;
2020 switch ( GetStackType() )
2024 const ScMatrixValue
* pMatVal
= 0;
2025 ScMatrixRef pMat
= PopMatrix();
2028 else if (!pJumpMatrix
)
2029 pMatVal
= pMat
->Get( 0, 0, nMatValType
);
2032 SCSIZE nCols
, nRows
, nC
, nR
;
2033 pMat
->GetDimensions( nCols
, nRows
);
2034 pJumpMatrix
->GetPos( nC
, nR
);
2035 if ( nC
< nCols
&& nR
< nRows
)
2036 pMatVal
= pMat
->Get( nC
, nR
, nMatValType
);
2038 SetError( errNoValue
);
2045 else if (nMatValType
== SC_MATVAL_VALUE
)
2046 rDouble
= pMatVal
->fVal
;
2047 else if (nMatValType
== SC_MATVAL_BOOLEAN
)
2049 rDouble
= pMatVal
->fVal
;
2050 nMatValType
= SC_MATVAL_VALUE
;
2053 rString
= pMatVal
->GetString();
2060 SetError( errIllegalParameter
);
2066 void ScInterpreter::ScDBGet()
2068 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBGet" );
2070 ScQueryParam aQueryParam
;
2071 BOOL bMissingField
= FALSE
;
2072 if (GetDBParams( nTab
, aQueryParam
, bMissingField
))
2075 ScQueryCellIterator
aCellIter(pDok
, nTab
, aQueryParam
);
2076 if ( (pCell
= aCellIter
.GetFirst()) != NULL
)
2078 if (aCellIter
.GetNext())
2079 PushIllegalArgument();
2082 switch (pCell
->GetCellType())
2084 case CELLTYPE_VALUE
:
2086 double rValue
= ((ScValueCell
*)pCell
)->GetValue();
2090 nFormat
= aCellIter
.GetNumberFormat();
2091 rValue
= pDok
->RoundValueAsShown( rValue
, nFormat
);
2096 case CELLTYPE_STRING
:
2099 ((ScStringCell
*)pCell
)->GetString(rString
);
2100 PushString(rString
);
2106 ((ScEditCell
*)pCell
)->GetString(rString
);
2107 PushString(rString
);
2110 case CELLTYPE_FORMULA
:
2112 USHORT rErr
= ((ScFormulaCell
*)pCell
)->GetErrCode();
2115 else if (((ScFormulaCell
*)pCell
)->IsValue())
2117 double rValue
= ((ScFormulaCell
*)pCell
)->GetValue();
2123 ((ScFormulaCell
*)pCell
)->GetString(rString
);
2124 PushString(rString
);
2131 PushIllegalArgument();
2140 PushIllegalParameter();
2144 void ScInterpreter::ScExternal()
2146 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScExternal" );
2148 BYTE nParamCount
= GetByte();
2150 String
aFuncName( ScGlobal::pCharClass
->upper( pCur
->GetExternal() ) );
2151 if (ScGlobal::GetFuncCollection()->SearchFunc(aFuncName
, nIndex
))
2153 FuncData
* pFuncData
= (FuncData
*)ScGlobal::GetFuncCollection()->At(nIndex
);
2154 if (nParamCount
== pFuncData
->GetParamCount() - 1)
2156 ParamType eParamType
[MAXFUNCPARAM
];
2157 void* ppParam
[MAXFUNCPARAM
];
2158 double nVal
[MAXFUNCPARAM
];
2159 sal_Char
* pStr
[MAXFUNCPARAM
];
2160 BYTE
* pCellArr
[MAXFUNCPARAM
];
2163 for (i
= 0; i
< MAXFUNCPARAM
; i
++)
2165 eParamType
[i
] = pFuncData
->GetParamType(i
);
2172 for (i
= nParamCount
; (i
> 0) && (nGlobalError
== 0); i
--)
2174 switch (eParamType
[i
])
2178 nVal
[i
-1] = GetDouble();
2179 ppParam
[i
] = &nVal
[i
-1];
2184 ByteString
aStr( GetString(), osl_getThreadTextEncoding() );
2185 if ( aStr
.Len() >= ADDIN_MAXSTRLEN
)
2186 SetError( errStringOverflow
);
2189 pStr
[i
-1] = new sal_Char
[ADDIN_MAXSTRLEN
];
2190 strncpy( pStr
[i
-1], aStr
.GetBuffer(), ADDIN_MAXSTRLEN
);
2191 pStr
[i
-1][ADDIN_MAXSTRLEN
-1] = 0;
2192 ppParam
[i
] = pStr
[i
-1];
2196 case PTR_DOUBLE_ARR
:
2204 PopDoubleRef(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
2205 pCellArr
[i
-1] = new BYTE
[MAXARRSIZE
];
2206 if (!CreateDoubleArr(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, pCellArr
[i
-1]))
2207 SetError(errCodeOverflow
);
2209 ppParam
[i
] = pCellArr
[i
-1];
2212 case PTR_STRING_ARR
:
2220 PopDoubleRef(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
2221 pCellArr
[i
-1] = new BYTE
[MAXARRSIZE
];
2222 if (!CreateStringArr(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, pCellArr
[i
-1]))
2223 SetError(errCodeOverflow
);
2225 ppParam
[i
] = pCellArr
[i
-1];
2236 PopDoubleRef(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
2237 pCellArr
[i
-1] = new BYTE
[MAXARRSIZE
];
2238 if (!CreateCellArr(nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, pCellArr
[i
-1]))
2239 SetError(errCodeOverflow
);
2241 ppParam
[i
] = pCellArr
[i
-1];
2245 SetError(errIllegalParameter
);
2250 Pop(); // im Fehlerfall (sonst ist i==0) Parameter wegpoppen
2252 if (nGlobalError
== 0)
2254 if ( pFuncData
->GetAsyncType() == NONE
)
2256 switch ( eParamType
[0] )
2262 pFuncData
->Call(ppParam
);
2268 sal_Char
* pcErg
= new sal_Char
[ADDIN_MAXSTRLEN
];
2270 pFuncData
->Call(ppParam
);
2271 String
aUni( pcErg
, osl_getThreadTextEncoding() );
2277 PushError( errUnknownState
);
2282 // nach dem Laden Asyncs wieder anwerfen
2283 if ( pMyFormulaCell
->GetCode()->IsRecalcModeNormal() )
2284 pMyFormulaCell
->GetCode()->SetRecalcModeOnLoad();
2285 // garantiert identischer Handle bei identischem Aufruf?!?
2286 // sonst schei*e ...
2289 pFuncData
->Call(ppParam
);
2290 ULONG nHandle
= ULONG( nErg
);
2291 if ( nHandle
>= 65536 )
2293 ScAddInAsync
* pAs
= ScAddInAsync::Get( nHandle
);
2296 pAs
= new ScAddInAsync( nHandle
, nIndex
, pDok
);
2297 pMyFormulaCell
->StartListening( *pAs
);
2301 // falls per cut/copy/paste
2302 pMyFormulaCell
->StartListening( *pAs
);
2303 // in anderes Dokument?
2304 if ( !pAs
->HasDocument( pDok
) )
2305 pAs
->AddDocument( pDok
);
2307 if ( pAs
->IsValid() )
2309 switch ( pAs
->GetType() )
2312 PushDouble( pAs
->GetValue() );
2315 PushString( pAs
->GetString() );
2318 PushError( errUnknownState
);
2329 for (i
= 0; i
< MAXFUNCPARAM
; i
++)
2332 delete[] pCellArr
[i
];
2337 while( nParamCount
-- > 0)
2339 PushIllegalParameter();
2342 else if ( ( aUnoName
= ScGlobal::GetAddInCollection()->FindFunction(aFuncName
, FALSE
) ).Len() )
2344 // bLocalFirst=FALSE in FindFunction, cFunc should be the stored internal name
2346 ScUnoAddInCall
aCall( *ScGlobal::GetAddInCollection(), aUnoName
, nParamCount
);
2348 if ( !aCall
.ValidParamCount() )
2349 SetError( errIllegalParameter
);
2351 if ( aCall
.NeedsCaller() && !GetError() )
2353 SfxObjectShell
* pShell
= pDok
->GetDocumentShell();
2355 aCall
.SetCallerFromObjectShell( pShell
);
2358 // use temporary model object (without document) to supply options
2359 aCall
.SetCaller( static_cast<beans::XPropertySet
*>(
2360 new ScDocOptionsObj( pDok
->GetDocOptions() ) ) );
2364 short nPar
= nParamCount
;
2365 while ( nPar
> 0 && !GetError() )
2367 --nPar
; // 0 .. (nParamCount-1)
2369 ScAddInArgumentType eType
= aCall
.GetArgType( nPar
);
2370 BYTE nStackType
= sal::static_int_cast
<BYTE
>( GetStackType() );
2375 case SC_ADDINARG_INTEGER
:
2377 double fVal
= GetDouble();
2378 double fInt
= (fVal
>= 0.0) ? ::rtl::math::approxFloor( fVal
) :
2379 ::rtl::math::approxCeil( fVal
);
2380 if ( fInt
>= LONG_MIN
&& fInt
<= LONG_MAX
)
2381 aParam
<<= (INT32
)fInt
;
2383 SetError(errIllegalArgument
);
2387 case SC_ADDINARG_DOUBLE
:
2388 aParam
<<= (double) GetDouble();
2391 case SC_ADDINARG_STRING
:
2392 aParam
<<= rtl::OUString( GetString() );
2395 case SC_ADDINARG_INTEGER_ARRAY
:
2396 switch( nStackType
)
2402 double fVal
= GetDouble();
2403 double fInt
= (fVal
>= 0.0) ? ::rtl::math::approxFloor( fVal
) :
2404 ::rtl::math::approxCeil( fVal
);
2405 if ( fInt
>= LONG_MIN
&& fInt
<= LONG_MAX
)
2407 INT32 nIntVal
= (long)fInt
;
2408 uno::Sequence
<INT32
> aInner( &nIntVal
, 1 );
2409 uno::Sequence
< uno::Sequence
<INT32
> > aOuter( &aInner
, 1 );
2413 SetError(errIllegalArgument
);
2419 PopDoubleRef( aRange
);
2420 if (!ScRangeToSequence::FillLongArray( aParam
, pDok
, aRange
))
2421 SetError(errIllegalParameter
);
2425 if (!ScRangeToSequence::FillLongArray( aParam
, PopMatrix() ))
2426 SetError(errIllegalParameter
);
2430 SetError(errIllegalParameter
);
2434 case SC_ADDINARG_DOUBLE_ARRAY
:
2435 switch( nStackType
)
2441 double fVal
= GetDouble();
2442 uno::Sequence
<double> aInner( &fVal
, 1 );
2443 uno::Sequence
< uno::Sequence
<double> > aOuter( &aInner
, 1 );
2450 PopDoubleRef( aRange
);
2451 if (!ScRangeToSequence::FillDoubleArray( aParam
, pDok
, aRange
))
2452 SetError(errIllegalParameter
);
2456 if (!ScRangeToSequence::FillDoubleArray( aParam
, PopMatrix() ))
2457 SetError(errIllegalParameter
);
2461 SetError(errIllegalParameter
);
2465 case SC_ADDINARG_STRING_ARRAY
:
2466 switch( nStackType
)
2472 rtl::OUString aString
= rtl::OUString( GetString() );
2473 uno::Sequence
<rtl::OUString
> aInner( &aString
, 1 );
2474 uno::Sequence
< uno::Sequence
<rtl::OUString
> > aOuter( &aInner
, 1 );
2481 PopDoubleRef( aRange
);
2482 if (!ScRangeToSequence::FillStringArray( aParam
, pDok
, aRange
))
2483 SetError(errIllegalParameter
);
2487 if (!ScRangeToSequence::FillStringArray( aParam
, PopMatrix(), pFormatter
))
2488 SetError(errIllegalParameter
);
2492 SetError(errIllegalParameter
);
2496 case SC_ADDINARG_MIXED_ARRAY
:
2497 switch( nStackType
)
2504 if ( nStackType
== svDouble
)
2505 aElem
<<= (double) GetDouble();
2506 else if ( nStackType
== svString
)
2507 aElem
<<= rtl::OUString( GetString() );
2511 if ( PopDoubleRefOrSingleRef( aAdr
) )
2513 ScBaseCell
* pCell
= GetCell( aAdr
);
2514 if ( pCell
&& pCell
->HasStringData() )
2517 GetCellString( aStr
, pCell
);
2518 aElem
<<= rtl::OUString( aStr
);
2521 aElem
<<= (double) GetCellValue( aAdr
, pCell
);
2524 uno::Sequence
<uno::Any
> aInner( &aElem
, 1 );
2525 uno::Sequence
< uno::Sequence
<uno::Any
> > aOuter( &aInner
, 1 );
2532 PopDoubleRef( aRange
);
2533 if (!ScRangeToSequence::FillMixedArray( aParam
, pDok
, aRange
))
2534 SetError(errIllegalParameter
);
2538 if (!ScRangeToSequence::FillMixedArray( aParam
, PopMatrix() ))
2539 SetError(errIllegalParameter
);
2543 SetError(errIllegalParameter
);
2547 case SC_ADDINARG_VALUE_OR_ARRAY
:
2549 nStackType
= svMissing
;
2550 switch( nStackType
)
2553 aParam
<<= (double) GetDouble();
2556 aParam
<<= rtl::OUString( GetString() );
2561 if ( PopDoubleRefOrSingleRef( aAdr
) )
2563 ScBaseCell
* pCell
= GetCell( aAdr
);
2564 if ( pCell
&& pCell
->HasStringData() )
2567 GetCellString( aStr
, pCell
);
2568 aParam
<<= rtl::OUString( aStr
);
2571 aParam
<<= (double) GetCellValue( aAdr
, pCell
);
2578 PopDoubleRef( aRange
);
2579 if (!ScRangeToSequence::FillMixedArray( aParam
, pDok
, aRange
))
2580 SetError(errIllegalParameter
);
2584 if (!ScRangeToSequence::FillMixedArray( aParam
, PopMatrix() ))
2585 SetError(errIllegalParameter
);
2593 SetError(errIllegalParameter
);
2597 case SC_ADDINARG_CELLRANGE
:
2598 switch( nStackType
)
2603 PopSingleRef( aAdr
);
2604 ScRange
aRange( aAdr
);
2605 uno::Reference
<table::XCellRange
> xObj
=
2606 ScCellRangeObj::CreateRangeFromDoc( pDok
, aRange
);
2610 SetError(errIllegalParameter
);
2616 PopDoubleRef( aRange
);
2617 uno::Reference
<table::XCellRange
> xObj
=
2618 ScCellRangeObj::CreateRangeFromDoc( pDok
, aRange
);
2622 SetError(errIllegalParameter
);
2627 SetError(errIllegalParameter
);
2633 SetError(errIllegalParameter
);
2635 aCall
.SetParam( nPar
, aParam
);
2639 Pop(); // in case of error, remove remaining args
2643 aCall
.ExecuteCall();
2645 if ( aCall
.HasVarRes() ) // handle async functions
2647 if ( pMyFormulaCell
->GetCode()->IsRecalcModeNormal() )
2648 pMyFormulaCell
->GetCode()->SetRecalcModeOnLoad();
2650 uno::Reference
<sheet::XVolatileResult
> xRes
= aCall
.GetVarRes();
2651 ScAddInListener
* pLis
= ScAddInListener::Get( xRes
);
2654 pLis
= ScAddInListener::CreateListener( xRes
, pDok
);
2655 pMyFormulaCell
->StartListening( *pLis
);
2659 pMyFormulaCell
->StartListening( *pLis
);
2660 if ( !pLis
->HasDocument( pDok
) )
2661 pLis
->AddDocument( pDok
);
2664 aCall
.SetResult( pLis
->GetResult() ); // use result from async
2667 if ( aCall
.GetErrCode() )
2668 PushError( aCall
.GetErrCode() );
2669 else if ( aCall
.HasMatrix() )
2671 ScMatrixRef xMat
= aCall
.GetMatrix();
2674 else if ( aCall
.HasString() )
2675 PushString( aCall
.GetString() );
2677 PushDouble( aCall
.GetValue() );
2680 PushError( GetError());
2684 while( nParamCount
-- > 0)
2686 PushError( errNoAddin
);
2691 void ScInterpreter::ScMissing()
2693 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMissing" );
2694 PushTempToken( new FormulaMissingToken
);
2698 lcl_setVBARange( ScRange
& aRange
, ScDocument
* pDok
, SbxVariable
* pPar
)
2703 uno::Reference
< uno::XInterface
> xVBARange
;
2704 uno::Reference
<table::XCellRange
> xCellRange
= ScCellRangeObj::CreateRangeFromDoc( pDok
, aRange
);
2705 uno::Sequence
< uno::Any
> aArgs(2);
2706 aArgs
[0] = uno::Any( uno::Reference
< uno::XInterface
>() ); // dummy parent
2707 aArgs
[1] = uno::Any( xCellRange
);
2708 xVBARange
= ov::createVBAUnoAPIServiceWithArgs( pDok
->GetDocumentShell(), "ooo.vba.excel.Range", aArgs
);
2709 if ( xVBARange
.is() )
2711 String
sDummy(RTL_CONSTASCII_USTRINGPARAM("A-Range") );
2712 SbxObjectRef aObj
= GetSbUnoObject( sDummy
, uno::Any( xVBARange
) );
2713 SetSbUnoObjectDfltPropName( aObj
);
2714 bOk
= pPar
->PutObject( aObj
);
2717 catch( uno::Exception
& )
2722 void ScInterpreter::ScMacro()
2724 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMacro" );
2725 SbxBase::ResetError();
2727 BYTE nParamCount
= GetByte();
2728 String
aMacro( pCur
->GetExternal() );
2730 SfxObjectShell
* pDocSh
= pDok
->GetDocumentShell();
2731 if ( !pDocSh
|| !pDok
->CheckMacroWarn() )
2733 PushNoValue(); // ohne DocShell kein CallBasic
2737 // keine Sicherheitsabfrage mehr vorneweg (nur CheckMacroWarn), das passiert im CallBasic
2739 SfxApplication
* pSfxApp
= SFX_APP();
2740 pSfxApp
->EnterBasicCall(); // Dok-Basic anlegen etc.
2742 // Wenn das Dok waehrend eines Basic-Calls geladen wurde,
2743 // ist das Sbx-Objekt evtl. nicht angelegt (?)
2744 // pDocSh->GetSbxObject();
2746 // Funktion ueber den einfachen Namen suchen,
2747 // dann aBasicStr, aMacroStr fuer SfxObjectShell::CallBasic zusammenbauen
2749 StarBASIC
* pRoot
= pDocSh
->GetBasic();
2750 SbxVariable
* pVar
= pRoot
->Find( aMacro
, SbxCLASS_METHOD
);
2751 if( !pVar
|| pVar
->GetType() == SbxVOID
|| !pVar
->ISA(SbMethod
) )
2753 PushError( errNoMacro
);
2754 pSfxApp
->LeaveBasicCall();
2758 bool bVolatileMacro
= false;
2759 SbMethod
* pMethod
= (SbMethod
*)pVar
;
2761 SbModule
* pModule
= pMethod
->GetModule();
2762 bool bUseVBAObjects
= pModule
->IsVBACompat();
2763 SbxObject
* pObject
= pModule
->GetParent();
2764 DBG_ASSERT(pObject
->IsA(TYPE(StarBASIC
)), "Kein Basic gefunden!");
2765 String aMacroStr
= pObject
->GetName();
2767 aMacroStr
+= pModule
->GetName();
2769 aMacroStr
+= pMethod
->GetName();
2771 if (pObject
->GetParent())
2773 aBasicStr
= pObject
->GetParent()->GetName(); // Dokumentenbasic
2774 const SfxFilter
* pFilter
= NULL
;
2775 SfxMedium
* pMedium
= pDok
->GetDocumentShell()->GetMedium();
2777 pFilter
= pMedium
->GetFilter();
2780 aBasicStr
= SFX_APP()->GetName(); // Applikationsbasic
2782 // Parameter-Array zusammenbauen
2784 SbxArrayRef refPar
= new SbxArray
;
2786 for( short i
= nParamCount
; i
&& bOk
; i
-- )
2788 SbxVariable
* pPar
= refPar
->Get( (USHORT
) i
);
2789 BYTE nStackType
= sal::static_int_cast
<BYTE
>( GetStackType() );
2790 switch( nStackType
)
2793 pPar
->PutDouble( GetDouble() );
2796 pPar
->PutString( GetString() );
2801 PopSingleRef( aAdr
);
2802 if ( bUseVBAObjects
)
2804 ScRange
aRange( aAdr
);
2805 bOk
= lcl_setVBARange( aRange
, pDok
, pPar
);
2808 bOk
= SetSbxVariable( pPar
, aAdr
);
2819 PopDoubleRef( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
2820 if( nTab1
!= nTab2
)
2822 SetError( errIllegalParameter
);
2827 if ( bUseVBAObjects
)
2829 ScRange
aRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
2830 bOk
= lcl_setVBARange( aRange
, pDok
, pPar
);
2834 SbxDimArrayRef refArray
= new SbxDimArray
;
2835 refArray
->AddDim32( 1, nRow2
- nRow1
+ 1 );
2836 refArray
->AddDim32( 1, nCol2
- nCol1
+ 1 );
2837 ScAddress
aAdr( nCol1
, nRow1
, nTab1
);
2838 for( SCROW nRow
= nRow1
; bOk
&& nRow
<= nRow2
; nRow
++ )
2840 aAdr
.SetRow( nRow
);
2842 nIdx
[ 0 ] = nRow
-nRow1
+1;
2843 for( SCCOL nCol
= nCol1
; bOk
&& nCol
<= nCol2
; nCol
++ )
2845 aAdr
.SetCol( nCol
);
2846 nIdx
[ 1 ] = nCol
-nCol1
+1;
2847 SbxVariable
* p
= refArray
->Get32( nIdx
);
2848 bOk
= SetSbxVariable( p
, aAdr
);
2851 pPar
->PutObject( refArray
);
2858 ScMatrixRef pMat
= PopMatrix();
2862 pMat
->GetDimensions(nC
, nR
);
2863 SbxDimArrayRef refArray
= new SbxDimArray
;
2864 refArray
->AddDim32( 1, static_cast<INT32
>(nR
) );
2865 refArray
->AddDim32( 1, static_cast<INT32
>(nC
) );
2866 for( SCSIZE nMatRow
= 0; nMatRow
< nR
; nMatRow
++ )
2869 nIdx
[ 0 ] = static_cast<INT32
>(nMatRow
+1);
2870 for( SCSIZE nMatCol
= 0; nMatCol
< nC
; nMatCol
++ )
2872 nIdx
[ 1 ] = static_cast<INT32
>(nMatCol
+1);
2873 SbxVariable
* p
= refArray
->Get32( nIdx
);
2874 if (pMat
->IsString(nMatCol
, nMatRow
))
2875 p
->PutString( pMat
->GetString(nMatCol
, nMatRow
) );
2877 p
->PutDouble( pMat
->GetDouble(nMatCol
, nMatRow
));
2880 pPar
->PutObject( refArray
);
2883 SetError( errIllegalParameter
);
2887 SetError( errIllegalParameter
);
2893 pDok
->LockTable( aPos
.Tab() );
2894 SbxVariableRef refRes
= new SbxVariable
;
2895 pDok
->IncMacroInterpretLevel();
2896 ErrCode eRet
= pDocSh
->CallBasic( aMacroStr
, aBasicStr
, NULL
, refPar
, refRes
);
2897 pDok
->DecMacroInterpretLevel();
2898 pDok
->UnlockTable( aPos
.Tab() );
2900 ScMacroManager
* pMacroMgr
= pDok
->GetMacroManager();
2903 bVolatileMacro
= pMacroMgr
->GetUserFuncVolatile( pMethod
->GetName() );
2904 pMacroMgr
->AddDependentCell(pModule
->GetName(), pMyFormulaCell
);
2907 SbxDataType eResType
= refRes
->GetType();
2908 if( pVar
->GetError() )
2909 SetError( errNoValue
);
2910 if ( eRet
!= ERRCODE_NONE
)
2912 else if( eResType
>= SbxINTEGER
&& eResType
<= SbxDOUBLE
)
2913 PushDouble( refRes
->GetDouble() );
2914 else if ( eResType
& SbxARRAY
)
2916 SbxBase
* pElemObj
= refRes
->GetObject();
2917 SbxDimArray
* pDimArray
= PTR_CAST(SbxDimArray
,pElemObj
);
2918 short nDim
= pDimArray
->GetDims();
2919 if ( 1 <= nDim
&& nDim
<= 2 )
2921 INT32 nCs
, nCe
, nRs
, nRe
;
2926 { // array( cols ) eine Zeile, mehrere Spalten
2927 pDimArray
->GetDim32( 1, nCs
, nCe
);
2928 nC
= static_cast<SCSIZE
>(nCe
- nCs
+ 1);
2935 { // array( rows, cols )
2936 pDimArray
->GetDim32( 1, nRs
, nRe
);
2937 nR
= static_cast<SCSIZE
>(nRe
- nRs
+ 1);
2938 pDimArray
->GetDim32( 2, nCs
, nCe
);
2939 nC
= static_cast<SCSIZE
>(nCe
- nCs
+ 1);
2943 ScMatrixRef pMat
= GetNewMat( nC
, nR
);
2948 for ( SCSIZE j
=0; j
< nR
; j
++ )
2951 // bei eindimensionalem array( cols ) wird nIdx[1]
2952 // von SbxDimArray::Get ignoriert
2953 nIdx
[ nRowIdx
] = nRs
+ static_cast<INT32
>(j
);
2954 for ( SCSIZE i
=0; i
< nC
; i
++ )
2956 nIdx
[ nColIdx
] = nCs
+ static_cast<INT32
>(i
);
2957 pV
= pDimArray
->Get32( nIdx
);
2958 eType
= pV
->GetType();
2959 if ( eType
>= SbxINTEGER
&& eType
<= SbxDOUBLE
)
2960 pMat
->PutDouble( pV
->GetDouble(), i
, j
);
2962 pMat
->PutString( pV
->GetString(), i
, j
);
2968 PushIllegalArgument();
2974 PushString( refRes
->GetString() );
2977 pSfxApp
->LeaveBasicCall();
2979 if (bVolatileMacro
&& meVolaileType
== NOT_VOLATILE
)
2980 meVolaileType
= VOLATILE_MACRO
;
2984 BOOL
ScInterpreter::SetSbxVariable( SbxVariable
* pVar
, const ScAddress
& rPos
)
2986 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::SetSbxVariable" );
2988 ScBaseCell
* pCell
= pDok
->GetCell( rPos
);
2993 switch( pCell
->GetCellType() )
2995 case CELLTYPE_VALUE
:
2996 nVal
= GetValueCellValue( rPos
, (ScValueCell
*)pCell
);
2997 pVar
->PutDouble( nVal
);
2999 case CELLTYPE_STRING
:
3002 ((ScStringCell
*)pCell
)->GetString( aVal
);
3003 pVar
->PutString( aVal
);
3006 case CELLTYPE_EDIT
:
3009 ((ScEditCell
*) pCell
)->GetString( aVal
);
3010 pVar
->PutString( aVal
);
3013 case CELLTYPE_FORMULA
:
3014 nErr
= ((ScFormulaCell
*)pCell
)->GetErrCode();
3017 if( ((ScFormulaCell
*)pCell
)->IsValue() )
3019 nVal
= ((ScFormulaCell
*)pCell
)->GetValue();
3020 pVar
->PutDouble( nVal
);
3025 ((ScFormulaCell
*)pCell
)->GetString( aVal
);
3026 pVar
->PutString( aVal
);
3030 SetError( nErr
), bOk
= FALSE
;
3033 pVar
->PutDouble( 0.0 );
3037 pVar
->PutDouble( 0.0 );
3042 void ScInterpreter::ScTableOp()
3044 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTableOp" );
3045 BYTE nParamCount
= GetByte();
3046 if (nParamCount
!= 3 && nParamCount
!= 5)
3048 PushIllegalParameter();
3051 ScInterpreterTableOpParams
* pTableOp
= new ScInterpreterTableOpParams
;
3052 if (nParamCount
== 5)
3054 PopSingleRef( pTableOp
->aNew2
);
3055 PopSingleRef( pTableOp
->aOld2
);
3057 PopSingleRef( pTableOp
->aNew1
);
3058 PopSingleRef( pTableOp
->aOld1
);
3059 PopSingleRef( pTableOp
->aFormulaPos
);
3061 pTableOp
->bValid
= TRUE
;
3062 pDok
->aTableOpList
.Insert( pTableOp
);
3063 pDok
->IncInterpreterTableOpLevel();
3065 BOOL bReuseLastParams
= (pDok
->aLastTableOpParams
== *pTableOp
);
3066 if ( bReuseLastParams
)
3068 pTableOp
->aNotifiedFormulaPos
= pDok
->aLastTableOpParams
.aNotifiedFormulaPos
;
3069 pTableOp
->bRefresh
= TRUE
;
3070 for ( ::std::vector
< ScAddress
>::const_iterator
iBroadcast(
3071 pTableOp
->aNotifiedFormulaPos
.begin() );
3072 iBroadcast
!= pTableOp
->aNotifiedFormulaPos
.end();
3074 { // emulate broadcast and indirectly collect cell pointers
3075 ScBaseCell
* pCell
= pDok
->GetCell( *iBroadcast
);
3076 if ( pCell
&& pCell
->GetCellType() == CELLTYPE_FORMULA
)
3077 ((ScFormulaCell
*)pCell
)->SetTableOpDirty();
3081 { // broadcast and indirectly collect cell pointers and positions
3082 pDok
->SetTableOpDirty( pTableOp
->aOld1
);
3083 if ( nParamCount
== 5 )
3084 pDok
->SetTableOpDirty( pTableOp
->aOld2
);
3086 pTableOp
->bCollectNotifications
= FALSE
;
3088 ScBaseCell
* pFCell
= pDok
->GetCell( pTableOp
->aFormulaPos
);
3089 if ( pFCell
&& pFCell
->GetCellType() == CELLTYPE_FORMULA
)
3090 ((ScFormulaCell
*)pFCell
)->SetDirtyVar();
3091 if ( HasCellValueData( pFCell
) )
3092 PushDouble( GetCellValue( pTableOp
->aFormulaPos
, pFCell
));
3096 GetCellString( aCellString
, pFCell
);
3097 PushString( aCellString
);
3100 pDok
->aTableOpList
.Remove( pTableOp
);
3101 // set dirty again once more to be able to recalculate original
3102 for ( ::std::vector
< ScFormulaCell
* >::const_iterator
iBroadcast(
3103 pTableOp
->aNotifiedFormulaCells
.begin() );
3104 iBroadcast
!= pTableOp
->aNotifiedFormulaCells
.end();
3107 (*iBroadcast
)->SetTableOpDirty();
3110 // save these params for next incarnation
3111 if ( !bReuseLastParams
)
3112 pDok
->aLastTableOpParams
= *pTableOp
;
3114 if ( pFCell
&& pFCell
->GetCellType() == CELLTYPE_FORMULA
)
3116 ((ScFormulaCell
*)pFCell
)->SetDirtyVar();
3117 ((ScFormulaCell
*)pFCell
)->GetErrCode(); // recalculate original
3120 // Reset all dirty flags so next incarnation does really collect all cell
3121 // pointers during notifications and not just non-dirty ones, which may
3122 // happen if a formula cell is used by more than one TableOp block.
3123 for ( ::std::vector
< ScFormulaCell
* >::const_iterator
iBroadcast2(
3124 pTableOp
->aNotifiedFormulaCells
.begin() );
3125 iBroadcast2
!= pTableOp
->aNotifiedFormulaCells
.end();
3128 (*iBroadcast2
)->ResetTableOpDirtyVar();
3132 pDok
->DecInterpreterTableOpLevel();
3138 void ScInterpreter::ScErrCell()
3140 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScErrCell" );
3141 double fErrNum = GetDouble();
3142 PushError((USHORT) fErrNum);
3146 void ScInterpreter::ScDBArea()
3148 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBArea" );
3149 ScDBData
* pDBData
= pDok
->GetDBCollection()->FindIndex( pCur
->GetIndex());
3152 ScComplexRefData aRefData
;
3153 aRefData
.InitFlags();
3154 pDBData
->GetArea( (SCTAB
&) aRefData
.Ref1
.nTab
,
3155 (SCCOL
&) aRefData
.Ref1
.nCol
,
3156 (SCROW
&) aRefData
.Ref1
.nRow
,
3157 (SCCOL
&) aRefData
.Ref2
.nCol
,
3158 (SCROW
&) aRefData
.Ref2
.nRow
);
3159 aRefData
.Ref2
.nTab
= aRefData
.Ref1
.nTab
;
3160 aRefData
.CalcRelFromAbs( aPos
);
3161 PushTempToken( new ScDoubleRefToken( aRefData
) );
3164 PushError( errNoName
);
3168 void ScInterpreter::ScColRowNameAuto()
3170 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScColRowNameAuto" );
3171 ScComplexRefData
aRefData( static_cast<const ScToken
*>(pCur
)->GetDoubleRef() );
3172 aRefData
.CalcAbsIfRel( aPos
);
3173 if ( aRefData
.Valid() )
3179 // evtl. Begrenzung durch definierte ColRowNameRanges merken
3180 nCol2
= aRefData
.Ref2
.nCol
;
3181 nRow2
= aRefData
.Ref2
.nRow
;
3182 // DataArea der ersten Zelle
3183 nStartCol
= aRefData
.Ref2
.nCol
= aRefData
.Ref1
.nCol
;
3184 nStartRow
= aRefData
.Ref2
.nRow
= aRefData
.Ref1
.nRow
;
3185 aRefData
.Ref2
.nTab
= aRefData
.Ref1
.nTab
;
3186 pDok
->GetDataArea( (SCTAB
&) aRefData
.Ref1
.nTab
,
3187 (SCCOL
&) aRefData
.Ref1
.nCol
,
3188 (SCROW
&) aRefData
.Ref1
.nRow
,
3189 (SCCOL
&) aRefData
.Ref2
.nCol
,
3190 (SCROW
&) aRefData
.Ref2
.nRow
,
3192 // DataArea im Ursprung begrenzen
3193 aRefData
.Ref1
.nCol
= nStartCol
;
3194 aRefData
.Ref1
.nRow
= nStartRow
;
3196 //! korrespondiert mit ScCompiler::GetToken
3197 if ( aRefData
.Ref1
.IsColRel() )
3199 aRefData
.Ref2
.nCol
= nStartCol
;
3200 // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten
3201 if ( aRefData
.Ref2
.nRow
> nRow2
)
3202 aRefData
.Ref2
.nRow
= nRow2
;
3204 if ( aPos
.Col() == nStartCol
3205 && nStartRow
<= (nMyRow
= aPos
.Row()) && nMyRow
<= aRefData
.Ref2
.nRow
)
3206 { // Formel in gleicher Spalte und innerhalb des Range
3207 if ( nMyRow
== nStartRow
)
3208 { // direkt unter dem Namen den Rest nehmen
3210 if ( nStartRow
> MAXROW
)
3212 aRefData
.Ref1
.nRow
= nStartRow
;
3215 { // weiter unten vom Namen bis zur Formelzelle
3216 aRefData
.Ref2
.nRow
= nMyRow
- 1;
3222 aRefData
.Ref2
.nRow
= nStartRow
;
3223 // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten
3224 if ( aRefData
.Ref2
.nCol
> nCol2
)
3225 aRefData
.Ref2
.nCol
= nCol2
;
3227 if ( aPos
.Row() == nStartRow
3228 && nStartCol
<= (nMyCol
= aPos
.Col()) && nMyCol
<= aRefData
.Ref2
.nCol
)
3229 { // Formel in gleicher Zeile und innerhalb des Range
3230 if ( nMyCol
== nStartCol
)
3231 { // direkt neben dem Namen den Rest nehmen
3233 if ( nStartCol
> MAXCOL
)
3235 aRefData
.Ref1
.nCol
= nStartCol
;
3238 { // weiter rechts vom Namen bis zur Formelzelle
3239 aRefData
.Ref2
.nCol
= nMyCol
- 1;
3243 aRefData
.CalcRelFromAbs( aPos
);
3244 PushTempToken( new ScDoubleRefToken( aRefData
) );
3247 PushError( errNoRef
);
3250 void ScInterpreter::ScExternalRef()
3252 ScExternalRefManager
* pRefMgr
= pDok
->GetExternalRefManager();
3253 const String
* pFile
= pRefMgr
->getExternalFileName(pCur
->GetIndex());
3255 PushError(errNoName
);
3257 switch (pCur
->GetType())
3259 case svExternalSingleRef
:
3261 ScSingleRefData
aData(static_cast<const ScToken
*>(pCur
)->GetSingleRef());
3262 if (aData
.IsTabRel())
3264 DBG_ERROR("ScCompiler::GetToken: external single reference must have an absolute table reference!");
3268 aData
.CalcAbsIfRel(aPos
);
3269 ScAddress
aAddr(aData
.nCol
, aData
.nRow
, aData
.nTab
);
3270 ScExternalRefCache::CellFormat aFmt
;
3271 ScExternalRefCache::TokenRef xNew
= pRefMgr
->getSingleRefToken(
3272 pCur
->GetIndex(), pCur
->GetString(), aAddr
, &aPos
, NULL
, &aFmt
);
3277 PushTempToken( *xNew
); // push a clone
3281 nFuncFmtType
= aFmt
.mnType
;
3282 nFuncFmtIndex
= aFmt
.mnIndex
;
3286 //break; // unreachable, prevent compiler warning
3287 case svExternalDoubleRef
:
3289 ScComplexRefData
aData(static_cast<const ScToken
*>(pCur
)->GetDoubleRef());
3290 if (aData
.Ref1
.IsTabRel() || aData
.Ref2
.IsTabRel())
3292 DBG_ERROR("ScCompiler::GetToken: external double reference must have an absolute table reference!");
3296 aData
.CalcAbsIfRel(aPos
);
3297 ScRange
aRange(aData
.Ref1
.nCol
, aData
.Ref1
.nRow
, aData
.Ref1
.nTab
,
3298 aData
.Ref2
.nCol
, aData
.Ref2
.nRow
, aData
.Ref2
.nTab
);
3299 ScExternalRefCache::TokenArrayRef xNew
= pRefMgr
->getDoubleRefTokens(
3300 pCur
->GetIndex(), pCur
->GetString(), aRange
, &aPos
);
3305 ScToken
* p
= static_cast<ScToken
*>(xNew
->First());
3306 if (p
->GetType() != svMatrix
)
3311 // Can't handle more than one matrix per parameter.
3312 SetError( errIllegalArgument
);
3316 PushMatrix(p
->GetMatrix());
3319 //break; // unreachable, prevent compiler warning
3323 PushError(errNoRef
);
3326 // --- internals ------------------------------------------------------------
3329 void ScInterpreter::ScAnswer()
3331 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAnswer" );
3332 String
aStr( GetString() );
3333 if( aStr
.EqualsIgnoreCaseAscii( "Das Leben, das Universum und der ganze Rest" ) )
3343 void ScInterpreter::ScCalcTeam()
3345 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCalcTeam" );
3346 static BOOL bShown
= FALSE
;
3350 String
aTeam( RTL_CONSTASCII_USTRINGPARAM( "Ballach, Nebel, Rentz, Rathke, Marmion" ) );
3351 if ( (GetByte() == 1) && ::rtl::math::approxEqual( GetDouble(), 1996) )
3352 aTeam
.AppendAscii( " (a word with 'B': -Olk, -Nietsch, -Daeumling)" );
3353 PushString( aTeam
);
3361 void ScInterpreter::ScSpewFunc()
3363 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSpewFunc" );
3364 BOOL bRefresh
= FALSE
;
3365 BOOL bClear
= FALSE
;
3367 BYTE nParamCount
= GetByte();
3368 while ( nParamCount
-- > 0)
3370 switch ( GetStackType() )
3376 const sal_Unicode ch
= GetString().GetChar(0);
3377 if ( !bRefresh
&& ch
< 256 )
3378 bRefresh
= (tolower( (sal_uChar
) ch
) == 'r');
3379 if ( !bClear
&& ch
< 256 )
3380 bClear
= (tolower( (sal_uChar
) ch
) == 'c');
3390 theSpew
.Clear(); // GetSpew liest SpewRulesFile neu
3391 theSpew
.GetSpew( aStr
);
3393 theSpew
.Clear(); // release Memory
3394 xub_StrLen nPos
= 0;
3395 while ( (nPos
= aStr
.SearchAndReplace( '\n', ' ', nPos
)) != STRING_NOTFOUND
)
3398 aStr
.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "spitted out all spew :-(" ) );
3404 #include "sctictac.hxx"
3405 #include "scmod.hxx"
3407 extern "C" { static void SAL_CALL
thisModule() {} }
3409 void ScInterpreter::ScGame()
3411 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGame" );
3416 SC_GAME_TICTACTOE
= SC_GAME_START
,
3421 // ein grep im binary laeuft ins leere
3422 static sal_Char sGameNone
[] = "\14\36\6\137\10\27\36\13\100";
3423 static sal_Char sGameOnce
[] = "\20\27\137\21\20\123\137\21\20\13\137\36\30\36\26\21\136";
3424 static sal_Char sGameTicTacToe
[] = "\53\26\34\53\36\34\53\20\32";
3425 static sal_Char sGameStarWars
[] = "\54\13\36\15\50\36\15\14";
3426 static sal_Char sGameFrogger
[] = "\71\15\20\30\30\26\32";
3427 sal_Char
* const pGames
[SC_GAME_COUNT
] = {
3440 // Routine um Datenblock zu erzeugen:
3446 while ( (c
= getchar()) != EOF
)
3456 printf( "\\%o", c
);
3468 static BOOL bRun
[SC_GAME_COUNT
] = { FALSE
};
3469 static BOOL bFirst
= TRUE
;
3473 for ( int j
= SC_GAME_NONE
; j
< SC_GAME_COUNT
; j
++ )
3475 sal_Char
* p
= pGames
[j
];
3481 GameType eGame
= SC_GAME_NONE
;
3482 BYTE nParamCount
= GetByte();
3483 if ( nParamCount
>= 1 )
3485 String
aStr( GetString() );
3487 for ( int j
= SC_GAME_START
; j
< SC_GAME_COUNT
; j
++ )
3489 if ( aStr
.EqualsAscii( pGames
[j
] ) )
3491 eGame
= (GameType
) j
;
3495 if ( eGame
!= SC_GAME_NONE
)
3497 // jedes Game nur ein einziges Mal starten, um nicht durch Recalc
3498 // o.ae. mehrere Instanzen zu haben, ideal waere eine Abfrage an den
3499 // Games, ob sie bereits laufen ...
3500 if ( bRun
[ eGame
] && eGame
!= SC_GAME_TICTACTOE
)
3501 eGame
= SC_GAME_ONCE
;
3504 bRun
[ eGame
] = TRUE
;
3507 case SC_GAME_TICTACTOE
:
3509 static ScTicTacToe
* pTicTacToe
= NULL
;
3510 static ScRange aTTTrange
;
3511 static BOOL bHumanFirst
= FALSE
;
3512 if ( nParamCount
>= 1 )
3514 if ( GetStackType() == svDoubleRef
)
3517 PopDoubleRef( aRange
);
3519 if ( aRange
.aEnd
.Col() - aRange
.aStart
.Col() == 2
3520 && aRange
.aEnd
.Row() - aRange
.aStart
.Row() == 2 )
3524 bOk
= (aRange
== aTTTrange
);
3529 pTicTacToe
= new ScTicTacToe( pDok
,
3531 pTicTacToe
->Initialize( bHumanFirst
);
3533 // nur einmal und das auf dem gleichen Range
3535 eGame
= SC_GAME_ONCE
;
3538 Square_Type aWinner
= pTicTacToe
->CalcMove();
3539 pTicTacToe
->GetOutput( aFuncResult
);
3540 if ( aWinner
!= pTicTacToe
->GetEmpty() )
3544 bRun
[ eGame
] = FALSE
;
3545 bHumanFirst
= !bHumanFirst
;
3547 pDok
->GetDocumentShell()->Broadcast(
3548 SfxSimpleHint( FID_DATACHANGED
) );
3549 pDok
->ResetChanged( aRange
);
3553 SetError( errIllegalArgument
);
3556 SetError( errIllegalParameter
);
3559 SetError( errIllegalParameter
);
3562 case SC_GAME_STARWARS
:
3564 oslModule m_tfu
= osl_loadModuleRelative(&thisModule
, rtl::OUString::createFromAscii( SVLIBRARY( "tfu" ) ).pData
, SAL_LOADMODULE_NOW
);
3565 typedef void StartInvader_Type (Window
*, ResMgr
*);
3567 StartInvader_Type
*StartInvader
= (StartInvader_Type
*) osl_getFunctionSymbol( m_tfu
, rtl::OUString::createFromAscii("StartInvader").pData
);
3569 StartInvader( Application::GetDefDialogParent(), ResMgr::CreateResMgr( "tfu" ));
3572 case SC_GAME_FROGGER
:
3577 // added to avoid warnings
3584 while ( nParamCount
-- > 0)
3586 if ( !aFuncResult
.Len() )
3587 PushString( String( pGames
[ eGame
], RTL_TEXTENCODING_ASCII_US
) );
3589 PushString( aFuncResult
);
3592 void ScInterpreter::ScTTT()
3593 { // Temporaerer Test-Tanz, zum auspropieren von Funktionen etc.
3595 BYTE nParamCount
= GetByte();
3596 // do something, nParamCount bei Pops runterzaehlen!
3598 if ( bOk
&& nParamCount
)
3604 while ( nParamCount
-- > 0)
3606 static const sal_Unicode __FAR_DATA sEyes
[] = { ',',';',':','|','8','B', 0 };
3607 static const sal_Unicode __FAR_DATA sGoods
[] = { ')',']','}', 0 };
3608 static const sal_Unicode __FAR_DATA sBads
[] = { '(','[','{','/', 0 };
3609 sal_Unicode aFace
[4];
3612 aFace
[0] = sEyes
[ rand() % ((sizeof( sEyes
)/sizeof(sal_Unicode
)) - 1) ];
3614 aFace
[2] = sGoods
[ rand() % ((sizeof( sGoods
)/sizeof(sal_Unicode
)) - 1) ];
3620 aFace
[2] = sBads
[ rand() % ((sizeof( sBads
)/sizeof(sal_Unicode
)) - 1) ];
3623 PushStringBuffer( aFace
);
3626 // -------------------------------------------------------------------------
3629 ScInterpreter::ScInterpreter( ScFormulaCell
* pCell
, ScDocument
* pDoc
,
3630 const ScAddress
& rPos
, ScTokenArray
& r
) :
3635 pTokenMatrixMap( NULL
),
3636 pMyFormulaCell( pCell
),
3637 pFormatter( pDoc
->GetFormatTable() ),
3638 bCalcAsShown( pDoc
->GetDocOptions().IsCalcAsShown() ),
3639 meVolaileType(NOT_VOLATILE
)
3641 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTTT" );
3642 // pStack = new ScToken*[ MAXSTACK ];
3644 BYTE cMatFlag
= pMyFormulaCell
->GetMatrixFlag();
3645 bMatrixFormula
= ( cMatFlag
== MM_FORMULA
|| cMatFlag
== MM_FAKE
);
3646 if (!bGlobalStackInUse
)
3648 bGlobalStackInUse
= TRUE
;
3650 pGlobalStack
= new ScTokenStack
;
3651 pStackObj
= pGlobalStack
;
3655 pStackObj
= new ScTokenStack
;
3657 pStack
= pStackObj
->pPointer
;
3660 ScInterpreter::~ScInterpreter()
3664 if ( pStackObj
== pGlobalStack
)
3665 bGlobalStackInUse
= FALSE
;
3668 if (pTokenMatrixMap
)
3669 delete pTokenMatrixMap
;
3673 void ScInterpreter::GlobalExit() // static
3675 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GlobalExit" );
3676 DBG_ASSERT(!bGlobalStackInUse
, "wer benutzt noch den TokenStack?");
3677 DELETEZ(pGlobalStack
);
3681 StackVar
ScInterpreter::Interpret()
3683 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Interpret" );
3684 short nRetTypeExpr
= NUMBERFORMAT_UNDEFINED
;
3685 ULONG nRetIndexExpr
= 0;
3686 USHORT nErrorFunction
= 0;
3687 USHORT nErrorFunctionCount
= 0;
3691 nStackBase
= sp
= maxsp
= 0;
3692 nRetFmtType
= NUMBERFORMAT_UNDEFINED
;
3693 nFuncFmtType
= NUMBERFORMAT_UNDEFINED
;
3694 nFuncFmtIndex
= nCurFmtIndex
= nRetFmtIndex
= 0;
3698 ScTokenMatrixMap::const_iterator aTokenMatrixMapIter
;
3700 // Once upon a time we used to have FP exceptions on, and there was a
3701 // Windows printer driver that kept switching off exceptions, so we had to
3702 // switch them back on again every time. Who knows if there isn't a driver
3703 // that keeps switching exceptions on, now that we run with exceptions off,
3704 // so reassure exceptions are really off.
3705 SAL_MATH_FPEXCEPTIONS_OFF();
3708 while( ( pCur
= aCode
.Next() ) != NULL
3709 && (!nGlobalError
|| nErrorFunction
<= nErrorFunctionCount
) )
3711 OpCode eOp
= pCur
->GetOpCode();
3712 cPar
= pCur
->GetByte();
3713 if ( eOp
== ocPush
)
3715 // RPN code push without error
3716 PushWithoutError( (FormulaToken
&) *pCur
);
3718 else if (pTokenMatrixMap
&& !(eOp
== ocIf
|| eOp
== ocChose
) &&
3719 ((aTokenMatrixMapIter
= pTokenMatrixMap
->find( pCur
)) !=
3720 pTokenMatrixMap
->end()) &&
3721 (*aTokenMatrixMapIter
).second
->GetType() != svJumpMatrix
)
3723 // Path already calculated, reuse result.
3724 nStackBase
= sp
- pCur
->GetParamCount();
3725 if ( nStackBase
> sp
)
3726 nStackBase
= sp
; // underflow?!?
3728 PushTempToken( (*aTokenMatrixMapIter
).second
);
3732 // previous expression determines the current number format
3733 nCurFmtType
= nRetTypeExpr
;
3734 nCurFmtIndex
= nRetIndexExpr
;
3735 // default function's format, others are set if needed
3736 nFuncFmtType
= NUMBERFORMAT_NUMBER
;
3739 if ( eOp
== ocIf
|| eOp
== ocChose
)
3740 nStackBase
= sp
; // don't mess around with the jumps
3743 // Convert parameters to matrix if in array/matrix formula and
3744 // parameters of function indicate doing so. Create JumpMatrix
3746 if ( MatrixParameterConversion() )
3748 eOp
= ocNone
; // JumpMatrix created
3752 nStackBase
= sp
- pCur
->GetParamCount();
3754 if ( nStackBase
> sp
)
3755 nStackBase
= sp
; // underflow?!?
3760 case ocClose
: // pushed by the compiler
3761 case ocMissing
: ScMissing(); break;
3762 case ocMacro
: ScMacro(); break;
3763 case ocDBArea
: ScDBArea(); break;
3764 case ocColRowNameAuto
: ScColRowNameAuto(); break;
3765 // separated case ocPush : Push( (ScToken&) *pCur ); break;
3766 case ocExternalRef
: ScExternalRef(); break;
3767 case ocIf
: ScIfJump(); break;
3768 case ocChose
: ScChoseJump(); break;
3769 case ocAdd
: ScAdd(); break;
3770 case ocSub
: ScSub(); break;
3771 case ocMul
: ScMul(); break;
3772 case ocDiv
: ScDiv(); break;
3773 case ocAmpersand
: ScAmpersand(); break;
3774 case ocPow
: ScPow(); break;
3775 case ocEqual
: ScEqual(); break;
3776 case ocNotEqual
: ScNotEqual(); break;
3777 case ocLess
: ScLess(); break;
3778 case ocGreater
: ScGreater(); break;
3779 case ocLessEqual
: ScLessEqual(); break;
3780 case ocGreaterEqual
: ScGreaterEqual(); break;
3781 case ocAnd
: ScAnd(); break;
3782 case ocOr
: ScOr(); break;
3783 case ocIntersect
: ScIntersect(); break;
3784 case ocRange
: ScRangeFunc(); break;
3785 case ocUnion
: ScUnionFunc(); break;
3786 case ocNot
: ScNot(); break;
3788 case ocNeg
: ScNeg(); break;
3789 case ocPercentSign
: ScPercentSign(); break;
3790 case ocPi
: ScPi(); break;
3791 // case ocDefPar : ScDefPar(); break;
3792 case ocRandom
: ScRandom(); break;
3793 case ocTrue
: ScTrue(); break;
3794 case ocFalse
: ScFalse(); break;
3795 case ocGetActDate
: ScGetActDate(); break;
3796 case ocGetActTime
: ScGetActTime(); break;
3797 case ocNotAvail
: PushError( NOTAVAILABLE
); break;
3798 case ocDeg
: ScDeg(); break;
3799 case ocRad
: ScRad(); break;
3800 case ocSin
: ScSin(); break;
3801 case ocCos
: ScCos(); break;
3802 case ocTan
: ScTan(); break;
3803 case ocCot
: ScCot(); break;
3804 case ocArcSin
: ScArcSin(); break;
3805 case ocArcCos
: ScArcCos(); break;
3806 case ocArcTan
: ScArcTan(); break;
3807 case ocArcCot
: ScArcCot(); break;
3808 case ocSinHyp
: ScSinHyp(); break;
3809 case ocCosHyp
: ScCosHyp(); break;
3810 case ocTanHyp
: ScTanHyp(); break;
3811 case ocCotHyp
: ScCotHyp(); break;
3812 case ocArcSinHyp
: ScArcSinHyp(); break;
3813 case ocArcCosHyp
: ScArcCosHyp(); break;
3814 case ocArcTanHyp
: ScArcTanHyp(); break;
3815 case ocArcCotHyp
: ScArcCotHyp(); break;
3816 case ocExp
: ScExp(); break;
3817 case ocLn
: ScLn(); break;
3818 case ocLog10
: ScLog10(); break;
3819 case ocSqrt
: ScSqrt(); break;
3820 case ocFact
: ScFact(); break;
3821 case ocGetYear
: ScGetYear(); break;
3822 case ocGetMonth
: ScGetMonth(); break;
3823 case ocGetDay
: ScGetDay(); break;
3824 case ocGetDayOfWeek
: ScGetDayOfWeek(); break;
3825 case ocWeek
: ScGetWeekOfYear(); break;
3826 case ocEasterSunday
: ScEasterSunday(); break;
3827 case ocGetHour
: ScGetHour(); break;
3828 case ocGetMin
: ScGetMin(); break;
3829 case ocGetSec
: ScGetSec(); break;
3830 case ocPlusMinus
: ScPlusMinus(); break;
3831 case ocAbs
: ScAbs(); break;
3832 case ocInt
: ScInt(); break;
3833 case ocEven
: ScEven(); break;
3834 case ocOdd
: ScOdd(); break;
3835 case ocPhi
: ScPhi(); break;
3836 case ocGauss
: ScGauss(); break;
3837 case ocStdNormDist
: ScStdNormDist(); break;
3838 case ocFisher
: ScFisher(); break;
3839 case ocFisherInv
: ScFisherInv(); break;
3840 case ocIsEmpty
: ScIsEmpty(); break;
3841 case ocIsString
: ScIsString(); break;
3842 case ocIsNonString
: ScIsNonString(); break;
3843 case ocIsLogical
: ScIsLogical(); break;
3844 case ocType
: ScType(); break;
3845 case ocCell
: ScCell(); break;
3846 case ocIsRef
: ScIsRef(); break;
3847 case ocIsValue
: ScIsValue(); break;
3848 case ocIsFormula
: ScIsFormula(); break;
3849 case ocFormula
: ScFormula(); break;
3850 case ocIsNA
: ScIsNV(); break;
3851 case ocIsErr
: ScIsErr(); break;
3852 case ocIsError
: ScIsError(); break;
3853 case ocIsEven
: ScIsEven(); break;
3854 case ocIsOdd
: ScIsOdd(); break;
3855 case ocN
: ScN(); break;
3856 case ocGetDateValue
: ScGetDateValue(); break;
3857 case ocGetTimeValue
: ScGetTimeValue(); break;
3858 case ocCode
: ScCode(); break;
3859 case ocTrim
: ScTrim(); break;
3860 case ocUpper
: ScUpper(); break;
3861 case ocPropper
: ScPropper(); break;
3862 case ocLower
: ScLower(); break;
3863 case ocLen
: ScLen(); break;
3864 case ocT
: ScT(); break;
3865 case ocClean
: ScClean(); break;
3866 case ocValue
: ScValue(); break;
3867 case ocChar
: ScChar(); break;
3868 case ocArcTan2
: ScArcTan2(); break;
3869 case ocMod
: ScMod(); break;
3870 case ocPower
: ScPower(); break;
3871 case ocRound
: ScRound(); break;
3872 case ocRoundUp
: ScRoundUp(); break;
3874 case ocRoundDown
: ScRoundDown(); break;
3875 case ocCeil
: ScCeil(); break;
3876 case ocFloor
: ScFloor(); break;
3877 case ocSumProduct
: ScSumProduct(); break;
3878 case ocSumSQ
: ScSumSQ(); break;
3879 case ocSumX2MY2
: ScSumX2MY2(); break;
3880 case ocSumX2DY2
: ScSumX2DY2(); break;
3881 case ocSumXMY2
: ScSumXMY2(); break;
3882 case ocLog
: ScLog(); break;
3883 case ocGCD
: ScGCD(); break;
3884 case ocLCM
: ScLCM(); break;
3885 case ocGetDate
: ScGetDate(); break;
3886 case ocGetTime
: ScGetTime(); break;
3887 case ocGetDiffDate
: ScGetDiffDate(); break;
3888 case ocGetDiffDate360
: ScGetDiffDate360(); break;
3889 case ocMin
: ScMin( FALSE
); break;
3890 case ocMinA
: ScMin( TRUE
); break;
3891 case ocMax
: ScMax( FALSE
); break;
3892 case ocMaxA
: ScMax( TRUE
); break;
3893 case ocSum
: ScSum(); break;
3894 case ocProduct
: ScProduct(); break;
3895 case ocNPV
: ScNPV(); break;
3896 case ocIRR
: ScIRR(); break;
3897 case ocMIRR
: ScMIRR(); break;
3898 case ocISPMT
: ScISPMT(); break;
3899 case ocAverage
: ScAverage( FALSE
); break;
3900 case ocAverageA
: ScAverage( TRUE
); break;
3901 case ocCount
: ScCount(); break;
3902 case ocCount2
: ScCount2(); break;
3903 case ocVar
: ScVar( FALSE
); break;
3904 case ocVarA
: ScVar( TRUE
); break;
3905 case ocVarP
: ScVarP( FALSE
); break;
3906 case ocVarPA
: ScVarP( TRUE
); break;
3907 case ocStDev
: ScStDev( FALSE
); break;
3908 case ocStDevA
: ScStDev( TRUE
); break;
3909 case ocStDevP
: ScStDevP( FALSE
); break;
3910 case ocStDevPA
: ScStDevP( TRUE
); break;
3911 case ocBW
: ScBW(); break;
3912 case ocDIA
: ScDIA(); break;
3913 case ocGDA
: ScGDA(); break;
3914 case ocGDA2
: ScGDA2(); break;
3915 case ocVBD
: ScVDB(); break;
3916 case ocLaufz
: ScLaufz(); break;
3917 case ocLIA
: ScLIA(); break;
3918 case ocRMZ
: ScRMZ(); break;
3919 case ocColumns
: ScColumns(); break;
3920 case ocRows
: ScRows(); break;
3921 case ocTables
: ScTables(); break;
3922 case ocColumn
: ScColumn(); break;
3923 case ocRow
: ScRow(); break;
3924 case ocTable
: ScTable(); break;
3925 case ocZGZ
: ScZGZ(); break;
3926 case ocZW
: ScZW(); break;
3927 case ocZZR
: ScZZR(); break;
3928 case ocZins
: ScZins(); break;
3929 case ocZinsZ
: ScZinsZ(); break;
3930 case ocKapz
: ScKapz(); break;
3931 case ocKumZinsZ
: ScKumZinsZ(); break;
3932 case ocKumKapZ
: ScKumKapZ(); break;
3933 case ocEffektiv
: ScEffektiv(); break;
3934 case ocNominal
: ScNominal(); break;
3935 case ocSubTotal
: ScSubTotal(); break;
3936 case ocDBSum
: ScDBSum(); break;
3937 case ocDBCount
: ScDBCount(); break;
3938 case ocDBCount2
: ScDBCount2(); break;
3939 case ocDBAverage
: ScDBAverage(); break;
3940 case ocDBGet
: ScDBGet(); break;
3941 case ocDBMax
: ScDBMax(); break;
3942 case ocDBMin
: ScDBMin(); break;
3943 case ocDBProduct
: ScDBProduct(); break;
3944 case ocDBStdDev
: ScDBStdDev(); break;
3945 case ocDBStdDevP
: ScDBStdDevP(); break;
3946 case ocDBVar
: ScDBVar(); break;
3947 case ocDBVarP
: ScDBVarP(); break;
3948 case ocIndirect
: ScIndirect(); break;
3949 case ocAddress
: ScAddressFunc(); break;
3950 case ocMatch
: ScMatch(); break;
3951 case ocCountEmptyCells
: ScCountEmptyCells(); break;
3952 case ocCountIf
: ScCountIf(); break;
3953 case ocSumIf
: ScSumIf(); break;
3954 case ocLookup
: ScLookup(); break;
3955 case ocVLookup
: ScVLookup(); break;
3956 case ocHLookup
: ScHLookup(); break;
3957 case ocIndex
: ScIndex(); break;
3958 case ocMultiArea
: ScMultiArea(); break;
3959 case ocOffset
: ScOffset(); break;
3960 case ocAreas
: ScAreas(); break;
3961 case ocCurrency
: ScCurrency(); break;
3962 case ocReplace
: ScReplace(); break;
3963 case ocFixed
: ScFixed(); break;
3964 case ocFind
: ScFind(); break;
3965 case ocExact
: ScExact(); break;
3966 case ocLeft
: ScLeft(); break;
3967 case ocRight
: ScRight(); break;
3968 case ocSearch
: ScSearch(); break;
3969 case ocMid
: ScMid(); break;
3970 case ocText
: ScText(); break;
3971 case ocSubstitute
: ScSubstitute(); break;
3972 case ocRept
: ScRept(); break;
3973 case ocConcat
: ScConcat(); break;
3974 case ocMatValue
: ScMatValue(); break;
3975 case ocMatrixUnit
: ScEMat(); break;
3976 case ocMatDet
: ScMatDet(); break;
3977 case ocMatInv
: ScMatInv(); break;
3978 case ocMatMult
: ScMatMult(); break;
3979 case ocMatTrans
: ScMatTrans(); break;
3980 case ocMatRef
: ScMatRef(); break;
3981 case ocBackSolver
: ScBackSolver(); break;
3982 case ocB
: ScB(); break;
3983 case ocNormDist
: ScNormDist(); break;
3984 case ocExpDist
: ScExpDist(); break;
3985 case ocBinomDist
: ScBinomDist(); break;
3986 case ocPoissonDist
: ScPoissonDist(); break;
3987 case ocKombin
: ScKombin(); break;
3988 case ocKombin2
: ScKombin2(); break;
3989 case ocVariationen
: ScVariationen(); break;
3990 case ocVariationen2
: ScVariationen2(); break;
3991 case ocHypGeomDist
: ScHypGeomDist(); break;
3992 case ocLogNormDist
: ScLogNormDist(); break;
3993 case ocTDist
: ScTDist(); break;
3994 case ocFDist
: ScFDist(); break;
3995 case ocChiDist
: ScChiDist(); break;
3996 case ocChiSqDist
: ScChiSqDist(); break;
3997 case ocStandard
: ScStandard(); break;
3998 case ocAveDev
: ScAveDev(); break;
3999 case ocDevSq
: ScDevSq(); break;
4000 case ocKurt
: ScKurt(); break;
4001 case ocSchiefe
: ScSkew(); break;
4002 case ocModalValue
: ScModalValue(); break;
4003 case ocMedian
: ScMedian(); break;
4004 case ocGeoMean
: ScGeoMean(); break;
4005 case ocHarMean
: ScHarMean(); break;
4006 case ocWeibull
: ScWeibull(); break;
4007 case ocKritBinom
: ScCritBinom(); break;
4008 case ocNegBinomVert
: ScNegBinomDist(); break;
4009 case ocNoName
: ScNoName(); break;
4010 case ocBad
: ScBadName(); break;
4011 case ocZTest
: ScZTest(); break;
4012 case ocTTest
: ScTTest(); break;
4013 case ocFTest
: ScFTest(); break;
4014 case ocRank
: ScRank(); break;
4015 case ocPercentile
: ScPercentile(); break;
4016 case ocPercentrank
: ScPercentrank(); break;
4017 case ocLarge
: ScLarge(); break;
4018 case ocSmall
: ScSmall(); break;
4019 case ocFrequency
: ScFrequency(); break;
4020 case ocQuartile
: ScQuartile(); break;
4021 case ocNormInv
: ScNormInv(); break;
4022 case ocSNormInv
: ScSNormInv(); break;
4023 case ocConfidence
: ScConfidence(); break;
4024 case ocTrimMean
: ScTrimMean(); break;
4025 case ocProb
: ScProbability(); break;
4026 case ocCorrel
: ScCorrel(); break;
4027 case ocCovar
: ScCovar(); break;
4028 case ocPearson
: ScPearson(); break;
4029 case ocRSQ
: ScRSQ(); break;
4030 case ocSTEYX
: ScSTEXY(); break;
4031 case ocSlope
: ScSlope(); break;
4032 case ocIntercept
: ScIntercept(); break;
4033 case ocTrend
: ScTrend(); break;
4034 case ocGrowth
: ScGrowth(); break;
4035 case ocRGP
: ScRGP(); break;
4036 case ocRKP
: ScRKP(); break;
4037 case ocForecast
: ScForecast(); break;
4038 case ocGammaLn
: ScLogGamma(); break;
4039 case ocGamma
: ScGamma(); break;
4040 case ocGammaDist
: ScGammaDist(); break;
4041 case ocGammaInv
: ScGammaInv(); break;
4042 case ocChiTest
: ScChiTest(); break;
4043 case ocChiInv
: ScChiInv(); break;
4044 case ocChiSqInv
: ScChiSqInv(); break;
4045 case ocTInv
: ScTInv(); break;
4046 case ocFInv
: ScFInv(); break;
4047 case ocLogInv
: ScLogNormInv(); break;
4048 case ocBetaDist
: ScBetaDist(); break;
4049 case ocBetaInv
: ScBetaInv(); break;
4050 case ocExternal
: ScExternal(); break;
4051 case ocTableOp
: ScTableOp(); break;
4052 // case ocErrCell : ScErrCell(); break;
4053 case ocStop
: break;
4054 case ocErrorType
: ScErrorType(); break;
4055 case ocCurrent
: ScCurrent(); break;
4056 case ocStyle
: ScStyle(); break;
4057 case ocDde
: ScDde(); break;
4058 case ocBase
: ScBase(); break;
4059 case ocDecimal
: ScDecimal(); break;
4060 case ocConvert
: ScConvert(); break;
4061 case ocEuroConvert
: ScEuroConvert(); break;
4062 case ocRoman
: ScRoman(); break;
4063 case ocArabic
: ScArabic(); break;
4064 case ocInfo
: ScInfo(); break;
4065 case ocHyperLink
: ScHyperLink(); break;
4066 case ocBahtText
: ScBahtText(); break;
4067 case ocPhonetic
: ScPhoneticString(); break;
4068 case ocGetPivotData
: ScGetPivotData(); break;
4069 case ocJis
: ScJis(); break;
4070 case ocAsc
: ScAsc(); break;
4071 case ocAnswer
: ScAnswer(); break;
4072 case ocTeam
: ScCalcTeam(); break;
4073 case ocTTT
: ScTTT(); break;
4074 case ocSpew
: ScSpewFunc(); break;
4075 case ocGame
: ScGame(); break;
4076 case ocNone
: nFuncFmtType
= NUMBERFORMAT_UNDEFINED
; break;
4077 default : PushError( errUnknownOpCode
); break;
4080 // If the function signalled that it pushed a subroutine on the
4081 // instruction code stack instead of a result, continue with
4082 // execution of the subroutine.
4083 if (sp
> nStackBase
&& pStack
[sp
-1]->GetOpCode() == ocCall
)
4086 continue; // while( ( pCur = aCode.Next() ) != NULL ...
4089 if (FormulaCompiler::IsOpCodeVolatile(eOp
))
4090 meVolaileType
= VOLATILE
;
4092 // Remember result matrix in case it could be reused.
4093 if (pTokenMatrixMap
&& sp
&& GetStackType() == svMatrix
)
4094 pTokenMatrixMap
->insert( ScTokenMatrixMap::value_type( pCur
,
4097 // outer function determines format of an expression
4098 if ( nFuncFmtType
!= NUMBERFORMAT_UNDEFINED
)
4100 nRetTypeExpr
= nFuncFmtType
;
4101 // inherit the format index only for currency formats
4102 nRetIndexExpr
= ( nFuncFmtType
== NUMBERFORMAT_CURRENCY
?
4103 nFuncFmtIndex
: 0 );
4107 // Need a clean stack environment for the JumpMatrix to work.
4108 if (nGlobalError
&& eOp
!= ocPush
&& sp
> nStackBase
+ 1)
4110 // Not all functions pop all parameters in case an error is
4111 // generated. Clean up stack. Assumes that every function pushes a
4112 // result, may be arbitrary in case of error.
4113 const FormulaToken
* pLocalResult
= pStack
[ sp
- 1 ];
4114 while (sp
> nStackBase
)
4116 PushTempToken( *pLocalResult
);
4124 if ( GetStackType( ++nLevel
) == svJumpMatrix
)
4126 else if ( GetStackType( ++nLevel
) == svJumpMatrix
)
4130 if ( nLevel
== 1 || (nLevel
== 2 && aCode
.IsEndOfPath()) )
4131 bGotResult
= JumpMatrix( nLevel
);
4134 } while ( bGotResult
);
4137 // Functions that evaluate an error code and directly set nGlobalError to 0,
4138 // usage: switch( OpCode ) { CASE_OCERRFUNC statements; }
4139 #define CASE_OCERRFUNC \
4142 case ocErrorType : \
4146 case ocIsFormula : \
4147 case ocIsLogical : \
4149 case ocIsNonString : \
4165 if ( !nErrorFunctionCount
)
4166 { // count of errorcode functions in formula
4167 for ( FormulaToken
* t
= rArr
.FirstRPN(); t
; t
= rArr
.NextRPN() )
4169 switch ( t
->GetOpCode() )
4172 ++nErrorFunctionCount
;
4178 if ( nErrorFunction
>= nErrorFunctionCount
)
4179 ++nErrorFunction
; // that's it, error => terminate
4183 // End: obtain result
4187 pCur
= pStack
[ sp
-1 ];
4188 if( pCur
->GetOpCode() == ocPush
)
4190 switch( pCur
->GetType() )
4196 nGlobalError
= pCur
->GetError();
4199 if ( nFuncFmtType
== NUMBERFORMAT_UNDEFINED
)
4201 nRetTypeExpr
= NUMBERFORMAT_NUMBER
;
4206 nRetTypeExpr
= NUMBERFORMAT_TEXT
;
4212 PopSingleRef( aAdr
);
4214 PushCellResultToken( false, aAdr
,
4215 &nRetTypeExpr
, &nRetIndexExpr
);
4219 PopError(); // maybe #REF! takes precedence over #VALUE!
4220 PushError( errNoValue
);
4224 if ( bMatrixFormula
)
4225 { // create matrix for {=A1:A5}
4226 PopDoubleRefPushMatrix();
4227 // no break, continue with svMatrix
4232 PopDoubleRef( aRange
);
4234 if ( !nGlobalError
&& DoubleRefToPosSingleRef( aRange
, aAdr
))
4235 PushCellResultToken( false, aAdr
,
4236 &nRetTypeExpr
, &nRetIndexExpr
);
4243 ScMatrixRef xMat
= PopMatrix();
4246 ScMatValType nMatValType
;
4247 const ScMatrixValue
* pMatVal
= xMat
->Get(0, 0, nMatValType
);
4250 if (ScMatrix::IsNonValueType( nMatValType
))
4252 if ( xMat
->IsEmptyPath( 0, 0))
4253 { // result of empty FALSE jump path
4254 FormulaTokenRef xRes
= new FormulaDoubleToken( 0.0);
4255 PushTempToken( new ScMatrixCellResultToken( xMat
, xRes
));
4256 nRetTypeExpr
= NUMBERFORMAT_LOGICAL
;
4260 String
aStr( pMatVal
->GetString());
4261 FormulaTokenRef xRes
= new FormulaStringToken( aStr
);
4262 PushTempToken( new ScMatrixCellResultToken( xMat
, xRes
));
4263 nRetTypeExpr
= NUMBERFORMAT_TEXT
;
4268 USHORT nErr
= GetDoubleErrorValue( pMatVal
->fVal
);
4269 FormulaTokenRef xRes
;
4271 xRes
= new FormulaErrorToken( nErr
);
4273 xRes
= new FormulaDoubleToken( pMatVal
->fVal
);
4274 PushTempToken( new ScMatrixCellResultToken( xMat
, xRes
));
4275 if ( nRetTypeExpr
!= NUMBERFORMAT_LOGICAL
)
4276 nRetTypeExpr
= NUMBERFORMAT_NUMBER
;
4281 SetError( errUnknownStackVariable
);
4282 xMat
->SetErrorInterpreter( NULL
);
4285 SetError( errUnknownStackVariable
);
4289 SetError( errUnknownStackVariable
);
4293 SetError( errUnknownStackVariable
);
4296 SetError( errNoCode
);
4298 if( nRetTypeExpr
!= NUMBERFORMAT_UNDEFINED
)
4300 nRetFmtType
= nRetTypeExpr
;
4301 nRetFmtIndex
= nRetIndexExpr
;
4303 else if( nFuncFmtType
!= NUMBERFORMAT_UNDEFINED
)
4305 nRetFmtType
= nFuncFmtType
;
4306 nRetFmtIndex
= nFuncFmtIndex
;
4309 nRetFmtType
= NUMBERFORMAT_NUMBER
;
4310 // inherit the format index only for currency formats
4311 if ( nRetFmtType
!= NUMBERFORMAT_CURRENCY
)
4314 if (nGlobalError
&& GetStackType() != svError
)
4315 PushError( nGlobalError
);
4317 // THE final result.
4318 xResult
= PopToken();
4320 xResult
= new FormulaErrorToken( errUnknownStackVariable
);
4322 // release tokens in expression stack
4323 FormulaToken
** p
= pStack
;
4327 return xResult
->GetType();