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