LibreOffice Module sc (master) 1
parclass.cxx
Go to the documentation of this file.
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 <parclass.hxx>
21#include <global.hxx>
22#include <callform.hxx>
23#include <addincol.hxx>
24#include <formula/token.hxx>
26#include <osl/diagnose.h>
27#include <sal/log.hxx>
28#include <string.h>
29
30#if DEBUG_SC_PARCLASSDOC
31// the documentation thingy
32#include <com/sun/star/sheet/FormulaLanguage.hpp>
33#include <rtl/strbuf.hxx>
34#include <formula/funcvarargs.h>
35#include "compiler.hxx"
36#endif
37
38using namespace formula;
39
40/* Following assumptions are made:
41 * - OpCodes not specified at all will have at least one and only parameters of
42 * type Value, no check is done on the count of parameters => no Bounds type
43 * is returned.
44 * - For OpCodes with a variable number of parameters the type(s) of the last
45 * repeated parameter(s) specified determine(s) the type(s) of all following
46 * parameters.
47 */
48
50{
51 // { OpCode, {{ ParamClass, ... }, nRepeatLast, ReturnClass }},
52
53 // IF() and CHOOSE() are somewhat special, since the ScJumpMatrix is
54 // created inside those functions and ConvertMatrixParameters() is not
55 // called for them.
56 { ocIf, {{ Array, Reference, Reference }, 0, Value }},
57 { ocIfError, {{ Array, Reference }, 0, Value }},
58 { ocIfNA, {{ Array, Reference }, 0, Value }},
59 { ocChoose, {{ Array, Reference }, 1, Value }},
60 // Other specials.
61 { ocArrayClose, {{ Bounds }, 0, Bounds }},
62 { ocArrayColSep, {{ Bounds }, 0, Bounds }},
63 { ocArrayOpen, {{ Bounds }, 0, Bounds }},
64 { ocArrayRowSep, {{ Bounds }, 0, Bounds }},
65 { ocBad, {{ Bounds }, 0, Bounds }},
66 { ocClose, {{ Bounds }, 0, Bounds }},
67 { ocColRowName, {{ Bounds }, 0, Value }}, // or Reference?
68 { ocColRowNameAuto, {{ Bounds }, 0, Value }}, // or Reference?
69 { ocDBArea, {{ Bounds }, 0, Value }}, // or Reference?
70 { ocMatRef, {{ Bounds }, 0, Value }},
71 { ocMissing, {{ Bounds }, 0, Value }},
72 { ocNoName, {{ Bounds }, 0, Bounds }},
73 { ocOpen, {{ Bounds }, 0, Bounds }},
74 { ocSep, {{ Bounds }, 0, Bounds }},
75 { ocSkip, {{ Bounds }, 0, Bounds }},
76 { ocSpaces, {{ Bounds }, 0, Bounds }},
77 { ocStop, {{ Bounds }, 0, Bounds }},
78 { ocStringXML, {{ Bounds }, 0, Bounds }},
79 { ocTableRef, {{ Bounds }, 0, Value }}, // or Reference?
80 { ocTableRefClose, {{ Bounds }, 0, Bounds }},
81 { ocTableRefItemAll, {{ Bounds }, 0, Bounds }},
82 { ocTableRefItemData, {{ Bounds }, 0, Bounds }},
83 { ocTableRefItemHeaders, {{ Bounds }, 0, Bounds }},
84 { ocTableRefItemThisRow, {{ Bounds }, 0, Bounds }},
85 { ocTableRefItemTotals, {{ Bounds }, 0, Bounds }},
86 { ocTableRefOpen, {{ Bounds }, 0, Bounds }},
87 // Error constants.
88 { ocErrDivZero, {{ Bounds }, 0, Bounds }},
89 { ocErrNA, {{ Bounds }, 0, Bounds }},
90 { ocErrName, {{ Bounds }, 0, Bounds }},
91 { ocErrNull, {{ Bounds }, 0, Bounds }},
92 { ocErrNum, {{ Bounds }, 0, Bounds }},
93 { ocErrRef, {{ Bounds }, 0, Bounds }},
94 { ocErrValue, {{ Bounds }, 0, Bounds }},
95 // Functions with Value parameters only but not in resource.
96 { ocBackSolver, {{ Value, Value, Value }, 0, Value }},
97 { ocTableOp, {{ Value, Value, Value, Value, Value }, 0, Value }},
98 // Operators and functions.
99 { ocAdd, {{ Array, Array }, 0, Value }},
101 { ocAmpersand, {{ Array, Array }, 0, Value }},
102 { ocAnd, {{ Reference }, 1, Value }},
103 { ocAreas, {{ Reference }, 0, Value }},
104 { ocAveDev, {{ Reference }, 1, Value }},
105 { ocAverage, {{ ReferenceOrRefArray }, 1, Value }},
106 { ocAverageA, {{ ReferenceOrRefArray }, 1, Value }},
109 { ocCell, {{ Value, Reference }, 0, Value }},
110 { ocColumn, {{ Reference }, 0, Value }},
111 { ocColumns, {{ Reference }, 1, Value }},
112 { ocConcat_MS, {{ Reference }, 1, Value }},
113 { ocCorrel, {{ ForceArray, ForceArray }, 0, Value }},
114 { ocCount, {{ ReferenceOrRefArray }, 1, Value }},
115 { ocCount2, {{ ReferenceOrRefArray }, 1, Value }},
119 { ocCovar, {{ ForceArray, ForceArray }, 0, Value }},
122 { ocCurrent, {{ Bounds }, 0, Value }},
126 { ocDBGet, {{ Reference, Reference, Reference }, 0, Value }},
127 { ocDBMax, {{ Reference, Reference, Reference }, 0, Value }},
128 { ocDBMin, {{ Reference, Reference, Reference }, 0, Value }},
132 { ocDBSum, {{ Reference, Reference, Reference }, 0, Value }},
133 { ocDBVar, {{ Reference, Reference, Reference }, 0, Value }},
134 { ocDBVarP, {{ Reference, Reference, Reference }, 0, Value }},
135 { ocDevSq, {{ Reference }, 1, Value }},
136 { ocDiv, {{ Array, Array }, 0, Value }},
137 { ocEqual, {{ Array, Array }, 0, Value }},
138 { ocFTest, {{ ForceArray, ForceArray }, 0, Value }},
139 { ocFalse, {{ Bounds }, 0, Value }},
140 { ocForecast, {{ Value, ForceArray, ForceArray }, 0, Value }},
148 { ocFormula, {{ Reference }, 0, Value }},
149 { ocFourier, {{ ForceArray, Value, Value, Value, Value }, 0, Value }},
151 { ocGCD, {{ Reference }, 1, Value }},
152 { ocGeoMean, {{ Reference }, 1, Value }},
153 { ocGetActDate, {{ Bounds }, 0, Value }},
154 { ocGetActTime, {{ Bounds }, 0, Value }},
155 { ocGreater, {{ Array, Array }, 0, Value }},
156 { ocGreaterEqual, {{ Array, Array }, 0, Value }},
159 { ocHarMean, {{ Reference }, 1, Value }},
160 { ocIRR, {{ Reference, Value }, 0, Value }},
161 { ocIndex, {{ Reference, Value, Value, Value }, 0, Value }},
162 { ocIndirect, {{ Value, Value }, 0, Reference }},
163 { ocIntercept, {{ ForceArray, ForceArray }, 0, Value }},
165 { ocIsFormula, {{ Reference }, 0, Value }},
166 { ocIsRef, {{ Reference }, 0, Value }},
167 { ocKurt, {{ Reference }, 1, Value }},
168 { ocLCM, {{ Reference }, 1, Value }},
169 { ocLarge, {{ Reference, Value }, 0, Value }},
170 { ocLess, {{ Array, Array }, 0, Value }},
171 { ocLessEqual, {{ Array, Array }, 0, Value }},
172 { ocLinest, {{ ForceArray, ForceArray, Value, Value }, 0, Value }},
173 { ocLogest, {{ ForceArray, ForceArray, Value, Value }, 0, Value }},
175 { ocMIRR, {{ Reference, Value, Value }, 0, Value }},
176 { ocMatDet, {{ ForceArray }, 0, Value }},
177 { ocMatInv, {{ ForceArray }, 0, Value }},
178 { ocMatMult, {{ ForceArray, ForceArray }, 0, Value }},
180 { ocMatValue, {{ Reference, Value, Value }, 0, Value }},
182 { ocMax, {{ ReferenceOrRefArray }, 1, Value }},
183 { ocMaxA, {{ ReferenceOrRefArray }, 1, Value }},
185 { ocMedian, {{ Reference }, 1, Value }},
186 { ocMin, {{ ReferenceOrRefArray }, 1, Value }},
187 { ocMinA, {{ ReferenceOrRefArray }, 1, Value }},
189 { ocModalValue, {{ ForceArray }, 1, Value }},
190 { ocModalValue_MS, {{ ForceArray }, 1, Value }},
191 { ocModalValue_Multi,{{ ForceArray }, 1, Value }},
192 { ocMul, {{ Array, Array }, 0, Value }},
193 { ocMultiArea, {{ Reference }, 1, Reference }},
194 { ocNPV, {{ Value, Reference }, 1, Value }},
195 { ocNeg, {{ Array }, 0, Value }},
196 { ocNegSub, {{ Array }, 0, Value }},
199 { ocNot, {{ Array }, 0, Value }},
200 { ocNotAvail, {{ Bounds }, 0, Value }},
201 { ocNotEqual, {{ Array, Array }, 0, Value }},
202 { ocOffset, {{ Reference, Value, Value, Value, Value }, 0, Reference }},
203 { ocOr, {{ Reference }, 1, Value }},
204 { ocPearson, {{ ForceArray, ForceArray }, 0, Value }},
205 { ocPercentSign, {{ Array }, 0, Value }},
206 { ocPercentile, {{ Reference, Value }, 0, Value }},
207 { ocPercentile_Exc, {{ Reference, Value }, 0, Value }},
208 { ocPercentile_Inc, {{ Reference, Value }, 0, Value }},
209 { ocPercentrank, {{ Reference, Value, Value }, 0, Value }},
212 { ocPi, {{ Bounds }, 0, Value }},
213 { ocPow, {{ Array, Array }, 0, Value }},
214 { ocPower, {{ Array, Array }, 0, Value }},
215 { ocProb, {{ ForceArray, ForceArray, Value, Value }, 0, Value }},
216 { ocProduct, {{ ReferenceOrRefArray }, 1, Value }},
217 { ocQuartile, {{ Reference, Value }, 0, Value }},
218 { ocQuartile_Exc, {{ Reference, Value }, 0, Value }},
219 { ocQuartile_Inc, {{ Reference, Value }, 0, Value }},
220 { ocRSQ, {{ ForceArray, ForceArray }, 0, Value }},
221 { ocRandom, {{ Bounds }, 0, Value }},
222 { ocRandomNV, {{ Bounds }, 0, Value }},
223 { ocRange, {{ Reference, Reference }, 0, Reference }},
224 { ocRank, {{ Value, Reference, Value }, 0, Value }},
225 { ocRank_Avg, {{ Value, Reference, Value }, 0, Value }},
226 { ocRank_Eq, {{ Value, Reference, Value }, 0, Value }},
227 { ocRow, {{ Reference }, 0, Value }},
228 { ocRows, {{ Reference }, 1, Value }},
229 { ocSTEYX, {{ ForceArray, ForceArray }, 0, Value }},
230 { ocSheet, {{ Reference }, 0, Value }},
231 { ocSheets, {{ Reference }, 1, Value }},
232 { ocSkew, {{ Reference }, 1, Value }},
233 { ocSkewp, {{ Reference }, 1, Value }},
234 { ocSlope, {{ ForceArray, ForceArray }, 0, Value }},
235 { ocSmall, {{ Reference, Value }, 0, Value }},
236 { ocStDev, {{ Reference }, 1, Value }},
237 { ocStDevA, {{ Reference }, 1, Value }},
238 { ocStDevP, {{ Reference }, 1, Value }},
239 { ocStDevPA, {{ Reference }, 1, Value }},
240 { ocStDevP_MS, {{ Reference }, 1, Value }},
241 { ocStDevS, {{ Reference }, 1, Value }},
242 { ocSub, {{ Array, Array }, 0, Value }},
244 { ocSum, {{ ReferenceOrRefArray }, 1, Value }},
247 { ocSumProduct, {{ ForceArray }, 1, Value }},
248 { ocSumSQ, {{ ReferenceOrRefArray }, 1, Value }},
249 { ocSumX2DY2, {{ ForceArray, ForceArray }, 0, Value }},
250 { ocSumX2MY2, {{ ForceArray, ForceArray }, 0, Value }},
251 { ocSumXMY2, {{ ForceArray, ForceArray }, 0, Value }},
252 { ocTTest, {{ ForceArray, ForceArray, Value, Value }, 0, Value }},
255 { ocTrimMean, {{ Reference, Value }, 0, Value }},
256 { ocTrue, {{ Bounds }, 0, Value }},
257 { ocUnion, {{ Reference, Reference }, 0, Reference }},
259 { ocVar, {{ ReferenceOrRefArray }, 1, Value }},
260 { ocVarA, {{ ReferenceOrRefArray }, 1, Value }},
261 { ocVarP, {{ ReferenceOrRefArray }, 1, Value }},
262 { ocVarPA, {{ ReferenceOrRefArray }, 1, Value }},
263 { ocVarP_MS, {{ Reference }, 1, Value }},
264 { ocVarS, {{ Reference }, 1, Value }},
265 { ocWhitespace, {{ Bounds }, 0, Bounds }},
266 { ocWorkday_MS, {{ Value, Value, Value, Reference }, 0, Value }},
267 { ocXor, {{ Reference }, 1, Value }},
268 { ocZTest, {{ Reference, Value, Value }, 0, Value }},
269 { ocZTest_MS, {{ Reference, Value, Value }, 0, Value }},
270 // Excel doubts:
271 // ocN, ocT: Excel says (and handles) Reference, error? This means no
272 // position dependent SingleRef if DoubleRef, and no array calculation,
273 // just the upper left corner. We never did that for ocT and now also not
274 // for ocN (position dependent intersection worked before but array
275 // didn't). No specifics in ODFF, so the general rule applies. Gnumeric
276 // does the same.
277 { ocN, {{ Value }, 0, Value }},
278 { ocT, {{ Value }, 0, Value }},
279 // The stopper.
280 { ocNone, {{ Bounds }, 0, Value }}
281};
282
284
286{
287 if ( pData )
288 return;
290 memset( pData, 0, sizeof(RunData) * (SC_OPCODE_LAST_OPCODE_ID + 1));
291
292 // init from specified static data above
293 for (const auto & i : pRawData)
294 {
295 const RawData* pRaw = &i;
296 if ( pRaw->eOp > SC_OPCODE_LAST_OPCODE_ID )
297 {
298 OSL_ENSURE( pRaw->eOp == ocNone, "RawData OpCode error");
299 }
300 else
301 {
302 RunData* pRun = &pData[ pRaw->eOp ];
303 SAL_WARN_IF(pRun->aData.nParam[0] != Unknown, "sc.core", "already assigned: " << static_cast<int>(pRaw->eOp));
304 memcpy( &(pRun->aData), &(pRaw->aData), sizeof(CommonData));
305 // fill 0-initialized fields with real values
306 if ( pRun->aData.nRepeatLast )
307 {
308 for ( sal_Int32 j=0; j < CommonData::nMaxParams; ++j )
309 {
310 if ( pRun->aData.nParam[j] )
311 pRun->nMinParams = sal::static_int_cast<sal_uInt8>( j+1 );
312 else if (j >= pRun->aData.nRepeatLast)
313 pRun->aData.nParam[j] = pRun->aData.nParam[j - pRun->aData.nRepeatLast];
314 else
315 {
316 SAL_INFO(
317 "sc.core",
318 "bad classification: eOp " << +pRaw->eOp
319 << ", repeated param " << j
320 << " negative offset");
321 pRun->aData.nParam[j] = Unknown;
322 }
323 }
324 }
325 else
326 {
327 for ( sal_Int32 j=0; j < CommonData::nMaxParams; ++j )
328 {
329 if ( !pRun->aData.nParam[j] )
330 {
331 if ( j == 0 || pRun->aData.nParam[j-1] != Bounds )
332 pRun->nMinParams = sal::static_int_cast<sal_uInt8>( j );
333 pRun->aData.nParam[j] = Bounds;
334 }
335 }
336 if ( !pRun->nMinParams &&
339 }
340 for (const formula::ParamClass & j : pRun->aData.nParam)
341 {
342 if ( j == ForceArray || j == ReferenceOrForceArray )
343 {
344 pRun->bHasForceArray = true;
345 break; // for
346 }
347 }
348 }
349 }
350
351#if DEBUG_SC_PARCLASSDOC
352 GenerateDocumentation();
353#endif
354}
355
357{
358 delete [] pData;
359 pData = nullptr;
360}
361
363 const formula::FormulaToken* pToken, sal_uInt16 nParameter)
364{
365 OpCode eOp = pToken->GetOpCode();
366 switch ( eOp )
367 {
368 case ocExternal:
369 return GetExternalParameterType( pToken, nParameter);
370 case ocMacro:
371 return (nParameter == SAL_MAX_UINT16 ? Value : Reference);
372 default:
373 {
374 // added to avoid warnings
375 }
376 }
377 if ( 0 <= static_cast<short>(eOp) && eOp <= SC_OPCODE_LAST_OPCODE_ID )
378 {
379 sal_uInt8 nRepeat;
381 if (nParameter == SAL_MAX_UINT16)
382 eType = pData[eOp].aData.eReturn;
383 else if ( nParameter < CommonData::nMaxParams )
384 eType = pData[eOp].aData.nParam[nParameter];
385 else if ( (nRepeat = pData[eOp].aData.nRepeatLast) > 0 )
386 {
387 // The usual case is 1 repeated parameter, we don't need to
388 // calculate that on each call.
389 sal_uInt16 nParam = (nRepeat > 1 ?
390 (pData[eOp].nMinParams -
391 ((nParameter - pData[eOp].nMinParams) % nRepeat)) :
392 pData[eOp].nMinParams);
393 return pData[eOp].aData.nParam[nParam];
394 }
395 else
396 eType = Bounds;
397 return eType == Unknown ? Value : eType;
398 }
399 return Unknown;
400}
401
403 sal_uInt16 nParameter)
404{
406 if (nParameter == SAL_MAX_UINT16)
407 return eRet;
408
409 // similar to ScInterpreter::ScExternal()
410 OUString aFuncName = pToken->GetExternal().toAsciiUpperCase(); // programmatic name
411 {
412 const LegacyFuncData* pLegacyFuncData = ScGlobal::GetLegacyFuncCollection()->findByName(aFuncName);
413 if (pLegacyFuncData)
414 {
415 if ( nParameter >= pLegacyFuncData->GetParamCount() )
416 eRet = Bounds;
417 else
418 {
419 switch ( pLegacyFuncData->GetParamType( nParameter) )
420 {
423 eRet = Value;
424 break;
425 default:
426 eRet = Reference;
427 // also array types are created using an area reference
428 }
429 }
430 return eRet;
431 }
432 }
433
434 OUString aUnoName =
435 ScGlobal::GetAddInCollection()->FindFunction(aFuncName, false);
436
437 if (!aUnoName.isEmpty())
438 {
439 // the relevant parts of ScUnoAddInCall without having to create one
440 const ScUnoAddInFuncData* pFuncData =
441 ScGlobal::GetAddInCollection()->GetFuncData( aUnoName, true ); // need fully initialized data
442 if ( pFuncData )
443 {
444 tools::Long nCount = pFuncData->GetArgumentCount();
445 if ( nCount <= 0 )
446 eRet = Bounds;
447 else
448 {
449 const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
450 if ( nParameter >= nCount &&
451 pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
452 eRet = Value;
453 // last arg is sequence, optional "any"s, we simply can't
454 // determine the type
455 if ( eRet == Unknown )
456 {
457 if ( nParameter >= nCount )
458 eRet = Bounds;
459 else
460 {
461 switch ( pArgs[nParameter].eType )
462 {
466 eRet = Value;
467 break;
468 default:
469 eRet = Reference;
470 }
471 }
472 }
473 }
474 }
475 }
476 return eRet;
477}
478
479#if DEBUG_SC_PARCLASSDOC
480
481// add remaining functions, all Value parameters
482void ScParameterClassification::MergeArgumentsFromFunctionResource()
483{
485 for ( const ScFuncDesc* pDesc = pFuncList->First(); pDesc;
486 pDesc = pFuncList->Next() )
487 {
488 if ( pDesc->nFIndex > SC_OPCODE_LAST_OPCODE_ID ||
489 pData[pDesc->nFIndex].aData.nParam[0] != Unknown )
490 continue; // not an internal opcode or already done
491
492 RunData* pRun = &pData[ pDesc->nFIndex ];
493 sal_uInt16 nArgs = pDesc->GetSuppressedArgCount();
494 if ( nArgs >= PAIRED_VAR_ARGS )
495 {
496 nArgs -= PAIRED_VAR_ARGS - 2;
497 pRun->aData.nRepeatLast = 2;
498 }
499 else if ( nArgs >= VAR_ARGS )
500 {
501 nArgs -= VAR_ARGS - 1;
502 pRun->aData.nRepeatLast = 1;
503 }
504 if ( nArgs > CommonData::nMaxParams )
505 {
506 SAL_WARN( "sc", "ScParameterClassification::Init: too many arguments in listed function: "
507 << *(pDesc->pFuncName)
508 << ": " << nArgs );
509 nArgs = CommonData::nMaxParams - 1;
510 pRun->aData.nRepeatLast = 1;
511 }
512 pRun->nMinParams = static_cast< sal_uInt8 >( nArgs );
513 for ( sal_Int32 j=0; j < nArgs; ++j )
514 {
515 pRun->aData.nParam[j] = Value;
516 }
517 if ( pRun->aData.nRepeatLast )
518 {
519 for ( sal_Int32 j = nArgs; j < CommonData::nMaxParams; ++j )
520 {
521 pRun->aData.nParam[j] = Value;
522 }
523 }
524 else
525 {
526 for ( sal_Int32 j = nArgs; j < CommonData::nMaxParams; ++j )
527 {
528 pRun->aData.nParam[j] = Bounds;
529 }
530 }
531 }
532}
533
534void ScParameterClassification::GenerateDocumentation()
535{
536 static const char aEnvVarName[] = "OOO_CALC_GENPARCLASSDOC";
537 if ( !getenv( aEnvVarName) )
538 return;
539 MergeArgumentsFromFunctionResource();
540 ScAddress aAddress;
541 ScCompiler aComp(NULL,aAddress);
542 ScCompiler::OpCodeMapPtr xMap( aComp.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
543 if (!xMap)
544 return;
545 fflush( stderr);
546 size_t nCount = xMap->getSymbolCount();
547 for ( size_t i=0; i<nCount; ++i )
548 {
549 OpCode eOp = OpCode(i);
550 if ( !xMap->getSymbol(eOp).isEmpty() )
551 {
552 OUStringBuffer aStr(xMap->getSymbol(eOp));
553 formula::FormulaByteToken aToken( eOp);
554 sal_uInt8 nParams = GetMinimumParameters( eOp);
555 // preset parameter count according to opcode value, with some
556 // special handling
557 bool bAddParentheses = true;
558 if ( eOp < SC_OPCODE_STOP_DIV )
559 {
560 bAddParentheses = false; // will be overridden below if parameters
561 switch ( eOp )
562 {
563 case ocIf:
564 aToken.SetByte(3);
565 break;
566 case ocIfError:
567 case ocIfNA:
568 case ocChoose:
569 aToken.SetByte(2);
570 break;
571 case ocPercentSign:
572 aToken.SetByte(1);
573 break;
574 default:;
575 }
576 }
577 else if ( eOp < SC_OPCODE_STOP_ERRORS )
578 {
579 bAddParentheses = false;
580 aToken.SetByte(0);
581 }
582 else if ( eOp < SC_OPCODE_STOP_BIN_OP )
583 {
584 switch ( eOp )
585 {
586 case ocAnd:
587 case ocOr:
588 aToken.SetByte(1); // (r1)AND(r2) --> AND( r1, ...)
589 break;
590 default:
591 aToken.SetByte(2);
592 }
593 }
594 else if ( eOp < SC_OPCODE_STOP_UN_OP )
595 aToken.SetByte(1);
596 else if ( eOp < SC_OPCODE_STOP_NO_PAR )
597 aToken.SetByte(0);
598 else if ( eOp < SC_OPCODE_STOP_1_PAR )
599 aToken.SetByte(1);
600 else
601 aToken.SetByte( nParams);
602 // compare (this is a mere test for opcode order Div, BinOp, UnOp,
603 // NoPar, 1Par, ...) and override parameter count with
604 // classification
605 if ( nParams != aToken.GetByte() )
606 SAL_WARN("sc.core", "(parameter count differs, token Byte: " << (int)aToken.GetByte() << " classification: " << (int)nParams << ") ");
607 aToken.SetByte( nParams);
608 if ( nParams != aToken.GetParamCount() )
609 SAL_WARN("sc.core", "(parameter count differs, token ParamCount: " << (int)aToken.GetParamCount() << " classification: " << (int)nParams << ") ");
610 if (aToken.GetByte())
611 bAddParentheses = true;
612 if (bAddParentheses)
613 aStr.append('(');
614 for ( sal_uInt16 j=0; j < nParams; ++j )
615 {
616 if ( j > 0 )
617 aStr.append(',');
619 switch ( eType )
620 {
621 case Value :
622 aStr.append(" Value");
623 break;
624 case Reference :
625 aStr.append(" Reference");
626 break;
628 aStr.append(" ReferenceOrRefArray");
629 break;
630 case Array :
631 aStr.append(" Array");
632 break;
633 case ForceArray :
634 aStr.append(" ForceArray");
635 break;
637 aStr.append(" ReferenceOrForceArray");
638 break;
639 case Bounds :
640 aStr.append(" (Bounds, classification error?)");
641 break;
642 default:
643 aStr.append(" (???, classification error?)");
644 }
645 }
646 if ( HasRepeatParameters( eOp) )
647 aStr.append(", ...");
648 if ( nParams )
649 aStr.append(' ');
650 if (bAddParentheses)
651 aStr.append(')');
652 switch ( eOp )
653 {
654 case ocRRI:
655 aStr.append(" // RRI in English resource, but ZGZ in English-only section");
656 break;
657 case ocMultiArea:
658 aStr.append(" // e.g. combined first parameter of INDEX() function, not a real function");
659 break;
660 case ocBackSolver:
661 aStr.append(" // goal seek via menu, not a real function");
662 break;
663 case ocTableOp:
664 aStr.append(" // MULTIPLE.OPERATIONS in English resource, but TABLE in English-only section");
665 break;
666 case ocNoName:
667 aStr.append(" // error function, not a real function");
668 break;
669 default:;
670 }
671 // Return type.
672 formula::ParamClass eType = GetParameterType( &aToken, SAL_MAX_UINT16);
673 switch ( eType )
674 {
675 case Value :
676 aStr.append(" -> Value");
677 break;
678 case Reference :
679 aStr.append(" -> Reference");
680 break;
682 aStr.append(" -> ReferenceOrRefArray");
683 break;
684 case Array :
685 aStr.append(" -> Array");
686 break;
687 case ForceArray :
688 aStr.append(" -> ForceArray");
689 break;
691 aStr.append(" -> ReferenceOrForceArray");
692 break;
693 case Bounds :
694 ; // nothing
695 break;
696 default:
697 aStr.append(" (-> ???, classification error?)");
698 }
699 /* We could add yet another log domain for this, if we wanted... but
700 * as it more seldom than rarely used it's not actually necessary,
701 * just grep output. */
702 SAL_INFO( "sc.core", "CALC_GENPARCLASSDOC: " << aStr.makeStringAndClear());
703 }
704 }
705 fflush( stdout);
706}
707
708#endif // OSL_DEBUG_LEVEL
709
710/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ SC_ADDINARG_INTEGER
long
Definition: addincol.hxx:54
@ SC_ADDINARG_STRING
string
Definition: addincol.hxx:56
@ SC_ADDINARG_VARARGS
sequence<any>
Definition: addincol.hxx:64
@ SC_ADDINARG_DOUBLE
double
Definition: addincol.hxx:55
const LegacyFuncData * findByName(const OUString &rName) const
Definition: callform.cxx:384
ParamType GetParamType(sal_uInt16 nIndex) const
Definition: callform.hxx:76
sal_uInt16 GetParamCount() const
Definition: callform.hxx:75
Stores and generates human readable descriptions for spreadsheet-functions, e.g. functions used in fo...
Definition: funcdesc.hxx:41
List of spreadsheet functions.
Definition: funcdesc.hxx:242
const ScFuncDesc * First()
Definition: funcdesc.cxx:972
const ScFuncDesc * Next()
Definition: funcdesc.cxx:982
static LegacyFuncCollection * GetLegacyFuncCollection()
Definition: global.cxx:278
static SC_DLLPUBLIC ScUnoAddInCollection * GetAddInCollection()
Definition: global.cxx:283
static ScFunctionList * GetStarCalcFunctionList()
Definition: global.cxx:626
static formula::ParamClass GetParameterType(const formula::FormulaToken *pToken, sal_uInt16 nParameter)
Get one parameter type for function eOp.
Definition: parclass.cxx:362
static RunData * pData
Definition: parclass.hxx:97
static void Init()
MUST be called once before any other method.
Definition: parclass.cxx:285
static formula::ParamClass GetExternalParameterType(const formula::FormulaToken *pToken, sal_uInt16 nParameter)
Definition: parclass.cxx:402
static const RawData pRawData[]
Definition: parclass.hxx:96
const ScUnoAddInFuncData * GetFuncData(const OUString &rName, bool bComplete=false)
Only if bComplete is set, the function reference and argument types are initialized (component may ha...
Definition: addincol.cxx:1224
OUString FindFunction(const OUString &rUpperName, bool bLocalFirst)
User entered name. rUpperName MUST already be upper case!
Definition: addincol.cxx:1181
const ScAddInArgDesc * GetArguments() const
Definition: addincol.hxx:124
tools::Long GetArgumentCount() const
Definition: addincol.hxx:123
std::shared_ptr< const OpCodeMap > OpCodeMapPtr
virtual const OUString & GetExternal() const
OpCode GetOpCode() const
#define SC_OPCODE_LAST_OPCODE_ID
int nCount
DocumentType eType
#define VAR_ARGS
#define PAIRED_VAR_ARGS
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
aStr
constexpr OUStringLiteral aData
Bounds
Value
Unknown
ReferenceOrRefArray
ForceArray
ReferenceOrForceArray
ForceArrayReturn
Reference
Array
int i
long Long
OpCode
ocSumProduct
ocModalValue
ocCurrent
ocArrayOpen
ocNot
ocCountIfs
ocNegSub
ocSkew
ocQuartile_Exc
ocTableRefItemThisRow
ocRank_Avg
ocPercentile_Exc
ocNetWorkdays
ocForecast_ETS_PIA
ocBackSolver
ocDiv
ocAggregate
ocTableRef
ocSmall
ocColumns
ocSumIf
ocTTest
ocIRR
ocDBCount
ocDBMax
ocTableRefItemHeaders
ocCountIf
ocFalse
ocTrimMean
ocNPV
ocAmpersand
ocPercentrank_Inc
ocStringXML
ocRSQ
ocIsRef
ocIndex
ocPearson
ocStDev
ocAreas
ocGrowth
ocCell
ocMultiArea
ocLessEqual
ocNone
ocOr
ocNotEqual
ocAverageIfs
ocIntercept
ocDBVarP
ocClose
ocColRowName
ocMatInv
ocN
ocSumSQ
ocIndirect
ocHLookup
ocSubTotal
ocGeoMean
ocLCM
ocVarS
ocArrayRowSep
ocRow
ocGetActTime
ocMacro
ocQuartile
ocRandomNV
ocProduct
ocForecast_ETS_ADD
ocAverageA
ocCountEmptyCells
ocCovarianceS
ocAverage
ocStDevP_MS
ocMinA
ocSkewp
ocOffset
ocZTest_MS
ocIfNA
ocXor
ocMinIfs_MS
ocMatTrans
ocForecast_ETS_PIM
ocPow
ocPercentile_Inc
ocAdd
ocStop
ocPercentrank_Exc
ocPercentrank
ocTableRefItemTotals
ocSkip
ocRange
ocGCD
ocUnion
ocDBVar
ocZTest
ocErrName
ocSTEYX
ocRank
ocEqual
ocLogest
ocQuartile_Inc
ocFrequency
ocTextJoin_MS
ocModalValue_Multi
ocForecast_ETS_STM
ocDBGet
ocSlope
ocMatMult
ocMatDet
ocLarge
ocRRI
ocGetActDate
ocErrValue
ocOpen
ocSub
ocMIRR
ocTrend
ocAverageIf
ocDBMin
ocVarPA
ocLookup
ocGreater
ocHarMean
ocRandom
ocColRowNameAuto
ocTrue
ocLinest
ocRows
ocCorrel
ocTableRefItemData
ocExternal
ocSpaces
ocAnd
ocPercentile
ocPercentSign
ocErrNull
ocCount2
ocMatValue
ocForecast_ETS_MUL
ocSep
ocMissing
ocMedian
ocVarP_MS
ocTableRefItemAll
ocVarP
ocDBCount2
ocDevSq
ocIntersect
ocStDevS
ocGreaterEqual
ocBad
ocForecast_ETS_SEA
ocErrNA
ocFTest
ocDBArea
ocStDevP
ocForecast_ETS_STA
ocIfError
ocErrNum
ocKurt
ocPower
ocSumXMY2
ocSheets
ocWhitespace
ocTableRefClose
ocMatRef
ocForecast
ocMin
ocLess
ocSumX2MY2
ocFourier
ocErrDivZero
ocNoName
ocCovarianceP
ocIsFormula
ocDBProduct
ocArrayClose
ocErrRef
ocNeg
ocDBAverage
ocArrayColSep
ocMul
ocMatch
ocVLookup
ocStDevA
ocSumIfs
ocMaxIfs_MS
ocNetWorkdays_MS
ocTableOp
ocDBSum
ocChoose
ocWorkday_MS
ocVarA
ocVar
ocCovar
ocColumn
ocNotAvail
ocRank_Eq
ocModalValue_MS
ocDBStdDev
ocT
ocIf
ocSumX2DY2
ocSheet
ocProb
ocFormula
ocConcat_MS
ocDBStdDevP
ocMaxA
ocStDevPA
ocTableRefOpen
ocSum
ocAveDev
ocPi
ocCount
ocMax
static const sal_Int32 nMaxParams
Definition: parclass.hxx:74
formula::ParamClass nParam[nMaxParams]
Definition: parclass.hxx:76
unsigned char sal_uInt8
#define SAL_MAX_UINT16