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 :
32 : using namespace ::formula;
33 :
34 : // Function data ==============================================================
35 :
36 2280 : String XclFunctionInfo::GetMacroFuncName() const
37 : {
38 2280 : if( IsMacroFunc() )
39 2280 : return String( mpcMacroName, RTL_TEXTENCODING_UTF8 );
40 0 : return EMPTY_STRING;
41 : }
42 :
43 : // abbreviations for function return token class
44 : const sal_uInt8 R = EXC_TOKCLASS_REF;
45 : const sal_uInt8 V = EXC_TOKCLASS_VAL;
46 : const sal_uInt8 A = EXC_TOKCLASS_ARR;
47 :
48 : // abbreviations for parameter infos
49 : #define RO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, false }
50 : #define RV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, false }
51 : #define RA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, false }
52 : #define RR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, false }
53 : #define RX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, false }
54 : #define VO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, true }
55 : #define VV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, true }
56 : #define VA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, true }
57 : #define VR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, true }
58 : #define VX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, true }
59 : #define RO_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_ORG, false }
60 : #define VR_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_RPT, true }
61 : #define C { EXC_PARAM_CALCONLY, EXC_PARAMCONV_ORG, false }
62 :
63 : const sal_uInt16 NOID = SAL_MAX_UINT16; /// No BIFF/OOBIN function identifier available.
64 : const sal_uInt8 MX = 30; /// Maximum parameter count.
65 :
66 : #define EXC_FUNCNAME( ascii ) "_xlfn." ascii
67 : #define EXC_FUNCNAME_ODF( ascii ) "_xlfnodf." ascii
68 :
69 : /** Functions new in BIFF2. */
70 : static const XclFunctionInfo saFuncTable_2[] =
71 : {
72 : { ocCount, 0, 0, MX, V, { RX }, 0, 0 },
73 : { ocIf, 1, 2, 3, R, { VO, RO }, 0, 0 },
74 : { ocIsNA, 2, 1, 1, V, { VR }, 0, 0 },
75 : { ocIsError, 3, 1, 1, V, { VR }, 0, 0 },
76 : { ocSum, 4, 0, MX, V, { RX }, 0, 0 },
77 : { ocAverage, 5, 1, MX, V, { RX }, 0, 0 },
78 : { ocMin, 6, 1, MX, V, { RX }, 0, 0 },
79 : { ocMax, 7, 1, MX, V, { RX }, 0, 0 },
80 : { ocRow, 8, 0, 1, V, { RO }, 0, 0 },
81 : { ocColumn, 9, 0, 1, V, { RO }, 0, 0 },
82 : { ocNotAvail, 10, 0, 0, V, {}, 0, 0 },
83 : { ocNPV, 11, 2, MX, V, { VR, RX }, 0, 0 },
84 : { ocStDev, 12, 1, MX, V, { RX }, 0, 0 },
85 : { ocCurrency, 13, 1, 2, V, { VR }, 0, 0 },
86 : { ocFixed, 14, 1, 2, V, { VR, VR, C }, 0, 0 },
87 : { ocSin, 15, 1, 1, V, { VR }, 0, 0 },
88 : { ocCosecant, 15, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
89 : { ocCos, 16, 1, 1, V, { VR }, 0, 0 },
90 : { ocSecant, 16, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
91 : { ocTan, 17, 1, 1, V, { VR }, 0, 0 },
92 : { ocCot, 17, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
93 : { ocArcTan, 18, 1, 1, V, { VR }, 0, 0 },
94 : { ocArcCot, 18, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
95 : { ocPi, 19, 0, 0, V, {}, 0, 0 },
96 : { ocSqrt, 20, 1, 1, V, { VR }, 0, 0 },
97 : { ocExp, 21, 1, 1, V, { VR }, 0, 0 },
98 : { ocLn, 22, 1, 1, V, { VR }, 0, 0 },
99 : { ocLog10, 23, 1, 1, V, { VR }, 0, 0 },
100 : { ocAbs, 24, 1, 1, V, { VR }, 0, 0 },
101 : { ocInt, 25, 1, 1, V, { VR }, 0, 0 },
102 : { ocPlusMinus, 26, 1, 1, V, { VR }, 0, 0 },
103 : { ocRound, 27, 2, 2, V, { VR }, 0, 0 },
104 : { ocLookup, 28, 2, 3, V, { VR, RA }, 0, 0 },
105 : { ocIndex, 29, 2, 4, R, { RA, VV }, 0, 0 },
106 : { ocRept, 30, 2, 2, V, { VR }, 0, 0 },
107 : { ocMid, 31, 3, 3, V, { VR }, 0, 0 },
108 : { ocLen, 32, 1, 1, V, { VR }, 0, 0 },
109 : { ocValue, 33, 1, 1, V, { VR }, 0, 0 },
110 : { ocTrue, 34, 0, 0, V, {}, 0, 0 },
111 : { ocFalse, 35, 0, 0, V, {}, 0, 0 },
112 : { ocAnd, 36, 1, MX, V, { RX }, 0, 0 },
113 : { ocOr, 37, 1, MX, V, { RX }, 0, 0 },
114 : { ocNot, 38, 1, 1, V, { VR }, 0, 0 },
115 : { ocMod, 39, 2, 2, V, { VR }, 0, 0 },
116 : { ocDBCount, 40, 3, 3, V, { RO, RR }, 0, 0 },
117 : { ocDBSum, 41, 3, 3, V, { RO, RR }, 0, 0 },
118 : { ocDBAverage, 42, 3, 3, V, { RO, RR }, 0, 0 },
119 : { ocDBMin, 43, 3, 3, V, { RO, RR }, 0, 0 },
120 : { ocDBMax, 44, 3, 3, V, { RO, RR }, 0, 0 },
121 : { ocDBStdDev, 45, 3, 3, V, { RO, RR }, 0, 0 },
122 : { ocVar, 46, 1, MX, V, { RX }, 0, 0 },
123 : { ocDBVar, 47, 3, 3, V, { RO, RR }, 0, 0 },
124 : { ocText, 48, 2, 2, V, { VR }, 0, 0 },
125 : { ocRGP, 49, 1, 2, A, { RA, RA, C, C }, 0, 0 },
126 : { ocTrend, 50, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
127 : { ocRKP, 51, 1, 2, A, { RA, RA, C, C }, 0, 0 },
128 : { ocGrowth, 52, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
129 : { ocBW, 56, 3, 5, V, { VR }, 0, 0 },
130 : { ocZW, 57, 3, 5, V, { VR }, 0, 0 },
131 : { ocZZR, 58, 3, 5, V, { VR }, 0, 0 },
132 : { ocRMZ, 59, 3, 5, V, { VR }, 0, 0 },
133 : { ocZins, 60, 3, 6, V, { VR }, 0, 0 },
134 : { ocMIRR, 61, 3, 3, V, { RA, VR }, 0, 0 },
135 : { ocIRR, 62, 1, 2, V, { RA, VR }, 0, 0 },
136 : { ocRandom, 63, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
137 : { ocMatch, 64, 2, 3, V, { VR, RX, RR }, 0, 0 },
138 : { ocGetDate, 65, 3, 3, V, { VR }, 0, 0 },
139 : { ocGetTime, 66, 3, 3, V, { VR }, 0, 0 },
140 : { ocGetDay, 67, 1, 1, V, { VR }, 0, 0 },
141 : { ocGetMonth, 68, 1, 1, V, { VR }, 0, 0 },
142 : { ocGetYear, 69, 1, 1, V, { VR }, 0, 0 },
143 : { ocGetDayOfWeek, 70, 1, 1, V, { VR, C }, 0, 0 },
144 : { ocGetHour, 71, 1, 1, V, { VR }, 0, 0 },
145 : { ocGetMin, 72, 1, 1, V, { VR }, 0, 0 },
146 : { ocGetSec, 73, 1, 1, V, { VR }, 0, 0 },
147 : { ocGetActTime, 74, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
148 : { ocAreas, 75, 1, 1, V, { RO }, 0, 0 },
149 : { ocRows, 76, 1, 1, V, { RO }, 0, 0 },
150 : { ocColumns, 77, 1, 1, V, { RO }, 0, 0 },
151 : { ocOffset, 78, 3, 5, R, { RO, VR }, EXC_FUNCFLAG_VOLATILE, 0 },
152 : { ocSearch, 82, 2, 3, V, { VR }, 0, 0 },
153 : { ocMatTrans, 83, 1, 1, A, { VO }, 0, 0 },
154 : { ocType, 86, 1, 1, V, { VX }, 0, 0 },
155 : { ocArcTan2, 97, 2, 2, V, { VR }, 0, 0 },
156 : { ocArcSin, 98, 1, 1, V, { VR }, 0, 0 },
157 : { ocArcCos, 99, 1, 1, V, { VR }, 0, 0 },
158 : { ocChose, 100, 2, MX, R, { VO, RO }, 0, 0 },
159 : { ocHLookup, 101, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
160 : { ocVLookup, 102, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
161 : { ocIsRef, 105, 1, 1, V, { RX }, 0, 0 },
162 : { ocLog, 109, 1, 2, V, { VR }, 0, 0 },
163 : { ocChar, 111, 1, 1, V, { VR }, 0, 0 },
164 : { ocLower, 112, 1, 1, V, { VR }, 0, 0 },
165 : { ocUpper, 113, 1, 1, V, { VR }, 0, 0 },
166 : { ocPropper, 114, 1, 1, V, { VR }, 0, 0 },
167 : { ocLeft, 115, 1, 2, V, { VR }, 0, 0 },
168 : { ocRight, 116, 1, 2, V, { VR }, 0, 0 },
169 : { ocExact, 117, 2, 2, V, { VR }, 0, 0 },
170 : { ocTrim, 118, 1, 1, V, { VR }, 0, 0 },
171 : { ocReplace, 119, 4, 4, V, { VR }, 0, 0 },
172 : { ocSubstitute, 120, 3, 4, V, { VR }, 0, 0 },
173 : { ocCode, 121, 1, 1, V, { VR }, 0, 0 },
174 : { ocFind, 124, 2, 3, V, { VR }, 0, 0 },
175 : { ocCell, 125, 1, 2, V, { VV, RO }, EXC_FUNCFLAG_VOLATILE, 0 },
176 : { ocIsErr, 126, 1, 1, V, { VR }, 0, 0 },
177 : { ocIsString, 127, 1, 1, V, { VR }, 0, 0 },
178 : { ocIsValue, 128, 1, 1, V, { VR }, 0, 0 },
179 : { ocIsEmpty, 129, 1, 1, V, { VR }, 0, 0 },
180 : { ocT, 130, 1, 1, V, { RO }, 0, 0 },
181 : { ocN, 131, 1, 1, V, { RO }, 0, 0 },
182 : { ocGetDateValue, 140, 1, 1, V, { VR }, 0, 0 },
183 : { ocGetTimeValue, 141, 1, 1, V, { VR }, 0, 0 },
184 : { ocLIA, 142, 3, 3, V, { VR }, 0, 0 },
185 : { ocDIA, 143, 4, 4, V, { VR }, 0, 0 },
186 : { ocGDA, 144, 4, 5, V, { VR }, 0, 0 },
187 : { ocIndirect, 148, 1, 2, R, { VR }, EXC_FUNCFLAG_VOLATILE, 0 },
188 : { ocClean, 162, 1, 1, V, { VR }, 0, 0 },
189 : { ocMatDet, 163, 1, 1, V, { VA }, 0, 0 },
190 : { ocMatInv, 164, 1, 1, A, { VA }, 0, 0 },
191 : { ocMatMult, 165, 2, 2, A, { VA }, 0, 0 },
192 : { ocZinsZ, 167, 4, 6, V, { VR }, 0, 0 },
193 : { ocKapz, 168, 4, 6, V, { VR }, 0, 0 },
194 : { ocCount2, 169, 0, MX, V, { RX }, 0, 0 },
195 : { ocProduct, 183, 0, MX, V, { RX }, 0, 0 },
196 : { ocFact, 184, 1, 1, V, { VR }, 0, 0 },
197 : { ocDBProduct, 189, 3, 3, V, { RO, RR }, 0, 0 },
198 : { ocIsNonString, 190, 1, 1, V, { VR }, 0, 0 },
199 : { ocStDevP, 193, 1, MX, V, { RX }, 0, 0 },
200 : { ocVarP, 194, 1, MX, V, { RX }, 0, 0 },
201 : { ocDBStdDevP, 195, 3, 3, V, { RO, RR }, 0, 0 },
202 : { ocDBVarP, 196, 3, 3, V, { RO, RR }, 0, 0 },
203 : { ocTrunc, 197, 1, 1, V, { VR, C }, 0, 0 },
204 : { ocIsLogical, 198, 1, 1, V, { VR }, 0, 0 },
205 : { ocDBCount2, 199, 3, 3, V, { RO, RR }, 0, 0 },
206 : { ocCurrency, 204, 1, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },
207 : { ocRoundUp, 212, 2, 2, V, { VR }, 0, 0 },
208 : { ocRoundDown, 213, 2, 2, V, { VR }, 0, 0 },
209 : { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }
210 : };
211 :
212 : /** Functions new in BIFF3. */
213 : static const XclFunctionInfo saFuncTable_3[] =
214 : {
215 : { ocRGP, 49, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
216 : { ocTrend, 50, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
217 : { ocRKP, 51, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
218 : { ocGrowth, 52, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
219 : { ocTrunc, 197, 1, 2, V, { VR }, 0, 0 }, // BIFF2: 1, BIFF3: 1-2
220 : { ocAddress, 219, 2, 5, V, { VR }, 0, 0 },
221 : { ocGetDiffDate360, 220, 2, 2, V, { VR, VR, C }, 0, 0 },
222 : { ocGetActDate, 221, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
223 : { ocVBD, 222, 5, 7, V, { VR }, 0, 0 },
224 : { ocMedian, 227, 1, MX, V, { RX }, 0, 0 },
225 : { ocSumProduct, 228, 1, MX, V, { VA }, 0, 0 },
226 : { ocSinHyp, 229, 1, 1, V, { VR }, 0, 0 },
227 : { ocCosecantHyp, 229, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
228 : { ocCosHyp, 230, 1, 1, V, { VR }, 0, 0 },
229 : { ocSecantHyp, 230, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
230 : { ocTanHyp, 231, 1, 1, V, { VR }, 0, 0 },
231 : { ocCotHyp, 231, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
232 : { ocArcSinHyp, 232, 1, 1, V, { VR }, 0, 0 },
233 : { ocArcCosHyp, 233, 1, 1, V, { VR }, 0, 0 },
234 : { ocArcTanHyp, 234, 1, 1, V, { VR }, 0, 0 },
235 : { ocArcCotHyp, 234, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
236 : { ocDBGet, 235, 3, 3, V, { RO, RR }, 0, 0 },
237 : { ocInfo, 244, 1, 1, V, { VR }, EXC_FUNCFLAG_VOLATILE, 0 }
238 : };
239 :
240 : /** Functions new in BIFF4. */
241 : static const XclFunctionInfo saFuncTable_4[] =
242 : {
243 : { ocFixed, 14, 1, 3, V, { VR }, 0, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3
244 : { ocAsc, 214, 1, 1, V, { VR }, 0, 0 },
245 : { ocJis, 215, 1, 1, V, { VR }, 0, 0 },
246 : { ocRank, 216, 2, 3, V, { VR, RO, VR }, 0, 0 },
247 : { ocGDA2, 247, 4, 5, V, { VR }, 0, 0 },
248 : { ocFrequency, 252, 2, 2, A, { RA }, 0, 0 },
249 : { ocErrorType, 261, 1, 1, V, { VR }, 0, 0 },
250 : { ocAveDev, 269, 1, MX, V, { RX }, 0, 0 },
251 : { ocBetaDist, 270, 3, 5, V, { VR }, 0, 0 },
252 : { ocGammaLn, 271, 1, 1, V, { VR }, 0, 0 },
253 : { ocBetaInv, 272, 3, 5, V, { VR }, 0, 0 },
254 : { ocBinomDist, 273, 4, 4, V, { VR }, 0, 0 },
255 : { ocChiDist, 274, 2, 2, V, { VR }, 0, 0 },
256 : { ocChiInv, 275, 2, 2, V, { VR }, 0, 0 },
257 : { ocKombin, 276, 2, 2, V, { VR }, 0, 0 },
258 : { ocConfidence, 277, 3, 3, V, { VR }, 0, 0 },
259 : { ocKritBinom, 278, 3, 3, V, { VR }, 0, 0 },
260 : { ocEven, 279, 1, 1, V, { VR }, 0, 0 },
261 : { ocExpDist, 280, 3, 3, V, { VR }, 0, 0 },
262 : { ocFDist, 281, 3, 3, V, { VR }, 0, 0 },
263 : { ocFInv, 282, 3, 3, V, { VR }, 0, 0 },
264 : { ocFisher, 283, 1, 1, V, { VR }, 0, 0 },
265 : { ocFisherInv, 284, 1, 1, V, { VR }, 0, 0 },
266 : { ocFloor, 285, 2, 2, V, { VR, VR, C }, 0, 0 },
267 : { ocGammaDist, 286, 4, 4, V, { VR }, 0, 0 },
268 : { ocGammaInv, 287, 3, 3, V, { VR }, 0, 0 },
269 : { ocCeil, 288, 2, 2, V, { VR, VR, C }, 0, 0 },
270 : { ocHypGeomDist, 289, 4, 4, V, { VR }, 0, 0 },
271 : { ocLogNormDist, 290, 3, 3, V, { VR }, 0, 0 },
272 : { ocLogInv, 291, 3, 3, V, { VR }, 0, 0 },
273 : { ocNegBinomVert, 292, 3, 3, V, { VR }, 0, 0 },
274 : { ocNormDist, 293, 4, 4, V, { VR }, 0, 0 },
275 : { ocStdNormDist, 294, 1, 1, V, { VR }, 0, 0 },
276 : { ocNormInv, 295, 3, 3, V, { VR }, 0, 0 },
277 : { ocSNormInv, 296, 1, 1, V, { VR }, 0, 0 },
278 : { ocStandard, 297, 3, 3, V, { VR }, 0, 0 },
279 : { ocOdd, 298, 1, 1, V, { VR }, 0, 0 },
280 : { ocVariationen, 299, 2, 2, V, { VR }, 0, 0 },
281 : { ocPoissonDist, 300, 3, 3, V, { VR }, 0, 0 },
282 : { ocTDist, 301, 3, 3, V, { VR }, 0, 0 },
283 : { ocWeibull, 302, 4, 4, V, { VR }, 0, 0 },
284 : { ocSumXMY2, 303, 2, 2, V, { VA }, 0, 0 },
285 : { ocSumX2MY2, 304, 2, 2, V, { VA }, 0, 0 },
286 : { ocSumX2DY2, 305, 2, 2, V, { VA }, 0, 0 },
287 : { ocChiTest, 306, 2, 2, V, { VA }, 0, 0 },
288 : { ocCorrel, 307, 2, 2, V, { VA }, 0, 0 },
289 : { ocCovar, 308, 2, 2, V, { VA }, 0, 0 },
290 : { ocForecast, 309, 3, 3, V, { VR, VA }, 0, 0 },
291 : { ocFTest, 310, 2, 2, V, { VA }, 0, 0 },
292 : { ocIntercept, 311, 2, 2, V, { VA }, 0, 0 },
293 : { ocPearson, 312, 2, 2, V, { VA }, 0, 0 },
294 : { ocRSQ, 313, 2, 2, V, { VA }, 0, 0 },
295 : { ocSTEYX, 314, 2, 2, V, { VA }, 0, 0 },
296 : { ocSlope, 315, 2, 2, V, { VA }, 0, 0 },
297 : { ocTTest, 316, 4, 4, V, { VA, VA, VR }, 0, 0 },
298 : { ocProb, 317, 3, 4, V, { VA, VA, VR }, 0, 0 },
299 : { ocDevSq, 318, 1, MX, V, { RX }, 0, 0 },
300 : { ocGeoMean, 319, 1, MX, V, { RX }, 0, 0 },
301 : { ocHarMean, 320, 1, MX, V, { RX }, 0, 0 },
302 : { ocSumSQ, 321, 0, MX, V, { RX }, 0, 0 },
303 : { ocKurt, 322, 1, MX, V, { RX }, 0, 0 },
304 : { ocSchiefe, 323, 1, MX, V, { RX }, 0, 0 },
305 : { ocZTest, 324, 2, 3, V, { RX, VR }, 0, 0 },
306 : { ocLarge, 325, 2, 2, V, { RX, VR }, 0, 0 },
307 : { ocSmall, 326, 2, 2, V, { RX, VR }, 0, 0 },
308 : { ocQuartile, 327, 2, 2, V, { RX, VR }, 0, 0 },
309 : { ocPercentile, 328, 2, 2, V, { RX, VR }, 0, 0 },
310 : { ocPercentrank, 329, 2, 3, V, { RX, VR, VR_E }, 0, 0 },
311 : { ocModalValue, 330, 1, MX, V, { VA }, 0, 0 },
312 : { ocTrimMean, 331, 2, 2, V, { RX, VR }, 0, 0 },
313 : { ocTInv, 332, 2, 2, V, { VR }, 0, 0 }
314 : };
315 :
316 : /** Functions new in BIFF5/BIFF7. Unsupported functions: DATESTRING, NUMBERSTRING. */
317 : static const XclFunctionInfo saFuncTable_5[] =
318 : {
319 : { ocGetDayOfWeek, 70, 1, 2, V, { VR }, 0, 0 }, // BIFF2-4: 1, BIFF5: 1-2
320 : { ocHLookup, 101, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
321 : { ocVLookup, 102, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
322 : { ocGetDiffDate360, 220, 2, 3, V, { VR }, 0, 0 }, // BIFF3-4: 2, BIFF5: 2-3
323 : { ocMacro, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
324 : { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
325 : { ocConcat, 336, 0, MX, V, { VR }, 0, 0 },
326 : { ocPower, 337, 2, 2, V, { VR }, 0, 0 },
327 : { ocRad, 342, 1, 1, V, { VR }, 0, 0 },
328 : { ocDeg, 343, 1, 1, V, { VR }, 0, 0 },
329 : { ocSubTotal, 344, 2, MX, V, { VR, RO }, 0, 0 },
330 : { ocSumIf, 345, 2, 3, V, { RO, VR, RO }, 0, 0 },
331 : { ocCountIf, 346, 2, 2, V, { RO, VR }, 0, 0 },
332 : { ocCountEmptyCells, 347, 1, 1, V, { RO }, 0, 0 },
333 : { ocISPMT, 350, 4, 4, V, { VR }, 0, 0 },
334 : { ocGetDateDif, 351, 3, 3, V, { VR }, 0, 0 },
335 : { ocNoName, 352, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATESTRING
336 : { ocNoName, 353, 2, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // NUMBERSTRING
337 : { ocRoman, 354, 1, 2, V, { VR }, 0, 0 }
338 : };
339 :
340 : /** Functions new in BIFF8. Unsupported functions: PHONETIC. */
341 : static const XclFunctionInfo saFuncTable_8[] =
342 : {
343 : { ocGetPivotData, 358, 2, MX, V, { RR, RR, VR }, 0, 0 },
344 : { ocHyperLink, 359, 1, 2, V, { VV, VO }, 0, 0 },
345 : { ocNoName, 360, 1, 1, V, { RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // PHONETIC
346 : { ocAverageA, 361, 1, MX, V, { RX }, 0, 0 },
347 : { ocMaxA, 362, 1, MX, V, { RX }, 0, 0 },
348 : { ocMinA, 363, 1, MX, V, { RX }, 0, 0 },
349 : { ocStDevPA, 364, 1, MX, V, { RX }, 0, 0 },
350 : { ocVarPA, 365, 1, MX, V, { RX }, 0, 0 },
351 : { ocStDevA, 366, 1, MX, V, { RX }, 0, 0 },
352 : { ocVarA, 367, 1, MX, V, { RX }, 0, 0 },
353 : { ocBahtText, 368, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
354 : { ocBahtText, 255, 2, 2, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) },
355 : { ocEuroConvert, 255, 4, 6, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" }
356 : };
357 :
358 : /** Functions new in OOXML. */
359 : static const XclFunctionInfo saFuncTable_Oox[] =
360 : {
361 : { ocCountIfs, NOID, 2, MX, V, { RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "COUNTIFS" ) },
362 : { ocCountIfs, 255, 3, MX, V, { RO_E, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "COUNTIFS" ) },
363 : { ocSumIfs, NOID, 3, MX, V, { RO, RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "SUMIFS" ) },
364 : { ocSumIfs, 255, 4, MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "SUMIFS" ) },
365 : { ocAverageIf, NOID, 2, 3, V, { RO, VR, RO }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "AVERAGEIF" ) },
366 : { ocAverageIf, 255, 3, 4, V, { RO_E, RO, VR, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "AVERAGEIF" ) },
367 : { ocAverageIfs, NOID, 3, MX, V, { RO, RO, VR }, EXC_FUNCFLAG_IMPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) },
368 : { ocAverageIfs, 255, 4, MX, V, { RO_E, RO, RO, VR }, EXC_FUNCFLAG_EXPORTONLY|EXC_FUNCFLAG_PARAMPAIRS, EXC_FUNCNAME( "AVERAGEIFS" ) }
369 : };
370 :
371 : #define EXC_FUNCENTRY_ODF( opcode, minparam, maxparam, flags, asciiname ) \
372 : { opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }, \
373 : { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }
374 :
375 : /** Functions defined by OpenFormula, but not supported by Calc (ocNoName) or by Excel (defined op-code). */
376 : static const XclFunctionInfo saFuncTable_Odf[] =
377 : {
378 : EXC_FUNCENTRY_ODF( ocArabic, 1, 1, 0, "ARABIC" ),
379 : EXC_FUNCENTRY_ODF( ocB, 3, 4, 0, "B" ),
380 : EXC_FUNCENTRY_ODF( ocBase, 2, 3, 0, "BASE" ),
381 : EXC_FUNCENTRY_ODF( ocBitAnd, 2, 2, 0, "BITAND" ),
382 : EXC_FUNCENTRY_ODF( ocBitLshift, 2, 2, 0, "BITLSHIFT" ),
383 : EXC_FUNCENTRY_ODF( ocBitOr, 2, 2, 0, "BITOR" ),
384 : EXC_FUNCENTRY_ODF( ocBitRshift, 2, 2, 0, "BITRSHIFT" ),
385 : EXC_FUNCENTRY_ODF( ocBitXor, 2, 2, 0, "BITXOR" ),
386 : EXC_FUNCENTRY_ODF( ocChiSqDist, 2, 3, 0, "CHISQDIST" ),
387 : EXC_FUNCENTRY_ODF( ocChiSqInv, 2, 2, 0, "CHISQINV" ),
388 : EXC_FUNCENTRY_ODF( ocKombin2, 2, 2, 0, "COMBINA" ),
389 : EXC_FUNCENTRY_ODF( ocGetDiffDate, 2, 2, 0, "DAYS" ),
390 : EXC_FUNCENTRY_ODF( ocDecimal, 2, 2, 0, "DECIMAL" ),
391 : EXC_FUNCENTRY_ODF( ocFDist, 3, 4, 0, "FDIST" ),
392 : EXC_FUNCENTRY_ODF( ocFInv, 3, 3, 0, "FINV" ),
393 : EXC_FUNCENTRY_ODF( ocFormula, 1, 1, 0, "FORMULA" ),
394 : EXC_FUNCENTRY_ODF( ocGamma, 1, 1, 0, "GAMMA" ),
395 : EXC_FUNCENTRY_ODF( ocGauss, 1, 1, 0, "GAUSS" ),
396 : EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "IFNA" ),
397 : EXC_FUNCENTRY_ODF( ocIsFormula, 1, 1, 0, "ISFORMULA" ),
398 : EXC_FUNCENTRY_ODF( ocWeek, 1, 2, 0, "ISOWEEKNUM" ),
399 : EXC_FUNCENTRY_ODF( ocMatrixUnit, 1, 1, 0, "MUNIT" ),
400 : EXC_FUNCENTRY_ODF( ocNumberValue, 2, 2, 0, "NUMBERVALUE" ),
401 : EXC_FUNCENTRY_ODF( ocLaufz, 3, 3, 0, "PDURATION" ),
402 : EXC_FUNCENTRY_ODF( ocVariationen2, 2, 2, 0, "PERMUTATIONA" ),
403 : EXC_FUNCENTRY_ODF( ocPhi, 1, 1, 0, "PHI" ),
404 : EXC_FUNCENTRY_ODF( ocZGZ, 3, 3, 0, "RRI" ),
405 : EXC_FUNCENTRY_ODF( ocTable, 0, 1, 0, "SHEET" ),
406 : EXC_FUNCENTRY_ODF( ocTables, 0, 1, 0, "SHEETS" ),
407 : EXC_FUNCENTRY_ODF( ocNoName, 1, MX, 0, "SKEWP" ),
408 : EXC_FUNCENTRY_ODF( ocUnichar, 1, 1, 0, "UNICHAR" ),
409 : EXC_FUNCENTRY_ODF( ocUnicode, 1, 1, 0, "UNICODE" ),
410 : EXC_FUNCENTRY_ODF( ocXor, 1, MX, 0, "XOR" )
411 : };
412 :
413 : #undef EXC_FUNCENTRY_ODF
414 :
415 : // ----------------------------------------------------------------------------
416 :
417 61 : XclFunctionProvider::XclFunctionProvider( const XclRoot& rRoot )
418 : {
419 : void (XclFunctionProvider::*pFillFunc)( const XclFunctionInfo*, const XclFunctionInfo* ) =
420 61 : rRoot.IsImport() ? &XclFunctionProvider::FillXclFuncMap : &XclFunctionProvider::FillScFuncMap;
421 :
422 : /* Only read/write functions supported in the current BIFF version.
423 : Function tables from later BIFF versions may overwrite single functions
424 : from earlier tables. */
425 61 : XclBiff eBiff = rRoot.GetBiff();
426 61 : if( eBiff >= EXC_BIFF2 )
427 61 : (this->*pFillFunc)( saFuncTable_2, STATIC_ARRAY_END( saFuncTable_2 ) );
428 61 : if( eBiff >= EXC_BIFF3 )
429 61 : (this->*pFillFunc)( saFuncTable_3, STATIC_ARRAY_END( saFuncTable_3 ) );
430 61 : if( eBiff >= EXC_BIFF4 )
431 61 : (this->*pFillFunc)( saFuncTable_4, STATIC_ARRAY_END( saFuncTable_4 ) );
432 61 : if( eBiff >= EXC_BIFF5 )
433 61 : (this->*pFillFunc)( saFuncTable_5, STATIC_ARRAY_END( saFuncTable_5 ) );
434 61 : if( eBiff >= EXC_BIFF8 )
435 61 : (this->*pFillFunc)( saFuncTable_8, STATIC_ARRAY_END( saFuncTable_8 ) );
436 61 : (this->*pFillFunc)( saFuncTable_Oox, STATIC_ARRAY_END( saFuncTable_Oox ) );
437 61 : (this->*pFillFunc)( saFuncTable_Odf, STATIC_ARRAY_END( saFuncTable_Odf ) );
438 61 : }
439 :
440 2712 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const
441 : {
442 : // only in import filter allowed
443 : OSL_ENSURE( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclFunc - wrong filter" );
444 2712 : XclFuncMap::const_iterator aIt = maXclFuncMap.find( nXclFunc );
445 2712 : return (aIt == maXclFuncMap.end()) ? 0 : aIt->second;
446 : }
447 :
448 1 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclMacroName( const String& rXclMacroName ) const
449 : {
450 : // only in import filter allowed, but do not test maXclMacroNameMap, it may be empty for old BIFF versions
451 : OSL_ENSURE( !maXclFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromXclMacroName - wrong filter" );
452 1 : XclMacroNameMap::const_iterator aIt = maXclMacroNameMap.find( rXclMacroName );
453 1 : return (aIt == maXclMacroNameMap.end()) ? 0 : aIt->second;
454 : }
455 :
456 0 : const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromOpCode( OpCode eOpCode ) const
457 : {
458 : // only in export filter allowed
459 : OSL_ENSURE( !maScFuncMap.empty(), "XclFunctionProvider::GetFuncInfoFromOpCode - wrong filter" );
460 0 : ScFuncMap::const_iterator aIt = maScFuncMap.find( eOpCode );
461 0 : return (aIt == maScFuncMap.end()) ? 0 : aIt->second;
462 : }
463 :
464 420 : void XclFunctionProvider::FillXclFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
465 : {
466 20700 : for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
467 : {
468 20280 : if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_EXPORTONLY ) )
469 : {
470 17340 : if( pIt->mnXclFunc != NOID )
471 15120 : maXclFuncMap[ pIt->mnXclFunc ] = pIt;
472 17340 : if( pIt->IsMacroFunc() )
473 2280 : maXclMacroNameMap[ pIt->GetMacroFuncName() ] = pIt;
474 : }
475 : }
476 420 : }
477 :
478 7 : void XclFunctionProvider::FillScFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd )
479 : {
480 345 : for( const XclFunctionInfo* pIt = pBeg; pIt != pEnd; ++pIt )
481 338 : if( !::get_flag( pIt->mnFlags, EXC_FUNCFLAG_IMPORTONLY ) )
482 295 : maScFuncMap[ pIt->meOpCode ] = pIt;
483 7 : }
484 :
485 : // Token array ================================================================
486 :
487 83 : XclTokenArray::XclTokenArray( bool bVolatile ) :
488 83 : mbVolatile( bVolatile )
489 : {
490 83 : }
491 :
492 8 : XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile ) :
493 8 : mbVolatile( bVolatile )
494 : {
495 8 : maTokVec.swap( rTokVec );
496 8 : maExtDataVec.swap( rExtDataVec );
497 8 : }
498 :
499 249 : sal_uInt16 XclTokenArray::GetSize() const
500 : {
501 : OSL_ENSURE( maTokVec.size() <= 0xFFFF, "XclTokenArray::GetSize - array too long" );
502 249 : return limit_cast< sal_uInt16 >( maTokVec.size() );
503 : }
504 :
505 83 : void XclTokenArray::ReadSize( XclImpStream& rStrm )
506 : {
507 : sal_uInt16 nSize;
508 83 : rStrm >> nSize;
509 83 : maTokVec.resize( nSize );
510 83 : }
511 :
512 83 : void XclTokenArray::ReadArray( XclImpStream& rStrm )
513 : {
514 83 : if( !maTokVec.empty() )
515 83 : rStrm.Read( &maTokVec.front(), GetSize() );
516 83 : }
517 :
518 82 : void XclTokenArray::Read( XclImpStream& rStrm )
519 : {
520 82 : ReadSize( rStrm );
521 82 : ReadArray( rStrm );
522 82 : }
523 :
524 0 : void XclTokenArray::WriteSize( XclExpStream& rStrm ) const
525 : {
526 0 : rStrm << GetSize();
527 0 : }
528 :
529 0 : void XclTokenArray::WriteArray( XclExpStream& rStrm ) const
530 : {
531 0 : if( !maTokVec.empty() )
532 0 : rStrm.Write( &maTokVec.front(), GetSize() );
533 0 : if( !maExtDataVec.empty() )
534 0 : rStrm.Write( &maExtDataVec.front(), maExtDataVec.size() );
535 0 : }
536 :
537 0 : void XclTokenArray::Write( XclExpStream& rStrm ) const
538 : {
539 0 : WriteSize( rStrm );
540 0 : WriteArray( rStrm );
541 0 : }
542 :
543 0 : bool XclTokenArray::operator==( const XclTokenArray& rTokArr ) const
544 : {
545 0 : return (mbVolatile == rTokArr.mbVolatile) && (maTokVec == rTokArr.maTokVec) && (maExtDataVec == rTokArr.maExtDataVec);
546 : }
547 :
548 82 : XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr )
549 : {
550 82 : rTokArr.Read( rStrm );
551 82 : return rStrm;
552 : }
553 :
554 0 : XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArrayRef& rxTokArr )
555 : {
556 0 : if( !rxTokArr )
557 0 : rxTokArr.reset( new XclTokenArray );
558 0 : rxTokArr->Read( rStrm );
559 0 : return rStrm;
560 : }
561 :
562 0 : XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArray& rTokArr )
563 : {
564 0 : rTokArr.Write( rStrm );
565 0 : return rStrm;
566 : }
567 :
568 0 : XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr )
569 : {
570 0 : if( rxTokArr )
571 0 : rxTokArr->Write( rStrm );
572 : else
573 0 : rStrm << sal_uInt16( 0 );
574 0 : return rStrm;
575 : }
576 :
577 : // ----------------------------------------------------------------------------
578 :
579 8 : XclTokenArrayIterator::XclTokenArrayIterator() :
580 : mppScTokenBeg( 0 ),
581 : mppScTokenEnd( 0 ),
582 : mppScToken( 0 ),
583 8 : mbSkipSpaces( false )
584 : {
585 8 : }
586 :
587 0 : XclTokenArrayIterator::XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces )
588 : {
589 0 : Init( rScTokArr, bSkipSpaces );
590 0 : }
591 :
592 0 : XclTokenArrayIterator::XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces ) :
593 : mppScTokenBeg( rTokArrIt.mppScTokenBeg ),
594 : mppScTokenEnd( rTokArrIt.mppScTokenEnd ),
595 : mppScToken( rTokArrIt.mppScToken ),
596 0 : mbSkipSpaces( bSkipSpaces )
597 : {
598 0 : SkipSpaces();
599 0 : }
600 :
601 8 : void XclTokenArrayIterator::Init( const ScTokenArray& rScTokArr, bool bSkipSpaces )
602 : {
603 8 : sal_uInt16 nTokArrLen = rScTokArr.GetLen();
604 8 : mppScTokenBeg = static_cast< const FormulaToken* const* >( nTokArrLen ? rScTokArr.GetArray() : 0 );
605 8 : mppScTokenEnd = mppScTokenBeg ? (mppScTokenBeg + nTokArrLen) : 0;
606 8 : mppScToken = (mppScTokenBeg != mppScTokenEnd) ? mppScTokenBeg : 0;
607 8 : mbSkipSpaces = bSkipSpaces;
608 8 : SkipSpaces();
609 8 : }
610 :
611 16 : XclTokenArrayIterator& XclTokenArrayIterator::operator++()
612 : {
613 16 : NextRawToken();
614 16 : SkipSpaces();
615 16 : return *this;
616 : }
617 :
618 16 : void XclTokenArrayIterator::NextRawToken()
619 : {
620 16 : if( mppScToken )
621 8 : if( (++mppScToken == mppScTokenEnd) || !*mppScToken )
622 8 : mppScToken = 0;
623 16 : }
624 :
625 24 : void XclTokenArrayIterator::SkipSpaces()
626 : {
627 24 : if( mbSkipSpaces )
628 0 : while( Is() && ((*this)->GetOpCode() == ocSpaces) )
629 0 : NextRawToken();
630 24 : }
631 :
632 : // strings and string lists ---------------------------------------------------
633 :
634 0 : bool XclTokenArrayHelper::GetTokenString( String& rString, const FormulaToken& rScToken )
635 : {
636 0 : bool bIsStr = (rScToken.GetType() == svString) && (rScToken.GetOpCode() == ocPush);
637 0 : if( bIsStr ) rString = rScToken.GetString();
638 0 : return bIsStr;
639 : }
640 :
641 0 : bool XclTokenArrayHelper::GetString( String& rString, const ScTokenArray& rScTokArr )
642 : {
643 0 : XclTokenArrayIterator aIt( rScTokArr, true );
644 : // something is following the string token -> error
645 0 : return aIt.Is() && GetTokenString( rString, *aIt ) && !++aIt;
646 : }
647 :
648 0 : bool XclTokenArrayHelper::GetStringList( String& rStringList, const ScTokenArray& rScTokArr, sal_Unicode cSep )
649 : {
650 0 : bool bRet = true;
651 0 : String aString;
652 0 : XclTokenArrayIterator aIt( rScTokArr, true );
653 0 : enum { STATE_START, STATE_STR, STATE_SEP, STATE_END } eState = STATE_START;
654 0 : while( eState != STATE_END ) switch( eState )
655 : {
656 : case STATE_START:
657 0 : eState = aIt.Is() ? STATE_STR : STATE_END;
658 0 : break;
659 : case STATE_STR:
660 0 : bRet = GetTokenString( aString, *aIt );
661 0 : if( bRet ) rStringList.Append( aString );
662 0 : eState = (bRet && (++aIt).Is()) ? STATE_SEP : STATE_END;
663 0 : break;
664 : case STATE_SEP:
665 0 : bRet = aIt->GetOpCode() == ocSep;
666 0 : if( bRet ) rStringList.Append( cSep );
667 0 : eState = (bRet && (++aIt).Is()) ? STATE_STR : STATE_END;
668 0 : break;
669 : default:;
670 : }
671 0 : return bRet;
672 : }
673 :
674 0 : void XclTokenArrayHelper::ConvertStringToList( ScTokenArray& rScTokArr, sal_Unicode cStringSep, bool bTrimLeadingSpaces )
675 : {
676 0 : String aString;
677 0 : if( GetString( aString, rScTokArr ) )
678 : {
679 0 : rScTokArr.Clear();
680 0 : xub_StrLen nTokenCnt = comphelper::string::getTokenCount(aString, cStringSep);
681 0 : xub_StrLen nStringIx = 0;
682 0 : for( xub_StrLen nToken = 0; nToken < nTokenCnt; ++nToken )
683 : {
684 0 : String aToken( aString.GetToken( 0, cStringSep, nStringIx ) );
685 0 : if( bTrimLeadingSpaces )
686 0 : aToken = comphelper::string::stripStart(aToken, ' ');
687 0 : if( nToken > 0 )
688 0 : rScTokArr.AddOpCode( ocSep );
689 0 : rScTokArr.AddString( aToken );
690 0 : }
691 0 : }
692 0 : }
693 :
694 : // shared formulas ------------------------------------------------------------
695 :
696 0 : const ScTokenArray* XclTokenArrayHelper::GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr )
697 : {
698 0 : if( rScTokArr.GetLen() == 1 )
699 0 : if( const FormulaToken* pScToken = rScTokArr.GetArray()[ 0 ] )
700 0 : if( pScToken->GetOpCode() == ocName )
701 0 : if( ScRangeData* pData = rRoot.GetNamedRanges().findByIndex( pScToken->GetIndex() ) )
702 0 : if( pData->HasType( RT_SHARED ) )
703 0 : return pData->GetCode();
704 0 : return 0;
705 : }
706 :
707 : // multiple operations --------------------------------------------------------
708 :
709 : namespace {
710 :
711 0 : inline bool lclGetAddress( ScAddress& rAddress, const FormulaToken& rToken )
712 : {
713 0 : OpCode eOpCode = rToken.GetOpCode();
714 0 : bool bIsSingleRef = (eOpCode == ocPush) && (rToken.GetType() == svSingleRef);
715 0 : if( bIsSingleRef )
716 : {
717 0 : const ScSingleRefData& rRef = static_cast<const ScToken&>(rToken).GetSingleRef();
718 0 : rAddress.Set( rRef.nCol, rRef.nRow, rRef.nTab );
719 0 : bIsSingleRef = !rRef.IsDeleted();
720 : }
721 0 : return bIsSingleRef;
722 : }
723 :
724 : } // namespace
725 :
726 0 : bool XclTokenArrayHelper::GetMultipleOpRefs( XclMultipleOpRefs& rRefs, const ScTokenArray& rScTokArr )
727 : {
728 0 : rRefs.mbDblRefMode = false;
729 : enum
730 : {
731 : stBegin, stTableOp, stOpen, stFormula, stFormulaSep,
732 : stColFirst, stColFirstSep, stColRel, stColRelSep,
733 : stRowFirst, stRowFirstSep, stRowRel, stClose, stError
734 0 : } eState = stBegin; // last read token
735 0 : for( XclTokenArrayIterator aIt( rScTokArr, true ); aIt.Is() && (eState != stError); ++aIt )
736 : {
737 0 : OpCode eOpCode = aIt->GetOpCode();
738 0 : bool bIsSep = eOpCode == ocSep;
739 0 : switch( eState )
740 : {
741 : case stBegin:
742 0 : eState = (eOpCode == ocTableOp) ? stTableOp : stError;
743 0 : break;
744 : case stTableOp:
745 0 : eState = (eOpCode == ocOpen) ? stOpen : stError;
746 0 : break;
747 : case stOpen:
748 0 : eState = lclGetAddress( rRefs.maFmlaScPos, *aIt ) ? stFormula : stError;
749 0 : break;
750 : case stFormula:
751 0 : eState = bIsSep ? stFormulaSep : stError;
752 0 : break;
753 : case stFormulaSep:
754 0 : eState = lclGetAddress( rRefs.maColFirstScPos, *aIt ) ? stColFirst : stError;
755 0 : break;
756 : case stColFirst:
757 0 : eState = bIsSep ? stColFirstSep : stError;
758 0 : break;
759 : case stColFirstSep:
760 0 : eState = lclGetAddress( rRefs.maColRelScPos, *aIt ) ? stColRel : stError;
761 0 : break;
762 : case stColRel:
763 0 : eState = bIsSep ? stColRelSep : ((eOpCode == ocClose) ? stClose : stError);
764 0 : break;
765 : case stColRelSep:
766 0 : eState = lclGetAddress( rRefs.maRowFirstScPos, *aIt ) ? stRowFirst : stError;
767 0 : rRefs.mbDblRefMode = true;
768 0 : break;
769 : case stRowFirst:
770 0 : eState = bIsSep ? stRowFirstSep : stError;
771 0 : break;
772 : case stRowFirstSep:
773 0 : eState = lclGetAddress( rRefs.maRowRelScPos, *aIt ) ? stRowRel : stError;
774 0 : break;
775 : case stRowRel:
776 0 : eState = (eOpCode == ocClose) ? stClose : stError;
777 0 : break;
778 : default:
779 0 : eState = stError;
780 : }
781 : }
782 0 : return eState == stClose;
783 9 : }
784 :
785 : // ============================================================================
786 :
787 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|