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