xref: /trunk/main/sc/source/core/tool/interpr4.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_sc.hxx"
24cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <rangelst.hxx>
27cdf0e10cSrcweir #include <sfx2/app.hxx>
28cdf0e10cSrcweir #include <sfx2/docfile.hxx>
29cdf0e10cSrcweir #include <sfx2/objsh.hxx>
30cdf0e10cSrcweir #include <basic/sbmeth.hxx>
31cdf0e10cSrcweir #include <basic/sbmod.hxx>
32cdf0e10cSrcweir #include <basic/sbstar.hxx>
33cdf0e10cSrcweir #include <basic/sbx.hxx>
34cdf0e10cSrcweir #include <svl/zforlist.hxx>
35cdf0e10cSrcweir #include <tools/urlobj.hxx>
36cdf0e10cSrcweir #include <rtl/logfile.hxx>
37cdf0e10cSrcweir #include <stdlib.h>
38cdf0e10cSrcweir #include <string.h>
39cdf0e10cSrcweir #include <signal.h>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include <com/sun/star/table/XCellRange.hpp>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include "interpre.hxx"
44cdf0e10cSrcweir #include "global.hxx"
45cdf0e10cSrcweir #include "dbcolect.hxx"
46cdf0e10cSrcweir #include "cell.hxx"
47cdf0e10cSrcweir #include "callform.hxx"
48cdf0e10cSrcweir #include "addincol.hxx"
49cdf0e10cSrcweir #include "document.hxx"
50cdf0e10cSrcweir #include "dociter.hxx"
51cdf0e10cSrcweir #include "docoptio.hxx"
52cdf0e10cSrcweir #include "scmatrix.hxx"
53cdf0e10cSrcweir #include "adiasync.hxx"
54cdf0e10cSrcweir #include "sc.hrc"
55cdf0e10cSrcweir #include "cellsuno.hxx"
56cdf0e10cSrcweir #include "optuno.hxx"
57cdf0e10cSrcweir #include "rangeseq.hxx"
58cdf0e10cSrcweir #include "addinlis.hxx"
59cdf0e10cSrcweir #include "jumpmatrix.hxx"
60cdf0e10cSrcweir #include "parclass.hxx"
61cdf0e10cSrcweir #include "externalrefmgr.hxx"
62cdf0e10cSrcweir #include "doubleref.hxx"
6361e64f4aSWang Lei #include "token.hxx"
64cdf0e10cSrcweir 
65cdf0e10cSrcweir #include <math.h>
66cdf0e10cSrcweir #include <float.h>
67cdf0e10cSrcweir #include <map>
68cdf0e10cSrcweir #include <algorithm>
69cdf0e10cSrcweir #include <functional>
70cdf0e10cSrcweir #include <memory>
71cdf0e10cSrcweir 
72cdf0e10cSrcweir using namespace com::sun::star;
73cdf0e10cSrcweir using namespace formula;
74cdf0e10cSrcweir using ::std::auto_ptr;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir #define ADDIN_MAXSTRLEN 256
77cdf0e10cSrcweir 
78cdf0e10cSrcweir //-----------------------------static data -----------------
79cdf0e10cSrcweir 
80cdf0e10cSrcweir //-------------------------------------------------------------------------
81cdf0e10cSrcweir // Funktionen fuer den Zugriff auf das Document
82cdf0e10cSrcweir //-------------------------------------------------------------------------
83cdf0e10cSrcweir 
84cdf0e10cSrcweir 
ReplaceCell(ScAddress & rPos)85cdf0e10cSrcweir void ScInterpreter::ReplaceCell( ScAddress& rPos )
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ReplaceCell" );
88cdf0e10cSrcweir     ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First();
89cdf0e10cSrcweir     while (pTOp)
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         if ( rPos == pTOp->aOld1 )
92cdf0e10cSrcweir         {
93cdf0e10cSrcweir             rPos = pTOp->aNew1;
94cdf0e10cSrcweir             return ;
95cdf0e10cSrcweir         }
96cdf0e10cSrcweir         else if ( rPos == pTOp->aOld2 )
97cdf0e10cSrcweir         {
98cdf0e10cSrcweir             rPos = pTOp->aNew2;
99cdf0e10cSrcweir             return ;
100cdf0e10cSrcweir         }
101cdf0e10cSrcweir         else
102cdf0e10cSrcweir             pTOp = pDok->aTableOpList.Next();
103cdf0e10cSrcweir     }
104cdf0e10cSrcweir }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 
ReplaceCell(SCCOL & rCol,SCROW & rRow,SCTAB & rTab)107cdf0e10cSrcweir void ScInterpreter::ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ReplaceCell" );
110cdf0e10cSrcweir     ScAddress aCellPos( rCol, rRow, rTab );
111cdf0e10cSrcweir     ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First();
112cdf0e10cSrcweir     while (pTOp)
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         if ( aCellPos == pTOp->aOld1 )
115cdf0e10cSrcweir         {
116cdf0e10cSrcweir             rCol = pTOp->aNew1.Col();
117cdf0e10cSrcweir             rRow = pTOp->aNew1.Row();
118cdf0e10cSrcweir             rTab = pTOp->aNew1.Tab();
119cdf0e10cSrcweir             return ;
120cdf0e10cSrcweir         }
121cdf0e10cSrcweir         else if ( aCellPos == pTOp->aOld2 )
122cdf0e10cSrcweir         {
123cdf0e10cSrcweir             rCol = pTOp->aNew2.Col();
124cdf0e10cSrcweir             rRow = pTOp->aNew2.Row();
125cdf0e10cSrcweir             rTab = pTOp->aNew2.Tab();
126cdf0e10cSrcweir             return ;
127cdf0e10cSrcweir         }
128cdf0e10cSrcweir         else
129cdf0e10cSrcweir             pTOp = pDok->aTableOpList.Next();
130cdf0e10cSrcweir     }
131cdf0e10cSrcweir }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 
IsTableOpInRange(const ScRange & rRange)134cdf0e10cSrcweir sal_Bool ScInterpreter::IsTableOpInRange( const ScRange& rRange )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsTableOpInRange" );
137cdf0e10cSrcweir     if ( rRange.aStart == rRange.aEnd )
138cdf0e10cSrcweir         return sal_False;   // not considered to be a range in TableOp sense
139cdf0e10cSrcweir 
140cdf0e10cSrcweir     // we can't replace a single cell in a range
141cdf0e10cSrcweir     ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First();
142cdf0e10cSrcweir     while (pTOp)
143cdf0e10cSrcweir     {
144cdf0e10cSrcweir         if ( rRange.In( pTOp->aOld1 ) )
145cdf0e10cSrcweir             return sal_True;
146cdf0e10cSrcweir         if ( rRange.In( pTOp->aOld2 ) )
147cdf0e10cSrcweir             return sal_True;
148cdf0e10cSrcweir         pTOp = pDok->aTableOpList.Next();
149cdf0e10cSrcweir     }
150cdf0e10cSrcweir     return sal_False;
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 
GetCellNumberFormat(const ScAddress & rPos,const ScBaseCell * pCell)154cdf0e10cSrcweir sal_uLong ScInterpreter::GetCellNumberFormat( const ScAddress& rPos, const ScBaseCell* pCell)
155cdf0e10cSrcweir {
156cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellNumberFormat" );
157cdf0e10cSrcweir     sal_uLong nFormat;
158cdf0e10cSrcweir     sal_uInt16 nErr;
159cdf0e10cSrcweir     if ( pCell )
160cdf0e10cSrcweir     {
161cdf0e10cSrcweir         if ( pCell->GetCellType() == CELLTYPE_FORMULA )
162cdf0e10cSrcweir             nErr = ((ScFormulaCell*)pCell)->GetErrCode();
163cdf0e10cSrcweir         else
164cdf0e10cSrcweir             nErr = 0;
165cdf0e10cSrcweir         nFormat = pDok->GetNumberFormat( rPos );
166cdf0e10cSrcweir         if ( pCell->GetCellType() == CELLTYPE_FORMULA
167cdf0e10cSrcweir           && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) )
168cdf0e10cSrcweir             nFormat = ((ScFormulaCell*)pCell)->GetStandardFormat( *pFormatter,
169cdf0e10cSrcweir                 nFormat );
170cdf0e10cSrcweir     }
171cdf0e10cSrcweir     else
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         nFormat = pDok->GetNumberFormat( rPos );
174cdf0e10cSrcweir         nErr = 0;
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir     SetError(nErr);
177cdf0e10cSrcweir     return nFormat;
178cdf0e10cSrcweir }
179cdf0e10cSrcweir 
180cdf0e10cSrcweir 
181cdf0e10cSrcweir /// Only ValueCell, formula cells already store the result rounded.
GetValueCellValue(const ScAddress & rPos,const ScValueCell * pCell)182cdf0e10cSrcweir double ScInterpreter::GetValueCellValue( const ScAddress& rPos, const ScValueCell* pCell )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetValueCellValue" );
185cdf0e10cSrcweir     double fVal = pCell->GetValue();
186cdf0e10cSrcweir     if ( bCalcAsShown && fVal != 0.0 )
187cdf0e10cSrcweir     {
188cdf0e10cSrcweir         sal_uLong nFormat = pDok->GetNumberFormat( rPos );
189cdf0e10cSrcweir         fVal = pDok->RoundValueAsShown( fVal, nFormat );
190cdf0e10cSrcweir     }
191cdf0e10cSrcweir     return fVal;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 
195cdf0e10cSrcweir /** Convert string content to numeric value.
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     Converted are only integer numbers including exponent, and ISO 8601 dates
198cdf0e10cSrcweir     and times in their extended formats with separators. Anything else,
199cdf0e10cSrcweir     especially fractional numeric values with decimal separators or dates other
200cdf0e10cSrcweir     than ISO 8601 would be locale dependent and is a no-no. Leading and
201cdf0e10cSrcweir     trailing blanks are ignored.
202cdf0e10cSrcweir 
203cdf0e10cSrcweir     The following ISO 8601 formats are converted:
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     CCYY-MM-DD
206cdf0e10cSrcweir     CCYY-MM-DDThh:mm
207cdf0e10cSrcweir     CCYY-MM-DDThh:mm:ss
208cdf0e10cSrcweir     CCYY-MM-DDThh:mm:ss,s
209cdf0e10cSrcweir     CCYY-MM-DDThh:mm:ss.s
210cdf0e10cSrcweir     hh:mm
211cdf0e10cSrcweir     hh:mm:ss
212cdf0e10cSrcweir     hh:mm:ss,s
213cdf0e10cSrcweir     hh:mm:ss.s
214cdf0e10cSrcweir 
215cdf0e10cSrcweir     The century CC may not be omitted and the two-digit year setting is not
216cdf0e10cSrcweir     taken into account. Instead of the T date and time separator exactly one
217cdf0e10cSrcweir     blank may be used.
218cdf0e10cSrcweir 
219cdf0e10cSrcweir     If a date is given, it must be a valid Gregorian calendar date. In this
220cdf0e10cSrcweir     case the optional time must be in the range 00:00 to 23:59:59.99999...
221cdf0e10cSrcweir     If only time is given, it may have any value for hours, taking elapsed time
222cdf0e10cSrcweir     into account; minutes and seconds are limited to the value 59 as well.
223cdf0e10cSrcweir  */
224cdf0e10cSrcweir 
ConvertStringToValue(const String & rStr)225cdf0e10cSrcweir double ScInterpreter::ConvertStringToValue( const String& rStr )
226cdf0e10cSrcweir {
227cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ConvertStringToValue" );
228cdf0e10cSrcweir     double fValue = 0.0;
229cdf0e10cSrcweir     if (mnStringNoValueError == errCellNoValue)
230cdf0e10cSrcweir     {
231cdf0e10cSrcweir         // Requested that all strings result in 0, error handled by caller.
232cdf0e10cSrcweir         SetError( mnStringNoValueError);
233cdf0e10cSrcweir         return fValue;
234cdf0e10cSrcweir     }
235cdf0e10cSrcweir     ::rtl::OUString aStr( rStr);
236cdf0e10cSrcweir     rtl_math_ConversionStatus eStatus;
237cdf0e10cSrcweir     sal_Int32 nParseEnd;
238cdf0e10cSrcweir     // Decimal and group separator 0 => only integer and possibly exponent,
239cdf0e10cSrcweir     // stops at first non-digit non-sign.
240cdf0e10cSrcweir     fValue = ::rtl::math::stringToDouble( aStr, 0, 0, &eStatus, &nParseEnd);
241cdf0e10cSrcweir     sal_Int32 nLen;
242cdf0e10cSrcweir     if (eStatus == rtl_math_ConversionStatus_Ok && nParseEnd < (nLen = aStr.getLength()))
243cdf0e10cSrcweir     {
244cdf0e10cSrcweir         // Not at string end, check for trailing blanks or switch to date or
245cdf0e10cSrcweir         // time parsing or bail out.
246cdf0e10cSrcweir         const sal_Unicode* const pStart = aStr.getStr();
247cdf0e10cSrcweir         const sal_Unicode* p = pStart + nParseEnd;
248cdf0e10cSrcweir         const sal_Unicode* const pStop = pStart + nLen;
249cdf0e10cSrcweir         switch (*p++)
250cdf0e10cSrcweir         {
251cdf0e10cSrcweir             case ' ':
252cdf0e10cSrcweir                 while (p < pStop && *p == ' ')
253cdf0e10cSrcweir                     ++p;
254cdf0e10cSrcweir                 if (p < pStop)
255cdf0e10cSrcweir                     SetError( mnStringNoValueError);
256cdf0e10cSrcweir                 break;
257cdf0e10cSrcweir             case '-':
258cdf0e10cSrcweir             case ':':
259cdf0e10cSrcweir                 {
260cdf0e10cSrcweir                     bool bDate = (*(p-1) == '-');
261cdf0e10cSrcweir                     enum State { year = 0, month, day, hour, minute, second, fraction, done, blank, stop };
262cdf0e10cSrcweir                     sal_Int32 nUnit[done] = {0,0,0,0,0,0,0};
263cdf0e10cSrcweir                     const sal_Int32 nLimit[done] = {0,12,31,0,59,59,0};
264cdf0e10cSrcweir                     State eState = (bDate ? month : minute);
265cdf0e10cSrcweir                     nCurFmtType = (bDate ? NUMBERFORMAT_DATE : NUMBERFORMAT_TIME);
266cdf0e10cSrcweir                     nUnit[eState-1] = aStr.copy( 0, nParseEnd).toInt32();
267cdf0e10cSrcweir                     const sal_Unicode* pLastStart = p;
268cdf0e10cSrcweir                     // Ensure there's no preceding sign. Negative dates
269cdf0e10cSrcweir                     // currently aren't handled correctly. Also discard
270cdf0e10cSrcweir                     // +CCYY-MM-DD
271cdf0e10cSrcweir                     p = pStart;
272cdf0e10cSrcweir                     while (p < pStop && *p == ' ')
273cdf0e10cSrcweir                         ++p;
274cdf0e10cSrcweir                     if (p < pStop && !CharClass::isAsciiDigit(*p))
275cdf0e10cSrcweir                         SetError( mnStringNoValueError);
276cdf0e10cSrcweir                     p = pLastStart;
277cdf0e10cSrcweir                     while (p < pStop && !nGlobalError && eState < blank)
278cdf0e10cSrcweir                     {
279cdf0e10cSrcweir                         if (eState == minute)
280cdf0e10cSrcweir                             nCurFmtType |= NUMBERFORMAT_TIME;
281cdf0e10cSrcweir                         if (CharClass::isAsciiDigit(*p))
282cdf0e10cSrcweir                         {
283cdf0e10cSrcweir                             // Maximum 2 digits per unit, except fractions.
284cdf0e10cSrcweir                             if (p - pLastStart >= 2 && eState != fraction)
285cdf0e10cSrcweir                                 SetError( mnStringNoValueError);
286cdf0e10cSrcweir                         }
287cdf0e10cSrcweir                         else if (p > pLastStart)
288cdf0e10cSrcweir                         {
289cdf0e10cSrcweir                             // We had at least one digit.
290cdf0e10cSrcweir                             if (eState < done)
291cdf0e10cSrcweir                             {
292cdf0e10cSrcweir                                 nUnit[eState] = aStr.copy( pLastStart - pStart, p - pLastStart).toInt32();
293cdf0e10cSrcweir                                 if (nLimit[eState] && nLimit[eState] < nUnit[eState])
294cdf0e10cSrcweir                                     SetError( mnStringNoValueError);
295cdf0e10cSrcweir                             }
296cdf0e10cSrcweir                             pLastStart = p + 1;     // hypothetical next start
297cdf0e10cSrcweir                             // Delimiters must match, a trailing delimiter
298cdf0e10cSrcweir                             // yields an invalid date/time.
299cdf0e10cSrcweir                             switch (eState)
300cdf0e10cSrcweir                             {
301cdf0e10cSrcweir                                 case month:
302cdf0e10cSrcweir                                     // Month must be followed by separator and
303cdf0e10cSrcweir                                     // day, no trailing blanks.
304cdf0e10cSrcweir                                     if (*p != '-' || (p+1 == pStop))
305cdf0e10cSrcweir                                         SetError( mnStringNoValueError);
306cdf0e10cSrcweir                                     break;
307cdf0e10cSrcweir                                 case day:
308cdf0e10cSrcweir                                     if ((*p != 'T' || (p+1 == pStop)) && *p != ' ')
309cdf0e10cSrcweir                                         SetError( mnStringNoValueError);
310cdf0e10cSrcweir                                     // Take one blank as a valid delimiter
311cdf0e10cSrcweir                                     // between date and time.
312cdf0e10cSrcweir                                     break;
313cdf0e10cSrcweir                                 case hour:
314cdf0e10cSrcweir                                     // Hour must be followed by separator and
315cdf0e10cSrcweir                                     // minute, no trailing blanks.
316cdf0e10cSrcweir                                     if (*p != ':' || (p+1 == pStop))
317cdf0e10cSrcweir                                         SetError( mnStringNoValueError);
318cdf0e10cSrcweir                                     break;
319cdf0e10cSrcweir                                 case minute:
320cdf0e10cSrcweir                                     if ((*p != ':' || (p+1 == pStop)) && *p != ' ')
321cdf0e10cSrcweir                                         SetError( mnStringNoValueError);
322cdf0e10cSrcweir                                     if (*p == ' ')
323cdf0e10cSrcweir                                         eState = done;
324cdf0e10cSrcweir                                     break;
325cdf0e10cSrcweir                                 case second:
326cdf0e10cSrcweir                                     if (((*p != ',' && *p != '.') || (p+1 == pStop)) && *p != ' ')
327cdf0e10cSrcweir                                         SetError( mnStringNoValueError);
328cdf0e10cSrcweir                                     if (*p == ' ')
329cdf0e10cSrcweir                                         eState = done;
330cdf0e10cSrcweir                                     break;
331cdf0e10cSrcweir                                 case fraction:
332cdf0e10cSrcweir                                     eState = done;
333cdf0e10cSrcweir                                     break;
334cdf0e10cSrcweir                                 case year:
335cdf0e10cSrcweir                                 case done:
336cdf0e10cSrcweir                                 case blank:
337cdf0e10cSrcweir                                 case stop:
338cdf0e10cSrcweir                                     SetError( mnStringNoValueError);
339cdf0e10cSrcweir                                     break;
340cdf0e10cSrcweir                             }
341cdf0e10cSrcweir                             eState = static_cast<State>(eState + 1);
342cdf0e10cSrcweir                         }
343cdf0e10cSrcweir                         else
344cdf0e10cSrcweir                             SetError( mnStringNoValueError);
345cdf0e10cSrcweir                         ++p;
346cdf0e10cSrcweir                     }
347cdf0e10cSrcweir                     if (eState == blank)
348cdf0e10cSrcweir                     {
349cdf0e10cSrcweir                         while (p < pStop && *p == ' ')
350cdf0e10cSrcweir                             ++p;
351cdf0e10cSrcweir                         if (p < pStop)
352cdf0e10cSrcweir                             SetError( mnStringNoValueError);
353cdf0e10cSrcweir                         eState = stop;
354cdf0e10cSrcweir                     }
355cdf0e10cSrcweir 
356cdf0e10cSrcweir                     // Month without day, or hour without minute.
357cdf0e10cSrcweir                     if (eState == month || (eState == day && p <= pLastStart) ||
358cdf0e10cSrcweir                             eState == hour || (eState == minute && p <= pLastStart))
359cdf0e10cSrcweir                         SetError( mnStringNoValueError);
360cdf0e10cSrcweir 
361cdf0e10cSrcweir                     if (!nGlobalError)
362cdf0e10cSrcweir                     {
363cdf0e10cSrcweir                         // Catch the very last unit at end of string.
364cdf0e10cSrcweir                         if (p > pLastStart && eState < done)
365cdf0e10cSrcweir                         {
366cdf0e10cSrcweir                             nUnit[eState] = aStr.copy( pLastStart - pStart, p - pLastStart).toInt32();
367cdf0e10cSrcweir                             if (nLimit[eState] && nLimit[eState] < nUnit[eState])
368cdf0e10cSrcweir                                 SetError( mnStringNoValueError);
369cdf0e10cSrcweir                         }
370cdf0e10cSrcweir                         if (bDate && nUnit[hour] > 23)
371cdf0e10cSrcweir                             SetError( mnStringNoValueError);
372cdf0e10cSrcweir                         if (!nGlobalError)
373cdf0e10cSrcweir                         {
374cdf0e10cSrcweir                             if (bDate && nUnit[day] == 0)
375cdf0e10cSrcweir                                 nUnit[day] = 1;
376cdf0e10cSrcweir                             double fFraction = (nUnit[fraction] <= 0 ? 0.0 :
377cdf0e10cSrcweir                                     ::rtl::math::pow10Exp( nUnit[fraction],
378cdf0e10cSrcweir                                         static_cast<int>( -ceil( log10( static_cast<double>( nUnit[fraction]))))));
379cdf0e10cSrcweir                             fValue = (bDate ? GetDateSerial(
380cdf0e10cSrcweir                                         sal::static_int_cast<sal_Int16>(nUnit[year]),
381cdf0e10cSrcweir                                         sal::static_int_cast<sal_Int16>(nUnit[month]),
382cdf0e10cSrcweir                                         sal::static_int_cast<sal_Int16>(nUnit[day]),
383cdf0e10cSrcweir                                         true) : 0.0);
384cdf0e10cSrcweir                             fValue += ((nUnit[hour] * 3600) + (nUnit[minute] * 60) + nUnit[second] + fFraction) / 86400.0;
385cdf0e10cSrcweir                         }
386cdf0e10cSrcweir                     }
387cdf0e10cSrcweir                 }
388cdf0e10cSrcweir                 break;
389cdf0e10cSrcweir             default:
390cdf0e10cSrcweir                 SetError( mnStringNoValueError);
391cdf0e10cSrcweir         }
392cdf0e10cSrcweir         if (nGlobalError)
393cdf0e10cSrcweir             fValue = 0.0;
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir     return fValue;
396cdf0e10cSrcweir }
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 
GetCellValue(const ScAddress & rPos,const ScBaseCell * pCell)399cdf0e10cSrcweir double ScInterpreter::GetCellValue( const ScAddress& rPos, const ScBaseCell* pCell )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellValue" );
402cdf0e10cSrcweir     sal_uInt16 nErr = nGlobalError;
403cdf0e10cSrcweir     nGlobalError = 0;
404cdf0e10cSrcweir     double nVal = GetCellValueOrZero( rPos, pCell );
405cdf0e10cSrcweir     if ( !nGlobalError || nGlobalError == errCellNoValue )
406cdf0e10cSrcweir         nGlobalError = nErr;
407cdf0e10cSrcweir     return nVal;
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 
GetCellValueOrZero(const ScAddress & rPos,const ScBaseCell * pCell)411cdf0e10cSrcweir double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCell* pCell )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellValueOrZero" );
414cdf0e10cSrcweir     double fValue = 0.0;
415cdf0e10cSrcweir     if (pCell)
416cdf0e10cSrcweir     {
417cdf0e10cSrcweir         CellType eType = pCell->GetCellType();
418cdf0e10cSrcweir         switch ( eType )
419cdf0e10cSrcweir         {
420cdf0e10cSrcweir             case CELLTYPE_FORMULA:
421cdf0e10cSrcweir             {
422cdf0e10cSrcweir                 ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
423cdf0e10cSrcweir                 sal_uInt16 nErr = pFCell->GetErrCode();
424cdf0e10cSrcweir                 if( !nErr )
425cdf0e10cSrcweir                 {
426cdf0e10cSrcweir                     if (pFCell->IsValue())
427cdf0e10cSrcweir                     {
428cdf0e10cSrcweir                         fValue = pFCell->GetValue();
429cdf0e10cSrcweir                         pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex,
430cdf0e10cSrcweir                             rPos, pFCell );
431cdf0e10cSrcweir                     }
432cdf0e10cSrcweir                     else
433cdf0e10cSrcweir                     {
434cdf0e10cSrcweir                         String aStr;
435cdf0e10cSrcweir                         pFCell->GetString( aStr );
436cdf0e10cSrcweir                         fValue = ConvertStringToValue( aStr );
437cdf0e10cSrcweir                     }
438cdf0e10cSrcweir                 }
439cdf0e10cSrcweir                 else
440cdf0e10cSrcweir                 {
441cdf0e10cSrcweir                     fValue = 0.0;
442cdf0e10cSrcweir                     SetError(nErr);
443cdf0e10cSrcweir                 }
444cdf0e10cSrcweir             }
445cdf0e10cSrcweir             break;
446cdf0e10cSrcweir             case CELLTYPE_VALUE:
447cdf0e10cSrcweir             {
448cdf0e10cSrcweir                 fValue = ((ScValueCell*)pCell)->GetValue();
449cdf0e10cSrcweir                 nCurFmtIndex = pDok->GetNumberFormat( rPos );
450cdf0e10cSrcweir                 nCurFmtType = pFormatter->GetType( nCurFmtIndex );
451cdf0e10cSrcweir                 if ( bCalcAsShown && fValue != 0.0 )
452cdf0e10cSrcweir                     fValue = pDok->RoundValueAsShown( fValue, nCurFmtIndex );
453cdf0e10cSrcweir             }
454cdf0e10cSrcweir             break;
455cdf0e10cSrcweir             case  CELLTYPE_STRING:
456cdf0e10cSrcweir             case  CELLTYPE_EDIT:
457cdf0e10cSrcweir             {
458cdf0e10cSrcweir                 // SUM(A1:A2) differs from A1+A2. No good. But people insist on
459cdf0e10cSrcweir                 // it ... #i5658#
460cdf0e10cSrcweir                 String aStr;
461cdf0e10cSrcweir                 if ( eType == CELLTYPE_STRING )
462cdf0e10cSrcweir                     ((ScStringCell*)pCell)->GetString( aStr );
463cdf0e10cSrcweir                 else
464cdf0e10cSrcweir                     ((ScEditCell*)pCell)->GetString( aStr );
465cdf0e10cSrcweir                 fValue = ConvertStringToValue( aStr );
466cdf0e10cSrcweir             }
467cdf0e10cSrcweir             break;
468cdf0e10cSrcweir             case CELLTYPE_NONE:
469cdf0e10cSrcweir             case CELLTYPE_NOTE:
470cdf0e10cSrcweir                 fValue = 0.0;       // empty or broadcaster cell
471cdf0e10cSrcweir             break;
472cdf0e10cSrcweir             case CELLTYPE_SYMBOLS:
473cdf0e10cSrcweir #if DBG_UTIL
474cdf0e10cSrcweir             case CELLTYPE_DESTROYED:
475cdf0e10cSrcweir #endif
476cdf0e10cSrcweir                 SetError(errCellNoValue);
477cdf0e10cSrcweir                 fValue = 0.0;
478cdf0e10cSrcweir             break;
479cdf0e10cSrcweir         }
480cdf0e10cSrcweir     }
481cdf0e10cSrcweir     else
482cdf0e10cSrcweir         fValue = 0.0;
483cdf0e10cSrcweir     return fValue;
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 
GetCellString(String & rStr,const ScBaseCell * pCell)487cdf0e10cSrcweir void ScInterpreter::GetCellString( String& rStr, const ScBaseCell* pCell )
488cdf0e10cSrcweir {
489cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellString" );
490cdf0e10cSrcweir     sal_uInt16 nErr = 0;
491cdf0e10cSrcweir     if (pCell)
492cdf0e10cSrcweir     {
493cdf0e10cSrcweir         switch (pCell->GetCellType())
494cdf0e10cSrcweir         {
495cdf0e10cSrcweir             case CELLTYPE_STRING:
496cdf0e10cSrcweir                 ((ScStringCell*) pCell)->GetString(rStr);
497cdf0e10cSrcweir             break;
498cdf0e10cSrcweir             case CELLTYPE_EDIT:
499cdf0e10cSrcweir                 ((ScEditCell*) pCell)->GetString(rStr);
500cdf0e10cSrcweir             break;
501cdf0e10cSrcweir             case CELLTYPE_FORMULA:
502cdf0e10cSrcweir             {
503cdf0e10cSrcweir                 ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
504cdf0e10cSrcweir                 nErr = pFCell->GetErrCode();
505cdf0e10cSrcweir                 if (pFCell->IsValue())
506cdf0e10cSrcweir                 {
507cdf0e10cSrcweir                     double fVal = pFCell->GetValue();
508cdf0e10cSrcweir                     sal_uLong nIndex = pFormatter->GetStandardFormat(
509cdf0e10cSrcweir                                         NUMBERFORMAT_NUMBER,
510cdf0e10cSrcweir                                         ScGlobal::eLnge);
511cdf0e10cSrcweir                     pFormatter->GetInputLineString(fVal, nIndex, rStr);
512cdf0e10cSrcweir                 }
513cdf0e10cSrcweir                 else
514cdf0e10cSrcweir                     pFCell->GetString(rStr);
515cdf0e10cSrcweir             }
516cdf0e10cSrcweir             break;
517cdf0e10cSrcweir             case CELLTYPE_VALUE:
518cdf0e10cSrcweir             {
519cdf0e10cSrcweir                 double fVal = ((ScValueCell*) pCell)->GetValue();
520cdf0e10cSrcweir                 sal_uLong nIndex = pFormatter->GetStandardFormat(
521cdf0e10cSrcweir                                         NUMBERFORMAT_NUMBER,
522cdf0e10cSrcweir                                         ScGlobal::eLnge);
523cdf0e10cSrcweir                 pFormatter->GetInputLineString(fVal, nIndex, rStr);
524cdf0e10cSrcweir             }
525cdf0e10cSrcweir             break;
526cdf0e10cSrcweir             default:
527cdf0e10cSrcweir                 rStr = ScGlobal::GetEmptyString();
528cdf0e10cSrcweir             break;
529cdf0e10cSrcweir         }
530cdf0e10cSrcweir     }
531cdf0e10cSrcweir     else
532cdf0e10cSrcweir         rStr = ScGlobal::GetEmptyString();
533cdf0e10cSrcweir     SetError(nErr);
534cdf0e10cSrcweir }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir 
CreateDoubleArr(SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2,sal_uInt8 * pCellArr)537cdf0e10cSrcweir sal_Bool ScInterpreter::CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
538cdf0e10cSrcweir                             SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr)
539cdf0e10cSrcweir {
540cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateDoubleArr" );
541cdf0e10cSrcweir 
542cdf0e10cSrcweir     // Old Add-Ins are hard limited to sal_uInt16 values.
543cdf0e10cSrcweir #if MAXCOLCOUNT_DEFINE > USHRT_MAX
544cdf0e10cSrcweir #error Add check for columns > USHRT_MAX!
545cdf0e10cSrcweir #endif
546cdf0e10cSrcweir     if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
547cdf0e10cSrcweir         return sal_False;
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     sal_uInt16 nCount = 0;
550cdf0e10cSrcweir     sal_uInt16* p = (sal_uInt16*) pCellArr;
551cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nCol1);
552cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nRow1);
553cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nTab1);
554cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nCol2);
555cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nRow2);
556cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nTab2);
557cdf0e10cSrcweir     sal_uInt16* pCount = p;
558cdf0e10cSrcweir     *p++ = 0;
559cdf0e10cSrcweir     sal_uInt16 nPos = 14;
560cdf0e10cSrcweir     SCTAB nTab = nTab1;
561cdf0e10cSrcweir     ScAddress aAdr;
562cdf0e10cSrcweir     while (nTab <= nTab2)
563cdf0e10cSrcweir     {
564cdf0e10cSrcweir         aAdr.SetTab( nTab );
565cdf0e10cSrcweir         SCROW nRow = nRow1;
566cdf0e10cSrcweir         while (nRow <= nRow2)
567cdf0e10cSrcweir         {
568cdf0e10cSrcweir             aAdr.SetRow( nRow );
569cdf0e10cSrcweir             SCCOL nCol = nCol1;
570cdf0e10cSrcweir             while (nCol <= nCol2)
571cdf0e10cSrcweir             {
572cdf0e10cSrcweir                 aAdr.SetCol( nCol );
573cdf0e10cSrcweir                 ScBaseCell* pCell = pDok->GetCell( aAdr );
574cdf0e10cSrcweir                 if (pCell)
575cdf0e10cSrcweir                 {
576cdf0e10cSrcweir                     sal_uInt16  nErr = 0;
577cdf0e10cSrcweir                     double  nVal = 0.0;
578cdf0e10cSrcweir                     sal_Bool    bOk = sal_True;
579cdf0e10cSrcweir                     switch ( pCell->GetCellType() )
580cdf0e10cSrcweir                     {
581cdf0e10cSrcweir                         case CELLTYPE_VALUE :
582cdf0e10cSrcweir                             nVal = GetValueCellValue( aAdr, (ScValueCell*)pCell );
583cdf0e10cSrcweir                             break;
584cdf0e10cSrcweir                         case CELLTYPE_FORMULA :
585cdf0e10cSrcweir                             if (((ScFormulaCell*)pCell)->IsValue())
586cdf0e10cSrcweir                             {
587cdf0e10cSrcweir                                 nErr = ((ScFormulaCell*)pCell)->GetErrCode();
588cdf0e10cSrcweir                                 nVal = ((ScFormulaCell*)pCell)->GetValue();
589cdf0e10cSrcweir                             }
590cdf0e10cSrcweir                             else
591cdf0e10cSrcweir                                 bOk = sal_False;
592cdf0e10cSrcweir                             break;
593cdf0e10cSrcweir                         default :
594cdf0e10cSrcweir                             bOk = sal_False;
595cdf0e10cSrcweir                             break;
596cdf0e10cSrcweir                     }
597cdf0e10cSrcweir                     if (bOk)
598cdf0e10cSrcweir                     {
599cdf0e10cSrcweir                         if ((nPos + (4 * sizeof(sal_uInt16)) + sizeof(double)) > MAXARRSIZE)
600cdf0e10cSrcweir                             return sal_False;
601cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nCol);
602cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nRow);
603cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nTab);
604cdf0e10cSrcweir                         *p++ = nErr;
605cdf0e10cSrcweir                         memcpy( p, &nVal, sizeof(double));
606cdf0e10cSrcweir                         nPos += 8 + sizeof(double);
607cdf0e10cSrcweir                         p = (sal_uInt16*) ( pCellArr + nPos );
608cdf0e10cSrcweir                         nCount++;
609cdf0e10cSrcweir                     }
610cdf0e10cSrcweir                 }
611cdf0e10cSrcweir                 nCol++;
612cdf0e10cSrcweir             }
613cdf0e10cSrcweir             nRow++;
614cdf0e10cSrcweir         }
615cdf0e10cSrcweir         nTab++;
616cdf0e10cSrcweir     }
617cdf0e10cSrcweir     *pCount = nCount;
618cdf0e10cSrcweir     return sal_True;
619cdf0e10cSrcweir }
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 
CreateStringArr(SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2,sal_uInt8 * pCellArr)622cdf0e10cSrcweir sal_Bool ScInterpreter::CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
623cdf0e10cSrcweir                                     SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
624cdf0e10cSrcweir                                     sal_uInt8* pCellArr)
625cdf0e10cSrcweir {
626cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateStringArr" );
627cdf0e10cSrcweir 
628cdf0e10cSrcweir     // Old Add-Ins are hard limited to sal_uInt16 values.
629cdf0e10cSrcweir #if MAXCOLCOUNT_DEFINE > USHRT_MAX
630cdf0e10cSrcweir #error Add check for columns > USHRT_MAX!
631cdf0e10cSrcweir #endif
632cdf0e10cSrcweir     if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
633cdf0e10cSrcweir         return sal_False;
634cdf0e10cSrcweir 
635cdf0e10cSrcweir     sal_uInt16 nCount = 0;
636cdf0e10cSrcweir     sal_uInt16* p = (sal_uInt16*) pCellArr;
637cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nCol1);
638cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nRow1);
639cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nTab1);
640cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nCol2);
641cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nRow2);
642cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nTab2);
643cdf0e10cSrcweir     sal_uInt16* pCount = p;
644cdf0e10cSrcweir     *p++ = 0;
645cdf0e10cSrcweir     sal_uInt16 nPos = 14;
646cdf0e10cSrcweir     SCTAB nTab = nTab1;
647cdf0e10cSrcweir     while (nTab <= nTab2)
648cdf0e10cSrcweir     {
649cdf0e10cSrcweir         SCROW nRow = nRow1;
650cdf0e10cSrcweir         while (nRow <= nRow2)
651cdf0e10cSrcweir         {
652cdf0e10cSrcweir             SCCOL nCol = nCol1;
653cdf0e10cSrcweir             while (nCol <= nCol2)
654cdf0e10cSrcweir             {
655cdf0e10cSrcweir                 ScBaseCell* pCell;
656cdf0e10cSrcweir                 pDok->GetCell(nCol, nRow, nTab, pCell);
657cdf0e10cSrcweir                 if (pCell)
658cdf0e10cSrcweir                 {
659cdf0e10cSrcweir                     String  aStr;
660cdf0e10cSrcweir                     sal_uInt16  nErr = 0;
661cdf0e10cSrcweir                     sal_Bool    bOk = sal_True;
662cdf0e10cSrcweir                     switch ( pCell->GetCellType() )
663cdf0e10cSrcweir                     {
664cdf0e10cSrcweir                         case CELLTYPE_STRING :
665cdf0e10cSrcweir                             ((ScStringCell*)pCell)->GetString(aStr);
666cdf0e10cSrcweir                             break;
667cdf0e10cSrcweir                         case CELLTYPE_EDIT :
668cdf0e10cSrcweir                             ((ScEditCell*)pCell)->GetString(aStr);
669cdf0e10cSrcweir                             break;
670cdf0e10cSrcweir                         case CELLTYPE_FORMULA :
671cdf0e10cSrcweir                             if (!((ScFormulaCell*)pCell)->IsValue())
672cdf0e10cSrcweir                             {
673cdf0e10cSrcweir                                 nErr = ((ScFormulaCell*)pCell)->GetErrCode();
674cdf0e10cSrcweir                                 ((ScFormulaCell*)pCell)->GetString(aStr);
675cdf0e10cSrcweir                             }
676cdf0e10cSrcweir                             else
677cdf0e10cSrcweir                                 bOk = sal_False;
678cdf0e10cSrcweir                             break;
679cdf0e10cSrcweir                         default :
680cdf0e10cSrcweir                             bOk = sal_False;
681cdf0e10cSrcweir                             break;
682cdf0e10cSrcweir                     }
683cdf0e10cSrcweir                     if (bOk)
684cdf0e10cSrcweir                     {
685cdf0e10cSrcweir                         ByteString aTmp( aStr, osl_getThreadTextEncoding() );
686cdf0e10cSrcweir                         // In case the xub_StrLen will be longer than USHORT
687cdf0e10cSrcweir                         // one day, and room for pad byte check.
688cdf0e10cSrcweir                         if ( aTmp.Len() > ((sal_uInt16)(~0)) - 2 )
689cdf0e10cSrcweir                             return sal_False;
690cdf0e10cSrcweir                         // Append a 0-pad-byte if string length is not even
691cdf0e10cSrcweir                         //! MUST be sal_uInt16 and not xub_StrLen
692cdf0e10cSrcweir                         sal_uInt16 nStrLen = (sal_uInt16) aTmp.Len();
693cdf0e10cSrcweir                         sal_uInt16 nLen = ( nStrLen + 2 ) & ~1;
694cdf0e10cSrcweir 
695cdf0e10cSrcweir                         if (((sal_uLong)nPos + (5 * sizeof(sal_uInt16)) + nLen) > MAXARRSIZE)
696cdf0e10cSrcweir                             return sal_False;
697cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nCol);
698cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nRow);
699cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nTab);
700cdf0e10cSrcweir                         *p++ = nErr;
701cdf0e10cSrcweir                         *p++ = nLen;
702cdf0e10cSrcweir                         memcpy( p, aTmp.GetBuffer(), nStrLen + 1);
703cdf0e10cSrcweir                         nPos += 10 + nStrLen + 1;
704cdf0e10cSrcweir                         sal_uInt8* q = ( pCellArr + nPos );
705cdf0e10cSrcweir                         if( !nStrLen & 1 )
706cdf0e10cSrcweir                             *q++ = 0, nPos++;
707cdf0e10cSrcweir                         p = (sal_uInt16*) ( pCellArr + nPos );
708cdf0e10cSrcweir                         nCount++;
709cdf0e10cSrcweir                     }
710cdf0e10cSrcweir                 }
711cdf0e10cSrcweir                 nCol++;
712cdf0e10cSrcweir             }
713cdf0e10cSrcweir             nRow++;
714cdf0e10cSrcweir         }
715cdf0e10cSrcweir         nTab++;
716cdf0e10cSrcweir     }
717cdf0e10cSrcweir     *pCount = nCount;
718cdf0e10cSrcweir     return sal_True;
719cdf0e10cSrcweir }
720cdf0e10cSrcweir 
721cdf0e10cSrcweir 
CreateCellArr(SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2,sal_uInt8 * pCellArr)722cdf0e10cSrcweir sal_Bool ScInterpreter::CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
723cdf0e10cSrcweir                                   SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
724cdf0e10cSrcweir                                   sal_uInt8* pCellArr)
725cdf0e10cSrcweir {
726cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateCellArr" );
727cdf0e10cSrcweir 
728cdf0e10cSrcweir     // Old Add-Ins are hard limited to sal_uInt16 values.
729cdf0e10cSrcweir #if MAXCOLCOUNT_DEFINE > USHRT_MAX
730cdf0e10cSrcweir #error Add check for columns > USHRT_MAX!
731cdf0e10cSrcweir #endif
732cdf0e10cSrcweir     if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
733cdf0e10cSrcweir         return sal_False;
734cdf0e10cSrcweir 
735cdf0e10cSrcweir     sal_uInt16 nCount = 0;
736cdf0e10cSrcweir     sal_uInt16* p = (sal_uInt16*) pCellArr;
737cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nCol1);
738cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nRow1);
739cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nTab1);
740cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nCol2);
741cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nRow2);
742cdf0e10cSrcweir     *p++ = static_cast<sal_uInt16>(nTab2);
743cdf0e10cSrcweir     sal_uInt16* pCount = p;
744cdf0e10cSrcweir     *p++ = 0;
745cdf0e10cSrcweir     sal_uInt16 nPos = 14;
746cdf0e10cSrcweir     SCTAB nTab = nTab1;
747cdf0e10cSrcweir     ScAddress aAdr;
748cdf0e10cSrcweir     while (nTab <= nTab2)
749cdf0e10cSrcweir     {
750cdf0e10cSrcweir         aAdr.SetTab( nTab );
751cdf0e10cSrcweir         SCROW nRow = nRow1;
752cdf0e10cSrcweir         while (nRow <= nRow2)
753cdf0e10cSrcweir         {
754cdf0e10cSrcweir             aAdr.SetRow( nRow );
755cdf0e10cSrcweir             SCCOL nCol = nCol1;
756cdf0e10cSrcweir             while (nCol <= nCol2)
757cdf0e10cSrcweir             {
758cdf0e10cSrcweir                 aAdr.SetCol( nCol );
759cdf0e10cSrcweir                 ScBaseCell* pCell = pDok->GetCell( aAdr );
760cdf0e10cSrcweir                 if (pCell)
761cdf0e10cSrcweir                 {
762cdf0e10cSrcweir                     sal_uInt16  nErr = 0;
763cdf0e10cSrcweir                     sal_uInt16  nType = 0; // 0 = Zahl; 1 = String
764cdf0e10cSrcweir                     double  nVal = 0.0;
765cdf0e10cSrcweir                     String  aStr;
766cdf0e10cSrcweir                     sal_Bool    bOk = sal_True;
767cdf0e10cSrcweir                     switch ( pCell->GetCellType() )
768cdf0e10cSrcweir                     {
769cdf0e10cSrcweir                         case CELLTYPE_STRING :
770cdf0e10cSrcweir                             ((ScStringCell*)pCell)->GetString(aStr);
771cdf0e10cSrcweir                             nType = 1;
772cdf0e10cSrcweir                             break;
773cdf0e10cSrcweir                         case CELLTYPE_EDIT :
774cdf0e10cSrcweir                             ((ScEditCell*)pCell)->GetString(aStr);
775cdf0e10cSrcweir                             nType = 1;
776cdf0e10cSrcweir                             break;
777cdf0e10cSrcweir                         case CELLTYPE_VALUE :
778cdf0e10cSrcweir                             nVal = GetValueCellValue( aAdr, (ScValueCell*)pCell );
779cdf0e10cSrcweir                             break;
780cdf0e10cSrcweir                         case CELLTYPE_FORMULA :
781cdf0e10cSrcweir                             nErr = ((ScFormulaCell*)pCell)->GetErrCode();
782cdf0e10cSrcweir                             if (((ScFormulaCell*)pCell)->IsValue())
783cdf0e10cSrcweir                                 nVal = ((ScFormulaCell*)pCell)->GetValue();
784cdf0e10cSrcweir                             else
785cdf0e10cSrcweir                                 ((ScFormulaCell*)pCell)->GetString(aStr);
786cdf0e10cSrcweir                             break;
787cdf0e10cSrcweir                         default :
788cdf0e10cSrcweir                             bOk = sal_False;
789cdf0e10cSrcweir                             break;
790cdf0e10cSrcweir                     }
791cdf0e10cSrcweir                     if (bOk)
792cdf0e10cSrcweir                     {
793cdf0e10cSrcweir                         if ((nPos + (5 * sizeof(sal_uInt16))) > MAXARRSIZE)
794cdf0e10cSrcweir                             return sal_False;
795cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nCol);
796cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nRow);
797cdf0e10cSrcweir                         *p++ = static_cast<sal_uInt16>(nTab);
798cdf0e10cSrcweir                         *p++ = nErr;
799cdf0e10cSrcweir                         *p++ = nType;
800cdf0e10cSrcweir                         nPos += 10;
801cdf0e10cSrcweir                         if (nType == 0)
802cdf0e10cSrcweir                         {
803cdf0e10cSrcweir                             if ((nPos + sizeof(double)) > MAXARRSIZE)
804cdf0e10cSrcweir                                 return sal_False;
805cdf0e10cSrcweir                             memcpy( p, &nVal, sizeof(double));
806cdf0e10cSrcweir                             nPos += sizeof(double);
807cdf0e10cSrcweir                         }
808cdf0e10cSrcweir                         else
809cdf0e10cSrcweir                         {
810cdf0e10cSrcweir                             ByteString aTmp( aStr, osl_getThreadTextEncoding() );
811cdf0e10cSrcweir                             // In case the xub_StrLen will be longer than USHORT
812cdf0e10cSrcweir                             // one day, and room for pad byte check.
813cdf0e10cSrcweir                             if ( aTmp.Len() > ((sal_uInt16)(~0)) - 2 )
814cdf0e10cSrcweir                                 return sal_False;
815cdf0e10cSrcweir                             // Append a 0-pad-byte if string length is not even
816cdf0e10cSrcweir                             //! MUST be sal_uInt16 and not xub_StrLen
817cdf0e10cSrcweir                             sal_uInt16 nStrLen = (sal_uInt16) aTmp.Len();
818cdf0e10cSrcweir                             sal_uInt16 nLen = ( nStrLen + 2 ) & ~1;
819cdf0e10cSrcweir                             if ( ((sal_uLong)nPos + 2 + nLen) > MAXARRSIZE)
820cdf0e10cSrcweir                                 return sal_False;
821cdf0e10cSrcweir                             *p++ = nLen;
822cdf0e10cSrcweir                             memcpy( p, aTmp.GetBuffer(), nStrLen + 1);
823cdf0e10cSrcweir                             nPos += 2 + nStrLen + 1;
824cdf0e10cSrcweir                             sal_uInt8* q = ( pCellArr + nPos );
825cdf0e10cSrcweir                             if( !nStrLen & 1 )
826cdf0e10cSrcweir                                 *q++ = 0, nPos++;
827cdf0e10cSrcweir                         }
828cdf0e10cSrcweir                         nCount++;
829cdf0e10cSrcweir                         p = (sal_uInt16*) ( pCellArr + nPos );
830cdf0e10cSrcweir                     }
831cdf0e10cSrcweir                 }
832cdf0e10cSrcweir                 nCol++;
833cdf0e10cSrcweir             }
834cdf0e10cSrcweir             nRow++;
835cdf0e10cSrcweir         }
836cdf0e10cSrcweir         nTab++;
837cdf0e10cSrcweir     }
838cdf0e10cSrcweir     *pCount = nCount;
839cdf0e10cSrcweir     return sal_True;
840cdf0e10cSrcweir }
841cdf0e10cSrcweir 
842cdf0e10cSrcweir 
843cdf0e10cSrcweir //-----------------------------------------------------------------------------
844cdf0e10cSrcweir // Stack operations
845cdf0e10cSrcweir //-----------------------------------------------------------------------------
846cdf0e10cSrcweir 
847cdf0e10cSrcweir 
848cdf0e10cSrcweir // Also releases a TempToken if appropriate.
849cdf0e10cSrcweir 
PushWithoutError(FormulaToken & r)850cdf0e10cSrcweir void ScInterpreter::PushWithoutError( FormulaToken& r )
851cdf0e10cSrcweir {
852cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushWithoutError" );
853cdf0e10cSrcweir     if ( sp >= MAXSTACK )
854cdf0e10cSrcweir         SetError( errStackOverflow );
855cdf0e10cSrcweir     else
856cdf0e10cSrcweir     {
857cdf0e10cSrcweir         nCurFmtType = NUMBERFORMAT_UNDEFINED;
858cdf0e10cSrcweir         r.IncRef();
859cdf0e10cSrcweir         if( sp >= maxsp )
860cdf0e10cSrcweir             maxsp = sp + 1;
861cdf0e10cSrcweir         else
862cdf0e10cSrcweir             pStack[ sp ]->DecRef();
863cdf0e10cSrcweir         pStack[ sp ] = (ScToken*) &r;
864cdf0e10cSrcweir         ++sp;
865cdf0e10cSrcweir     }
866cdf0e10cSrcweir }
867cdf0e10cSrcweir 
Push(FormulaToken & r)868cdf0e10cSrcweir void ScInterpreter::Push( FormulaToken& r )
869cdf0e10cSrcweir {
870cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Push" );
871cdf0e10cSrcweir     if ( sp >= MAXSTACK )
872cdf0e10cSrcweir         SetError( errStackOverflow );
873cdf0e10cSrcweir     else
874cdf0e10cSrcweir     {
875cdf0e10cSrcweir         if (nGlobalError)
876cdf0e10cSrcweir         {
877cdf0e10cSrcweir             if (r.GetType() == svError)
878cdf0e10cSrcweir             {
879cdf0e10cSrcweir                 r.SetError( nGlobalError);
880cdf0e10cSrcweir                 PushWithoutError( r);
881cdf0e10cSrcweir             }
882cdf0e10cSrcweir             else
883cdf0e10cSrcweir                 PushWithoutError( *(new FormulaErrorToken( nGlobalError)));
884cdf0e10cSrcweir         }
885cdf0e10cSrcweir         else
886cdf0e10cSrcweir             PushWithoutError( r);
887cdf0e10cSrcweir     }
888cdf0e10cSrcweir }
889cdf0e10cSrcweir 
890cdf0e10cSrcweir 
PushTempToken(FormulaToken * p)891cdf0e10cSrcweir void ScInterpreter::PushTempToken( FormulaToken* p )
892cdf0e10cSrcweir {
893cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempToken" );
894cdf0e10cSrcweir     if ( sp >= MAXSTACK )
895cdf0e10cSrcweir     {
896cdf0e10cSrcweir         SetError( errStackOverflow );
897cdf0e10cSrcweir         if (!p->GetRef())
898cdf0e10cSrcweir             //! p is a dangling pointer hereafter!
899cdf0e10cSrcweir             p->Delete();
900cdf0e10cSrcweir     }
901cdf0e10cSrcweir     else
902cdf0e10cSrcweir     {
903cdf0e10cSrcweir         if (nGlobalError)
904cdf0e10cSrcweir         {
905cdf0e10cSrcweir             if (p->GetType() == svError)
906cdf0e10cSrcweir             {
907cdf0e10cSrcweir                 p->SetError( nGlobalError);
908cdf0e10cSrcweir                 PushTempTokenWithoutError( p);
909cdf0e10cSrcweir             }
910cdf0e10cSrcweir             else
911cdf0e10cSrcweir             {
912cdf0e10cSrcweir                 if (!p->GetRef())
913cdf0e10cSrcweir                     //! p is a dangling pointer hereafter!
914cdf0e10cSrcweir                     p->Delete();
915cdf0e10cSrcweir                 PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError));
916cdf0e10cSrcweir             }
917cdf0e10cSrcweir         }
918cdf0e10cSrcweir         else
919cdf0e10cSrcweir             PushTempTokenWithoutError( p);
920cdf0e10cSrcweir     }
921cdf0e10cSrcweir }
922cdf0e10cSrcweir 
923cdf0e10cSrcweir 
PushTempTokenWithoutError(FormulaToken * p)924cdf0e10cSrcweir void ScInterpreter::PushTempTokenWithoutError( FormulaToken* p )
925cdf0e10cSrcweir {
926cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempTokenWithoutError" );
927cdf0e10cSrcweir     p->IncRef();
928cdf0e10cSrcweir     if ( sp >= MAXSTACK )
929cdf0e10cSrcweir     {
930cdf0e10cSrcweir         SetError( errStackOverflow );
931cdf0e10cSrcweir         //! p may be a dangling pointer hereafter!
932cdf0e10cSrcweir         p->DecRef();
933cdf0e10cSrcweir     }
934cdf0e10cSrcweir     else
935cdf0e10cSrcweir     {
936cdf0e10cSrcweir         if( sp >= maxsp )
937cdf0e10cSrcweir             maxsp = sp + 1;
938cdf0e10cSrcweir         else
939cdf0e10cSrcweir             pStack[ sp ]->DecRef();
940cdf0e10cSrcweir         pStack[ sp ] = p;
941cdf0e10cSrcweir         ++sp;
942cdf0e10cSrcweir     }
943cdf0e10cSrcweir }
944cdf0e10cSrcweir 
945cdf0e10cSrcweir 
PushTempToken(const FormulaToken & r)946cdf0e10cSrcweir void ScInterpreter::PushTempToken( const FormulaToken& r )
947cdf0e10cSrcweir {
948cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempToken" );
949cdf0e10cSrcweir     if (!IfErrorPushError())
950cdf0e10cSrcweir         PushTempTokenWithoutError( r.Clone());
951cdf0e10cSrcweir }
952cdf0e10cSrcweir 
953cdf0e10cSrcweir 
PushCellResultToken(bool bDisplayEmptyAsString,const ScAddress & rAddress,short * pRetTypeExpr,sal_uLong * pRetIndexExpr)954cdf0e10cSrcweir void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString,
955cdf0e10cSrcweir         const ScAddress & rAddress, short * pRetTypeExpr, sal_uLong * pRetIndexExpr )
956cdf0e10cSrcweir {
957cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushCellResultToken" );
958cdf0e10cSrcweir     ScBaseCell* pCell = pDok->GetCell( rAddress);
959cdf0e10cSrcweir     if (!pCell || pCell->HasEmptyData())
960cdf0e10cSrcweir     {
961cdf0e10cSrcweir         if (pRetTypeExpr && pRetIndexExpr)
962cdf0e10cSrcweir             pDok->GetNumberFormatInfo( *pRetTypeExpr, *pRetIndexExpr, rAddress, pCell);
963cdf0e10cSrcweir         bool bInherited = (GetCellType( pCell) == CELLTYPE_FORMULA);
964cdf0e10cSrcweir         PushTempToken( new ScEmptyCellToken( bInherited, bDisplayEmptyAsString));
965cdf0e10cSrcweir         return;
966cdf0e10cSrcweir     }
967cdf0e10cSrcweir     sal_uInt16 nErr;
968cdf0e10cSrcweir     if ((nErr = pCell->GetErrorCode()) != 0)
969cdf0e10cSrcweir     {
970cdf0e10cSrcweir         PushError( nErr);
971cdf0e10cSrcweir         if (pRetTypeExpr)
972cdf0e10cSrcweir             *pRetTypeExpr = NUMBERFORMAT_UNDEFINED;
973cdf0e10cSrcweir         if (pRetIndexExpr)
974cdf0e10cSrcweir             *pRetIndexExpr = 0;
975cdf0e10cSrcweir     }
976cdf0e10cSrcweir     else if (pCell->HasStringData())
977cdf0e10cSrcweir     {
978cdf0e10cSrcweir         String aRes;
979cdf0e10cSrcweir         GetCellString( aRes, pCell);
980cdf0e10cSrcweir         PushString( aRes);
981cdf0e10cSrcweir         if (pRetTypeExpr)
982cdf0e10cSrcweir             *pRetTypeExpr = NUMBERFORMAT_TEXT;
983cdf0e10cSrcweir         if (pRetIndexExpr)
984cdf0e10cSrcweir             *pRetIndexExpr = 0;
985cdf0e10cSrcweir     }
986cdf0e10cSrcweir     else
987cdf0e10cSrcweir     {
988cdf0e10cSrcweir         double fVal = GetCellValue( rAddress, pCell);
989cdf0e10cSrcweir         PushDouble( fVal);
990cdf0e10cSrcweir         if (pRetTypeExpr)
991cdf0e10cSrcweir             *pRetTypeExpr = nCurFmtType;
992cdf0e10cSrcweir         if (pRetIndexExpr)
993cdf0e10cSrcweir             *pRetIndexExpr = nCurFmtIndex;
994cdf0e10cSrcweir     }
995cdf0e10cSrcweir }
996cdf0e10cSrcweir 
997cdf0e10cSrcweir 
998cdf0e10cSrcweir // Simply throw away TOS.
999cdf0e10cSrcweir 
Pop()1000cdf0e10cSrcweir void ScInterpreter::Pop()
1001cdf0e10cSrcweir {
1002cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Pop" );
1003cdf0e10cSrcweir     if( sp )
1004cdf0e10cSrcweir         sp--;
1005cdf0e10cSrcweir     else
1006cdf0e10cSrcweir         SetError(errUnknownStackVariable);
1007cdf0e10cSrcweir }
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir 
1010cdf0e10cSrcweir // Simply throw away TOS and set error code, used with ocIsError et al.
1011cdf0e10cSrcweir 
PopError()1012cdf0e10cSrcweir void ScInterpreter::PopError()
1013cdf0e10cSrcweir {
1014cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopError" );
1015cdf0e10cSrcweir     if( sp )
1016cdf0e10cSrcweir     {
1017cdf0e10cSrcweir         sp--;
1018cdf0e10cSrcweir         if (pStack[sp]->GetType() == svError)
1019cdf0e10cSrcweir             nGlobalError = pStack[sp]->GetError();
1020cdf0e10cSrcweir     }
1021cdf0e10cSrcweir     else
1022cdf0e10cSrcweir         SetError(errUnknownStackVariable);
1023cdf0e10cSrcweir }
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir 
PopToken()1026cdf0e10cSrcweir FormulaTokenRef ScInterpreter::PopToken()
1027cdf0e10cSrcweir {
1028cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopToken" );
1029cdf0e10cSrcweir     if (sp)
1030cdf0e10cSrcweir     {
1031cdf0e10cSrcweir         sp--;
1032cdf0e10cSrcweir         FormulaToken* p = pStack[ sp ];
1033cdf0e10cSrcweir         if (p->GetType() == svError)
1034cdf0e10cSrcweir             nGlobalError = p->GetError();
1035cdf0e10cSrcweir         return p;
1036cdf0e10cSrcweir     }
1037cdf0e10cSrcweir     else
1038cdf0e10cSrcweir         SetError(errUnknownStackVariable);
1039cdf0e10cSrcweir     return NULL;
1040cdf0e10cSrcweir }
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir 
PopDouble()1043cdf0e10cSrcweir double ScInterpreter::PopDouble()
1044cdf0e10cSrcweir {
1045cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDouble" );
1046cdf0e10cSrcweir     nCurFmtType = NUMBERFORMAT_NUMBER;
1047cdf0e10cSrcweir     nCurFmtIndex = 0;
1048cdf0e10cSrcweir     if( sp )
1049cdf0e10cSrcweir     {
1050cdf0e10cSrcweir         --sp;
1051cdf0e10cSrcweir         FormulaToken* p = pStack[ sp ];
1052cdf0e10cSrcweir         switch (p->GetType())
1053cdf0e10cSrcweir         {
1054cdf0e10cSrcweir             case svError:
1055cdf0e10cSrcweir                 nGlobalError = p->GetError();
1056cdf0e10cSrcweir                 break;
1057cdf0e10cSrcweir             case svDouble:
1058cdf0e10cSrcweir                 return p->GetDouble();
1059cdf0e10cSrcweir             case svEmptyCell:
1060cdf0e10cSrcweir             case svMissing:
1061cdf0e10cSrcweir                 return 0.0;
1062cdf0e10cSrcweir             default:
1063cdf0e10cSrcweir                 SetError( errIllegalArgument);
1064cdf0e10cSrcweir         }
1065cdf0e10cSrcweir     }
1066cdf0e10cSrcweir     else
1067cdf0e10cSrcweir         SetError( errUnknownStackVariable);
1068cdf0e10cSrcweir     return 0.0;
1069cdf0e10cSrcweir }
1070cdf0e10cSrcweir 
1071cdf0e10cSrcweir 
PopString()1072cdf0e10cSrcweir const String& ScInterpreter::PopString()
1073cdf0e10cSrcweir {
1074cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopString" );
1075cdf0e10cSrcweir     nCurFmtType = NUMBERFORMAT_TEXT;
1076cdf0e10cSrcweir     nCurFmtIndex = 0;
1077cdf0e10cSrcweir     if( sp )
1078cdf0e10cSrcweir     {
1079cdf0e10cSrcweir         --sp;
1080cdf0e10cSrcweir         FormulaToken* p = pStack[ sp ];
1081cdf0e10cSrcweir         switch (p->GetType())
1082cdf0e10cSrcweir         {
1083cdf0e10cSrcweir             case svError:
1084cdf0e10cSrcweir                 nGlobalError = p->GetError();
1085cdf0e10cSrcweir                 break;
1086cdf0e10cSrcweir             case svString:
1087cdf0e10cSrcweir                 return p->GetString();
1088cdf0e10cSrcweir             case svEmptyCell:
1089cdf0e10cSrcweir             case svMissing:
1090cdf0e10cSrcweir                 return EMPTY_STRING;
1091cdf0e10cSrcweir             default:
1092cdf0e10cSrcweir                 SetError( errIllegalArgument);
1093cdf0e10cSrcweir         }
1094cdf0e10cSrcweir     }
1095cdf0e10cSrcweir     else
1096cdf0e10cSrcweir         SetError( errUnknownStackVariable);
1097cdf0e10cSrcweir     return EMPTY_STRING;
1098cdf0e10cSrcweir }
1099cdf0e10cSrcweir 
1100cdf0e10cSrcweir 
ValidateRef(const ScSingleRefData & rRef)1101cdf0e10cSrcweir void ScInterpreter::ValidateRef( const ScSingleRefData & rRef )
1102cdf0e10cSrcweir {
1103cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
1104cdf0e10cSrcweir     SCCOL nCol;
1105cdf0e10cSrcweir     SCROW nRow;
1106cdf0e10cSrcweir     SCTAB nTab;
1107cdf0e10cSrcweir     SingleRefToVars( rRef, nCol, nRow, nTab);
1108cdf0e10cSrcweir }
1109cdf0e10cSrcweir 
1110cdf0e10cSrcweir 
ValidateRef(const ScComplexRefData & rRef)1111cdf0e10cSrcweir void ScInterpreter::ValidateRef( const ScComplexRefData & rRef )
1112cdf0e10cSrcweir {
1113cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
1114cdf0e10cSrcweir     ValidateRef( rRef.Ref1);
1115cdf0e10cSrcweir     ValidateRef( rRef.Ref2);
1116cdf0e10cSrcweir }
1117cdf0e10cSrcweir 
1118cdf0e10cSrcweir 
ValidateRef(const ScRefList & rRefList)1119cdf0e10cSrcweir void ScInterpreter::ValidateRef( const ScRefList & rRefList )
1120cdf0e10cSrcweir {
1121cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
1122cdf0e10cSrcweir     ScRefList::const_iterator it( rRefList.begin());
1123cdf0e10cSrcweir     ScRefList::const_iterator end( rRefList.end());
1124cdf0e10cSrcweir     for ( ; it != end; ++it)
1125cdf0e10cSrcweir     {
1126cdf0e10cSrcweir         ValidateRef( *it);
1127cdf0e10cSrcweir     }
1128cdf0e10cSrcweir }
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir 
SingleRefToVars(const ScSingleRefData & rRef,SCCOL & rCol,SCROW & rRow,SCTAB & rTab)1131cdf0e10cSrcweir void ScInterpreter::SingleRefToVars( const ScSingleRefData & rRef,
1132cdf0e10cSrcweir         SCCOL & rCol, SCROW & rRow, SCTAB & rTab )
1133cdf0e10cSrcweir {
1134cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::SingleRefToVars" );
1135cdf0e10cSrcweir     if ( rRef.IsColRel() )
1136cdf0e10cSrcweir         rCol = aPos.Col() + rRef.nRelCol;
1137cdf0e10cSrcweir     else
1138cdf0e10cSrcweir         rCol = rRef.nCol;
1139cdf0e10cSrcweir     if ( rRef.IsRowRel() )
1140cdf0e10cSrcweir         rRow = aPos.Row() + rRef.nRelRow;
1141cdf0e10cSrcweir     else
1142cdf0e10cSrcweir         rRow = rRef.nRow;
1143cdf0e10cSrcweir     if ( rRef.IsTabRel() )
1144cdf0e10cSrcweir         rTab = aPos.Tab() + rRef.nRelTab;
1145cdf0e10cSrcweir     else
1146cdf0e10cSrcweir         rTab = rRef.nTab;
1147cdf0e10cSrcweir     if( !ValidCol( rCol) || rRef.IsColDeleted() )
1148cdf0e10cSrcweir         SetError( errNoRef ), rCol = 0;
1149cdf0e10cSrcweir     if( !ValidRow( rRow) || rRef.IsRowDeleted() )
1150cdf0e10cSrcweir         SetError( errNoRef ), rRow = 0;
1151cdf0e10cSrcweir     if( !ValidTab( rTab, pDok->GetTableCount() - 1) || rRef.IsTabDeleted() )
1152cdf0e10cSrcweir         SetError( errNoRef ), rTab = 0;
1153cdf0e10cSrcweir }
1154cdf0e10cSrcweir 
1155cdf0e10cSrcweir 
PopSingleRef(SCCOL & rCol,SCROW & rRow,SCTAB & rTab)1156cdf0e10cSrcweir void ScInterpreter::PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab)
1157cdf0e10cSrcweir {
1158cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopSingleRef" );
1159cdf0e10cSrcweir     if( sp )
1160cdf0e10cSrcweir     {
1161cdf0e10cSrcweir         --sp;
1162cdf0e10cSrcweir         FormulaToken* p = pStack[ sp ];
1163cdf0e10cSrcweir         switch (p->GetType())
1164cdf0e10cSrcweir         {
1165cdf0e10cSrcweir             case svError:
1166cdf0e10cSrcweir                 nGlobalError = p->GetError();
1167cdf0e10cSrcweir                 break;
1168cdf0e10cSrcweir             case svSingleRef:
1169cdf0e10cSrcweir                 SingleRefToVars( static_cast<ScToken*>(p)->GetSingleRef(), rCol, rRow, rTab);
1170cdf0e10cSrcweir                 if ( pDok->aTableOpList.Count() > 0 )
1171cdf0e10cSrcweir                     ReplaceCell( rCol, rRow, rTab );
117261e64f4aSWang Lei                 DELETEZ(pLastStackRefToken);
117361e64f4aSWang Lei                 pLastStackRefToken = static_cast<ScToken*>(p->Clone());
117461e64f4aSWang Lei                 ((ScSingleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True);
1175cdf0e10cSrcweir                 break;
1176cdf0e10cSrcweir             default:
1177cdf0e10cSrcweir                 SetError( errIllegalParameter);
1178cdf0e10cSrcweir         }
1179cdf0e10cSrcweir     }
1180cdf0e10cSrcweir     else
1181cdf0e10cSrcweir         SetError( errUnknownStackVariable);
1182cdf0e10cSrcweir }
1183cdf0e10cSrcweir 
1184cdf0e10cSrcweir 
PopSingleRef(ScAddress & rAdr)1185cdf0e10cSrcweir void ScInterpreter::PopSingleRef( ScAddress& rAdr )
1186cdf0e10cSrcweir {
1187cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopSingleRef" );
1188cdf0e10cSrcweir     if( sp )
1189cdf0e10cSrcweir     {
1190cdf0e10cSrcweir         --sp;
1191cdf0e10cSrcweir         FormulaToken* p = pStack[ sp ];
1192cdf0e10cSrcweir         switch (p->GetType())
1193cdf0e10cSrcweir         {
1194cdf0e10cSrcweir             case svError:
1195cdf0e10cSrcweir                 nGlobalError = p->GetError();
1196cdf0e10cSrcweir                 break;
1197cdf0e10cSrcweir             case svSingleRef:
1198cdf0e10cSrcweir                 {
1199cdf0e10cSrcweir                     SCCOL nCol;
1200cdf0e10cSrcweir                     SCROW nRow;
1201cdf0e10cSrcweir                     SCTAB nTab;
1202cdf0e10cSrcweir                     SingleRefToVars( static_cast<ScToken*>(p)->GetSingleRef(), nCol, nRow, nTab);
1203cdf0e10cSrcweir                     rAdr.Set( nCol, nRow, nTab );
1204cdf0e10cSrcweir                     if ( pDok->aTableOpList.Count() > 0 )
1205cdf0e10cSrcweir                         ReplaceCell( rAdr );
120661e64f4aSWang Lei                     DELETEZ(pLastStackRefToken);
120761e64f4aSWang Lei                     pLastStackRefToken = static_cast<ScToken*>(p->Clone());
120861e64f4aSWang Lei                     ((ScSingleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True);
1209cdf0e10cSrcweir                 }
1210cdf0e10cSrcweir                 break;
1211cdf0e10cSrcweir             default:
1212cdf0e10cSrcweir                 SetError( errIllegalParameter);
1213cdf0e10cSrcweir         }
1214cdf0e10cSrcweir     }
1215cdf0e10cSrcweir     else
1216cdf0e10cSrcweir         SetError( errUnknownStackVariable);
1217cdf0e10cSrcweir }
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir 
DoubleRefToVars(const ScToken * p,SCCOL & rCol1,SCROW & rRow1,SCTAB & rTab1,SCCOL & rCol2,SCROW & rRow2,SCTAB & rTab2,sal_Bool bDontCheckForTableOp)1220cdf0e10cSrcweir void ScInterpreter::DoubleRefToVars( const ScToken* p,
1221cdf0e10cSrcweir         SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
1222cdf0e10cSrcweir         SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
1223cdf0e10cSrcweir         sal_Bool bDontCheckForTableOp )
1224cdf0e10cSrcweir {
1225cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToVars" );
1226cdf0e10cSrcweir     const ScComplexRefData& rCRef = p->GetDoubleRef();
1227cdf0e10cSrcweir     SingleRefToVars( rCRef.Ref1, rCol1, rRow1, rTab1);
1228cdf0e10cSrcweir     SingleRefToVars( rCRef.Ref2, rCol2, rRow2, rTab2);
1229cdf0e10cSrcweir     if ( pDok->aTableOpList.Count() > 0 && !bDontCheckForTableOp )
1230cdf0e10cSrcweir     {
1231cdf0e10cSrcweir         ScRange aRange( rCol1, rRow1, rTab1, rCol2, rRow2, rTab2 );
1232cdf0e10cSrcweir         if ( IsTableOpInRange( aRange ) )
1233cdf0e10cSrcweir             SetError( errIllegalParameter );
1234cdf0e10cSrcweir     }
1235cdf0e10cSrcweir }
1236cdf0e10cSrcweir 
PopDoubleRef()1237cdf0e10cSrcweir ScDBRangeBase* ScInterpreter::PopDoubleRef()
1238cdf0e10cSrcweir {
1239cdf0e10cSrcweir     if (!sp)
1240cdf0e10cSrcweir     {
1241cdf0e10cSrcweir         SetError(errUnknownStackVariable);
1242cdf0e10cSrcweir         return NULL;
1243cdf0e10cSrcweir     }
1244cdf0e10cSrcweir 
1245cdf0e10cSrcweir     --sp;
1246cdf0e10cSrcweir     FormulaToken* p = pStack[sp];
1247cdf0e10cSrcweir     switch (p->GetType())
1248cdf0e10cSrcweir     {
1249cdf0e10cSrcweir         case svError:
1250cdf0e10cSrcweir             nGlobalError = p->GetError();
1251cdf0e10cSrcweir         break;
1252cdf0e10cSrcweir         case svDoubleRef:
1253cdf0e10cSrcweir         {
1254cdf0e10cSrcweir             SCCOL nCol1, nCol2;
1255cdf0e10cSrcweir             SCROW nRow1, nRow2;
1256cdf0e10cSrcweir             SCTAB nTab1, nTab2;
1257cdf0e10cSrcweir             DoubleRefToVars(static_cast<ScToken*>(p),
1258cdf0e10cSrcweir                             nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, false);
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir             return new ScDBInternalRange(pDok,
1261cdf0e10cSrcweir                 ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
1262cdf0e10cSrcweir         }
1263cdf0e10cSrcweir         case svMatrix:
1264cdf0e10cSrcweir         {
1265cdf0e10cSrcweir             ScMatrixRef pMat = static_cast<ScToken*>(p)->GetMatrix();
1266cdf0e10cSrcweir             return new ScDBExternalRange(pDok, pMat);
1267cdf0e10cSrcweir         }
1268cdf0e10cSrcweir         default:
1269cdf0e10cSrcweir             SetError( errIllegalParameter);
1270cdf0e10cSrcweir     }
1271cdf0e10cSrcweir     return NULL;
1272cdf0e10cSrcweir }
1273cdf0e10cSrcweir 
PopDoubleRef(SCCOL & rCol1,SCROW & rRow1,SCTAB & rTab1,SCCOL & rCol2,SCROW & rRow2,SCTAB & rTab2,sal_Bool bDontCheckForTableOp)1274cdf0e10cSrcweir void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
1275cdf0e10cSrcweir                                  SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
1276cdf0e10cSrcweir                                  sal_Bool bDontCheckForTableOp )
1277cdf0e10cSrcweir {
1278cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
1279cdf0e10cSrcweir     if( sp )
1280cdf0e10cSrcweir     {
1281cdf0e10cSrcweir         --sp;
1282cdf0e10cSrcweir         FormulaToken* p = pStack[ sp ];
1283cdf0e10cSrcweir         switch (p->GetType())
1284cdf0e10cSrcweir         {
1285cdf0e10cSrcweir             case svError:
1286cdf0e10cSrcweir                 nGlobalError = p->GetError();
1287cdf0e10cSrcweir                 break;
1288cdf0e10cSrcweir             case svDoubleRef:
1289cdf0e10cSrcweir                 DoubleRefToVars( static_cast<ScToken*>(p), rCol1, rRow1, rTab1, rCol2, rRow2, rTab2,
1290cdf0e10cSrcweir                         bDontCheckForTableOp);
129161e64f4aSWang Lei                 DELETEZ(pLastStackRefToken);
129261e64f4aSWang Lei                 pLastStackRefToken = static_cast<ScToken*>(p->Clone());
129361e64f4aSWang Lei                 ((ScDoubleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True);
1294cdf0e10cSrcweir                 break;
1295cdf0e10cSrcweir             default:
1296cdf0e10cSrcweir                 SetError( errIllegalParameter);
1297cdf0e10cSrcweir         }
1298cdf0e10cSrcweir     }
1299cdf0e10cSrcweir     else
1300cdf0e10cSrcweir         SetError( errUnknownStackVariable);
1301cdf0e10cSrcweir }
1302cdf0e10cSrcweir 
1303cdf0e10cSrcweir 
DoubleRefToRange(const ScComplexRefData & rCRef,ScRange & rRange,sal_Bool bDontCheckForTableOp)1304cdf0e10cSrcweir void ScInterpreter::DoubleRefToRange( const ScComplexRefData & rCRef,
1305cdf0e10cSrcweir         ScRange & rRange, sal_Bool bDontCheckForTableOp )
1306cdf0e10cSrcweir {
1307cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToRange" );
1308cdf0e10cSrcweir     SCCOL nCol;
1309cdf0e10cSrcweir     SCROW nRow;
1310cdf0e10cSrcweir     SCTAB nTab;
1311cdf0e10cSrcweir     SingleRefToVars( rCRef.Ref1, nCol, nRow, nTab);
1312cdf0e10cSrcweir     rRange.aStart.Set( nCol, nRow, nTab );
1313cdf0e10cSrcweir     SingleRefToVars( rCRef.Ref2, nCol, nRow, nTab);
1314cdf0e10cSrcweir     rRange.aEnd.Set( nCol, nRow, nTab );
1315cdf0e10cSrcweir     if ( pDok->aTableOpList.Count() > 0 && !bDontCheckForTableOp )
1316cdf0e10cSrcweir     {
1317cdf0e10cSrcweir         if ( IsTableOpInRange( rRange ) )
1318cdf0e10cSrcweir             SetError( errIllegalParameter );
1319cdf0e10cSrcweir     }
1320cdf0e10cSrcweir }
1321cdf0e10cSrcweir 
1322cdf0e10cSrcweir 
PopDoubleRef(ScRange & rRange,short & rParam,size_t & rRefInList)1323cdf0e10cSrcweir void ScInterpreter::PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList )
1324cdf0e10cSrcweir {
1325cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
1326cdf0e10cSrcweir     if (sp)
1327cdf0e10cSrcweir     {
1328cdf0e10cSrcweir         formula::FormulaToken* pToken = pStack[ sp-1 ];
1329cdf0e10cSrcweir         ScToken* p = static_cast<ScToken*>(pToken);
1330cdf0e10cSrcweir         switch (pToken->GetType())
1331cdf0e10cSrcweir         {
1332cdf0e10cSrcweir             case svError:
1333cdf0e10cSrcweir                 nGlobalError = p->GetError();
1334cdf0e10cSrcweir                 break;
1335cdf0e10cSrcweir             case svDoubleRef:
1336cdf0e10cSrcweir                 --sp;
1337cdf0e10cSrcweir                 DoubleRefToRange( p->GetDoubleRef(), rRange);
133861e64f4aSWang Lei                 DELETEZ(pLastStackRefToken);
133961e64f4aSWang Lei                 pLastStackRefToken = static_cast<ScToken*>(p->Clone());
134061e64f4aSWang Lei                 ((ScDoubleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True);
1341cdf0e10cSrcweir                 break;
1342cdf0e10cSrcweir             case svRefList:
1343cdf0e10cSrcweir                 {
1344cdf0e10cSrcweir                     const ScRefList* pList = p->GetRefList();
1345cdf0e10cSrcweir                     if (rRefInList < pList->size())
1346cdf0e10cSrcweir                     {
1347cdf0e10cSrcweir                         DoubleRefToRange( (*pList)[rRefInList], rRange);
1348cdf0e10cSrcweir                         if (++rRefInList < pList->size())
1349cdf0e10cSrcweir                             ++rParam;
1350cdf0e10cSrcweir                         else
1351cdf0e10cSrcweir                         {
1352cdf0e10cSrcweir                             --sp;
1353cdf0e10cSrcweir                             rRefInList = 0;
1354cdf0e10cSrcweir                         }
1355cdf0e10cSrcweir                     }
1356cdf0e10cSrcweir                     else
1357cdf0e10cSrcweir                     {
1358cdf0e10cSrcweir                         --sp;
1359cdf0e10cSrcweir                         rRefInList = 0;
1360cdf0e10cSrcweir                         SetError( errIllegalParameter);
1361cdf0e10cSrcweir                     }
1362cdf0e10cSrcweir                 }
1363cdf0e10cSrcweir                 break;
1364cdf0e10cSrcweir             default:
1365cdf0e10cSrcweir                 SetError( errIllegalParameter);
1366cdf0e10cSrcweir         }
1367cdf0e10cSrcweir     }
1368cdf0e10cSrcweir     else
1369cdf0e10cSrcweir         SetError( errUnknownStackVariable);
1370cdf0e10cSrcweir }
1371cdf0e10cSrcweir 
1372cdf0e10cSrcweir 
PopDoubleRef(ScRange & rRange,sal_Bool bDontCheckForTableOp)1373cdf0e10cSrcweir void ScInterpreter::PopDoubleRef( ScRange& rRange, sal_Bool bDontCheckForTableOp )
1374cdf0e10cSrcweir {
1375cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
1376cdf0e10cSrcweir     if( sp )
1377cdf0e10cSrcweir     {
1378cdf0e10cSrcweir         --sp;
1379cdf0e10cSrcweir         FormulaToken* p = pStack[ sp ];
1380cdf0e10cSrcweir         switch (p->GetType())
1381cdf0e10cSrcweir         {
1382cdf0e10cSrcweir             case svError:
1383cdf0e10cSrcweir                 nGlobalError = p->GetError();
1384cdf0e10cSrcweir                 break;
1385cdf0e10cSrcweir             case svDoubleRef:
1386cdf0e10cSrcweir                 DoubleRefToRange( static_cast<ScToken*>(p)->GetDoubleRef(), rRange, bDontCheckForTableOp);
138761e64f4aSWang Lei                 DELETEZ(pLastStackRefToken);
138861e64f4aSWang Lei                 pLastStackRefToken = static_cast<ScToken*>(p->Clone());
138961e64f4aSWang Lei                 ((ScDoubleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True);
1390cdf0e10cSrcweir                 break;
1391cdf0e10cSrcweir             default:
1392cdf0e10cSrcweir                 SetError( errIllegalParameter);
1393cdf0e10cSrcweir         }
1394cdf0e10cSrcweir     }
1395cdf0e10cSrcweir     else
1396cdf0e10cSrcweir         SetError( errUnknownStackVariable);
1397cdf0e10cSrcweir }
1398cdf0e10cSrcweir 
1399cdf0e10cSrcweir 
PopDoubleRefOrSingleRef(ScAddress & rAdr)1400cdf0e10cSrcweir sal_Bool ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr )
1401cdf0e10cSrcweir {
1402cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefOrSingleRef" );
1403cdf0e10cSrcweir     switch ( GetStackType() )
1404cdf0e10cSrcweir     {
1405cdf0e10cSrcweir         case svDoubleRef :
1406cdf0e10cSrcweir         {
1407cdf0e10cSrcweir             ScRange aRange;
1408cdf0e10cSrcweir             PopDoubleRef( aRange, sal_True );
1409cdf0e10cSrcweir             return DoubleRefToPosSingleRef( aRange, rAdr );
1410cdf0e10cSrcweir         }
1411cdf0e10cSrcweir         //break;
1412cdf0e10cSrcweir         case svSingleRef :
1413cdf0e10cSrcweir         {
1414cdf0e10cSrcweir             PopSingleRef( rAdr );
1415cdf0e10cSrcweir             return sal_True;
1416cdf0e10cSrcweir         }
1417cdf0e10cSrcweir         //break;
1418cdf0e10cSrcweir         default:
1419cdf0e10cSrcweir             PopError();
1420cdf0e10cSrcweir             SetError( errNoRef );
1421cdf0e10cSrcweir     }
1422cdf0e10cSrcweir     return sal_False;
1423cdf0e10cSrcweir }
1424cdf0e10cSrcweir 
1425cdf0e10cSrcweir 
PopDoubleRefPushMatrix()1426cdf0e10cSrcweir void ScInterpreter::PopDoubleRefPushMatrix()
1427cdf0e10cSrcweir {
1428cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefPushMatrix" );
1429cdf0e10cSrcweir     if ( GetStackType() == svDoubleRef )
1430cdf0e10cSrcweir     {
1431cdf0e10cSrcweir         ScMatrixRef pMat = GetMatrix();
1432cdf0e10cSrcweir         if ( pMat )
1433cdf0e10cSrcweir             PushMatrix( pMat );
1434cdf0e10cSrcweir         else
1435cdf0e10cSrcweir             PushIllegalParameter();
1436cdf0e10cSrcweir     }
1437cdf0e10cSrcweir     else
1438cdf0e10cSrcweir         SetError( errNoRef );
1439cdf0e10cSrcweir }
1440cdf0e10cSrcweir 
1441cdf0e10cSrcweir 
CreateTokenMatrixMap()1442cdf0e10cSrcweir ScTokenMatrixMap* ScInterpreter::CreateTokenMatrixMap()
1443cdf0e10cSrcweir {
1444cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateTokenMatrixMap" );
1445cdf0e10cSrcweir     return new ScTokenMatrixMap;
1446cdf0e10cSrcweir }
1447cdf0e10cSrcweir 
1448cdf0e10cSrcweir 
ConvertMatrixParameters()1449cdf0e10cSrcweir bool ScInterpreter::ConvertMatrixParameters()
1450cdf0e10cSrcweir {
1451cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ConvertMatrixParameters" );
1452cdf0e10cSrcweir     sal_uInt16 nParams = pCur->GetParamCount();
1453cdf0e10cSrcweir     DBG_ASSERT( nParams <= sp, "ConvertMatrixParameters: stack/param count mismatch");
1454cdf0e10cSrcweir     SCSIZE nJumpCols = 0, nJumpRows = 0;
1455cdf0e10cSrcweir     for ( sal_uInt16 i=1; i <= nParams && i <= sp; ++i )
1456cdf0e10cSrcweir     {
1457cdf0e10cSrcweir         FormulaToken* p = pStack[ sp - i ];
1458cdf0e10cSrcweir         if ( p->GetOpCode() != ocPush && p->GetOpCode() != ocMissing  )
1459cdf0e10cSrcweir         {
1460cdf0e10cSrcweir             DBG_ERRORFILE( "ConvertMatrixParameters: not a push");
1461cdf0e10cSrcweir         }
1462cdf0e10cSrcweir         else
1463cdf0e10cSrcweir         {
1464cdf0e10cSrcweir             switch ( p->GetType() )
1465cdf0e10cSrcweir             {
1466cdf0e10cSrcweir                 case svDouble:
1467cdf0e10cSrcweir                 case svString:
1468cdf0e10cSrcweir                 case svSingleRef:
1469cdf0e10cSrcweir                 case svMissing:
1470cdf0e10cSrcweir                 case svError:
1471cdf0e10cSrcweir                 case svEmptyCell:
1472cdf0e10cSrcweir                     // nothing to do
1473cdf0e10cSrcweir                 break;
1474cdf0e10cSrcweir                 case svMatrix:
1475cdf0e10cSrcweir                 {
1476cdf0e10cSrcweir                     if ( ScParameterClassification::GetParameterType( pCur, nParams - i)
1477cdf0e10cSrcweir                             == ScParameterClassification::Value )
1478cdf0e10cSrcweir                     {   // only if single value expected
1479cdf0e10cSrcweir                         ScMatrixRef pMat = static_cast<ScToken*>(p)->GetMatrix();
1480cdf0e10cSrcweir                         if ( !pMat )
1481cdf0e10cSrcweir                             SetError( errUnknownVariable);
1482cdf0e10cSrcweir                         else
1483cdf0e10cSrcweir                         {
1484cdf0e10cSrcweir                             SCSIZE nCols, nRows;
1485cdf0e10cSrcweir                             pMat->GetDimensions( nCols, nRows);
1486cdf0e10cSrcweir                             if ( nJumpCols < nCols )
1487cdf0e10cSrcweir                                 nJumpCols = nCols;
1488cdf0e10cSrcweir                             if ( nJumpRows < nRows )
1489cdf0e10cSrcweir                                 nJumpRows = nRows;
1490cdf0e10cSrcweir                         }
1491cdf0e10cSrcweir                     }
1492cdf0e10cSrcweir                 }
1493cdf0e10cSrcweir                 break;
1494cdf0e10cSrcweir                 case svDoubleRef:
1495cdf0e10cSrcweir                 {
1496cdf0e10cSrcweir                     ScParameterClassification::Type eType =
1497cdf0e10cSrcweir                         ScParameterClassification::GetParameterType( pCur, nParams - i);
1498cdf0e10cSrcweir                     if ( eType != ScParameterClassification::Reference &&
1499cdf0e10cSrcweir                             eType != ScParameterClassification::ReferenceOrForceArray)
1500cdf0e10cSrcweir                     {
1501cdf0e10cSrcweir                         SCCOL nCol1, nCol2;
1502cdf0e10cSrcweir                         SCROW nRow1, nRow2;
1503cdf0e10cSrcweir                         SCTAB nTab1, nTab2;
1504cdf0e10cSrcweir                         DoubleRefToVars( static_cast<const ScToken*>( p), nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
1505cdf0e10cSrcweir                         // Make sure the map exists, created if not.
1506cdf0e10cSrcweir                         GetTokenMatrixMap();
1507cdf0e10cSrcweir                         ScMatrixRef pMat = CreateMatrixFromDoubleRef( p,
1508cdf0e10cSrcweir                                 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
1509cdf0e10cSrcweir                         if (pMat)
1510cdf0e10cSrcweir                         {
1511cdf0e10cSrcweir                             if ( eType == ScParameterClassification::Value )
1512cdf0e10cSrcweir                             {   // only if single value expected
1513cdf0e10cSrcweir                                 if ( nJumpCols < static_cast<SCSIZE>(nCol2 - nCol1 + 1) )
1514cdf0e10cSrcweir                                     nJumpCols = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
1515cdf0e10cSrcweir                                 if ( nJumpRows < static_cast<SCSIZE>(nRow2 - nRow1 + 1) )
1516cdf0e10cSrcweir                                     nJumpRows = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
1517cdf0e10cSrcweir                             }
1518cdf0e10cSrcweir                             ScToken* pNew = new ScMatrixToken( pMat);
1519cdf0e10cSrcweir                             pNew->IncRef();
1520cdf0e10cSrcweir                             pStack[ sp - i ] = pNew;
1521cdf0e10cSrcweir                             p->DecRef();    // p may be dead now!
1522cdf0e10cSrcweir                         }
1523cdf0e10cSrcweir                     }
1524cdf0e10cSrcweir                 }
1525cdf0e10cSrcweir                 break;
1526cdf0e10cSrcweir                 case svRefList:
1527cdf0e10cSrcweir                 {
1528cdf0e10cSrcweir                     ScParameterClassification::Type eType =
1529cdf0e10cSrcweir                         ScParameterClassification::GetParameterType( pCur, nParams - i);
1530cdf0e10cSrcweir                     if ( eType != ScParameterClassification::Reference &&
1531cdf0e10cSrcweir                             eType != ScParameterClassification::ReferenceOrForceArray)
1532cdf0e10cSrcweir                     {
1533cdf0e10cSrcweir                         // can't convert to matrix
1534cdf0e10cSrcweir                         SetError( errNoValue);
1535cdf0e10cSrcweir                     }
1536cdf0e10cSrcweir                 }
1537cdf0e10cSrcweir                 break;
1538cdf0e10cSrcweir                 default:
1539cdf0e10cSrcweir                     DBG_ERRORFILE( "ConvertMatrixParameters: unknown parameter type");
1540cdf0e10cSrcweir             }
1541cdf0e10cSrcweir         }
1542cdf0e10cSrcweir     }
1543cdf0e10cSrcweir     if( nJumpCols && nJumpRows )
1544cdf0e10cSrcweir     {
1545cdf0e10cSrcweir         short nPC = aCode.GetPC();
1546cdf0e10cSrcweir         short nStart = nPC - 1;     // restart on current code (-1)
1547cdf0e10cSrcweir         short nNext = nPC;          // next instruction after subroutine
1548cdf0e10cSrcweir         short nStop = nPC + 1;      // stop subroutine before reaching that
1549cdf0e10cSrcweir         FormulaTokenRef xNew;
1550cdf0e10cSrcweir         ScTokenMatrixMap::const_iterator aMapIter;
1551cdf0e10cSrcweir         if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find( pCur)) !=
1552cdf0e10cSrcweir                     pTokenMatrixMap->end()))
1553cdf0e10cSrcweir             xNew = (*aMapIter).second;
1554cdf0e10cSrcweir         else
1555cdf0e10cSrcweir         {
1556cdf0e10cSrcweir             ScJumpMatrix* pJumpMat = new ScJumpMatrix( nJumpCols, nJumpRows);
1557cdf0e10cSrcweir             pJumpMat->SetAllJumps( 1.0, nStart, nNext, nStop);
1558cdf0e10cSrcweir             // pop parameters and store in ScJumpMatrix, push in JumpMatrix()
1559cdf0e10cSrcweir             ScTokenVec* pParams = new ScTokenVec( nParams);
1560cdf0e10cSrcweir             for ( sal_uInt16 i=1; i <= nParams && sp > 0; ++i )
1561cdf0e10cSrcweir             {
1562cdf0e10cSrcweir                 FormulaToken* p = pStack[ --sp ];
1563cdf0e10cSrcweir                 p->IncRef();
1564cdf0e10cSrcweir                 // store in reverse order such that a push may simply iterate
1565cdf0e10cSrcweir                 (*pParams)[ nParams - i ] = p;
1566cdf0e10cSrcweir             }
1567cdf0e10cSrcweir             pJumpMat->SetJumpParameters( pParams);
1568cdf0e10cSrcweir             xNew = new ScJumpMatrixToken( pJumpMat );
1569cdf0e10cSrcweir             GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type( pCur,
1570cdf0e10cSrcweir                         xNew));
1571cdf0e10cSrcweir         }
1572cdf0e10cSrcweir         PushTempToken( xNew);
1573cdf0e10cSrcweir         // set continuation point of path for main code line
1574cdf0e10cSrcweir         aCode.Jump( nNext, nNext);
1575cdf0e10cSrcweir         return true;
1576cdf0e10cSrcweir     }
1577cdf0e10cSrcweir     return false;
1578cdf0e10cSrcweir }
1579cdf0e10cSrcweir 
1580cdf0e10cSrcweir 
PopMatrix()1581cdf0e10cSrcweir ScMatrixRef ScInterpreter::PopMatrix()
1582cdf0e10cSrcweir {
1583cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopMatrix" );
1584cdf0e10cSrcweir     if( sp )
1585cdf0e10cSrcweir     {
1586cdf0e10cSrcweir         --sp;
1587cdf0e10cSrcweir         FormulaToken* p = pStack[ sp ];
1588cdf0e10cSrcweir         switch (p->GetType())
1589cdf0e10cSrcweir         {
1590cdf0e10cSrcweir             case svError:
1591cdf0e10cSrcweir                 nGlobalError = p->GetError();
1592cdf0e10cSrcweir                 break;
1593cdf0e10cSrcweir             case svMatrix:
1594cdf0e10cSrcweir                 {
1595cdf0e10cSrcweir                     ScMatrix* pMat = static_cast<ScToken*>(p)->GetMatrix();
1596cdf0e10cSrcweir                     if ( pMat )
1597cdf0e10cSrcweir                         pMat->SetErrorInterpreter( this);
1598cdf0e10cSrcweir                     else
1599cdf0e10cSrcweir                         SetError( errUnknownVariable);
1600cdf0e10cSrcweir                     return pMat;
1601cdf0e10cSrcweir                 }
1602cdf0e10cSrcweir             default:
1603cdf0e10cSrcweir                 SetError( errIllegalParameter);
1604cdf0e10cSrcweir         }
1605cdf0e10cSrcweir     }
1606cdf0e10cSrcweir     else
1607cdf0e10cSrcweir         SetError( errUnknownStackVariable);
1608cdf0e10cSrcweir     return NULL;
1609cdf0e10cSrcweir }
1610cdf0e10cSrcweir 
1611cdf0e10cSrcweir 
PushDouble(double nVal)1612cdf0e10cSrcweir void ScInterpreter::PushDouble(double nVal)
1613cdf0e10cSrcweir {
1614cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushDouble" );
1615cdf0e10cSrcweir     TreatDoubleError( nVal );
1616cdf0e10cSrcweir     if (!IfErrorPushError())
1617cdf0e10cSrcweir         PushTempTokenWithoutError( new FormulaDoubleToken( nVal ) );
1618cdf0e10cSrcweir }
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir 
PushInt(int nVal)1621cdf0e10cSrcweir void ScInterpreter::PushInt(int nVal)
1622cdf0e10cSrcweir {
1623cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushInt" );
1624cdf0e10cSrcweir     if (!IfErrorPushError())
1625cdf0e10cSrcweir         PushTempTokenWithoutError( new FormulaDoubleToken( nVal ) );
1626cdf0e10cSrcweir }
1627cdf0e10cSrcweir 
1628cdf0e10cSrcweir 
PushStringBuffer(const sal_Unicode * pString)1629cdf0e10cSrcweir void ScInterpreter::PushStringBuffer( const sal_Unicode* pString )
1630cdf0e10cSrcweir {
1631cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushStringBuffer" );
1632cdf0e10cSrcweir     if ( pString )
1633cdf0e10cSrcweir         PushString( String( pString ) );
1634cdf0e10cSrcweir     else
1635cdf0e10cSrcweir         PushString( EMPTY_STRING );
1636cdf0e10cSrcweir }
1637cdf0e10cSrcweir 
1638cdf0e10cSrcweir 
PushString(const String & rString)1639cdf0e10cSrcweir void ScInterpreter::PushString( const String& rString )
1640cdf0e10cSrcweir {
1641cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushString" );
1642cdf0e10cSrcweir     if (!IfErrorPushError())
1643cdf0e10cSrcweir         PushTempTokenWithoutError( new FormulaStringToken( rString ) );
1644cdf0e10cSrcweir }
1645cdf0e10cSrcweir 
1646cdf0e10cSrcweir 
PushSingleRef(SCCOL nCol,SCROW nRow,SCTAB nTab)1647cdf0e10cSrcweir void ScInterpreter::PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab)
1648cdf0e10cSrcweir {
1649cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushSingleRef" );
1650cdf0e10cSrcweir     if (!IfErrorPushError())
1651cdf0e10cSrcweir     {
1652cdf0e10cSrcweir         ScSingleRefData aRef;
1653cdf0e10cSrcweir         aRef.InitFlags();
1654cdf0e10cSrcweir         aRef.nCol = nCol;
1655cdf0e10cSrcweir         aRef.nRow = nRow;
1656cdf0e10cSrcweir         aRef.nTab = nTab;
1657cdf0e10cSrcweir         PushTempTokenWithoutError( new ScSingleRefToken( aRef ) );
1658cdf0e10cSrcweir     }
1659cdf0e10cSrcweir }
1660cdf0e10cSrcweir 
1661cdf0e10cSrcweir 
PushDoubleRef(SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2)1662cdf0e10cSrcweir void ScInterpreter::PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1663cdf0e10cSrcweir                                   SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
1664cdf0e10cSrcweir {
1665cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushDoubleRef" );
1666cdf0e10cSrcweir     if (!IfErrorPushError())
1667cdf0e10cSrcweir     {
1668cdf0e10cSrcweir         ScComplexRefData aRef;
1669cdf0e10cSrcweir         aRef.InitFlags();
1670cdf0e10cSrcweir         aRef.Ref1.nCol = nCol1;
1671cdf0e10cSrcweir         aRef.Ref1.nRow = nRow1;
1672cdf0e10cSrcweir         aRef.Ref1.nTab = nTab1;
1673cdf0e10cSrcweir         aRef.Ref2.nCol = nCol2;
1674cdf0e10cSrcweir         aRef.Ref2.nRow = nRow2;
1675cdf0e10cSrcweir         aRef.Ref2.nTab = nTab2;
1676cdf0e10cSrcweir         PushTempTokenWithoutError( new ScDoubleRefToken( aRef ) );
1677cdf0e10cSrcweir     }
1678cdf0e10cSrcweir }
1679cdf0e10cSrcweir 
1680cdf0e10cSrcweir 
PushMatrix(ScMatrix * pMat)1681cdf0e10cSrcweir void ScInterpreter::PushMatrix(ScMatrix* pMat)
1682cdf0e10cSrcweir {
1683cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushMatrix" );
1684cdf0e10cSrcweir     pMat->SetErrorInterpreter( NULL);
1685cdf0e10cSrcweir     // No   if (!IfErrorPushError())   because ScMatrix stores errors itself,
1686cdf0e10cSrcweir     // but with notifying ScInterpreter via nGlobalError, substituting it would
1687cdf0e10cSrcweir     // mean to inherit the error on all array elements in all following
1688cdf0e10cSrcweir     // operations.
1689cdf0e10cSrcweir     nGlobalError = 0;
1690cdf0e10cSrcweir     PushTempTokenWithoutError( new ScMatrixToken( pMat ) );
1691cdf0e10cSrcweir }
1692cdf0e10cSrcweir 
1693cdf0e10cSrcweir 
PushError(sal_uInt16 nError)1694cdf0e10cSrcweir void ScInterpreter::PushError( sal_uInt16 nError )
1695cdf0e10cSrcweir {
1696cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushError" );
1697cdf0e10cSrcweir     SetError( nError );     // only sets error if not already set
1698cdf0e10cSrcweir     PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError));
1699cdf0e10cSrcweir }
1700cdf0e10cSrcweir 
PushParameterExpected()1701cdf0e10cSrcweir void ScInterpreter::PushParameterExpected()
1702cdf0e10cSrcweir {
1703cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushParameterExpected" );
1704cdf0e10cSrcweir     PushError( errParameterExpected);
1705cdf0e10cSrcweir }
1706cdf0e10cSrcweir 
1707cdf0e10cSrcweir 
PushIllegalParameter()1708cdf0e10cSrcweir void ScInterpreter::PushIllegalParameter()
1709cdf0e10cSrcweir {
1710cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushIllegalParameter" );
1711cdf0e10cSrcweir     PushError( errIllegalParameter);
1712cdf0e10cSrcweir }
1713cdf0e10cSrcweir 
1714cdf0e10cSrcweir 
PushIllegalArgument()1715cdf0e10cSrcweir void ScInterpreter::PushIllegalArgument()
1716cdf0e10cSrcweir {
1717cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushIllegalArgument" );
1718cdf0e10cSrcweir     PushError( errIllegalArgument);
1719cdf0e10cSrcweir }
1720cdf0e10cSrcweir 
1721cdf0e10cSrcweir 
PushNA()1722cdf0e10cSrcweir void ScInterpreter::PushNA()
1723cdf0e10cSrcweir {
1724cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushNA" );
1725cdf0e10cSrcweir     PushError( NOTAVAILABLE);
1726cdf0e10cSrcweir }
1727cdf0e10cSrcweir 
1728cdf0e10cSrcweir 
PushNoValue()1729cdf0e10cSrcweir void ScInterpreter::PushNoValue()
1730cdf0e10cSrcweir {
1731cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushNoValue" );
1732cdf0e10cSrcweir     PushError( errNoValue);
1733cdf0e10cSrcweir }
1734cdf0e10cSrcweir 
1735cdf0e10cSrcweir 
IsMissing()1736cdf0e10cSrcweir sal_Bool ScInterpreter::IsMissing()
1737cdf0e10cSrcweir {
1738cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsMissing" );
1739cdf0e10cSrcweir     return sp && pStack[sp - 1]->GetType() == svMissing;
1740cdf0e10cSrcweir }
1741cdf0e10cSrcweir 
1742cdf0e10cSrcweir 
GetRawStackType()1743cdf0e10cSrcweir StackVar ScInterpreter::GetRawStackType()
1744cdf0e10cSrcweir {
1745cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetRawStackType" );
1746cdf0e10cSrcweir     StackVar eRes;
1747cdf0e10cSrcweir     if( sp )
1748cdf0e10cSrcweir     {
1749cdf0e10cSrcweir         eRes = pStack[sp - 1]->GetType();
1750cdf0e10cSrcweir     }
1751cdf0e10cSrcweir     else
1752cdf0e10cSrcweir     {
1753cdf0e10cSrcweir         SetError(errUnknownStackVariable);
1754cdf0e10cSrcweir         eRes = svUnknown;
1755cdf0e10cSrcweir     }
1756cdf0e10cSrcweir     return eRes;
1757cdf0e10cSrcweir }
1758cdf0e10cSrcweir 
1759cdf0e10cSrcweir 
GetStackType()1760cdf0e10cSrcweir StackVar ScInterpreter::GetStackType()
1761cdf0e10cSrcweir {
1762cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStackType" );
1763cdf0e10cSrcweir     StackVar eRes;
1764cdf0e10cSrcweir     if( sp )
1765cdf0e10cSrcweir     {
1766cdf0e10cSrcweir         eRes = pStack[sp - 1]->GetType();
1767cdf0e10cSrcweir         if( eRes == svMissing || eRes == svEmptyCell )
1768cdf0e10cSrcweir             eRes = svDouble;    // default!
1769cdf0e10cSrcweir     }
1770cdf0e10cSrcweir     else
1771cdf0e10cSrcweir     {
1772cdf0e10cSrcweir         SetError(errUnknownStackVariable);
1773cdf0e10cSrcweir         eRes = svUnknown;
1774cdf0e10cSrcweir     }
1775cdf0e10cSrcweir     return eRes;
1776cdf0e10cSrcweir }
1777cdf0e10cSrcweir 
1778cdf0e10cSrcweir 
GetStackType(sal_uInt8 nParam)1779cdf0e10cSrcweir StackVar ScInterpreter::GetStackType( sal_uInt8 nParam )
1780cdf0e10cSrcweir {
1781cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStackType" );
1782cdf0e10cSrcweir     StackVar eRes;
1783cdf0e10cSrcweir     if( sp > nParam-1 )
1784cdf0e10cSrcweir     {
1785cdf0e10cSrcweir         eRes = pStack[sp - nParam]->GetType();
1786cdf0e10cSrcweir         if( eRes == svMissing || eRes == svEmptyCell )
1787cdf0e10cSrcweir             eRes = svDouble;    // default!
1788cdf0e10cSrcweir     }
1789cdf0e10cSrcweir     else
1790cdf0e10cSrcweir         eRes = svUnknown;
1791cdf0e10cSrcweir     return eRes;
1792cdf0e10cSrcweir }
1793cdf0e10cSrcweir 
1794cdf0e10cSrcweir 
DoubleRefToPosSingleRef(const ScRange & rRange,ScAddress & rAdr)1795cdf0e10cSrcweir sal_Bool ScInterpreter::DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr )
1796cdf0e10cSrcweir {
1797cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToPosSingleRef" );
1798cdf0e10cSrcweir     // Check for a singleton first - no implicit intersection for them.
1799cdf0e10cSrcweir     if( rRange.aStart == rRange.aEnd )
1800cdf0e10cSrcweir     {
1801cdf0e10cSrcweir         rAdr = rRange.aStart;
1802cdf0e10cSrcweir         return sal_True;
1803cdf0e10cSrcweir     }
1804cdf0e10cSrcweir 
1805cdf0e10cSrcweir     sal_Bool bOk = sal_False;
1806cdf0e10cSrcweir 
1807cdf0e10cSrcweir     if ( pJumpMatrix )
1808cdf0e10cSrcweir     {
1809cdf0e10cSrcweir         bOk = rRange.aStart.Tab() == rRange.aEnd.Tab();
1810cdf0e10cSrcweir         if ( !bOk )
1811cdf0e10cSrcweir             SetError( errIllegalArgument);
1812cdf0e10cSrcweir         else
1813cdf0e10cSrcweir         {
1814cdf0e10cSrcweir             SCSIZE nC, nR;
1815cdf0e10cSrcweir             pJumpMatrix->GetPos( nC, nR);
1816cdf0e10cSrcweir             rAdr.SetCol( sal::static_int_cast<SCCOL>( rRange.aStart.Col() + nC ) );
1817cdf0e10cSrcweir             rAdr.SetRow( sal::static_int_cast<SCROW>( rRange.aStart.Row() + nR ) );
1818cdf0e10cSrcweir             rAdr.SetTab( rRange.aStart.Tab());
1819cdf0e10cSrcweir             bOk = rRange.aStart.Col() <= rAdr.Col() && rAdr.Col() <=
1820cdf0e10cSrcweir                 rRange.aEnd.Col() && rRange.aStart.Row() <= rAdr.Row() &&
1821cdf0e10cSrcweir                 rAdr.Row() <= rRange.aEnd.Row();
1822cdf0e10cSrcweir             if ( !bOk )
1823cdf0e10cSrcweir                 SetError( errNoValue);
1824cdf0e10cSrcweir         }
1825cdf0e10cSrcweir         return bOk;
1826cdf0e10cSrcweir     }
1827cdf0e10cSrcweir 
1828cdf0e10cSrcweir     SCCOL nMyCol = aPos.Col();
1829cdf0e10cSrcweir     SCROW nMyRow = aPos.Row();
1830cdf0e10cSrcweir     SCTAB nMyTab = aPos.Tab();
1831cdf0e10cSrcweir     SCCOL nCol = 0;
1832cdf0e10cSrcweir     SCROW nRow = 0;
1833cdf0e10cSrcweir     SCTAB nTab;
1834cdf0e10cSrcweir     nTab = rRange.aStart.Tab();
1835cdf0e10cSrcweir     if ( rRange.aStart.Col() <= nMyCol && nMyCol <= rRange.aEnd.Col() )
1836cdf0e10cSrcweir     {
1837cdf0e10cSrcweir         nRow = rRange.aStart.Row();
1838cdf0e10cSrcweir         if ( nRow == rRange.aEnd.Row() )
1839cdf0e10cSrcweir         {
1840cdf0e10cSrcweir             bOk = sal_True;
1841cdf0e10cSrcweir             nCol = nMyCol;
1842cdf0e10cSrcweir         }
1843cdf0e10cSrcweir         else if ( nTab != nMyTab && nTab == rRange.aEnd.Tab()
1844cdf0e10cSrcweir                 && rRange.aStart.Row() <= nMyRow && nMyRow <= rRange.aEnd.Row() )
1845cdf0e10cSrcweir         {
1846cdf0e10cSrcweir             bOk = sal_True;
1847cdf0e10cSrcweir             nCol = nMyCol;
1848cdf0e10cSrcweir             nRow = nMyRow;
1849cdf0e10cSrcweir         }
1850cdf0e10cSrcweir     }
1851cdf0e10cSrcweir     else if ( rRange.aStart.Row() <= nMyRow && nMyRow <= rRange.aEnd.Row() )
1852cdf0e10cSrcweir     {
1853cdf0e10cSrcweir         nCol = rRange.aStart.Col();
1854cdf0e10cSrcweir         if ( nCol == rRange.aEnd.Col() )
1855cdf0e10cSrcweir         {
1856cdf0e10cSrcweir             bOk = sal_True;
1857cdf0e10cSrcweir             nRow = nMyRow;
1858cdf0e10cSrcweir         }
1859cdf0e10cSrcweir         else if ( nTab != nMyTab && nTab == rRange.aEnd.Tab()
1860cdf0e10cSrcweir                 && rRange.aStart.Col() <= nMyCol && nMyCol <= rRange.aEnd.Col() )
1861cdf0e10cSrcweir         {
1862cdf0e10cSrcweir             bOk = sal_True;
1863cdf0e10cSrcweir             nCol = nMyCol;
1864cdf0e10cSrcweir             nRow = nMyRow;
1865cdf0e10cSrcweir         }
1866cdf0e10cSrcweir     }
1867cdf0e10cSrcweir     if ( bOk )
1868cdf0e10cSrcweir     {
1869cdf0e10cSrcweir         if ( nTab == rRange.aEnd.Tab() )
1870cdf0e10cSrcweir             ;   // all done
1871cdf0e10cSrcweir         else if ( nTab <= nMyTab && nMyTab <= rRange.aEnd.Tab() )
1872cdf0e10cSrcweir             nTab = nMyTab;
1873cdf0e10cSrcweir         else
1874cdf0e10cSrcweir             bOk = sal_False;
1875cdf0e10cSrcweir         if ( bOk )
1876cdf0e10cSrcweir             rAdr.Set( nCol, nRow, nTab );
1877cdf0e10cSrcweir     }
1878cdf0e10cSrcweir     if ( !bOk )
1879cdf0e10cSrcweir         SetError( errNoValue );
1880cdf0e10cSrcweir     return bOk;
1881cdf0e10cSrcweir }
1882cdf0e10cSrcweir 
1883cdf0e10cSrcweir 
GetDouble()1884cdf0e10cSrcweir double ScInterpreter::GetDouble()
1885cdf0e10cSrcweir {
1886cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDouble" );
1887cdf0e10cSrcweir     double nVal;
1888cdf0e10cSrcweir     switch( GetRawStackType() )
1889cdf0e10cSrcweir     {
1890cdf0e10cSrcweir         case svDouble:
1891cdf0e10cSrcweir             nVal = PopDouble();
1892cdf0e10cSrcweir         break;
1893cdf0e10cSrcweir         case svString:
1894cdf0e10cSrcweir             nVal = ConvertStringToValue( PopString());
1895cdf0e10cSrcweir         break;
1896cdf0e10cSrcweir         case svSingleRef:
1897cdf0e10cSrcweir         {
1898cdf0e10cSrcweir             ScAddress aAdr;
1899cdf0e10cSrcweir             PopSingleRef( aAdr );
1900cdf0e10cSrcweir             ScBaseCell* pCell = GetCell( aAdr );
1901cdf0e10cSrcweir             nVal = GetCellValue( aAdr, pCell );
1902cdf0e10cSrcweir         }
1903cdf0e10cSrcweir         break;
1904cdf0e10cSrcweir         case svDoubleRef:
1905cdf0e10cSrcweir         {   // generate position dependent SingleRef
1906cdf0e10cSrcweir             ScRange aRange;
1907cdf0e10cSrcweir             PopDoubleRef( aRange );
1908cdf0e10cSrcweir             ScAddress aAdr;
1909cdf0e10cSrcweir             if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr ) )
1910cdf0e10cSrcweir             {
1911cdf0e10cSrcweir                 ScBaseCell* pCell = GetCell( aAdr );
1912cdf0e10cSrcweir                 nVal = GetCellValue( aAdr, pCell );
1913cdf0e10cSrcweir             }
1914cdf0e10cSrcweir             else
1915cdf0e10cSrcweir                 nVal = 0.0;
1916cdf0e10cSrcweir         }
1917cdf0e10cSrcweir         break;
1918cdf0e10cSrcweir         case svMatrix:
1919cdf0e10cSrcweir         {
1920cdf0e10cSrcweir             ScMatrixRef pMat = PopMatrix();
1921cdf0e10cSrcweir             if ( !pMat )
1922cdf0e10cSrcweir                 nVal = 0.0;
1923cdf0e10cSrcweir             else if ( !pJumpMatrix )
1924cdf0e10cSrcweir                 nVal = pMat->GetDouble( 0 );
1925cdf0e10cSrcweir             else
1926cdf0e10cSrcweir             {
1927cdf0e10cSrcweir                 SCSIZE nCols, nRows, nC, nR;
1928cdf0e10cSrcweir                 pMat->GetDimensions( nCols, nRows);
1929cdf0e10cSrcweir                 pJumpMatrix->GetPos( nC, nR);
1930cdf0e10cSrcweir                 if ( nC < nCols && nR < nRows )
1931cdf0e10cSrcweir                     nVal = pMat->GetDouble( nC, nR);
1932cdf0e10cSrcweir                 else
1933cdf0e10cSrcweir                 {
1934cdf0e10cSrcweir                     SetError( errNoValue);
1935cdf0e10cSrcweir                     nVal = 0.0;
1936cdf0e10cSrcweir                 }
1937cdf0e10cSrcweir             }
1938cdf0e10cSrcweir         }
1939cdf0e10cSrcweir         break;
1940cdf0e10cSrcweir         case svError:
1941cdf0e10cSrcweir             PopError();
1942cdf0e10cSrcweir             nVal = 0.0;
1943cdf0e10cSrcweir         break;
1944cdf0e10cSrcweir         case svEmptyCell:
1945cdf0e10cSrcweir         case svMissing:
1946cdf0e10cSrcweir             Pop();
1947cdf0e10cSrcweir             nVal = 0.0;
1948cdf0e10cSrcweir         break;
1949cdf0e10cSrcweir         default:
1950cdf0e10cSrcweir             PopError();
1951cdf0e10cSrcweir             SetError( errIllegalParameter);
1952cdf0e10cSrcweir             nVal = 0.0;
1953cdf0e10cSrcweir     }
1954cdf0e10cSrcweir     if ( nFuncFmtType == nCurFmtType )
1955cdf0e10cSrcweir         nFuncFmtIndex = nCurFmtIndex;
1956cdf0e10cSrcweir     return nVal;
1957cdf0e10cSrcweir }
1958cdf0e10cSrcweir 
1959cdf0e10cSrcweir 
GetDoubleWithDefault(double nDefault)1960cdf0e10cSrcweir double ScInterpreter::GetDoubleWithDefault(double nDefault)
1961cdf0e10cSrcweir {
1962cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDoubleWithDefault" );
1963cdf0e10cSrcweir     bool bMissing = IsMissing();
1964cdf0e10cSrcweir     double nResultVal = GetDouble();
1965cdf0e10cSrcweir     if ( bMissing )
1966cdf0e10cSrcweir         nResultVal = nDefault;
1967cdf0e10cSrcweir     return nResultVal;
1968cdf0e10cSrcweir }
1969cdf0e10cSrcweir 
1970cdf0e10cSrcweir 
GetString()1971cdf0e10cSrcweir const String& ScInterpreter::GetString()
1972cdf0e10cSrcweir {
1973cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetString" );
1974cdf0e10cSrcweir     switch (GetRawStackType())
1975cdf0e10cSrcweir     {
1976cdf0e10cSrcweir         case svError:
1977cdf0e10cSrcweir             PopError();
1978cdf0e10cSrcweir             return EMPTY_STRING;
1979cdf0e10cSrcweir         //break;
1980cdf0e10cSrcweir         case svMissing:
1981cdf0e10cSrcweir         case svEmptyCell:
1982cdf0e10cSrcweir             Pop();
1983cdf0e10cSrcweir             return EMPTY_STRING;
1984cdf0e10cSrcweir         //break;
1985cdf0e10cSrcweir         case svDouble:
1986cdf0e10cSrcweir         {
1987cdf0e10cSrcweir             double fVal = PopDouble();
1988cdf0e10cSrcweir             sal_uLong nIndex = pFormatter->GetStandardFormat(
1989cdf0e10cSrcweir                                     NUMBERFORMAT_NUMBER,
1990cdf0e10cSrcweir                                     ScGlobal::eLnge);
1991cdf0e10cSrcweir             pFormatter->GetInputLineString(fVal, nIndex, aTempStr);
1992cdf0e10cSrcweir             return aTempStr;
1993cdf0e10cSrcweir         }
1994cdf0e10cSrcweir         //break;
1995cdf0e10cSrcweir         case svString:
1996cdf0e10cSrcweir             return PopString();
1997cdf0e10cSrcweir         //break;
1998cdf0e10cSrcweir         case svSingleRef:
1999cdf0e10cSrcweir         {
2000cdf0e10cSrcweir             ScAddress aAdr;
2001cdf0e10cSrcweir             PopSingleRef( aAdr );
2002cdf0e10cSrcweir             if (nGlobalError == 0)
2003cdf0e10cSrcweir             {
2004cdf0e10cSrcweir                 ScBaseCell* pCell = GetCell( aAdr );
2005cdf0e10cSrcweir                 GetCellString( aTempStr, pCell );
2006cdf0e10cSrcweir                 return aTempStr;
2007cdf0e10cSrcweir             }
2008cdf0e10cSrcweir             else
2009cdf0e10cSrcweir                 return EMPTY_STRING;
2010cdf0e10cSrcweir         }
2011cdf0e10cSrcweir         //break;
2012cdf0e10cSrcweir         case svDoubleRef:
2013cdf0e10cSrcweir         {   // generate position dependent SingleRef
2014cdf0e10cSrcweir             ScRange aRange;
2015cdf0e10cSrcweir             PopDoubleRef( aRange );
2016cdf0e10cSrcweir             ScAddress aAdr;
2017cdf0e10cSrcweir             if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr ) )
2018cdf0e10cSrcweir             {
2019cdf0e10cSrcweir                 ScBaseCell* pCell = GetCell( aAdr );
2020cdf0e10cSrcweir                 GetCellString( aTempStr, pCell );
2021cdf0e10cSrcweir                 return aTempStr;
2022cdf0e10cSrcweir             }
2023cdf0e10cSrcweir             else
2024cdf0e10cSrcweir                 return EMPTY_STRING;
2025cdf0e10cSrcweir         }
2026cdf0e10cSrcweir         //break;
2027cdf0e10cSrcweir         case svMatrix:
2028cdf0e10cSrcweir         {
2029cdf0e10cSrcweir             ScMatrixRef pMat = PopMatrix();
2030cdf0e10cSrcweir             if ( !pMat )
2031cdf0e10cSrcweir                 ;   // nothing
2032cdf0e10cSrcweir             else if ( !pJumpMatrix )
2033cdf0e10cSrcweir             {
2034cdf0e10cSrcweir                 aTempStr = pMat->GetString( *pFormatter, 0, 0);
2035cdf0e10cSrcweir                 return aTempStr;
2036cdf0e10cSrcweir             }
2037cdf0e10cSrcweir             else
2038cdf0e10cSrcweir             {
2039cdf0e10cSrcweir                 SCSIZE nCols, nRows, nC, nR;
2040cdf0e10cSrcweir                 pMat->GetDimensions( nCols, nRows);
2041cdf0e10cSrcweir                 pJumpMatrix->GetPos( nC, nR);
2042cdf0e10cSrcweir                 if ( nC < nCols && nR < nRows )
2043cdf0e10cSrcweir                 {
2044cdf0e10cSrcweir                     aTempStr = pMat->GetString( *pFormatter, nC, nR);
2045cdf0e10cSrcweir                     return aTempStr;
2046cdf0e10cSrcweir                 }
2047cdf0e10cSrcweir                 else
2048cdf0e10cSrcweir                     SetError( errNoValue);
2049cdf0e10cSrcweir             }
2050cdf0e10cSrcweir         }
2051cdf0e10cSrcweir         break;
2052cdf0e10cSrcweir         default:
2053cdf0e10cSrcweir             PopError();
2054cdf0e10cSrcweir             SetError( errIllegalArgument);
2055cdf0e10cSrcweir     }
2056cdf0e10cSrcweir     return EMPTY_STRING;
2057cdf0e10cSrcweir }
2058cdf0e10cSrcweir 
2059cdf0e10cSrcweir 
2060cdf0e10cSrcweir 
GetDoubleOrStringFromMatrix(double & rDouble,String & rString)2061cdf0e10cSrcweir ScMatValType ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble,
2062cdf0e10cSrcweir         String& rString )
2063cdf0e10cSrcweir {
2064cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDoubleOrStringFromMatrix" );
2065cdf0e10cSrcweir     ScMatValType nMatValType = SC_MATVAL_EMPTY;
2066cdf0e10cSrcweir     switch ( GetStackType() )
2067cdf0e10cSrcweir     {
2068cdf0e10cSrcweir         case svMatrix:
2069cdf0e10cSrcweir             {
2070cdf0e10cSrcweir                 const ScMatrixValue* pMatVal = 0;
2071cdf0e10cSrcweir                 ScMatrixRef pMat = PopMatrix();
2072cdf0e10cSrcweir                 if (!pMat)
2073cdf0e10cSrcweir                     ;   // nothing
2074cdf0e10cSrcweir                 else if (!pJumpMatrix)
2075cdf0e10cSrcweir                     pMatVal = pMat->Get( 0, 0, nMatValType);
2076cdf0e10cSrcweir                 else
2077cdf0e10cSrcweir                 {
2078cdf0e10cSrcweir                     SCSIZE nCols, nRows, nC, nR;
2079cdf0e10cSrcweir                     pMat->GetDimensions( nCols, nRows);
2080cdf0e10cSrcweir                     pJumpMatrix->GetPos( nC, nR);
2081cdf0e10cSrcweir                     if ( nC < nCols && nR < nRows )
2082cdf0e10cSrcweir                         pMatVal = pMat->Get( nC, nR, nMatValType);
2083cdf0e10cSrcweir                     else
2084cdf0e10cSrcweir                         SetError( errNoValue);
2085cdf0e10cSrcweir                 }
2086cdf0e10cSrcweir                 if (!pMatVal)
2087cdf0e10cSrcweir                 {
2088cdf0e10cSrcweir                     rDouble = 0.0;
2089cdf0e10cSrcweir                     rString.Erase();
2090cdf0e10cSrcweir                 }
2091cdf0e10cSrcweir                 else if (nMatValType == SC_MATVAL_VALUE)
2092cdf0e10cSrcweir                     rDouble = pMatVal->fVal;
2093cdf0e10cSrcweir                 else if (nMatValType == SC_MATVAL_BOOLEAN)
2094cdf0e10cSrcweir                 {
2095cdf0e10cSrcweir                     rDouble = pMatVal->fVal;
2096cdf0e10cSrcweir                     nMatValType = SC_MATVAL_VALUE;
2097cdf0e10cSrcweir                 }
2098cdf0e10cSrcweir                 else
2099cdf0e10cSrcweir                     rString = pMatVal->GetString();
2100cdf0e10cSrcweir             }
2101cdf0e10cSrcweir             break;
2102cdf0e10cSrcweir         default:
2103cdf0e10cSrcweir             PopError();
2104cdf0e10cSrcweir             rDouble = 0.0;
2105cdf0e10cSrcweir             rString.Erase();
2106cdf0e10cSrcweir             SetError( errIllegalParameter);
2107cdf0e10cSrcweir     }
2108cdf0e10cSrcweir     return nMatValType;
2109cdf0e10cSrcweir }
2110cdf0e10cSrcweir 
2111cdf0e10cSrcweir 
ScDBGet()2112cdf0e10cSrcweir void ScInterpreter::ScDBGet()
2113cdf0e10cSrcweir {
2114cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBGet" );
2115cdf0e10cSrcweir     sal_Bool bMissingField = sal_False;
2116cdf0e10cSrcweir     auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
2117cdf0e10cSrcweir     if (!pQueryParam.get())
2118cdf0e10cSrcweir     {
2119cdf0e10cSrcweir         // Failed to create query param.
2120cdf0e10cSrcweir         PushIllegalParameter();
2121cdf0e10cSrcweir         return;
2122cdf0e10cSrcweir     }
2123cdf0e10cSrcweir 
2124cdf0e10cSrcweir     pQueryParam->mbSkipString = false;
2125cdf0e10cSrcweir     ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
2126cdf0e10cSrcweir     ScDBQueryDataIterator::Value aValue;
2127cdf0e10cSrcweir     if (!aValIter.GetFirst(aValue) || aValue.mnError)
2128cdf0e10cSrcweir     {
2129cdf0e10cSrcweir         // No match found.
2130cdf0e10cSrcweir         PushNoValue();
2131cdf0e10cSrcweir         return;
2132cdf0e10cSrcweir     }
2133cdf0e10cSrcweir 
2134cdf0e10cSrcweir     ScDBQueryDataIterator::Value aValNext;
2135cdf0e10cSrcweir     if (aValIter.GetNext(aValNext) && !aValNext.mnError)
2136cdf0e10cSrcweir     {
2137cdf0e10cSrcweir         // There should be only one unique match.
2138cdf0e10cSrcweir         PushIllegalArgument();
2139cdf0e10cSrcweir         return;
2140cdf0e10cSrcweir     }
2141cdf0e10cSrcweir 
2142cdf0e10cSrcweir     if (aValue.mbIsNumber)
2143cdf0e10cSrcweir         PushDouble(aValue.mfValue);
2144cdf0e10cSrcweir     else
2145cdf0e10cSrcweir         PushString(aValue.maString);
2146cdf0e10cSrcweir }
2147cdf0e10cSrcweir 
2148cdf0e10cSrcweir 
ScExternal()2149cdf0e10cSrcweir void ScInterpreter::ScExternal()
2150cdf0e10cSrcweir {
2151cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExternal" );
2152cdf0e10cSrcweir     sal_uInt16 nIndex;
2153cdf0e10cSrcweir     sal_uInt8 nParamCount = GetByte();
2154cdf0e10cSrcweir     String aUnoName;
2155cdf0e10cSrcweir     String aFuncName( ScGlobal::pCharClass->upper( pCur->GetExternal() ) );
2156cdf0e10cSrcweir     if (ScGlobal::GetFuncCollection()->SearchFunc(aFuncName, nIndex))
2157cdf0e10cSrcweir     {
2158cdf0e10cSrcweir         FuncData* pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex);
2159cdf0e10cSrcweir         if (nParamCount <= MAXFUNCPARAM && nParamCount == pFuncData->GetParamCount() - 1)
2160cdf0e10cSrcweir         {
2161cdf0e10cSrcweir             ParamType   eParamType[MAXFUNCPARAM];
2162cdf0e10cSrcweir             void*       ppParam[MAXFUNCPARAM];
2163cdf0e10cSrcweir             double      nVal[MAXFUNCPARAM];
2164cdf0e10cSrcweir             sal_Char*   pStr[MAXFUNCPARAM];
2165cdf0e10cSrcweir             sal_uInt8*       pCellArr[MAXFUNCPARAM];
2166cdf0e10cSrcweir             short       i;
2167cdf0e10cSrcweir 
2168cdf0e10cSrcweir             for (i = 0; i < MAXFUNCPARAM; i++)
2169cdf0e10cSrcweir             {
2170cdf0e10cSrcweir                 eParamType[i] = pFuncData->GetParamType(i);
2171cdf0e10cSrcweir                 ppParam[i] = NULL;
2172cdf0e10cSrcweir                 nVal[i] = 0.0;
2173cdf0e10cSrcweir                 pStr[i] = NULL;
2174cdf0e10cSrcweir                 pCellArr[i] = NULL;
2175cdf0e10cSrcweir             }
2176cdf0e10cSrcweir 
2177cdf0e10cSrcweir             for (i = nParamCount; (i > 0) && (nGlobalError == 0); i--)
2178cdf0e10cSrcweir             {
2179cdf0e10cSrcweir                 switch (eParamType[i])
2180cdf0e10cSrcweir                 {
2181cdf0e10cSrcweir                     case PTR_DOUBLE :
2182cdf0e10cSrcweir                         {
2183cdf0e10cSrcweir                             nVal[i-1] = GetDouble();
2184cdf0e10cSrcweir                             ppParam[i] = &nVal[i-1];
2185cdf0e10cSrcweir                         }
2186cdf0e10cSrcweir                         break;
2187cdf0e10cSrcweir                     case PTR_STRING :
2188cdf0e10cSrcweir                         {
2189cdf0e10cSrcweir                             ByteString aStr( GetString(), osl_getThreadTextEncoding() );
2190cdf0e10cSrcweir                             if ( aStr.Len() >= ADDIN_MAXSTRLEN )
2191cdf0e10cSrcweir                                 SetError( errStringOverflow );
2192cdf0e10cSrcweir                             else
2193cdf0e10cSrcweir                             {
2194cdf0e10cSrcweir                                 pStr[i-1] = new sal_Char[ADDIN_MAXSTRLEN];
2195cdf0e10cSrcweir                                 strncpy( pStr[i-1], aStr.GetBuffer(), ADDIN_MAXSTRLEN );
2196cdf0e10cSrcweir                                 pStr[i-1][ADDIN_MAXSTRLEN-1] = 0;
2197cdf0e10cSrcweir                                 ppParam[i] = pStr[i-1];
2198cdf0e10cSrcweir                             }
2199cdf0e10cSrcweir                         }
2200cdf0e10cSrcweir                         break;
2201cdf0e10cSrcweir                     case PTR_DOUBLE_ARR :
2202cdf0e10cSrcweir                         {
2203cdf0e10cSrcweir                             SCCOL nCol1;
2204cdf0e10cSrcweir                             SCROW nRow1;
2205cdf0e10cSrcweir                             SCTAB nTab1;
2206cdf0e10cSrcweir                             SCCOL nCol2;
2207cdf0e10cSrcweir                             SCROW nRow2;
2208cdf0e10cSrcweir                             SCTAB nTab2;
2209cdf0e10cSrcweir                             PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2210cdf0e10cSrcweir                             pCellArr[i-1] = new sal_uInt8[MAXARRSIZE];
2211cdf0e10cSrcweir                             if (!CreateDoubleArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
2212cdf0e10cSrcweir                                 SetError(errCodeOverflow);
2213cdf0e10cSrcweir                             else
2214cdf0e10cSrcweir                                 ppParam[i] = pCellArr[i-1];
2215cdf0e10cSrcweir                         }
2216cdf0e10cSrcweir                         break;
2217cdf0e10cSrcweir                     case PTR_STRING_ARR :
2218cdf0e10cSrcweir                         {
2219cdf0e10cSrcweir                             SCCOL nCol1;
2220cdf0e10cSrcweir                             SCROW nRow1;
2221cdf0e10cSrcweir                             SCTAB nTab1;
2222cdf0e10cSrcweir                             SCCOL nCol2;
2223cdf0e10cSrcweir                             SCROW nRow2;
2224cdf0e10cSrcweir                             SCTAB nTab2;
2225cdf0e10cSrcweir                             PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2226cdf0e10cSrcweir                             pCellArr[i-1] = new sal_uInt8[MAXARRSIZE];
2227cdf0e10cSrcweir                             if (!CreateStringArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
2228cdf0e10cSrcweir                                 SetError(errCodeOverflow);
2229cdf0e10cSrcweir                             else
2230cdf0e10cSrcweir                                 ppParam[i] = pCellArr[i-1];
2231cdf0e10cSrcweir                         }
2232cdf0e10cSrcweir                         break;
2233cdf0e10cSrcweir                     case PTR_CELL_ARR :
2234cdf0e10cSrcweir                         {
2235cdf0e10cSrcweir                             SCCOL nCol1;
2236cdf0e10cSrcweir                             SCROW nRow1;
2237cdf0e10cSrcweir                             SCTAB nTab1;
2238cdf0e10cSrcweir                             SCCOL nCol2;
2239cdf0e10cSrcweir                             SCROW nRow2;
2240cdf0e10cSrcweir                             SCTAB nTab2;
2241cdf0e10cSrcweir                             PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2242cdf0e10cSrcweir                             pCellArr[i-1] = new sal_uInt8[MAXARRSIZE];
2243cdf0e10cSrcweir                             if (!CreateCellArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
2244cdf0e10cSrcweir                                 SetError(errCodeOverflow);
2245cdf0e10cSrcweir                             else
2246cdf0e10cSrcweir                                 ppParam[i] = pCellArr[i-1];
2247cdf0e10cSrcweir                         }
2248cdf0e10cSrcweir                         break;
2249cdf0e10cSrcweir                     default :
2250cdf0e10cSrcweir                         SetError(errIllegalParameter);
2251cdf0e10cSrcweir                         break;
2252cdf0e10cSrcweir                 }
2253cdf0e10cSrcweir             }
2254cdf0e10cSrcweir             while ( i-- )
2255cdf0e10cSrcweir                 Pop();      // im Fehlerfall (sonst ist i==0) Parameter wegpoppen
2256cdf0e10cSrcweir 
2257cdf0e10cSrcweir             if (nGlobalError == 0)
2258cdf0e10cSrcweir             {
2259cdf0e10cSrcweir                 if ( pFuncData->GetAsyncType() == NONE )
2260cdf0e10cSrcweir                 {
2261cdf0e10cSrcweir                     switch ( eParamType[0] )
2262cdf0e10cSrcweir                     {
2263cdf0e10cSrcweir                         case PTR_DOUBLE :
2264cdf0e10cSrcweir                         {
2265cdf0e10cSrcweir                             double nErg = 0.0;
2266cdf0e10cSrcweir                             ppParam[0] = &nErg;
2267cdf0e10cSrcweir                             pFuncData->Call(ppParam);
2268cdf0e10cSrcweir                             PushDouble(nErg);
2269cdf0e10cSrcweir                         }
2270cdf0e10cSrcweir                         break;
2271cdf0e10cSrcweir                         case PTR_STRING :
2272cdf0e10cSrcweir                         {
2273cdf0e10cSrcweir                             sal_Char* pcErg = new sal_Char[ADDIN_MAXSTRLEN];
2274cdf0e10cSrcweir                             ppParam[0] = pcErg;
2275cdf0e10cSrcweir                             pFuncData->Call(ppParam);
2276cdf0e10cSrcweir                             String aUni( pcErg, osl_getThreadTextEncoding() );
2277cdf0e10cSrcweir                             PushString( aUni );
2278cdf0e10cSrcweir                             delete[] pcErg;
2279cdf0e10cSrcweir                         }
2280cdf0e10cSrcweir                         break;
2281cdf0e10cSrcweir                         default:
2282cdf0e10cSrcweir                             PushError( errUnknownState );
2283cdf0e10cSrcweir                     }
2284cdf0e10cSrcweir                 }
2285cdf0e10cSrcweir                 else
2286cdf0e10cSrcweir                 {
2287cdf0e10cSrcweir                     // nach dem Laden Asyncs wieder anwerfen
2288cdf0e10cSrcweir                     if ( pMyFormulaCell->GetCode()->IsRecalcModeNormal() )
2289cdf0e10cSrcweir                         pMyFormulaCell->GetCode()->SetRecalcModeOnLoad();
2290cdf0e10cSrcweir                     // garantiert identischer Handle bei identischem Aufruf?!?
2291cdf0e10cSrcweir                     // sonst schei*e ...
2292cdf0e10cSrcweir                     double nErg = 0.0;
2293cdf0e10cSrcweir                     ppParam[0] = &nErg;
2294cdf0e10cSrcweir                     pFuncData->Call(ppParam);
2295cdf0e10cSrcweir                     sal_uLong nHandle = sal_uLong( nErg );
2296cdf0e10cSrcweir                     if ( nHandle >= 65536 )
2297cdf0e10cSrcweir                     {
2298cdf0e10cSrcweir                         ScAddInAsync* pAs = ScAddInAsync::Get( nHandle );
2299cdf0e10cSrcweir                         if ( !pAs )
2300cdf0e10cSrcweir                         {
2301cdf0e10cSrcweir                             pAs = new ScAddInAsync( nHandle, nIndex, pDok );
2302cdf0e10cSrcweir                             pMyFormulaCell->StartListening( *pAs );
2303cdf0e10cSrcweir                         }
2304cdf0e10cSrcweir                         else
2305cdf0e10cSrcweir                         {
2306cdf0e10cSrcweir                             // falls per cut/copy/paste
2307cdf0e10cSrcweir                             pMyFormulaCell->StartListening( *pAs );
2308cdf0e10cSrcweir                             // in anderes Dokument?
2309cdf0e10cSrcweir                             if ( !pAs->HasDocument( pDok ) )
2310cdf0e10cSrcweir                                 pAs->AddDocument( pDok );
2311cdf0e10cSrcweir                         }
2312cdf0e10cSrcweir                         if ( pAs->IsValid() )
2313cdf0e10cSrcweir                         {
2314cdf0e10cSrcweir                             switch ( pAs->GetType() )
2315cdf0e10cSrcweir                             {
2316cdf0e10cSrcweir                                 case PTR_DOUBLE :
2317cdf0e10cSrcweir                                     PushDouble( pAs->GetValue() );
2318cdf0e10cSrcweir                                     break;
2319cdf0e10cSrcweir                                 case PTR_STRING :
2320cdf0e10cSrcweir                                     PushString( pAs->GetString() );
2321cdf0e10cSrcweir                                     break;
2322cdf0e10cSrcweir                                 default:
2323cdf0e10cSrcweir                                     PushError( errUnknownState );
2324cdf0e10cSrcweir                             }
2325cdf0e10cSrcweir                         }
2326cdf0e10cSrcweir                         else
2327cdf0e10cSrcweir                             PushNA();
2328cdf0e10cSrcweir                     }
2329cdf0e10cSrcweir                     else
2330cdf0e10cSrcweir                         PushNoValue();
2331cdf0e10cSrcweir                 }
2332cdf0e10cSrcweir             }
2333cdf0e10cSrcweir 
2334cdf0e10cSrcweir             for (i = 0; i < MAXFUNCPARAM; i++)
2335cdf0e10cSrcweir             {
2336cdf0e10cSrcweir                 delete[] pStr[i];
2337cdf0e10cSrcweir                 delete[] pCellArr[i];
2338cdf0e10cSrcweir             }
2339cdf0e10cSrcweir         }
2340cdf0e10cSrcweir         else
2341cdf0e10cSrcweir         {
2342cdf0e10cSrcweir             while( nParamCount-- > 0)
2343cdf0e10cSrcweir                 Pop();
2344cdf0e10cSrcweir             PushIllegalParameter();
2345cdf0e10cSrcweir         }
2346cdf0e10cSrcweir     }
2347cdf0e10cSrcweir     else if ( ( aUnoName = ScGlobal::GetAddInCollection()->FindFunction(aFuncName, sal_False) ).Len()  )
2348cdf0e10cSrcweir     {
2349cdf0e10cSrcweir         //  bLocalFirst=sal_False in FindFunction, cFunc should be the stored internal name
2350cdf0e10cSrcweir 
2351cdf0e10cSrcweir         ScUnoAddInCall aCall( *ScGlobal::GetAddInCollection(), aUnoName, nParamCount );
2352cdf0e10cSrcweir 
2353cdf0e10cSrcweir         if ( !aCall.ValidParamCount() )
2354cdf0e10cSrcweir             SetError( errIllegalParameter );
2355cdf0e10cSrcweir 
2356cdf0e10cSrcweir         if ( aCall.NeedsCaller() && !GetError() )
2357cdf0e10cSrcweir         {
2358cdf0e10cSrcweir             SfxObjectShell* pShell = pDok->GetDocumentShell();
2359cdf0e10cSrcweir             if (pShell)
2360cdf0e10cSrcweir                 aCall.SetCallerFromObjectShell( pShell );
2361cdf0e10cSrcweir             else
2362cdf0e10cSrcweir             {
2363cdf0e10cSrcweir                 // use temporary model object (without document) to supply options
2364cdf0e10cSrcweir                 aCall.SetCaller( static_cast<beans::XPropertySet*>(
2365cdf0e10cSrcweir                                     new ScDocOptionsObj( pDok->GetDocOptions() ) ) );
2366cdf0e10cSrcweir             }
2367cdf0e10cSrcweir         }
2368cdf0e10cSrcweir 
2369cdf0e10cSrcweir         short nPar = nParamCount;
2370cdf0e10cSrcweir         while ( nPar > 0 && !GetError() )
2371cdf0e10cSrcweir         {
2372cdf0e10cSrcweir             --nPar;     // 0 .. (nParamCount-1)
2373cdf0e10cSrcweir 
2374cdf0e10cSrcweir             ScAddInArgumentType eType = aCall.GetArgType( nPar );
2375cdf0e10cSrcweir             sal_uInt8 nStackType = sal::static_int_cast<sal_uInt8>( GetStackType() );
2376cdf0e10cSrcweir 
2377cdf0e10cSrcweir             uno::Any aParam;
2378cdf0e10cSrcweir             switch (eType)
2379cdf0e10cSrcweir             {
2380cdf0e10cSrcweir                 case SC_ADDINARG_INTEGER:
2381cdf0e10cSrcweir                     {
2382cdf0e10cSrcweir                         double fVal = GetDouble();
2383cdf0e10cSrcweir                         double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) :
2384cdf0e10cSrcweir                                                       ::rtl::math::approxCeil( fVal );
2385cdf0e10cSrcweir                         if ( fInt >= LONG_MIN && fInt <= LONG_MAX )
2386cdf0e10cSrcweir                             aParam <<= (sal_Int32)fInt;
2387cdf0e10cSrcweir                         else
2388cdf0e10cSrcweir                             SetError(errIllegalArgument);
2389cdf0e10cSrcweir                     }
2390cdf0e10cSrcweir                     break;
2391cdf0e10cSrcweir 
2392cdf0e10cSrcweir                 case SC_ADDINARG_DOUBLE:
2393cdf0e10cSrcweir                     aParam <<= (double) GetDouble();
2394cdf0e10cSrcweir                     break;
2395cdf0e10cSrcweir 
2396cdf0e10cSrcweir                 case SC_ADDINARG_STRING:
2397cdf0e10cSrcweir                     aParam <<= rtl::OUString( GetString() );
2398cdf0e10cSrcweir                     break;
2399cdf0e10cSrcweir 
2400cdf0e10cSrcweir                 case SC_ADDINARG_INTEGER_ARRAY:
2401cdf0e10cSrcweir                     switch( nStackType )
2402cdf0e10cSrcweir                     {
2403cdf0e10cSrcweir                         case svDouble:
2404cdf0e10cSrcweir                         case svString:
2405cdf0e10cSrcweir                         case svSingleRef:
2406cdf0e10cSrcweir                             {
2407cdf0e10cSrcweir                                 double fVal = GetDouble();
2408cdf0e10cSrcweir                                 double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) :
2409cdf0e10cSrcweir                                                               ::rtl::math::approxCeil( fVal );
2410cdf0e10cSrcweir                                 if ( fInt >= LONG_MIN && fInt <= LONG_MAX )
2411cdf0e10cSrcweir                                 {
2412cdf0e10cSrcweir                                     sal_Int32 nIntVal = (long)fInt;
2413cdf0e10cSrcweir                                     uno::Sequence<sal_Int32> aInner( &nIntVal, 1 );
2414cdf0e10cSrcweir                                     uno::Sequence< uno::Sequence<sal_Int32> > aOuter( &aInner, 1 );
2415cdf0e10cSrcweir                                     aParam <<= aOuter;
2416cdf0e10cSrcweir                                 }
2417cdf0e10cSrcweir                                 else
2418cdf0e10cSrcweir                                     SetError(errIllegalArgument);
2419cdf0e10cSrcweir                             }
2420cdf0e10cSrcweir                             break;
2421cdf0e10cSrcweir                         case svDoubleRef:
2422cdf0e10cSrcweir                             {
2423cdf0e10cSrcweir                                 ScRange aRange;
2424cdf0e10cSrcweir                                 PopDoubleRef( aRange );
2425cdf0e10cSrcweir                                 if (!ScRangeToSequence::FillLongArray( aParam, pDok, aRange ))
2426cdf0e10cSrcweir                                     SetError(errIllegalParameter);
2427cdf0e10cSrcweir                             }
2428cdf0e10cSrcweir                             break;
2429cdf0e10cSrcweir                         case svMatrix:
2430cdf0e10cSrcweir                             if (!ScRangeToSequence::FillLongArray( aParam, PopMatrix() ))
2431cdf0e10cSrcweir                                 SetError(errIllegalParameter);
2432cdf0e10cSrcweir                             break;
2433cdf0e10cSrcweir                         default:
2434cdf0e10cSrcweir                             PopError();
2435cdf0e10cSrcweir                             SetError(errIllegalParameter);
2436cdf0e10cSrcweir                     }
2437cdf0e10cSrcweir                     break;
2438cdf0e10cSrcweir 
2439cdf0e10cSrcweir                 case SC_ADDINARG_DOUBLE_ARRAY:
2440cdf0e10cSrcweir                     switch( nStackType )
2441cdf0e10cSrcweir                     {
2442cdf0e10cSrcweir                         case svDouble:
2443cdf0e10cSrcweir                         case svString:
2444cdf0e10cSrcweir                         case svSingleRef:
2445cdf0e10cSrcweir                             {
2446cdf0e10cSrcweir                                 double fVal = GetDouble();
2447cdf0e10cSrcweir                                 uno::Sequence<double> aInner( &fVal, 1 );
2448cdf0e10cSrcweir                                 uno::Sequence< uno::Sequence<double> > aOuter( &aInner, 1 );
2449cdf0e10cSrcweir                                 aParam <<= aOuter;
2450cdf0e10cSrcweir                             }
2451cdf0e10cSrcweir                             break;
2452cdf0e10cSrcweir                         case svDoubleRef:
2453cdf0e10cSrcweir                             {
2454cdf0e10cSrcweir                                 ScRange aRange;
2455cdf0e10cSrcweir                                 PopDoubleRef( aRange );
2456cdf0e10cSrcweir                                 if (!ScRangeToSequence::FillDoubleArray( aParam, pDok, aRange ))
2457cdf0e10cSrcweir                                     SetError(errIllegalParameter);
2458cdf0e10cSrcweir                             }
2459cdf0e10cSrcweir                             break;
2460cdf0e10cSrcweir                         case svMatrix:
2461cdf0e10cSrcweir                             if (!ScRangeToSequence::FillDoubleArray( aParam, PopMatrix() ))
2462cdf0e10cSrcweir                                 SetError(errIllegalParameter);
2463cdf0e10cSrcweir                             break;
2464cdf0e10cSrcweir                         default:
2465cdf0e10cSrcweir                             PopError();
2466cdf0e10cSrcweir                             SetError(errIllegalParameter);
2467cdf0e10cSrcweir                     }
2468cdf0e10cSrcweir                     break;
2469cdf0e10cSrcweir 
2470cdf0e10cSrcweir                 case SC_ADDINARG_STRING_ARRAY:
2471cdf0e10cSrcweir                     switch( nStackType )
2472cdf0e10cSrcweir                     {
2473cdf0e10cSrcweir                         case svDouble:
2474cdf0e10cSrcweir                         case svString:
2475cdf0e10cSrcweir                         case svSingleRef:
2476cdf0e10cSrcweir                             {
2477cdf0e10cSrcweir                                 rtl::OUString aString = rtl::OUString( GetString() );
2478cdf0e10cSrcweir                                 uno::Sequence<rtl::OUString> aInner( &aString, 1 );
2479cdf0e10cSrcweir                                 uno::Sequence< uno::Sequence<rtl::OUString> > aOuter( &aInner, 1 );
2480cdf0e10cSrcweir                                 aParam <<= aOuter;
2481cdf0e10cSrcweir                             }
2482cdf0e10cSrcweir                             break;
2483cdf0e10cSrcweir                         case svDoubleRef:
2484cdf0e10cSrcweir                             {
2485cdf0e10cSrcweir                                 ScRange aRange;
2486cdf0e10cSrcweir                                 PopDoubleRef( aRange );
2487cdf0e10cSrcweir                                 if (!ScRangeToSequence::FillStringArray( aParam, pDok, aRange ))
2488cdf0e10cSrcweir                                     SetError(errIllegalParameter);
2489cdf0e10cSrcweir                             }
2490cdf0e10cSrcweir                             break;
2491cdf0e10cSrcweir                         case svMatrix:
2492cdf0e10cSrcweir                             if (!ScRangeToSequence::FillStringArray( aParam, PopMatrix(), pFormatter ))
2493cdf0e10cSrcweir                                 SetError(errIllegalParameter);
2494cdf0e10cSrcweir                             break;
2495cdf0e10cSrcweir                         default:
2496cdf0e10cSrcweir                             PopError();
2497cdf0e10cSrcweir                             SetError(errIllegalParameter);
2498cdf0e10cSrcweir                     }
2499cdf0e10cSrcweir                     break;
2500cdf0e10cSrcweir 
2501cdf0e10cSrcweir                 case SC_ADDINARG_MIXED_ARRAY:
2502cdf0e10cSrcweir                     switch( nStackType )
2503cdf0e10cSrcweir                     {
2504cdf0e10cSrcweir                         case svDouble:
2505cdf0e10cSrcweir                         case svString:
2506cdf0e10cSrcweir                         case svSingleRef:
2507cdf0e10cSrcweir                             {
2508cdf0e10cSrcweir                                 uno::Any aElem;
2509cdf0e10cSrcweir                                 if ( nStackType == svDouble )
2510cdf0e10cSrcweir                                     aElem <<= (double) GetDouble();
2511cdf0e10cSrcweir                                 else if ( nStackType == svString )
2512cdf0e10cSrcweir                                     aElem <<= rtl::OUString( GetString() );
2513cdf0e10cSrcweir                                 else
2514cdf0e10cSrcweir                                 {
2515cdf0e10cSrcweir                                     ScAddress aAdr;
2516cdf0e10cSrcweir                                     if ( PopDoubleRefOrSingleRef( aAdr ) )
2517cdf0e10cSrcweir                                     {
2518cdf0e10cSrcweir                                         ScBaseCell* pCell = GetCell( aAdr );
2519cdf0e10cSrcweir                                         if ( pCell && pCell->HasStringData() )
2520cdf0e10cSrcweir                                         {
2521cdf0e10cSrcweir                                             String aStr;
2522cdf0e10cSrcweir                                             GetCellString( aStr, pCell );
2523cdf0e10cSrcweir                                             aElem <<= rtl::OUString( aStr );
2524cdf0e10cSrcweir                                         }
2525cdf0e10cSrcweir                                         else
2526cdf0e10cSrcweir                                             aElem <<= (double) GetCellValue( aAdr, pCell );
2527cdf0e10cSrcweir                                     }
2528cdf0e10cSrcweir                                 }
2529cdf0e10cSrcweir                                 uno::Sequence<uno::Any> aInner( &aElem, 1 );
2530cdf0e10cSrcweir                                 uno::Sequence< uno::Sequence<uno::Any> > aOuter( &aInner, 1 );
2531cdf0e10cSrcweir                                 aParam <<= aOuter;
2532cdf0e10cSrcweir                             }
2533cdf0e10cSrcweir                             break;
2534cdf0e10cSrcweir                         case svDoubleRef:
2535cdf0e10cSrcweir                             {
2536cdf0e10cSrcweir                                 ScRange aRange;
2537cdf0e10cSrcweir                                 PopDoubleRef( aRange );
2538cdf0e10cSrcweir                                 if (!ScRangeToSequence::FillMixedArray( aParam, pDok, aRange ))
2539cdf0e10cSrcweir                                     SetError(errIllegalParameter);
2540cdf0e10cSrcweir                             }
2541cdf0e10cSrcweir                             break;
2542cdf0e10cSrcweir                         case svMatrix:
2543cdf0e10cSrcweir                             if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix() ))
2544cdf0e10cSrcweir                                 SetError(errIllegalParameter);
2545cdf0e10cSrcweir                             break;
2546cdf0e10cSrcweir                         default:
2547cdf0e10cSrcweir                             PopError();
2548cdf0e10cSrcweir                             SetError(errIllegalParameter);
2549cdf0e10cSrcweir                     }
2550cdf0e10cSrcweir                     break;
2551cdf0e10cSrcweir 
2552cdf0e10cSrcweir                 case SC_ADDINARG_VALUE_OR_ARRAY:
2553cdf0e10cSrcweir                     if ( IsMissing() )
2554cdf0e10cSrcweir                         nStackType = svMissing;
2555cdf0e10cSrcweir                     switch( nStackType )
2556cdf0e10cSrcweir                     {
2557cdf0e10cSrcweir                         case svDouble:
2558cdf0e10cSrcweir                             aParam <<= (double) GetDouble();
2559cdf0e10cSrcweir                             break;
2560cdf0e10cSrcweir                         case svString:
2561cdf0e10cSrcweir                             aParam <<= rtl::OUString( GetString() );
2562cdf0e10cSrcweir                             break;
2563cdf0e10cSrcweir                         case svSingleRef:
2564cdf0e10cSrcweir                             {
2565cdf0e10cSrcweir                                 ScAddress aAdr;
2566cdf0e10cSrcweir                                 if ( PopDoubleRefOrSingleRef( aAdr ) )
2567cdf0e10cSrcweir                                 {
2568cdf0e10cSrcweir                                     ScBaseCell* pCell = GetCell( aAdr );
2569cdf0e10cSrcweir                                     if ( pCell && pCell->HasStringData() )
2570cdf0e10cSrcweir                                     {
2571cdf0e10cSrcweir                                         String aStr;
2572cdf0e10cSrcweir                                         GetCellString( aStr, pCell );
2573cdf0e10cSrcweir                                         aParam <<= rtl::OUString( aStr );
2574cdf0e10cSrcweir                                     }
2575cdf0e10cSrcweir                                     else
2576cdf0e10cSrcweir                                         aParam <<= (double) GetCellValue( aAdr, pCell );
2577cdf0e10cSrcweir                                 }
2578cdf0e10cSrcweir                             }
2579cdf0e10cSrcweir                             break;
2580cdf0e10cSrcweir                         case svDoubleRef:
2581cdf0e10cSrcweir                             {
2582cdf0e10cSrcweir                                 ScRange aRange;
2583cdf0e10cSrcweir                                 PopDoubleRef( aRange );
2584cdf0e10cSrcweir                                 if (!ScRangeToSequence::FillMixedArray( aParam, pDok, aRange ))
2585cdf0e10cSrcweir                                     SetError(errIllegalParameter);
2586cdf0e10cSrcweir                             }
2587cdf0e10cSrcweir                             break;
2588cdf0e10cSrcweir                         case svMatrix:
2589cdf0e10cSrcweir                             if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix() ))
2590cdf0e10cSrcweir                                 SetError(errIllegalParameter);
2591cdf0e10cSrcweir                             break;
2592cdf0e10cSrcweir                         case svMissing:
2593cdf0e10cSrcweir                             Pop();
2594cdf0e10cSrcweir                             aParam.clear();
2595cdf0e10cSrcweir                             break;
2596cdf0e10cSrcweir                         default:
2597cdf0e10cSrcweir                             PopError();
2598cdf0e10cSrcweir                             SetError(errIllegalParameter);
2599cdf0e10cSrcweir                     }
2600cdf0e10cSrcweir                     break;
2601cdf0e10cSrcweir 
2602cdf0e10cSrcweir                 case SC_ADDINARG_CELLRANGE:
2603cdf0e10cSrcweir                     switch( nStackType )
2604cdf0e10cSrcweir                     {
2605cdf0e10cSrcweir                         case svSingleRef:
2606cdf0e10cSrcweir                             {
2607cdf0e10cSrcweir                                 ScAddress aAdr;
2608cdf0e10cSrcweir                                 PopSingleRef( aAdr );
2609cdf0e10cSrcweir                                 ScRange aRange( aAdr );
2610cdf0e10cSrcweir                                 uno::Reference<table::XCellRange> xObj =
2611cdf0e10cSrcweir                                         ScCellRangeObj::CreateRangeFromDoc( pDok, aRange );
2612cdf0e10cSrcweir                                 if (xObj.is())
2613cdf0e10cSrcweir                                     aParam <<= xObj;
2614cdf0e10cSrcweir                                 else
2615cdf0e10cSrcweir                                     SetError(errIllegalParameter);
2616cdf0e10cSrcweir                             }
2617cdf0e10cSrcweir                             break;
2618cdf0e10cSrcweir                         case svDoubleRef:
2619cdf0e10cSrcweir                             {
2620cdf0e10cSrcweir                                 ScRange aRange;
2621cdf0e10cSrcweir                                 PopDoubleRef( aRange );
2622cdf0e10cSrcweir                                 uno::Reference<table::XCellRange> xObj =
2623cdf0e10cSrcweir                                         ScCellRangeObj::CreateRangeFromDoc( pDok, aRange );
2624cdf0e10cSrcweir                                 if (xObj.is())
2625cdf0e10cSrcweir                                     aParam <<= xObj;
2626cdf0e10cSrcweir                                 else
2627cdf0e10cSrcweir                                     SetError(errIllegalParameter);
2628cdf0e10cSrcweir                             }
2629cdf0e10cSrcweir                             break;
2630cdf0e10cSrcweir                         default:
2631cdf0e10cSrcweir                             PopError();
2632cdf0e10cSrcweir                             SetError(errIllegalParameter);
2633cdf0e10cSrcweir                     }
2634cdf0e10cSrcweir                     break;
2635cdf0e10cSrcweir 
2636cdf0e10cSrcweir                 default:
2637cdf0e10cSrcweir                     PopError();
2638cdf0e10cSrcweir                     SetError(errIllegalParameter);
2639cdf0e10cSrcweir             }
2640cdf0e10cSrcweir             aCall.SetParam( nPar, aParam );
2641cdf0e10cSrcweir         }
2642cdf0e10cSrcweir 
2643cdf0e10cSrcweir         while (nPar-- > 0)
2644cdf0e10cSrcweir             Pop();                  // in case of error, remove remaining args
2645cdf0e10cSrcweir 
2646cdf0e10cSrcweir         if ( !GetError() )
2647cdf0e10cSrcweir         {
2648cdf0e10cSrcweir             aCall.ExecuteCall();
2649cdf0e10cSrcweir 
2650cdf0e10cSrcweir             if ( aCall.HasVarRes() )                        // handle async functions
2651cdf0e10cSrcweir             {
2652cdf0e10cSrcweir                 if ( pMyFormulaCell->GetCode()->IsRecalcModeNormal() )
2653cdf0e10cSrcweir                     pMyFormulaCell->GetCode()->SetRecalcModeOnLoad();
2654cdf0e10cSrcweir 
2655cdf0e10cSrcweir                 uno::Reference<sheet::XVolatileResult> xRes = aCall.GetVarRes();
2656cdf0e10cSrcweir                 ScAddInListener* pLis = ScAddInListener::Get( xRes );
2657cdf0e10cSrcweir                 if ( !pLis )
2658cdf0e10cSrcweir                 {
2659cdf0e10cSrcweir                     pLis = ScAddInListener::CreateListener( xRes, pDok );
2660cdf0e10cSrcweir                     pMyFormulaCell->StartListening( *pLis );
2661cdf0e10cSrcweir                 }
2662cdf0e10cSrcweir                 else
2663cdf0e10cSrcweir                 {
2664cdf0e10cSrcweir                     pMyFormulaCell->StartListening( *pLis );
2665cdf0e10cSrcweir                     if ( !pLis->HasDocument( pDok ) )
2666cdf0e10cSrcweir                         pLis->AddDocument( pDok );
2667cdf0e10cSrcweir                 }
2668cdf0e10cSrcweir 
2669cdf0e10cSrcweir                 aCall.SetResult( pLis->GetResult() );       // use result from async
2670cdf0e10cSrcweir             }
2671cdf0e10cSrcweir 
2672cdf0e10cSrcweir             if ( aCall.GetErrCode() )
2673cdf0e10cSrcweir                 PushError( aCall.GetErrCode() );
2674cdf0e10cSrcweir             else if ( aCall.HasMatrix() )
2675cdf0e10cSrcweir             {
2676cdf0e10cSrcweir                 ScMatrixRef xMat = aCall.GetMatrix();
2677cdf0e10cSrcweir                 PushMatrix( xMat );
2678cdf0e10cSrcweir             }
2679cdf0e10cSrcweir             else if ( aCall.HasString() )
2680cdf0e10cSrcweir                 PushString( aCall.GetString() );
2681cdf0e10cSrcweir             else
2682cdf0e10cSrcweir                 PushDouble( aCall.GetValue() );
2683cdf0e10cSrcweir         }
2684cdf0e10cSrcweir         else                // error...
2685cdf0e10cSrcweir             PushError( GetError());
2686cdf0e10cSrcweir     }
2687cdf0e10cSrcweir     else
2688cdf0e10cSrcweir     {
2689cdf0e10cSrcweir         while( nParamCount-- > 0)
2690cdf0e10cSrcweir             Pop();
2691cdf0e10cSrcweir         PushError( errNoAddin );
2692cdf0e10cSrcweir     }
2693cdf0e10cSrcweir }
2694cdf0e10cSrcweir 
2695cdf0e10cSrcweir 
ScMissing()2696cdf0e10cSrcweir void ScInterpreter::ScMissing()
2697cdf0e10cSrcweir {
2698cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMissing" );
2699cdf0e10cSrcweir     PushTempToken( new FormulaMissingToken );
2700cdf0e10cSrcweir }
2701cdf0e10cSrcweir 
2702cdf0e10cSrcweir 
ScMacro()2703cdf0e10cSrcweir void ScInterpreter::ScMacro()
2704cdf0e10cSrcweir {
2705cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMacro" );
2706cdf0e10cSrcweir     SbxBase::ResetError();
2707cdf0e10cSrcweir 
2708cdf0e10cSrcweir     sal_uInt8 nParamCount = GetByte();
2709cdf0e10cSrcweir     String aMacro( pCur->GetExternal() );
2710cdf0e10cSrcweir 
2711cdf0e10cSrcweir     SfxObjectShell* pDocSh = pDok->GetDocumentShell();
2712cdf0e10cSrcweir     if ( !pDocSh || !pDok->CheckMacroWarn() )
2713cdf0e10cSrcweir     {
2714cdf0e10cSrcweir         PushNoValue();      // ohne DocShell kein CallBasic
2715cdf0e10cSrcweir         return;
2716cdf0e10cSrcweir     }
2717cdf0e10cSrcweir 
2718cdf0e10cSrcweir     //  keine Sicherheitsabfrage mehr vorneweg (nur CheckMacroWarn), das passiert im CallBasic
2719cdf0e10cSrcweir 
2720cdf0e10cSrcweir     //  Wenn das Dok waehrend eines Basic-Calls geladen wurde,
2721cdf0e10cSrcweir     //  ist das Sbx-Objekt evtl. nicht angelegt (?)
2722cdf0e10cSrcweir //  pDocSh->GetSbxObject();
2723cdf0e10cSrcweir 
2724cdf0e10cSrcweir     //  Funktion ueber den einfachen Namen suchen,
2725cdf0e10cSrcweir     //  dann aBasicStr, aMacroStr fuer SfxObjectShell::CallBasic zusammenbauen
2726cdf0e10cSrcweir 
2727cdf0e10cSrcweir     StarBASIC* pRoot = pDocSh->GetBasic();
2728cdf0e10cSrcweir     SbxVariable* pVar = pRoot->Find( aMacro, SbxCLASS_METHOD );
2729cdf0e10cSrcweir     if( !pVar || pVar->GetType() == SbxVOID || !pVar->ISA(SbMethod) )
2730cdf0e10cSrcweir     {
2731cdf0e10cSrcweir         PushError( errNoMacro );
2732cdf0e10cSrcweir         return;
2733cdf0e10cSrcweir     }
2734cdf0e10cSrcweir 
2735cdf0e10cSrcweir     SbMethod* pMethod = (SbMethod*)pVar;
2736cdf0e10cSrcweir     SbModule* pModule = pMethod->GetModule();
2737cdf0e10cSrcweir     SbxObject* pObject = pModule->GetParent();
2738cdf0e10cSrcweir     DBG_ASSERT(pObject->IsA(TYPE(StarBASIC)), "Kein Basic gefunden!");
2739cdf0e10cSrcweir     String aMacroStr = pObject->GetName();
2740cdf0e10cSrcweir     aMacroStr += '.';
2741cdf0e10cSrcweir     aMacroStr += pModule->GetName();
2742cdf0e10cSrcweir     aMacroStr += '.';
2743cdf0e10cSrcweir     aMacroStr += pMethod->GetName();
2744cdf0e10cSrcweir     String aBasicStr;
2745cdf0e10cSrcweir     if (pObject->GetParent())
2746cdf0e10cSrcweir         aBasicStr = pObject->GetParent()->GetName();    // Dokumentenbasic
2747cdf0e10cSrcweir     else
2748cdf0e10cSrcweir         aBasicStr = SFX_APP()->GetName();               // Applikationsbasic
2749cdf0e10cSrcweir 
2750cdf0e10cSrcweir     //  Parameter-Array zusammenbauen
2751cdf0e10cSrcweir 
2752cdf0e10cSrcweir     SbxArrayRef refPar = new SbxArray;
2753cdf0e10cSrcweir     sal_Bool bOk = sal_True;
2754cdf0e10cSrcweir     for( short i = nParamCount; i && bOk ; i-- )
2755cdf0e10cSrcweir     {
2756cdf0e10cSrcweir         SbxVariable* pPar = refPar->Get( (sal_uInt16) i );
2757cdf0e10cSrcweir         sal_uInt8 nStackType = sal::static_int_cast<sal_uInt8>( GetStackType() );
2758cdf0e10cSrcweir         switch( nStackType )
2759cdf0e10cSrcweir         {
2760cdf0e10cSrcweir             case svDouble:
2761cdf0e10cSrcweir                 pPar->PutDouble( GetDouble() );
2762cdf0e10cSrcweir             break;
2763cdf0e10cSrcweir             case svString:
2764cdf0e10cSrcweir                 pPar->PutString( GetString() );
2765cdf0e10cSrcweir             break;
2766cdf0e10cSrcweir             case svSingleRef:
2767cdf0e10cSrcweir             {
2768cdf0e10cSrcweir                 ScAddress aAdr;
2769cdf0e10cSrcweir                 PopSingleRef( aAdr );
2770cdf0e10cSrcweir                 bOk = SetSbxVariable( pPar, aAdr );
2771cdf0e10cSrcweir             }
2772cdf0e10cSrcweir             break;
2773cdf0e10cSrcweir             case svDoubleRef:
2774cdf0e10cSrcweir             {
2775cdf0e10cSrcweir                 SCCOL nCol1;
2776cdf0e10cSrcweir                 SCROW nRow1;
2777cdf0e10cSrcweir                 SCTAB nTab1;
2778cdf0e10cSrcweir                 SCCOL nCol2;
2779cdf0e10cSrcweir                 SCROW nRow2;
2780cdf0e10cSrcweir                 SCTAB nTab2;
2781cdf0e10cSrcweir                 PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
2782cdf0e10cSrcweir                 if( nTab1 != nTab2 )
2783cdf0e10cSrcweir                 {
2784cdf0e10cSrcweir                     SetError( errIllegalParameter );
2785cdf0e10cSrcweir                     bOk = sal_False;
2786cdf0e10cSrcweir                 }
2787cdf0e10cSrcweir                 else
2788cdf0e10cSrcweir                 {
2789cdf0e10cSrcweir                     SbxDimArrayRef refArray = new SbxDimArray;
2790cdf0e10cSrcweir                     refArray->AddDim32( 1, nRow2 - nRow1 + 1 );
2791cdf0e10cSrcweir                     refArray->AddDim32( 1, nCol2 - nCol1 + 1 );
2792cdf0e10cSrcweir                     ScAddress aAdr( nCol1, nRow1, nTab1 );
2793cdf0e10cSrcweir                     for( SCROW nRow = nRow1; bOk && nRow <= nRow2; nRow++ )
2794cdf0e10cSrcweir                     {
2795cdf0e10cSrcweir                         aAdr.SetRow( nRow );
2796cdf0e10cSrcweir                         sal_Int32 nIdx[ 2 ];
2797cdf0e10cSrcweir                         nIdx[ 0 ] = nRow-nRow1+1;
2798cdf0e10cSrcweir                         for( SCCOL nCol = nCol1; bOk && nCol <= nCol2; nCol++ )
2799cdf0e10cSrcweir                         {
2800cdf0e10cSrcweir                             aAdr.SetCol( nCol );
2801cdf0e10cSrcweir                             nIdx[ 1 ] = nCol-nCol1+1;
2802cdf0e10cSrcweir                             SbxVariable* p = refArray->Get32( nIdx );
2803cdf0e10cSrcweir                             bOk = SetSbxVariable( p, aAdr );
2804cdf0e10cSrcweir                         }
2805cdf0e10cSrcweir                     }
2806cdf0e10cSrcweir                     pPar->PutObject( refArray );
2807cdf0e10cSrcweir                 }
2808cdf0e10cSrcweir             }
2809cdf0e10cSrcweir             break;
2810cdf0e10cSrcweir             case svMatrix:
2811cdf0e10cSrcweir             {
2812cdf0e10cSrcweir                 ScMatrixRef pMat = PopMatrix();
2813cdf0e10cSrcweir                 SCSIZE nC, nR;
2814cdf0e10cSrcweir                 if (pMat)
2815cdf0e10cSrcweir                 {
2816cdf0e10cSrcweir                     pMat->GetDimensions(nC, nR);
2817cdf0e10cSrcweir                     SbxDimArrayRef refArray = new SbxDimArray;
2818cdf0e10cSrcweir                     refArray->AddDim32( 1, static_cast<sal_Int32>(nR) );
2819cdf0e10cSrcweir                     refArray->AddDim32( 1, static_cast<sal_Int32>(nC) );
2820cdf0e10cSrcweir                     for( SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++ )
2821cdf0e10cSrcweir                     {
2822cdf0e10cSrcweir                         sal_Int32 nIdx[ 2 ];
2823cdf0e10cSrcweir                         nIdx[ 0 ] = static_cast<sal_Int32>(nMatRow+1);
2824cdf0e10cSrcweir                         for( SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++ )
2825cdf0e10cSrcweir                         {
2826cdf0e10cSrcweir                             nIdx[ 1 ] = static_cast<sal_Int32>(nMatCol+1);
2827cdf0e10cSrcweir                             SbxVariable* p = refArray->Get32( nIdx );
2828cdf0e10cSrcweir                             if (pMat->IsString(nMatCol, nMatRow))
2829cdf0e10cSrcweir                                 p->PutString( pMat->GetString(nMatCol, nMatRow) );
2830cdf0e10cSrcweir                             else
2831cdf0e10cSrcweir                                 p->PutDouble( pMat->GetDouble(nMatCol, nMatRow));
2832cdf0e10cSrcweir                         }
2833cdf0e10cSrcweir                     }
2834cdf0e10cSrcweir                     pPar->PutObject( refArray );
2835cdf0e10cSrcweir                 }
2836cdf0e10cSrcweir                 else
2837cdf0e10cSrcweir                     SetError( errIllegalParameter );
2838cdf0e10cSrcweir             }
2839cdf0e10cSrcweir             break;
2840cdf0e10cSrcweir             default:
2841cdf0e10cSrcweir                 SetError( errIllegalParameter );
2842cdf0e10cSrcweir                 bOk = sal_False;
2843cdf0e10cSrcweir         }
2844cdf0e10cSrcweir     }
2845cdf0e10cSrcweir     if( bOk )
2846cdf0e10cSrcweir     {
2847cdf0e10cSrcweir         pDok->LockTable( aPos.Tab() );
2848cdf0e10cSrcweir         SbxVariableRef refRes = new SbxVariable;
2849cdf0e10cSrcweir         pDok->IncMacroInterpretLevel();
2850cdf0e10cSrcweir         ErrCode eRet = pDocSh->CallBasic( aMacroStr, aBasicStr, refPar, refRes );
2851cdf0e10cSrcweir         pDok->DecMacroInterpretLevel();
2852cdf0e10cSrcweir         pDok->UnlockTable( aPos.Tab() );
2853cdf0e10cSrcweir 
2854cdf0e10cSrcweir         SbxDataType eResType = refRes->GetType();
2855cdf0e10cSrcweir         if( pVar->GetError() )
2856cdf0e10cSrcweir             SetError( errNoValue);
2857cdf0e10cSrcweir         if ( eRet != ERRCODE_NONE )
2858cdf0e10cSrcweir             PushNoValue();
2859cdf0e10cSrcweir         else if( eResType >= SbxINTEGER && eResType <= SbxDOUBLE )
2860cdf0e10cSrcweir             PushDouble( refRes->GetDouble() );
2861cdf0e10cSrcweir         else if ( eResType & SbxARRAY )
2862cdf0e10cSrcweir         {
2863cdf0e10cSrcweir             SbxBase* pElemObj = refRes->GetObject();
2864cdf0e10cSrcweir             SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj);
2865cdf0e10cSrcweir             short nDim = pDimArray->GetDims();
2866cdf0e10cSrcweir             if ( 1 <= nDim && nDim <= 2 )
2867cdf0e10cSrcweir             {
2868cdf0e10cSrcweir                 sal_Int32 nCs, nCe, nRs, nRe;
2869cdf0e10cSrcweir                 SCSIZE nC, nR;
2870cdf0e10cSrcweir                 SCCOL nColIdx;
2871cdf0e10cSrcweir                 SCROW nRowIdx;
2872cdf0e10cSrcweir                 if ( nDim == 1 )
2873cdf0e10cSrcweir                 {   // array( cols )  eine Zeile, mehrere Spalten
2874cdf0e10cSrcweir                     pDimArray->GetDim32( 1, nCs, nCe );
2875cdf0e10cSrcweir                     nC = static_cast<SCSIZE>(nCe - nCs + 1);
2876cdf0e10cSrcweir                     nRs = nRe = 0;
2877cdf0e10cSrcweir                     nR = 1;
2878cdf0e10cSrcweir                     nColIdx = 0;
2879cdf0e10cSrcweir                     nRowIdx = 1;
2880cdf0e10cSrcweir                 }
2881cdf0e10cSrcweir                 else
2882cdf0e10cSrcweir                 {   // array( rows, cols )
2883cdf0e10cSrcweir                     pDimArray->GetDim32( 1, nRs, nRe );
2884cdf0e10cSrcweir                     nR = static_cast<SCSIZE>(nRe - nRs + 1);
2885cdf0e10cSrcweir                     pDimArray->GetDim32( 2, nCs, nCe );
2886cdf0e10cSrcweir                     nC = static_cast<SCSIZE>(nCe - nCs + 1);
2887cdf0e10cSrcweir                     nColIdx = 1;
2888cdf0e10cSrcweir                     nRowIdx = 0;
2889cdf0e10cSrcweir                 }
2890cdf0e10cSrcweir                 ScMatrixRef pMat = GetNewMat( nC, nR);
2891cdf0e10cSrcweir                 if ( pMat )
2892cdf0e10cSrcweir                 {
2893cdf0e10cSrcweir                     SbxVariable* pV;
2894cdf0e10cSrcweir                     SbxDataType eType;
2895cdf0e10cSrcweir                     for ( SCSIZE j=0; j < nR; j++ )
2896cdf0e10cSrcweir                     {
2897cdf0e10cSrcweir                         sal_Int32 nIdx[ 2 ];
2898cdf0e10cSrcweir                         // bei eindimensionalem array( cols ) wird nIdx[1]
2899cdf0e10cSrcweir                         // von SbxDimArray::Get ignoriert
2900cdf0e10cSrcweir                         nIdx[ nRowIdx ] = nRs + static_cast<sal_Int32>(j);
2901cdf0e10cSrcweir                         for ( SCSIZE i=0; i < nC; i++ )
2902cdf0e10cSrcweir                         {
2903cdf0e10cSrcweir                             nIdx[ nColIdx ] = nCs + static_cast<sal_Int32>(i);
2904cdf0e10cSrcweir                             pV = pDimArray->Get32( nIdx );
2905cdf0e10cSrcweir                             eType = pV->GetType();
2906cdf0e10cSrcweir                             if ( eType >= SbxINTEGER && eType <= SbxDOUBLE )
2907cdf0e10cSrcweir                                 pMat->PutDouble( pV->GetDouble(), i, j );
2908cdf0e10cSrcweir                             else
2909cdf0e10cSrcweir                                 pMat->PutString( pV->GetString(), i, j );
2910cdf0e10cSrcweir                         }
2911cdf0e10cSrcweir                     }
2912cdf0e10cSrcweir                     PushMatrix( pMat );
2913cdf0e10cSrcweir                 }
2914cdf0e10cSrcweir                 else
2915cdf0e10cSrcweir                     PushIllegalArgument();
2916cdf0e10cSrcweir             }
2917cdf0e10cSrcweir             else
2918cdf0e10cSrcweir                 PushNoValue();
2919cdf0e10cSrcweir         }
2920cdf0e10cSrcweir         else
2921cdf0e10cSrcweir             PushString( refRes->GetString() );
2922cdf0e10cSrcweir     }
2923cdf0e10cSrcweir }
2924cdf0e10cSrcweir 
2925cdf0e10cSrcweir 
SetSbxVariable(SbxVariable * pVar,const ScAddress & rPos)2926cdf0e10cSrcweir sal_Bool ScInterpreter::SetSbxVariable( SbxVariable* pVar, const ScAddress& rPos )
2927cdf0e10cSrcweir {
2928cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::SetSbxVariable" );
2929cdf0e10cSrcweir     sal_Bool bOk = sal_True;
2930cdf0e10cSrcweir     ScBaseCell* pCell = pDok->GetCell( rPos );
2931cdf0e10cSrcweir     if (pCell)
2932cdf0e10cSrcweir     {
2933cdf0e10cSrcweir         sal_uInt16 nErr;
2934cdf0e10cSrcweir         double nVal;
2935cdf0e10cSrcweir         switch( pCell->GetCellType() )
2936cdf0e10cSrcweir         {
2937cdf0e10cSrcweir             case CELLTYPE_VALUE :
2938cdf0e10cSrcweir                 nVal = GetValueCellValue( rPos, (ScValueCell*)pCell );
2939cdf0e10cSrcweir                 pVar->PutDouble( nVal );
2940cdf0e10cSrcweir                 break;
2941cdf0e10cSrcweir             case CELLTYPE_STRING :
2942cdf0e10cSrcweir             {
2943cdf0e10cSrcweir                 String aVal;
2944cdf0e10cSrcweir                 ((ScStringCell*)pCell)->GetString( aVal );
2945cdf0e10cSrcweir                 pVar->PutString( aVal );
2946cdf0e10cSrcweir                 break;
2947cdf0e10cSrcweir             }
2948cdf0e10cSrcweir             case CELLTYPE_EDIT :
2949cdf0e10cSrcweir             {
2950cdf0e10cSrcweir                 String aVal;
2951cdf0e10cSrcweir                 ((ScEditCell*) pCell)->GetString( aVal );
2952cdf0e10cSrcweir                 pVar->PutString( aVal );
2953cdf0e10cSrcweir                 break;
2954cdf0e10cSrcweir             }
2955cdf0e10cSrcweir             case CELLTYPE_FORMULA :
2956cdf0e10cSrcweir                 nErr = ((ScFormulaCell*)pCell)->GetErrCode();
2957cdf0e10cSrcweir                 if( !nErr )
2958cdf0e10cSrcweir                 {
2959cdf0e10cSrcweir                     if( ((ScFormulaCell*)pCell)->IsValue() )
2960cdf0e10cSrcweir                     {
2961cdf0e10cSrcweir                         nVal = ((ScFormulaCell*)pCell)->GetValue();
2962cdf0e10cSrcweir                         pVar->PutDouble( nVal );
2963cdf0e10cSrcweir                     }
2964cdf0e10cSrcweir                     else
2965cdf0e10cSrcweir                     {
2966cdf0e10cSrcweir                         String aVal;
2967cdf0e10cSrcweir                         ((ScFormulaCell*)pCell)->GetString( aVal );
2968cdf0e10cSrcweir                         pVar->PutString( aVal );
2969cdf0e10cSrcweir                     }
2970cdf0e10cSrcweir                 }
2971cdf0e10cSrcweir                 else
2972cdf0e10cSrcweir                     SetError( nErr ), bOk = sal_False;
2973cdf0e10cSrcweir                 break;
2974cdf0e10cSrcweir             default :
2975cdf0e10cSrcweir                 pVar->PutDouble( 0.0 );
2976cdf0e10cSrcweir         }
2977cdf0e10cSrcweir     }
2978cdf0e10cSrcweir     else
2979cdf0e10cSrcweir         pVar->PutDouble( 0.0 );
2980cdf0e10cSrcweir     return bOk;
2981cdf0e10cSrcweir }
2982cdf0e10cSrcweir 
2983cdf0e10cSrcweir 
ScTableOp()2984cdf0e10cSrcweir void ScInterpreter::ScTableOp()
2985cdf0e10cSrcweir {
2986cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTableOp" );
2987cdf0e10cSrcweir     sal_uInt8 nParamCount = GetByte();
2988cdf0e10cSrcweir     if (nParamCount != 3 && nParamCount != 5)
2989cdf0e10cSrcweir     {
2990cdf0e10cSrcweir         PushIllegalParameter();
2991cdf0e10cSrcweir         return;
2992cdf0e10cSrcweir     }
2993cdf0e10cSrcweir     ScInterpreterTableOpParams* pTableOp = new ScInterpreterTableOpParams;
2994cdf0e10cSrcweir     if (nParamCount == 5)
2995cdf0e10cSrcweir     {
2996cdf0e10cSrcweir         PopSingleRef( pTableOp->aNew2 );
2997cdf0e10cSrcweir         PopSingleRef( pTableOp->aOld2 );
2998cdf0e10cSrcweir     }
2999cdf0e10cSrcweir     PopSingleRef( pTableOp->aNew1 );
3000cdf0e10cSrcweir     PopSingleRef( pTableOp->aOld1 );
3001cdf0e10cSrcweir     PopSingleRef( pTableOp->aFormulaPos );
3002cdf0e10cSrcweir 
3003cdf0e10cSrcweir     pTableOp->bValid = sal_True;
3004cdf0e10cSrcweir     pDok->aTableOpList.Insert( pTableOp );
3005cdf0e10cSrcweir     pDok->IncInterpreterTableOpLevel();
3006cdf0e10cSrcweir 
3007cdf0e10cSrcweir     sal_Bool bReuseLastParams = (pDok->aLastTableOpParams == *pTableOp);
3008cdf0e10cSrcweir     if ( bReuseLastParams )
3009cdf0e10cSrcweir     {
3010cdf0e10cSrcweir         pTableOp->aNotifiedFormulaPos = pDok->aLastTableOpParams.aNotifiedFormulaPos;
3011cdf0e10cSrcweir         pTableOp->bRefresh = sal_True;
3012cdf0e10cSrcweir         for ( ::std::vector< ScAddress >::const_iterator iBroadcast(
3013cdf0e10cSrcweir                     pTableOp->aNotifiedFormulaPos.begin() );
3014cdf0e10cSrcweir                 iBroadcast != pTableOp->aNotifiedFormulaPos.end();
3015cdf0e10cSrcweir                 ++iBroadcast )
3016cdf0e10cSrcweir         {   // emulate broadcast and indirectly collect cell pointers
3017cdf0e10cSrcweir             ScBaseCell* pCell = pDok->GetCell( *iBroadcast );
3018cdf0e10cSrcweir             if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
3019cdf0e10cSrcweir                 ((ScFormulaCell*)pCell)->SetTableOpDirty();
3020cdf0e10cSrcweir         }
3021cdf0e10cSrcweir     }
3022cdf0e10cSrcweir     else
3023cdf0e10cSrcweir     {   // broadcast and indirectly collect cell pointers and positions
3024cdf0e10cSrcweir         pDok->SetTableOpDirty( pTableOp->aOld1 );
3025cdf0e10cSrcweir         if ( nParamCount == 5 )
3026cdf0e10cSrcweir             pDok->SetTableOpDirty( pTableOp->aOld2 );
3027cdf0e10cSrcweir     }
3028cdf0e10cSrcweir     pTableOp->bCollectNotifications = sal_False;
3029cdf0e10cSrcweir 
3030cdf0e10cSrcweir     ScBaseCell* pFCell = pDok->GetCell( pTableOp->aFormulaPos );
3031cdf0e10cSrcweir     if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA )
3032cdf0e10cSrcweir         ((ScFormulaCell*)pFCell)->SetDirtyVar();
3033cdf0e10cSrcweir     if ( HasCellValueData( pFCell ) )
3034cdf0e10cSrcweir         PushDouble( GetCellValue( pTableOp->aFormulaPos, pFCell ));
3035cdf0e10cSrcweir     else
3036cdf0e10cSrcweir     {
3037cdf0e10cSrcweir         String aCellString;
3038cdf0e10cSrcweir         GetCellString( aCellString, pFCell );
3039cdf0e10cSrcweir         PushString( aCellString );
3040cdf0e10cSrcweir     }
3041cdf0e10cSrcweir 
3042cdf0e10cSrcweir     pDok->aTableOpList.Remove( pTableOp );
3043cdf0e10cSrcweir     // set dirty again once more to be able to recalculate original
3044cdf0e10cSrcweir     for ( ::std::vector< ScFormulaCell* >::const_iterator iBroadcast(
3045cdf0e10cSrcweir                 pTableOp->aNotifiedFormulaCells.begin() );
3046cdf0e10cSrcweir             iBroadcast != pTableOp->aNotifiedFormulaCells.end();
3047cdf0e10cSrcweir             ++iBroadcast )
3048cdf0e10cSrcweir     {
3049cdf0e10cSrcweir         (*iBroadcast)->SetTableOpDirty();
3050cdf0e10cSrcweir     }
3051cdf0e10cSrcweir 
3052cdf0e10cSrcweir     // save these params for next incarnation
3053cdf0e10cSrcweir     if ( !bReuseLastParams )
3054cdf0e10cSrcweir         pDok->aLastTableOpParams = *pTableOp;
3055cdf0e10cSrcweir 
3056cdf0e10cSrcweir     if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA )
3057cdf0e10cSrcweir     {
3058cdf0e10cSrcweir         ((ScFormulaCell*)pFCell)->SetDirtyVar();
3059cdf0e10cSrcweir         ((ScFormulaCell*)pFCell)->GetErrCode();     // recalculate original
3060cdf0e10cSrcweir     }
3061cdf0e10cSrcweir 
3062cdf0e10cSrcweir     // Reset all dirty flags so next incarnation does really collect all cell
3063cdf0e10cSrcweir     // pointers during notifications and not just non-dirty ones, which may
3064cdf0e10cSrcweir     // happen if a formula cell is used by more than one TableOp block.
3065cdf0e10cSrcweir     for ( ::std::vector< ScFormulaCell* >::const_iterator iBroadcast2(
3066cdf0e10cSrcweir                 pTableOp->aNotifiedFormulaCells.begin() );
3067cdf0e10cSrcweir             iBroadcast2 != pTableOp->aNotifiedFormulaCells.end();
3068cdf0e10cSrcweir             ++iBroadcast2 )
3069cdf0e10cSrcweir     {
3070cdf0e10cSrcweir         (*iBroadcast2)->ResetTableOpDirtyVar();
3071cdf0e10cSrcweir     }
3072cdf0e10cSrcweir     delete pTableOp;
3073cdf0e10cSrcweir 
3074cdf0e10cSrcweir     pDok->DecInterpreterTableOpLevel();
3075cdf0e10cSrcweir }
3076cdf0e10cSrcweir 
3077cdf0e10cSrcweir 
3078cdf0e10cSrcweir /*
3079cdf0e10cSrcweir 
3080cdf0e10cSrcweir void ScInterpreter::ScErrCell()
3081cdf0e10cSrcweir {
3082cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScErrCell" );
3083cdf0e10cSrcweir     double fErrNum = GetDouble();
3084cdf0e10cSrcweir     PushError((sal_uInt16) fErrNum);
3085cdf0e10cSrcweir }
3086cdf0e10cSrcweir */
3087cdf0e10cSrcweir 
ScDBArea()3088cdf0e10cSrcweir void ScInterpreter::ScDBArea()
3089cdf0e10cSrcweir {
3090cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBArea" );
3091cdf0e10cSrcweir     ScDBData* pDBData = pDok->GetDBCollection()->FindIndex( pCur->GetIndex());
3092cdf0e10cSrcweir     if (pDBData)
3093cdf0e10cSrcweir     {
3094cdf0e10cSrcweir         ScComplexRefData aRefData;
3095cdf0e10cSrcweir         aRefData.InitFlags();
3096cdf0e10cSrcweir         pDBData->GetArea( (SCTAB&) aRefData.Ref1.nTab,
3097cdf0e10cSrcweir                           (SCCOL&) aRefData.Ref1.nCol,
3098cdf0e10cSrcweir                           (SCROW&) aRefData.Ref1.nRow,
3099cdf0e10cSrcweir                           (SCCOL&) aRefData.Ref2.nCol,
3100cdf0e10cSrcweir                           (SCROW&) aRefData.Ref2.nRow);
3101cdf0e10cSrcweir         aRefData.Ref2.nTab    = aRefData.Ref1.nTab;
3102cdf0e10cSrcweir         aRefData.CalcRelFromAbs( aPos );
3103cdf0e10cSrcweir         PushTempToken( new ScDoubleRefToken( aRefData ) );
3104cdf0e10cSrcweir     }
3105cdf0e10cSrcweir     else
3106cdf0e10cSrcweir         PushError( errNoName);
3107cdf0e10cSrcweir }
3108cdf0e10cSrcweir 
3109cdf0e10cSrcweir 
ScColRowNameAuto()3110cdf0e10cSrcweir void ScInterpreter::ScColRowNameAuto()
3111cdf0e10cSrcweir {
3112cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColRowNameAuto" );
3113cdf0e10cSrcweir     ScComplexRefData aRefData( static_cast<const ScToken*>(pCur)->GetDoubleRef() );
3114cdf0e10cSrcweir     aRefData.CalcAbsIfRel( aPos );
3115cdf0e10cSrcweir     if ( aRefData.Valid() )
3116cdf0e10cSrcweir     {
3117cdf0e10cSrcweir         SCsCOL nStartCol;
3118cdf0e10cSrcweir         SCsROW nStartRow;
3119cdf0e10cSrcweir         SCsCOL nCol2;
3120cdf0e10cSrcweir         SCsROW nRow2;
3121cdf0e10cSrcweir         // evtl. Begrenzung durch definierte ColRowNameRanges merken
3122cdf0e10cSrcweir         nCol2 = aRefData.Ref2.nCol;
3123cdf0e10cSrcweir         nRow2 = aRefData.Ref2.nRow;
3124cdf0e10cSrcweir         // DataArea der ersten Zelle
3125cdf0e10cSrcweir         nStartCol = aRefData.Ref2.nCol = aRefData.Ref1.nCol;
3126cdf0e10cSrcweir         nStartRow = aRefData.Ref2.nRow = aRefData.Ref1.nRow;
3127cdf0e10cSrcweir         aRefData.Ref2.nTab = aRefData.Ref1.nTab;
3128cdf0e10cSrcweir         pDok->GetDataArea(  (SCTAB&) aRefData.Ref1.nTab,
3129cdf0e10cSrcweir                             (SCCOL&) aRefData.Ref1.nCol,
3130cdf0e10cSrcweir                             (SCROW&) aRefData.Ref1.nRow,
3131cdf0e10cSrcweir                             (SCCOL&) aRefData.Ref2.nCol,
3132cdf0e10cSrcweir                             (SCROW&) aRefData.Ref2.nRow,
3133cdf0e10cSrcweir                             sal_True, false );
3134cdf0e10cSrcweir         // DataArea im Ursprung begrenzen
3135cdf0e10cSrcweir         aRefData.Ref1.nCol = nStartCol;
3136cdf0e10cSrcweir         aRefData.Ref1.nRow = nStartRow;
3137cdf0e10cSrcweir 
3138cdf0e10cSrcweir         //! korrespondiert mit ScCompiler::GetToken
3139cdf0e10cSrcweir         if ( aRefData.Ref1.IsColRel() )
3140cdf0e10cSrcweir         {   // ColName
3141cdf0e10cSrcweir             aRefData.Ref2.nCol = nStartCol;
3142cdf0e10cSrcweir             // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten
3143cdf0e10cSrcweir             if ( aRefData.Ref2.nRow > nRow2 )
3144cdf0e10cSrcweir                 aRefData.Ref2.nRow = nRow2;
3145cdf0e10cSrcweir             SCROW nMyRow;
3146cdf0e10cSrcweir             if ( aPos.Col() == nStartCol
3147cdf0e10cSrcweir               && nStartRow <= (nMyRow = aPos.Row()) && nMyRow <= aRefData.Ref2.nRow )
3148cdf0e10cSrcweir             {   // Formel in gleicher Spalte und innerhalb des Range
3149cdf0e10cSrcweir                 if ( nMyRow == nStartRow )
3150cdf0e10cSrcweir                 {   // direkt unter dem Namen den Rest nehmen
3151cdf0e10cSrcweir                     nStartRow++;
3152cdf0e10cSrcweir                     if ( nStartRow > MAXROW )
3153cdf0e10cSrcweir                         nStartRow = MAXROW;
3154cdf0e10cSrcweir                     aRefData.Ref1.nRow = nStartRow;
3155cdf0e10cSrcweir                 }
3156cdf0e10cSrcweir                 else
3157cdf0e10cSrcweir                 {   // weiter unten vom Namen bis zur Formelzelle
3158cdf0e10cSrcweir                     aRefData.Ref2.nRow = nMyRow - 1;
3159cdf0e10cSrcweir                 }
3160cdf0e10cSrcweir             }
3161cdf0e10cSrcweir         }
3162cdf0e10cSrcweir         else
3163cdf0e10cSrcweir         {   // RowName
3164cdf0e10cSrcweir             aRefData.Ref2.nRow = nStartRow;
3165cdf0e10cSrcweir             // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten
3166cdf0e10cSrcweir             if ( aRefData.Ref2.nCol > nCol2 )
3167cdf0e10cSrcweir                 aRefData.Ref2.nCol = nCol2;
3168cdf0e10cSrcweir             SCCOL nMyCol;
3169cdf0e10cSrcweir             if ( aPos.Row() == nStartRow
3170cdf0e10cSrcweir               && nStartCol <= (nMyCol = aPos.Col()) && nMyCol <= aRefData.Ref2.nCol )
3171cdf0e10cSrcweir             {   // Formel in gleicher Zeile und innerhalb des Range
3172cdf0e10cSrcweir                 if ( nMyCol == nStartCol )
3173cdf0e10cSrcweir                 {   // direkt neben dem Namen den Rest nehmen
3174cdf0e10cSrcweir                     nStartCol++;
3175cdf0e10cSrcweir                     if ( nStartCol > MAXCOL )
3176cdf0e10cSrcweir                         nStartCol = MAXCOL;
3177cdf0e10cSrcweir                     aRefData.Ref1.nCol = nStartCol;
3178cdf0e10cSrcweir                 }
3179cdf0e10cSrcweir                 else
3180cdf0e10cSrcweir                 {   // weiter rechts vom Namen bis zur Formelzelle
3181cdf0e10cSrcweir                     aRefData.Ref2.nCol = nMyCol - 1;
3182cdf0e10cSrcweir                 }
3183cdf0e10cSrcweir             }
3184cdf0e10cSrcweir         }
3185cdf0e10cSrcweir         aRefData.CalcRelFromAbs( aPos );
3186cdf0e10cSrcweir         PushTempToken( new ScDoubleRefToken( aRefData ) );
3187cdf0e10cSrcweir     }
3188cdf0e10cSrcweir     else
3189cdf0e10cSrcweir         PushError( errNoRef );
3190cdf0e10cSrcweir }
3191cdf0e10cSrcweir 
ScExternalRef()3192cdf0e10cSrcweir void ScInterpreter::ScExternalRef()
3193cdf0e10cSrcweir {
3194cdf0e10cSrcweir     const FormulaToken* pNextOp = aCode.PeekNextOperator();
3195cdf0e10cSrcweir     if (pNextOp && pNextOp->GetOpCode() == ocOffset)
3196cdf0e10cSrcweir     {
3197cdf0e10cSrcweir         // Handled by OFFSET function.
3198cdf0e10cSrcweir         PushTempToken( *pCur);
3199cdf0e10cSrcweir         return;
3200cdf0e10cSrcweir     }
3201cdf0e10cSrcweir 
3202cdf0e10cSrcweir     ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
3203cdf0e10cSrcweir     const String* pFile = pRefMgr->getExternalFileName(pCur->GetIndex());
3204cdf0e10cSrcweir     if (!pFile)
3205cdf0e10cSrcweir         PushError(errNoName);
3206cdf0e10cSrcweir 
3207cdf0e10cSrcweir     switch (pCur->GetType())
3208cdf0e10cSrcweir     {
3209cdf0e10cSrcweir         case svExternalSingleRef:
3210cdf0e10cSrcweir         {
3211cdf0e10cSrcweir             ScSingleRefData aData(static_cast<const ScToken*>(pCur)->GetSingleRef());
3212cdf0e10cSrcweir             if (aData.IsTabRel())
3213cdf0e10cSrcweir             {
3214cdf0e10cSrcweir                 DBG_ERROR("ScCompiler::GetToken: external single reference must have an absolute table reference!");
3215cdf0e10cSrcweir                 break;
3216cdf0e10cSrcweir             }
3217cdf0e10cSrcweir 
3218cdf0e10cSrcweir             aData.CalcAbsIfRel(aPos);
3219cdf0e10cSrcweir             ScAddress aAddr(aData.nCol, aData.nRow, aData.nTab);
3220cdf0e10cSrcweir             ScExternalRefCache::CellFormat aFmt;
3221cdf0e10cSrcweir             ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(
3222cdf0e10cSrcweir                 pCur->GetIndex(), pCur->GetString(), aAddr, &aPos, NULL, &aFmt);
3223cdf0e10cSrcweir 
3224cdf0e10cSrcweir             if (!xNew)
3225cdf0e10cSrcweir                 break;
3226cdf0e10cSrcweir 
3227cdf0e10cSrcweir             PushTempToken( *xNew);      // push a clone
3228cdf0e10cSrcweir 
3229cdf0e10cSrcweir             if (aFmt.mbIsSet)
3230cdf0e10cSrcweir             {
3231cdf0e10cSrcweir                 nFuncFmtType = aFmt.mnType;
3232cdf0e10cSrcweir                 nFuncFmtIndex = aFmt.mnIndex;
3233cdf0e10cSrcweir             }
3234cdf0e10cSrcweir             return;
3235cdf0e10cSrcweir         }
3236cdf0e10cSrcweir         //break;    // unreachable, prevent compiler warning
3237cdf0e10cSrcweir         case svExternalDoubleRef:
3238cdf0e10cSrcweir         {
3239cdf0e10cSrcweir             ScComplexRefData aData(static_cast<const ScToken*>(pCur)->GetDoubleRef());
3240cdf0e10cSrcweir             if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
3241cdf0e10cSrcweir             {
3242cdf0e10cSrcweir                 DBG_ERROR("ScCompiler::GetToken: external double reference must have an absolute table reference!");
3243cdf0e10cSrcweir                 break;
3244cdf0e10cSrcweir             }
3245cdf0e10cSrcweir 
3246cdf0e10cSrcweir             aData.CalcAbsIfRel(aPos);
3247cdf0e10cSrcweir             ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab,
3248cdf0e10cSrcweir                            aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
3249cdf0e10cSrcweir             ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getDoubleRefTokens(
3250cdf0e10cSrcweir                 pCur->GetIndex(), pCur->GetString(), aRange, &aPos);
3251cdf0e10cSrcweir 
3252cdf0e10cSrcweir             if (!xNew)
3253cdf0e10cSrcweir                 break;
3254cdf0e10cSrcweir 
3255cdf0e10cSrcweir             ScToken* p = static_cast<ScToken*>(xNew->First());
3256cdf0e10cSrcweir             if (p->GetType() != svMatrix)
3257cdf0e10cSrcweir                 break;
3258cdf0e10cSrcweir 
3259cdf0e10cSrcweir             if (xNew->Next())
3260cdf0e10cSrcweir             {
3261cdf0e10cSrcweir                 // Can't handle more than one matrix per parameter.
3262cdf0e10cSrcweir                 SetError( errIllegalArgument);
3263cdf0e10cSrcweir                 break;
3264cdf0e10cSrcweir             }
3265cdf0e10cSrcweir 
3266cdf0e10cSrcweir             PushMatrix(p->GetMatrix());
3267cdf0e10cSrcweir             return;
3268cdf0e10cSrcweir         }
3269cdf0e10cSrcweir         //break;    // unreachable, prevent compiler warning
3270cdf0e10cSrcweir         default:
3271cdf0e10cSrcweir             ;
3272cdf0e10cSrcweir     }
3273cdf0e10cSrcweir     PushError(errNoRef);
3274cdf0e10cSrcweir }
3275cdf0e10cSrcweir 
3276cdf0e10cSrcweir // --- internals ------------------------------------------------------------
3277cdf0e10cSrcweir 
3278cdf0e10cSrcweir 
ScTTT()3279cdf0e10cSrcweir void ScInterpreter::ScTTT()
3280cdf0e10cSrcweir {   // Temporaerer Test-Tanz, zum auspropieren von Funktionen etc.
3281cdf0e10cSrcweir     sal_uInt8 nParamCount = GetByte();
3282cdf0e10cSrcweir     // do something, nParamCount bei Pops runterzaehlen!
3283cdf0e10cSrcweir 
3284cdf0e10cSrcweir     // Stack aufraeumen
3285cdf0e10cSrcweir     while ( nParamCount-- > 0)
3286cdf0e10cSrcweir         Pop();
3287cdf0e10cSrcweir     PushError(errNoValue);
3288cdf0e10cSrcweir }
3289cdf0e10cSrcweir 
3290cdf0e10cSrcweir // -------------------------------------------------------------------------
3291cdf0e10cSrcweir 
3292cdf0e10cSrcweir 
ScInterpreter(ScFormulaCell * pCell,ScDocument * pDoc,const ScAddress & rPos,ScTokenArray & r)3293cdf0e10cSrcweir ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
3294cdf0e10cSrcweir         const ScAddress& rPos, ScTokenArray& r ) :
3295cdf0e10cSrcweir     aCode( r ),
3296cdf0e10cSrcweir     aPos( rPos ),
3297cdf0e10cSrcweir     rArr( r ),
3298cdf0e10cSrcweir     pDok( pDoc ),
3299cdf0e10cSrcweir     pTokenMatrixMap( NULL ),
3300cdf0e10cSrcweir     pMyFormulaCell( pCell ),
3301cdf0e10cSrcweir     pFormatter( pDoc->GetFormatTable() ),
330261e64f4aSWang Lei     pLastStackRefToken( NULL ),
330361e64f4aSWang Lei     bRefFunc( false ),
3304b158ee6cSPavel Janík     mnStringNoValueError( errNoValue ),
3305cdf0e10cSrcweir     bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() )
3306cdf0e10cSrcweir {
3307cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTT" );
3308cdf0e10cSrcweir //  pStack = new ScToken*[ MAXSTACK ];
3309cdf0e10cSrcweir 
3310cdf0e10cSrcweir     sal_uInt8 cMatFlag = pMyFormulaCell->GetMatrixFlag();
3311cdf0e10cSrcweir     bMatrixFormula = ( cMatFlag == MM_FORMULA || cMatFlag == MM_FAKE );
3312cdf0e10cSrcweir     if (!bGlobalStackInUse)
3313cdf0e10cSrcweir     {
3314cdf0e10cSrcweir         bGlobalStackInUse = sal_True;
3315cdf0e10cSrcweir         if (!pGlobalStack)
3316cdf0e10cSrcweir             pGlobalStack = new ScTokenStack;
3317cdf0e10cSrcweir         pStackObj = pGlobalStack;
3318cdf0e10cSrcweir     }
3319cdf0e10cSrcweir     else
3320cdf0e10cSrcweir     {
3321cdf0e10cSrcweir         pStackObj = new ScTokenStack;
3322cdf0e10cSrcweir     }
3323cdf0e10cSrcweir     pStack = pStackObj->pPointer;
3324cdf0e10cSrcweir }
3325cdf0e10cSrcweir 
~ScInterpreter()3326cdf0e10cSrcweir ScInterpreter::~ScInterpreter()
3327cdf0e10cSrcweir {
3328cdf0e10cSrcweir //  delete pStack;
3329cdf0e10cSrcweir 
3330cdf0e10cSrcweir     if ( pStackObj == pGlobalStack )
3331cdf0e10cSrcweir         bGlobalStackInUse = sal_False;
3332cdf0e10cSrcweir     else
3333cdf0e10cSrcweir         delete pStackObj;
3334cdf0e10cSrcweir     if (pTokenMatrixMap)
3335cdf0e10cSrcweir         delete pTokenMatrixMap;
333661e64f4aSWang Lei     DELETEZ(pLastStackRefToken);
3337cdf0e10cSrcweir }
3338cdf0e10cSrcweir 
3339cdf0e10cSrcweir 
GlobalExit()3340cdf0e10cSrcweir void ScInterpreter::GlobalExit()        // static
3341cdf0e10cSrcweir {
3342cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GlobalExit" );
3343cdf0e10cSrcweir     DBG_ASSERT(!bGlobalStackInUse, "wer benutzt noch den TokenStack?");
3344cdf0e10cSrcweir     DELETEZ(pGlobalStack);
3345cdf0e10cSrcweir }
3346cdf0e10cSrcweir 
3347cdf0e10cSrcweir 
3348cdf0e10cSrcweir // A ::std::vector<FormulaTokenRef> is not possible, a push_back() attempts to
3349cdf0e10cSrcweir // use a FormulaToken(const FormulaTokenRef&) ctor. Reinvent wheel..
3350cdf0e10cSrcweir struct FormulaTokenRefPtr
3351cdf0e10cSrcweir {
3352cdf0e10cSrcweir     FormulaToken* mp;
FormulaTokenRefPtrFormulaTokenRefPtr3353cdf0e10cSrcweir     FormulaTokenRefPtr() : mp(0) {}
FormulaTokenRefPtrFormulaTokenRefPtr3354cdf0e10cSrcweir     FormulaTokenRefPtr( FormulaToken* p ) : mp(p) { if (mp) mp->IncRef(); }
FormulaTokenRefPtrFormulaTokenRefPtr3355cdf0e10cSrcweir     FormulaTokenRefPtr( const FormulaTokenRefPtr & r ) : mp(r.mp) { if (mp) mp->IncRef(); }
~FormulaTokenRefPtrFormulaTokenRefPtr3356cdf0e10cSrcweir     ~FormulaTokenRefPtr() { if (mp) mp->DecRef(); }
operator =FormulaTokenRefPtr3357cdf0e10cSrcweir     FormulaTokenRefPtr& operator=( const FormulaTokenRefPtr & r )
3358cdf0e10cSrcweir     { if (r.mp) r.mp->IncRef(); if (mp) mp->DecRef(); mp = r.mp; return *this; }
3359cdf0e10cSrcweir };
3360cdf0e10cSrcweir typedef ::std::vector< FormulaTokenRefPtr > FormulaTokenDtor;
3361cdf0e10cSrcweir 
3362cdf0e10cSrcweir 
Interpret()3363cdf0e10cSrcweir StackVar ScInterpreter::Interpret()
3364cdf0e10cSrcweir {
3365cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Interpret" );
3366cdf0e10cSrcweir     short nRetTypeExpr = NUMBERFORMAT_UNDEFINED;
3367cdf0e10cSrcweir     sal_uLong nRetIndexExpr = 0;
3368cdf0e10cSrcweir     sal_uInt16 nErrorFunction = 0;
3369cdf0e10cSrcweir     sal_uInt16 nErrorFunctionCount = 0;
3370cdf0e10cSrcweir     sal_uInt16 nStackBase;
3371cdf0e10cSrcweir 
3372cdf0e10cSrcweir     nGlobalError = 0;
3373cdf0e10cSrcweir     nStackBase = sp = maxsp = 0;
3374cdf0e10cSrcweir     nRetFmtType = NUMBERFORMAT_UNDEFINED;
3375cdf0e10cSrcweir     nFuncFmtType = NUMBERFORMAT_UNDEFINED;
3376cdf0e10cSrcweir     nFuncFmtIndex = nCurFmtIndex = nRetFmtIndex = 0;
3377cdf0e10cSrcweir     xResult = NULL;
3378cdf0e10cSrcweir     pJumpMatrix = NULL;
3379cdf0e10cSrcweir     glSubTotal = sal_False;
3380cdf0e10cSrcweir     ScTokenMatrixMap::const_iterator aTokenMatrixMapIter;
3381cdf0e10cSrcweir     ::boost::scoped_ptr< FormulaTokenDtor > pTokenDtor;
3382cdf0e10cSrcweir 
3383cdf0e10cSrcweir     // Once upon a time we used to have FP exceptions on, and there was a
3384cdf0e10cSrcweir     // Windows printer driver that kept switching off exceptions, so we had to
3385cdf0e10cSrcweir     // switch them back on again every time. Who knows if there isn't a driver
3386cdf0e10cSrcweir     // that keeps switching exceptions on, now that we run with exceptions off,
3387cdf0e10cSrcweir     // so reassure exceptions are really off.
3388cdf0e10cSrcweir     SAL_MATH_FPEXCEPTIONS_OFF();
3389cdf0e10cSrcweir 
3390cdf0e10cSrcweir     aCode.Reset();
3391cdf0e10cSrcweir     while( ( pCur = aCode.Next() ) != NULL
3392cdf0e10cSrcweir             && (!nGlobalError || nErrorFunction <= nErrorFunctionCount) )
3393cdf0e10cSrcweir     {
3394cdf0e10cSrcweir         OpCode eOp = pCur->GetOpCode();
3395cdf0e10cSrcweir         cPar = pCur->GetByte();
3396cdf0e10cSrcweir         if ( eOp == ocPush )
3397cdf0e10cSrcweir         {
3398cdf0e10cSrcweir             // RPN code push without error
3399cdf0e10cSrcweir             PushWithoutError( (FormulaToken&) *pCur );
3400cdf0e10cSrcweir         }
3401cdf0e10cSrcweir         else if (pTokenMatrixMap && !(eOp == ocIf || eOp == ocChose) &&
3402cdf0e10cSrcweir                 ((aTokenMatrixMapIter = pTokenMatrixMap->find( pCur)) !=
3403cdf0e10cSrcweir                  pTokenMatrixMap->end()) &&
3404cdf0e10cSrcweir                 (*aTokenMatrixMapIter).second->GetType() != svJumpMatrix)
3405cdf0e10cSrcweir         {
3406cdf0e10cSrcweir             // Path already calculated, reuse result.
3407cdf0e10cSrcweir             nStackBase = sp - pCur->GetParamCount();
3408cdf0e10cSrcweir             if ( nStackBase > sp )
3409cdf0e10cSrcweir                 nStackBase = sp;        // underflow?!?
3410cdf0e10cSrcweir             sp = nStackBase;
3411cdf0e10cSrcweir             PushTempToken( (*aTokenMatrixMapIter).second);
3412cdf0e10cSrcweir         }
3413cdf0e10cSrcweir         else
3414cdf0e10cSrcweir         {
3415cdf0e10cSrcweir             // previous expression determines the current number format
3416cdf0e10cSrcweir             nCurFmtType = nRetTypeExpr;
3417cdf0e10cSrcweir             nCurFmtIndex = nRetIndexExpr;
3418cdf0e10cSrcweir             // default function's format, others are set if needed
3419cdf0e10cSrcweir             nFuncFmtType = NUMBERFORMAT_NUMBER;
3420cdf0e10cSrcweir             nFuncFmtIndex = 0;
3421cdf0e10cSrcweir 
3422cdf0e10cSrcweir             if ( eOp == ocIf || eOp == ocChose )
3423cdf0e10cSrcweir                 nStackBase = sp;        // don't mess around with the jumps
3424cdf0e10cSrcweir             else
3425cdf0e10cSrcweir             {
3426cdf0e10cSrcweir                 // Convert parameters to matrix if in array/matrix formula and
3427cdf0e10cSrcweir                 // parameters of function indicate doing so. Create JumpMatrix
3428cdf0e10cSrcweir                 // if necessary.
3429cdf0e10cSrcweir                 if ( MatrixParameterConversion() )
3430cdf0e10cSrcweir                 {
3431cdf0e10cSrcweir                     eOp = ocNone;       // JumpMatrix created
3432cdf0e10cSrcweir                     nStackBase = sp;
3433cdf0e10cSrcweir                 }
3434cdf0e10cSrcweir                 else
3435cdf0e10cSrcweir                     nStackBase = sp - pCur->GetParamCount();
3436cdf0e10cSrcweir             }
3437cdf0e10cSrcweir             if ( nStackBase > sp )
3438cdf0e10cSrcweir                 nStackBase = sp;        // underflow?!?
3439cdf0e10cSrcweir 
3440cdf0e10cSrcweir             switch( eOp )
3441cdf0e10cSrcweir             {
3442cdf0e10cSrcweir                 case ocSep:
3443cdf0e10cSrcweir                 case ocClose:           // pushed by the compiler
3444cdf0e10cSrcweir                 case ocMissing          : ScMissing();                  break;
3445cdf0e10cSrcweir                 case ocMacro            : ScMacro();                    break;
3446cdf0e10cSrcweir                 case ocDBArea           : ScDBArea();                   break;
3447cdf0e10cSrcweir                 case ocColRowNameAuto   : ScColRowNameAuto();           break;
3448cdf0e10cSrcweir // separated    case ocPush             : Push( (ScToken&) *pCur );     break;
3449cdf0e10cSrcweir                 case ocExternalRef      : ScExternalRef();              break;
3450cdf0e10cSrcweir                 case ocIf               : ScIfJump();                   break;
3451cdf0e10cSrcweir                 case ocChose            : ScChoseJump();                break;
3452cdf0e10cSrcweir                 case ocAdd              : ScAdd();                      break;
3453cdf0e10cSrcweir                 case ocSub              : ScSub();                      break;
3454cdf0e10cSrcweir                 case ocMul              : ScMul();                      break;
3455cdf0e10cSrcweir                 case ocDiv              : ScDiv();                      break;
3456cdf0e10cSrcweir                 case ocAmpersand        : ScAmpersand();                break;
3457cdf0e10cSrcweir                 case ocPow              : ScPow();                      break;
3458cdf0e10cSrcweir                 case ocEqual            : ScEqual();                    break;
3459cdf0e10cSrcweir                 case ocNotEqual         : ScNotEqual();                 break;
3460cdf0e10cSrcweir                 case ocLess             : ScLess();                     break;
3461cdf0e10cSrcweir                 case ocGreater          : ScGreater();                  break;
3462cdf0e10cSrcweir                 case ocLessEqual        : ScLessEqual();                break;
3463cdf0e10cSrcweir                 case ocGreaterEqual     : ScGreaterEqual();             break;
3464cdf0e10cSrcweir                 case ocAnd              : ScAnd();                      break;
3465cdf0e10cSrcweir                 case ocOr               : ScOr();                       break;
3466245212b4SAndrew Rist                 case ocXor              : ScXor();                      break;
3467cdf0e10cSrcweir                 case ocIntersect        : ScIntersect();                break;
3468cdf0e10cSrcweir                 case ocRange            : ScRangeFunc();                break;
3469cdf0e10cSrcweir                 case ocUnion            : ScUnionFunc();                break;
3470cdf0e10cSrcweir                 case ocNot              : ScNot();                      break;
3471cdf0e10cSrcweir                 case ocNegSub           :
3472cdf0e10cSrcweir                 case ocNeg              : ScNeg();                      break;
3473cdf0e10cSrcweir                 case ocPercentSign      : ScPercentSign();              break;
3474cdf0e10cSrcweir                 case ocPi               : ScPi();                       break;
3475cdf0e10cSrcweir //              case ocDefPar           : ScDefPar();                   break;
3476cdf0e10cSrcweir                 case ocRandom           : ScRandom();                   break;
3477cdf0e10cSrcweir                 case ocTrue             : ScTrue();                     break;
3478cdf0e10cSrcweir                 case ocFalse            : ScFalse();                    break;
3479cdf0e10cSrcweir                 case ocGetActDate       : ScGetActDate();               break;
3480cdf0e10cSrcweir                 case ocGetActTime       : ScGetActTime();               break;
3481cdf0e10cSrcweir                 case ocNotAvail         : PushError( NOTAVAILABLE);     break;
3482cdf0e10cSrcweir                 case ocDeg              : ScDeg();                      break;
3483cdf0e10cSrcweir                 case ocRad              : ScRad();                      break;
3484cdf0e10cSrcweir                 case ocSin              : ScSin();                      break;
3485cdf0e10cSrcweir                 case ocCos              : ScCos();                      break;
3486cdf0e10cSrcweir                 case ocTan              : ScTan();                      break;
3487cdf0e10cSrcweir                 case ocCot              : ScCot();                      break;
3488cdf0e10cSrcweir                 case ocArcSin           : ScArcSin();                   break;
3489cdf0e10cSrcweir                 case ocArcCos           : ScArcCos();                   break;
3490cdf0e10cSrcweir                 case ocArcTan           : ScArcTan();                   break;
3491cdf0e10cSrcweir                 case ocArcCot           : ScArcCot();                   break;
3492cdf0e10cSrcweir                 case ocSinHyp           : ScSinHyp();                   break;
3493cdf0e10cSrcweir                 case ocCosHyp           : ScCosHyp();                   break;
3494cdf0e10cSrcweir                 case ocTanHyp           : ScTanHyp();                   break;
3495cdf0e10cSrcweir                 case ocCotHyp           : ScCotHyp();                   break;
3496cdf0e10cSrcweir                 case ocArcSinHyp        : ScArcSinHyp();                break;
3497cdf0e10cSrcweir                 case ocArcCosHyp        : ScArcCosHyp();                break;
3498cdf0e10cSrcweir                 case ocArcTanHyp        : ScArcTanHyp();                break;
3499cdf0e10cSrcweir                 case ocArcCotHyp        : ScArcCotHyp();                break;
3500cdf0e10cSrcweir                 case ocCosecant         : ScCosecant();                 break;
3501cdf0e10cSrcweir                 case ocSecant           : ScSecant();                   break;
3502cdf0e10cSrcweir                 case ocCosecantHyp      : ScCosecantHyp();              break;
3503cdf0e10cSrcweir                 case ocSecantHyp        : ScSecantHyp();                break;
3504cdf0e10cSrcweir                 case ocExp              : ScExp();                      break;
3505cdf0e10cSrcweir                 case ocLn               : ScLn();                       break;
3506cdf0e10cSrcweir                 case ocLog10            : ScLog10();                    break;
3507cdf0e10cSrcweir                 case ocSqrt             : ScSqrt();                     break;
3508cdf0e10cSrcweir                 case ocFact             : ScFact();                     break;
3509cdf0e10cSrcweir                 case ocGetYear          : ScGetYear();                  break;
3510cdf0e10cSrcweir                 case ocGetMonth         : ScGetMonth();                 break;
3511cdf0e10cSrcweir                 case ocGetDay           : ScGetDay();                   break;
3512cdf0e10cSrcweir                 case ocGetDayOfWeek     : ScGetDayOfWeek();             break;
3513cdf0e10cSrcweir                 case ocWeek             : ScGetWeekOfYear();            break;
3514cdf0e10cSrcweir                 case ocEasterSunday     : ScEasterSunday();             break;
3515cdf0e10cSrcweir                 case ocGetHour          : ScGetHour();                  break;
3516cdf0e10cSrcweir                 case ocGetMin           : ScGetMin();                   break;
3517cdf0e10cSrcweir                 case ocGetSec           : ScGetSec();                   break;
3518cdf0e10cSrcweir                 case ocPlusMinus        : ScPlusMinus();                break;
3519cdf0e10cSrcweir                 case ocAbs              : ScAbs();                      break;
3520cdf0e10cSrcweir                 case ocInt              : ScInt();                      break;
3521cdf0e10cSrcweir                 case ocEven             : ScEven();                     break;
3522cdf0e10cSrcweir                 case ocOdd              : ScOdd();                      break;
3523cdf0e10cSrcweir                 case ocPhi              : ScPhi();                      break;
3524cdf0e10cSrcweir                 case ocGauss            : ScGauss();                    break;
3525cdf0e10cSrcweir                 case ocStdNormDist      : ScStdNormDist();              break;
3526cdf0e10cSrcweir                 case ocFisher           : ScFisher();                   break;
3527cdf0e10cSrcweir                 case ocFisherInv        : ScFisherInv();                break;
3528cdf0e10cSrcweir                 case ocIsEmpty          : ScIsEmpty();                  break;
3529cdf0e10cSrcweir                 case ocIsString         : ScIsString();                 break;
3530cdf0e10cSrcweir                 case ocIsNonString      : ScIsNonString();              break;
3531cdf0e10cSrcweir                 case ocIsLogical        : ScIsLogical();                break;
3532cdf0e10cSrcweir                 case ocType             : ScType();                     break;
3533cdf0e10cSrcweir                 case ocCell             : ScCell();                     break;
3534cdf0e10cSrcweir                 case ocIsRef            : ScIsRef();                    break;
3535cdf0e10cSrcweir                 case ocIsValue          : ScIsValue();                  break;
3536cdf0e10cSrcweir                 case ocIsFormula        : ScIsFormula();                break;
3537cdf0e10cSrcweir                 case ocFormula          : ScFormula();                  break;
3538cdf0e10cSrcweir                 case ocIsNA             : ScIsNV();                     break;
3539cdf0e10cSrcweir                 case ocIsErr            : ScIsErr();                    break;
3540cdf0e10cSrcweir                 case ocIsError          : ScIsError();                  break;
3541cdf0e10cSrcweir                 case ocIsEven           : ScIsEven();                   break;
3542cdf0e10cSrcweir                 case ocIsOdd            : ScIsOdd();                    break;
3543cdf0e10cSrcweir                 case ocN                : ScN();                        break;
3544cdf0e10cSrcweir                 case ocGetDateValue     : ScGetDateValue();             break;
3545cdf0e10cSrcweir                 case ocGetTimeValue     : ScGetTimeValue();             break;
3546cdf0e10cSrcweir                 case ocCode             : ScCode();                     break;
3547cdf0e10cSrcweir                 case ocTrim             : ScTrim();                     break;
3548cdf0e10cSrcweir                 case ocUpper            : ScUpper();                    break;
3549cdf0e10cSrcweir                 case ocPropper          : ScPropper();                  break;
3550cdf0e10cSrcweir                 case ocLower            : ScLower();                    break;
3551cdf0e10cSrcweir                 case ocLen              : ScLen();                      break;
3552cdf0e10cSrcweir                 case ocT                : ScT();                        break;
3553cdf0e10cSrcweir                 case ocClean            : ScClean();                    break;
3554cdf0e10cSrcweir                 case ocValue            : ScValue();                    break;
3555cdf0e10cSrcweir                 case ocChar             : ScChar();                     break;
3556cdf0e10cSrcweir                 case ocArcTan2          : ScArcTan2();                  break;
3557cdf0e10cSrcweir                 case ocMod              : ScMod();                      break;
3558cdf0e10cSrcweir                 case ocPower            : ScPower();                    break;
3559cdf0e10cSrcweir                 case ocRound            : ScRound();                    break;
3560cdf0e10cSrcweir                 case ocRoundUp          : ScRoundUp();                  break;
3561cdf0e10cSrcweir                 case ocTrunc            :
3562cdf0e10cSrcweir                 case ocRoundDown        : ScRoundDown();                break;
3563cdf0e10cSrcweir                 case ocCeil             : ScCeil();                     break;
3564cdf0e10cSrcweir                 case ocFloor            : ScFloor();                    break;
3565cdf0e10cSrcweir                 case ocSumProduct       : ScSumProduct();               break;
3566cdf0e10cSrcweir                 case ocSumSQ            : ScSumSQ();                    break;
3567cdf0e10cSrcweir                 case ocSumX2MY2         : ScSumX2MY2();                 break;
3568cdf0e10cSrcweir                 case ocSumX2DY2         : ScSumX2DY2();                 break;
3569cdf0e10cSrcweir                 case ocSumXMY2          : ScSumXMY2();                  break;
3570cdf0e10cSrcweir                 case ocLog              : ScLog();                      break;
3571cdf0e10cSrcweir                 case ocGCD              : ScGCD();                      break;
3572cdf0e10cSrcweir                 case ocLCM              : ScLCM();                      break;
3573cdf0e10cSrcweir                 case ocGetDate          : ScGetDate();                  break;
3574cdf0e10cSrcweir                 case ocGetTime          : ScGetTime();                  break;
3575cdf0e10cSrcweir                 case ocGetDiffDate      : ScGetDiffDate();              break;
3576cdf0e10cSrcweir                 case ocGetDiffDate360   : ScGetDiffDate360();           break;
3577cdf0e10cSrcweir                 case ocMin              : ScMin( sal_False );               break;
3578cdf0e10cSrcweir                 case ocMinA             : ScMin( sal_True );                break;
3579cdf0e10cSrcweir                 case ocMax              : ScMax( sal_False );               break;
3580cdf0e10cSrcweir                 case ocMaxA             : ScMax( sal_True );                break;
3581cdf0e10cSrcweir                 case ocSum              : ScSum();                      break;
3582cdf0e10cSrcweir                 case ocProduct          : ScProduct();                  break;
3583cdf0e10cSrcweir                 case ocNPV              : ScNPV();                      break;
3584cdf0e10cSrcweir                 case ocIRR              : ScIRR();                      break;
3585cdf0e10cSrcweir                 case ocMIRR             : ScMIRR();                     break;
3586cdf0e10cSrcweir                 case ocISPMT            : ScISPMT();                    break;
3587cdf0e10cSrcweir                 case ocAverage          : ScAverage( sal_False );           break;
3588cdf0e10cSrcweir                 case ocAverageA         : ScAverage( sal_True );            break;
3589cdf0e10cSrcweir                 case ocCount            : ScCount();                    break;
3590cdf0e10cSrcweir                 case ocCount2           : ScCount2();                   break;
3591cdf0e10cSrcweir                 case ocVar              : ScVar( sal_False );               break;
3592cdf0e10cSrcweir                 case ocVarA             : ScVar( sal_True );                break;
3593cdf0e10cSrcweir                 case ocVarP             : ScVarP( sal_False );              break;
3594cdf0e10cSrcweir                 case ocVarPA            : ScVarP( sal_True );               break;
3595cdf0e10cSrcweir                 case ocStDev            : ScStDev( sal_False );             break;
3596cdf0e10cSrcweir                 case ocStDevA           : ScStDev( sal_True );              break;
3597cdf0e10cSrcweir                 case ocStDevP           : ScStDevP( sal_False );            break;
3598cdf0e10cSrcweir                 case ocStDevPA          : ScStDevP( sal_True );             break;
3599cdf0e10cSrcweir                 case ocBW               : ScBW();                       break;
3600cdf0e10cSrcweir                 case ocDIA              : ScDIA();                      break;
3601cdf0e10cSrcweir                 case ocGDA              : ScGDA();                      break;
3602cdf0e10cSrcweir                 case ocGDA2             : ScGDA2();                     break;
3603cdf0e10cSrcweir                 case ocVBD              : ScVDB();                      break;
3604cdf0e10cSrcweir                 case ocLaufz            : ScLaufz();                    break;
3605cdf0e10cSrcweir                 case ocLIA              : ScLIA();                      break;
3606cdf0e10cSrcweir                 case ocRMZ              : ScRMZ();                      break;
3607cdf0e10cSrcweir                 case ocColumns          : ScColumns();                  break;
3608cdf0e10cSrcweir                 case ocRows             : ScRows();                     break;
3609cdf0e10cSrcweir                 case ocTables           : ScTables();                   break;
3610cdf0e10cSrcweir                 case ocColumn           : ScColumn();                   break;
3611cdf0e10cSrcweir                 case ocRow              : ScRow();                      break;
3612cdf0e10cSrcweir                 case ocTable            : ScTable();                    break;
3613cdf0e10cSrcweir                 case ocZGZ              : ScZGZ();                      break;
3614cdf0e10cSrcweir                 case ocZW               : ScZW();                       break;
3615cdf0e10cSrcweir                 case ocZZR              : ScZZR();                      break;
3616cdf0e10cSrcweir                 case ocZins             : ScZins();                     break;
3617cdf0e10cSrcweir                 case ocZinsZ            : ScZinsZ();                    break;
3618cdf0e10cSrcweir                 case ocKapz             : ScKapz();                     break;
3619cdf0e10cSrcweir                 case ocKumZinsZ         : ScKumZinsZ();                 break;
3620cdf0e10cSrcweir                 case ocKumKapZ          : ScKumKapZ();                  break;
3621cdf0e10cSrcweir                 case ocEffektiv         : ScEffektiv();                 break;
3622cdf0e10cSrcweir                 case ocNominal          : ScNominal();                  break;
3623cdf0e10cSrcweir                 case ocSubTotal         : ScSubTotal();                 break;
3624cdf0e10cSrcweir                 case ocDBSum            : ScDBSum();                    break;
3625cdf0e10cSrcweir                 case ocDBCount          : ScDBCount();                  break;
3626cdf0e10cSrcweir                 case ocDBCount2         : ScDBCount2();                 break;
3627cdf0e10cSrcweir                 case ocDBAverage        : ScDBAverage();                break;
3628cdf0e10cSrcweir                 case ocDBGet            : ScDBGet();                    break;
3629cdf0e10cSrcweir                 case ocDBMax            : ScDBMax();                    break;
3630cdf0e10cSrcweir                 case ocDBMin            : ScDBMin();                    break;
3631cdf0e10cSrcweir                 case ocDBProduct        : ScDBProduct();                break;
3632cdf0e10cSrcweir                 case ocDBStdDev         : ScDBStdDev();                 break;
3633cdf0e10cSrcweir                 case ocDBStdDevP        : ScDBStdDevP();                break;
3634cdf0e10cSrcweir                 case ocDBVar            : ScDBVar();                    break;
3635cdf0e10cSrcweir                 case ocDBVarP           : ScDBVarP();                   break;
3636cdf0e10cSrcweir                 case ocIndirect         : ScIndirect();                 break;
3637cdf0e10cSrcweir                 case ocAddress          : ScAddressFunc();              break;
3638cdf0e10cSrcweir                 case ocMatch            : ScMatch();                    break;
3639cdf0e10cSrcweir                 case ocCountEmptyCells  : ScCountEmptyCells();          break;
3640cdf0e10cSrcweir                 case ocCountIf          : ScCountIf();                  break;
3641cdf0e10cSrcweir                 case ocSumIf            : ScSumIf();                    break;
3642f53782ebSAndrew Rist                 case ocAverageIf        : ScAverageIf();                break;
36431b1b70fbSAndrew Rist                 case ocSumIfs           : ScSumIfs();                   break;
36441b1b70fbSAndrew Rist                 case ocAverageIfs       : ScAverageIfs();               break;
36451b1b70fbSAndrew Rist                 case ocCountIfs         : ScCountIfs();                 break;
3646cdf0e10cSrcweir                 case ocLookup           : ScLookup();                   break;
3647cdf0e10cSrcweir                 case ocVLookup          : ScVLookup();                  break;
3648cdf0e10cSrcweir                 case ocHLookup          : ScHLookup();                  break;
3649cdf0e10cSrcweir                 case ocIndex            : ScIndex();                    break;
3650cdf0e10cSrcweir                 case ocMultiArea        : ScMultiArea();                break;
3651cdf0e10cSrcweir                 case ocOffset           : ScOffset();                   break;
3652cdf0e10cSrcweir                 case ocAreas            : ScAreas();                    break;
3653cdf0e10cSrcweir                 case ocCurrency         : ScCurrency();                 break;
3654cdf0e10cSrcweir                 case ocReplace          : ScReplace();                  break;
3655cdf0e10cSrcweir                 case ocFixed            : ScFixed();                    break;
3656cdf0e10cSrcweir                 case ocFind             : ScFind();                     break;
3657cdf0e10cSrcweir                 case ocExact            : ScExact();                    break;
3658cdf0e10cSrcweir                 case ocLeft             : ScLeft();                     break;
3659cdf0e10cSrcweir                 case ocRight            : ScRight();                    break;
3660cdf0e10cSrcweir                 case ocSearch           : ScSearch();                   break;
3661cdf0e10cSrcweir                 case ocMid              : ScMid();                      break;
3662cdf0e10cSrcweir                 case ocText             : ScText();                     break;
3663cdf0e10cSrcweir                 case ocSubstitute       : ScSubstitute();               break;
3664cdf0e10cSrcweir                 case ocRept             : ScRept();                     break;
3665cdf0e10cSrcweir                 case ocConcat           : ScConcat();                   break;
3666cdf0e10cSrcweir                 case ocMatValue         : ScMatValue();                 break;
3667cdf0e10cSrcweir                 case ocMatrixUnit       : ScEMat();                     break;
3668cdf0e10cSrcweir                 case ocMatDet           : ScMatDet();                   break;
3669cdf0e10cSrcweir                 case ocMatInv           : ScMatInv();                   break;
3670cdf0e10cSrcweir                 case ocMatMult          : ScMatMult();                  break;
3671cdf0e10cSrcweir                 case ocMatTrans         : ScMatTrans();                 break;
3672cdf0e10cSrcweir                 case ocMatRef           : ScMatRef();                   break;
3673cdf0e10cSrcweir                 case ocBackSolver       : ScBackSolver();               break;
3674cdf0e10cSrcweir                 case ocB                : ScB();                        break;
3675cdf0e10cSrcweir                 case ocNormDist         : ScNormDist();                 break;
3676cdf0e10cSrcweir                 case ocExpDist          : ScExpDist();                  break;
3677cdf0e10cSrcweir                 case ocBinomDist        : ScBinomDist();                break;
3678cdf0e10cSrcweir                 case ocPoissonDist      : ScPoissonDist();              break;
3679cdf0e10cSrcweir                 case ocKombin           : ScKombin();                   break;
3680cdf0e10cSrcweir                 case ocKombin2          : ScKombin2();                  break;
3681cdf0e10cSrcweir                 case ocVariationen      : ScVariationen();              break;
3682cdf0e10cSrcweir                 case ocVariationen2     : ScVariationen2();             break;
3683cdf0e10cSrcweir                 case ocHypGeomDist      : ScHypGeomDist();              break;
3684cdf0e10cSrcweir                 case ocLogNormDist      : ScLogNormDist();              break;
3685cdf0e10cSrcweir                 case ocTDist            : ScTDist();                    break;
3686cdf0e10cSrcweir                 case ocFDist            : ScFDist();                    break;
3687cdf0e10cSrcweir                 case ocChiDist          : ScChiDist();                  break;
3688cdf0e10cSrcweir                 case ocChiSqDist        : ScChiSqDist();                break;
3689cdf0e10cSrcweir                 case ocStandard         : ScStandard();                 break;
3690cdf0e10cSrcweir                 case ocAveDev           : ScAveDev();                   break;
3691cdf0e10cSrcweir                 case ocDevSq            : ScDevSq();                    break;
3692cdf0e10cSrcweir                 case ocKurt             : ScKurt();                     break;
3693cdf0e10cSrcweir                 case ocSchiefe          : ScSkew();                     break;
3694cdf0e10cSrcweir                 case ocModalValue       : ScModalValue();               break;
3695cdf0e10cSrcweir                 case ocMedian           : ScMedian();                   break;
3696cdf0e10cSrcweir                 case ocGeoMean          : ScGeoMean();                  break;
3697cdf0e10cSrcweir                 case ocHarMean          : ScHarMean();                  break;
3698cdf0e10cSrcweir                 case ocWeibull          : ScWeibull();                  break;
3699cdf0e10cSrcweir                 case ocKritBinom        : ScCritBinom();                break;
3700cdf0e10cSrcweir                 case ocNegBinomVert     : ScNegBinomDist();             break;
3701cdf0e10cSrcweir                 case ocNoName           : ScNoName();                   break;
3702cdf0e10cSrcweir                 case ocBad              : ScBadName();                  break;
3703cdf0e10cSrcweir                 case ocZTest            : ScZTest();                    break;
3704cdf0e10cSrcweir                 case ocTTest            : ScTTest();                    break;
3705cdf0e10cSrcweir                 case ocFTest            : ScFTest();                    break;
3706cdf0e10cSrcweir                 case ocRank             : ScRank();                     break;
3707cdf0e10cSrcweir                 case ocPercentile       : ScPercentile();               break;
3708cdf0e10cSrcweir                 case ocPercentrank      : ScPercentrank();              break;
3709cdf0e10cSrcweir                 case ocLarge            : ScLarge();                    break;
3710cdf0e10cSrcweir                 case ocSmall            : ScSmall();                    break;
3711cdf0e10cSrcweir                 case ocFrequency        : ScFrequency();                break;
3712cdf0e10cSrcweir                 case ocQuartile         : ScQuartile();                 break;
3713cdf0e10cSrcweir                 case ocNormInv          : ScNormInv();                  break;
3714cdf0e10cSrcweir                 case ocSNormInv         : ScSNormInv();                 break;
3715cdf0e10cSrcweir                 case ocConfidence       : ScConfidence();               break;
3716cdf0e10cSrcweir                 case ocTrimMean         : ScTrimMean();                 break;
3717cdf0e10cSrcweir                 case ocProb             : ScProbability();              break;
3718cdf0e10cSrcweir                 case ocCorrel           : ScCorrel();                   break;
3719cdf0e10cSrcweir                 case ocCovar            : ScCovar();                    break;
3720cdf0e10cSrcweir                 case ocPearson          : ScPearson();                  break;
3721cdf0e10cSrcweir                 case ocRSQ              : ScRSQ();                      break;
3722cdf0e10cSrcweir                 case ocSTEYX            : ScSTEXY();                    break;
3723cdf0e10cSrcweir                 case ocSlope            : ScSlope();                    break;
3724cdf0e10cSrcweir                 case ocIntercept        : ScIntercept();                break;
3725cdf0e10cSrcweir                 case ocTrend            : ScTrend();                    break;
3726cdf0e10cSrcweir                 case ocGrowth           : ScGrowth();                   break;
3727cdf0e10cSrcweir                 case ocRGP              : ScRGP();                      break;
3728cdf0e10cSrcweir                 case ocRKP              : ScRKP();                      break;
3729cdf0e10cSrcweir                 case ocForecast         : ScForecast();                 break;
3730cdf0e10cSrcweir                 case ocGammaLn          : ScLogGamma();                 break;
3731cdf0e10cSrcweir                 case ocGamma            : ScGamma();                    break;
3732cdf0e10cSrcweir                 case ocGammaDist        : ScGammaDist();                break;
3733cdf0e10cSrcweir                 case ocGammaInv         : ScGammaInv();                 break;
3734cdf0e10cSrcweir                 case ocChiTest          : ScChiTest();                  break;
3735cdf0e10cSrcweir                 case ocChiInv           : ScChiInv();                   break;
3736cdf0e10cSrcweir                 case ocChiSqInv         : ScChiSqInv();                 break;
3737cdf0e10cSrcweir                 case ocTInv             : ScTInv();                     break;
3738cdf0e10cSrcweir                 case ocFInv             : ScFInv();                     break;
3739cdf0e10cSrcweir                 case ocLogInv           : ScLogNormInv();               break;
3740cdf0e10cSrcweir                 case ocBetaDist         : ScBetaDist();                 break;
3741cdf0e10cSrcweir                 case ocBetaInv          : ScBetaInv();                  break;
3742cdf0e10cSrcweir                 case ocExternal         : ScExternal();                 break;
3743cdf0e10cSrcweir                 case ocTableOp          : ScTableOp();                  break;
3744cdf0e10cSrcweir //              case ocErrCell          : ScErrCell();                  break;
3745cdf0e10cSrcweir                 case ocStop :                                           break;
3746cdf0e10cSrcweir                 case ocErrorType        : ScErrorType();                break;
3747cdf0e10cSrcweir                 case ocCurrent          : ScCurrent();                  break;
3748cdf0e10cSrcweir                 case ocStyle            : ScStyle();                    break;
3749cdf0e10cSrcweir                 case ocDde              : ScDde();                      break;
3750cdf0e10cSrcweir                 case ocBase             : ScBase();                     break;
3751cdf0e10cSrcweir                 case ocDecimal          : ScDecimal();                  break;
3752cdf0e10cSrcweir                 case ocConvert          : ScConvert();                  break;
3753cdf0e10cSrcweir                 case ocEuroConvert      : ScEuroConvert();              break;
3754cdf0e10cSrcweir                 case ocRoman            : ScRoman();                    break;
3755cdf0e10cSrcweir                 case ocArabic           : ScArabic();                   break;
3756cdf0e10cSrcweir                 case ocInfo             : ScInfo();                     break;
3757cdf0e10cSrcweir                 case ocHyperLink        : ScHyperLink();                break;
3758cdf0e10cSrcweir                 case ocBahtText         : ScBahtText();                 break;
3759cdf0e10cSrcweir                 case ocGetPivotData     : ScGetPivotData();             break;
3760cdf0e10cSrcweir                 case ocJis              : ScJis();                      break;
3761cdf0e10cSrcweir                 case ocAsc              : ScAsc();                      break;
376239c2db0bSWang Lei                 case ocLenB             : ScLenB();                     break;
376339c2db0bSWang Lei                 case ocRightB           : ScRightB();                   break;
376439c2db0bSWang Lei                 case ocLeftB            : ScLeftB();                    break;
376539c2db0bSWang Lei                 case ocMidB             : ScMidB();                     break;
3766cdf0e10cSrcweir                 case ocUnicode          : ScUnicode();                  break;
3767cdf0e10cSrcweir                 case ocUnichar          : ScUnichar();                  break;
3768cdf0e10cSrcweir                 case ocTTT              : ScTTT();                      break;
37690f94c4d7SDamjan Jovanovic                 case ocBitAnd           : ScBitAnd();                   break;
37700f94c4d7SDamjan Jovanovic                 case ocBitOr            : ScBitOr();                    break;
37710f94c4d7SDamjan Jovanovic                 case ocBitXor           : ScBitXor();                   break;
3772*a940b7f5Sasf-sync-process                 case ocBitLShift        : ScBitLShift();                break;
3773*a940b7f5Sasf-sync-process                 case ocBitRShift        : ScBitRShift();                break;
3774cdf0e10cSrcweir                 case ocNone : nFuncFmtType = NUMBERFORMAT_UNDEFINED;    break;
3775cdf0e10cSrcweir                 default : PushError( errUnknownOpCode);                 break;
3776cdf0e10cSrcweir             }
3777cdf0e10cSrcweir 
3778cdf0e10cSrcweir             // If the function pushed a subroutine as result, continue with
3779cdf0e10cSrcweir             // execution of the subroutine.
3780cdf0e10cSrcweir             if (sp > nStackBase && pStack[sp-1]->GetOpCode() == ocCall && pStack[sp-1]->GetType() == svSubroutine)
3781cdf0e10cSrcweir             {
3782cdf0e10cSrcweir                 FormulaTokenRef xTok = PopToken();
3783cdf0e10cSrcweir                 const FormulaSubroutineToken* pSub = dynamic_cast<FormulaSubroutineToken*>(xTok.get());
3784cdf0e10cSrcweir                 if (pSub)
3785cdf0e10cSrcweir                 {
3786cdf0e10cSrcweir                     // Remember token for late destruction.
3787cdf0e10cSrcweir                     if (!pTokenDtor)
3788cdf0e10cSrcweir                         pTokenDtor.reset( new FormulaTokenDtor);
3789cdf0e10cSrcweir                     pTokenDtor->push_back( FormulaTokenDtor::value_type( xTok));
3790cdf0e10cSrcweir                     // Continue with execution of subroutine.
3791cdf0e10cSrcweir                     aCode.Push( pSub->GetTokenArray());
3792cdf0e10cSrcweir                     continue;   // while( ( pCur = aCode.Next() ) != NULL  ...
3793cdf0e10cSrcweir                 }
3794cdf0e10cSrcweir                 else
3795cdf0e10cSrcweir                 {
3796cdf0e10cSrcweir                     DBG_ERRORFILE( "ScInterpreter::Interpret: ocCall svSubroutine, but no FormulaSubroutineToken?!?");
3797cdf0e10cSrcweir                     PushError( errNoCode);
3798cdf0e10cSrcweir                 }
3799cdf0e10cSrcweir             }
3800cdf0e10cSrcweir 
3801cdf0e10cSrcweir             // Remember result matrix in case it could be reused.
3802cdf0e10cSrcweir             if (pTokenMatrixMap && sp && GetStackType() == svMatrix)
3803cdf0e10cSrcweir                 pTokenMatrixMap->insert( ScTokenMatrixMap::value_type( pCur,
3804cdf0e10cSrcweir                             pStack[sp-1]));
3805cdf0e10cSrcweir 
3806cdf0e10cSrcweir             // outer function determines format of an expression
3807cdf0e10cSrcweir             if ( nFuncFmtType != NUMBERFORMAT_UNDEFINED )
3808cdf0e10cSrcweir             {
3809cdf0e10cSrcweir                 nRetTypeExpr = nFuncFmtType;
3810cdf0e10cSrcweir                 // inherit the format index only for currency formats
3811cdf0e10cSrcweir                 nRetIndexExpr = ( nFuncFmtType == NUMBERFORMAT_CURRENCY ?
3812cdf0e10cSrcweir                     nFuncFmtIndex : 0 );
3813cdf0e10cSrcweir             }
3814cdf0e10cSrcweir         }
3815cdf0e10cSrcweir 
3816cdf0e10cSrcweir         // Need a clean stack environment for the JumpMatrix to work.
3817cdf0e10cSrcweir         if (nGlobalError && eOp != ocPush && sp > nStackBase + 1)
3818cdf0e10cSrcweir         {
3819cdf0e10cSrcweir             // Not all functions pop all parameters in case an error is
3820cdf0e10cSrcweir             // generated. Clean up stack. Assumes that every function pushes a
3821cdf0e10cSrcweir             // result, may be arbitrary in case of error.
3822cdf0e10cSrcweir             const FormulaToken* pLocalResult = pStack[ sp - 1 ];
3823cdf0e10cSrcweir             while (sp > nStackBase)
3824cdf0e10cSrcweir                 Pop();
3825cdf0e10cSrcweir             PushTempToken( *pLocalResult );
3826cdf0e10cSrcweir         }
3827cdf0e10cSrcweir 
3828cdf0e10cSrcweir         bool bGotResult;
3829cdf0e10cSrcweir         do
3830cdf0e10cSrcweir         {
3831cdf0e10cSrcweir             bGotResult = false;
3832cdf0e10cSrcweir             sal_uInt8 nLevel = 0;
3833cdf0e10cSrcweir             if ( GetStackType( ++nLevel ) == svJumpMatrix )
3834cdf0e10cSrcweir                 ;   // nothing
3835cdf0e10cSrcweir             else if ( GetStackType( ++nLevel ) == svJumpMatrix )
3836cdf0e10cSrcweir                 ;   // nothing
3837cdf0e10cSrcweir             else
3838cdf0e10cSrcweir                 nLevel = 0;
3839cdf0e10cSrcweir             if ( nLevel == 1 || (nLevel == 2 && aCode.IsEndOfPath()) )
3840cdf0e10cSrcweir                 bGotResult = JumpMatrix( nLevel );
3841cdf0e10cSrcweir             else
3842cdf0e10cSrcweir                 pJumpMatrix = NULL;
3843cdf0e10cSrcweir         } while ( bGotResult );
3844cdf0e10cSrcweir 
3845cdf0e10cSrcweir 
3846cdf0e10cSrcweir // Functions that evaluate an error code and directly set nGlobalError to 0,
3847cdf0e10cSrcweir // usage: switch( OpCode ) { CASE_OCERRFUNC statements; }
3848cdf0e10cSrcweir #define CASE_OCERRFUNC \
3849cdf0e10cSrcweir     case ocCount : \
3850cdf0e10cSrcweir     case ocCount2 : \
3851cdf0e10cSrcweir     case ocErrorType : \
3852cdf0e10cSrcweir     case ocIsEmpty : \
3853cdf0e10cSrcweir     case ocIsErr : \
3854cdf0e10cSrcweir     case ocIsError : \
3855cdf0e10cSrcweir     case ocIsFormula : \
3856cdf0e10cSrcweir     case ocIsLogical : \
3857cdf0e10cSrcweir     case ocIsNA : \
3858cdf0e10cSrcweir     case ocIsNonString : \
3859cdf0e10cSrcweir     case ocIsRef : \
3860cdf0e10cSrcweir     case ocIsString : \
3861cdf0e10cSrcweir     case ocIsValue : \
3862cdf0e10cSrcweir     case ocN : \
3863cdf0e10cSrcweir     case ocType :
3864cdf0e10cSrcweir 
3865cdf0e10cSrcweir         switch ( eOp )
3866cdf0e10cSrcweir         {
3867cdf0e10cSrcweir             CASE_OCERRFUNC
3868cdf0e10cSrcweir                  ++ nErrorFunction;
3869cdf0e10cSrcweir             default:
3870cdf0e10cSrcweir                 ;   // nothing
3871cdf0e10cSrcweir         }
3872cdf0e10cSrcweir         if ( nGlobalError )
3873cdf0e10cSrcweir         {
3874cdf0e10cSrcweir             if ( !nErrorFunctionCount )
3875cdf0e10cSrcweir             {   // count of errorcode functions in formula
3876cdf0e10cSrcweir                 for ( FormulaToken* t = rArr.FirstRPN(); t; t = rArr.NextRPN() )
3877cdf0e10cSrcweir                 {
3878cdf0e10cSrcweir                     switch ( t->GetOpCode() )
3879cdf0e10cSrcweir                     {
3880cdf0e10cSrcweir                         CASE_OCERRFUNC
3881cdf0e10cSrcweir                              ++nErrorFunctionCount;
3882cdf0e10cSrcweir                         default:
3883cdf0e10cSrcweir                             ;   // nothing
3884cdf0e10cSrcweir                     }
3885cdf0e10cSrcweir                 }
3886cdf0e10cSrcweir             }
3887cdf0e10cSrcweir             if ( nErrorFunction >= nErrorFunctionCount )
3888cdf0e10cSrcweir                 ++nErrorFunction;   // that's it, error => terminate
3889cdf0e10cSrcweir         }
3890cdf0e10cSrcweir     }
3891cdf0e10cSrcweir 
3892cdf0e10cSrcweir     // End: obtain result
3893cdf0e10cSrcweir 
389461e64f4aSWang Lei     bRefFunc = false;
3895cdf0e10cSrcweir     if( sp )
3896cdf0e10cSrcweir     {
3897cdf0e10cSrcweir         pCur = pStack[ sp-1 ];
3898cdf0e10cSrcweir         if( pCur->GetOpCode() == ocPush )
3899cdf0e10cSrcweir         {
3900cdf0e10cSrcweir             switch( pCur->GetType() )
3901cdf0e10cSrcweir             {
3902cdf0e10cSrcweir                 case svEmptyCell:
3903cdf0e10cSrcweir                     ;   // nothing
3904cdf0e10cSrcweir                 break;
3905cdf0e10cSrcweir                 case svError:
3906cdf0e10cSrcweir                     nGlobalError = pCur->GetError();
3907cdf0e10cSrcweir                 break;
3908cdf0e10cSrcweir                 case svDouble :
3909cdf0e10cSrcweir                     if ( nFuncFmtType == NUMBERFORMAT_UNDEFINED )
3910cdf0e10cSrcweir                     {
3911cdf0e10cSrcweir                         nRetTypeExpr = NUMBERFORMAT_NUMBER;
3912cdf0e10cSrcweir                         nRetIndexExpr = 0;
3913cdf0e10cSrcweir                     }
3914cdf0e10cSrcweir                 break;
3915cdf0e10cSrcweir                 case svString :
3916cdf0e10cSrcweir                     nRetTypeExpr = NUMBERFORMAT_TEXT;
3917cdf0e10cSrcweir                     nRetIndexExpr = 0;
3918cdf0e10cSrcweir                 break;
3919cdf0e10cSrcweir                 case svSingleRef :
3920cdf0e10cSrcweir                 {
392161e64f4aSWang Lei                     bRefFunc = true;
3922cdf0e10cSrcweir                     ScAddress aAdr;
3923cdf0e10cSrcweir                     PopSingleRef( aAdr );
3924cdf0e10cSrcweir                     if( !nGlobalError )
3925cdf0e10cSrcweir                         PushCellResultToken( false, aAdr,
3926cdf0e10cSrcweir                                 &nRetTypeExpr, &nRetIndexExpr);
3927cdf0e10cSrcweir                 }
3928cdf0e10cSrcweir                 break;
3929cdf0e10cSrcweir                 case svRefList :
3930cdf0e10cSrcweir                     PopError();     // maybe #REF! takes precedence over #VALUE!
3931cdf0e10cSrcweir                     PushError( errNoValue);
3932cdf0e10cSrcweir                 break;
3933cdf0e10cSrcweir                 case svDoubleRef :
3934cdf0e10cSrcweir                 {
3935cdf0e10cSrcweir                     if ( bMatrixFormula )
3936cdf0e10cSrcweir                     {   // create matrix for {=A1:A5}
3937cdf0e10cSrcweir                         PopDoubleRefPushMatrix();
3938cdf0e10cSrcweir                         // no break, continue with svMatrix
3939cdf0e10cSrcweir                     }
3940cdf0e10cSrcweir                     else
3941cdf0e10cSrcweir                     {
394261e64f4aSWang Lei                         bRefFunc = true;
3943cdf0e10cSrcweir                         ScRange aRange;
3944cdf0e10cSrcweir                         PopDoubleRef( aRange );
3945cdf0e10cSrcweir                         ScAddress aAdr;
3946cdf0e10cSrcweir                         if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr))
3947cdf0e10cSrcweir                             PushCellResultToken( false, aAdr,
3948cdf0e10cSrcweir                                     &nRetTypeExpr, &nRetIndexExpr);
3949cdf0e10cSrcweir                         break;
3950cdf0e10cSrcweir                     }
3951cdf0e10cSrcweir                 }
3952cdf0e10cSrcweir                 // no break
3953cdf0e10cSrcweir                 case svMatrix :
3954cdf0e10cSrcweir                 {
3955cdf0e10cSrcweir                     ScMatrixRef xMat = PopMatrix();
3956cdf0e10cSrcweir                     if (xMat)
3957cdf0e10cSrcweir                     {
3958cdf0e10cSrcweir                         ScMatValType nMatValType;
3959cdf0e10cSrcweir                         const ScMatrixValue* pMatVal = xMat->Get(0, 0, nMatValType);
3960cdf0e10cSrcweir                         if ( pMatVal )
3961cdf0e10cSrcweir                         {
3962cdf0e10cSrcweir                             if (ScMatrix::IsNonValueType( nMatValType))
3963cdf0e10cSrcweir                             {
3964cdf0e10cSrcweir                                 if ( xMat->IsEmptyPath( 0, 0))
3965cdf0e10cSrcweir                                 {   // result of empty sal_False jump path
3966cdf0e10cSrcweir                                     FormulaTokenRef xRes = new FormulaDoubleToken( 0.0);
3967cdf0e10cSrcweir                                     PushTempToken( new ScMatrixCellResultToken( xMat, xRes));
3968cdf0e10cSrcweir                                     nRetTypeExpr = NUMBERFORMAT_LOGICAL;
3969cdf0e10cSrcweir                                 }
3970cdf0e10cSrcweir                                 else
3971cdf0e10cSrcweir                                 {
3972cdf0e10cSrcweir                                     String aStr( pMatVal->GetString());
3973cdf0e10cSrcweir                                     FormulaTokenRef xRes = new FormulaStringToken( aStr);
3974cdf0e10cSrcweir                                     PushTempToken( new ScMatrixCellResultToken( xMat, xRes));
3975cdf0e10cSrcweir                                     nRetTypeExpr = NUMBERFORMAT_TEXT;
3976cdf0e10cSrcweir                                 }
3977cdf0e10cSrcweir                             }
3978cdf0e10cSrcweir                             else
3979cdf0e10cSrcweir                             {
3980cdf0e10cSrcweir                                 sal_uInt16 nErr = GetDoubleErrorValue( pMatVal->fVal);
3981cdf0e10cSrcweir                                 FormulaTokenRef xRes;
3982cdf0e10cSrcweir                                 if (nErr)
3983cdf0e10cSrcweir                                     xRes = new FormulaErrorToken( nErr);
3984cdf0e10cSrcweir                                 else
3985cdf0e10cSrcweir                                     xRes = new FormulaDoubleToken( pMatVal->fVal);
3986cdf0e10cSrcweir                                 PushTempToken( new ScMatrixCellResultToken( xMat, xRes));
3987cdf0e10cSrcweir                                 if ( nRetTypeExpr != NUMBERFORMAT_LOGICAL )
3988cdf0e10cSrcweir                                     nRetTypeExpr = NUMBERFORMAT_NUMBER;
3989cdf0e10cSrcweir                             }
3990cdf0e10cSrcweir                             nRetIndexExpr = 0;
3991cdf0e10cSrcweir                         }
3992cdf0e10cSrcweir                         else
3993cdf0e10cSrcweir                             SetError( errUnknownStackVariable);
3994cdf0e10cSrcweir                         xMat->SetErrorInterpreter( NULL);
3995cdf0e10cSrcweir                     }
3996cdf0e10cSrcweir                     else
3997cdf0e10cSrcweir                         SetError( errUnknownStackVariable);
3998cdf0e10cSrcweir                 }
3999cdf0e10cSrcweir                 break;
4000cdf0e10cSrcweir                 default :
4001cdf0e10cSrcweir                     SetError( errUnknownStackVariable);
4002cdf0e10cSrcweir             }
4003cdf0e10cSrcweir         }
4004cdf0e10cSrcweir         else
4005cdf0e10cSrcweir             SetError( errUnknownStackVariable);
4006cdf0e10cSrcweir     }
4007cdf0e10cSrcweir     else
4008cdf0e10cSrcweir         SetError( errNoCode);
4009cdf0e10cSrcweir 
4010cdf0e10cSrcweir     if( nRetTypeExpr != NUMBERFORMAT_UNDEFINED )
4011cdf0e10cSrcweir     {
4012cdf0e10cSrcweir         nRetFmtType = nRetTypeExpr;
4013cdf0e10cSrcweir         nRetFmtIndex = nRetIndexExpr;
4014cdf0e10cSrcweir     }
4015cdf0e10cSrcweir     else if( nFuncFmtType != NUMBERFORMAT_UNDEFINED )
4016cdf0e10cSrcweir     {
4017cdf0e10cSrcweir         nRetFmtType = nFuncFmtType;
4018cdf0e10cSrcweir         nRetFmtIndex = nFuncFmtIndex;
4019cdf0e10cSrcweir     }
4020cdf0e10cSrcweir     else
4021cdf0e10cSrcweir         nRetFmtType = NUMBERFORMAT_NUMBER;
4022cdf0e10cSrcweir     // inherit the format index only for currency formats
4023cdf0e10cSrcweir     if ( nRetFmtType != NUMBERFORMAT_CURRENCY )
4024cdf0e10cSrcweir         nRetFmtIndex = 0;
4025cdf0e10cSrcweir 
4026cdf0e10cSrcweir     if (nGlobalError && GetStackType() != svError )
4027cdf0e10cSrcweir         PushError( nGlobalError);
4028cdf0e10cSrcweir 
4029cdf0e10cSrcweir     // THE final result.
4030cdf0e10cSrcweir     xResult = PopToken();
4031cdf0e10cSrcweir     if (!xResult)
4032cdf0e10cSrcweir         xResult = new FormulaErrorToken( errUnknownStackVariable);
4033cdf0e10cSrcweir 
4034cdf0e10cSrcweir     // release tokens in expression stack
4035cdf0e10cSrcweir     FormulaToken** p = pStack;
4036cdf0e10cSrcweir     while( maxsp-- )
4037cdf0e10cSrcweir         (*p++)->DecRef();
4038cdf0e10cSrcweir 
4039cdf0e10cSrcweir     StackVar eType = xResult->GetType();
4040cdf0e10cSrcweir     if (eType == svMatrix)
4041cdf0e10cSrcweir         // Results are immutable in case they would be reused as input for new
4042cdf0e10cSrcweir         // interpreters.
4043cdf0e10cSrcweir         static_cast<ScToken*>(xResult.operator->())->GetMatrix()->SetImmutable( true);
4044cdf0e10cSrcweir     return eType;
4045cdf0e10cSrcweir }
4046