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