Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "parclass.hxx"
30 : : #include "token.hxx"
31 : : #include "global.hxx"
32 : : #include "callform.hxx"
33 : : #include "addincol.hxx"
34 : : #include "funcdesc.hxx"
35 : : #include <unotools/charclass.hxx>
36 : : #include <osl/diagnose.h>
37 : : #include <sal/macros.h>
38 : : #include <string.h>
39 : :
40 : : #if OSL_DEBUG_LEVEL > 1
41 : : // the documentation thingy
42 : : #include <stdio.h>
43 : : #include <com/sun/star/sheet/FormulaLanguage.hpp>
44 : : #include <rtl/strbuf.hxx>
45 : : #include "compiler.hxx"
46 : : #include "sc.hrc" // VAR_ARGS
47 : : #endif
48 : :
49 : :
50 : : /* Following assumptions are made:
51 : : * - OpCodes not specified at all will have at least one and only parameters of
52 : : * type Value, no check is done on the count of parameters => no Bounds type
53 : : * is returned.
54 : : * - For OpCodes with a variable number of parameters the type of the last
55 : : * parameter specified determines the type of all following parameters.
56 : : */
57 : :
58 : : const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
59 : : {
60 : : // IF() and CHOOSE() are somewhat special, since the ScJumpMatrix is
61 : : // created inside those functions and ConvertMatrixParameters() is not
62 : : // called for them.
63 : : { ocIf, {{ Array, Reference, Reference }, false }},
64 : : { ocChose, {{ Array, Reference }, true }},
65 : : // Other specials.
66 : : { ocOpen, {{ Bounds }, false }},
67 : : { ocClose, {{ Bounds }, false }},
68 : : { ocSep, {{ Bounds }, false }},
69 : : { ocNoName, {{ Bounds }, false }},
70 : : { ocErrCell, {{ Bounds }, false }},
71 : : { ocStop, {{ Bounds }, false }},
72 : : { ocUnion, {{ Reference, Reference }, false }},
73 : : { ocRange, {{ Reference, Reference }, false }},
74 : : // Functions with Value parameters only but not in resource.
75 : : { ocBackSolver, {{ Value, Value, Value }, false }},
76 : : { ocTableOp, {{ Value, Value, Value, Value, Value }, false }},
77 : : // Operators and functions.
78 : : { ocAdd, {{ Array, Array }, false }},
79 : : { ocAmpersand, {{ Array, Array }, false }},
80 : : { ocAnd, {{ Reference }, true }},
81 : : { ocAreas, {{ Reference }, false }},
82 : : { ocAveDev, {{ Reference }, true }},
83 : : { ocAverage, {{ Reference }, true }},
84 : : { ocAverageA, {{ Reference }, true }},
85 : : { ocCell, {{ Value, Reference }, false }},
86 : : { ocColumn, {{ Reference }, false }},
87 : : { ocColumns, {{ Reference }, true }},
88 : : { ocCorrel, {{ ForceArray, ForceArray }, false }},
89 : : { ocCount, {{ Reference }, true }},
90 : : { ocCount2, {{ Reference }, true }},
91 : : { ocCountEmptyCells, {{ Reference }, false }},
92 : : { ocCountIf, {{ Reference, Value }, false }},
93 : : { ocCovar, {{ ForceArray, ForceArray }, false }},
94 : : { ocDBAverage, {{ Reference, Reference, Reference }, false }},
95 : : { ocDBCount, {{ Reference, Reference, Reference }, false }},
96 : : { ocDBCount2, {{ Reference, Reference, Reference }, false }},
97 : : { ocDBGet, {{ Reference, Reference, Reference }, false }},
98 : : { ocDBMax, {{ Reference, Reference, Reference }, false }},
99 : : { ocDBMin, {{ Reference, Reference, Reference }, false }},
100 : : { ocDBProduct, {{ Reference, Reference, Reference }, false }},
101 : : { ocDBStdDev, {{ Reference, Reference, Reference }, false }},
102 : : { ocDBStdDevP, {{ Reference, Reference, Reference }, false }},
103 : : { ocDBSum, {{ Reference, Reference, Reference }, false }},
104 : : { ocDBVar, {{ Reference, Reference, Reference }, false }},
105 : : { ocDBVarP, {{ Reference, Reference, Reference }, false }},
106 : : { ocDevSq, {{ Reference }, true }},
107 : : { ocDiv, {{ Array, Array }, false }},
108 : : { ocEqual, {{ Array, Array }, false }},
109 : : { ocForecast, {{ Value, ForceArray, ForceArray }, false }},
110 : : { ocFrequency, {{ Reference, Reference }, false }},
111 : : { ocFTest, {{ ForceArray, ForceArray }, false }},
112 : : { ocGeoMean, {{ Reference }, true }},
113 : : { ocGCD, {{ Reference }, true }},
114 : : { ocGreater, {{ Array, Array }, false }},
115 : : { ocGreaterEqual, {{ Array, Array }, false }},
116 : : { ocGrowth, {{ Reference, Reference, Reference, Value }, false }},
117 : : { ocHarMean, {{ Reference }, true }},
118 : : { ocHLookup, {{ Value, Reference, Value, Value }, false }},
119 : : { ocIRR, {{ Reference, Value }, false }},
120 : : { ocIndex, {{ Reference, Value, Value, Value }, false }},
121 : : { ocIntercept, {{ ForceArray, ForceArray }, false }},
122 : : { ocIntersect, {{ Reference, Reference }, false }},
123 : : { ocIsRef, {{ Reference }, false }},
124 : : { ocLCM, {{ Reference }, true }},
125 : : { ocKurt, {{ Reference }, true }},
126 : : { ocLarge, {{ Reference, Value }, false }},
127 : : { ocLess, {{ Array, Array }, false }},
128 : : { ocLessEqual, {{ Array, Array }, false }},
129 : : { ocLookup, {{ Value, ReferenceOrForceArray, ReferenceOrForceArray }, false }},
130 : : { ocMatch, {{ Value, Reference, Reference }, false }},
131 : : { ocMatDet, {{ ForceArray }, false }},
132 : : { ocMatInv, {{ ForceArray }, false }},
133 : : { ocMatMult, {{ ForceArray, ForceArray }, false }},
134 : : { ocMatTrans, {{ Array }, false }}, // strange, but Xcl doesn't force MatTrans array
135 : : { ocMatValue, {{ Reference, Value, Value }, false }},
136 : : { ocMax, {{ Reference }, true }},
137 : : { ocMaxA, {{ Reference }, true }},
138 : : { ocMedian, {{ Reference }, true }},
139 : : { ocMin, {{ Reference }, true }},
140 : : { ocMinA, {{ Reference }, true }},
141 : : { ocMIRR, {{ Reference, Value, Value }, false }},
142 : : { ocModalValue, {{ ForceArray }, true }},
143 : : { ocMul, {{ Array, Array }, false }},
144 : : { ocMultiArea, {{ Reference }, true }},
145 : : { ocNPV, {{ Value, Reference }, true }},
146 : : { ocNeg, {{ Array }, false }},
147 : : { ocNegSub, {{ Array }, false }},
148 : : { ocNot, {{ Array }, false }},
149 : : { ocNotEqual, {{ Array, Array }, false }},
150 : : { ocOffset, {{ Reference, Value, Value, Value, Value }, false }},
151 : : { ocOr, {{ Reference }, true }},
152 : : { ocPearson, {{ ForceArray, ForceArray }, false }},
153 : : { ocPercentile, {{ Reference, Value }, false }},
154 : : { ocPercentrank, {{ Reference, Value }, false }},
155 : : { ocPow, {{ Array, Array }, false }},
156 : : { ocPower, {{ Array, Array }, false }},
157 : : { ocProb, {{ ForceArray, ForceArray, Value, Value }, false }},
158 : : { ocProduct, {{ Reference }, true }},
159 : : { ocQuartile, {{ Reference, Value }, false }},
160 : : { ocRank, {{ Value, Reference, Value }, false }},
161 : : { ocRGP, {{ Reference, Reference, Value, Value }, false }},
162 : : { ocRKP, {{ Reference, Reference, Value, Value }, false }},
163 : : { ocRow, {{ Reference }, false }},
164 : : { ocRows, {{ Reference }, true }},
165 : : { ocRSQ, {{ ForceArray, ForceArray }, false }},
166 : : { ocSchiefe, {{ Reference }, true }},
167 : : { ocSlope, {{ ForceArray, ForceArray }, false }},
168 : : { ocSmall, {{ Reference, Value }, false }},
169 : : { ocStDev, {{ Reference }, true }},
170 : : { ocStDevA, {{ Reference }, true }},
171 : : { ocStDevP, {{ Reference }, true }},
172 : : { ocStDevPA, {{ Reference }, true }},
173 : : { ocSTEYX, {{ ForceArray, ForceArray }, false }},
174 : : { ocSub, {{ Array, Array }, false }},
175 : : { ocSubTotal, {{ Value, Reference }, true }},
176 : : { ocSum, {{ Reference }, true }},
177 : : { ocSumIf, {{ Reference, Value, Reference }, false }},
178 : : { ocSumProduct, {{ ForceArray }, true }},
179 : : { ocSumSQ, {{ Reference }, true }},
180 : : { ocSumX2MY2, {{ ForceArray, ForceArray }, false }},
181 : : { ocSumX2DY2, {{ ForceArray, ForceArray }, false }},
182 : : { ocSumXMY2, {{ ForceArray, ForceArray }, false }},
183 : : { ocTable, {{ Reference }, false }},
184 : : { ocTables, {{ Reference }, true }},
185 : : { ocTrend, {{ Reference, Reference, Reference, Value }, false }},
186 : : { ocTrimMean, {{ Reference, Value }, false }},
187 : : { ocTTest, {{ ForceArray, ForceArray, Value, Value }, false }},
188 : : { ocVar, {{ Reference }, true }},
189 : : { ocVarA, {{ Reference }, true }},
190 : : { ocVarP, {{ Reference }, true }},
191 : : { ocVarPA, {{ Reference }, true }},
192 : : { ocVLookup, {{ Value, Reference, Value, Value }, false }},
193 : : { ocXor, {{ Reference }, true }},
194 : : { ocZTest, {{ Reference, Value, Value }, false }},
195 : : // Excel doubts:
196 : : // ocN, ocT: Excel says (and handles) Reference, error? This means no
197 : : // position dependent SingleRef if DoubleRef, and no array calculation,
198 : : // just the upper left corner. We never did that for ocT and now also not
199 : : // for ocN (position dependent intersection worked before but array
200 : : // didn't). No specifics in ODFF, so the general rule applies. Gnumeric
201 : : // does the same.
202 : : { ocN, {{ Value }, false }},
203 : : { ocT, {{ Value }, false }},
204 : : // The stopper.
205 : : { ocNone, {{ Bounds }, false } }
206 : : };
207 : :
208 : : ScParameterClassification::RunData * ScParameterClassification::pData = NULL;
209 : :
210 : :
211 : 51 : void ScParameterClassification::Init()
212 : : {
213 [ - + ]: 51 : if ( pData )
214 : 51 : return;
215 : 51 : pData = new RunData[ SC_OPCODE_LAST_OPCODE_ID + 1 ];
216 : 51 : memset( pData, 0, sizeof(RunData) * (SC_OPCODE_LAST_OPCODE_ID + 1));
217 : :
218 : : // init from specified static data above
219 [ + + ]: 6783 : for ( size_t i=0; i < SAL_N_ELEMENTS(pRawData); ++i )
220 : : {
221 : 6732 : const RawData* pRaw = &pRawData[i];
222 [ + + ]: 6732 : if ( pRaw->eOp > SC_OPCODE_LAST_OPCODE_ID )
223 : : {
224 : : OSL_ENSURE( pRaw->eOp == ocNone, "RawData OpCode error");
225 : : }
226 : : else
227 : : {
228 : 6681 : RunData* pRun = &pData[ pRaw->eOp ];
229 : : #if OSL_DEBUG_LEVEL > 1
230 : : if ( pRun->aData.nParam[0] != Unknown )
231 : : {
232 : : OSL_TRACE( "already assigned: %d", pRaw->eOp);
233 : : }
234 : : #endif
235 : 6681 : memcpy( &(pRun->aData), &(pRaw->aData), sizeof(CommonData));
236 : : // fill 0-initialized fields with real values
237 [ + + ]: 6681 : if ( pRun->aData.bRepeatLast )
238 : : {
239 : 2040 : Type eLast = Unknown;
240 [ + + ]: 16320 : for ( sal_Int32 j=0; j < CommonData::nMaxParams; ++j )
241 : : {
242 [ + + ]: 14280 : if ( pRun->aData.nParam[j] )
243 : : {
244 : 2193 : eLast = pRun->aData.nParam[j];
245 : 2193 : pRun->nMinParams = sal::static_int_cast<sal_uInt8>( j+1 );
246 : : }
247 : : else
248 : 12087 : pRun->aData.nParam[j] = eLast;
249 : : }
250 : : }
251 : : else
252 : : {
253 [ + + ]: 37128 : for ( sal_Int32 j=0; j < CommonData::nMaxParams; ++j )
254 : : {
255 [ + + ]: 32487 : if ( !pRun->aData.nParam[j] )
256 : : {
257 [ + - ][ + + ]: 21879 : if ( j == 0 || pRun->aData.nParam[j-1] != Bounds )
258 : 4335 : pRun->nMinParams = sal::static_int_cast<sal_uInt8>( j );
259 : 21879 : pRun->aData.nParam[j] = Bounds;
260 : : }
261 : : }
262 [ + + ][ - + ]: 4641 : if ( !pRun->nMinParams &&
263 : 306 : pRun->aData.nParam[CommonData::nMaxParams-1] != Bounds)
264 : 0 : pRun->nMinParams = CommonData::nMaxParams;
265 : : }
266 [ + + ]: 46410 : for ( sal_Int32 j=0; j < CommonData::nMaxParams; ++j )
267 : : {
268 [ + + ][ + + ]: 40749 : if ( pRun->aData.nParam[j] == ForceArray || pRun->aData.nParam[j] == ReferenceOrForceArray )
269 : : {
270 : 1020 : pRun->bHasForceArray = true;
271 : 1020 : break; // for
272 : : }
273 : : }
274 : : }
275 : : }
276 : :
277 : : #if OSL_DEBUG_LEVEL > 1
278 : : GenerateDocumentation();
279 : : #endif
280 : : }
281 : :
282 : :
283 : 18 : void ScParameterClassification::Exit()
284 : : {
285 [ + - ]: 18 : delete [] pData;
286 : 18 : pData = NULL;
287 : 18 : }
288 : :
289 : :
290 : 177 : ScParameterClassification::Type ScParameterClassification::GetParameterType(
291 : : const formula::FormulaToken* pToken, sal_uInt16 nParameter)
292 : : {
293 : 177 : OpCode eOp = pToken->GetOpCode();
294 [ - - + ]: 177 : switch ( eOp )
295 : : {
296 : : case ocExternal:
297 : 0 : return GetExternalParameterType( pToken, nParameter);
298 : : //break;
299 : : case ocMacro:
300 : 0 : return Reference;
301 : : //break;
302 : : default:
303 : : {
304 : : // added to avoid warnings
305 : : }
306 : : }
307 [ + - ][ + - ]: 177 : if ( 0 <= (short)eOp && eOp <= SC_OPCODE_LAST_OPCODE_ID )
308 : : {
309 [ + - ]: 177 : if ( nParameter < CommonData::nMaxParams )
310 : : {
311 : 177 : Type eT = pData[eOp].aData.nParam[nParameter];
312 [ + - ]: 177 : return eT == Unknown ? Value : eT;
313 : : }
314 [ # # ]: 0 : else if ( pData[eOp].aData.bRepeatLast )
315 : 0 : return pData[eOp].aData.nParam[CommonData::nMaxParams-1];
316 : : else
317 : 0 : return Bounds;
318 : : }
319 : 177 : return Unknown;
320 : : }
321 : :
322 : :
323 : : ScParameterClassification::Type
324 : 0 : ScParameterClassification::GetExternalParameterType( const formula::FormulaToken* pToken,
325 : : sal_uInt16 nParameter)
326 : : {
327 : 0 : Type eRet = Unknown;
328 : : // similar to ScInterpreter::ScExternal()
329 [ # # ][ # # ]: 0 : rtl::OUString aFuncName = ScGlobal::pCharClass->uppercase( pToken->GetExternal());
[ # # ]
330 : : {
331 [ # # ][ # # ]: 0 : const FuncData* pFuncData = ScGlobal::GetFuncCollection()->findByName(aFuncName);
332 [ # # ]: 0 : if (pFuncData)
333 : : {
334 [ # # ]: 0 : if ( nParameter >= pFuncData->GetParamCount() )
335 : 0 : eRet = Bounds;
336 : : else
337 : : {
338 [ # # ]: 0 : switch ( pFuncData->GetParamType( nParameter) )
339 : : {
340 : : case PTR_DOUBLE:
341 : : case PTR_STRING:
342 : 0 : eRet = Value;
343 : 0 : break;
344 : : default:
345 : 0 : eRet = Reference;
346 : : // also array types are created using an area reference
347 : : }
348 : : }
349 : 0 : return eRet;
350 : : }
351 : : }
352 : :
353 : : rtl::OUString aUnoName =
354 [ # # ][ # # ]: 0 : ScGlobal::GetAddInCollection()->FindFunction(aFuncName, false);
355 : :
356 [ # # ]: 0 : if (!aUnoName.isEmpty())
357 : : {
358 : : // the relevant parts of ScUnoAddInCall without having to create one
359 : : const ScUnoAddInFuncData* pFuncData =
360 [ # # ][ # # ]: 0 : ScGlobal::GetAddInCollection()->GetFuncData( aUnoName, true ); // need fully initialized data
361 [ # # ]: 0 : if ( pFuncData )
362 : : {
363 : 0 : long nCount = pFuncData->GetArgumentCount();
364 [ # # ]: 0 : if ( nCount <= 0 )
365 : 0 : eRet = Bounds;
366 : : else
367 : : {
368 : 0 : const ScAddInArgDesc* pArgs = pFuncData->GetArguments();
369 [ # # ][ # # ]: 0 : if ( nParameter >= nCount &&
370 : 0 : pArgs[nCount-1].eType == SC_ADDINARG_VARARGS )
371 : 0 : eRet = Value;
372 : : // last arg is sequence, optional "any"s, we simply can't
373 : : // determine the type
374 [ # # ]: 0 : if ( eRet == Unknown )
375 : : {
376 [ # # ]: 0 : if ( nParameter >= nCount )
377 : 0 : eRet = Bounds;
378 : : else
379 : : {
380 [ # # ]: 0 : switch ( pArgs[nParameter].eType )
381 : : {
382 : : case SC_ADDINARG_INTEGER:
383 : : case SC_ADDINARG_DOUBLE:
384 : : case SC_ADDINARG_STRING:
385 : 0 : eRet = Value;
386 : 0 : break;
387 : : default:
388 : 0 : eRet = Reference;
389 : : }
390 : : }
391 : : }
392 : : }
393 : : }
394 : : }
395 : 0 : return eRet;
396 : : }
397 : :
398 : : //-----------------------------------------------------------------------------
399 : :
400 : : #if OSL_DEBUG_LEVEL > 1
401 : :
402 : : // add remaining functions, all Value parameters
403 : : void ScParameterClassification::MergeArgumentsFromFunctionResource()
404 : : {
405 : : ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
406 : : for ( const ScFuncDesc* pDesc = pFuncList->First(); pDesc;
407 : : pDesc = pFuncList->Next() )
408 : : {
409 : : if ( pDesc->nFIndex > SC_OPCODE_LAST_OPCODE_ID ||
410 : : pData[pDesc->nFIndex].aData.nParam[0] != Unknown )
411 : : continue; // not an internal opcode or already done
412 : :
413 : : RunData* pRun = &pData[ pDesc->nFIndex ];
414 : : sal_uInt16 nArgs = pDesc->GetSuppressedArgCount();
415 : : if ( nArgs >= VAR_ARGS )
416 : : {
417 : : nArgs -= VAR_ARGS - 1;
418 : : pRun->aData.bRepeatLast = true;
419 : : }
420 : : if ( nArgs > CommonData::nMaxParams )
421 : : {
422 : : rtl::OStringBuffer aBuf;
423 : : aBuf.append("ScParameterClassification::Init: too many arguments in listed function: ");
424 : : aBuf.append(rtl::OUStringToOString(*(pDesc->pFuncName), RTL_TEXTENCODING_UTF8));
425 : : aBuf.append(": ");
426 : : aBuf.append(sal_Int32(nArgs));
427 : : OSL_FAIL( aBuf.getStr());
428 : : nArgs = CommonData::nMaxParams;
429 : : pRun->aData.bRepeatLast = true;
430 : : }
431 : : pRun->nMinParams = static_cast< sal_uInt8 >( nArgs );
432 : : for ( sal_Int32 j=0; j < nArgs; ++j )
433 : : {
434 : : pRun->aData.nParam[j] = Value;
435 : : }
436 : : if ( pRun->aData.bRepeatLast )
437 : : {
438 : : for ( sal_Int32 j = nArgs; j < CommonData::nMaxParams; ++j )
439 : : {
440 : : pRun->aData.nParam[j] = Value;
441 : : }
442 : : }
443 : : else
444 : : {
445 : : for ( sal_Int32 j = nArgs; j < CommonData::nMaxParams; ++j )
446 : : {
447 : : pRun->aData.nParam[j] = Bounds;
448 : : }
449 : : }
450 : : }
451 : : }
452 : :
453 : :
454 : : void ScParameterClassification::GenerateDocumentation()
455 : : {
456 : : static const sal_Char aEnvVarName[] = "OOO_CALC_GENPARCLASSDOC";
457 : : if ( !getenv( aEnvVarName) )
458 : : return;
459 : : MergeArgumentsFromFunctionResource();
460 : : ScAddress aAddress;
461 : : ScCompiler aComp(NULL,aAddress);
462 : : ScCompiler::OpCodeMapPtr xMap( aComp.GetOpCodeMap(::com::sun::star::sheet::FormulaLanguage::ENGLISH));
463 : : if (!xMap)
464 : : return;
465 : : fflush( stderr);
466 : : size_t nCount = xMap->getSymbolCount();
467 : : for ( size_t i=0; i<nCount; ++i )
468 : : {
469 : : OpCode eOp = OpCode(i);
470 : : if ( xMap->getSymbol(eOp).Len() )
471 : : {
472 : : fprintf( stdout, "%s: ", aEnvVarName);
473 : : rtl::OStringBuffer aStr(rtl::OUStringToOString(xMap->getSymbol(eOp), RTL_TEXTENCODING_UTF8));
474 : : aStr.append('(');
475 : : formula::FormulaByteToken aToken( eOp);
476 : : sal_uInt8 nParams = GetMinimumParameters( eOp);
477 : : // preset parameter count according to opcode value, with some
478 : : // special handling
479 : : if ( eOp < SC_OPCODE_STOP_DIV )
480 : : {
481 : : switch ( eOp )
482 : : {
483 : : case ocIf:
484 : : aToken.SetByte(3);
485 : : break;
486 : : case ocChose:
487 : : aToken.SetByte(2);
488 : : break;
489 : : case ocPercentSign:
490 : : aToken.SetByte(1);
491 : : break;
492 : : default:;
493 : : }
494 : : }
495 : : else if ( eOp < SC_OPCODE_STOP_ERRORS )
496 : : aToken.SetByte(0);
497 : : else if ( eOp < SC_OPCODE_STOP_BIN_OP )
498 : : {
499 : : switch ( eOp )
500 : : {
501 : : case ocAnd:
502 : : case ocOr:
503 : : aToken.SetByte(1); // (r1)AND(r2) --> AND( r1, ...)
504 : : break;
505 : : default:
506 : : aToken.SetByte(2);
507 : : }
508 : : }
509 : : else if ( eOp < SC_OPCODE_STOP_UN_OP )
510 : : aToken.SetByte(1);
511 : : else if ( eOp < SC_OPCODE_STOP_NO_PAR )
512 : : aToken.SetByte(0);
513 : : else if ( eOp < SC_OPCODE_STOP_1_PAR )
514 : : aToken.SetByte(1);
515 : : else
516 : : aToken.SetByte( nParams);
517 : : // compare (this is a mere test for opcode order Div, BinOp, UnOp,
518 : : // NoPar, 1Par, ...) and override parameter count with
519 : : // classification
520 : : if ( nParams != aToken.GetByte() )
521 : : fprintf( stdout, "(parameter count differs, token Byte: %d classification: %d) ",
522 : : aToken.GetByte(), nParams);
523 : : aToken.SetByte( nParams);
524 : : if ( nParams != aToken.GetParamCount() )
525 : : fprintf( stdout, "(parameter count differs, token ParamCount: %d classification: %d) ",
526 : : aToken.GetParamCount(), nParams);
527 : : for ( sal_uInt16 j=0; j < nParams; ++j )
528 : : {
529 : : if ( j > 0 )
530 : : aStr.append(',');
531 : : Type eType = GetParameterType( &aToken, j);
532 : : switch ( eType )
533 : : {
534 : : case Value :
535 : : aStr.append(" Value");
536 : : break;
537 : : case Reference :
538 : : aStr.append(" Reference");
539 : : break;
540 : : case Array :
541 : : aStr.append(" Array");
542 : : break;
543 : : case ForceArray :
544 : : aStr.append(" ForceArray");
545 : : break;
546 : : case ReferenceOrForceArray :
547 : : aStr.append(" ReferenceOrForceArray");
548 : : break;
549 : : case Bounds :
550 : : aStr.append(" (Bounds, classification error?)");
551 : : break;
552 : : default:
553 : : aStr.append(" (???, classification error?)");
554 : : }
555 : : }
556 : : if ( HasRepeatParameters( eOp) )
557 : : aStr.append(", ...");
558 : : if ( nParams )
559 : : aStr.append(' ');
560 : : aStr.append(')');
561 : : switch ( eOp )
562 : : {
563 : : case ocZGZ:
564 : : aStr.append(" // RRI in English resource, but ZGZ in English-only section");
565 : : break;
566 : : case ocMultiArea:
567 : : aStr.append(" // e.g. combined first parameter of INDEX() function, not a real function");
568 : : break;
569 : : case ocBackSolver:
570 : : aStr.append(" // goal seek via menu, not a real function");
571 : : break;
572 : : case ocTableOp:
573 : : aStr.append(" // MULTIPLE.OPERATIONS in English resource, but TABLE in English-only section");
574 : : break;
575 : : case ocNoName:
576 : : aStr.append(" // error function, not a real function");
577 : : break;
578 : : default:;
579 : : }
580 : : fprintf( stdout, "%s\n", aStr.getStr());
581 : : }
582 : : }
583 : : fflush( stdout);
584 : : }
585 : :
586 : : #endif // OSL_DEBUG_LEVEL
587 : :
588 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|