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_sc.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