1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef SC_PARCLASS_HXX 29 #define SC_PARCLASS_HXX 30 31 #include "formula/opcode.hxx" 32 #include <sys/types.h> // size_t 33 34 namespace formula 35 { 36 class FormulaToken; 37 } 38 39 class ScParameterClassification 40 { 41 public: 42 43 enum Type 44 { 45 Unknown = 0, // MUST be zero for initialization mechanism! 46 47 /** Out of bounds, function doesn't expect that many parameters. 48 However, not necessarily returned. */ 49 Bounds, 50 51 /** In array formula: single value to be passed. Results in JumpMatrix 52 being created and multiple calls to function. Functions handling a 53 formula::svDoubleRef by means of DoubleRefToPosSingleRef() or 54 PopDoubleRefOrSingleRef() or GetDouble() or GetString() should have 55 this. */ 56 Value, 57 58 /** In array formula: area reference must stay reference. Otherwise 59 don't care. Functions handling a formula::svDoubleRef by means of 60 PopDoubleRefOrSingleRef() should not have this. */ 61 Reference, 62 63 /** In array formula: convert area reference to array. Function will be 64 called only once if no Value type is involved. Functions able to 65 handle a svMatrix parameter but not a formula::svDoubleRef parameter as area 66 should have this. */ 67 Array, 68 69 /** Area reference must be converted to array in any case, and must 70 also be propagated to subsequent operators and functions being part 71 of a parameter of this function. */ 72 ForceArray, 73 74 /** Area reference is not converted to array, but ForceArray must be 75 propagated to subsequent operators and functions being part of a 76 parameter of this function. Used with functions that treat 77 references separately from arrays, but need the forced array 78 calculation of parameters that are not references.*/ 79 ReferenceOrForceArray 80 }; 81 82 /// MUST be called once before any other method. 83 static void Init(); 84 85 static void Exit(); 86 87 /** Get one parameter type for function eOp. 88 @param nParameter 89 Which parameter, 0-based */ 90 static Type GetParameterType( const formula::FormulaToken* pToken, 91 sal_uInt16 nParameter); 92 93 /** Whether OpCode has a parameter of type 94 ForceArray or ReferenceOrForceArray. */ 95 static inline bool HasForceArray( OpCode eOp) 96 { 97 return 0 <= (short)eOp && 98 eOp <= SC_OPCODE_LAST_OPCODE_ID && 99 pData[eOp].bHasForceArray; 100 } 101 102 private: 103 104 struct CommonData 105 { 106 const static size_t nMaxParams = 7; 107 108 Type nParam[nMaxParams]; 109 bool bRepeatLast; 110 }; 111 112 // SUNWS7 needs a forward declared friend, otherwise members of the outer 113 // class are not accessible (in this case CommonData). 114 struct RawData; 115 friend struct ScParameterClassification::RawData; 116 struct RawData 117 { 118 OpCode eOp; 119 CommonData aData; 120 }; 121 122 struct RunData; 123 friend struct ScParameterClassification::RunData; 124 struct RunData 125 { 126 CommonData aData; 127 sal_uInt8 nMinParams; // fix or minimum, or repeat start 128 bool bHasForceArray; 129 }; 130 131 static const RawData pRawData[]; 132 static RunData* pData; 133 134 // ocExternal AddIns 135 static Type GetExternalParameterType( 136 const formula::FormulaToken* pToken, sal_uInt16 nParameter); 137 138 #if OSL_DEBUG_LEVEL > 1 139 // Generate documentation to stdout if environment variable 140 // OOO_CALC_GENPARCLASSDOC is set. 141 static void GenerateDocumentation(); 142 143 /* OpCodes not specified in the implementation are taken from the global 144 * function list and all parameters, if any, are assumed to be of type 145 * Value. This could also be done in the product version if needed, but we 146 * don't want to spoil startup time. However, doing so could propagate the 147 * minimum parameter count to the formula compiler, which, together with 148 * additional information about optional parameters, could react on missing 149 * parameters then. */ 150 static void MergeArgumentsFromFunctionResource(); 151 152 /** Minimum number of parameters, or fix number 153 of parameters if HasRepeatParameters() 154 returns sal_False. For opcodes not specified in 155 the implementation a parameter count of 1 156 is assumed, for opcodes out of range 0 is 157 assumed. If HasRepeatParameters() returns 158 sal_True, information is NOT related to whether 159 any parameters are optional, only the type 160 of parameters is significant. */ 161 static inline sal_uInt8 GetMinimumParameters( OpCode eOp) 162 { 163 if ( eOp <= SC_OPCODE_LAST_OPCODE_ID ) 164 return pData[eOp].aData.nParam[0] 165 == Unknown ? 1 : 166 pData[eOp].nMinParams; 167 return 0; 168 } 169 170 /** Whether last parameter type is repeated. */ 171 static inline bool HasRepeatParameters( OpCode eOp) 172 { 173 return eOp <= SC_OPCODE_LAST_OPCODE_ID 174 && pData[eOp].aData.bRepeatLast; 175 } 176 #endif // OSL_DEBUG_LEVEL 177 }; 178 179 #endif // SC_PARCLASS_HXX 180 181