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