xref: /aoo41x/main/oox/inc/oox/xls/formulabase.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef OOX_XLS_FORMULABASE_HXX
29 #define OOX_XLS_FORMULABASE_HXX
30 
31 #include <com/sun/star/beans/Pair.hpp>
32 #include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
33 #include <com/sun/star/sheet/FormulaToken.hpp>
34 #include <com/sun/star/table/CellAddress.hpp>
35 #include <com/sun/star/table/CellRangeAddress.hpp>
36 #include <com/sun/star/uno/Sequence.hxx>
37 #include "oox/helper/propertyset.hxx"
38 #include "oox/helper/refvector.hxx"
39 #include "oox/xls/addressconverter.hxx"
40 
41 namespace com { namespace sun { namespace star {
42     namespace sheet { class XFormulaOpCodeMapper; }
43     namespace sheet { class XFormulaParser; }
44 } } }
45 
46 namespace oox { template< typename Type > class Matrix; }
47 
48 namespace oox {
49 namespace xls {
50 
51 // Constants ==================================================================
52 
53 const size_t BIFF_TOKARR_MAXLEN                 = 4096;     /// Maximum size of a token array.
54 
55 // token class flags ----------------------------------------------------------
56 
57 const sal_uInt8 BIFF_TOKCLASS_MASK              = 0x60;
58 const sal_uInt8 BIFF_TOKCLASS_NONE              = 0x00;     /// 00-1F: Base tokens.
59 const sal_uInt8 BIFF_TOKCLASS_REF               = 0x20;     /// 20-3F: Reference class tokens.
60 const sal_uInt8 BIFF_TOKCLASS_VAL               = 0x40;     /// 40-5F: Value class tokens.
61 const sal_uInt8 BIFF_TOKCLASS_ARR               = 0x60;     /// 60-7F: Array class tokens.
62 
63 const sal_uInt8 BIFF_TOKFLAG_INVALID            = 0x80;     /// This bit must be null for a valid token identifier.
64 
65 // base token identifiers -----------------------------------------------------
66 
67 const sal_uInt8 BIFF_TOKID_MASK                 = 0x1F;
68 
69 const sal_uInt8 BIFF_TOKID_NONE                 = 0x00;     /// Placeholder for invalid token id.
70 const sal_uInt8 BIFF_TOKID_EXP                  = 0x01;     /// Array or shared formula reference.
71 const sal_uInt8 BIFF_TOKID_TBL                  = 0x02;     /// Multiple operation reference.
72 const sal_uInt8 BIFF_TOKID_ADD                  = 0x03;     /// Addition operator.
73 const sal_uInt8 BIFF_TOKID_SUB                  = 0x04;     /// Subtraction operator.
74 const sal_uInt8 BIFF_TOKID_MUL                  = 0x05;     /// Multiplication operator.
75 const sal_uInt8 BIFF_TOKID_DIV                  = 0x06;     /// Division operator.
76 const sal_uInt8 BIFF_TOKID_POWER                = 0x07;     /// Power operator.
77 const sal_uInt8 BIFF_TOKID_CONCAT               = 0x08;     /// String concatenation operator.
78 const sal_uInt8 BIFF_TOKID_LT                   = 0x09;     /// Less than operator.
79 const sal_uInt8 BIFF_TOKID_LE                   = 0x0A;     /// Less than or equal operator.
80 const sal_uInt8 BIFF_TOKID_EQ                   = 0x0B;     /// Equal operator.
81 const sal_uInt8 BIFF_TOKID_GE                   = 0x0C;     /// Greater than or equal operator.
82 const sal_uInt8 BIFF_TOKID_GT                   = 0x0D;     /// Greater than operator.
83 const sal_uInt8 BIFF_TOKID_NE                   = 0x0E;     /// Not equal operator.
84 const sal_uInt8 BIFF_TOKID_ISECT                = 0x0F;     /// Intersection operator.
85 const sal_uInt8 BIFF_TOKID_LIST                 = 0x10;     /// List operator.
86 const sal_uInt8 BIFF_TOKID_RANGE                = 0x11;     /// Range operator.
87 const sal_uInt8 BIFF_TOKID_UPLUS                = 0x12;     /// Unary plus.
88 const sal_uInt8 BIFF_TOKID_UMINUS               = 0x13;     /// Unary minus.
89 const sal_uInt8 BIFF_TOKID_PERCENT              = 0x14;     /// Percent sign.
90 const sal_uInt8 BIFF_TOKID_PAREN                = 0x15;     /// Parentheses.
91 const sal_uInt8 BIFF_TOKID_MISSARG              = 0x16;     /// Missing argument.
92 const sal_uInt8 BIFF_TOKID_STR                  = 0x17;     /// String constant.
93 const sal_uInt8 BIFF_TOKID_NLR                  = 0x18;     /// Natural language reference (NLR).
94 const sal_uInt8 BIFF_TOKID_ATTR                 = 0x19;     /// Special attribute.
95 const sal_uInt8 BIFF_TOKID_SHEET                = 0x1A;     /// Start of a sheet reference (BIFF2-BIFF4).
96 const sal_uInt8 BIFF_TOKID_ENDSHEET             = 0x1B;     /// End of a sheet reference (BIFF2-BIFF4).
97 const sal_uInt8 BIFF_TOKID_ERR                  = 0x1C;     /// Error constant.
98 const sal_uInt8 BIFF_TOKID_BOOL                 = 0x1D;     /// Boolean constant.
99 const sal_uInt8 BIFF_TOKID_INT                  = 0x1E;     /// Integer constant.
100 const sal_uInt8 BIFF_TOKID_NUM                  = 0x1F;     /// Floating-point constant.
101 
102 // base identifiers of classified tokens --------------------------------------
103 
104 const sal_uInt8 BIFF_TOKID_ARRAY                = 0x00;     /// Array constant.
105 const sal_uInt8 BIFF_TOKID_FUNC                 = 0x01;     /// Function, fixed number of arguments.
106 const sal_uInt8 BIFF_TOKID_FUNCVAR              = 0x02;     /// Function, variable number of arguments.
107 const sal_uInt8 BIFF_TOKID_NAME                 = 0x03;     /// Defined name.
108 const sal_uInt8 BIFF_TOKID_REF                  = 0x04;     /// 2D cell reference.
109 const sal_uInt8 BIFF_TOKID_AREA                 = 0x05;     /// 2D area reference.
110 const sal_uInt8 BIFF_TOKID_MEMAREA              = 0x06;     /// Constant reference subexpression.
111 const sal_uInt8 BIFF_TOKID_MEMERR               = 0x07;     /// Deleted reference subexpression.
112 const sal_uInt8 BIFF_TOKID_MEMNOMEM             = 0x08;     /// Constant reference subexpression without result.
113 const sal_uInt8 BIFF_TOKID_MEMFUNC              = 0x09;     /// Variable reference subexpression.
114 const sal_uInt8 BIFF_TOKID_REFERR               = 0x0A;     /// Deleted 2D cell reference.
115 const sal_uInt8 BIFF_TOKID_AREAERR              = 0x0B;     /// Deleted 2D area reference.
116 const sal_uInt8 BIFF_TOKID_REFN                 = 0x0C;     /// Relative 2D cell reference (in names).
117 const sal_uInt8 BIFF_TOKID_AREAN                = 0x0D;     /// Relative 2D area reference (in names).
118 const sal_uInt8 BIFF_TOKID_MEMAREAN             = 0x0E;     /// Reference subexpression (in names).
119 const sal_uInt8 BIFF_TOKID_MEMNOMEMN            = 0x0F;     /// Reference subexpression (in names) without result.
120 const sal_uInt8 BIFF_TOKID_FUNCCE               = 0x18;
121 const sal_uInt8 BIFF_TOKID_NAMEX                = 0x19;     /// External reference.
122 const sal_uInt8 BIFF_TOKID_REF3D                = 0x1A;     /// 3D cell reference.
123 const sal_uInt8 BIFF_TOKID_AREA3D               = 0x1B;     /// 3D area reference.
124 const sal_uInt8 BIFF_TOKID_REFERR3D             = 0x1C;     /// Deleted 3D cell reference.
125 const sal_uInt8 BIFF_TOKID_AREAERR3D            = 0x1D;     /// Deleted 3D area reference
126 
127 // specific token constants ---------------------------------------------------
128 
129 const sal_uInt8 BIFF_TOK_ARRAY_DOUBLE           = 0;        /// Double value in an array.
130 const sal_uInt8 BIFF_TOK_ARRAY_STRING           = 1;        /// String value in an array.
131 const sal_uInt8 BIFF_TOK_ARRAY_BOOL             = 2;        /// Boolean value in an array.
132 const sal_uInt8 BIFF_TOK_ARRAY_ERROR            = 4;        /// Error code in an array.
133 
134 const sal_uInt8 BIFF_TOK_BOOL_FALSE             = 0;        /// FALSE value of a tBool token.
135 const sal_uInt8 BIFF_TOK_BOOL_TRUE              = 1;        /// TRUE value of a tBool token.
136 
137 const sal_uInt8 BIFF_TOK_ATTR_VOLATILE          = 0x01;     /// Volatile function.
138 const sal_uInt8 BIFF_TOK_ATTR_IF                = 0x02;     /// Start of true condition in IF function.
139 const sal_uInt8 BIFF_TOK_ATTR_CHOOSE            = 0x04;     /// Jump array of CHOOSE function.
140 const sal_uInt8 BIFF_TOK_ATTR_SKIP              = 0x08;     /// Skip tokens.
141 const sal_uInt8 BIFF_TOK_ATTR_SUM               = 0x10;     /// SUM function with one parameter.
142 const sal_uInt8 BIFF_TOK_ATTR_ASSIGN            = 0x20;     /// BASIC style assignment.
143 const sal_uInt8 BIFF_TOK_ATTR_SPACE             = 0x40;     /// Spaces in formula representation.
144 const sal_uInt8 BIFF_TOK_ATTR_SPACE_VOLATILE    = 0x41;     /// Leading spaces and volatile formula.
145 const sal_uInt8 BIFF_TOK_ATTR_IFERROR           = 0x80;     /// Start of condition in IFERROR function (BIFF12 only).
146 
147 const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP          = 0x00;     /// Spaces before next token.
148 const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR          = 0x01;     /// Line breaks before next token.
149 const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP_OPEN     = 0x02;     /// Spaces before opening parenthesis.
150 const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR_OPEN     = 0x03;     /// Line breaks before opening parenthesis.
151 const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP_CLOSE    = 0x04;     /// Spaces before closing parenthesis.
152 const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR_CLOSE    = 0x05;     /// Line breaks before closing parenthesis.
153 const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP_PRE      = 0x06;     /// Spaces before formula (BIFF3).
154 
155 const sal_uInt16 BIFF_TOK_FUNCVAR_CMD           = 0x8000;   /// Macro command.
156 const sal_uInt16 BIFF_TOK_FUNCVAR_FUNCIDMASK    = 0x7FFF;   /// Mask for function/command index.
157 const sal_uInt8 BIFF_TOK_FUNCVAR_CMDPROMPT      = 0x80;     /// User prompt for macro commands.
158 const sal_uInt8 BIFF_TOK_FUNCVAR_COUNTMASK      = 0x7F;     /// Mask for parameter count.
159 
160 const sal_uInt16 BIFF12_TOK_REF_COLMASK         = 0x3FFF;   /// Mask to extract column from reference (BIFF12).
161 const sal_Int32 BIFF12_TOK_REF_ROWMASK          = 0xFFFFF;  /// Mask to extract row from reference (BIFF12).
162 const sal_uInt16 BIFF12_TOK_REF_COLREL          = 0x4000;   /// True = column is relative (BIFF12).
163 const sal_uInt16 BIFF12_TOK_REF_ROWREL          = 0x8000;   /// True = row is relative (BIFF12).
164 
165 const sal_uInt16 BIFF_TOK_REF_COLMASK           = 0x00FF;   /// Mask to extract BIFF8 column from reference.
166 const sal_uInt16 BIFF_TOK_REF_ROWMASK           = 0x3FFF;   /// Mask to extract BIFF2-BIFF5 row from reference.
167 const sal_uInt16 BIFF_TOK_REF_COLREL            = 0x4000;   /// True = column is relative.
168 const sal_uInt16 BIFF_TOK_REF_ROWREL            = 0x8000;   /// True = row is relative.
169 
170 const sal_uInt16 BIFF12_TOK_TABLE_COLUMN         = 0x0001;   /// Table reference: Single column.
171 const sal_uInt16 BIFF12_TOK_TABLE_COLRANGE       = 0x0002;   /// Table reference: Range of columns.
172 const sal_uInt16 BIFF12_TOK_TABLE_ALL            = 0x0004;   /// Table reference: Special [#All] range.
173 const sal_uInt16 BIFF12_TOK_TABLE_HEADERS        = 0x0008;   /// Table reference: Special [#Headers] range.
174 const sal_uInt16 BIFF12_TOK_TABLE_DATA           = 0x0010;   /// Table reference: Special [#Data] range.
175 const sal_uInt16 BIFF12_TOK_TABLE_TOTALS         = 0x0020;   /// Table reference: Special [#Totals] range.
176 const sal_uInt16 BIFF12_TOK_TABLE_THISROW        = 0x0040;   /// Table reference: Special [#This Row] range.
177 const sal_uInt16 BIFF12_TOK_TABLE_SP_BRACKETS    = 0x0080;   /// Table reference: Spaces in outer brackets.
178 const sal_uInt16 BIFF12_TOK_TABLE_SP_SEP         = 0x0100;   /// Table reference: Spaces after separators.
179 const sal_uInt16 BIFF12_TOK_TABLE_ROW            = 0x0200;   /// Table reference: Single row.
180 const sal_uInt16 BIFF12_TOK_TABLE_CELL           = 0x0400;   /// Table reference: Single cell.
181 
182 const sal_uInt8 BIFF_TOK_NLR_ERR                = 0x01;     /// NLR: Invalid/deleted.
183 const sal_uInt8 BIFF_TOK_NLR_ROWR               = 0x02;     /// NLR: Row index.
184 const sal_uInt8 BIFF_TOK_NLR_COLR               = 0x03;     /// NLR: Column index.
185 const sal_uInt8 BIFF_TOK_NLR_ROWV               = 0x06;     /// NLR: Value in row.
186 const sal_uInt8 BIFF_TOK_NLR_COLV               = 0x07;     /// NLR: Value in column.
187 const sal_uInt8 BIFF_TOK_NLR_RANGE              = 0x0A;     /// NLR: Range.
188 const sal_uInt8 BIFF_TOK_NLR_SRANGE             = 0x0B;     /// Stacked NLR: Range.
189 const sal_uInt8 BIFF_TOK_NLR_SROWR              = 0x0C;     /// Stacked NLR: Row index.
190 const sal_uInt8 BIFF_TOK_NLR_SCOLR              = 0x0D;     /// Stacked NLR: Column index.
191 const sal_uInt8 BIFF_TOK_NLR_SROWV              = 0x0E;     /// Stacked NLR: Value in row.
192 const sal_uInt8 BIFF_TOK_NLR_SCOLV              = 0x0F;     /// Stacked NLR: Value in column.
193 const sal_uInt8 BIFF_TOK_NLR_RANGEERR           = 0x10;     /// NLR: Invalid/deleted range.
194 const sal_uInt8 BIFF_TOK_NLR_SXNAME             = 0x1D;     /// NLR: Pivot table name.
195 const sal_uInt16 BIFF_TOK_NLR_REL               = 0x8000;   /// True = NLR is relative.
196 const sal_uInt16 BIFF_TOK_NLR_MASK              = 0x3FFF;   /// Mask to extract BIFF8 column from NLR.
197 
198 const sal_uInt32 BIFF_TOK_NLR_ADDREL            = 0x80000000;   /// NLR relative (in appended data).
199 const sal_uInt32 BIFF_TOK_NLR_ADDMASK           = 0x3FFFFFFF;   /// Mask for number of appended ranges.
200 
201 // function constants ---------------------------------------------------------
202 
203 const sal_uInt8 OOX_MAX_PARAMCOUNT              = 255;      /// Maximum parameter count for OOXML/BIFF12 files.
204 const sal_uInt8 BIFF_MAX_PARAMCOUNT             = 30;       /// Maximum parameter count for BIFF2-BIFF8 files.
205 
206 const sal_uInt16 BIFF_FUNC_IF                   = 1;        /// Function identifier of the IF function.
207 const sal_uInt16 BIFF_FUNC_SUM                  = 4;        /// Function identifier of the SUM function.
208 const sal_uInt16 BIFF_FUNC_TRUE                 = 34;       /// Function identifier of the TRUE function.
209 const sal_uInt16 BIFF_FUNC_FALSE                = 35;       /// Function identifier of the FALSE function.
210 const sal_uInt16 BIFF_FUNC_ROWS                 = 76;       /// Function identifier of the ROWS function.
211 const sal_uInt16 BIFF_FUNC_COLUMNS              = 77;       /// Function identifier of the COLUMNS function.
212 const sal_uInt16 BIFF_FUNC_OFFSET               = 78;       /// Function identifier of the OFFSET function.
213 const sal_uInt16 BIFF_FUNC_EXTERNCALL           = 255;      /// BIFF function id of the EXTERN.CALL function.
214 const sal_uInt16 BIFF_FUNC_FLOOR                = 285;      /// Function identifier of the FLOOR function.
215 const sal_uInt16 BIFF_FUNC_CEILING              = 288;      /// Function identifier of the CEILING function.
216 const sal_uInt16 BIFF_FUNC_HYPERLINK            = 359;      /// Function identifier of the HYPERLINK function.
217 const sal_uInt16 BIFF_FUNC_WEEKNUM              = 465;      /// Function identifier of the WEEKNUM function.
218 
219 // Formula type ===============================================================
220 
221 /** Enumerates all possible types of a formula. */
222 enum FormulaType
223 {
224     FORMULATYPE_CELL,           /// Simple cell formula, or reference to a shared formula name.
225     FORMULATYPE_ARRAY,          /// Array (matrix) formula.
226     FORMULATYPE_SHAREDFORMULA,  /// Shared formula definition.
227     FORMULATYPE_CONDFORMAT,     /// Condition of a conditional format rule.
228     FORMULATYPE_VALIDATION,     /// Condition of a data validation.
229     FORMULATYPE_DEFINEDNAME     /// Definition of a defined name.
230 };
231 
232 // Reference helpers ==========================================================
233 
234 /** A 2D formula cell reference struct with relative flags. */
235 struct BinSingleRef2d
236 {
237     sal_Int32           mnCol;              /// Column index.
238     sal_Int32           mnRow;              /// Row index.
239     bool                mbColRel;           /// True = relative column reference.
240     bool                mbRowRel;           /// True = relative row reference.
241 
242     explicit            BinSingleRef2d();
243 
244     void                setBiff12Data( sal_uInt16 nCol, sal_Int32 nRow, bool bRelativeAsOffset );
245     void                setBiff2Data( sal_uInt8 nCol, sal_uInt16 nRow, bool bRelativeAsOffset );
246     void                setBiff8Data( sal_uInt16 nCol, sal_uInt16 nRow, bool bRelativeAsOffset );
247 
248     void                readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset );
249     void                readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset );
250     void                readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset );
251 };
252 
253 // ----------------------------------------------------------------------------
254 
255 /** A 2D formula cell range reference struct with relative flags. */
256 struct BinComplexRef2d
257 {
258     BinSingleRef2d      maRef1;             /// Start (top-left) cell address.
259     BinSingleRef2d      maRef2;             /// End (bottom-right) cell address.
260 
261     void                readBiff12Data( SequenceInputStream& rStrm, bool bRelativeAsOffset );
262     void                readBiff2Data( BiffInputStream& rStrm, bool bRelativeAsOffset );
263     void                readBiff8Data( BiffInputStream& rStrm, bool bRelativeAsOffset );
264 };
265 
266 // Token vector, token sequence ===============================================
267 
268 typedef ::com::sun::star::sheet::FormulaToken       ApiToken;
269 typedef ::com::sun::star::uno::Sequence< ApiToken > ApiTokenSequence;
270 
271 /** Contains the base address and type of a special token representing an array
272     formula or a shared formula (sal_False), or a table operation (sal_True). */
273 typedef ::com::sun::star::beans::Pair< ::com::sun::star::table::CellAddress, sal_Bool > ApiSpecialTokenInfo;
274 
275 /** A vector of formula tokens with additional convenience functions. */
276 class ApiTokenVector : public ::std::vector< ApiToken >
277 {
278 public:
279     explicit            ApiTokenVector();
280 
281     /** Appends a new token with the passed op-code, returns its data field. */
282     ::com::sun::star::uno::Any&
283                         append( sal_Int32 nOpCode );
284 
285     /** Appends a new token with the passed op-code and data. */
286     template< typename Type >
287     inline void         append( sal_Int32 nOpCode, const Type& rData ) { append( nOpCode ) <<= rData; }
288 };
289 
290 // Token sequence iterator ====================================================
291 
292 /** Token sequence iterator that is able to skip space tokens. */
293 class ApiTokenIterator
294 {
295 public:
296     explicit            ApiTokenIterator( const ApiTokenSequence& rTokens, sal_Int32 nSpacesOpCode, bool bSkipSpaces );
297     /** Copy constructor that allows to change the skip spaces mode. */
298     explicit            ApiTokenIterator( const ApiTokenIterator& rIter, bool bSkipSpaces );
299 
300     inline bool         is() const { return mpToken != mpTokenEnd; }
301     inline const ApiToken* get() const { return mpToken; }
302     inline const ApiToken* operator->() const { return mpToken; }
303     inline const ApiToken& operator*() const { return *mpToken; }
304 
305     ApiTokenIterator&   operator++();
306 
307 private:
308     void                skipSpaces();
309 
310 private:
311     const ApiToken*     mpToken;            /// Pointer to current token of the token sequence.
312     const ApiToken*     mpTokenEnd;         /// Pointer behind last token of the token sequence.
313     const sal_Int32     mnSpacesOpCode;     /// Op-code for whitespace tokens.
314     const bool          mbSkipSpaces;       /// true = Skip whitespace tokens.
315 };
316 
317 // List of API op-codes =======================================================
318 
319 /** Contains all API op-codes needed to build formulas with tokens. */
320 struct ApiOpCodes
321 {
322     // special
323     sal_Int32           OPCODE_UNKNOWN;         /// Internal: function name unknown to mapper.
324     sal_Int32           OPCODE_EXTERNAL;        /// External function call (e.g. add-ins).
325     // formula structure
326     sal_Int32           OPCODE_PUSH;            /// Op-code for common value operands.
327     sal_Int32           OPCODE_MISSING;         /// Placeholder for a missing function parameter.
328     sal_Int32           OPCODE_SPACES;          /// Spaces between other formula tokens.
329     sal_Int32           OPCODE_NAME;            /// Index of a defined name.
330     sal_Int32           OPCODE_DBAREA;          /// Index of a database area.
331     sal_Int32           OPCODE_NLR;             /// Natural language reference.
332     sal_Int32           OPCODE_DDE;             /// DDE link function.
333     sal_Int32           OPCODE_MACRO;           /// Macro function call.
334     sal_Int32           OPCODE_BAD;             /// Bad token (unknown name, formula error).
335     sal_Int32           OPCODE_NONAME;          /// Function style #NAME? error.
336     // separators
337     sal_Int32           OPCODE_OPEN;            /// Opening parenthesis.
338     sal_Int32           OPCODE_CLOSE;           /// Closing parenthesis.
339     sal_Int32           OPCODE_SEP;             /// Function parameter separator.
340     // array separators
341     sal_Int32           OPCODE_ARRAY_OPEN;      /// Opening brace for constant arrays.
342     sal_Int32           OPCODE_ARRAY_CLOSE;     /// Closing brace for constant arrays.
343     sal_Int32           OPCODE_ARRAY_ROWSEP;    /// Row separator in constant arrays.
344     sal_Int32           OPCODE_ARRAY_COLSEP;    /// Column separator in constant arrays.
345     // unary operators
346     sal_Int32           OPCODE_PLUS_SIGN;       /// Unary plus sign.
347     sal_Int32           OPCODE_MINUS_SIGN;      /// Unary minus sign.
348     sal_Int32           OPCODE_PERCENT;         /// Percent sign.
349     // binary operators
350     sal_Int32           OPCODE_ADD;             /// Addition operator.
351     sal_Int32           OPCODE_SUB;             /// Subtraction operator.
352     sal_Int32           OPCODE_MULT;            /// Multiplication operator.
353     sal_Int32           OPCODE_DIV;             /// Division operator.
354     sal_Int32           OPCODE_POWER;           /// Power operator.
355     sal_Int32           OPCODE_CONCAT;          /// String concatenation operator.
356     sal_Int32           OPCODE_EQUAL;           /// Compare equal operator.
357     sal_Int32           OPCODE_NOT_EQUAL;       /// Compare not equal operator.
358     sal_Int32           OPCODE_LESS;            /// Compare less operator.
359     sal_Int32           OPCODE_LESS_EQUAL;      /// Compare less or equal operator.
360     sal_Int32           OPCODE_GREATER;         /// Compare greater operator.
361     sal_Int32           OPCODE_GREATER_EQUAL;   /// Compare greater or equal operator.
362     sal_Int32           OPCODE_INTERSECT;       /// Range intersection operator.
363     sal_Int32           OPCODE_LIST;            /// Range list operator.
364     sal_Int32           OPCODE_RANGE;           /// Range operator.
365 };
366 
367 // Function parameter info ====================================================
368 
369 /** Enumerates validity modes for a function parameter. */
370 enum FuncParamValidity
371 {
372     FUNC_PARAM_NONE = 0,        /// Default for an unspecified entry in a C-array.
373     FUNC_PARAM_REGULAR,         /// Parameter supported by Calc and Excel.
374     FUNC_PARAM_CALCONLY,        /// Parameter supported by Calc only.
375     FUNC_PARAM_EXCELONLY        /// Parameter supported by Excel only.
376 };
377 
378 /** Enumerates different types of token class conversion in function parameters. */
379 enum FuncParamConversion
380 {
381     FUNC_PARAMCONV_ORG,         /// Use original class of current token.
382     FUNC_PARAMCONV_VAL,         /// Convert tokens to VAL class.
383     FUNC_PARAMCONV_ARR,         /// Convert tokens to ARR class.
384     FUNC_PARAMCONV_RPT,         /// Repeat parent conversion in VALTYPE parameters.
385     FUNC_PARAMCONV_RPX,         /// Repeat parent conversion in REFTYPE parameters.
386     FUNC_PARAMCONV_RPO          /// Repeat parent conversion in operands of operators.
387 };
388 
389 /** Structure that contains all needed information for a parameter in a
390     function.
391 
392     The member meValid specifies which application supports the parameter. If
393     set to CALCONLY, import filters have to insert a default value for this
394     parameter, and export filters have to skip the parameter. If set to
395     EXCELONLY, import filters have to skip the parameter, and export filters
396     have to insert a default value for this parameter.
397 
398     The member mbValType specifies whether the parameter requires tokens to be
399     of value type (VAL or ARR class).
400 
401         If set to false, the parameter is called to be REFTYPE. Tokens with REF
402         default class can be inserted for the parameter (e.g. tAreaR tokens).
403 
404         If set to true, the parameter is called to be VALTYPE. Tokens with REF
405         class need to be converted to VAL tokens first (e.g. tAreaR will be
406         converted to tAreaV), and further conversion is done according to this
407         new token class.
408 
409     The member meConv specifies how to convert the current token class of the
410     token inserted for the parameter. If the token class is still REF this
411     means that the token has default REF class and the parameter is REFTYPE
412     (see member mbValType), the token will not be converted at all and remains
413     in REF class. Otherwise, token class conversion is depending on the actual
414     token class of the return value of the function containing this parameter.
415     The function may return REF class (tFuncR, tFuncVarR, tFuncCER), or it may
416     return VAL or ARR class (tFuncV, tFuncA, tFuncVarV, tFuncVarA, tFuncCEV,
417     tFuncCEA). Even if the function is able to return REF class, it may return
418     VAL or ARR class instead due to the VALTYPE data type of the parent
419     function parameter that calls the own function. Example: The INDIRECT
420     function returns REF class by default. But if called from a VALTYPE
421     function parameter, e.g. in the formula =ABS(INDIRECT("A1")), it returns
422     VAL or ARR class instead. Additionally, the repeating conversion types RPT
423     and RPX rely on the conversion executed for the function token class.
424 
425         1) ORG:
426         Use the original class of the token (VAL or ARR), regardless of any
427         conversion done for the function return class.
428 
429         2) VAL:
430         Convert ARR tokens to VAL class, regardless of any conversion done for
431         the function return class.
432 
433         3) ARR:
434         Convert VAL tokens to ARR class, regardless of any conversion done for
435         the function return class.
436 
437         4) RPT:
438         If the own function returns REF class (thus it is called from a REFTYPE
439         parameter, see above), and the parent conversion type (for the function
440         return class) was ORG, VAL, or ARR, ignore that conversion and always
441         use VAL conversion for the own token instead. If the parent conversion
442         type was RPT or RPX, repeat the conversion that would have been used if
443         the function would return value type.
444         If the own function returns value type (VAL or ARR class, see above),
445         and the parent conversion type (for the function return class) was ORG,
446         VAL, ARR, or RPT, repeat this conversion for the own token. If the
447         parent conversion type was RPX, always use ORG conversion type for the
448         own token instead.
449 
450         5) RPX:
451         This type of conversion only occurs in functions returning VAL class by
452         default. If the own token is value type, and the VAL return class of
453         the own function has been changed to ARR class (due to direct ARR
454         conversion, or due to ARR conversion repeated by RPT or RPX), set the
455         own token to ARR type. Otherwise use the original token type (VAL
456         conversion from parent parameter will not be repeated at all). If
457         nested functions have RPT or value-type RPX parameters, they will not
458         repeat this conversion type, but will use ORG conversion instead (see
459         description of RPT above).
460 
461         6) RPO:
462         This type of conversion is only used for the operands of all operators
463         (unary and binary arithmetic operators, comparison operators, and range
464         operators). It is not used for function parameters. On conversion, it
465         will be replaced by the last conversion type that was not the RPO
466         conversion. This leads to a slightly different behaviour than the RPT
467         conversion for operands in conjunction with a parent RPX conversion.
468  */
469 struct FunctionParamInfo
470 {
471     FuncParamValidity   meValid;        /// Parameter validity.
472     FuncParamConversion meConv;         /// Token class conversion type.
473     bool                mbValType;      /// Data type (false = REFTYPE, true = VALTYPE).
474 };
475 
476 // Function data ==============================================================
477 
478 /** This enumeration contains constants for all known external libraries
479     containing supported sheet functions. */
480 enum FunctionLibraryType
481 {
482     FUNCLIB_UNKNOWN = 0,        /// Unknown library (must be zero).
483     FUNCLIB_EUROTOOL            /// EuroTool add-in with EUROCONVERT function.
484 };
485 
486 // ----------------------------------------------------------------------------
487 
488 /** Represents information for a spreadsheet function.
489 
490     The member mpParamInfos points to a C-array of type information structures
491     for all parameters of the function. The last initialized structure
492     describing a regular parameter (member meValid == FUNC_PARAM_REGULAR) in
493     this array is used repeatedly for all following parameters supported by a
494     function.
495  */
496 struct FunctionInfo
497 {
498     ::rtl::OUString     maOdfFuncName;      /// ODF function name.
499     ::rtl::OUString     maOoxFuncName;      /// OOXML function name.
500     ::rtl::OUString     maBiffMacroName;    /// Expected macro name in EXTERN.CALL function.
501     ::rtl::OUString     maExtProgName;      /// Programmatic function name for external functions.
502     FunctionLibraryType meFuncLibType;      /// The external library this function is part of.
503     sal_Int32           mnApiOpCode;        /// API function opcode.
504     sal_uInt16          mnBiff12FuncId;     /// BIFF12 function identifier.
505     sal_uInt16          mnBiffFuncId;       /// BIFF2-BIFF8 function identifier.
506     sal_uInt8           mnMinParamCount;    /// Minimum number of parameters.
507     sal_uInt8           mnMaxParamCount;    /// Maximum number of parameters.
508     sal_uInt8           mnRetClass;         /// BIFF token class of the return value.
509     const FunctionParamInfo* mpParamInfos;  /// Information about all parameters.
510     bool                mbParamPairs;       /// True = optional parameters are expected to appear in pairs.
511     bool                mbVolatile;         /// True = volatile function.
512     bool                mbExternal;         /// True = external function in Calc.
513     bool                mbMacroFunc;        /// True = macro sheet function or command.
514     bool                mbVarParam;         /// True = use a tFuncVar token, also if min/max are equal.
515 };
516 
517 typedef RefVector< FunctionInfo > FunctionInfoVector;
518 
519 // Function info parameter class iterator =====================================
520 
521 /** Iterator working on the mpParamInfos member of the FunctionInfo struct.
522 
523     This iterator can be used to iterate through the array containing the
524     token class conversion information of function parameters. This iterator
525     repeats the last valid structure in the array - it stops automatically
526     before the first empty array entry or before the end of the array, even for
527     repeated calls to the increment operator.
528  */
529 class FunctionParamInfoIterator
530 {
531 public:
532     explicit            FunctionParamInfoIterator( const FunctionInfo& rFuncInfo );
533 
534     const FunctionParamInfo& getParamInfo() const;
535     bool                isCalcOnlyParam() const;
536     bool                isExcelOnlyParam() const;
537     FunctionParamInfoIterator& operator++();
538 
539 private:
540     const FunctionParamInfo* mpParamInfo;
541     const FunctionParamInfo* mpParamInfoEnd;
542     bool                mbParamPairs;
543 };
544 
545 // Base function provider =====================================================
546 
547 struct FunctionProviderImpl;
548 
549 /** Provides access to function info structs for all available sheet functions.
550  */
551 class FunctionProvider  // not derived from WorkbookHelper to make it usable in file dumpers
552 {
553 public:
554     explicit            FunctionProvider( FilterType eFilter, BiffType eBiff, bool bImportFilter );
555     virtual             ~FunctionProvider();
556 
557     /** Returns the function info for an ODF function name, or 0 on error. */
558     const FunctionInfo* getFuncInfoFromOdfFuncName( const ::rtl::OUString& rFuncName ) const;
559 
560     /** Returns the function info for an OOXML function name, or 0 on error. */
561     const FunctionInfo* getFuncInfoFromOoxFuncName( const ::rtl::OUString& rFuncName ) const;
562 
563     /** Returns the function info for a BIFF12 function index, or 0 on error. */
564     const FunctionInfo* getFuncInfoFromBiff12FuncId( sal_uInt16 nFuncId ) const;
565 
566     /** Returns the function info for a BIFF2-BIFF8 function index, or 0 on error. */
567     const FunctionInfo* getFuncInfoFromBiffFuncId( sal_uInt16 nFuncId ) const;
568 
569     /** Returns the function info for a macro function referred by the
570         EXTERN.CALL function, or 0 on error. */
571     const FunctionInfo* getFuncInfoFromMacroName( const ::rtl::OUString& rFuncName ) const;
572 
573     /** Returns the library type associated with the passed URL of a function
574         library (function add-in). */
575     FunctionLibraryType getFuncLibTypeFromLibraryName( const ::rtl::OUString& rLibraryName ) const;
576 
577 protected:
578     /** Returns the list of all function infos. */
579     const FunctionInfoVector& getFuncs() const;
580 
581 private:
582     typedef ::boost::shared_ptr< FunctionProviderImpl > FunctionProviderImplRef;
583     FunctionProviderImplRef mxFuncImpl;     /// Shared implementation between all copies of the provider.
584 };
585 
586 // Op-code and function provider ==============================================
587 
588 struct OpCodeProviderImpl;
589 
590 /** Provides access to API op-codes for all available formula tokens and to
591     function info structs for all available sheet functions.
592  */
593 class OpCodeProvider : public FunctionProvider // not derived from WorkbookHelper to make it usable as UNO service
594 {
595 public:
596     explicit            OpCodeProvider(
597                             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxModelFactory,
598                             FilterType eFilter, BiffType eBiff, bool bImportFilter );
599     virtual             ~OpCodeProvider();
600 
601     /** Returns the structure containing all token op-codes for operators and
602         special tokens used by the Calc document and its formula parser. */
603     const ApiOpCodes&   getOpCodes() const;
604 
605     /** Returns the function info for an API token, or 0 on error. */
606     const FunctionInfo* getFuncInfoFromApiToken( const ApiToken& rToken ) const;
607 
608     /** Returns the op-code map that is used by the OOXML formula parser. */
609     ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaOpCodeMapEntry >
610                         getOoxParserMap() const;
611 
612 private:
613     typedef ::boost::shared_ptr< OpCodeProviderImpl > OpCodeProviderImplRef;
614     OpCodeProviderImplRef mxOpCodeImpl;     /// Shared implementation between all copies of the provider.
615 };
616 
617 // API formula parser wrapper =================================================
618 
619 /** A wrapper around the FormulaParser service provided by the Calc document. */
620 class ApiParserWrapper : public OpCodeProvider
621 {
622 public:
623     explicit            ApiParserWrapper(
624                             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxModelFactory,
625                             const OpCodeProvider& rOpCodeProv );
626 
627     /** Returns read/write access to the formula parser property set. */
628     inline PropertySet& getParserProperties() { return maParserProps; }
629 
630     /** Calls the XFormulaParser::parseFormula() function of the API parser. */
631     ApiTokenSequence    parseFormula(
632                             const ::rtl::OUString& rFormula,
633                             const ::com::sun::star::table::CellAddress& rRefPos );
634 
635 private:
636     ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XFormulaParser >
637                         mxParser;
638     PropertySet         maParserProps;
639 };
640 
641 // Formula parser/printer base class for filters ==============================
642 
643 /** Base class for import formula parsers and export formula compilers. */
644 class FormulaProcessorBase : public OpCodeProvider, protected ApiOpCodes, public WorkbookHelper
645 {
646 public:
647     explicit            FormulaProcessorBase( const WorkbookHelper& rHelper );
648 
649     // ------------------------------------------------------------------------
650 
651     /** Generates a cell address string in A1 notation from the passed cell
652         address.
653 
654         @param rAddress  The cell address containing column and row index.
655         @param bAbsolute  True = adds dollar signs before column and row.
656      */
657     static ::rtl::OUString generateAddress2dString(
658                             const ::com::sun::star::table::CellAddress& rAddress,
659                             bool bAbsolute );
660 
661     /** Generates a cell address string in A1 notation from the passed binary
662         cell address.
663 
664         @param rAddress  The cell address containing column and row index.
665         @param bAbsolute  True = adds dollar signs before column and row.
666      */
667     static ::rtl::OUString generateAddress2dString(
668                             const BinAddress& rAddress,
669                             bool bAbsolute );
670 
671     /** Generates a cell range string in A1:A1 notation from the passed cell
672         range address.
673 
674         @param rRange  The cell range address containing column and row indexes.
675         @param bAbsolute  True = adds dollar signs before columns and rows.
676      */
677     static ::rtl::OUString generateRange2dString(
678                             const ::com::sun::star::table::CellRangeAddress& rRange,
679                             bool bAbsolute );
680 
681     /** Generates a cell range string in A1:A1 notation from the passed binary
682         cell range address.
683 
684         @param rRange  The cell range address containing column and row indexes.
685         @param bAbsolute  True = adds dollar signs before columns and rows.
686      */
687     static ::rtl::OUString generateRange2dString(
688                             const BinRange& rRange,
689                             bool bAbsolute );
690 
691     /** Generates a cell range list string in A1:A1 notation from the passed
692         cell range addresses. May enclose multiple ranges into parentheses.
693 
694         @param rRanges  The list of cell range addresses.
695         @param bAbsolute  True = adds dollar signs before columns and rows.
696         @param cSeparator  Separator character between ranges.
697         @param bEncloseMultiple  True = enclose multiple ranges in parentheses.
698      */
699     static ::rtl::OUString generateRangeList2dString(
700                             const ApiCellRangeList& rRanges,
701                             bool bAbsolute,
702                             sal_Unicode cSeparator,
703                             bool bEncloseMultiple );
704 
705     // ------------------------------------------------------------------------
706 
707     /** Generates a cell address string in Calc's absolute $Sheet.$A$1 notation
708         from the passed cell address.
709 
710         @param rAddress  The cell address to be converted to a string.
711      */
712     ::rtl::OUString     generateApiAddressString(
713                             const ::com::sun::star::table::CellAddress& rAddress ) const;
714 
715     /** Generates a cell range string in Calc's absolute $Sheet.$A$1:$A$
716         notation from the passed cell range address.
717 
718         @param rRange  The cell range address to be converted to a string.
719      */
720     ::rtl::OUString     generateApiRangeString(
721                             const ::com::sun::star::table::CellRangeAddress& rRange ) const;
722 
723     /** Generates a cell range list string in Calc's absolute $Sheet.$A$1:$A$1
724         notation from the passed cell range addresses.
725 
726         @param rRanges  The list of cell ranges to be converted to a string.
727      */
728     ::rtl::OUString     generateApiRangeListString( const ApiCellRangeList& rRanges ) const;
729 
730     /** Generates a string in Calc formula notation from the passed string.
731 
732         @param rString  The string value.
733 
734         @return  The string enclosed in double quotes, where all contained
735             quote characters are doubled.
736      */
737     static ::rtl::OUString generateApiString( const ::rtl::OUString& rString );
738 
739     /** Generates an array string in Calc formula notation from the passed
740         matrix with Any's containing double values or strings.
741 
742         @param rMatrix  The matrix containing double values or strings.
743      */
744     static ::rtl::OUString generateApiArray( const Matrix< ::com::sun::star::uno::Any >& rMatrix );
745 
746     // ------------------------------------------------------------------------
747 
748     /** Tries to extract a single cell reference from a formula token sequence.
749 
750         @param rTokens  The token sequence to be parsed. Should contain exactly
751             one address token or cell range address token. The token sequence
752             may contain whitespace tokens.
753 
754         @return  If the token sequence is valid, this function returns an Any
755             containing a com.sun.star.sheet.SingleReference object, or a
756             com.sun.star.sheet.ComplexReference object. If the token sequence
757             contains too many, or unexpected tokens, an empty Any is returned.
758      */
759     ::com::sun::star::uno::Any
760                         extractReference( const ApiTokenSequence& rTokens ) const;
761 
762     /** Tries to extract a single cell address from a formula token sequence.
763 
764         @param orAddress  (output parameter) If the token sequence is valid,
765             this parameter will contain the extracted cell address. If the
766             token sequence contains unexpected tokens, nothing meaningful is
767             inserted, and the function returns false.
768 
769         @param rTokens  The token sequence to be parsed. Should contain exactly
770             one cell address token. The token sequence may contain whitespace
771             tokens.
772 
773         @param bAllowRelative  True = it is allowed that rTokens contains
774             relative references (based on cell A1 of the current sheet).
775             False = only real absolute references will be accepted.
776 
777         @return  True, if the token sequence contains a valid cell address
778             which has been extracted to orAddress, false otherwise.
779      */
780     bool                extractCellAddress(
781                             ::com::sun::star::table::CellAddress& orAddress,
782                             const ApiTokenSequence& rTokens,
783                             bool bAllowRelative ) const;
784 
785     /** Tries to extract a cell range address from a formula token sequence.
786 
787         @param orAddress  (output parameter) If the token sequence is valid,
788             this parameter will contain the extracted cell range address. If
789             the token sequence contains unexpected tokens, nothing meaningful
790             is inserted, and the function returns false.
791 
792         @param rTokens  The token sequence to be parsed. Should contain exactly
793             one cell range address token. The token sequence may contain
794             whitespace tokens.
795 
796         @param bAllowRelative  True = it is allowed that rTokens contains
797             relative references (based on cell A1 of the current sheet).
798             False = only real absolute references will be accepted.
799 
800         @return  True, if the token sequence contains a valid cell range
801             address which has been extracted to orRange, false otherwise.
802      */
803     bool                extractCellRange(
804                             ::com::sun::star::table::CellRangeAddress& orRange,
805                             const ApiTokenSequence& rTokens,
806                             bool bAllowRelative ) const;
807 
808     /** Tries to extract a cell range list from a formula token sequence.
809 
810         @param orRanges  (output parameter) If the token sequence is valid,
811             this parameter will contain the extracted cell range list. Deleted
812             cells or cell ranges (shown as #REF! error in a formula) will be
813             skipped. If the token sequence contains unexpected tokens, an empty
814             list is returned here.
815 
816         @param rTokens  The token sequence to be parsed. Should contain cell
817             address tokens or cell range address tokens, separated by the
818             standard function parameter separator token. The token sequence may
819             contain parentheses and whitespace tokens.
820 
821         @param bAllowRelative  True = it is allowed that rTokens contains
822             relative references (based on cell A1 of the current sheet).
823             False = only real absolute references will be accepted.
824 
825         @param nFilterBySheet  If non-negative, this function returns only cell
826             ranges located in the specified sheet, otherwise returns all cell
827             ranges contained in the token sequence.
828      */
829     void                extractCellRangeList(
830                             ApiCellRangeList& orRanges,
831                             const ApiTokenSequence& rTokens,
832                             bool bAllowRelative,
833                             sal_Int32 nFilterBySheet = -1 ) const;
834 
835     /** Tries to extract a string from a formula token sequence.
836 
837         @param orString  (output parameter) The extracted string.
838 
839         @param rTokens  The token sequence to be parsed. Should contain exactly
840             one string token, may contain whitespace tokens.
841 
842         @return  True = token sequence is valid, output parameter orString
843             contains the string extracted from the token sequence.
844      */
845     bool                extractString(
846                             ::rtl::OUString& orString,
847                             const ApiTokenSequence& rTokens ) const;
848 
849     /** Tries to extract information about a special token used for array
850         formulas, shared formulas, or table operations.
851 
852         @param orTokenInfo  (output parameter) The extracted information about
853             the token. Contains the base address and the token type (sal_False
854             for array or shared formulas, sal_True for table operations).
855 
856         @param rTokens  The token sequence to be parsed. If it contains exactly
857             one OPCODE_BAD token with special token information, this
858             information will be extracted.
859 
860         @return  True = token sequence is valid, output parameter orTokenInfo
861             contains the token information extracted from the token sequence.
862      */
863     bool                extractSpecialTokenInfo(
864                             ApiSpecialTokenInfo& orTokenInfo,
865                             const ApiTokenSequence& rTokens ) const;
866 
867     /** Converts a single string with separators in the passed formula token
868         sequence to a list of string tokens.
869 
870         @param orTokens  (input/output parameter) Expects a single string token
871             in this token sequence (whitespace tokens are allowed). The string
872             is split into substrings. A list of string tokens separated with
873             parameter separator tokens is returned in this psrameter.
874 
875         @param cStringSep  The separator character used to split the input
876             string.
877 
878         @param bTrimLeadingSpaces  True = removes leading whitespace from all
879             substrings inserted into the formula token sequence.
880      */
881     void                convertStringToStringList(
882                             ApiTokenSequence& orTokens,
883                             sal_Unicode cStringSep,
884                             bool bTrimLeadingSpaces ) const;
885 };
886 
887 // ============================================================================
888 
889 } // namespace xls
890 } // namespace oox
891 
892 #endif
893