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