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