xref: /AOO41X/main/oox/source/xls/formulabase.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "oox/xls/formulabase.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <map>
31*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32*cdf0e10cSrcweir #include <com/sun/star/table/XCellRange.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/sheet/AddressConvention.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/sheet/ReferenceFlags.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/sheet/SingleReference.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/sheet/ComplexReference.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaLanguage.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaMapGroup.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/sheet/XFormulaParser.hpp>
42*cdf0e10cSrcweir #include <rtl/strbuf.hxx>
43*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
44*cdf0e10cSrcweir #include "oox/core/filterbase.hxx"
45*cdf0e10cSrcweir #include "oox/helper/containerhelper.hxx"
46*cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx"
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir namespace oox {
49*cdf0e10cSrcweir namespace xls {
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir // ============================================================================
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
54*cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
55*cdf0e10cSrcweir using namespace ::com::sun::star::table;
56*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir using ::rtl::OString;
59*cdf0e10cSrcweir using ::rtl::OStringBuffer;
60*cdf0e10cSrcweir using ::rtl::OStringToOUString;
61*cdf0e10cSrcweir using ::rtl::OUString;
62*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
63*cdf0e10cSrcweir using ::rtl::OUStringToOString;
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir // reference helpers ==========================================================
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir BinSingleRef2d::BinSingleRef2d() :
68*cdf0e10cSrcweir     mnCol( 0 ),
69*cdf0e10cSrcweir     mnRow( 0 ),
70*cdf0e10cSrcweir     mbColRel( false ),
71*cdf0e10cSrcweir     mbRowRel( false )
72*cdf0e10cSrcweir {
73*cdf0e10cSrcweir }
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir void BinSingleRef2d::setBiff12Data( sal_uInt16 nCol, sal_Int32 nRow, bool bRelativeAsOffset )
76*cdf0e10cSrcweir {
77*cdf0e10cSrcweir     mnCol = nCol & BIFF12_TOK_REF_COLMASK;
78*cdf0e10cSrcweir     mnRow = nRow & BIFF12_TOK_REF_ROWMASK;
79*cdf0e10cSrcweir     mbColRel = getFlag( nCol, BIFF12_TOK_REF_COLREL );
80*cdf0e10cSrcweir     mbRowRel = getFlag( nCol, BIFF12_TOK_REF_ROWREL );
81*cdf0e10cSrcweir     if( bRelativeAsOffset && mbColRel && (mnCol > (BIFF12_TOK_REF_COLMASK >> 1)) )
82*cdf0e10cSrcweir         mnCol -= (BIFF12_TOK_REF_COLMASK + 1);
83*cdf0e10cSrcweir     if( bRelativeAsOffset && mbRowRel && (mnRow > (BIFF12_TOK_REF_ROWMASK >> 1)) )
84*cdf0e10cSrcweir         mnRow -= (BIFF12_TOK_REF_ROWMASK + 1);
85*cdf0e10cSrcweir }
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir void BinSingleRef2d::setBiff2Data( sal_uInt8 nCol, sal_uInt16 nRow, bool bRelativeAsOffset )
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir     mnCol = nCol;
90*cdf0e10cSrcweir     mnRow = nRow & BIFF_TOK_REF_ROWMASK;
91*cdf0e10cSrcweir     mbColRel = getFlag( nRow, BIFF_TOK_REF_COLREL );
92*cdf0e10cSrcweir     mbRowRel = getFlag( nRow, BIFF_TOK_REF_ROWREL );
93*cdf0e10cSrcweir     if( bRelativeAsOffset && mbColRel && (mnCol >= 0x80) )
94*cdf0e10cSrcweir         mnCol -= 0x100;
95*cdf0e10cSrcweir     if( bRelativeAsOffset && mbRowRel && (mnRow > (BIFF_TOK_REF_ROWMASK >> 1)) )
96*cdf0e10cSrcweir         mnRow -= (BIFF_TOK_REF_ROWMASK + 1);
97*cdf0e10cSrcweir }
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir void BinSingleRef2d::setBiff8Data( sal_uInt16 nCol, sal_uInt16 nRow, bool bRelativeAsOffset )
100*cdf0e10cSrcweir {
101*cdf0e10cSrcweir     mnCol = nCol & BIFF_TOK_REF_COLMASK;
102*cdf0e10cSrcweir     mnRow = nRow;
103*cdf0e10cSrcweir     mbColRel = getFlag( nCol, BIFF_TOK_REF_COLREL );
104*cdf0e10cSrcweir     mbRowRel = getFlag( nCol, BIFF_TOK_REF_ROWREL );
105*cdf0e10cSrcweir     if( bRelativeAsOffset && mbColRel && (mnCol > (BIFF_TOK_REF_COLMASK >> 1)) )
106*cdf0e10cSrcweir         mnCol -= (BIFF_TOK_REF_COLMASK + 1);
107*cdf0e10cSrcweir     if( bRelativeAsOffset && mbRowRel && (mnRow >= 0x8000) )
108*cdf0e10cSrcweir         mnRow -= 0x10000;
109*cdf0e10cSrcweir }
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir void BinSingleRef2d::readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset )
112*cdf0e10cSrcweir {
113*cdf0e10cSrcweir     sal_Int32 nRow;
114*cdf0e10cSrcweir     sal_uInt16 nCol;
115*cdf0e10cSrcweir     rStrm >> nRow >> nCol;
116*cdf0e10cSrcweir     setBiff12Data( nCol, nRow, bRelativeAsOffset );
117*cdf0e10cSrcweir }
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir void BinSingleRef2d::readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset )
120*cdf0e10cSrcweir {
121*cdf0e10cSrcweir     sal_uInt16 nRow;
122*cdf0e10cSrcweir     sal_uInt8 nCol;
123*cdf0e10cSrcweir     rStrm >> nRow >> nCol;
124*cdf0e10cSrcweir     setBiff2Data( nCol, nRow, bRelativeAsOffset );
125*cdf0e10cSrcweir }
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir void BinSingleRef2d::readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset )
128*cdf0e10cSrcweir {
129*cdf0e10cSrcweir     sal_uInt16 nRow, nCol;
130*cdf0e10cSrcweir     rStrm >> nRow >> nCol;
131*cdf0e10cSrcweir     setBiff8Data( nCol, nRow, bRelativeAsOffset );
132*cdf0e10cSrcweir }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir // ----------------------------------------------------------------------------
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir void BinComplexRef2d::readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset )
137*cdf0e10cSrcweir {
138*cdf0e10cSrcweir     sal_Int32 nRow1, nRow2;
139*cdf0e10cSrcweir     sal_uInt16 nCol1, nCol2;
140*cdf0e10cSrcweir     rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
141*cdf0e10cSrcweir     maRef1.setBiff12Data( nCol1, nRow1, bRelativeAsOffset );
142*cdf0e10cSrcweir     maRef2.setBiff12Data( nCol2, nRow2, bRelativeAsOffset );
143*cdf0e10cSrcweir }
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir void BinComplexRef2d::readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset )
146*cdf0e10cSrcweir {
147*cdf0e10cSrcweir     sal_uInt16 nRow1, nRow2;
148*cdf0e10cSrcweir     sal_uInt8 nCol1, nCol2;
149*cdf0e10cSrcweir     rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
150*cdf0e10cSrcweir     maRef1.setBiff2Data( nCol1, nRow1, bRelativeAsOffset );
151*cdf0e10cSrcweir     maRef2.setBiff2Data( nCol2, nRow2, bRelativeAsOffset );
152*cdf0e10cSrcweir }
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir void BinComplexRef2d::readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset )
155*cdf0e10cSrcweir {
156*cdf0e10cSrcweir     sal_uInt16 nRow1, nRow2, nCol1, nCol2;
157*cdf0e10cSrcweir     rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
158*cdf0e10cSrcweir     maRef1.setBiff8Data( nCol1, nRow1, bRelativeAsOffset );
159*cdf0e10cSrcweir     maRef2.setBiff8Data( nCol2, nRow2, bRelativeAsOffset );
160*cdf0e10cSrcweir }
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir // token vector, sequence =====================================================
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir ApiTokenVector::ApiTokenVector()
165*cdf0e10cSrcweir {
166*cdf0e10cSrcweir }
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir Any& ApiTokenVector::append( sal_Int32 nOpCode )
169*cdf0e10cSrcweir {
170*cdf0e10cSrcweir     resize( size() + 1 );
171*cdf0e10cSrcweir     back().OpCode = nOpCode;
172*cdf0e10cSrcweir     return back().Data;
173*cdf0e10cSrcweir }
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir // token sequence iterator ====================================================
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir ApiTokenIterator::ApiTokenIterator( const ApiTokenSequence& rTokens, sal_Int32 nSpacesOpCode, bool bSkipSpaces ) :
178*cdf0e10cSrcweir     mpToken( rTokens.getConstArray() ),
179*cdf0e10cSrcweir     mpTokenEnd( rTokens.getConstArray() + rTokens.getLength() ),
180*cdf0e10cSrcweir     mnSpacesOpCode( nSpacesOpCode ),
181*cdf0e10cSrcweir     mbSkipSpaces( bSkipSpaces )
182*cdf0e10cSrcweir {
183*cdf0e10cSrcweir     skipSpaces();
184*cdf0e10cSrcweir }
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir ApiTokenIterator::ApiTokenIterator( const ApiTokenIterator& rIter, bool bSkipSpaces ) :
187*cdf0e10cSrcweir     mpToken( rIter.mpToken ),
188*cdf0e10cSrcweir     mpTokenEnd( rIter.mpTokenEnd ),
189*cdf0e10cSrcweir     mnSpacesOpCode( rIter.mnSpacesOpCode ),
190*cdf0e10cSrcweir     mbSkipSpaces( bSkipSpaces )
191*cdf0e10cSrcweir {
192*cdf0e10cSrcweir     skipSpaces();
193*cdf0e10cSrcweir }
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir ApiTokenIterator& ApiTokenIterator::operator++()
196*cdf0e10cSrcweir {
197*cdf0e10cSrcweir     if( is() )
198*cdf0e10cSrcweir     {
199*cdf0e10cSrcweir         ++mpToken;
200*cdf0e10cSrcweir         skipSpaces();
201*cdf0e10cSrcweir     }
202*cdf0e10cSrcweir     return *this;
203*cdf0e10cSrcweir }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir void ApiTokenIterator::skipSpaces()
206*cdf0e10cSrcweir {
207*cdf0e10cSrcweir     if( mbSkipSpaces )
208*cdf0e10cSrcweir         while( is() && (mpToken->OpCode == mnSpacesOpCode) )
209*cdf0e10cSrcweir             ++mpToken;
210*cdf0e10cSrcweir }
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir // function data ==============================================================
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir namespace {
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir const size_t FUNCINFO_PARAMINFOCOUNT        = 5;        /// Number of parameter type entries.
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_VOLATILE          = 0x0001;   /// Result is volatile (e.g. NOW() function).
219*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_IMPORTONLY        = 0x0002;   /// Only used in import filter.
220*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_EXPORTONLY        = 0x0004;   /// Only used in export filter.
221*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_MACROCALL         = 0x0008;   /// Function is stored as macro call in Excel (_xlfn. prefix). OOXML name MUST exist.
222*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_MACROCALLODF      = 0x0010;   /// ODF-only function stored as macro call in Excel (_xlfnodf. prefix). ODF name MUST exist.
223*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_EXTERNAL          = 0x0020;   /// Function is external in Calc.
224*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_MACROFUNC         = 0x0040;   /// Function is a macro-sheet function.
225*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_MACROCMD          = 0x0080;   /// Function is a macro-sheet command.
226*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_ALWAYSVAR         = 0x0100;   /// Function is always represented by a tFuncVar token.
227*cdf0e10cSrcweir const sal_uInt16 FUNCFLAG_PARAMPAIRS        = 0x0200;   /// Optional parameters are expected to appear in pairs.
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir /// Converts a function library index (value of enum FunctionLibraryType) to function flags.
230*cdf0e10cSrcweir #define FUNCLIB_TO_FUNCFLAGS( funclib_index ) static_cast< sal_uInt16 >( static_cast< sal_uInt8 >( funclib_index ) << 12 )
231*cdf0e10cSrcweir /// Extracts a function library index (value of enum FunctionLibraryType) from function flags.
232*cdf0e10cSrcweir #define FUNCFLAGS_TO_FUNCLIB( func_flags ) extractValue< FunctionLibraryType >( func_flags, 12, 4 )
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir typedef ::boost::shared_ptr< FunctionInfo > FunctionInfoRef;
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir struct FunctionData
237*cdf0e10cSrcweir {
238*cdf0e10cSrcweir     const sal_Char*     mpcOdfFuncName;     /// ODF function name.
239*cdf0e10cSrcweir     const sal_Char*     mpcOoxFuncName;     /// OOXML function name.
240*cdf0e10cSrcweir     sal_uInt16          mnBiff12FuncId;     /// BIFF12 function identifier.
241*cdf0e10cSrcweir     sal_uInt16          mnBiffFuncId;       /// BIFF2-BIFF8 function identifier.
242*cdf0e10cSrcweir     sal_uInt8           mnMinParamCount;    /// Minimum number of parameters.
243*cdf0e10cSrcweir     sal_uInt8           mnMaxParamCount;    /// Maximum number of parameters.
244*cdf0e10cSrcweir     sal_uInt8           mnRetClass;         /// BIFF token class of the return value.
245*cdf0e10cSrcweir     FunctionParamInfo   mpParamInfos[ FUNCINFO_PARAMINFOCOUNT ]; /// Information about all parameters.
246*cdf0e10cSrcweir     sal_uInt16          mnFlags;            /// Additional flags.
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir     inline bool         isSupported( bool bImportFilter ) const;
249*cdf0e10cSrcweir };
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir inline bool FunctionData::isSupported( bool bImportFilter ) const
252*cdf0e10cSrcweir {
253*cdf0e10cSrcweir     /*  For import filters: the FUNCFLAG_EXPORTONLY flag must not be set,
254*cdf0e10cSrcweir         for export filters: the FUNCFLAG_IMPORTONLY flag must not be set. */
255*cdf0e10cSrcweir     return !getFlag( mnFlags, bImportFilter ? FUNCFLAG_EXPORTONLY : FUNCFLAG_IMPORTONLY );
256*cdf0e10cSrcweir }
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir const sal_uInt16 NOID = SAL_MAX_UINT16;     /// No BIFF function identifier available.
259*cdf0e10cSrcweir const sal_uInt8 MX    = SAL_MAX_UINT8;      /// Maximum parameter count.
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir // abbreviations for function return token class
262*cdf0e10cSrcweir const sal_uInt8 R = BIFF_TOKCLASS_REF;
263*cdf0e10cSrcweir const sal_uInt8 V = BIFF_TOKCLASS_VAL;
264*cdf0e10cSrcweir const sal_uInt8 A = BIFF_TOKCLASS_ARR;
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir // abbreviations for parameter infos
267*cdf0e10cSrcweir #define RO   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_ORG, false }
268*cdf0e10cSrcweir #define RV   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_VAL, false }
269*cdf0e10cSrcweir #define RA   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_ARR, false }
270*cdf0e10cSrcweir #define RR   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_RPT, false }
271*cdf0e10cSrcweir #define RX   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_RPX, false }
272*cdf0e10cSrcweir #define VO   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_ORG, true  }
273*cdf0e10cSrcweir #define VV   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_VAL, true  }
274*cdf0e10cSrcweir #define VA   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_ARR, true  }
275*cdf0e10cSrcweir #define VR   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_RPT, true  }
276*cdf0e10cSrcweir #define VX   { FUNC_PARAM_REGULAR,   FUNC_PARAMCONV_RPX, true  }
277*cdf0e10cSrcweir #define RO_E { FUNC_PARAM_EXCELONLY, FUNC_PARAMCONV_ORG, false }
278*cdf0e10cSrcweir #define VR_E { FUNC_PARAM_EXCELONLY, FUNC_PARAMCONV_RPT, true  }
279*cdf0e10cSrcweir #define C    { FUNC_PARAM_CALCONLY,  FUNC_PARAMCONV_ORG, false }
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir // Note: parameter types of all macro sheet functions (FUNCFLAG_MACROFUNC/FUNCFLAG_MACROCMD) untested!
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir /** Functions new in BIFF2. */
284*cdf0e10cSrcweir static const FunctionData saFuncTableBiff2[] =
285*cdf0e10cSrcweir {
286*cdf0e10cSrcweir     { "COUNT",                  "COUNT",                0,      0,      0,  MX, V, { RX }, 0 },
287*cdf0e10cSrcweir     { "IF",                     "IF",                   1,      1,      2,  3,  R, { VO, RO }, 0 },
288*cdf0e10cSrcweir     { "ISNA",                   "ISNA",                 2,      2,      1,  1,  V, { VR }, 0 },
289*cdf0e10cSrcweir     { "ISERROR",                "ISERROR",              3,      3,      1,  1,  V, { VR }, 0 },
290*cdf0e10cSrcweir     { "SUM",                    "SUM",                  4,      4,      0,  MX, V, { RX }, 0 },
291*cdf0e10cSrcweir     { "AVERAGE",                "AVERAGE",              5,      5,      1,  MX, V, { RX }, 0 },
292*cdf0e10cSrcweir     { "MIN",                    "MIN",                  6,      6,      1,  MX, V, { RX }, 0 },
293*cdf0e10cSrcweir     { "MAX",                    "MAX",                  7,      7,      1,  MX, V, { RX }, 0 },
294*cdf0e10cSrcweir     { "ROW",                    "ROW",                  8,      8,      0,  1,  V, { RO }, 0 },
295*cdf0e10cSrcweir     { "COLUMN",                 "COLUMN",               9,      9,      0,  1,  V, { RO }, 0 },
296*cdf0e10cSrcweir     { "NA",                     "NA",                   10,     10,     0,  0,  V, {}, 0 },
297*cdf0e10cSrcweir     { "NPV",                    "NPV",                  11,     11,     2,  MX, V, { VR, RX }, 0 },
298*cdf0e10cSrcweir     { "STDEV",                  "STDEV",                12,     12,     1,  MX, V, { RX }, 0 },
299*cdf0e10cSrcweir     { "DOLLAR",                 "DOLLAR",               13,     13,     1,  2,  V, { VR }, 0 },
300*cdf0e10cSrcweir     { "FIXED",                  "FIXED",                14,     14,     1,  2,  V, { VR, VR, C }, 0 },
301*cdf0e10cSrcweir     { "SIN",                    "SIN",                  15,     15,     1,  1,  V, { VR }, 0 },
302*cdf0e10cSrcweir     { "CSC",                    "SIN",                  15,     15,     1,  1,  V, { VR }, FUNCFLAG_EXPORTONLY },
303*cdf0e10cSrcweir     { "COS",                    "COS",                  16,     16,     1,  1,  V, { VR }, 0 },
304*cdf0e10cSrcweir     { "SEC",                    "COS",                  16,     16,     1,  1,  V, { VR }, FUNCFLAG_EXPORTONLY },
305*cdf0e10cSrcweir     { "TAN",                    "TAN",                  17,     17,     1,  1,  V, { VR }, 0 },
306*cdf0e10cSrcweir     { "COT",                    "TAN",                  17,     17,     1,  1,  V, { VR }, FUNCFLAG_EXPORTONLY },
307*cdf0e10cSrcweir     { "ATAN",                   "ATAN",                 18,     18,     1,  1,  V, { VR }, 0 },
308*cdf0e10cSrcweir     { "ACOT",                   "ATAN",                 18,     18,     1,  1,  V, { VR }, FUNCFLAG_EXPORTONLY },
309*cdf0e10cSrcweir     { "PI",                     "PI",                   19,     19,     0,  0,  V, {}, 0 },
310*cdf0e10cSrcweir     { "SQRT",                   "SQRT",                 20,     20,     1,  1,  V, { VR }, 0 },
311*cdf0e10cSrcweir     { "EXP",                    "EXP",                  21,     21,     1,  1,  V, { VR }, 0 },
312*cdf0e10cSrcweir     { "LN",                     "LN",                   22,     22,     1,  1,  V, { VR }, 0 },
313*cdf0e10cSrcweir     { "LOG10",                  "LOG10",                23,     23,     1,  1,  V, { VR }, 0 },
314*cdf0e10cSrcweir     { "ABS",                    "ABS",                  24,     24,     1,  1,  V, { VR }, 0 },
315*cdf0e10cSrcweir     { "INT",                    "INT",                  25,     25,     1,  1,  V, { VR }, 0 },
316*cdf0e10cSrcweir     { "SIGN",                   "SIGN",                 26,     26,     1,  1,  V, { VR }, 0 },
317*cdf0e10cSrcweir     { "ROUND",                  "ROUND",                27,     27,     2,  2,  V, { VR }, 0 },
318*cdf0e10cSrcweir     { "LOOKUP",                 "LOOKUP",               28,     28,     2,  3,  V, { VR, RA }, 0 },
319*cdf0e10cSrcweir     { "INDEX",                  "INDEX",                29,     29,     2,  4,  R, { RA, VV }, 0 },
320*cdf0e10cSrcweir     { "REPT",                   "REPT",                 30,     30,     2,  2,  V, { VR }, 0 },
321*cdf0e10cSrcweir     { "MID",                    "MID",                  31,     31,     3,  3,  V, { VR }, 0 },
322*cdf0e10cSrcweir     { "LEN",                    "LEN",                  32,     32,     1,  1,  V, { VR }, 0 },
323*cdf0e10cSrcweir     { "VALUE",                  "VALUE",                33,     33,     1,  1,  V, { VR }, 0 },
324*cdf0e10cSrcweir     { "TRUE",                   "TRUE",                 34,     34,     0,  0,  V, {}, 0 },
325*cdf0e10cSrcweir     { "FALSE",                  "FALSE",                35,     35,     0,  0,  V, {}, 0 },
326*cdf0e10cSrcweir     { "AND",                    "AND",                  36,     36,     1,  MX, V, { RX }, 0 },
327*cdf0e10cSrcweir     { "OR",                     "OR",                   37,     37,     1,  MX, V, { RX }, 0 },
328*cdf0e10cSrcweir     { "NOT",                    "NOT",                  38,     38,     1,  1,  V, { VR }, 0 },
329*cdf0e10cSrcweir     { "MOD",                    "MOD",                  39,     39,     2,  2,  V, { VR }, 0 },
330*cdf0e10cSrcweir     { "DCOUNT",                 "DCOUNT",               40,     40,     3,  3,  V, { RO, RR }, 0 },
331*cdf0e10cSrcweir     { "DSUM",                   "DSUM",                 41,     41,     3,  3,  V, { RO, RR }, 0 },
332*cdf0e10cSrcweir     { "DAVERAGE",               "DAVERAGE",             42,     42,     3,  3,  V, { RO, RR }, 0 },
333*cdf0e10cSrcweir     { "DMIN",                   "DMIN",                 43,     43,     3,  3,  V, { RO, RR }, 0 },
334*cdf0e10cSrcweir     { "DMAX",                   "DMAX",                 44,     44,     3,  3,  V, { RO, RR }, 0 },
335*cdf0e10cSrcweir     { "DSTDEV",                 "DSTDEV",               45,     45,     3,  3,  V, { RO, RR }, 0 },
336*cdf0e10cSrcweir     { "VAR",                    "VAR",                  46,     46,     1,  MX, V, { RX }, 0 },
337*cdf0e10cSrcweir     { "DVAR",                   "DVAR",                 47,     47,     3,  3,  V, { RO, RR }, 0 },
338*cdf0e10cSrcweir     { "TEXT",                   "TEXT",                 48,     48,     2,  2,  V, { VR }, 0 },
339*cdf0e10cSrcweir     { "LINEST",                 "LINEST",               49,     49,     1,  2,  A, { RA, RA, C, C }, 0 },
340*cdf0e10cSrcweir     { "TREND",                  "TREND",                50,     50,     1,  3,  A, { RA, RA, RA, C }, 0 },
341*cdf0e10cSrcweir     { "LOGEST",                 "LOGEST",               51,     51,     1,  2,  A, { RA, RA, C, C }, 0 },
342*cdf0e10cSrcweir     { "GROWTH",                 "GROWTH",               52,     52,     1,  3,  A, { RA, RA, RA, C }, 0 },
343*cdf0e10cSrcweir     { "PV",                     "PV",                   56,     56,     3,  5,  V, { VR }, 0 },
344*cdf0e10cSrcweir     { "FV",                     "FV",                   57,     57,     3,  5,  V, { VR }, 0 },
345*cdf0e10cSrcweir     { "NPER",                   "NPER",                 58,     58,     3,  5,  V, { VR }, 0 },
346*cdf0e10cSrcweir     { "PMT",                    "PMT",                  59,     59,     3,  5,  V, { VR }, 0 },
347*cdf0e10cSrcweir     { "RATE",                   "RATE",                 60,     60,     3,  6,  V, { VR }, 0 },
348*cdf0e10cSrcweir     { "MIRR",                   "MIRR",                 61,     61,     3,  3,  V, { RA, VR }, 0 },
349*cdf0e10cSrcweir     { "IRR",                    "IRR",                  62,     62,     1,  2,  V, { RA, VR }, 0 },
350*cdf0e10cSrcweir     { "RAND",                   "RAND",                 63,     63,     0,  0,  V, {}, FUNCFLAG_VOLATILE },
351*cdf0e10cSrcweir     { "MATCH",                  "MATCH",                64,     64,     2,  3,  V, { VR, RX, RR }, 0 },
352*cdf0e10cSrcweir     { "DATE",                   "DATE",                 65,     65,     3,  3,  V, { VR }, 0 },
353*cdf0e10cSrcweir     { "TIME",                   "TIME",                 66,     66,     3,  3,  V, { VR }, 0 },
354*cdf0e10cSrcweir     { "DAY",                    "DAY",                  67,     67,     1,  1,  V, { VR }, 0 },
355*cdf0e10cSrcweir     { "MONTH",                  "MONTH",                68,     68,     1,  1,  V, { VR }, 0 },
356*cdf0e10cSrcweir     { "YEAR",                   "YEAR",                 69,     69,     1,  1,  V, { VR }, 0 },
357*cdf0e10cSrcweir     { "WEEKDAY",                "WEEKDAY",              70,     70,     1,  1,  V, { VR, C }, 0 },
358*cdf0e10cSrcweir     { "HOUR",                   "HOUR",                 71,     71,     1,  1,  V, { VR }, 0 },
359*cdf0e10cSrcweir     { "MINUTE",                 "MINUTE",               72,     72,     1,  1,  V, { VR }, 0 },
360*cdf0e10cSrcweir     { "SECOND",                 "SECOND",               73,     73,     1,  1,  V, { VR }, 0 },
361*cdf0e10cSrcweir     { "NOW",                    "NOW",                  74,     74,     0,  0,  V, {}, FUNCFLAG_VOLATILE },
362*cdf0e10cSrcweir     { "AREAS",                  "AREAS",                75,     75,     1,  1,  V, { RO }, 0 },
363*cdf0e10cSrcweir     { "ROWS",                   "ROWS",                 76,     76,     1,  1,  V, { RO }, 0 },
364*cdf0e10cSrcweir     { "COLUMNS",                "COLUMNS",              77,     77,     1,  1,  V, { RO }, 0 },
365*cdf0e10cSrcweir     { "OFFSET",                 "OFFSET",               78,     78,     3,  5,  R, { RO, VR }, FUNCFLAG_VOLATILE },
366*cdf0e10cSrcweir     { "SEARCH",                 "SEARCH",               82,     82,     2,  3,  V, { VR }, 0 },
367*cdf0e10cSrcweir     { "TRANSPOSE",              "TRANSPOSE",            83,     83,     1,  1,  A, { VO }, 0 },
368*cdf0e10cSrcweir     { "TYPE",                   "TYPE",                 86,     86,     1,  1,  V, { VX }, 0 },
369*cdf0e10cSrcweir     { "ATAN2",                  "ATAN2",                97,     97,     2,  2,  V, { VR }, 0 },
370*cdf0e10cSrcweir     { "ASIN",                   "ASIN",                 98,     98,     1,  1,  V, { VR }, 0 },
371*cdf0e10cSrcweir     { "ACOS",                   "ACOS",                 99,     99,     1,  1,  V, { VR }, 0 },
372*cdf0e10cSrcweir     { "CHOOSE",                 "CHOOSE",               100,    100,    2,  MX, R, { VO, RO }, 0 },
373*cdf0e10cSrcweir     { "HLOOKUP",                "HLOOKUP",              101,    101,    3,  3,  V, { VV, RO, RO, C }, 0 },
374*cdf0e10cSrcweir     { "VLOOKUP",                "VLOOKUP",              102,    102,    3,  3,  V, { VV, RO, RO, C }, 0 },
375*cdf0e10cSrcweir     { "ISREF",                  "ISREF",                105,    105,    1,  1,  V, { RX }, 0 },
376*cdf0e10cSrcweir     { "LOG",                    "LOG",                  109,    109,    1,  2,  V, { VR }, 0 },
377*cdf0e10cSrcweir     { "CHAR",                   "CHAR",                 111,    111,    1,  1,  V, { VR }, 0 },
378*cdf0e10cSrcweir     { "LOWER",                  "LOWER",                112,    112,    1,  1,  V, { VR }, 0 },
379*cdf0e10cSrcweir     { "UPPER",                  "UPPER",                113,    113,    1,  1,  V, { VR }, 0 },
380*cdf0e10cSrcweir     { "PROPER",                 "PROPER",               114,    114,    1,  1,  V, { VR }, 0 },
381*cdf0e10cSrcweir     { "LEFT",                   "LEFT",                 115,    115,    1,  2,  V, { VR }, 0 },
382*cdf0e10cSrcweir     { "RIGHT",                  "RIGHT",                116,    116,    1,  2,  V, { VR }, 0 },
383*cdf0e10cSrcweir     { "EXACT",                  "EXACT",                117,    117,    2,  2,  V, { VR }, 0 },
384*cdf0e10cSrcweir     { "TRIM",                   "TRIM",                 118,    118,    1,  1,  V, { VR }, 0 },
385*cdf0e10cSrcweir     { "REPLACE",                "REPLACE",              119,    119,    4,  4,  V, { VR }, 0 },
386*cdf0e10cSrcweir     { "SUBSTITUTE",             "SUBSTITUTE",           120,    120,    3,  4,  V, { VR }, 0 },
387*cdf0e10cSrcweir     { "CODE",                   "CODE",                 121,    121,    1,  1,  V, { VR }, 0 },
388*cdf0e10cSrcweir     { "FIND",                   "FIND",                 124,    124,    2,  3,  V, { VR }, 0 },
389*cdf0e10cSrcweir     { "CELL",                   "CELL",                 125,    125,    1,  2,  V, { VV, RO }, FUNCFLAG_VOLATILE },
390*cdf0e10cSrcweir     { "ISERR",                  "ISERR",                126,    126,    1,  1,  V, { VR }, 0 },
391*cdf0e10cSrcweir     { "ISTEXT",                 "ISTEXT",               127,    127,    1,  1,  V, { VR }, 0 },
392*cdf0e10cSrcweir     { "ISNUMBER",               "ISNUMBER",             128,    128,    1,  1,  V, { VR }, 0 },
393*cdf0e10cSrcweir     { "ISBLANK",                "ISBLANK",              129,    129,    1,  1,  V, { VR }, 0 },
394*cdf0e10cSrcweir     { "T",                      "T",                    130,    130,    1,  1,  V, { RO }, 0 },
395*cdf0e10cSrcweir     { "N",                      "N",                    131,    131,    1,  1,  V, { RO }, 0 },
396*cdf0e10cSrcweir     { "DATEVALUE",              "DATEVALUE",            140,    140,    1,  1,  V, { VR }, 0 },
397*cdf0e10cSrcweir     { "TIMEVALUE",              "TIMEVALUE",            141,    141,    1,  1,  V, { VR }, 0 },
398*cdf0e10cSrcweir     { "SLN",                    "SLN",                  142,    142,    3,  3,  V, { VR }, 0 },
399*cdf0e10cSrcweir     { "SYD",                    "SYD",                  143,    143,    4,  4,  V, { VR }, 0 },
400*cdf0e10cSrcweir     { "DDB",                    "DDB",                  144,    144,    4,  5,  V, { VR }, 0 },
401*cdf0e10cSrcweir     { "INDIRECT",               "INDIRECT",             148,    148,    1,  2,  R, { VR }, FUNCFLAG_VOLATILE },
402*cdf0e10cSrcweir     { "CLEAN",                  "CLEAN",                162,    162,    1,  1,  V, { VR }, 0 },
403*cdf0e10cSrcweir     { "MDETERM",                "MDETERM",              163,    163,    1,  1,  V, { VA }, 0 },
404*cdf0e10cSrcweir     { "MINVERSE",               "MINVERSE",             164,    164,    1,  1,  A, { VA }, 0 },
405*cdf0e10cSrcweir     { "MMULT",                  "MMULT",                165,    165,    2,  2,  A, { VA }, 0 },
406*cdf0e10cSrcweir     { "IPMT",                   "IPMT",                 167,    167,    4,  6,  V, { VR }, 0 },
407*cdf0e10cSrcweir     { "PPMT",                   "PPMT",                 168,    168,    4,  6,  V, { VR }, 0 },
408*cdf0e10cSrcweir     { "COUNTA",                 "COUNTA",               169,    169,    0,  MX, V, { RX }, 0 },
409*cdf0e10cSrcweir     { "PRODUCT",                "PRODUCT",              183,    183,    0,  MX, V, { RX }, 0 },
410*cdf0e10cSrcweir     { "FACT",                   "FACT",                 184,    184,    1,  1,  V, { VR }, 0 },
411*cdf0e10cSrcweir     { "DPRODUCT",               "DPRODUCT",             189,    189,    3,  3,  V, { RO, RR }, 0 },
412*cdf0e10cSrcweir     { "ISNONTEXT",              "ISNONTEXT",            190,    190,    1,  1,  V, { VR }, 0 },
413*cdf0e10cSrcweir     { "STDEVP",                 "STDEVP",               193,    193,    1,  MX, V, { RX }, 0 },
414*cdf0e10cSrcweir     { "VARP",                   "VARP",                 194,    194,    1,  MX, V, { RX }, 0 },
415*cdf0e10cSrcweir     { "DSTDEVP",                "DSTDEVP",              195,    195,    3,  3,  V, { RO, RR }, 0 },
416*cdf0e10cSrcweir     { "DVARP",                  "DVARP",                196,    196,    3,  3,  V, { RO, RR }, 0 },
417*cdf0e10cSrcweir     { "TRUNC",                  "TRUNC",                197,    197,    1,  1,  V, { VR, C }, 0 },
418*cdf0e10cSrcweir     { "ISLOGICAL",              "ISLOGICAL",            198,    198,    1,  1,  V, { VR }, 0 },
419*cdf0e10cSrcweir     { "DCOUNTA",                "DCOUNTA",              199,    199,    3,  3,  V, { RO, RR }, 0 },
420*cdf0e10cSrcweir     { 0,                        "EXTERN.CALL",          255,    255,    1,  MX, R, { RO_E, RO }, FUNCFLAG_IMPORTONLY },
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir     // *** macro sheet commands ***
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir     { 0,                        "A1.R1C1",              30,     30,     0,  1,  V, { VR }, FUNCFLAG_MACROCMD },
425*cdf0e10cSrcweir     { 0,                        "RETURN",               55,     55,     0,  1,  R, { RO }, FUNCFLAG_MACROFUNC },
426*cdf0e10cSrcweir     { 0,                        "ABSREF",               79,     79,     2,  2,  R, { VR, RO }, FUNCFLAG_MACROFUNC },
427*cdf0e10cSrcweir     { 0,                        "ADD.ARROW",            81,     81,     0,  0,  V, {}, FUNCFLAG_MACROCMD },
428*cdf0e10cSrcweir     { 0,                        "ACTIVE.CELL",          94,     94,     0,  0,  R, {}, FUNCFLAG_MACROFUNC },
429*cdf0e10cSrcweir     { 0,                        "ACTIVATE",             103,    103,    0,  2,  V, { VR }, FUNCFLAG_MACROCMD },
430*cdf0e10cSrcweir     { 0,                        "ACTIVATE.NEXT",        104,    104,    0,  0,  V, {}, FUNCFLAG_MACROCMD },
431*cdf0e10cSrcweir     { 0,                        "ACTIVATE.PREV",        105,    105,    0,  0,  V, {}, FUNCFLAG_MACROCMD },
432*cdf0e10cSrcweir     { 0,                        "ADD.BAR",              151,    151,    0,  0,  V, {}, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
433*cdf0e10cSrcweir     { 0,                        "ADD.MENU",             152,    152,    2,  2,  V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR },
434*cdf0e10cSrcweir     { 0,                        "ADD.COMMAND",          153,    153,    3,  3,  V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }
435*cdf0e10cSrcweir };
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir /** Functions new in BIFF3. */
438*cdf0e10cSrcweir static const FunctionData saFuncTableBiff3[] =
439*cdf0e10cSrcweir {
440*cdf0e10cSrcweir     { "LINEST",                 "LINEST",               49,     49,     1,  4,  A, { RA, RA, VV }, 0 },             // BIFF2: 1-2, BIFF3: 1-4
441*cdf0e10cSrcweir     { "TREND",                  "TREND",                50,     50,     1,  4,  A, { RA, RA, RA, VV }, 0 },             // BIFF2: 1-3, BIFF3: 1-4
442*cdf0e10cSrcweir     { "LOGEST",                 "LOGEST",               51,     51,     1,  4,  A, { RA, RA, VV }, 0 },             // BIFF2: 1-2, BIFF3: 1-4
443*cdf0e10cSrcweir     { "GROWTH",                 "GROWTH",               52,     52,     1,  4,  A, { RA, RA, RA, VV }, 0 },             // BIFF2: 1-3, BIFF3: 1-4
444*cdf0e10cSrcweir     { "TRUNC",                  "TRUNC",                197,    197,    1,  2,  V, { VR }, 0 },                      // BIFF2: 1,   BIFF3: 1-2
445*cdf0e10cSrcweir     { "DOLLAR",                 "USDOLLAR",             204,    204,    1,  2,  V, { VR }, FUNCFLAG_IMPORTONLY },
446*cdf0e10cSrcweir     { 0/*"FIND"*/,              "FINDB",                205,    205,    2,  3,  V, { VR }, 0 },
447*cdf0e10cSrcweir     { 0/*"SEARCH"*/,            "SEARCHB",              206,    206,    2,  3,  V, { VR }, 0 },
448*cdf0e10cSrcweir     { 0/*"REPLACE"*/,           "REPLACEB",             207,    207,    4,  4,  V, { VR }, 0 },
449*cdf0e10cSrcweir     { 0/*"LEFT"*/,              "LEFTB",                208,    208,    1,  2,  V, { VR }, 0 },
450*cdf0e10cSrcweir     { 0/*"RIGHT"*/,             "RIGHTB",               209,    209,    1,  2,  V, { VR }, 0 },
451*cdf0e10cSrcweir     { 0/*"MID"*/,               "MIDB",                 210,    210,    3,  3,  V, { VR }, 0 },
452*cdf0e10cSrcweir     { 0/*"LEN"*/,               "LENB",                 211,    211,    1,  1,  V, { VR }, 0 },
453*cdf0e10cSrcweir     { "ROUNDUP",                "ROUNDUP",              212,    212,    2,  2,  V, { VR }, 0 },
454*cdf0e10cSrcweir     { "ROUNDDOWN",              "ROUNDDOWN",            213,    213,    2,  2,  V, { VR }, 0 },
455*cdf0e10cSrcweir     { "ASC",                    "ASC",                  214,    214,    1,  1,  V, { VR }, 0 },
456*cdf0e10cSrcweir     { "JIS",                    "DBCS",                 215,    215,    1,  1,  V, { VR }, 0 },
457*cdf0e10cSrcweir     { "ADDRESS",                "ADDRESS",              219,    219,    2,  5,  V, { VR }, 0 },
458*cdf0e10cSrcweir     { "DAYS360",                "DAYS360",              220,    220,    2,  2,  V, { VR, VR, C }, 0 },
459*cdf0e10cSrcweir     { "TODAY",                  "TODAY",                221,    221,    0,  0,  V, {}, FUNCFLAG_VOLATILE },
460*cdf0e10cSrcweir     { "VDB",                    "VDB",                  222,    222,    5,  7,  V, { VR }, 0 },
461*cdf0e10cSrcweir     { "MEDIAN",                 "MEDIAN",               227,    227,    1,  MX, V, { RX }, 0 },
462*cdf0e10cSrcweir     { "SUMPRODUCT",             "SUMPRODUCT",           228,    228,    1,  MX, V, { VA }, 0 },
463*cdf0e10cSrcweir     { "SINH",                   "SINH",                 229,    229,    1,  1,  V, { VR }, 0 },
464*cdf0e10cSrcweir     { "CSCH",                   "SINH",                 229,    229,    1,  1,  V, { VR }, FUNCFLAG_EXPORTONLY },
465*cdf0e10cSrcweir     { "COSH",                   "COSH",                 230,    230,    1,  1,  V, { VR }, 0 },
466*cdf0e10cSrcweir     { "SECH",                   "COSH",                 230,    230,    1,  1,  V, { VR }, FUNCFLAG_EXPORTONLY },
467*cdf0e10cSrcweir     { "TANH",                   "TANH",                 231,    231,    1,  1,  V, { VR }, 0 },
468*cdf0e10cSrcweir     { "COTH",                   "TANH",                 231,    231,    1,  1,  V, { VR }, FUNCFLAG_EXPORTONLY },
469*cdf0e10cSrcweir     { "ASINH",                  "ASINH",                232,    232,    1,  1,  V, { VR }, 0 },
470*cdf0e10cSrcweir     { "ACOSH",                  "ACOSH",                233,    233,    1,  1,  V, { VR }, 0 },
471*cdf0e10cSrcweir     { "ATANH",                  "ATANH",                234,    234,    1,  1,  V, { VR }, 0 },
472*cdf0e10cSrcweir     { "ACOTH",                  "ATANH",                234,    234,    1,  1,  V, { VR }, FUNCFLAG_EXPORTONLY },
473*cdf0e10cSrcweir     { "DGET",                   "DGET",                 235,    235,    3,  3,  V, { RO, RR }, 0 },
474*cdf0e10cSrcweir     { "INFO",                   "INFO",                 244,    244,    1,  1,  V, { VR }, FUNCFLAG_VOLATILE },
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir     // *** macro sheet commands ***
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir     { 0,                        "ADD.BAR",              151,    151,    0,  1,  V, { VR }, FUNCFLAG_MACROFUNC },    // BIFF2: 0,   BIFF3: 0-1
479*cdf0e10cSrcweir     { 0,                        "ADD.MENU",             152,    152,    2,  3,  V, { VR, RO }, FUNCFLAG_MACROFUNC },  // BIFF2: 2,   BIFF3: 2-3
480*cdf0e10cSrcweir     { 0,                        "ADD.COMMAND",          153,    153,    3,  4,  V, { VR, RO }, FUNCFLAG_MACROFUNC }   // BIFF2: 3,   BIFF3: 3-4
481*cdf0e10cSrcweir };
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir /** Functions new in BIFF4. */
484*cdf0e10cSrcweir static const FunctionData saFuncTableBiff4[] =
485*cdf0e10cSrcweir {
486*cdf0e10cSrcweir     { "FIXED",                  "FIXED",                14,     14,     1,  3,  V, { VR }, 0 },       // BIFF2-3: 1-2, BIFF4: 1-3
487*cdf0e10cSrcweir     { "RANK",                   "RANK",                 216,    216,    2,  3,  V, { VR, RO, VR }, 0 },
488*cdf0e10cSrcweir     { "DB",                     "DB",                   247,    247,    4,  5,  V, { VR }, 0 },
489*cdf0e10cSrcweir     { "FREQUENCY",              "FREQUENCY",            252,    252,    2,  2,  A, { RA }, 0 },
490*cdf0e10cSrcweir     { "ORG.OPENOFFICE.ERRORTYPE","ERROR.TYPE",          261,    261,    1,  1,  V, { VR }, 0 },
491*cdf0e10cSrcweir     { "AVEDEV",                 "AVEDEV",               269,    269,    1,  MX, V, { RX }, 0 },
492*cdf0e10cSrcweir     { "BETADIST",               "BETADIST",             270,    270,    3,  5,  V, { VR }, 0 },
493*cdf0e10cSrcweir     { "GAMMALN",                "GAMMALN",              271,    271,    1,  1,  V, { VR }, 0 },
494*cdf0e10cSrcweir     { "BETAINV",                "BETAINV",              272,    272,    3,  5,  V, { VR }, 0 },
495*cdf0e10cSrcweir     { "BINOMDIST",              "BINOMDIST",            273,    273,    4,  4,  V, { VR }, 0 },
496*cdf0e10cSrcweir     { "LEGACY.CHIDIST",         "CHIDIST",              274,    274,    2,  2,  V, { VR }, 0 },
497*cdf0e10cSrcweir     { "LEGACY.CHIINV",          "CHIINV",               275,    275,    2,  2,  V, { VR }, 0 },
498*cdf0e10cSrcweir     { "COMBIN",                 "COMBIN",               276,    276,    2,  2,  V, { VR }, 0 },
499*cdf0e10cSrcweir     { "CONFIDENCE",             "CONFIDENCE",           277,    277,    3,  3,  V, { VR }, 0 },
500*cdf0e10cSrcweir     { "CRITBINOM",              "CRITBINOM",            278,    278,    3,  3,  V, { VR }, 0 },
501*cdf0e10cSrcweir     { "EVEN",                   "EVEN",                 279,    279,    1,  1,  V, { VR }, 0 },
502*cdf0e10cSrcweir     { "EXPONDIST",              "EXPONDIST",            280,    280,    3,  3,  V, { VR }, 0 },
503*cdf0e10cSrcweir     { "LEGACY.FDIST",           "FDIST",                281,    281,    3,  3,  V, { VR }, 0 },
504*cdf0e10cSrcweir     { "LEGACY.FINV",            "FINV",                 282,    282,    3,  3,  V, { VR }, 0 },
505*cdf0e10cSrcweir     { "FISHER",                 "FISHER",               283,    283,    1,  1,  V, { VR }, 0 },
506*cdf0e10cSrcweir     { "FISHERINV",              "FISHERINV",            284,    284,    1,  1,  V, { VR }, 0 },
507*cdf0e10cSrcweir     { "FLOOR",                  "FLOOR",                285,    285,    2,  2,  V, { VR, VR, C }, 0 },
508*cdf0e10cSrcweir     { "GAMMADIST",              "GAMMADIST",            286,    286,    4,  4,  V, { VR }, 0 },
509*cdf0e10cSrcweir     { "GAMMAINV",               "GAMMAINV",             287,    287,    3,  3,  V, { VR }, 0 },
510*cdf0e10cSrcweir     { "CEILING",                "CEILING",              288,    288,    2,  2,  V, { VR, VR, C }, 0 },
511*cdf0e10cSrcweir     { "HYPGEOMDIST",            "HYPGEOMDIST",          289,    289,    4,  4,  V, { VR }, 0 },
512*cdf0e10cSrcweir     { "LOGNORMDIST",            "LOGNORMDIST",          290,    290,    3,  3,  V, { VR }, 0 },
513*cdf0e10cSrcweir     { "LOGINV",                 "LOGINV",               291,    291,    3,  3,  V, { VR }, 0 },
514*cdf0e10cSrcweir     { "NEGBINOMDIST",           "NEGBINOMDIST",         292,    292,    3,  3,  V, { VR }, 0 },
515*cdf0e10cSrcweir     { "NORMDIST",               "NORMDIST",             293,    293,    4,  4,  V, { VR }, 0 },
516*cdf0e10cSrcweir     { "LEGACY.NORMSDIST",       "NORMSDIST",            294,    294,    1,  1,  V, { VR }, 0 },
517*cdf0e10cSrcweir     { "NORMINV",                "NORMINV",              295,    295,    3,  3,  V, { VR }, 0 },
518*cdf0e10cSrcweir     { "LEGACY.NORMSINV",        "NORMSINV",             296,    296,    1,  1,  V, { VR }, 0 },
519*cdf0e10cSrcweir     { "STANDARDIZE",            "STANDARDIZE",          297,    297,    3,  3,  V, { VR }, 0 },
520*cdf0e10cSrcweir     { "ODD",                    "ODD",                  298,    298,    1,  1,  V, { VR }, 0 },
521*cdf0e10cSrcweir     { "PERMUT",                 "PERMUT",               299,    299,    2,  2,  V, { VR }, 0 },
522*cdf0e10cSrcweir     { "POISSON",                "POISSON",              300,    300,    3,  3,  V, { VR }, 0 },
523*cdf0e10cSrcweir     { "TDIST",                  "TDIST",                301,    301,    3,  3,  V, { VR }, 0 },
524*cdf0e10cSrcweir     { "WEIBULL",                "WEIBULL",              302,    302,    4,  4,  V, { VR }, 0 },
525*cdf0e10cSrcweir     { "SUMXMY2",                "SUMXMY2",              303,    303,    2,  2,  V, { VA }, 0 },
526*cdf0e10cSrcweir     { "SUMX2MY2",               "SUMX2MY2",             304,    304,    2,  2,  V, { VA }, 0 },
527*cdf0e10cSrcweir     { "SUMX2PY2",               "SUMX2PY2",             305,    305,    2,  2,  V, { VA }, 0 },
528*cdf0e10cSrcweir     { "LEGACY.CHITEST",         "CHITEST",              306,    306,    2,  2,  V, { VA }, 0 },
529*cdf0e10cSrcweir     { "CORREL",                 "CORREL",               307,    307,    2,  2,  V, { VA }, 0 },
530*cdf0e10cSrcweir     { "COVAR",                  "COVAR",                308,    308,    2,  2,  V, { VA }, 0 },
531*cdf0e10cSrcweir     { "FORECAST",               "FORECAST",             309,    309,    3,  3,  V, { VR, VA }, 0 },
532*cdf0e10cSrcweir     { "FTEST",                  "FTEST",                310,    310,    2,  2,  V, { VA }, 0 },
533*cdf0e10cSrcweir     { "INTERCEPT",              "INTERCEPT",            311,    311,    2,  2,  V, { VA }, 0 },
534*cdf0e10cSrcweir     { "PEARSON",                "PEARSON",              312,    312,    2,  2,  V, { VA }, 0 },
535*cdf0e10cSrcweir     { "RSQ",                    "RSQ",                  313,    313,    2,  2,  V, { VA }, 0 },
536*cdf0e10cSrcweir     { "STEYX",                  "STEYX",                314,    314,    2,  2,  V, { VA }, 0 },
537*cdf0e10cSrcweir     { "SLOPE",                  "SLOPE",                315,    315,    2,  2,  V, { VA }, 0 },
538*cdf0e10cSrcweir     { "TTEST",                  "TTEST",                316,    316,    4,  4,  V, { VA, VA, VR }, 0 },
539*cdf0e10cSrcweir     { "PROB",                   "PROB",                 317,    317,    3,  4,  V, { VA, VA, VR }, 0 },
540*cdf0e10cSrcweir     { "DEVSQ",                  "DEVSQ",                318,    318,    1,  MX, V, { RX }, 0 },
541*cdf0e10cSrcweir     { "GEOMEAN",                "GEOMEAN",              319,    319,    1,  MX, V, { RX }, 0 },
542*cdf0e10cSrcweir     { "HARMEAN",                "HARMEAN",              320,    320,    1,  MX, V, { RX }, 0 },
543*cdf0e10cSrcweir     { "SUMSQ",                  "SUMSQ",                321,    321,    0,  MX, V, { RX }, 0 },
544*cdf0e10cSrcweir     { "KURT",                   "KURT",                 322,    322,    1,  MX, V, { RX }, 0 },
545*cdf0e10cSrcweir     { "SKEW",                   "SKEW",                 323,    323,    1,  MX, V, { RX }, 0 },
546*cdf0e10cSrcweir     { "ZTEST",                  "ZTEST",                324,    324,    2,  3,  V, { RX, VR }, 0 },
547*cdf0e10cSrcweir     { "LARGE",                  "LARGE",                325,    325,    2,  2,  V, { RX, VR }, 0 },
548*cdf0e10cSrcweir     { "SMALL",                  "SMALL",                326,    326,    2,  2,  V, { RX, VR }, 0 },
549*cdf0e10cSrcweir     { "QUARTILE",               "QUARTILE",             327,    327,    2,  2,  V, { RX, VR }, 0 },
550*cdf0e10cSrcweir     { "PERCENTILE",             "PERCENTILE",           328,    328,    2,  2,  V, { RX, VR }, 0 },
551*cdf0e10cSrcweir     { "PERCENTRANK",            "PERCENTRANK",          329,    329,    2,  3,  V, { RX, VR, VR_E }, 0 },
552*cdf0e10cSrcweir     { "MODE",                   "MODE",                 330,    330,    1,  MX, V, { VA }, 0 },
553*cdf0e10cSrcweir     { "TRIMMEAN",               "TRIMMEAN",             331,    331,    2,  2,  V, { RX, VR }, 0 },
554*cdf0e10cSrcweir     { "TINV",                   "TINV",                 332,    332,    2,  2,  V, { VR }, 0 },
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir     // *** Analysis add-in ***
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir     { "HEX2BIN",                "HEX2BIN",              384,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
559*cdf0e10cSrcweir     { "HEX2DEC",                "HEX2DEC",              385,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
560*cdf0e10cSrcweir     { "HEX2OCT",                "HEX2OCT",              386,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
561*cdf0e10cSrcweir     { "DEC2BIN",                "DEC2BIN",              387,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
562*cdf0e10cSrcweir     { "DEC2HEX",                "DEC2HEX",              388,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
563*cdf0e10cSrcweir     { "DEC2OCT",                "DEC2OCT",              389,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
564*cdf0e10cSrcweir     { "OCT2BIN",                "OCT2BIN",              390,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
565*cdf0e10cSrcweir     { "OCT2HEX",                "OCT2HEX",              391,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
566*cdf0e10cSrcweir     { "OCT2DEC",                "OCT2DEC",              392,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
567*cdf0e10cSrcweir     { "BIN2DEC",                "BIN2DEC",              393,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
568*cdf0e10cSrcweir     { "BIN2OCT",                "BIN2OCT",              394,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
569*cdf0e10cSrcweir     { "BIN2HEX",                "BIN2HEX",              395,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
570*cdf0e10cSrcweir     { "IMSUB",                  "IMSUB",                396,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
571*cdf0e10cSrcweir     { "IMDIV",                  "IMDIV",                397,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
572*cdf0e10cSrcweir     { "IMPOWER",                "IMPOWER",              398,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
573*cdf0e10cSrcweir     { "IMABS",                  "IMABS",                399,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
574*cdf0e10cSrcweir     { "IMSQRT",                 "IMSQRT",               400,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
575*cdf0e10cSrcweir     { "IMLN",                   "IMLN",                 401,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
576*cdf0e10cSrcweir     { "IMLOG2",                 "IMLOG2",               402,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
577*cdf0e10cSrcweir     { "IMLOG10",                "IMLOG10",              403,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
578*cdf0e10cSrcweir     { "IMSIN",                  "IMSIN",                404,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
579*cdf0e10cSrcweir     { "IMCOS",                  "IMCOS",                405,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
580*cdf0e10cSrcweir     { "IMEXP",                  "IMEXP",                406,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
581*cdf0e10cSrcweir     { "IMARGUMENT",             "IMARGUMENT",           407,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
582*cdf0e10cSrcweir     { "IMCONJUGATE",            "IMCONJUGATE",          408,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
583*cdf0e10cSrcweir     { "IMAGINARY",              "IMAGINARY",            409,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
584*cdf0e10cSrcweir     { "IMREAL",                 "IMREAL",               410,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
585*cdf0e10cSrcweir     { "COMPLEX",                "COMPLEX",              411,    NOID,   2,  3,  V, { RR }, FUNCFLAG_EXTERNAL },
586*cdf0e10cSrcweir     { "IMSUM",                  "IMSUM",                412,    NOID,   1,  MX, V, { RX }, FUNCFLAG_EXTERNAL },
587*cdf0e10cSrcweir     { "IMPRODUCT",              "IMPRODUCT",            413,    NOID,   1,  MX, V, { RX }, FUNCFLAG_EXTERNAL },
588*cdf0e10cSrcweir     { "SERIESSUM",              "SERIESSUM",            414,    NOID,   4,  4,  V, { RR, RR, RR, RX }, FUNCFLAG_EXTERNAL },
589*cdf0e10cSrcweir     { "FACTDOUBLE",             "FACTDOUBLE",           415,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
590*cdf0e10cSrcweir     { "SQRTPI",                 "SQRTPI",               416,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
591*cdf0e10cSrcweir     { "QUOTIENT",               "QUOTIENT",             417,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
592*cdf0e10cSrcweir     { "DELTA",                  "DELTA",                418,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
593*cdf0e10cSrcweir     { "GESTEP",                 "GESTEP",               419,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
594*cdf0e10cSrcweir     { "ISEVEN",                 "ISEVEN",               420,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
595*cdf0e10cSrcweir     { "ISODD",                  "ISODD",                421,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
596*cdf0e10cSrcweir     { "MROUND",                 "MROUND",               422,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
597*cdf0e10cSrcweir     { "ERF",                    "ERF",                  423,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
598*cdf0e10cSrcweir     { "ERFC",                   "ERFC",                 424,    NOID,   1,  1,  V, { RR }, FUNCFLAG_EXTERNAL },
599*cdf0e10cSrcweir     { "BESSELJ",                "BESSELJ",              425,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
600*cdf0e10cSrcweir     { "BESSELK",                "BESSELK",              426,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
601*cdf0e10cSrcweir     { "BESSELY",                "BESSELY",              427,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
602*cdf0e10cSrcweir     { "BESSELI",                "BESSELI",              428,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
603*cdf0e10cSrcweir     { "XIRR",                   "XIRR",                 429,    NOID,   2,  3,  V, { RX, RX, RR }, FUNCFLAG_EXTERNAL },
604*cdf0e10cSrcweir     { "XNPV",                   "XNPV",                 430,    NOID,   3,  3,  V, { RR, RX, RX }, FUNCFLAG_EXTERNAL },
605*cdf0e10cSrcweir     { "PRICEMAT",               "PRICEMAT",             431,    NOID,   5,  6,  V, { RR }, FUNCFLAG_EXTERNAL },
606*cdf0e10cSrcweir     { "YIELDMAT",               "YIELDMAT",             432,    NOID,   5,  6,  V, { RR }, FUNCFLAG_EXTERNAL },
607*cdf0e10cSrcweir     { "INTRATE",                "INTRATE",              433,    NOID,   4,  5,  V, { RR }, FUNCFLAG_EXTERNAL },
608*cdf0e10cSrcweir     { "RECEIVED",               "RECEIVED",             434,    NOID,   4,  5,  V, { RR }, FUNCFLAG_EXTERNAL },
609*cdf0e10cSrcweir     { "DISC",                   "DISC",                 435,    NOID,   4,  5,  V, { RR }, FUNCFLAG_EXTERNAL },
610*cdf0e10cSrcweir     { "PRICEDISC",              "PRICEDISC",            436,    NOID,   4,  5,  V, { RR }, FUNCFLAG_EXTERNAL },
611*cdf0e10cSrcweir     { "YIELDDISC",              "YIELDDISC",            437,    NOID,   4,  5,  V, { RR }, FUNCFLAG_EXTERNAL },
612*cdf0e10cSrcweir     { "TBILLEQ",                "TBILLEQ",              438,    NOID,   3,  3,  V, { RR }, FUNCFLAG_EXTERNAL },
613*cdf0e10cSrcweir     { "TBILLPRICE",             "TBILLPRICE",           439,    NOID,   3,  3,  V, { RR }, FUNCFLAG_EXTERNAL },
614*cdf0e10cSrcweir     { "TBILLYIELD",             "TBILLYIELD",           440,    NOID,   3,  3,  V, { RR }, FUNCFLAG_EXTERNAL },
615*cdf0e10cSrcweir     { "PRICE",                  "PRICE",                441,    NOID,   6,  7,  V, { RR }, FUNCFLAG_EXTERNAL },
616*cdf0e10cSrcweir     { "YIELD",                  "YIELD",                442,    NOID,   6,  7,  V, { RR }, FUNCFLAG_EXTERNAL },
617*cdf0e10cSrcweir     { "DOLLARDE",               "DOLLARDE",             443,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
618*cdf0e10cSrcweir     { "DOLLARFR",               "DOLLARFR",             444,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
619*cdf0e10cSrcweir     { "NOMINAL",                "NOMINAL",              445,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
620*cdf0e10cSrcweir     { "EFFECT",                 "EFFECT",               446,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
621*cdf0e10cSrcweir     { "CUMPRINC",               "CUMPRINC",             447,    NOID,   6,  6,  V, { RR }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
622*cdf0e10cSrcweir     { "CUMIPMT",                "CUMIPMT",              448,    NOID,   6,  6,  V, { RR }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
623*cdf0e10cSrcweir     { "EDATE",                  "EDATE",                449,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
624*cdf0e10cSrcweir     { "EOMONTH",                "EOMONTH",              450,    NOID,   2,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
625*cdf0e10cSrcweir     { "YEARFRAC",               "YEARFRAC",             451,    NOID,   2,  3,  V, { RR }, FUNCFLAG_EXTERNAL },
626*cdf0e10cSrcweir     { "COUPDAYBS",              "COUPDAYBS",            452,    NOID,   3,  4,  V, { RR }, FUNCFLAG_EXTERNAL },
627*cdf0e10cSrcweir     { "COUPDAYS",               "COUPDAYS",             453,    NOID,   3,  4,  V, { RR }, FUNCFLAG_EXTERNAL },
628*cdf0e10cSrcweir     { "COUPDAYSNC",             "COUPDAYSNC",           454,    NOID,   3,  4,  V, { RR }, FUNCFLAG_EXTERNAL },
629*cdf0e10cSrcweir     { "COUPNCD",                "COUPNCD",              455,    NOID,   3,  4,  V, { RR }, FUNCFLAG_EXTERNAL },
630*cdf0e10cSrcweir     { "COUPNUM",                "COUPNUM",              456,    NOID,   3,  4,  V, { RR }, FUNCFLAG_EXTERNAL },
631*cdf0e10cSrcweir     { "COUPPCD",                "COUPPCD",              457,    NOID,   3,  4,  V, { RR }, FUNCFLAG_EXTERNAL },
632*cdf0e10cSrcweir     { "DURATION",               "DURATION",             458,    NOID,   5,  6,  V, { RR }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
633*cdf0e10cSrcweir     { "MDURATION",              "MDURATION",            459,    NOID,   5,  6,  V, { RR }, FUNCFLAG_EXTERNAL },
634*cdf0e10cSrcweir     { "ODDLPRICE",              "ODDLPRICE",            460,    NOID,   7,  8,  V, { RR }, FUNCFLAG_EXTERNAL },
635*cdf0e10cSrcweir     { "ODDLYIELD",              "ODDLYIELD",            461,    NOID,   8,  9,  V, { RR }, FUNCFLAG_EXTERNAL },
636*cdf0e10cSrcweir     { "ODDFPRICE",              "ODDFPRICE",            462,    NOID,   8,  9,  V, { RR }, FUNCFLAG_EXTERNAL },
637*cdf0e10cSrcweir     { "ODDFYIELD",              "ODDFYIELD",            463,    NOID,   8,  9,  V, { RR }, FUNCFLAG_EXTERNAL },
638*cdf0e10cSrcweir     { "RANDBETWEEN",            "RANDBETWEEN",          464,    NOID,   2,  2,  V, { RR }, FUNCFLAG_VOLATILE | FUNCFLAG_EXTERNAL },
639*cdf0e10cSrcweir     { "WEEKNUM",                "WEEKNUM",              465,    NOID,   1,  2,  V, { RR }, FUNCFLAG_EXTERNAL },
640*cdf0e10cSrcweir     { "AMORDEGRC",              "AMORDEGRC",            466,    NOID,   6,  7,  V, { RR }, FUNCFLAG_EXTERNAL },
641*cdf0e10cSrcweir     { "AMORLINC",               "AMORLINC",             467,    NOID,   6,  7,  V, { RR }, FUNCFLAG_EXTERNAL },
642*cdf0e10cSrcweir     { "CONVERT",                "CONVERT",              468,    NOID,   3,  3,  V, { RR }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
643*cdf0e10cSrcweir     { "ACCRINT",                "ACCRINT",              469,    NOID,   6,  7,  V, { RR }, FUNCFLAG_EXTERNAL },
644*cdf0e10cSrcweir     { "ACCRINTM",               "ACCRINTM",             470,    NOID,   4,  5,  V, { RR }, FUNCFLAG_EXTERNAL },
645*cdf0e10cSrcweir     { "WORKDAY",                "WORKDAY",              471,    NOID,   2,  3,  V, { RR, RR, RX, C }, FUNCFLAG_EXTERNAL },
646*cdf0e10cSrcweir     { "NETWORKDAYS",            "NETWORKDAYS",          472,    NOID,   2,  3,  V, { RR, RR, RX, C }, FUNCFLAG_EXTERNAL },
647*cdf0e10cSrcweir     { "GCD",                    "GCD",                  473,    NOID,   1,  MX, V, { RX }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
648*cdf0e10cSrcweir     { "MULTINOMIAL",            "MULTINOMIAL",          474,    NOID,   1,  MX, V, { RX }, FUNCFLAG_EXTERNAL },
649*cdf0e10cSrcweir     { "LCM",                    "LCM",                  475,    NOID,   1,  MX, V, { RX }, FUNCFLAG_EXTERNAL },       // Calc: builtin and add-in
650*cdf0e10cSrcweir     { "FVSCHEDULE",             "FVSCHEDULE",           476,    NOID,   2,  2,  V, { RR, RX }, FUNCFLAG_EXTERNAL },
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir     // *** macro sheet commands ***
653*cdf0e10cSrcweir 
654*cdf0e10cSrcweir     { 0,                        "ACTIVATE.NEXT",        104,    104,    0,  1,  V, { VR }, FUNCFLAG_MACROCMD },      // BIFF2-3: 0, BIFF4: 0-1
655*cdf0e10cSrcweir     { 0,                        "ACTIVATE.PREV",        105,    105,    0,  1,  V, { VR }, FUNCFLAG_MACROCMD }       // BIFF2-3: 0, BIFF4: 0-1
656*cdf0e10cSrcweir };
657*cdf0e10cSrcweir 
658*cdf0e10cSrcweir /** Functions new in BIFF5/BIFF7. */
659*cdf0e10cSrcweir static const FunctionData saFuncTableBiff5[] =
660*cdf0e10cSrcweir {
661*cdf0e10cSrcweir     { "WEEKDAY",                "WEEKDAY",              70,     70,     1,  2,  V, { VR }, 0 },                              // BIFF2-4: 1,   BIFF5: 1-2
662*cdf0e10cSrcweir     { "HLOOKUP",                "HLOOKUP",              101,    101,    3,  4,  V, { VV, RO, RO, VV }, 0 },                     // BIFF2-4: 3,   BIFF5: 3-4
663*cdf0e10cSrcweir     { "VLOOKUP",                "VLOOKUP",              102,    102,    3,  4,  V, { VV, RO, RO, VV }, 0 },                     // BIFF2-4: 3,   BIFF5: 3-4
664*cdf0e10cSrcweir     { "DAYS360",                "DAYS360",              220,    220,    2,  3,  V, { VR }, 0 },                              // BIFF3-4: 2,   BIFF5: 2-3
665*cdf0e10cSrcweir     { 0,                        "EXTERN.CALL",          255,    255,    1,  MX, R, { RO_E, RO }, FUNCFLAG_EXPORTONLY },        // MACRO or EXTERNAL
666*cdf0e10cSrcweir     { "CONCATENATE",            "CONCATENATE",          336,    336,    0,  MX, V, { VR }, 0 },
667*cdf0e10cSrcweir     { "POWER",                  "POWER",                337,    337,    2,  2,  V, { VR }, 0 },
668*cdf0e10cSrcweir     { "RADIANS",                "RADIANS",              342,    342,    1,  1,  V, { VR }, 0 },
669*cdf0e10cSrcweir     { "DEGREES",                "DEGREES",              343,    343,    1,  1,  V, { VR }, 0 },
670*cdf0e10cSrcweir     { "SUBTOTAL",               "SUBTOTAL",             344,    344,    2,  MX, V, { VR, RO }, 0 },
671*cdf0e10cSrcweir     { "SUMIF",                  "SUMIF",                345,    345,    2,  3,  V, { RO, VR, RO }, 0 },
672*cdf0e10cSrcweir     { "COUNTIF",                "COUNTIF",              346,    346,    2,  2,  V, { RO, VR }, 0 },
673*cdf0e10cSrcweir     { "COUNTBLANK",             "COUNTBLANK",           347,    347,    1,  1,  V, { RO }, 0 },
674*cdf0e10cSrcweir     { "ISPMT",                  "ISPMT",                350,    350,    4,  4,  V, { VR }, 0 },
675*cdf0e10cSrcweir     { 0,                        "DATEDIF",              351,    351,    3,  3,  V, { VR }, FUNCFLAG_IMPORTONLY },   // not supported in Calc
676*cdf0e10cSrcweir     { 0,                        "DATESTRING",           352,    352,    1,  1,  V, { VR }, FUNCFLAG_IMPORTONLY },   // not supported in Calc, missing in OOXML spec
677*cdf0e10cSrcweir     { 0,                        "NUMBERSTRING",         353,    353,    2,  2,  V, { VR }, FUNCFLAG_IMPORTONLY },   // not supported in Calc, missing in OOXML spec
678*cdf0e10cSrcweir     { "ROMAN",                  "ROMAN",                354,    354,    1,  2,  V, { VR }, 0 },
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir     // *** EuroTool add-in ***
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir     { "EUROCONVERT",            "EUROCONVERT",          NOID,   NOID,   3,  5,  V, { VR }, FUNCLIB_TO_FUNCFLAGS( FUNCLIB_EUROTOOL ) },
683*cdf0e10cSrcweir 
684*cdf0e10cSrcweir     // *** macro sheet commands ***
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir     { 0,                        "ADD.MENU",             152,    152,    2,  4,  V, { VR, RO, RO, VR }, FUNCFLAG_MACROFUNC },    // BIFF3-4: 2-3, BIFF5: 2-4
687*cdf0e10cSrcweir     { 0,                        "ADD.COMMAND",          153,    153,    3,  5,  V, { VR, RO, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5
688*cdf0e10cSrcweir     { 0,                        "ADD.CHART.AUTOFORMAT", 390,    390,    0,  2,  V, { VR }, FUNCFLAG_MACROCMD },
689*cdf0e10cSrcweir     { 0,                        "ADD.LIST.ITEM",        451,    451,    0,  2,  V, { VR }, FUNCFLAG_MACROCMD },
690*cdf0e10cSrcweir     { 0,                        "ACTIVE.CELL.FONT",     476,    476,    0,  14, V, { VR }, FUNCFLAG_MACROCMD }
691*cdf0e10cSrcweir };
692*cdf0e10cSrcweir 
693*cdf0e10cSrcweir /** Functions new in BIFF8. */
694*cdf0e10cSrcweir static const FunctionData saFuncTableBiff8[] =
695*cdf0e10cSrcweir {
696*cdf0e10cSrcweir     { "GETPIVOTDATA",           "GETPIVOTDATA",         358,    358,    2,  MX, V, { RR, RR, VR, VR }, FUNCFLAG_IMPORTONLY | FUNCFLAG_PARAMPAIRS },
697*cdf0e10cSrcweir     { "HYPERLINK",              "HYPERLINK",            359,    359,    1,  2,  V, { VV, VO }, 0 },
698*cdf0e10cSrcweir     { 0,                        "PHONETIC",             360,    360,    1,  1,  V, { RO }, FUNCFLAG_IMPORTONLY },
699*cdf0e10cSrcweir     { "AVERAGEA",               "AVERAGEA",             361,    361,    1,  MX, V, { RX }, 0 },
700*cdf0e10cSrcweir     { "MAXA",                   "MAXA",                 362,    362,    1,  MX, V, { RX }, 0 },
701*cdf0e10cSrcweir     { "MINA",                   "MINA",                 363,    363,    1,  MX, V, { RX }, 0 },
702*cdf0e10cSrcweir     { "STDEVPA",                "STDEVPA",              364,    364,    1,  MX, V, { RX }, 0 },
703*cdf0e10cSrcweir     { "VARPA",                  "VARPA",                365,    365,    1,  MX, V, { RX }, 0 },
704*cdf0e10cSrcweir     { "STDEVA",                 "STDEVA",               366,    366,    1,  MX, V, { RX }, 0 },
705*cdf0e10cSrcweir     { "VARA",                   "VARA",                 367,    367,    1,  MX, V, { RX }, 0 },
706*cdf0e10cSrcweir     { "COM.MICROSOFT.BAHTTEXT", "BAHTTEXT",             368,    368,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
707*cdf0e10cSrcweir     { 0,                        "THAIDAYOFWEEK",        369,    369,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
708*cdf0e10cSrcweir     { 0,                        "THAIDIGIT",            370,    370,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
709*cdf0e10cSrcweir     { 0,                        "THAIMONTHOFYEAR",      371,    371,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
710*cdf0e10cSrcweir     { 0,                        "THAINUMSOUND",         372,    372,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
711*cdf0e10cSrcweir     { 0,                        "THAINUMSTRING",        373,    373,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
712*cdf0e10cSrcweir     { 0,                        "THAISTRINGLENGTH",     374,    374,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
713*cdf0e10cSrcweir     { 0,                        "ISTHAIDIGIT",          375,    375,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
714*cdf0e10cSrcweir     { 0,                        "ROUNDBAHTDOWN",        376,    376,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
715*cdf0e10cSrcweir     { 0,                        "ROUNDBAHTUP",          377,    377,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
716*cdf0e10cSrcweir     { 0,                        "THAIYEAR",             378,    378,    1,  1,  V, { VR }, FUNCFLAG_MACROCALL },
717*cdf0e10cSrcweir     { 0,                        "RTD",                  379,    379,    3,  3,  A, { VR, VR, RO }, 0 }
718*cdf0e10cSrcweir };
719*cdf0e10cSrcweir 
720*cdf0e10cSrcweir /** Functions new in OOXML. */
721*cdf0e10cSrcweir static const FunctionData saFuncTableOox[] =
722*cdf0e10cSrcweir {
723*cdf0e10cSrcweir     { 0,                        "CUBEVALUE",            380,    NOID,   1,  MX, V, { VR, RX }, 0 },
724*cdf0e10cSrcweir     { 0,                        "CUBEMEMBER",           381,    NOID,   2,  3,  V, { VR, RX, VR }, 0 },
725*cdf0e10cSrcweir     { 0,                        "CUBEMEMBERPROPERTY",   382,    NOID,   3,  3,  V, { VR }, 0 },
726*cdf0e10cSrcweir     { 0,                        "CUBERANKEDMEMBER",     383,    NOID,   3,  4,  V, { VR }, 0 },
727*cdf0e10cSrcweir     { 0,                        "CUBEKPIMEMBER",        477,    NOID,   3,  4,  V, { VR }, 0 },
728*cdf0e10cSrcweir     { 0,                        "CUBESET",              478,    NOID,   2,  5,  V, { VR, RX, VR }, 0 },
729*cdf0e10cSrcweir     { 0,                        "CUBESETCOUNT",         479,    NOID,   1,  1,  V, { VR }, 0 },
730*cdf0e10cSrcweir     { 0,                        "IFERROR",              480,    NOID,   2,  2,  V, { VO, RO }, 0 },
731*cdf0e10cSrcweir     { 0,                        "COUNTIFS",             481,    NOID,   2,  MX, V, { RO, VR }, FUNCFLAG_PARAMPAIRS },
732*cdf0e10cSrcweir     { 0,                        "SUMIFS",               482,    NOID,   3,  MX, V, { RO, RO, VR }, FUNCFLAG_PARAMPAIRS },
733*cdf0e10cSrcweir     { 0,                        "AVERAGEIF",            483,    NOID,   2,  3,  V, { RO, VR, RO }, 0 },
734*cdf0e10cSrcweir     { 0,                        "AVERAGEIFS",           484,    NOID,   3,  MX, V, { RO, RO, VR }, 0 }
735*cdf0e10cSrcweir };
736*cdf0e10cSrcweir 
737*cdf0e10cSrcweir /** Functions defined by OpenFormula, but not supported by Calc or by Excel. */
738*cdf0e10cSrcweir static const FunctionData saFuncTableOdf[] =
739*cdf0e10cSrcweir {
740*cdf0e10cSrcweir     { "ARABIC",                 0,                      NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALLODF },
741*cdf0e10cSrcweir     { "B",                      0,                      NOID,   NOID,   3,  4,  V, { VR }, FUNCFLAG_MACROCALLODF },
742*cdf0e10cSrcweir     { "BASE",                   0,                      NOID,   NOID,   2,  3,  V, { VR }, FUNCFLAG_MACROCALLODF },
743*cdf0e10cSrcweir     { "BITAND",                 0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
744*cdf0e10cSrcweir     { "BITLSHIFT",              0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
745*cdf0e10cSrcweir     { "BITOR",                  0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
746*cdf0e10cSrcweir     { "BITRSHIFT",              0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
747*cdf0e10cSrcweir     { "BITXOR",                 0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
748*cdf0e10cSrcweir     { "CHISQDIST",              0,                      NOID,   NOID,   2,  3,  V, { VR }, FUNCFLAG_MACROCALLODF },
749*cdf0e10cSrcweir     { "CHISQINV",               0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
750*cdf0e10cSrcweir     { "COMBINA",                0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
751*cdf0e10cSrcweir     { "DAYS",                   0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
752*cdf0e10cSrcweir     { "DECIMAL",                0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
753*cdf0e10cSrcweir     { "FDIST",                  0,                      NOID,   NOID,   3,  4,  V, { VR }, FUNCFLAG_MACROCALLODF },
754*cdf0e10cSrcweir     { "FINV",                   0,                      NOID,   NOID,   3,  3,  V, { VR }, FUNCFLAG_MACROCALLODF },
755*cdf0e10cSrcweir     { "FORMULA",                0,                      NOID,   NOID,   1,  1,  V, { RO }, FUNCFLAG_MACROCALLODF },
756*cdf0e10cSrcweir     { "GAMMA",                  0,                      NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALLODF },
757*cdf0e10cSrcweir     { "GAUSS",                  0,                      NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALLODF },
758*cdf0e10cSrcweir     { "IFNA",                   0,                      NOID,   NOID,   2,  2,  V, { VR, RO }, FUNCFLAG_MACROCALLODF },
759*cdf0e10cSrcweir     { "ISFORMULA",              0,                      NOID,   NOID,   1,  1,  V, { RO }, FUNCFLAG_MACROCALLODF },
760*cdf0e10cSrcweir     { "ISOWEEKNUM",             0,                      NOID,   NOID,   1,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
761*cdf0e10cSrcweir     { "MUNIT",                  0,                      NOID,   NOID,   1,  1,  A, { VR }, FUNCFLAG_MACROCALLODF },
762*cdf0e10cSrcweir     { "NUMBERVALUE",            0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
763*cdf0e10cSrcweir     { "PDURATION",              0,                      NOID,   NOID,   3,  3,  V, { VR }, FUNCFLAG_MACROCALLODF },
764*cdf0e10cSrcweir     { "PERMUTATIONA",           0,                      NOID,   NOID,   2,  2,  V, { VR }, FUNCFLAG_MACROCALLODF },
765*cdf0e10cSrcweir     { "PHI",                    0,                      NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALLODF },
766*cdf0e10cSrcweir     { "RRI",                    0,                      NOID,   NOID,   3,  3,  V, { VR }, FUNCFLAG_MACROCALLODF },
767*cdf0e10cSrcweir     { "SHEET",                  0,                      NOID,   NOID,   0,  1,  V, { RO }, FUNCFLAG_MACROCALLODF },
768*cdf0e10cSrcweir     { "SHEETS",                 0,                      NOID,   NOID,   0,  1,  V, { RO }, FUNCFLAG_MACROCALLODF },
769*cdf0e10cSrcweir     { "SKEWP",                  0,                      NOID,   NOID,   1,  MX, V, { RX }, FUNCFLAG_MACROCALLODF },
770*cdf0e10cSrcweir     { "UNICHAR",                0,                      NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALLODF },
771*cdf0e10cSrcweir     { "UNICODE",                0,                      NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALLODF },
772*cdf0e10cSrcweir     { "XOR",                    0,                      NOID,   NOID,   1,  MX, V, { RX }, FUNCFLAG_MACROCALLODF }
773*cdf0e10cSrcweir };
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir // ----------------------------------------------------------------------------
776*cdf0e10cSrcweir 
777*cdf0e10cSrcweir const sal_Unicode API_TOKEN_OPEN            = '(';
778*cdf0e10cSrcweir const sal_Unicode API_TOKEN_CLOSE           = ')';
779*cdf0e10cSrcweir const sal_Unicode API_TOKEN_SEP             = ';';
780*cdf0e10cSrcweir 
781*cdf0e10cSrcweir const sal_Unicode API_TOKEN_ARRAY_OPEN      = '{';
782*cdf0e10cSrcweir const sal_Unicode API_TOKEN_ARRAY_CLOSE     = '}';
783*cdf0e10cSrcweir const sal_Unicode API_TOKEN_ARRAY_ROWSEP    = '|';
784*cdf0e10cSrcweir const sal_Unicode API_TOKEN_ARRAY_COLSEP    = ';';
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir } // namespace
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir // function info parameter class iterator =====================================
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir FunctionParamInfoIterator::FunctionParamInfoIterator( const FunctionInfo& rFuncInfo ) :
791*cdf0e10cSrcweir     mpParamInfo( rFuncInfo.mpParamInfos ),
792*cdf0e10cSrcweir     mpParamInfoEnd( rFuncInfo.mpParamInfos + FUNCINFO_PARAMINFOCOUNT ),
793*cdf0e10cSrcweir     mbParamPairs( rFuncInfo.mbParamPairs )
794*cdf0e10cSrcweir {
795*cdf0e10cSrcweir     OSL_ENSURE( !mbParamPairs || (mpParamInfo + 1 < mpParamInfoEnd),
796*cdf0e10cSrcweir         "FunctionParamInfoIterator::FunctionParamInfoIterator - expecting at least 2 infos for paired parameters" );
797*cdf0e10cSrcweir }
798*cdf0e10cSrcweir 
799*cdf0e10cSrcweir const FunctionParamInfo& FunctionParamInfoIterator::getParamInfo() const
800*cdf0e10cSrcweir {
801*cdf0e10cSrcweir     static const FunctionParamInfo saInvalidInfo = { FUNC_PARAM_NONE, FUNC_PARAMCONV_ORG, false };
802*cdf0e10cSrcweir     return mpParamInfo ? *mpParamInfo : saInvalidInfo;
803*cdf0e10cSrcweir }
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir bool FunctionParamInfoIterator::isCalcOnlyParam() const
806*cdf0e10cSrcweir {
807*cdf0e10cSrcweir     return mpParamInfo && (mpParamInfo->meValid == FUNC_PARAM_CALCONLY);
808*cdf0e10cSrcweir }
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir bool FunctionParamInfoIterator::isExcelOnlyParam() const
811*cdf0e10cSrcweir {
812*cdf0e10cSrcweir     return mpParamInfo && (mpParamInfo->meValid == FUNC_PARAM_EXCELONLY);
813*cdf0e10cSrcweir }
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir FunctionParamInfoIterator& FunctionParamInfoIterator::operator++()
816*cdf0e10cSrcweir {
817*cdf0e10cSrcweir     if( mpParamInfo )
818*cdf0e10cSrcweir     {
819*cdf0e10cSrcweir         // move pointer to next entry, if something explicit follows
820*cdf0e10cSrcweir         if( (mpParamInfo + 1 < mpParamInfoEnd) && (mpParamInfo[ 1 ].meValid != FUNC_PARAM_NONE) )
821*cdf0e10cSrcweir             ++mpParamInfo;
822*cdf0e10cSrcweir         // points to last info, but parameter pairs expected, move to previous info
823*cdf0e10cSrcweir         else if( mbParamPairs )
824*cdf0e10cSrcweir             --mpParamInfo;
825*cdf0e10cSrcweir         // if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it
826*cdf0e10cSrcweir         else if( isExcelOnlyParam() || isCalcOnlyParam() )
827*cdf0e10cSrcweir             mpParamInfo = 0;
828*cdf0e10cSrcweir         // otherwise: repeat last parameter class
829*cdf0e10cSrcweir     }
830*cdf0e10cSrcweir     return *this;
831*cdf0e10cSrcweir }
832*cdf0e10cSrcweir 
833*cdf0e10cSrcweir // function provider ==========================================================
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir struct FunctionProviderImpl
836*cdf0e10cSrcweir {
837*cdf0e10cSrcweir     typedef RefMap< OUString, FunctionInfo >    FuncNameMap;
838*cdf0e10cSrcweir     typedef RefMap< sal_uInt16, FunctionInfo >  FuncIdMap;
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir     FunctionInfoVector  maFuncs;            /// All function infos in one list.
841*cdf0e10cSrcweir     FuncNameMap         maOdfFuncs;         /// Maps ODF function names to function data.
842*cdf0e10cSrcweir     FuncNameMap         maOoxFuncs;         /// Maps OOXML function names to function data.
843*cdf0e10cSrcweir     FuncIdMap           maBiff12Funcs;      /// Maps BIFF12 function indexes to function data.
844*cdf0e10cSrcweir     FuncIdMap           maBiffFuncs;        /// Maps BIFF2-BIFF8 function indexes to function data.
845*cdf0e10cSrcweir     FuncNameMap         maMacroFuncs;       /// Maps macro function names to function data.
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir     explicit            FunctionProviderImpl( FilterType eFilter, BiffType eBiff, bool bImportFilter );
848*cdf0e10cSrcweir 
849*cdf0e10cSrcweir private:
850*cdf0e10cSrcweir     /** Creates and inserts a function info struct from the passed function data. */
851*cdf0e10cSrcweir     void                initFunc( const FunctionData& rFuncData, sal_uInt8 nMaxParam );
852*cdf0e10cSrcweir 
853*cdf0e10cSrcweir     /** Initializes the members from the passed function data list. */
854*cdf0e10cSrcweir     void                initFuncs(
855*cdf0e10cSrcweir                             const FunctionData* pBeg, const FunctionData* pEnd,
856*cdf0e10cSrcweir                             sal_uInt8 nMaxParam, bool bImportFilter );
857*cdf0e10cSrcweir };
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir // ----------------------------------------------------------------------------
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir FunctionProviderImpl::FunctionProviderImpl( FilterType eFilter, BiffType eBiff, bool bImportFilter )
862*cdf0e10cSrcweir {
863*cdf0e10cSrcweir     OSL_ENSURE( bImportFilter, "FunctionProviderImpl::FunctionProviderImpl - need special handling for macro call functions" );
864*cdf0e10cSrcweir     sal_uInt8 nMaxParam = 0;
865*cdf0e10cSrcweir     switch( eFilter )
866*cdf0e10cSrcweir     {
867*cdf0e10cSrcweir         case FILTER_OOXML:
868*cdf0e10cSrcweir             nMaxParam = OOX_MAX_PARAMCOUNT;
869*cdf0e10cSrcweir             eBiff = BIFF8;  // insert all BIFF function tables, then the OOXML table
870*cdf0e10cSrcweir         break;
871*cdf0e10cSrcweir         case FILTER_BIFF:
872*cdf0e10cSrcweir             nMaxParam = BIFF_MAX_PARAMCOUNT;
873*cdf0e10cSrcweir         break;
874*cdf0e10cSrcweir         case FILTER_UNKNOWN:
875*cdf0e10cSrcweir             OSL_ENSURE( false, "FunctionProviderImpl::FunctionProviderImpl - invalid filter type" );
876*cdf0e10cSrcweir         break;
877*cdf0e10cSrcweir     }
878*cdf0e10cSrcweir     OSL_ENSURE( eBiff != BIFF_UNKNOWN, "FunctionProviderImpl::FunctionProviderImpl - invalid BIFF type" );
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir     /*  Add functions supported in the current BIFF version only. Function
881*cdf0e10cSrcweir         tables from later BIFF versions may overwrite single functions from
882*cdf0e10cSrcweir         earlier tables. */
883*cdf0e10cSrcweir     if( eBiff >= BIFF2 )
884*cdf0e10cSrcweir         initFuncs( saFuncTableBiff2, STATIC_ARRAY_END( saFuncTableBiff2 ), nMaxParam, bImportFilter );
885*cdf0e10cSrcweir     if( eBiff >= BIFF3 )
886*cdf0e10cSrcweir         initFuncs( saFuncTableBiff3, STATIC_ARRAY_END( saFuncTableBiff3 ), nMaxParam, bImportFilter );
887*cdf0e10cSrcweir     if( eBiff >= BIFF4 )
888*cdf0e10cSrcweir         initFuncs( saFuncTableBiff4, STATIC_ARRAY_END( saFuncTableBiff4 ), nMaxParam, bImportFilter );
889*cdf0e10cSrcweir     if( eBiff >= BIFF5 )
890*cdf0e10cSrcweir         initFuncs( saFuncTableBiff5, STATIC_ARRAY_END( saFuncTableBiff5 ), nMaxParam, bImportFilter );
891*cdf0e10cSrcweir     if( eBiff >= BIFF8 )
892*cdf0e10cSrcweir         initFuncs( saFuncTableBiff8, STATIC_ARRAY_END( saFuncTableBiff8 ), nMaxParam, bImportFilter );
893*cdf0e10cSrcweir     if( eFilter == FILTER_OOXML )
894*cdf0e10cSrcweir         initFuncs( saFuncTableOox, STATIC_ARRAY_END( saFuncTableOox ), nMaxParam, bImportFilter );
895*cdf0e10cSrcweir     initFuncs( saFuncTableOdf, STATIC_ARRAY_END( saFuncTableOdf ), nMaxParam, bImportFilter );
896*cdf0e10cSrcweir }
897*cdf0e10cSrcweir 
898*cdf0e10cSrcweir void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nMaxParam )
899*cdf0e10cSrcweir {
900*cdf0e10cSrcweir     // create a function info object
901*cdf0e10cSrcweir     FunctionInfoRef xFuncInfo( new FunctionInfo );
902*cdf0e10cSrcweir     if( rFuncData.mpcOdfFuncName )
903*cdf0e10cSrcweir         xFuncInfo->maOdfFuncName = OUString::createFromAscii( rFuncData.mpcOdfFuncName );
904*cdf0e10cSrcweir     if( rFuncData.mpcOoxFuncName )
905*cdf0e10cSrcweir         xFuncInfo->maOoxFuncName = OUString::createFromAscii( rFuncData.mpcOoxFuncName );
906*cdf0e10cSrcweir 
907*cdf0e10cSrcweir     if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALL ) )
908*cdf0e10cSrcweir     {
909*cdf0e10cSrcweir         OSL_ENSURE( xFuncInfo->maOoxFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing OOXML function name" );
910*cdf0e10cSrcweir         OSL_ENSURE( !getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ), "FunctionProviderImpl::initFunc - unexpected flag FUNCFLAG_MACROCALLODF" );
911*cdf0e10cSrcweir         xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfn." ) + xFuncInfo->maOoxFuncName;
912*cdf0e10cSrcweir     }
913*cdf0e10cSrcweir     else if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ) )
914*cdf0e10cSrcweir     {
915*cdf0e10cSrcweir         OSL_ENSURE( xFuncInfo->maOdfFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing ODF function name" );
916*cdf0e10cSrcweir         xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfnodf." ) + xFuncInfo->maOdfFuncName;
917*cdf0e10cSrcweir     }
918*cdf0e10cSrcweir 
919*cdf0e10cSrcweir     xFuncInfo->meFuncLibType = FUNCFLAGS_TO_FUNCLIB( rFuncData.mnFlags );
920*cdf0e10cSrcweir     xFuncInfo->mnApiOpCode = -1;
921*cdf0e10cSrcweir     xFuncInfo->mnBiff12FuncId = rFuncData.mnBiff12FuncId;
922*cdf0e10cSrcweir     xFuncInfo->mnBiffFuncId = rFuncData.mnBiffFuncId;
923*cdf0e10cSrcweir     xFuncInfo->mnMinParamCount = rFuncData.mnMinParamCount;
924*cdf0e10cSrcweir     xFuncInfo->mnMaxParamCount = (rFuncData.mnMaxParamCount == MX) ? nMaxParam : rFuncData.mnMaxParamCount;
925*cdf0e10cSrcweir     xFuncInfo->mnRetClass = rFuncData.mnRetClass;
926*cdf0e10cSrcweir     xFuncInfo->mpParamInfos = rFuncData.mpParamInfos;
927*cdf0e10cSrcweir     xFuncInfo->mbParamPairs = getFlag( rFuncData.mnFlags, FUNCFLAG_PARAMPAIRS );
928*cdf0e10cSrcweir     xFuncInfo->mbVolatile = getFlag( rFuncData.mnFlags, FUNCFLAG_VOLATILE );
929*cdf0e10cSrcweir     xFuncInfo->mbExternal = getFlag( rFuncData.mnFlags, FUNCFLAG_EXTERNAL );
930*cdf0e10cSrcweir     bool bMacroCmd = getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCMD );
931*cdf0e10cSrcweir     xFuncInfo->mbMacroFunc = bMacroCmd || getFlag( rFuncData.mnFlags, FUNCFLAG_MACROFUNC );
932*cdf0e10cSrcweir     xFuncInfo->mbVarParam = bMacroCmd || (rFuncData.mnMinParamCount != rFuncData.mnMaxParamCount) || getFlag( rFuncData.mnFlags, FUNCFLAG_ALWAYSVAR );
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir     setFlag( xFuncInfo->mnBiff12FuncId, BIFF_TOK_FUNCVAR_CMD, bMacroCmd );
935*cdf0e10cSrcweir     setFlag( xFuncInfo->mnBiffFuncId, BIFF_TOK_FUNCVAR_CMD, bMacroCmd );
936*cdf0e10cSrcweir 
937*cdf0e10cSrcweir     // insert the function info into the member maps
938*cdf0e10cSrcweir     maFuncs.push_back( xFuncInfo );
939*cdf0e10cSrcweir     if( xFuncInfo->maOdfFuncName.getLength() > 0 )
940*cdf0e10cSrcweir         maOdfFuncs[ xFuncInfo->maOdfFuncName ] = xFuncInfo;
941*cdf0e10cSrcweir     if( xFuncInfo->maOoxFuncName.getLength() > 0 )
942*cdf0e10cSrcweir         maOoxFuncs[ xFuncInfo->maOoxFuncName ] = xFuncInfo;
943*cdf0e10cSrcweir     if( xFuncInfo->mnBiff12FuncId != NOID )
944*cdf0e10cSrcweir         maBiff12Funcs[ xFuncInfo->mnBiff12FuncId ] = xFuncInfo;
945*cdf0e10cSrcweir     if( xFuncInfo->mnBiffFuncId != NOID )
946*cdf0e10cSrcweir         maBiffFuncs[ xFuncInfo->mnBiffFuncId ] = xFuncInfo;
947*cdf0e10cSrcweir     if( xFuncInfo->maBiffMacroName.getLength() > 0 )
948*cdf0e10cSrcweir         maMacroFuncs[ xFuncInfo->maBiffMacroName ] = xFuncInfo;
949*cdf0e10cSrcweir }
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir void FunctionProviderImpl::initFuncs( const FunctionData* pBeg, const FunctionData* pEnd, sal_uInt8 nMaxParam, bool bImportFilter )
952*cdf0e10cSrcweir {
953*cdf0e10cSrcweir     for( const FunctionData* pIt = pBeg; pIt != pEnd; ++pIt )
954*cdf0e10cSrcweir         if( pIt->isSupported( bImportFilter ) )
955*cdf0e10cSrcweir             initFunc( *pIt, nMaxParam );
956*cdf0e10cSrcweir }
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir // ----------------------------------------------------------------------------
959*cdf0e10cSrcweir 
960*cdf0e10cSrcweir FunctionProvider::FunctionProvider( FilterType eFilter, BiffType eBiff, bool bImportFilter ) :
961*cdf0e10cSrcweir     mxFuncImpl( new FunctionProviderImpl( eFilter, eBiff, bImportFilter ) )
962*cdf0e10cSrcweir {
963*cdf0e10cSrcweir }
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir FunctionProvider::~FunctionProvider()
966*cdf0e10cSrcweir {
967*cdf0e10cSrcweir }
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromOdfFuncName( const OUString& rFuncName ) const
970*cdf0e10cSrcweir {
971*cdf0e10cSrcweir     return mxFuncImpl->maOdfFuncs.get( rFuncName ).get();
972*cdf0e10cSrcweir }
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromOoxFuncName( const OUString& rFuncName ) const
975*cdf0e10cSrcweir {
976*cdf0e10cSrcweir     return mxFuncImpl->maOoxFuncs.get( rFuncName ).get();
977*cdf0e10cSrcweir }
978*cdf0e10cSrcweir 
979*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromBiff12FuncId( sal_uInt16 nFuncId ) const
980*cdf0e10cSrcweir {
981*cdf0e10cSrcweir     return mxFuncImpl->maBiff12Funcs.get( nFuncId ).get();
982*cdf0e10cSrcweir }
983*cdf0e10cSrcweir 
984*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromBiffFuncId( sal_uInt16 nFuncId ) const
985*cdf0e10cSrcweir {
986*cdf0e10cSrcweir     return mxFuncImpl->maBiffFuncs.get( nFuncId ).get();
987*cdf0e10cSrcweir }
988*cdf0e10cSrcweir 
989*cdf0e10cSrcweir const FunctionInfo* FunctionProvider::getFuncInfoFromMacroName( const OUString& rFuncName ) const
990*cdf0e10cSrcweir {
991*cdf0e10cSrcweir     return mxFuncImpl->maMacroFuncs.get( rFuncName ).get();
992*cdf0e10cSrcweir }
993*cdf0e10cSrcweir 
994*cdf0e10cSrcweir FunctionLibraryType FunctionProvider::getFuncLibTypeFromLibraryName( const OUString& rLibraryName ) const
995*cdf0e10cSrcweir {
996*cdf0e10cSrcweir #define OOX_XLS_IS_LIBNAME( libname, basename ) (libname.equalsIgnoreAsciiCaseAscii( basename ".XLA" ) || libname.equalsIgnoreAsciiCaseAscii( basename ".XLAM" ))
997*cdf0e10cSrcweir 
998*cdf0e10cSrcweir     // the EUROTOOL add-in containing the EUROCONVERT function
999*cdf0e10cSrcweir     if( OOX_XLS_IS_LIBNAME( rLibraryName, "EUROTOOL" ) )
1000*cdf0e10cSrcweir         return FUNCLIB_EUROTOOL;
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir #undef OOX_XLS_IS_LIBNAME
1003*cdf0e10cSrcweir 
1004*cdf0e10cSrcweir     // default: unknown library
1005*cdf0e10cSrcweir     return FUNCLIB_UNKNOWN;
1006*cdf0e10cSrcweir }
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir const FunctionInfoVector& FunctionProvider::getFuncs() const
1009*cdf0e10cSrcweir {
1010*cdf0e10cSrcweir     return mxFuncImpl->maFuncs;
1011*cdf0e10cSrcweir }
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir // op-code and function provider ==============================================
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir struct OpCodeProviderImpl : public ApiOpCodes
1016*cdf0e10cSrcweir {
1017*cdf0e10cSrcweir     typedef RefMap< sal_Int32, FunctionInfo >       OpCodeFuncMap;
1018*cdf0e10cSrcweir     typedef RefMap< OUString, FunctionInfo >        FuncNameMap;
1019*cdf0e10cSrcweir     typedef ::std::vector< FormulaOpCodeMapEntry >  OpCodeEntryVector;
1020*cdf0e10cSrcweir 
1021*cdf0e10cSrcweir     OpCodeFuncMap       maOpCodeFuncs;      /// Maps API function op-codes to function data.
1022*cdf0e10cSrcweir     FuncNameMap         maExtProgFuncs;     /// Maps programmatical API function names to function data.
1023*cdf0e10cSrcweir     OpCodeEntryVector   maParserMap;        /// OOXML token mapping for formula parser service.
1024*cdf0e10cSrcweir 
1025*cdf0e10cSrcweir     explicit            OpCodeProviderImpl(
1026*cdf0e10cSrcweir                             const FunctionInfoVector& rFuncInfos,
1027*cdf0e10cSrcweir                             const Reference< XMultiServiceFactory >& rxModelFactory );
1028*cdf0e10cSrcweir 
1029*cdf0e10cSrcweir private:
1030*cdf0e10cSrcweir     typedef ::std::map< OUString, ApiToken >    ApiTokenMap;
1031*cdf0e10cSrcweir     typedef Sequence< FormulaOpCodeMapEntry >   OpCodeEntrySequence;
1032*cdf0e10cSrcweir 
1033*cdf0e10cSrcweir     static bool         fillEntrySeq( OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup );
1034*cdf0e10cSrcweir     static bool         fillTokenMap( ApiTokenMap& orTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup );
1035*cdf0e10cSrcweir     bool                fillFuncTokenMaps( ApiTokenMap& orIntFuncTokenMap, ApiTokenMap& orExtFuncTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper ) const;
1036*cdf0e10cSrcweir 
1037*cdf0e10cSrcweir     static bool         initOpCode( sal_Int32& ornOpCode, const OpCodeEntrySequence& rEntrySeq, sal_Int32 nSpecialId );
1038*cdf0e10cSrcweir     bool                initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const OUString& rOdfName, const OUString& rOoxName );
1039*cdf0e10cSrcweir     bool                initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const sal_Char* pcOdfName, const sal_Char* pcOoxName );
1040*cdf0e10cSrcweir     bool                initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, sal_Unicode cOdfName, sal_Unicode cOoxName );
1041*cdf0e10cSrcweir 
1042*cdf0e10cSrcweir     bool                initFuncOpCode( FunctionInfo& orFuncInfo, const ApiTokenMap& rFuncTokenMap );
1043*cdf0e10cSrcweir     bool                initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, const ApiTokenMap& rExtFuncTokenMap, const FunctionInfoVector& rFuncInfos );
1044*cdf0e10cSrcweir };
1045*cdf0e10cSrcweir 
1046*cdf0e10cSrcweir // ----------------------------------------------------------------------------
1047*cdf0e10cSrcweir 
1048*cdf0e10cSrcweir OpCodeProviderImpl::OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos,
1049*cdf0e10cSrcweir         const Reference< XMultiServiceFactory >& rxModelFactory )
1050*cdf0e10cSrcweir {
1051*cdf0e10cSrcweir     if( rxModelFactory.is() ) try
1052*cdf0e10cSrcweir     {
1053*cdf0e10cSrcweir         Reference< XFormulaOpCodeMapper > xMapper( rxModelFactory->createInstance(
1054*cdf0e10cSrcweir             CREATE_OUSTRING( "com.sun.star.sheet.FormulaOpCodeMapper" ) ), UNO_QUERY_THROW );
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir         // op-codes provided as attributes
1057*cdf0e10cSrcweir         OPCODE_UNKNOWN = xMapper->getOpCodeUnknown();
1058*cdf0e10cSrcweir         OPCODE_EXTERNAL = xMapper->getOpCodeExternal();
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir         using namespace ::com::sun::star::sheet::FormulaMapGroup;
1061*cdf0e10cSrcweir         using namespace ::com::sun::star::sheet::FormulaMapGroupSpecialOffset;
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir         OpCodeEntrySequence aEntrySeq;
1064*cdf0e10cSrcweir         ApiTokenMap aTokenMap, aExtFuncTokenMap;
1065*cdf0e10cSrcweir         bool bIsValid =
1066*cdf0e10cSrcweir             // special
1067*cdf0e10cSrcweir             fillEntrySeq( aEntrySeq, xMapper, SPECIAL ) &&
1068*cdf0e10cSrcweir             initOpCode( OPCODE_PUSH,          aEntrySeq, PUSH ) &&
1069*cdf0e10cSrcweir             initOpCode( OPCODE_MISSING,       aEntrySeq, MISSING ) &&
1070*cdf0e10cSrcweir             initOpCode( OPCODE_SPACES,        aEntrySeq, SPACES ) &&
1071*cdf0e10cSrcweir             initOpCode( OPCODE_NAME,          aEntrySeq, NAME ) &&
1072*cdf0e10cSrcweir             initOpCode( OPCODE_DBAREA,        aEntrySeq, DB_AREA ) &&
1073*cdf0e10cSrcweir             initOpCode( OPCODE_NLR,           aEntrySeq, COL_ROW_NAME ) &&
1074*cdf0e10cSrcweir             initOpCode( OPCODE_MACRO,         aEntrySeq, MACRO ) &&
1075*cdf0e10cSrcweir             initOpCode( OPCODE_BAD,           aEntrySeq, BAD ) &&
1076*cdf0e10cSrcweir             initOpCode( OPCODE_NONAME,        aEntrySeq, NO_NAME ) &&
1077*cdf0e10cSrcweir             // separators
1078*cdf0e10cSrcweir             fillTokenMap( aTokenMap, aEntrySeq, xMapper, SEPARATORS ) &&
1079*cdf0e10cSrcweir             initOpCode( OPCODE_OPEN,          aTokenMap, API_TOKEN_OPEN,  '('  ) &&
1080*cdf0e10cSrcweir             initOpCode( OPCODE_CLOSE,         aTokenMap, API_TOKEN_CLOSE, ')'  ) &&
1081*cdf0e10cSrcweir             initOpCode( OPCODE_SEP,           aTokenMap, API_TOKEN_SEP,   ','  ) &&
1082*cdf0e10cSrcweir             // array separators
1083*cdf0e10cSrcweir             fillTokenMap( aTokenMap, aEntrySeq, xMapper, ARRAY_SEPARATORS ) &&
1084*cdf0e10cSrcweir             initOpCode( OPCODE_ARRAY_OPEN,    aTokenMap, API_TOKEN_ARRAY_OPEN,   '{'  ) &&
1085*cdf0e10cSrcweir             initOpCode( OPCODE_ARRAY_CLOSE,   aTokenMap, API_TOKEN_ARRAY_CLOSE,  '}'  ) &&
1086*cdf0e10cSrcweir             initOpCode( OPCODE_ARRAY_ROWSEP,  aTokenMap, API_TOKEN_ARRAY_ROWSEP, ';'  ) &&
1087*cdf0e10cSrcweir             initOpCode( OPCODE_ARRAY_COLSEP,  aTokenMap, API_TOKEN_ARRAY_COLSEP, ','  ) &&
1088*cdf0e10cSrcweir             // unary operators
1089*cdf0e10cSrcweir             fillTokenMap( aTokenMap, aEntrySeq, xMapper, UNARY_OPERATORS ) &&
1090*cdf0e10cSrcweir             initOpCode( OPCODE_PLUS_SIGN,     aTokenMap, '+',  '\0' ) && // same op-code as OPCODE_ADD
1091*cdf0e10cSrcweir             initOpCode( OPCODE_MINUS_SIGN,    aTokenMap, '-',  '-'  ) &&
1092*cdf0e10cSrcweir             initOpCode( OPCODE_PERCENT,       aTokenMap, '%',  '%'  ) &&
1093*cdf0e10cSrcweir             // binary operators
1094*cdf0e10cSrcweir             fillTokenMap( aTokenMap, aEntrySeq, xMapper, BINARY_OPERATORS ) &&
1095*cdf0e10cSrcweir             initOpCode( OPCODE_ADD,           aTokenMap, '+',  '+'  ) &&
1096*cdf0e10cSrcweir             initOpCode( OPCODE_SUB,           aTokenMap, '-',  '-'  ) &&
1097*cdf0e10cSrcweir             initOpCode( OPCODE_MULT,          aTokenMap, '*',  '*'  ) &&
1098*cdf0e10cSrcweir             initOpCode( OPCODE_DIV,           aTokenMap, '/',  '/'  ) &&
1099*cdf0e10cSrcweir             initOpCode( OPCODE_POWER,         aTokenMap, '^',  '^'  ) &&
1100*cdf0e10cSrcweir             initOpCode( OPCODE_CONCAT,        aTokenMap, '&',  '&'  ) &&
1101*cdf0e10cSrcweir             initOpCode( OPCODE_EQUAL,         aTokenMap, '=',  '='  ) &&
1102*cdf0e10cSrcweir             initOpCode( OPCODE_NOT_EQUAL,     aTokenMap, "<>", "<>" ) &&
1103*cdf0e10cSrcweir             initOpCode( OPCODE_LESS,          aTokenMap, '<',  '<'  ) &&
1104*cdf0e10cSrcweir             initOpCode( OPCODE_LESS_EQUAL,    aTokenMap, "<=", "<=" ) &&
1105*cdf0e10cSrcweir             initOpCode( OPCODE_GREATER,       aTokenMap, '>',  '>'  ) &&
1106*cdf0e10cSrcweir             initOpCode( OPCODE_GREATER_EQUAL, aTokenMap, ">=", ">=" ) &&
1107*cdf0e10cSrcweir             initOpCode( OPCODE_INTERSECT,     aTokenMap, '!',  ' '  ) &&
1108*cdf0e10cSrcweir             initOpCode( OPCODE_LIST,          aTokenMap, '~',  ','  ) &&
1109*cdf0e10cSrcweir             initOpCode( OPCODE_RANGE,         aTokenMap, ':',  ':'  ) &&
1110*cdf0e10cSrcweir             // functions
1111*cdf0e10cSrcweir             fillFuncTokenMaps( aTokenMap, aExtFuncTokenMap, aEntrySeq, xMapper ) &&
1112*cdf0e10cSrcweir             initFuncOpCodes( aTokenMap, aExtFuncTokenMap, rFuncInfos ) &&
1113*cdf0e10cSrcweir             initOpCode( OPCODE_DDE,           aTokenMap, "DDE", 0 );
1114*cdf0e10cSrcweir 
1115*cdf0e10cSrcweir         OSL_ENSURE( bIsValid, "OpCodeProviderImpl::OpCodeProviderImpl - opcodes not initialized" );
1116*cdf0e10cSrcweir         (void)bIsValid;
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir         // OPCODE_PLUS_SIGN and OPCODE_ADD should be equal, otherwise "+" has to be passed above
1119*cdf0e10cSrcweir         OSL_ENSURE( OPCODE_PLUS_SIGN == OPCODE_ADD, "OpCodeProviderImpl::OpCodeProviderImpl - need opcode mapping for OPCODE_PLUS_SIGN" );
1120*cdf0e10cSrcweir     }
1121*cdf0e10cSrcweir     catch( Exception& )
1122*cdf0e10cSrcweir     {
1123*cdf0e10cSrcweir         OSL_ENSURE( false, "OpCodeProviderImpl::OpCodeProviderImpl - cannot receive formula opcode mapper" );
1124*cdf0e10cSrcweir     }
1125*cdf0e10cSrcweir }
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir bool OpCodeProviderImpl::fillEntrySeq( OpCodeEntrySequence& orEntrySeq,
1128*cdf0e10cSrcweir         const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup )
1129*cdf0e10cSrcweir {
1130*cdf0e10cSrcweir     try
1131*cdf0e10cSrcweir     {
1132*cdf0e10cSrcweir         orEntrySeq = rxMapper->getAvailableMappings( ::com::sun::star::sheet::FormulaLanguage::ODFF, nMapGroup );
1133*cdf0e10cSrcweir         return orEntrySeq.hasElements();
1134*cdf0e10cSrcweir     }
1135*cdf0e10cSrcweir     catch( Exception& )
1136*cdf0e10cSrcweir     {
1137*cdf0e10cSrcweir     }
1138*cdf0e10cSrcweir     return false;
1139*cdf0e10cSrcweir }
1140*cdf0e10cSrcweir 
1141*cdf0e10cSrcweir bool OpCodeProviderImpl::fillTokenMap( ApiTokenMap& orTokenMap, OpCodeEntrySequence& orEntrySeq,
1142*cdf0e10cSrcweir         const Reference< XFormulaOpCodeMapper >& rxMapper, sal_Int32 nMapGroup )
1143*cdf0e10cSrcweir {
1144*cdf0e10cSrcweir     orTokenMap.clear();
1145*cdf0e10cSrcweir     if( fillEntrySeq( orEntrySeq, rxMapper, nMapGroup ) )
1146*cdf0e10cSrcweir     {
1147*cdf0e10cSrcweir         const FormulaOpCodeMapEntry* pEntry = orEntrySeq.getConstArray();
1148*cdf0e10cSrcweir         const FormulaOpCodeMapEntry* pEntryEnd = pEntry + orEntrySeq.getLength();
1149*cdf0e10cSrcweir         for( ; pEntry != pEntryEnd; ++pEntry )
1150*cdf0e10cSrcweir             orTokenMap[ pEntry->Name ] = pEntry->Token;
1151*cdf0e10cSrcweir     }
1152*cdf0e10cSrcweir     return orEntrySeq.hasElements();
1153*cdf0e10cSrcweir }
1154*cdf0e10cSrcweir 
1155*cdf0e10cSrcweir bool OpCodeProviderImpl::fillFuncTokenMaps( ApiTokenMap& orIntFuncTokenMap, ApiTokenMap& orExtFuncTokenMap, OpCodeEntrySequence& orEntrySeq, const Reference< XFormulaOpCodeMapper >& rxMapper ) const
1156*cdf0e10cSrcweir {
1157*cdf0e10cSrcweir     orIntFuncTokenMap.clear();
1158*cdf0e10cSrcweir     orExtFuncTokenMap.clear();
1159*cdf0e10cSrcweir     if( fillEntrySeq( orEntrySeq, rxMapper, ::com::sun::star::sheet::FormulaMapGroup::FUNCTIONS ) )
1160*cdf0e10cSrcweir     {
1161*cdf0e10cSrcweir         const FormulaOpCodeMapEntry* pEntry = orEntrySeq.getConstArray();
1162*cdf0e10cSrcweir         const FormulaOpCodeMapEntry* pEntryEnd = pEntry + orEntrySeq.getLength();
1163*cdf0e10cSrcweir         for( ; pEntry != pEntryEnd; ++pEntry )
1164*cdf0e10cSrcweir             ((pEntry->Token.OpCode == OPCODE_EXTERNAL) ? orExtFuncTokenMap : orIntFuncTokenMap)[ pEntry->Name ] = pEntry->Token;
1165*cdf0e10cSrcweir     }
1166*cdf0e10cSrcweir     return orEntrySeq.hasElements();
1167*cdf0e10cSrcweir }
1168*cdf0e10cSrcweir 
1169*cdf0e10cSrcweir bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const OpCodeEntrySequence& rEntrySeq, sal_Int32 nSpecialId )
1170*cdf0e10cSrcweir {
1171*cdf0e10cSrcweir     if( (0 <= nSpecialId) && (nSpecialId < rEntrySeq.getLength()) )
1172*cdf0e10cSrcweir     {
1173*cdf0e10cSrcweir         ornOpCode = rEntrySeq[ nSpecialId ].Token.OpCode;
1174*cdf0e10cSrcweir         return true;
1175*cdf0e10cSrcweir     }
1176*cdf0e10cSrcweir     OSL_ENSURE( false,
1177*cdf0e10cSrcweir         OStringBuffer( "OpCodeProviderImpl::initOpCode - opcode for special offset " ).
1178*cdf0e10cSrcweir         append( nSpecialId ).append( " not found" ).getStr() );
1179*cdf0e10cSrcweir     return false;
1180*cdf0e10cSrcweir }
1181*cdf0e10cSrcweir 
1182*cdf0e10cSrcweir bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const OUString& rOdfName, const OUString& rOoxName )
1183*cdf0e10cSrcweir {
1184*cdf0e10cSrcweir     ApiTokenMap::const_iterator aIt = rTokenMap.find( rOdfName );
1185*cdf0e10cSrcweir     if( aIt != rTokenMap.end() )
1186*cdf0e10cSrcweir     {
1187*cdf0e10cSrcweir         ornOpCode = aIt->second.OpCode;
1188*cdf0e10cSrcweir         if( rOoxName.getLength() > 0 )
1189*cdf0e10cSrcweir         {
1190*cdf0e10cSrcweir             FormulaOpCodeMapEntry aEntry;
1191*cdf0e10cSrcweir             aEntry.Name = rOoxName;
1192*cdf0e10cSrcweir             aEntry.Token.OpCode = ornOpCode;
1193*cdf0e10cSrcweir             maParserMap.push_back( aEntry );
1194*cdf0e10cSrcweir         }
1195*cdf0e10cSrcweir         return true;
1196*cdf0e10cSrcweir     }
1197*cdf0e10cSrcweir     OSL_ENSURE( false,
1198*cdf0e10cSrcweir         OStringBuffer( "OpCodeProviderImpl::initOpCode - opcode for \"" ).
1199*cdf0e10cSrcweir         append( OUStringToOString( rOdfName, RTL_TEXTENCODING_ASCII_US ) ).
1200*cdf0e10cSrcweir         append( "\" not found" ).getStr() );
1201*cdf0e10cSrcweir     return false;
1202*cdf0e10cSrcweir }
1203*cdf0e10cSrcweir 
1204*cdf0e10cSrcweir bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, const sal_Char* pcOdfName, const sal_Char* pcOoxName )
1205*cdf0e10cSrcweir {
1206*cdf0e10cSrcweir     OUString aOoxName;
1207*cdf0e10cSrcweir     if( pcOoxName ) aOoxName = OUString::createFromAscii( pcOoxName );
1208*cdf0e10cSrcweir     return initOpCode( ornOpCode, rTokenMap, OUString::createFromAscii( pcOdfName ), aOoxName );
1209*cdf0e10cSrcweir }
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir bool OpCodeProviderImpl::initOpCode( sal_Int32& ornOpCode, const ApiTokenMap& rTokenMap, sal_Unicode cOdfName, sal_Unicode cOoxName )
1212*cdf0e10cSrcweir {
1213*cdf0e10cSrcweir     OUString aOoxName;
1214*cdf0e10cSrcweir     if( cOoxName ) aOoxName = OUString( cOoxName );
1215*cdf0e10cSrcweir     return initOpCode( ornOpCode, rTokenMap, OUString( cOdfName ), aOoxName );
1216*cdf0e10cSrcweir }
1217*cdf0e10cSrcweir 
1218*cdf0e10cSrcweir bool OpCodeProviderImpl::initFuncOpCode( FunctionInfo& orFuncInfo, const ApiTokenMap& rFuncTokenMap )
1219*cdf0e10cSrcweir {
1220*cdf0e10cSrcweir     bool bIsValid = false;
1221*cdf0e10cSrcweir     if( orFuncInfo.maOdfFuncName.getLength() > 0 )
1222*cdf0e10cSrcweir     {
1223*cdf0e10cSrcweir         ApiTokenMap::const_iterator aIt = rFuncTokenMap.find( orFuncInfo.maOdfFuncName );
1224*cdf0e10cSrcweir         if( aIt != rFuncTokenMap.end() )
1225*cdf0e10cSrcweir         {
1226*cdf0e10cSrcweir             orFuncInfo.mnApiOpCode = aIt->second.OpCode;
1227*cdf0e10cSrcweir             bIsValid =
1228*cdf0e10cSrcweir                 (orFuncInfo.mnApiOpCode >= 0) &&
1229*cdf0e10cSrcweir                 (orFuncInfo.mnApiOpCode != OPCODE_UNKNOWN) &&
1230*cdf0e10cSrcweir                 (orFuncInfo.mnApiOpCode != OPCODE_NONAME);
1231*cdf0e10cSrcweir             OSL_ENSURE( bIsValid,
1232*cdf0e10cSrcweir                 OStringBuffer( "OpCodeProviderImpl::initFuncOpCode - no valid opcode for ODF function \"" ).
1233*cdf0e10cSrcweir                 append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ).
1234*cdf0e10cSrcweir                 append( '"' ).getStr() );
1235*cdf0e10cSrcweir 
1236*cdf0e10cSrcweir             if( bIsValid && (orFuncInfo.mnApiOpCode == OPCODE_EXTERNAL) )
1237*cdf0e10cSrcweir             {
1238*cdf0e10cSrcweir                 bIsValid = (aIt->second.Data >>= orFuncInfo.maExtProgName) && (orFuncInfo.maExtProgName.getLength() > 0);
1239*cdf0e10cSrcweir                 OSL_ENSURE( bIsValid,
1240*cdf0e10cSrcweir                     OStringBuffer( "OpCodeProviderImpl::initFuncOpCode - no programmatical name for external function \"" ).
1241*cdf0e10cSrcweir                     append( OUStringToOString( orFuncInfo.maOdfFuncName, RTL_TEXTENCODING_ASCII_US ) ).
1242*cdf0e10cSrcweir                     append( '"' ).getStr() );
1243*cdf0e10cSrcweir             }
1244*cdf0e10cSrcweir 
1245*cdf0e10cSrcweir             // add to parser map, if OOXML function name exists
1246*cdf0e10cSrcweir             if( bIsValid && (orFuncInfo.maOoxFuncName.getLength() > 0) )
1247*cdf0e10cSrcweir             {
1248*cdf0e10cSrcweir                 // create the parser map entry
1249*cdf0e10cSrcweir                 FormulaOpCodeMapEntry aEntry;
1250*cdf0e10cSrcweir                 aEntry.Name = orFuncInfo.maOoxFuncName;
1251*cdf0e10cSrcweir                 aEntry.Token = aIt->second;
1252*cdf0e10cSrcweir                 maParserMap.push_back( aEntry );
1253*cdf0e10cSrcweir             }
1254*cdf0e10cSrcweir         }
1255*cdf0e10cSrcweir         else
1256*cdf0e10cSrcweir         {
1257*cdf0e10cSrcweir             // ignore entries for functions unknown by Calc *and* by Excel
1258*cdf0e10cSrcweir             bIsValid = orFuncInfo.maOoxFuncName.getLength() == 0;
1259*cdf0e10cSrcweir         }
1260*cdf0e10cSrcweir     }
1261*cdf0e10cSrcweir     else if( orFuncInfo.mnBiffFuncId == BIFF_FUNC_EXTERNCALL )
1262*cdf0e10cSrcweir     {
1263*cdf0e10cSrcweir         orFuncInfo.mnApiOpCode = OPCODE_EXTERNAL;
1264*cdf0e10cSrcweir         bIsValid = true;
1265*cdf0e10cSrcweir     }
1266*cdf0e10cSrcweir     else if( orFuncInfo.maOoxFuncName.getLength() > 0 )
1267*cdf0e10cSrcweir     {
1268*cdf0e10cSrcweir         orFuncInfo.mnApiOpCode = OPCODE_BAD;
1269*cdf0e10cSrcweir         bIsValid = true;
1270*cdf0e10cSrcweir     }
1271*cdf0e10cSrcweir 
1272*cdf0e10cSrcweir     if( !bIsValid || (orFuncInfo.mnApiOpCode == OPCODE_UNKNOWN) || (orFuncInfo.mnApiOpCode < 0) )
1273*cdf0e10cSrcweir         orFuncInfo.mnApiOpCode = OPCODE_NONAME;
1274*cdf0e10cSrcweir     return bIsValid;
1275*cdf0e10cSrcweir }
1276*cdf0e10cSrcweir 
1277*cdf0e10cSrcweir bool OpCodeProviderImpl::initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, const ApiTokenMap& rExtFuncTokenMap, const FunctionInfoVector& rFuncInfos )
1278*cdf0e10cSrcweir {
1279*cdf0e10cSrcweir     bool bIsValid = true;
1280*cdf0e10cSrcweir     for( FunctionInfoVector::const_iterator aIt = rFuncInfos.begin(), aEnd = rFuncInfos.end(); aIt != aEnd; ++aIt )
1281*cdf0e10cSrcweir     {
1282*cdf0e10cSrcweir         FunctionInfoRef xFuncInfo = *aIt;
1283*cdf0e10cSrcweir         // set API opcode from ODF function name
1284*cdf0e10cSrcweir         bIsValid &= initFuncOpCode( *xFuncInfo, xFuncInfo->mbExternal ? rExtFuncTokenMap : rIntFuncTokenMap );
1285*cdf0e10cSrcweir         // insert the function info into the maps
1286*cdf0e10cSrcweir         if( (xFuncInfo->mnApiOpCode != OPCODE_NONAME) && (xFuncInfo->mnApiOpCode != OPCODE_BAD) )
1287*cdf0e10cSrcweir         {
1288*cdf0e10cSrcweir             if( (xFuncInfo->mnApiOpCode == OPCODE_EXTERNAL) && (xFuncInfo->maExtProgName.getLength() > 0) )
1289*cdf0e10cSrcweir                 maExtProgFuncs[ xFuncInfo->maExtProgName ] = xFuncInfo;
1290*cdf0e10cSrcweir             else
1291*cdf0e10cSrcweir                 maOpCodeFuncs[ xFuncInfo->mnApiOpCode ] = xFuncInfo;
1292*cdf0e10cSrcweir         }
1293*cdf0e10cSrcweir     }
1294*cdf0e10cSrcweir     return bIsValid;
1295*cdf0e10cSrcweir }
1296*cdf0e10cSrcweir 
1297*cdf0e10cSrcweir // ----------------------------------------------------------------------------
1298*cdf0e10cSrcweir 
1299*cdf0e10cSrcweir OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxModelFactory,
1300*cdf0e10cSrcweir         FilterType eFilter, BiffType eBiff, bool bImportFilter ) :
1301*cdf0e10cSrcweir     FunctionProvider( eFilter, eBiff, bImportFilter ),
1302*cdf0e10cSrcweir     mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxModelFactory ) )
1303*cdf0e10cSrcweir {
1304*cdf0e10cSrcweir }
1305*cdf0e10cSrcweir 
1306*cdf0e10cSrcweir OpCodeProvider::~OpCodeProvider()
1307*cdf0e10cSrcweir {
1308*cdf0e10cSrcweir }
1309*cdf0e10cSrcweir 
1310*cdf0e10cSrcweir const ApiOpCodes& OpCodeProvider::getOpCodes() const
1311*cdf0e10cSrcweir {
1312*cdf0e10cSrcweir     return *mxOpCodeImpl;
1313*cdf0e10cSrcweir }
1314*cdf0e10cSrcweir 
1315*cdf0e10cSrcweir const FunctionInfo* OpCodeProvider::getFuncInfoFromApiToken( const ApiToken& rToken ) const
1316*cdf0e10cSrcweir {
1317*cdf0e10cSrcweir     const FunctionInfo* pFuncInfo = 0;
1318*cdf0e10cSrcweir     if( (rToken.OpCode == mxOpCodeImpl->OPCODE_EXTERNAL) && rToken.Data.has< OUString >() )
1319*cdf0e10cSrcweir         pFuncInfo = mxOpCodeImpl->maExtProgFuncs.get( rToken.Data.get< OUString >() ).get();
1320*cdf0e10cSrcweir     else if( (rToken.OpCode == mxOpCodeImpl->OPCODE_MACRO) && rToken.Data.has< OUString >() )
1321*cdf0e10cSrcweir         pFuncInfo = getFuncInfoFromMacroName( rToken.Data.get< OUString >() );
1322*cdf0e10cSrcweir     else if( (rToken.OpCode == mxOpCodeImpl->OPCODE_BAD) && rToken.Data.has< OUString >() )
1323*cdf0e10cSrcweir         pFuncInfo = getFuncInfoFromOoxFuncName( rToken.Data.get< OUString >() );
1324*cdf0e10cSrcweir     else
1325*cdf0e10cSrcweir         pFuncInfo = mxOpCodeImpl->maOpCodeFuncs.get( rToken.OpCode ).get();
1326*cdf0e10cSrcweir     return pFuncInfo;
1327*cdf0e10cSrcweir }
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir Sequence< FormulaOpCodeMapEntry > OpCodeProvider::getOoxParserMap() const
1330*cdf0e10cSrcweir {
1331*cdf0e10cSrcweir     return ContainerHelper::vectorToSequence( mxOpCodeImpl->maParserMap );
1332*cdf0e10cSrcweir }
1333*cdf0e10cSrcweir 
1334*cdf0e10cSrcweir // API formula parser wrapper =================================================
1335*cdf0e10cSrcweir 
1336*cdf0e10cSrcweir ApiParserWrapper::ApiParserWrapper(
1337*cdf0e10cSrcweir         const Reference< XMultiServiceFactory >& rxModelFactory, const OpCodeProvider& rOpCodeProv ) :
1338*cdf0e10cSrcweir     OpCodeProvider( rOpCodeProv )
1339*cdf0e10cSrcweir {
1340*cdf0e10cSrcweir     if( rxModelFactory.is() ) try
1341*cdf0e10cSrcweir     {
1342*cdf0e10cSrcweir         mxParser.set( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW );
1343*cdf0e10cSrcweir     }
1344*cdf0e10cSrcweir     catch( Exception& )
1345*cdf0e10cSrcweir     {
1346*cdf0e10cSrcweir     }
1347*cdf0e10cSrcweir     OSL_ENSURE( mxParser.is(), "ApiParserWrapper::ApiParserWrapper - cannot create API formula parser object" );
1348*cdf0e10cSrcweir     maParserProps.set( mxParser );
1349*cdf0e10cSrcweir     maParserProps.setProperty( PROP_CompileEnglish, true );
1350*cdf0e10cSrcweir     maParserProps.setProperty( PROP_FormulaConvention, ::com::sun::star::sheet::AddressConvention::XL_OOX );
1351*cdf0e10cSrcweir     maParserProps.setProperty( PROP_IgnoreLeadingSpaces, false );
1352*cdf0e10cSrcweir     maParserProps.setProperty( PROP_OpCodeMap, getOoxParserMap() );
1353*cdf0e10cSrcweir }
1354*cdf0e10cSrcweir 
1355*cdf0e10cSrcweir ApiTokenSequence ApiParserWrapper::parseFormula( const OUString& rFormula, const CellAddress& rRefPos )
1356*cdf0e10cSrcweir {
1357*cdf0e10cSrcweir     ApiTokenSequence aTokenSeq;
1358*cdf0e10cSrcweir     if( mxParser.is() ) try
1359*cdf0e10cSrcweir     {
1360*cdf0e10cSrcweir         aTokenSeq = mxParser->parseFormula( rFormula, rRefPos );
1361*cdf0e10cSrcweir     }
1362*cdf0e10cSrcweir     catch( Exception& )
1363*cdf0e10cSrcweir     {
1364*cdf0e10cSrcweir     }
1365*cdf0e10cSrcweir     return aTokenSeq;
1366*cdf0e10cSrcweir }
1367*cdf0e10cSrcweir 
1368*cdf0e10cSrcweir // formula parser/printer base class for filters ==============================
1369*cdf0e10cSrcweir 
1370*cdf0e10cSrcweir namespace {
1371*cdf0e10cSrcweir 
1372*cdf0e10cSrcweir bool lclConvertToCellAddress( CellAddress& orAddress, const SingleReference& rSingleRef, sal_Int32 nForbiddenFlags, sal_Int32 nFilterBySheet )
1373*cdf0e10cSrcweir {
1374*cdf0e10cSrcweir     orAddress = CellAddress( static_cast< sal_Int16 >( rSingleRef.Sheet ),
1375*cdf0e10cSrcweir         rSingleRef.Column, rSingleRef.Row );
1376*cdf0e10cSrcweir     return
1377*cdf0e10cSrcweir         !getFlag( rSingleRef.Flags, nForbiddenFlags ) &&
1378*cdf0e10cSrcweir         ((nFilterBySheet < 0) || (nFilterBySheet == rSingleRef.Sheet));
1379*cdf0e10cSrcweir }
1380*cdf0e10cSrcweir 
1381*cdf0e10cSrcweir bool lclConvertToCellRange( CellRangeAddress& orRange, const ComplexReference& rComplexRef, sal_Int32 nForbiddenFlags, sal_Int32 nFilterBySheet )
1382*cdf0e10cSrcweir {
1383*cdf0e10cSrcweir     orRange = CellRangeAddress( static_cast< sal_Int16 >( rComplexRef.Reference1.Sheet ),
1384*cdf0e10cSrcweir         rComplexRef.Reference1.Column, rComplexRef.Reference1.Row,
1385*cdf0e10cSrcweir         rComplexRef.Reference2.Column, rComplexRef.Reference2.Row );
1386*cdf0e10cSrcweir     return
1387*cdf0e10cSrcweir         !getFlag( rComplexRef.Reference1.Flags, nForbiddenFlags ) &&
1388*cdf0e10cSrcweir         !getFlag( rComplexRef.Reference2.Flags, nForbiddenFlags ) &&
1389*cdf0e10cSrcweir         (rComplexRef.Reference1.Sheet == rComplexRef.Reference2.Sheet) &&
1390*cdf0e10cSrcweir         ((nFilterBySheet < 0) || (nFilterBySheet == rComplexRef.Reference1.Sheet));
1391*cdf0e10cSrcweir }
1392*cdf0e10cSrcweir 
1393*cdf0e10cSrcweir enum TokenToRangeListState { STATE_REF, STATE_SEP, STATE_OPEN, STATE_CLOSE, STATE_ERROR };
1394*cdf0e10cSrcweir 
1395*cdf0e10cSrcweir TokenToRangeListState lclProcessRef( ApiCellRangeList& orRanges, const Any& rData, bool bAllowRelative, sal_Int32 nFilterBySheet )
1396*cdf0e10cSrcweir {
1397*cdf0e10cSrcweir     using namespace ::com::sun::star::sheet::ReferenceFlags;
1398*cdf0e10cSrcweir     const sal_Int32 FORBIDDEN_FLAGS_DEL = COLUMN_DELETED | ROW_DELETED | SHEET_DELETED;
1399*cdf0e10cSrcweir     const sal_Int32 FORBIDDEN_FLAGS_REL = FORBIDDEN_FLAGS_DEL | COLUMN_RELATIVE | ROW_RELATIVE | SHEET_RELATIVE | RELATIVE_NAME;
1400*cdf0e10cSrcweir 
1401*cdf0e10cSrcweir     sal_Int32 nForbiddenFlags = bAllowRelative ? FORBIDDEN_FLAGS_DEL : FORBIDDEN_FLAGS_REL;
1402*cdf0e10cSrcweir     SingleReference aSingleRef;
1403*cdf0e10cSrcweir     if( rData >>= aSingleRef )
1404*cdf0e10cSrcweir     {
1405*cdf0e10cSrcweir         CellAddress aAddress;
1406*cdf0e10cSrcweir         // ignore invalid addresses (with #REF! errors), but do not stop parsing
1407*cdf0e10cSrcweir         if( lclConvertToCellAddress( aAddress, aSingleRef, nForbiddenFlags, nFilterBySheet ) )
1408*cdf0e10cSrcweir             orRanges.push_back( CellRangeAddress( aAddress.Sheet, aAddress.Column, aAddress.Row, aAddress.Column, aAddress.Row ) );
1409*cdf0e10cSrcweir         return STATE_REF;
1410*cdf0e10cSrcweir     }
1411*cdf0e10cSrcweir     ComplexReference aComplexRef;
1412*cdf0e10cSrcweir     if( rData >>= aComplexRef )
1413*cdf0e10cSrcweir     {
1414*cdf0e10cSrcweir         CellRangeAddress aRange;
1415*cdf0e10cSrcweir         // ignore invalid ranges (with #REF! errors), but do not stop parsing
1416*cdf0e10cSrcweir         if( lclConvertToCellRange( aRange, aComplexRef, nForbiddenFlags, nFilterBySheet ) )
1417*cdf0e10cSrcweir             orRanges.push_back( aRange );
1418*cdf0e10cSrcweir         return STATE_REF;
1419*cdf0e10cSrcweir     }
1420*cdf0e10cSrcweir     return STATE_ERROR;
1421*cdf0e10cSrcweir }
1422*cdf0e10cSrcweir 
1423*cdf0e10cSrcweir TokenToRangeListState lclProcessOpen( sal_Int32& ornParenLevel )
1424*cdf0e10cSrcweir {
1425*cdf0e10cSrcweir     ++ornParenLevel;
1426*cdf0e10cSrcweir     return STATE_OPEN;
1427*cdf0e10cSrcweir }
1428*cdf0e10cSrcweir 
1429*cdf0e10cSrcweir TokenToRangeListState lclProcessClose( sal_Int32& ornParenLevel )
1430*cdf0e10cSrcweir {
1431*cdf0e10cSrcweir     --ornParenLevel;
1432*cdf0e10cSrcweir     return (ornParenLevel >= 0) ? STATE_CLOSE : STATE_ERROR;
1433*cdf0e10cSrcweir }
1434*cdf0e10cSrcweir 
1435*cdf0e10cSrcweir } // namespace
1436*cdf0e10cSrcweir 
1437*cdf0e10cSrcweir // ----------------------------------------------------------------------------
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir FormulaProcessorBase::FormulaProcessorBase( const WorkbookHelper& rHelper ) :
1440*cdf0e10cSrcweir     OpCodeProvider( rHelper.getBaseFilter().getModelFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ),
1441*cdf0e10cSrcweir     ApiOpCodes( getOpCodes() ),
1442*cdf0e10cSrcweir     WorkbookHelper( rHelper )
1443*cdf0e10cSrcweir {
1444*cdf0e10cSrcweir }
1445*cdf0e10cSrcweir 
1446*cdf0e10cSrcweir // ----------------------------------------------------------------------------
1447*cdf0e10cSrcweir 
1448*cdf0e10cSrcweir OUString FormulaProcessorBase::generateAddress2dString( const CellAddress& rAddress, bool bAbsolute )
1449*cdf0e10cSrcweir {
1450*cdf0e10cSrcweir     return generateAddress2dString( BinAddress( rAddress ), bAbsolute );
1451*cdf0e10cSrcweir }
1452*cdf0e10cSrcweir 
1453*cdf0e10cSrcweir OUString FormulaProcessorBase::generateAddress2dString( const BinAddress& rAddress, bool bAbsolute )
1454*cdf0e10cSrcweir {
1455*cdf0e10cSrcweir     OUStringBuffer aBuffer;
1456*cdf0e10cSrcweir     // column
1457*cdf0e10cSrcweir     for( sal_Int32 nTemp = rAddress.mnCol; nTemp >= 0; (nTemp /= 26) -= 1 )
1458*cdf0e10cSrcweir         aBuffer.insert( 0, sal_Unicode( 'A' + (nTemp % 26) ) );
1459*cdf0e10cSrcweir     if( bAbsolute )
1460*cdf0e10cSrcweir         aBuffer.insert( 0, sal_Unicode( '$' ) );
1461*cdf0e10cSrcweir     // row
1462*cdf0e10cSrcweir     if( bAbsolute )
1463*cdf0e10cSrcweir         aBuffer.append( sal_Unicode( '$' ) );
1464*cdf0e10cSrcweir     aBuffer.append( static_cast< sal_Int32 >( rAddress.mnRow + 1 ) );
1465*cdf0e10cSrcweir     return aBuffer.makeStringAndClear();
1466*cdf0e10cSrcweir }
1467*cdf0e10cSrcweir 
1468*cdf0e10cSrcweir OUString FormulaProcessorBase::generateRange2dString( const CellRangeAddress& rRange, bool bAbsolute )
1469*cdf0e10cSrcweir {
1470*cdf0e10cSrcweir     return generateRange2dString( BinRange( rRange ), bAbsolute );
1471*cdf0e10cSrcweir }
1472*cdf0e10cSrcweir 
1473*cdf0e10cSrcweir OUString FormulaProcessorBase::generateRange2dString( const BinRange& rRange, bool bAbsolute )
1474*cdf0e10cSrcweir {
1475*cdf0e10cSrcweir     OUStringBuffer aBuffer( generateAddress2dString( rRange.maFirst, bAbsolute ) );
1476*cdf0e10cSrcweir     if( (rRange.getColCount() > 1) || (rRange.getRowCount() > 1) )
1477*cdf0e10cSrcweir         aBuffer.append( sal_Unicode( ':' ) ).append( generateAddress2dString( rRange.maLast, bAbsolute ) );
1478*cdf0e10cSrcweir     return aBuffer.makeStringAndClear();
1479*cdf0e10cSrcweir }
1480*cdf0e10cSrcweir 
1481*cdf0e10cSrcweir OUString FormulaProcessorBase::generateRangeList2dString( const ApiCellRangeList& rRanges,
1482*cdf0e10cSrcweir         bool bAbsolute, sal_Unicode cSeparator, bool bEncloseMultiple )
1483*cdf0e10cSrcweir {
1484*cdf0e10cSrcweir     OUStringBuffer aBuffer;
1485*cdf0e10cSrcweir     for( ApiCellRangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt )
1486*cdf0e10cSrcweir     {
1487*cdf0e10cSrcweir         if( aBuffer.getLength() > 0 )
1488*cdf0e10cSrcweir             aBuffer.append( cSeparator );
1489*cdf0e10cSrcweir         aBuffer.append( generateRange2dString( *aIt, bAbsolute ) );
1490*cdf0e10cSrcweir     }
1491*cdf0e10cSrcweir     if( bEncloseMultiple && (rRanges.size() > 1) )
1492*cdf0e10cSrcweir         aBuffer.insert( 0, sal_Unicode( '(' ) ).append( sal_Unicode( ')' ) );
1493*cdf0e10cSrcweir     return aBuffer.makeStringAndClear();
1494*cdf0e10cSrcweir }
1495*cdf0e10cSrcweir 
1496*cdf0e10cSrcweir // ----------------------------------------------------------------------------
1497*cdf0e10cSrcweir 
1498*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiAddressString( const CellAddress& rAddress ) const
1499*cdf0e10cSrcweir {
1500*cdf0e10cSrcweir     OUString aCellName;
1501*cdf0e10cSrcweir     PropertySet aCellProp( getCellFromDoc( rAddress ) );
1502*cdf0e10cSrcweir     aCellProp.getProperty( aCellName, PROP_AbsoluteName );
1503*cdf0e10cSrcweir     OSL_ENSURE( aCellName.getLength() > 0, "FormulaProcessorBase::generateApiAddressString - cannot create cell address string" );
1504*cdf0e10cSrcweir     return aCellName;
1505*cdf0e10cSrcweir }
1506*cdf0e10cSrcweir 
1507*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiRangeString( const CellRangeAddress& rRange ) const
1508*cdf0e10cSrcweir {
1509*cdf0e10cSrcweir     OUString aRangeName;
1510*cdf0e10cSrcweir     PropertySet aRangeProp( getCellRangeFromDoc( rRange ) );
1511*cdf0e10cSrcweir     aRangeProp.getProperty( aRangeName, PROP_AbsoluteName );
1512*cdf0e10cSrcweir     OSL_ENSURE( aRangeName.getLength() > 0, "FormulaProcessorBase::generateApiRangeString - cannot create cell range string" );
1513*cdf0e10cSrcweir     return aRangeName;
1514*cdf0e10cSrcweir }
1515*cdf0e10cSrcweir 
1516*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiRangeListString( const ApiCellRangeList& rRanges ) const
1517*cdf0e10cSrcweir {
1518*cdf0e10cSrcweir     OUStringBuffer aBuffer;
1519*cdf0e10cSrcweir     for( ApiCellRangeList::const_iterator aIt = rRanges.begin(), aEnd = rRanges.end(); aIt != aEnd; ++aIt )
1520*cdf0e10cSrcweir     {
1521*cdf0e10cSrcweir         OUString aRangeName = generateApiRangeString( *aIt );
1522*cdf0e10cSrcweir         if( aRangeName.getLength() > 0 )
1523*cdf0e10cSrcweir         {
1524*cdf0e10cSrcweir             if( aBuffer.getLength() > 0 )
1525*cdf0e10cSrcweir                 aBuffer.append( API_TOKEN_SEP );
1526*cdf0e10cSrcweir             aBuffer.append( aRangeName );
1527*cdf0e10cSrcweir         }
1528*cdf0e10cSrcweir     }
1529*cdf0e10cSrcweir     return aBuffer.makeStringAndClear();
1530*cdf0e10cSrcweir }
1531*cdf0e10cSrcweir 
1532*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiString( const OUString& rString )
1533*cdf0e10cSrcweir {
1534*cdf0e10cSrcweir     OUString aRetString = rString;
1535*cdf0e10cSrcweir     sal_Int32 nQuotePos = aRetString.getLength();
1536*cdf0e10cSrcweir     while( (nQuotePos = aRetString.lastIndexOf( '"', nQuotePos )) >= 0 )
1537*cdf0e10cSrcweir         aRetString = aRetString.replaceAt( nQuotePos, 1, CREATE_OUSTRING( "\"\"" ) );
1538*cdf0e10cSrcweir     return OUStringBuffer().append( sal_Unicode( '"' ) ).append( aRetString ).append( sal_Unicode( '"' ) ).makeStringAndClear();
1539*cdf0e10cSrcweir }
1540*cdf0e10cSrcweir 
1541*cdf0e10cSrcweir OUString FormulaProcessorBase::generateApiArray( const Matrix< Any >& rMatrix )
1542*cdf0e10cSrcweir {
1543*cdf0e10cSrcweir     OSL_ENSURE( !rMatrix.empty(), "FormulaProcessorBase::generateApiArray - missing matrix values" );
1544*cdf0e10cSrcweir     OUStringBuffer aBuffer;
1545*cdf0e10cSrcweir     aBuffer.append( API_TOKEN_ARRAY_OPEN );
1546*cdf0e10cSrcweir     for( size_t nRow = 0, nHeight = rMatrix.height(); nRow < nHeight; ++nRow )
1547*cdf0e10cSrcweir     {
1548*cdf0e10cSrcweir         if( nRow > 0 )
1549*cdf0e10cSrcweir             aBuffer.append( API_TOKEN_ARRAY_ROWSEP );
1550*cdf0e10cSrcweir         for( Matrix< Any >::const_iterator aBeg = rMatrix.row_begin( nRow ), aIt = aBeg, aEnd = rMatrix.row_end( nRow ); aIt != aEnd; ++aIt )
1551*cdf0e10cSrcweir         {
1552*cdf0e10cSrcweir             double fValue = 0.0;
1553*cdf0e10cSrcweir             OUString aString;
1554*cdf0e10cSrcweir             if( aIt != aBeg )
1555*cdf0e10cSrcweir                 aBuffer.append( API_TOKEN_ARRAY_COLSEP );
1556*cdf0e10cSrcweir             if( *aIt >>= fValue )
1557*cdf0e10cSrcweir                 aBuffer.append( fValue );
1558*cdf0e10cSrcweir             else if( *aIt >>= aString )
1559*cdf0e10cSrcweir                 aBuffer.append( generateApiString( aString ) );
1560*cdf0e10cSrcweir             else
1561*cdf0e10cSrcweir                 aBuffer.appendAscii( "\"\"" );
1562*cdf0e10cSrcweir         }
1563*cdf0e10cSrcweir     }
1564*cdf0e10cSrcweir     aBuffer.append( API_TOKEN_ARRAY_CLOSE );
1565*cdf0e10cSrcweir     return aBuffer.makeStringAndClear();
1566*cdf0e10cSrcweir }
1567*cdf0e10cSrcweir 
1568*cdf0e10cSrcweir // ----------------------------------------------------------------------------
1569*cdf0e10cSrcweir 
1570*cdf0e10cSrcweir Any FormulaProcessorBase::extractReference( const ApiTokenSequence& rTokens ) const
1571*cdf0e10cSrcweir {
1572*cdf0e10cSrcweir     ApiTokenIterator aTokenIt( rTokens, OPCODE_SPACES, true );
1573*cdf0e10cSrcweir     if( aTokenIt.is() && (aTokenIt->OpCode == OPCODE_PUSH) )
1574*cdf0e10cSrcweir     {
1575*cdf0e10cSrcweir         Any aRefAny = aTokenIt->Data;
1576*cdf0e10cSrcweir         if( !(++aTokenIt).is() && (aRefAny.has< SingleReference >() || aRefAny.has< ComplexReference >()) )
1577*cdf0e10cSrcweir             return aRefAny;
1578*cdf0e10cSrcweir     }
1579*cdf0e10cSrcweir     return Any();
1580*cdf0e10cSrcweir }
1581*cdf0e10cSrcweir 
1582*cdf0e10cSrcweir bool FormulaProcessorBase::extractCellAddress( CellAddress& orAddress,
1583*cdf0e10cSrcweir         const ApiTokenSequence& rTokens, bool bAllowRelative ) const
1584*cdf0e10cSrcweir {
1585*cdf0e10cSrcweir     CellRangeAddress aRange;
1586*cdf0e10cSrcweir     if( extractCellRange( aRange, rTokens, bAllowRelative ) && (aRange.StartColumn == aRange.EndColumn) && (aRange.StartRow == aRange.EndRow) )
1587*cdf0e10cSrcweir     {
1588*cdf0e10cSrcweir         orAddress.Sheet = aRange.Sheet;
1589*cdf0e10cSrcweir         orAddress.Column = aRange.StartColumn;
1590*cdf0e10cSrcweir         orAddress.Row = aRange.StartRow;
1591*cdf0e10cSrcweir         return true;
1592*cdf0e10cSrcweir     }
1593*cdf0e10cSrcweir     return false;
1594*cdf0e10cSrcweir }
1595*cdf0e10cSrcweir 
1596*cdf0e10cSrcweir bool FormulaProcessorBase::extractCellRange( CellRangeAddress& orRange,
1597*cdf0e10cSrcweir         const ApiTokenSequence& rTokens, bool bAllowRelative ) const
1598*cdf0e10cSrcweir {
1599*cdf0e10cSrcweir     ApiCellRangeList aRanges;
1600*cdf0e10cSrcweir     lclProcessRef( aRanges, extractReference( rTokens ), bAllowRelative, -1 );
1601*cdf0e10cSrcweir     if( !aRanges.empty() )
1602*cdf0e10cSrcweir     {
1603*cdf0e10cSrcweir         orRange = aRanges.front();
1604*cdf0e10cSrcweir         return true;
1605*cdf0e10cSrcweir     }
1606*cdf0e10cSrcweir     return false;
1607*cdf0e10cSrcweir }
1608*cdf0e10cSrcweir 
1609*cdf0e10cSrcweir void FormulaProcessorBase::extractCellRangeList( ApiCellRangeList& orRanges,
1610*cdf0e10cSrcweir         const ApiTokenSequence& rTokens, bool bAllowRelative, sal_Int32 nFilterBySheet ) const
1611*cdf0e10cSrcweir {
1612*cdf0e10cSrcweir     orRanges.clear();
1613*cdf0e10cSrcweir     TokenToRangeListState eState = STATE_OPEN;
1614*cdf0e10cSrcweir     sal_Int32 nParenLevel = 0;
1615*cdf0e10cSrcweir     for( ApiTokenIterator aIt( rTokens, OPCODE_SPACES, true ); aIt.is() && (eState != STATE_ERROR); ++aIt )
1616*cdf0e10cSrcweir     {
1617*cdf0e10cSrcweir         sal_Int32 nOpCode = aIt->OpCode;
1618*cdf0e10cSrcweir         switch( eState )
1619*cdf0e10cSrcweir         {
1620*cdf0e10cSrcweir             // #i107275# accept OPCODE_SEP and OPCODE_LIST as separator token
1621*cdf0e10cSrcweir             case STATE_REF:
1622*cdf0e10cSrcweir                      if( nOpCode == OPCODE_SEP )   eState = STATE_SEP;
1623*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_LIST )  eState = STATE_SEP;
1624*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
1625*cdf0e10cSrcweir                 else                               eState = STATE_ERROR;
1626*cdf0e10cSrcweir             break;
1627*cdf0e10cSrcweir             case STATE_SEP:
1628*cdf0e10cSrcweir                      if( nOpCode == OPCODE_PUSH )  eState = lclProcessRef( orRanges, aIt->Data, bAllowRelative, nFilterBySheet );
1629*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_SEP )   eState = STATE_SEP;
1630*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_LIST )  eState = STATE_SEP;
1631*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_OPEN )  eState = lclProcessOpen( nParenLevel );
1632*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
1633*cdf0e10cSrcweir                 else                               eState = STATE_ERROR;
1634*cdf0e10cSrcweir             break;
1635*cdf0e10cSrcweir             case STATE_OPEN:
1636*cdf0e10cSrcweir                      if( nOpCode == OPCODE_PUSH )  eState = lclProcessRef( orRanges, aIt->Data, bAllowRelative, nFilterBySheet );
1637*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_SEP )   eState = STATE_SEP;
1638*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_LIST )  eState = STATE_SEP;
1639*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_OPEN )  eState = lclProcessOpen( nParenLevel );
1640*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
1641*cdf0e10cSrcweir                 else                               eState = STATE_ERROR;
1642*cdf0e10cSrcweir             break;
1643*cdf0e10cSrcweir             case STATE_CLOSE:
1644*cdf0e10cSrcweir                      if( nOpCode == OPCODE_SEP )   eState = STATE_SEP;
1645*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_LIST )  eState = STATE_SEP;
1646*cdf0e10cSrcweir                 else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel );
1647*cdf0e10cSrcweir                 else                               eState = STATE_ERROR;
1648*cdf0e10cSrcweir             break;
1649*cdf0e10cSrcweir             default:;
1650*cdf0e10cSrcweir         }
1651*cdf0e10cSrcweir     }
1652*cdf0e10cSrcweir 
1653*cdf0e10cSrcweir     if( eState == STATE_ERROR )
1654*cdf0e10cSrcweir         orRanges.clear();
1655*cdf0e10cSrcweir     else
1656*cdf0e10cSrcweir         getAddressConverter().validateCellRangeList( orRanges, false );
1657*cdf0e10cSrcweir }
1658*cdf0e10cSrcweir 
1659*cdf0e10cSrcweir bool FormulaProcessorBase::extractString( OUString& orString, const ApiTokenSequence& rTokens ) const
1660*cdf0e10cSrcweir {
1661*cdf0e10cSrcweir     ApiTokenIterator aTokenIt( rTokens, OPCODE_SPACES, true );
1662*cdf0e10cSrcweir     return aTokenIt.is() && (aTokenIt->OpCode == OPCODE_PUSH) && (aTokenIt->Data >>= orString) && !(++aTokenIt).is();
1663*cdf0e10cSrcweir }
1664*cdf0e10cSrcweir 
1665*cdf0e10cSrcweir bool FormulaProcessorBase::extractSpecialTokenInfo( ApiSpecialTokenInfo& orTokenInfo, const ApiTokenSequence& rTokens ) const
1666*cdf0e10cSrcweir {
1667*cdf0e10cSrcweir     ApiTokenIterator aTokenIt( rTokens, OPCODE_SPACES, true );
1668*cdf0e10cSrcweir     return aTokenIt.is() && (aTokenIt->OpCode == OPCODE_BAD) && (aTokenIt->Data >>= orTokenInfo);
1669*cdf0e10cSrcweir }
1670*cdf0e10cSrcweir 
1671*cdf0e10cSrcweir void FormulaProcessorBase::convertStringToStringList(
1672*cdf0e10cSrcweir         ApiTokenSequence& orTokens, sal_Unicode cStringSep, bool bTrimLeadingSpaces ) const
1673*cdf0e10cSrcweir {
1674*cdf0e10cSrcweir     OUString aString;
1675*cdf0e10cSrcweir     if( extractString( aString, orTokens ) && (aString.getLength() > 0) )
1676*cdf0e10cSrcweir     {
1677*cdf0e10cSrcweir         ::std::vector< ApiToken > aNewTokens;
1678*cdf0e10cSrcweir         sal_Int32 nPos = 0;
1679*cdf0e10cSrcweir         sal_Int32 nLen = aString.getLength();
1680*cdf0e10cSrcweir         while( (0 <= nPos) && (nPos < nLen) )
1681*cdf0e10cSrcweir         {
1682*cdf0e10cSrcweir             OUString aEntry = aString.getToken( 0, cStringSep, nPos );
1683*cdf0e10cSrcweir             if( bTrimLeadingSpaces )
1684*cdf0e10cSrcweir             {
1685*cdf0e10cSrcweir                 sal_Int32 nStart = 0;
1686*cdf0e10cSrcweir                 while( (nStart < aEntry.getLength()) && (aEntry[ nStart ] == ' ') ) ++nStart;
1687*cdf0e10cSrcweir                 aEntry = aEntry.copy( nStart );
1688*cdf0e10cSrcweir             }
1689*cdf0e10cSrcweir             if( !aNewTokens.empty() )
1690*cdf0e10cSrcweir                 aNewTokens.push_back( ApiToken( OPCODE_SEP, Any() ) );
1691*cdf0e10cSrcweir             aNewTokens.push_back( ApiToken( OPCODE_PUSH, Any( aEntry ) ) );
1692*cdf0e10cSrcweir         }
1693*cdf0e10cSrcweir         orTokens = ContainerHelper::vectorToSequence( aNewTokens );
1694*cdf0e10cSrcweir     }
1695*cdf0e10cSrcweir }
1696*cdf0e10cSrcweir 
1697*cdf0e10cSrcweir // ============================================================================
1698*cdf0e10cSrcweir 
1699*cdf0e10cSrcweir } // namespace xls
1700*cdf0e10cSrcweir } // namespace oox
1701