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 "xlformula.hxx"
21 :
22 : #include "compiler.hxx"
23 : #include "rangenam.hxx"
24 : #include "token.hxx"
25 : #include "tokenarray.hxx"
26 : #include "xestream.hxx"
27 : #include "xistream.hxx"
28 : #include "xlroot.hxx"
29 :
30 : #include <comphelper/string.hxx>
31 : #include <svl/sharedstringpool.hxx>
32 :
33 : using namespace ::formula;
34 :
35 : // Function data ==============================================================
36 :
37 50610 : OUString XclFunctionInfo::GetMacroFuncName() const
38 : {
39 50610 : if( IsMacroFunc() )
40 50610 : return OUString( mpcMacroName, strlen(mpcMacroName), RTL_TEXTENCODING_UTF8 );
41 0 : return OUString();
42 : }
43 :
44 0 : OUString XclFunctionInfo::GetAddInEquivalentFuncName() const
45 : {
46 0 : if( IsAddInEquivalent() )
47 0 : return OUString( mpcMacroName, strlen(mpcMacroName), RTL_TEXTENCODING_UTF8 );
48 0 : return OUString();
49 : }
50 :
51 : // abbreviations for function return token class
52 : const sal_uInt8 R = EXC_TOKCLASS_REF;
53 : const sal_uInt8 V = EXC_TOKCLASS_VAL;
54 : const sal_uInt8 A = EXC_TOKCLASS_ARR;
55 :
56 : // abbreviations for parameter infos
57 : #define RO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, false }
58 : #define RA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, false }
59 : #define RR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, false }
60 : #define RX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, false }
61 : #define VO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, true }
62 : #define VV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, true }
63 : #define VA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, true }
64 : #define VR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, true }
65 : #define VX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, true }
66 : #define RO_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_ORG, false }
67 : #define VR_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_RPT, true }
68 : #define C { EXC_PARAM_CALCONLY, EXC_PARAMCONV_ORG, false }
69 :
70 : const sal_uInt16 NOID = SAL_MAX_UINT16; /// No BIFF/OOBIN function identifier available.
71 : const sal_uInt8 MX = 30; /// Maximum parameter count.
72 :
73 : #define EXC_FUNCNAME( ascii ) "_xlfn." ascii
74 : #define EXC_FUNCNAME_ODF( ascii ) "_xlfnodf." ascii
75 : #define EXC_FUNCNAME_ADDIN( ascii ) "com.sun.star.sheet.addin." ascii
76 :
77 : /** Functions new in BIFF2. */
78 : static const XclFunctionInfo saFuncTable_2[] =
79 : {
80 : { ocCount, 0, 0, MX, V, { RX }, 0, 0 },
81 : { ocIf, 1, 2, 3, R, { VO, RO }, 0, 0 },
82 : { ocIsNA, 2, 1, 1, V, { VR }, 0, 0 },
83 : { ocIsError, 3, 1, 1, V, { VR }, 0, 0 },
84 : { ocSum, 4, 0, MX, V, { RX }, 0, 0 },
85 : { ocAverage, 5, 1, MX, V, { RX }, 0, 0 },
86 : { ocMin, 6, 1, MX, V, { RX }, 0, 0 },
87 : { ocMax, 7, 1, MX, V, { RX }, 0, 0 },
88 : { ocRow, 8, 0, 1, V, { RO }, 0, 0 },
89 : { ocColumn, 9, 0, 1, V, { RO }, 0, 0 },
90 : { ocNotAvail, 10, 0, 0, V, {}, 0, 0 },
91 : { ocNPV, 11, 2, MX, V, { VR, RX }, 0, 0 },
92 : { ocStDev, 12, 1, MX, V, { RX }, 0, 0 },
93 : { ocCurrency, 13, 1, 2, V, { VR }, 0, 0 },
94 : { ocFixed, 14, 1, 2, V, { VR, VR, C }, 0, 0 },
95 : { ocSin, 15, 1, 1, V, { VR }, 0, 0 },
96 : { ocCosecant, 15, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
97 : { ocCos, 16, 1, 1, V, { VR }, 0, 0 },
98 : { ocSecant, 16, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
99 : { ocTan, 17, 1, 1, V, { VR }, 0, 0 },
100 : { ocCot, 17, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
101 : { ocArcTan, 18, 1, 1, V, { VR }, 0, 0 },
102 : { ocArcCot, 18, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
103 : { ocPi, 19, 0, 0, V, {}, 0, 0 },
104 : { ocSqrt, 20, 1, 1, V, { VR }, 0, 0 },
105 : { ocExp, 21, 1, 1, V, { VR }, 0, 0 },
106 : { ocLn, 22, 1, 1, V, { VR }, 0, 0 },
107 : { ocLog10, 23, 1, 1, V, { VR }, 0, 0 },
108 : { ocAbs, 24, 1, 1, V, { VR }, 0, 0 },
109 : { ocInt, 25, 1, 1, V, { VR }, 0, 0 },
110 : { ocPlusMinus, 26, 1, 1, V, { VR }, 0, 0 },
111 : { ocRound, 27, 2, 2, V, { VR }, 0, 0 },
112 : { ocLookup, 28, 2, 3, V, { VR, RA }, 0, 0 },
113 : { ocIndex, 29, 2, 4, R, { RA, VV }, 0, 0 },
114 : { ocRept, 30, 2, 2, V, { VR }, 0, 0 },
115 : { ocMid, 31, 3, 3, V, { VR }, 0, 0 },
116 : { ocLen, 32, 1, 1, V, { VR }, 0, 0 },
117 : { ocValue, 33, 1, 1, V, { VR }, 0, 0 },
118 : { ocTrue, 34, 0, 0, V, {}, 0, 0 },
119 : { ocFalse, 35, 0, 0, V, {}, 0, 0 },
120 : { ocAnd, 36, 1, MX, V, { RX }, 0, 0 },
121 : { ocOr, 37, 1, MX, V, { RX }, 0, 0 },
122 : { ocNot, 38, 1, 1, V, { VR }, 0, 0 },
123 : { ocMod, 39, 2, 2, V, { VR }, 0, 0 },
124 : { ocDBCount, 40, 3, 3, V, { RO, RR }, 0, 0 },
125 : { ocDBSum, 41, 3, 3, V, { RO, RR }, 0, 0 },
126 : { ocDBAverage, 42, 3, 3, V, { RO, RR }, 0, 0 },
127 : { ocDBMin, 43, 3, 3, V, { RO, RR }, 0, 0 },
128 : { ocDBMax, 44, 3, 3, V, { RO, RR }, 0, 0 },
129 : { ocDBStdDev, 45, 3, 3, V, { RO, RR }, 0, 0 },
130 : { ocVar, 46, 1, MX, V, { RX }, 0, 0 },
131 : { ocDBVar, 47, 3, 3, V, { RO, RR }, 0, 0 },
132 : { ocText, 48, 2, 2, V, { VR }, 0, 0 },
133 : { ocRGP, 49, 1, 2, A, { RA, RA, C, C }, 0, 0 },
134 : { ocTrend, 50, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
135 : { ocRKP, 51, 1, 2, A, { RA, RA, C, C }, 0, 0 },
136 : { ocGrowth, 52, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
137 : { ocBW, 56, 3, 5, V, { VR }, 0, 0 },
138 : { ocZW, 57, 3, 5, V, { VR }, 0, 0 },
139 : { ocZZR, 58, 3, 5, V, { VR }, 0, 0 },
140 : { ocRMZ, 59, 3, 5, V, { VR }, 0, 0 },
141 : { ocZins, 60, 3, 6, V, { VR }, 0, 0 },
142 : { ocMIRR, 61, 3, 3, V, { RA, VR }, 0, 0 },
143 : { ocIRR, 62, 1, 2, V, { RA, VR }, 0, 0 },
144 : { ocRandom, 63, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
145 : { ocMatch, 64, 2, 3, V, { VR, RX, RR }, 0, 0 },
146 : { ocGetDate, 65, 3, 3, V, { VR }, 0, 0 },
147 : { ocGetTime, 66, 3, 3, V, { VR }, 0, 0 },
148 : { ocGetDay, 67, 1, 1, V, { VR }, 0, 0 },
149 : { ocGetMonth, 68, 1, 1, V, { VR }, 0, 0 },
150 : { ocGetYear, 69, 1, 1, V, { VR }, 0, 0 },
151 : { ocGetDayOfWeek, 70, 1, 1, V, { VR, C }, 0, 0 },
152 : { ocGetHour, 71, 1, 1, V, { VR }, 0, 0 },
153 : { ocGetMin, 72, 1, 1, V, { VR }, 0, 0 },
154 : { ocGetSec, 73, 1, 1, V, { VR }, 0, 0 },
155 : { ocGetActTime, 74, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
156 : { ocAreas, 75, 1, 1, V, { RO }, 0, 0 },
157 : { ocRows, 76, 1, 1, V, { RO }, 0, 0 },
158 : { ocColumns, 77, 1, 1, V, { RO }, 0, 0 },
159 : { ocOffset, 78, 3, 5, R, { RO, VR }, EXC_FUNCFLAG_VOLATILE, 0 },
160 : { ocSearch, 82, 2, 3, V, { VR }, 0, 0 },
161 : { ocMatTrans, 83, 1, 1, A, { VO }, 0, 0 },
162 : { ocType, 86, 1, 1, V, { VX }, 0, 0 },
163 : { ocArcTan2, 97, 2, 2, V, { VR }, 0, 0 },
164 : { ocArcSin, 98, 1, 1, V, { VR }, 0, 0 },
165 : { ocArcCos, 99, 1, 1, V, { VR }, 0, 0 },
166 : { ocChose, 100, 2, MX, R, { VO, RO }, 0, 0 },
167 : { ocHLookup, 101, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
168 : { ocVLookup, 102, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
169 : { ocIsRef, 105, 1, 1, V, { RX }, 0, 0 },
170 : { ocLog, 109, 1, 2, V, { VR }, 0, 0 },
171 : { ocChar, 111, 1, 1, V, { VR }, 0, 0 },
172 : { ocLower, 112, 1, 1, V, { VR }, 0, 0 },
173 : { ocUpper, 113, 1, 1, V, { VR }, 0, 0 },
174 : { ocPropper, 114, 1, 1, V, { VR }, 0, 0 },
175 : { ocLeft, 115, 1, 2, V, { VR }, 0, 0 },
176 : { ocRight, 116, 1, 2, V, { VR }, 0, 0 },
177 : { ocExact, 117, 2, 2, V, { VR }, 0, 0 },
178 : { ocTrim, 118, 1, 1, V, { VR }, 0, 0 },
179 : { ocReplace, 119, 4, 4, V, { VR }, 0, 0 },
180 : { ocSubstitute, 120, 3, 4, V, { VR }, 0, 0 },
181 : { ocCode, 121, 1, 1, V, { VR }, 0, 0 },
182 : { ocFind, 124, 2, 3, V, { VR }, 0, 0 },
183 : { ocCell, 125, 1, 2, V, { VV, RO }, EXC_FUNCFLAG_VOLATILE, 0 },
184 : { ocIsErr, 126, 1, 1, V, { VR }, 0, 0 },
185 : { ocIsString, 127, 1, 1, V, { VR }, 0, 0 },
186 : { ocIsValue, 128, 1, 1, V, { VR }, 0, 0 },
187 : { ocIsEmpty, 129, 1, 1, V, { VR }, 0, 0 },
188 : { ocT, 130, 1, 1, V, { RO }, 0, 0 },
189 : { ocN, 131, 1, 1, V, { RO }, 0, 0 },
190 : { ocGetDateValue, 140, 1, 1, V, { VR }, 0, 0 },
191 : { ocGetTimeValue, 141, 1, 1, V, { VR }, 0, 0 },
192 : { ocLIA, 142, 3, 3, V, { VR }, 0, 0 },
193 : { ocDIA, 143, 4, 4, V, { VR }, 0, 0 },
194 : { ocGDA, 144, 4, 5, V, { VR }, 0, 0 },
195 : { ocIndirect, 148, 1, 2, R, { VR }, EXC_FUNCFLAG_VOLATILE, 0 },
196 : { ocClean, 162, 1, 1, V, { VR }, 0, 0 },
197 : { ocMatDet, 163, 1, 1, V, { VA }, 0, 0 },
198 : { ocMatInv, 164, 1, 1, A, { VA }, 0, 0 },
199 : { ocMatMult, 165, 2, 2, A, { VA }, 0, 0 },
200 : { ocZinsZ, 167, 4, 6, V, { VR }, 0, 0 },
201 : { ocKapz, 168, 4, 6, V, { VR }, 0, 0 },
202 : { ocCount2, 169, 0, MX, V, { RX }, 0, 0 },
203 : { ocProduct, 183, 0, MX, V, { RX }, 0, 0 },
204 : { ocFact, 184, 1, 1, V, { VR }, 0, 0 },
205 : { ocDBProduct, 189, 3, 3, V, { RO, RR }, 0, 0 },
206 : { ocIsNonString, 190, 1, 1, V, { VR }, 0, 0 },
207 : { ocStDevP, 193, 1, MX, V, { RX }, 0, 0 },
208 : { ocVarP, 194, 1, MX, V, { RX }, 0, 0 },
209 : { ocDBStdDevP, 195, 3, 3, V, { RO, RR }, 0, 0 },
210 : { ocDBVarP, 196, 3, 3, V, { RO, RR }, 0, 0 },
211 : { ocTrunc, 197, 1, 1, V, { VR, C }, 0, 0 },
212 : { ocIsLogical, 198, 1, 1, V, { VR }, 0, 0 },
213 : { ocDBCount2, 199, 3, 3, V, { RO, RR }, 0, 0 },
214 : { ocCurrency, 204, 1, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },
215 : { ocLeftB, 208, 1, 2, V, { VR }, 0, 0 },
216 : { ocRightB, 209, 1, 2, V, { VR }, 0, 0 },
217 : { ocMidB, 210, 3, 3, V, { VR }, 0, 0 },
218 : { ocLenB, 211, 1, 1, V, { VR }, 0, 0 },
219 : { ocRoundUp, 212, 2, 2, V, { VR }, 0, 0 },
220 : { ocRoundDown, 213, 2, 2, V, { VR }, 0, 0 },
221 : { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }
222 : };
223 :
224 : /** Functions new in BIFF3. */
225 : static const XclFunctionInfo saFuncTable_3[] =
226 : {
227 : { ocRGP, 49, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
228 : { ocTrend, 50, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
229 : { ocRKP, 51, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
230 : { ocGrowth, 52, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
231 : { ocTrunc, 197, 1, 2, V, { VR }, 0, 0 }, // BIFF2: 1, BIFF3: 1-2
232 : { ocAddress, 219, 2, 5, V, { VR }, 0, 0 },
233 : { ocGetDiffDate360, 220, 2, 2, V, { VR, VR, C }, 0, 0 },
234 : { ocGetActDate, 221, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
235 : { ocVBD, 222, 5, 7, V, { VR }, 0, 0 },
236 : { ocMedian, 227, 1, MX, V, { RX }, 0, 0 },
237 : { ocSumProduct, 228, 1, MX, V, { VA }, 0, 0 },
238 : { ocSinHyp, 229, 1, 1, V, { VR }, 0, 0 },
239 : { ocCosecantHyp, 229, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
240 : { ocCosHyp, 230, 1, 1, V, { VR }, 0, 0 },
241 : { ocSecantHyp, 230, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
242 : { ocTanHyp, 231, 1, 1, V, { VR }, 0, 0 },
243 : { ocCotHyp, 231, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
244 : { ocArcSinHyp, 232, 1, 1, V, { VR }, 0, 0 },
245 : { ocArcCosHyp, 233, 1, 1, V, { VR }, 0, 0 },
246 : { ocArcTanHyp, 234, 1, 1, V, { VR }, 0, 0 },
247 : { ocArcCotHyp, 234, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
248 : { ocDBGet, 235, 3, 3, V, { RO, RR }, 0, 0 },
249 : { ocInfo, 244, 1, 1, V, { VR }, EXC_FUNCFLAG_VOLATILE, 0 }
250 : };
251 :
252 : /** Functions new in BIFF4. */
253 : static const XclFunctionInfo saFuncTable_4[] =
254 : {
255 : { ocFixed, 14, 1, 3, V, { VR }, 0, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3
256 : { ocAsc, 214, 1, 1, V, { VR }, 0, 0 },
257 : { ocJis, 215, 1, 1, V, { VR }, 0, 0 },
258 : { ocRank, 216, 2, 3, V, { VR, RO, VR }, 0, 0 },
259 : { ocGDA2, 247, 4, 5, V, { VR }, 0, 0 },
260 : { ocFrequency, 252, 2, 2, A, { RA }, 0, 0 },
261 : { ocErrorType, 261, 1, 1, V, { VR }, 0, 0 },
262 : { ocAveDev, 269, 1, MX, V, { RX }, 0, 0 },
263 : { ocBetaDist, 270, 3, 5, V, { VR }, 0, 0 },
264 : { ocGammaLn, 271, 1, 1, V, { VR }, 0, 0 },
265 : { ocBetaInv, 272, 3, 5, V, { VR }, 0, 0 },
266 : { ocBinomDist, 273, 4, 4, V, { VR }, 0, 0 },
267 : { ocChiDist, 274, 2, 2, V, { VR }, 0, 0 },
268 : { ocChiInv, 275, 2, 2, V, { VR }, 0, 0 },
269 : { ocKombin, 276, 2, 2, V, { VR }, 0, 0 },
270 : { ocConfidence, 277, 3, 3, V, { VR }, 0, 0 },
271 : { ocKritBinom, 278, 3, 3, V, { VR }, 0, 0 },
272 : { ocEven, 279, 1, 1, V, { VR }, 0, 0 },
273 : { ocExpDist, 280, 3, 3, V, { VR }, 0, 0 },
274 : { ocFDist, 281, 3, 3, V, { VR }, 0, 0 },
275 : { ocFInv, 282, 3, 3, V, { VR }, 0, 0 },
276 : { ocFisher, 283, 1, 1, V, { VR }, 0, 0 },
277 : { ocFisherInv, 284, 1, 1, V, { VR }, 0, 0 },
278 : { ocFloor, 285, 2, 2, V, { VR, VR, C }, 0, 0 },
279 : { ocGammaDist, 286, 4, 4, V, { VR }, 0, 0 },
280 : { ocGammaInv, 287, 3, 3, V, { VR }, 0, 0 },
281 : { ocCeil, 288, 2, 2, V, { VR, VR, C }, 0, 0 },
282 : { ocHypGeomDist, 289, 4, 4, V, { VR }, 0, 0 },
283 : { ocLogNormDist, 290, 3, 3, V, { VR }, 0, 0 },
284 : { ocLogInv, 291, 3, 3, V, { VR }, 0, 0 },
285 : { ocNegBinomVert, 292, 3, 3, V, { VR }, 0, 0 },
286 : { ocNormDist, 293, 4, 4, V, { VR }, 0, 0 },
287 : { ocStdNormDist, 294, 1, 1, V, { VR }, 0, 0 },
288 : { ocNormInv, 295, 3, 3, V, { VR }, 0, 0 },
289 : { ocSNormInv, 296, 1, 1, V, { VR }, 0, 0 },
290 : { ocStandard, 297, 3, 3, V, { VR }, 0, 0 },
291 : { ocOdd, 298, 1, 1, V, { VR }, 0, 0 },
292 : { ocVariationen, 299, 2, 2, V, { VR }, 0, 0 },
293 : { ocPoissonDist, 300, 3, 3, V, { VR }, 0, 0 },
294 : { ocTDist, 301, 3, 3, V, { VR }, 0, 0 },
295 : { ocWeibull, 302, 4, 4, V, { VR }, 0, 0 },
296 : { ocSumXMY2, 303, 2, 2, V, { VA }, 0, 0 },
297 : { ocSumX2MY2, 304, 2, 2, V, { VA }, 0, 0 },
298 : { ocSumX2DY2, 305, 2, 2, V, { VA }, 0, 0 },
299 : { ocChiTest, 306, 2, 2, V, { VA }, 0, 0 },
300 : { ocCorrel, 307, 2, 2, V, { VA }, 0, 0 },
301 : { ocCovar, 308, 2, 2, V, { VA }, 0, 0 },
302 : { ocForecast, 309, 3, 3, V, { VR, VA }, 0, 0 },
303 : { ocFTest, 310, 2, 2, V, { VA }, 0, 0 },
304 : { ocIntercept, 311, 2, 2, V, { VA }, 0, 0 },
305 : { ocPearson, 312, 2, 2, V, { VA }, 0, 0 },
306 : { ocRSQ, 313, 2, 2, V, { VA }, 0, 0 },
307 : { ocSTEYX, 314, 2, 2, V, { VA }, 0, 0 },
308 : { ocSlope, 315, 2, 2, V, { VA }, 0, 0 },
309 : { ocTTest, 316, 4, 4, V, { VA, VA, VR }, 0, 0 },
310 : { ocProb, 317, 3, 4, V, { VA, VA, VR }, 0, 0 },
311 : { ocDevSq, 318, 1, MX, V, { RX }, 0, 0 },
312 : { ocGeoMean, 319, 1, MX, V, { RX }, 0, 0 },
313 : { ocHarMean, 320, 1, MX, V, { RX }, 0, 0 },
314 : { ocSumSQ, 321, 0, MX, V, { RX }, 0, 0 },
315 : { ocKurt, 322, 1, MX, V, { RX }, 0, 0 },
316 : { ocSchiefe, 323, 1, MX, V, { RX }, 0, 0 },
317 : { ocZTest, 324, 2, 3, V, { RX, VR }, 0, 0 },
318 : { ocLarge, 325, 2, 2, V, { RX, VR }, 0, 0 },
319 : { ocSmall, 326, 2, 2, V, { RX, VR }, 0, 0 },
320 : { ocQuartile, 327, 2, 2, V, { RX, VR }, 0, 0 },
321 : { ocPercentile, 328, 2, 2, V, { RX, VR }, 0, 0 },
322 : { ocPercentrank, 329, 2, 3, V, { RX, VR, VR_E }, 0, 0 },
323 : { ocModalValue, 330, 1, MX, V, { VA }, 0, 0 },
324 : { ocTrimMean, 331, 2, 2, V, { RX, VR }, 0, 0 },
325 : { ocTInv, 332, 2, 2, V, { VR }, 0, 0 },
326 : // Functions equivalent to add-in functions, use same parameters as
327 : // ocExternal but add programmatical function name (here without
328 : // "com.sun.star.sheet.addin.") so it can be looked up and stored as
329 : // add-in, as older Excel versions only know them as add-in.
330 : // These are the functions flagged as AddInMap::bMapDupToInternal=true in
331 : // sc/source/core/tool/odffmap.cxx
332 : { ocIsEven, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY | EXC_FUNCFLAG_ADDINEQUIV, EXC_FUNCNAME_ADDIN( "Analysis.getIseven" ) },
333 : { ocIsOdd, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY | EXC_FUNCFLAG_ADDINEQUIV, EXC_FUNCNAME_ADDIN( "Analysis.getIsodd" ) },
334 : { ocGCD, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY | EXC_FUNCFLAG_ADDINEQUIV, EXC_FUNCNAME_ADDIN( "Analysis.getGcd" ) },
335 : { ocLCM, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY | EXC_FUNCFLAG_ADDINEQUIV, EXC_FUNCNAME_ADDIN( "Analysis.getLcm" ) },
336 : { ocEffektiv, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY | EXC_FUNCFLAG_ADDINEQUIV, EXC_FUNCNAME_ADDIN( "Analysis.getEffect" ) },
337 : { ocKumKapZ, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY | EXC_FUNCFLAG_ADDINEQUIV, EXC_FUNCNAME_ADDIN( "Analysis.getCumprinc" ) },
338 : { ocKumZinsZ, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY | EXC_FUNCFLAG_ADDINEQUIV, EXC_FUNCNAME_ADDIN( "Analysis.getCumipmt" ) },
339 : { ocNominal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY | EXC_FUNCFLAG_ADDINEQUIV, EXC_FUNCNAME_ADDIN( "Analysis.getNominal" ) }
340 : };
341 :
342 : /** Functions new in BIFF5/BIFF7. Unsupported functions: DATESTRING, NUMBERSTRING. */
343 : static const XclFunctionInfo saFuncTable_5[] =
344 : {
345 : { ocGetDayOfWeek, 70, 1, 2, V, { VR }, 0, 0 }, // BIFF2-4: 1, BIFF5: 1-2
346 : { ocHLookup, 101, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
347 : { ocVLookup, 102, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
348 : { ocGetDiffDate360, 220, 2, 3, V, { VR }, 0, 0 }, // BIFF3-4: 2, BIFF5: 2-3
349 : { ocMacro, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
350 : { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
351 : { ocConcat, 336, 0, MX, V, { VR }, 0, 0 },
352 : { ocPower, 337, 2, 2, V, { VR }, 0, 0 },
353 : { ocRad, 342, 1, 1, V, { VR }, 0, 0 },
354 : { ocDeg, 343, 1, 1, V, { VR }, 0, 0 },
355 : { ocSubTotal, 344, 2, MX, V, { VR, RO }, 0, 0 },
356 : { ocSumIf, 345, 2, 3, V, { RO, VR, RO }, 0, 0 },
357 : { ocCountIf, 346, 2, 2, V, { RO, VR }, 0, 0 },
358 : { ocCountEmptyCells, 347, 1, 1, V, { RO }, 0, 0 },
359 : { ocISPMT, 350, 4, 4, V, { VR }, 0, 0 },
360 : { ocGetDateDif, 351, 3, 3, V, { VR }, 0, 0 },
361 : { ocNoName, 352, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATESTRING
362 : { ocNoName, 353, 2, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // NUMBERSTRING
363 : { ocRoman, 354, 1, 2, V, { VR }, 0, 0 }
364 : };
365 :
366 : /** Functions new in BIFF8. Unsupported functions: PHONETIC. */
367 : static const XclFunctionInfo saFuncTable_8[] =
368 : {
369 : { ocGetPivotData, 358, 2, MX, V, { RR, RR, VR }, 0, 0 },
370 : { ocHyperLink, 359, 1, 2, V, { VV, VO }, 0, 0 },
371 : { ocNoName, 360, 1, 1, V, { RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // PHONETIC
372 : { ocAverageA, 361, 1, MX, V, { RX }, 0, 0 },
373 : { ocMaxA, 362, 1, MX, V, { RX }, 0, 0 },
374 : { ocMinA, 363, 1, MX, V, { RX }, 0, 0 },
375 : { ocStDevPA, 364, 1, MX, V, { RX }, 0, 0 },
376 : { ocVarPA, 365, 1, MX, V, { RX }, 0, 0 },
377 : { ocStDevA, 366, 1, MX, V, { RX }, 0, 0 },
378 : { ocVarA, 367, 1, MX, V, { RX }, 0, 0 },
379 : { ocBahtText, 368, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
380 : { ocBahtText, 255, 2, 2, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
381 : { ocEuroConvert, 255, 4, 6, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" }
382 : };
383 :
384 : #define EXC_FUNCENTRY_V_VR( opcode, minparam, maxparam, flags, asciiname ) \
385 : { opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }, \
386 : { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }
387 :
388 : /** Functions new in OOXML. */
389 : static const XclFunctionInfo saFuncTable_Oox[] =
390 : {
391 : { ocCountIfs, NOID, 2, MX, V, { RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "COUNTIFS" ) },
392 : { ocCountIfs, 255, 3, MX, V, { RO_E, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "COUNTIFS" ) },
393 : { ocSumIfs, NOID, 3, MX, V, { RO, RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "SUMIFS" ) },
394 : { ocSumIfs, 255, 4, MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "SUMIFS" ) },
395 : { ocAverageIf, NOID, 2, 3, V, { RO, VR, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "AVERAGEIF" ) },
396 : { ocAverageIf, 255, 3, 4, V, { RO_E, RO, VR, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "AVERAGEIF" ) },
397 : { ocAverageIfs, NOID, 3, MX, V, { RO, RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) },
398 : { ocAverageIfs, 255, 4, MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) },
399 : { ocIfError, NOID, 2, 2, V, { VO, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "IFERROR" ) },
400 : { ocIfError, 255, 3, 3, V, { RO_E, VO, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "IFERROR" ) },
401 : { ocNetWorkdays_MS, NOID, 2, 4, V, { VR, VR, VR, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "NETWORKDAYS.INTL" ) },
402 : { ocNetWorkdays_MS, 255, 3, 5, V, { RO_E, VR, VR, VR, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "NETWORKDAYS.INTL" ) },
403 : { ocWorkday_MS, NOID, 2, 4, V, { VR, VR, VR, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "WORKDAY.INTL" ) },
404 : { ocWorkday_MS, 255, 3, 5, V, { RO_E, VR, VR, VR, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "WORKDAY.INTL" ) },
405 : EXC_FUNCENTRY_V_VR( ocCeil_ISO, 2, 2, 0, "ISO.CEILING" )
406 : };
407 :
408 : #define EXC_FUNCENTRY_V_VR_IMPORT( opcode, minparam, maxparam, flags, asciiname ) \
409 : { opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }
410 :
411 : #define EXC_FUNCENTRY_A_VR( opcode, minparam, maxparam, flags, asciiname ) \
412 : { opcode, NOID, minparam, maxparam, A, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }, \
413 : { opcode, 255, (minparam)+1, (maxparam)+1, A, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }
414 :
415 : #define EXC_FUNCENTRY_V_RO( opcode, minparam, maxparam, flags, asciiname ) \
416 : { opcode, NOID, minparam, maxparam, V, { RO }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }, \
417 : { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }
418 :
419 : // implicit maxparam=MX
420 : #define EXC_FUNCENTRY_V_RX( opcode, minparam, maxparam, flags, asciiname ) \
421 : { opcode, NOID, minparam, MX, V, { RX }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }, \
422 : { opcode, 255, (minparam)+1, MX, V, { RO_E, RX }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }
423 :
424 : #define EXC_FUNCENTRY_V_VA( opcode, minparam, maxparam, flags, asciiname ) \
425 : { opcode, NOID, minparam, maxparam, V, { VA }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }, \
426 : { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }
427 :
428 : /** Functions new in Excel 2010.
429 :
430 : See http://office.microsoft.com/en-us/excel-help/what-s-new-changes-made-to-excel-functions-HA010355760.aspx
431 : A lot of statistical functions have been renamed (the 'old' function names still exist).
432 :
433 : @See sc/source/filter/oox/formulabase.cxx saFuncTable2010 for V,VR,RO,...
434 : */
435 : static const XclFunctionInfo saFuncTable_2010[] =
436 : {
437 : EXC_FUNCENTRY_V_VA( ocCovarianceP, 2, 2, 0, "COVARIANCE.P" ),
438 : EXC_FUNCENTRY_V_VA( ocCovarianceS, 2, 2, 0, "COVARIANCE.S" ),
439 : EXC_FUNCENTRY_V_RX( ocStDevP_MS, 1, MX, 0, "STDEV.P" ),
440 : EXC_FUNCENTRY_V_RX( ocStDevS, 1, MX, 0, "STDEV.S" ),
441 : EXC_FUNCENTRY_V_RX( ocVarP_MS, 1, MX, 0, "VAR.P" ),
442 : EXC_FUNCENTRY_V_RX( ocVarS, 1, MX, 0, "VAR.S" ),
443 : EXC_FUNCENTRY_V_VR( ocBetaDist_MS, 4, 6, 0, "BETA.DIST" ),
444 : EXC_FUNCENTRY_V_VR( ocBetaInv_MS, 3, 5, 0, "BETA.INV" ),
445 : EXC_FUNCENTRY_V_VR( ocBinomDist_MS, 4, 4, 0, "BINOM.DIST" ),
446 : EXC_FUNCENTRY_V_VR( ocBinomInv, 3, 3, 0, "BINOM.INV" ),
447 : EXC_FUNCENTRY_V_VR( ocChiSqDist_MS, 3, 3, 0, "CHISQ.DIST" ),
448 : EXC_FUNCENTRY_V_VR( ocChiSqInv_MS, 2, 2, 0, "CHISQ.INV" ),
449 : EXC_FUNCENTRY_V_VR( ocChiDist_MS, 2, 2, 0, "CHISQ.DIST.RT" ),
450 : EXC_FUNCENTRY_V_VR( ocChiInv_MS, 2, 2, 0, "CHISQ.INV.RT" ),
451 : EXC_FUNCENTRY_V_VR( ocChiTest_MS, 2, 2, 0, "CHISQ.TEST" ),
452 : EXC_FUNCENTRY_V_VR( ocConfidence_N, 3, 3, 0, "CONFIDENCE.NORM" ),
453 : EXC_FUNCENTRY_V_VR( ocConfidence_T, 3, 3, 0, "CONFIDENCE.T" ),
454 : EXC_FUNCENTRY_V_VR( ocFDist_LT, 4, 4, 0, "F.DIST" ),
455 : EXC_FUNCENTRY_V_VR( ocFDist_RT, 3, 3, 0, "F.DIST.RT" ),
456 : EXC_FUNCENTRY_V_VR( ocFInv_LT, 3, 3, 0, "F.INV" ),
457 : EXC_FUNCENTRY_V_VR( ocFInv_RT, 3, 3, 0, "F.INV.RT" ),
458 : EXC_FUNCENTRY_V_VR( ocFTest_MS, 2, 2, 0, "F.TEST" ),
459 : EXC_FUNCENTRY_V_VR( ocExpDist_MS, 3, 3, 0, "EXPON.DIST" ),
460 : EXC_FUNCENTRY_V_VR( ocHypGeomDist_MS, 5, 5, 0, "HYPGEOM.DIST" ),
461 : EXC_FUNCENTRY_V_VR( ocPoissonDist_MS, 3, 3, 0, "POISSON.DIST" ),
462 : EXC_FUNCENTRY_V_VR( ocWeibull_MS, 4, 4, 0, "WEIBULL.DIST" ),
463 : EXC_FUNCENTRY_V_VR( ocGammaDist_MS, 4, 4, 0, "GAMMA.DIST" ),
464 : EXC_FUNCENTRY_V_VR( ocGammaInv_MS, 3, 3, 0, "GAMMA.INV" ),
465 : EXC_FUNCENTRY_V_VR( ocGammaLn_MS, 1, 1, 0, "GAMMALN.PRECISE" ),
466 : EXC_FUNCENTRY_V_VR( ocLogNormDist_MS, 4, 4, 0, "LOGNORM.DIST" ),
467 : EXC_FUNCENTRY_V_VR( ocLogInv_MS, 3, 3, 0, "LOGNORM.INV" ),
468 : EXC_FUNCENTRY_V_VR( ocNormDist_MS, 4, 4, 0, "NORM.DIST" ),
469 : EXC_FUNCENTRY_V_VR( ocNormInv_MS, 3, 3, 0, "NORM.INV" ),
470 : EXC_FUNCENTRY_V_VR( ocStdNormDist_MS, 2, 2, 0, "NORM.S.DIST" ),
471 : EXC_FUNCENTRY_V_VR( ocSNormInv_MS, 1, 1, 0, "NORM.S.INV" ),
472 : EXC_FUNCENTRY_V_VR( ocTDist_2T, 2, 2, 0, "T.DIST.2T" ),
473 : EXC_FUNCENTRY_V_VR( ocTDist_MS, 3, 3, 0, "T.DIST" ),
474 : EXC_FUNCENTRY_V_VR( ocTDist_RT, 2, 2, 0, "T.DIST.RT" ),
475 : EXC_FUNCENTRY_V_VR( ocTInv_2T, 2, 2, 0, "T.INV.2T" ),
476 : EXC_FUNCENTRY_V_VR( ocTInv_MS, 2, 2, 0, "T.INV" ),
477 : EXC_FUNCENTRY_V_VR( ocTTest_MS, 4, 4, 0, "T.TEST" ),
478 : EXC_FUNCENTRY_V_VR( ocPercentile_Inc, 2, 2, 0, "PERCENTILE.INC" ),
479 : EXC_FUNCENTRY_V_VR( ocPercentrank_Inc, 2, 3, 0, "PERCENTRANK.INC" ),
480 : EXC_FUNCENTRY_V_VR( ocQuartile_Inc, 2, 2, 0, "QUARTILE.INC" ),
481 : EXC_FUNCENTRY_V_VR( ocRank_Eq, 2, 3, 0, "RANK.EQ" ),
482 : EXC_FUNCENTRY_V_VR( ocPercentile_Exc, 2, 2, 0, "PERCENTILE.EXC" ),
483 : EXC_FUNCENTRY_V_VR( ocPercentrank_Exc, 2, 3, 0, "PERCENTRANK.EXC" ),
484 : EXC_FUNCENTRY_V_VR( ocQuartile_Exc, 2, 2, 0, "QUARTILE.EXC" ),
485 : EXC_FUNCENTRY_V_VR( ocRank_Avg, 2, 3, 0, "RANK.AVG" ),
486 : EXC_FUNCENTRY_V_RX( ocModalValue_MS, 1, MX, 0, "MODE.SNGL" ),
487 : EXC_FUNCENTRY_V_RX( ocModalValue_Multi, 1, MX, 0, "MODE.MULT" ),
488 : EXC_FUNCENTRY_V_VR( ocNegBinomDist_MS, 4, 4, 0, "NEGBINOM.DIST" ),
489 : EXC_FUNCENTRY_V_VR( ocZTest_MS, 2, 3, 0, "Z.TEST" ),
490 : EXC_FUNCENTRY_V_VR( ocCeil_MS, 2, 2, 0, "CEILING.PRECISE" ),
491 : EXC_FUNCENTRY_V_VR( ocFloor_MS, 2, 2, 0, "FLOOR.PRECISE" ),
492 : EXC_FUNCENTRY_V_VR( ocErf_MS, 1, 1, 0, "ERF.PRECISE" ),
493 : EXC_FUNCENTRY_V_VR( ocErfc_MS, 1, 1, 0, "ERFC.PRECISE" ),
494 : EXC_FUNCENTRY_V_RX( ocAggregate, 3, MX, 0, "AGGREGATE" ),
495 : };
496 :
497 : /** Functions new in Excel 2013.
498 :
499 : See http://office.microsoft.com/en-us/excel-help/new-functions-in-excel-2013-HA103980604.aspx
500 : Most functions apparently were added for ODF1.2 ODFF / OpenFormula
501 : compatibility.
502 :
503 : Functions with EXC_FUNCENTRY_V_VR_IMPORT are rewritten in
504 : sc/source/filter/excel/xeformula.cxx during export for BIFF, OOXML export
505 : uses a different mapping but still uses this mapping here to determine the
506 : feature set.
507 :
508 : FIXME: either have the exporter determine the feature set from the active
509 : mapping, preferred, or enhance this mapping here such that for OOXML the
510 : rewrite can be overridden.
511 :
512 : @See sc/source/filter/oox/formulabase.cxx saFuncTable2013 for V,VR,RO,...
513 : */
514 : static const XclFunctionInfo saFuncTable_2013[] =
515 : {
516 : EXC_FUNCENTRY_V_VR_IMPORT( ocArcCot, 1, 1, 0, "ACOT" ),
517 : EXC_FUNCENTRY_V_VR_IMPORT( ocArcCotHyp, 1, 1, 0, "ACOTH" ),
518 : EXC_FUNCENTRY_V_VR( ocArabic, 1, 1, 0, "ARABIC" ),
519 : EXC_FUNCENTRY_V_VR( ocBase, 2, 3, 0, "BASE" ),
520 : EXC_FUNCENTRY_V_VR( ocB, 3, 4, 0, "BINOM.DIST.RANGE" ),
521 : EXC_FUNCENTRY_V_VR( ocBitAnd, 2, 2, 0, "BITAND" ),
522 : EXC_FUNCENTRY_V_VR( ocBitLshift, 2, 2, 0, "BITLSHIFT" ),
523 : EXC_FUNCENTRY_V_VR( ocBitOr, 2, 2, 0, "BITOR" ),
524 : EXC_FUNCENTRY_V_VR( ocBitRshift, 2, 2, 0, "BITRSHIFT" ),
525 : EXC_FUNCENTRY_V_VR( ocBitXor, 2, 2, 0, "BITXOR" ),
526 : /* FIXME: CEILING.MATH is our/ODFF CEILING, but we have special handling
527 : * for the weird Excel CEILING behavior, check that and unify or diversify.
528 : * */
529 : EXC_FUNCENTRY_V_VR( ocNoName, 1, 3, 0, "CEILING.MATH" ),
530 : EXC_FUNCENTRY_V_VR( ocKombin2, 2, 2, 0, "COMBINA" ),
531 : EXC_FUNCENTRY_V_VR_IMPORT( ocCot, 1, 1, 0, "COT" ),
532 : EXC_FUNCENTRY_V_VR_IMPORT( ocCotHyp, 1, 1, 0, "COTH" ),
533 : EXC_FUNCENTRY_V_VR_IMPORT( ocCosecant, 1, 1, 0, "CSC" ),
534 : EXC_FUNCENTRY_V_VR_IMPORT( ocCosecantHyp, 1, 1, 0, "CSCH" ),
535 : EXC_FUNCENTRY_V_VR( ocGetDiffDate, 2, 2, 0, "DAYS" ),
536 : EXC_FUNCENTRY_V_VR( ocDecimal, 2, 2, 0, "DECIMAL" ),
537 : EXC_FUNCENTRY_V_VR( ocNoName, 1, 1, 0, "ENCODEURL" ),
538 : // NOTE: this FDIST is not our LEGACY.FDIST
539 : EXC_FUNCENTRY_V_VR( ocNoName, 3, 4, 0, "FDIST" ),
540 : // NOTE: this FINV is not our LEGACY.FINV
541 : EXC_FUNCENTRY_V_VR( ocNoName, 3, 3, 0, "FINV" ),
542 : EXC_FUNCENTRY_V_VR( ocFilterXML, 2, 2, 0, "FILTERXML" ),
543 : /* FIXME: FLOOR.MATH is our/ODFF FLOOR, but we have special handling for
544 : * the weird Excel FLOOR behavior, check that and unify or diversify. */
545 : EXC_FUNCENTRY_V_VR( ocNoName, 1, 3, 0, "FLOOR.MATH" ),
546 : EXC_FUNCENTRY_V_RO( ocFormula, 1, 1, 0, "FORMULATEXT" ),
547 : EXC_FUNCENTRY_V_VR( ocGamma, 1, 1, 0, "GAMMA" ),
548 : EXC_FUNCENTRY_V_VR( ocGauss, 1, 1, 0, "GAUSS" ),
549 : { ocIfNA, NOID, 2, 2, V, { VO, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "IFNA" ) },
550 : { ocIfNA, 255, 3, 3, V, { RO_E, VO, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "IFNA" ) },
551 : // IMCOSH, IMCOT, IMCSC, IMCSCH, IMSEC, IMSECH, IMSINH and IMTAN are
552 : // implemented in the Analysis Add-In.
553 : EXC_FUNCENTRY_V_RO( ocIsFormula, 1, 1, 0, "ISFORMULA" ),
554 : EXC_FUNCENTRY_V_VR( ocWeek, 1, 2, 0, "ISOWEEKNUM" ),
555 : EXC_FUNCENTRY_A_VR( ocMatrixUnit, 1, 1, 0, "MUNIT" ),
556 : EXC_FUNCENTRY_V_VR( ocNumberValue, 1, 3, 0, "NUMBERVALUE" ),
557 : EXC_FUNCENTRY_V_VR( ocLaufz, 3, 3, 0, "PDURATION" ),
558 : EXC_FUNCENTRY_V_VR( ocVariationen2, 2, 2, 0, "PERMUTATIONA" ),
559 : EXC_FUNCENTRY_V_VR( ocPhi, 1, 1, 0, "PHI" ),
560 : EXC_FUNCENTRY_V_VR( ocZGZ, 3, 3, 0, "RRI" ),
561 : EXC_FUNCENTRY_V_VR_IMPORT( ocSecant, 1, 1, 0, "SEC" ),
562 : EXC_FUNCENTRY_V_VR_IMPORT( ocSecantHyp, 1, 1, 0, "SECH" ),
563 : EXC_FUNCENTRY_V_RO( ocTable, 0, 1, 0, "SHEET" ),
564 : EXC_FUNCENTRY_V_RO( ocTables, 0, 1, 0, "SHEETS" ),
565 : EXC_FUNCENTRY_V_RX( ocSkewp, 1, MX, 0, "SKEW.P" ),
566 : EXC_FUNCENTRY_V_VR( ocUnichar, 1, 1, 0, "UNICHAR" ),
567 : EXC_FUNCENTRY_V_VR( ocUnicode, 1, 1, 0, "UNICODE" ),
568 : EXC_FUNCENTRY_V_VR( ocWebservice, 1, 1, 0, "WEBSERVICE" ),
569 : EXC_FUNCENTRY_V_RX( ocXor, 1, MX, 0, "XOR" )
570 : };
571 :
572 : #define EXC_FUNCENTRY_ODF( opcode, minparam, maxparam, flags, asciiname ) \
573 : { opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }, \
574 : { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }
575 :
576 : /** Functions defined by OpenFormula, but not supported by Calc (ocNoName) or by Excel (defined op-code). */
577 : static const XclFunctionInfo saFuncTable_Odf[] =
578 : {
579 : EXC_FUNCENTRY_ODF( ocChiSqDist, 2, 3, 0, "CHISQDIST" ),
580 : EXC_FUNCENTRY_ODF( ocChiSqInv, 2, 2, 0, "CHISQINV" )
581 : };
582 :
583 : #undef EXC_FUNCENTRY_ODF
584 :
585 : #define EXC_FUNCENTRY_OOO( opcode, minparam, maxparam, flags, asciiname ) \
586 : { opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }, \
587 : { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME( asciiname ) }
588 :
589 : /** Functions defined by Calc, but not in OpenFormula nor supported by Excel. */
590 : static const XclFunctionInfo saFuncTable_OOoLO[] =
591 : {
592 : EXC_FUNCENTRY_OOO( ocConvert, 3, 3, 0, "ORG.OPENOFFICE.CONVERT" ),
593 : EXC_FUNCENTRY_OOO( ocColor, 3, 4, 0, "ORG.LIBREOFFICE.COLOR" )
594 : };
595 :
596 : #undef EXC_FUNCENTRY_OOO
597 :
598 498 : XclFunctionProvider::XclFunctionProvider( const XclRoot& rRoot )
599 : {
600 : void (XclFunctionProvider::*pFillFunc)( const XclFunctionInfo*, const XclFunctionInfo* ) =
601 498 : rRoot.IsImport() ? &XclFunctionProvider::FillXclFuncMap : &XclFunctionProvider::FillScFuncMap;
602 :
603 : /* Only read/write functions supported in the current BIFF version.
604 : Function tables from later BIFF versions may overwrite single functions
605 : from earlier tables. */
606 498 : XclBiff eBiff = rRoot.GetBiff();
607 498 : if( eBiff >= EXC_BIFF2 )
608 498 : (this->*pFillFunc)( saFuncTable_2, STATIC_ARRAY_END( saFuncTable_2 ) );
609 498 : if( eBiff >= EXC_BIFF3 )
610 498 : (this->*pFillFunc)( saFuncTable_3, STATIC_ARRAY_END( saFuncTable_3 ) );
611 498 : if( eBiff >= EXC_BIFF4 )
612 498 : (this->*pFillFunc)( saFuncTable_4, STATIC_ARRAY_END( saFuncTable_4 ) );
613 498 : if( eBiff >= EXC_BIFF5 )
614 498 : (this->*pFillFunc)( saFuncTable_5, STATIC_ARRAY_END( saFuncTable_5 ) );
615 498 : if( eBiff >= EXC_BIFF8 )
616 494 : (this->*pFillFunc)( saFuncTable_8, STATIC_ARRAY_END( saFuncTable_8 ) );
617 498 : (this->*pFillFunc)( saFuncTable_Oox, STATIC_ARRAY_END( saFuncTable_Oox ) );
618 498 : (this->*pFillFunc)( saFuncTable_2010, STATIC_ARRAY_END( saFuncTable_2010 ) );
619 498 : (this->*pFillFunc)( saFuncTable_2013, STATIC_ARRAY_END( saFuncTable_2013 ) );
620 498 : (this->*pFillFunc)( saFuncTable_Odf, STATIC_ARRAY_END( saFuncTable_Odf ) );
621 498 : (this->*pFillFunc)( saFuncTable_OOoLO, STATIC_ARRAY_END( saFuncTable_OOoLO ) );
622 498 : }
623 :
624 6016 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const
625 : {
626 : // only in import filter allowed
627 : OSL_ENSURE( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclFunc - wrong filter" );
628 6016 : XclFuncMap::const_iterator aIt = maXclFuncMap.find( nXclFunc );
629 6016 : return (aIt == maXclFuncMap.end()) ? 0 : aIt->second;
630 : }
631 :
632 354 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclMacroName( const OUString& rXclMacroName ) const
633 : {
634 : // only in import filter allowed, but do not test maXclMacroNameMap, it may be empty for old BIFF versions
635 : OSL_ENSURE( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclMacroName - wrong filter" );
636 354 : XclMacroNameMap::const_iterator aIt = maXclMacroNameMap.find( rXclMacroName );
637 354 : return (aIt == maXclMacroNameMap.end()) ? 0 : aIt->second;
638 : }
639 :
640 900 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromOpCode( OpCode eOpCode ) const
641 : {
642 : // only in export filter allowed
643 : OSL_ENSURE( !maScFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromOpCode - wrong filter" );
644 900 : ScFuncMap::const_iterator aIt = maScFuncMap.find( eOpCode );
645 900 : return (aIt == maScFuncMap.end()) ? 0 : aIt->second;
646 : }
647 :
648 4336 : void XclFunctionProvider::FillXclFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
649 : {
650 219548 : for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
651 : {
652 215212 : if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_EXPORTONLY ) )
653 : {
654 160536 : if( pIt->mnXclFunc != NOID )
655 111060 : maXclFuncMap[ pIt->mnXclFunc ] = pIt;
656 160536 : if( pIt->IsMacroFunc() )
657 49906 : maXclMacroNameMap[ pIt->GetMacroFuncName() ] = pIt;
658 : }
659 : }
660 4336 : }
661 :
662 640 : void XclFunctionProvider::FillScFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
663 : {
664 32384 : for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
665 31744 : if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_IMPORTONLY ) )
666 24064 : maScFuncMap[ pIt->meOpCode ] = pIt;
667 640 : }
668 :
669 : // Token array ================================================================
670 :
671 198 : XclTokenArray::XclTokenArray( bool bVolatile ) :
672 198 : mbVolatile( bVolatile )
673 : {
674 198 : }
675 :
676 1898 : XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile ) :
677 1898 : mbVolatile( bVolatile )
678 : {
679 1898 : maTokVec.swap( rTokVec );
680 1898 : maExtDataVec.swap( rExtDataVec );
681 1898 : }
682 :
683 4828 : sal_uInt16 XclTokenArray::GetSize() const
684 : {
685 : OSL_ENSURE( maTokVec.size() <= 0xFFFF, "XclTokenArray::GetSize - array too long" );
686 4828 : return limit_cast< sal_uInt16 >( maTokVec.size() );
687 : }
688 :
689 198 : void XclTokenArray::ReadSize( XclImpStream& rStrm )
690 : {
691 : sal_uInt16 nSize;
692 198 : rStrm >> nSize;
693 198 : maTokVec.resize( nSize );
694 198 : }
695 :
696 198 : void XclTokenArray::ReadArray( XclImpStream& rStrm )
697 : {
698 198 : if( !maTokVec.empty() )
699 198 : rStrm.Read( &maTokVec.front(), GetSize() );
700 198 : }
701 :
702 194 : void XclTokenArray::Read( XclImpStream& rStrm )
703 : {
704 194 : ReadSize( rStrm );
705 194 : ReadArray( rStrm );
706 194 : }
707 :
708 1252 : void XclTokenArray::WriteSize( XclExpStream& rStrm ) const
709 : {
710 1252 : rStrm << GetSize();
711 1252 : }
712 :
713 1372 : void XclTokenArray::WriteArray( XclExpStream& rStrm ) const
714 : {
715 1372 : if( !maTokVec.empty() )
716 1372 : rStrm.Write( &maTokVec.front(), GetSize() );
717 1372 : if( !maExtDataVec.empty() )
718 6 : rStrm.Write( &maExtDataVec.front(), maExtDataVec.size() );
719 1372 : }
720 :
721 1252 : void XclTokenArray::Write( XclExpStream& rStrm ) const
722 : {
723 1252 : WriteSize( rStrm );
724 1252 : WriteArray( rStrm );
725 1252 : }
726 :
727 0 : bool XclTokenArray::operator==( const XclTokenArray& rTokArr ) const
728 : {
729 0 : return (mbVolatile == rTokArr.mbVolatile) && (maTokVec == rTokArr.maTokVec) && (maExtDataVec == rTokArr.maExtDataVec);
730 : }
731 :
732 194 : XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr )
733 : {
734 194 : rTokArr.Read( rStrm );
735 194 : return rStrm;
736 : }
737 :
738 0 : XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArrayRef& rxTokArr )
739 : {
740 0 : if( !rxTokArr )
741 0 : rxTokArr.reset( new XclTokenArray );
742 0 : rxTokArr->Read( rStrm );
743 0 : return rStrm;
744 : }
745 :
746 1240 : XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArray& rTokArr )
747 : {
748 1240 : rTokArr.Write( rStrm );
749 1240 : return rStrm;
750 : }
751 :
752 44 : XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr )
753 : {
754 44 : if( rxTokArr )
755 12 : rxTokArr->Write( rStrm );
756 : else
757 32 : rStrm << sal_uInt16( 0 );
758 44 : return rStrm;
759 : }
760 :
761 1898 : XclTokenArrayIterator::XclTokenArrayIterator() :
762 : mppScTokenBeg( 0 ),
763 : mppScTokenEnd( 0 ),
764 : mppScToken( 0 ),
765 1898 : mbSkipSpaces( false )
766 : {
767 1898 : }
768 :
769 2206 : XclTokenArrayIterator::XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces )
770 : {
771 2206 : Init( rScTokArr, bSkipSpaces );
772 2206 : }
773 :
774 0 : XclTokenArrayIterator::XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces ) :
775 : mppScTokenBeg( rTokArrIt.mppScTokenBeg ),
776 : mppScTokenEnd( rTokArrIt.mppScTokenEnd ),
777 : mppScToken( rTokArrIt.mppScToken ),
778 0 : mbSkipSpaces( bSkipSpaces )
779 : {
780 0 : SkipSpaces();
781 0 : }
782 :
783 3212 : void XclTokenArrayIterator::Init( const ScTokenArray& rScTokArr, bool bSkipSpaces )
784 : {
785 3212 : sal_uInt16 nTokArrLen = rScTokArr.GetLen();
786 3212 : mppScTokenBeg = static_cast< const FormulaToken* const* >( nTokArrLen ? rScTokArr.GetArray() : 0 );
787 3212 : mppScTokenEnd = mppScTokenBeg ? (mppScTokenBeg + nTokArrLen) : 0;
788 3212 : mppScToken = (mppScTokenBeg != mppScTokenEnd) ? mppScTokenBeg : 0;
789 3212 : mbSkipSpaces = bSkipSpaces;
790 3212 : SkipSpaces();
791 3212 : }
792 :
793 10878 : XclTokenArrayIterator& XclTokenArrayIterator::operator++()
794 : {
795 10878 : NextRawToken();
796 10878 : SkipSpaces();
797 10878 : return *this;
798 : }
799 :
800 10878 : void XclTokenArrayIterator::NextRawToken()
801 : {
802 10878 : if( mppScToken )
803 9872 : if( (++mppScToken == mppScTokenEnd) || !*mppScToken )
804 1132 : mppScToken = 0;
805 10878 : }
806 :
807 14090 : void XclTokenArrayIterator::SkipSpaces()
808 : {
809 14090 : if( mbSkipSpaces )
810 8824 : while( Is() && ((*this)->GetOpCode() == ocSpaces) )
811 0 : NextRawToken();
812 14090 : }
813 :
814 : // strings and string lists ---------------------------------------------------
815 :
816 0 : bool XclTokenArrayHelper::GetTokenString( OUString& rString, const FormulaToken& rScToken )
817 : {
818 0 : bool bIsStr = (rScToken.GetType() == svString) && (rScToken.GetOpCode() == ocPush);
819 0 : if( bIsStr ) rString = rScToken.GetString().getString();
820 0 : return bIsStr;
821 : }
822 :
823 0 : bool XclTokenArrayHelper::GetString( OUString& rString, const ScTokenArray& rScTokArr )
824 : {
825 0 : XclTokenArrayIterator aIt( rScTokArr, true );
826 : // something is following the string token -> error
827 0 : return aIt.Is() && GetTokenString( rString, *aIt ) && !++aIt;
828 : }
829 :
830 0 : bool XclTokenArrayHelper::GetStringList( OUString& rStringList, const ScTokenArray& rScTokArr, sal_Unicode cSep )
831 : {
832 0 : bool bRet = true;
833 0 : OUString aString;
834 0 : XclTokenArrayIterator aIt( rScTokArr, true );
835 0 : enum { STATE_START, STATE_STR, STATE_SEP, STATE_END } eState = STATE_START;
836 0 : while( eState != STATE_END ) switch( eState )
837 : {
838 : case STATE_START:
839 0 : eState = aIt.Is() ? STATE_STR : STATE_END;
840 0 : break;
841 : case STATE_STR:
842 0 : bRet = GetTokenString( aString, *aIt );
843 0 : if( bRet ) rStringList += aString ;
844 0 : eState = (bRet && (++aIt).Is()) ? STATE_SEP : STATE_END;
845 0 : break;
846 : case STATE_SEP:
847 0 : bRet = aIt->GetOpCode() == ocSep;
848 0 : if( bRet ) rStringList += OUString(cSep);
849 0 : eState = (bRet && (++aIt).Is()) ? STATE_STR : STATE_END;
850 0 : break;
851 : default:;
852 : }
853 0 : return bRet;
854 : }
855 :
856 0 : void XclTokenArrayHelper::ConvertStringToList(
857 : ScTokenArray& rScTokArr, svl::SharedStringPool& rSPool, sal_Unicode cStringSep, bool bTrimLeadingSpaces )
858 : {
859 0 : OUString aString;
860 0 : if( GetString( aString, rScTokArr ) )
861 : {
862 0 : rScTokArr.Clear();
863 0 : sal_Int32 nTokenCnt = comphelper::string::getTokenCount(aString, cStringSep);
864 0 : sal_Int32 nStringIx = 0;
865 0 : for( sal_Int32 nToken = 0; nToken < nTokenCnt; ++nToken )
866 : {
867 0 : OUString aToken( aString.getToken( 0, cStringSep, nStringIx ) );
868 0 : if( bTrimLeadingSpaces )
869 0 : aToken = comphelper::string::stripStart(aToken, ' ');
870 0 : if( nToken > 0 )
871 0 : rScTokArr.AddOpCode( ocSep );
872 0 : rScTokArr.AddString(rSPool.intern(aToken));
873 0 : }
874 0 : }
875 0 : }
876 :
877 : // multiple operations --------------------------------------------------------
878 :
879 : namespace {
880 :
881 0 : inline bool lclGetAddress( ScAddress& rAddress, const FormulaToken& rToken, const ScAddress& rPos )
882 : {
883 0 : OpCode eOpCode = rToken.GetOpCode();
884 0 : bool bIsSingleRef = (eOpCode == ocPush) && (rToken.GetType() == svSingleRef);
885 0 : if( bIsSingleRef )
886 : {
887 0 : const ScSingleRefData& rRef = *rToken.GetSingleRef();
888 0 : rAddress = rRef.toAbs(rPos);
889 0 : bIsSingleRef = !rRef.IsDeleted();
890 : }
891 0 : return bIsSingleRef;
892 : }
893 :
894 : } // namespace
895 :
896 2206 : bool XclTokenArrayHelper::GetMultipleOpRefs(
897 : XclMultipleOpRefs& rRefs, const ScTokenArray& rScTokArr, const ScAddress& rScPos )
898 : {
899 2206 : rRefs.mbDblRefMode = false;
900 : enum
901 : {
902 : stBegin, stTableOp, stOpen, stFormula, stFormulaSep,
903 : stColFirst, stColFirstSep, stColRel, stColRelSep,
904 : stRowFirst, stRowFirstSep, stRowRel, stClose, stError
905 2206 : } eState = stBegin; // last read token
906 4412 : for( XclTokenArrayIterator aIt( rScTokArr, true ); aIt.Is() && (eState != stError); ++aIt )
907 : {
908 2206 : OpCode eOpCode = aIt->GetOpCode();
909 2206 : bool bIsSep = eOpCode == ocSep;
910 2206 : switch( eState )
911 : {
912 : case stBegin:
913 2206 : eState = (eOpCode == ocTableOp) ? stTableOp : stError;
914 2206 : break;
915 : case stTableOp:
916 0 : eState = (eOpCode == ocOpen) ? stOpen : stError;
917 0 : break;
918 : case stOpen:
919 0 : eState = lclGetAddress(rRefs.maFmlaScPos, *aIt, rScPos) ? stFormula : stError;
920 0 : break;
921 : case stFormula:
922 0 : eState = bIsSep ? stFormulaSep : stError;
923 0 : break;
924 : case stFormulaSep:
925 0 : eState = lclGetAddress(rRefs.maColFirstScPos, *aIt, rScPos) ? stColFirst : stError;
926 0 : break;
927 : case stColFirst:
928 0 : eState = bIsSep ? stColFirstSep : stError;
929 0 : break;
930 : case stColFirstSep:
931 0 : eState = lclGetAddress(rRefs.maColRelScPos, *aIt, rScPos) ? stColRel : stError;
932 0 : break;
933 : case stColRel:
934 0 : eState = bIsSep ? stColRelSep : ((eOpCode == ocClose) ? stClose : stError);
935 0 : break;
936 : case stColRelSep:
937 0 : eState = lclGetAddress(rRefs.maRowFirstScPos, *aIt, rScPos) ? stRowFirst : stError;
938 0 : rRefs.mbDblRefMode = true;
939 0 : break;
940 : case stRowFirst:
941 0 : eState = bIsSep ? stRowFirstSep : stError;
942 0 : break;
943 : case stRowFirstSep:
944 0 : eState = lclGetAddress(rRefs.maRowRelScPos, *aIt, rScPos) ? stRowRel : stError;
945 0 : break;
946 : case stRowRel:
947 0 : eState = (eOpCode == ocClose) ? stClose : stError;
948 0 : break;
949 : default:
950 0 : eState = stError;
951 : }
952 : }
953 2206 : return eState == stClose;
954 48 : }
955 :
956 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|