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