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