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