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