Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef SC_XLFORMULA_HXX
30 : : #define SC_XLFORMULA_HXX
31 : :
32 : : #include <map>
33 : : #include <formula/opcode.hxx>
34 : : #include "address.hxx"
35 : : #include "ftools.hxx"
36 : : #include <boost/shared_ptr.hpp>
37 : :
38 : : // Constants ==================================================================
39 : :
40 : : const size_t EXC_TOKARR_MAXLEN = 4096; /// Maximum size of a token array.
41 : :
42 : : // Token class flags ----------------------------------------------------------
43 : :
44 : : const sal_uInt8 EXC_TOKCLASS_MASK = 0x60;
45 : : const sal_uInt8 EXC_TOKCLASS_NONE = 0x00; /// 00-1F: Base tokens.
46 : : const sal_uInt8 EXC_TOKCLASS_REF = 0x20; /// 20-3F: Reference class tokens.
47 : : const sal_uInt8 EXC_TOKCLASS_VAL = 0x40; /// 40-5F: Value class tokens.
48 : : const sal_uInt8 EXC_TOKCLASS_ARR = 0x60; /// 60-7F: Array class tokens.
49 : :
50 : : // Base tokens ----------------------------------------------------------------
51 : :
52 : : const sal_uInt8 EXC_TOKID_MASK = 0x1F;
53 : :
54 : : const sal_uInt8 EXC_TOKID_NONE = 0x00; /// Placeholder for invalid token id.
55 : : const sal_uInt8 EXC_TOKID_EXP = 0x01; /// Array or shared formula reference.
56 : : const sal_uInt8 EXC_TOKID_TBL = 0x02; /// Multiple operation reference.
57 : : const sal_uInt8 EXC_TOKID_ADD = 0x03; /// Addition operator.
58 : : const sal_uInt8 EXC_TOKID_SUB = 0x04; /// Subtraction operator.
59 : : const sal_uInt8 EXC_TOKID_MUL = 0x05; /// Multiplication operator.
60 : : const sal_uInt8 EXC_TOKID_DIV = 0x06; /// Division operator.
61 : : const sal_uInt8 EXC_TOKID_POWER = 0x07; /// Power operator.
62 : : const sal_uInt8 EXC_TOKID_CONCAT = 0x08; /// String concatenation operator.
63 : : const sal_uInt8 EXC_TOKID_LT = 0x09; /// Less than operator.
64 : : const sal_uInt8 EXC_TOKID_LE = 0x0A; /// Less than or equal operator.
65 : : const sal_uInt8 EXC_TOKID_EQ = 0x0B; /// Equal operator.
66 : : const sal_uInt8 EXC_TOKID_GE = 0x0C; /// Greater than or equal operator.
67 : : const sal_uInt8 EXC_TOKID_GT = 0x0D; /// Greater than operator.
68 : : const sal_uInt8 EXC_TOKID_NE = 0x0E; /// Not equal operator.
69 : : const sal_uInt8 EXC_TOKID_ISECT = 0x0F; /// Intersection operator.
70 : : const sal_uInt8 EXC_TOKID_LIST = 0x10; /// List operator.
71 : : const sal_uInt8 EXC_TOKID_RANGE = 0x11; /// Range operator.
72 : : const sal_uInt8 EXC_TOKID_UPLUS = 0x12; /// Unary plus.
73 : : const sal_uInt8 EXC_TOKID_UMINUS = 0x13; /// Unary minus.
74 : : const sal_uInt8 EXC_TOKID_PERCENT = 0x14; /// Percent sign.
75 : : const sal_uInt8 EXC_TOKID_PAREN = 0x15; /// Parentheses.
76 : : const sal_uInt8 EXC_TOKID_MISSARG = 0x16; /// Missing argument.
77 : : const sal_uInt8 EXC_TOKID_STR = 0x17; /// String constant.
78 : : const sal_uInt8 EXC_TOKID_NLR = 0x18; /// Natural language reference (NLR).
79 : : const sal_uInt8 EXC_TOKID_ATTR = 0x19; /// Special attribute.
80 : : const sal_uInt8 EXC_TOKID_SHEET = 0x1A; /// Start of a sheet reference (BIFF2-BIFF4).
81 : : const sal_uInt8 EXC_TOKID_ENDSHEET = 0x1B; /// End of a sheet reference (BIFF2-BIFF4).
82 : : const sal_uInt8 EXC_TOKID_ERR = 0x1C; /// Error constant.
83 : : const sal_uInt8 EXC_TOKID_BOOL = 0x1D; /// Boolean constant.
84 : : const sal_uInt8 EXC_TOKID_INT = 0x1E; /// Integer constant.
85 : : const sal_uInt8 EXC_TOKID_NUM = 0x1F; /// Floating-point constant.
86 : :
87 : : // Base IDs of classified tokens ----------------------------------------------
88 : :
89 : : const sal_uInt8 EXC_TOKID_ARRAY = 0x00; /// Array constant.
90 : : const sal_uInt8 EXC_TOKID_FUNC = 0x01; /// Function, fixed number of arguments.
91 : : const sal_uInt8 EXC_TOKID_FUNCVAR = 0x02; /// Function, variable number of arguments.
92 : : const sal_uInt8 EXC_TOKID_NAME = 0x03; /// Defined name.
93 : : const sal_uInt8 EXC_TOKID_REF = 0x04; /// 2D cell reference.
94 : : const sal_uInt8 EXC_TOKID_AREA = 0x05; /// 2D area reference.
95 : : const sal_uInt8 EXC_TOKID_MEMAREA = 0x06; /// Constant reference subexpression.
96 : : const sal_uInt8 EXC_TOKID_MEMERR = 0x07; /// Deleted reference subexpression.
97 : : const sal_uInt8 EXC_TOKID_MEMNOMEM = 0x08; /// Constant reference subexpression without result.
98 : : const sal_uInt8 EXC_TOKID_MEMFUNC = 0x09; /// Variable reference subexpression.
99 : : const sal_uInt8 EXC_TOKID_REFERR = 0x0A; /// Deleted 2D cell reference.
100 : : const sal_uInt8 EXC_TOKID_AREAERR = 0x0B; /// Deleted 2D area reference.
101 : : const sal_uInt8 EXC_TOKID_REFN = 0x0C; /// Relative 2D cell reference (in names).
102 : : const sal_uInt8 EXC_TOKID_AREAN = 0x0D; /// Relative 2D area reference (in names).
103 : : const sal_uInt8 EXC_TOKID_MEMAREAN = 0x0E; /// Reference subexpression (in names).
104 : : const sal_uInt8 EXC_TOKID_MEMNOMEMN = 0x0F; /// Reference subexpression (in names) without result.
105 : : const sal_uInt8 EXC_TOKID_FUNCCE = 0x18;
106 : : const sal_uInt8 EXC_TOKID_NAMEX = 0x19; /// External reference.
107 : : const sal_uInt8 EXC_TOKID_REF3D = 0x1A; /// 3D cell reference.
108 : : const sal_uInt8 EXC_TOKID_AREA3D = 0x1B; /// 3D area reference.
109 : : const sal_uInt8 EXC_TOKID_REFERR3D = 0x1C; /// Deleted 3D cell reference.
110 : : const sal_uInt8 EXC_TOKID_AREAERR3D = 0x1D; /// Deleted 3D area reference
111 : :
112 : : // specific token constants ---------------------------------------------------
113 : :
114 : : const sal_uInt16 EXC_TOK_STR_MAXLEN = 255; /// Maximum string length of a tStr token.
115 : :
116 : : const sal_uInt8 EXC_TOK_BOOL_FALSE = 0; /// sal_False value of a tBool token.
117 : : const sal_uInt8 EXC_TOK_BOOL_TRUE = 1; /// sal_True value of a tBool token.
118 : :
119 : : const sal_uInt8 EXC_TOK_ATTR_VOLATILE = 0x01; /// Volatile function.
120 : : const sal_uInt8 EXC_TOK_ATTR_IF = 0x02; /// Start of true condition in IF function.
121 : : const sal_uInt8 EXC_TOK_ATTR_CHOOSE = 0x04; /// Jump array of CHOOSE function.
122 : : const sal_uInt8 EXC_TOK_ATTR_GOTO = 0x08; /// Jump to token.
123 : : const sal_uInt8 EXC_TOK_ATTR_SUM = 0x10; /// SUM function with one parameter.
124 : : const sal_uInt8 EXC_TOK_ATTR_ASSIGN = 0x20; /// BASIC style assignment.
125 : : const sal_uInt8 EXC_TOK_ATTR_SPACE = 0x40; /// Spaces in formula representation.
126 : :
127 : : const sal_uInt8 EXC_TOK_ATTR_SPACE_SP = 0x00; /// Spaces before next token.
128 : : const sal_uInt8 EXC_TOK_ATTR_SPACE_BR = 0x01; /// Line breaks before next token.
129 : : const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_OPEN = 0x02; /// Spaces before opening parenthesis.
130 : : const sal_uInt8 EXC_TOK_ATTR_SPACE_BR_OPEN = 0x03; /// Line breaks before opening parenthesis.
131 : : const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_CLOSE = 0x04; /// Spaces before closing parenthesis.
132 : : const sal_uInt8 EXC_TOK_ATTR_SPACE_BR_CLOSE = 0x05; /// Line breaks before closing parenthesis.
133 : : const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_PRE = 0x06; /// Spaces before formula (BIFF3).
134 : :
135 : : const sal_uInt16 EXC_TOK_FUNCVAR_CMD = 0x8000; /// Macro command.
136 : : const sal_uInt16 EXC_TOK_FUNCVAR_INDEXMASK = 0x7FFF; /// Mask for function/command index.
137 : : const sal_uInt8 EXC_TOK_FUNCVAR_PROMPT = 0x80; /// User prompt for macro commands.
138 : : const sal_uInt8 EXC_TOK_FUNCVAR_COUNTMASK = 0x7F; /// Mask for parameter count.
139 : :
140 : : const sal_uInt16 EXC_TOK_REF_COLREL = 0x4000; /// True = Column is relative.
141 : : const sal_uInt16 EXC_TOK_REF_ROWREL = 0x8000; /// True = Row is relative.
142 : :
143 : : const sal_uInt8 EXC_TOK_NLR_ERR = 0x01; /// NLR: Invalid/deleted.
144 : : const sal_uInt8 EXC_TOK_NLR_ROWR = 0x02; /// NLR: Row index.
145 : : const sal_uInt8 EXC_TOK_NLR_COLR = 0x03; /// NLR: Column index.
146 : : const sal_uInt8 EXC_TOK_NLR_ROWV = 0x06; /// NLR: Value in row.
147 : : const sal_uInt8 EXC_TOK_NLR_COLV = 0x07; /// NLR: Value in column.
148 : : const sal_uInt8 EXC_TOK_NLR_RANGE = 0x0A; /// NLR: Range.
149 : : const sal_uInt8 EXC_TOK_NLR_SRANGE = 0x0B; /// Stacked NLR: Range.
150 : : const sal_uInt8 EXC_TOK_NLR_SROWR = 0x0C; /// Stacked NLR: Row index.
151 : : const sal_uInt8 EXC_TOK_NLR_SCOLR = 0x0D; /// Stacked NLR: Column index.
152 : : const sal_uInt8 EXC_TOK_NLR_SROWV = 0x0E; /// Stacked NLR: Value in row.
153 : : const sal_uInt8 EXC_TOK_NLR_SCOLV = 0x0F; /// Stacked NLR: Value in column.
154 : : const sal_uInt8 EXC_TOK_NLR_RANGEERR = 0x10; /// NLR: Invalid/deleted range.
155 : : const sal_uInt8 EXC_TOK_NLR_SXNAME = 0x1D; /// NLR: Pivot table name.
156 : : const sal_uInt16 EXC_TOK_NLR_REL = 0x8000; /// True = Natural language ref is relative.
157 : :
158 : : const sal_uInt32 EXC_TOK_NLR_ADDREL = 0x80000000; /// NLR relative (in appended data).
159 : : const sal_uInt32 EXC_TOK_NLR_ADDMASK = 0x3FFFFFFF; /// Mask for number of appended ranges.
160 : :
161 : : // ----------------------------------------------------------------------------
162 : :
163 : : /** Type of a formula. */
164 : : enum XclFormulaType
165 : : {
166 : : EXC_FMLATYPE_CELL, /// Simple cell formula, also used in change tracking.
167 : : EXC_FMLATYPE_MATRIX, /// Matrix (array) formula.
168 : : EXC_FMLATYPE_SHARED, /// Shared formula.
169 : : EXC_FMLATYPE_CONDFMT, /// Conditional format.
170 : : EXC_FMLATYPE_DATAVAL, /// Data validation.
171 : : EXC_FMLATYPE_NAME, /// Defined name.
172 : : EXC_FMLATYPE_CHART, /// Chart source ranges.
173 : : EXC_FMLATYPE_CONTROL, /// Spreadsheet links in form controls.
174 : : EXC_FMLATYPE_WQUERY, /// Web query source range.
175 : : EXC_FMLATYPE_LISTVAL /// List (cell range) validation.
176 : : };
177 : :
178 : : // Function parameter info ====================================================
179 : :
180 : : /** Enumerates validity modes for a function parameter. */
181 : : enum XclFuncParamValidity
182 : : {
183 : : EXC_PARAM_NONE = 0, /// Default for an unspecified entry in a C-array.
184 : : EXC_PARAM_REGULAR, /// Parameter supported by Calc and Excel.
185 : : EXC_PARAM_CALCONLY, /// Parameter supported by Calc only.
186 : : EXC_PARAM_EXCELONLY /// Parameter supported by Excel only.
187 : : };
188 : :
189 : : /** Enumerates different types of token class conversion in function parameters. */
190 : : enum XclFuncParamConv
191 : : {
192 : : EXC_PARAMCONV_ORG, /// Use original class of current token.
193 : : EXC_PARAMCONV_VAL, /// Convert tokens to VAL class.
194 : : EXC_PARAMCONV_ARR, /// Convert tokens to ARR class.
195 : : EXC_PARAMCONV_RPT, /// Repeat parent conversion in VALTYPE parameters.
196 : : EXC_PARAMCONV_RPX, /// Repeat parent conversion in REFTYPE parameters.
197 : : EXC_PARAMCONV_RPO /// Repeat parent conversion in operands of operators.
198 : : };
199 : :
200 : : /** Structure that contains all needed information for a parameter in a
201 : : function.
202 : :
203 : : The member meValid specifies which application supports the parameter. If
204 : : set to CALCONLY, import filters have to insert a default value for this
205 : : parameter, and export filters have to skip the parameter. If set to
206 : : EXCELONLY, import filters have to skip the parameter, and export filters
207 : : have to insert a default value for this parameter.
208 : :
209 : : The member mbValType specifies whether the parameter requires tokens to be
210 : : of value type (VAL or ARR class).
211 : :
212 : : If set to false, the parameter is called to be REFTYPE. Tokens with REF
213 : : default class can be inserted for the parameter (e.g. tAreaR tokens).
214 : :
215 : : If set to true, the parameter is called to be VALTYPE. Tokens with REF
216 : : class need to be converted to VAL tokens first (e.g. tAreaR will be
217 : : converted to tAreaV), and further conversion is done according to this
218 : : new token class.
219 : :
220 : : The member meConv specifies how to convert the current token class of the
221 : : token inserted for the parameter. If the token class is still REF this
222 : : means that the token has default REF class and the parameter is REFTYPE
223 : : (see member mbValType), the token will not be converted at all and remains
224 : : in REF class. Otherwise, token class conversion is depending on the actual
225 : : token class of the return value of the function containing this parameter.
226 : : The function may return REF class (tFuncR, tFuncVarR, tFuncCER), or it may
227 : : return VAL or ARR class (tFuncV, tFuncA, tFuncVarV, tFuncVarA, tFuncCEV,
228 : : tFuncCEA). Even if the function is able to return REF class, it may return
229 : : VAL or ARR class instead due to the VALTYPE data type of the parent
230 : : function parameter that calls the own function. Example: The INDIRECT
231 : : function returns REF class by default. But if called from a VALTYPE
232 : : function parameter, e.g. in the formula =ABS(INDIRECT("A1")), it returns
233 : : VAL or ARR class instead. Additionally, the repeating conversion types RPT
234 : : and RPX rely on the conversion executed for the function token class.
235 : :
236 : : 1) ORG:
237 : : Use the original class of the token (VAL or ARR), regardless of any
238 : : conversion done for the function return class.
239 : :
240 : : 2) VAL:
241 : : Convert ARR tokens to VAL class, regardless of any conversion done for
242 : : the function return class.
243 : :
244 : : 3) ARR:
245 : : Convert VAL tokens to ARR class, regardless of any conversion done for
246 : : the function return class.
247 : :
248 : : 4) RPT:
249 : : If the own function returns REF class (thus it is called from a REFTYPE
250 : : parameter, see above), and the parent conversion type (for the function
251 : : return class) was ORG, VAL, or ARR, ignore that conversion and always
252 : : use VAL conversion for the own token instead. If the parent conversion
253 : : type was RPT or RPX, repeat the conversion that would have been used if
254 : : the function would return value type.
255 : : If the own function returns value type (VAL or ARR class, see above),
256 : : and the parent conversion type (for the function return class) was ORG,
257 : : VAL, ARR, or RPT, repeat this conversion for the own token. If the
258 : : parent conversion type was RPX, always use ORG conversion type for the
259 : : own token instead.
260 : :
261 : : 5) RPX:
262 : : This type of conversion only occurs in functions returning VAL class by
263 : : default. If the own token is value type, and the VAL return class of
264 : : the own function has been changed to ARR class (due to direct ARR
265 : : conversion, or due to ARR conversion repeated by RPT or RPX), set the
266 : : own token to ARR type. Otherwise use the original token type (VAL
267 : : conversion from parent parameter will not be repeated at all). If
268 : : nested functions have RPT or value-type RPX parameters, they will not
269 : : repeat this conversion type, but will use ORG conversion instead (see
270 : : description of RPT above).
271 : :
272 : : 6) RPO:
273 : : This type of conversion is only used for the operands of all operators
274 : : (unary and binary arithmetic operators, comparison operators, and range
275 : : operators). It is not used for function parameters. On conversion, it
276 : : will be replaced by the last conversion type that was not the RPO
277 : : conversion. This leads to a slightly different behaviour than the RPT
278 : : conversion for operands in conjunction with a parent RPX conversion.
279 : : */
280 : : struct XclFuncParamInfo
281 : : {
282 : : XclFuncParamValidity meValid; /// Parameter validity.
283 : : XclFuncParamConv meConv; /// Token class conversion type.
284 : : bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE).
285 : : };
286 : :
287 : : // Function data ==============================================================
288 : :
289 : : const sal_uInt8 EXC_FUNC_MAXPARAM = 30; /// Maximum parameter count.
290 : :
291 : : const size_t EXC_FUNCINFO_PARAMINFO_COUNT = 5; /// Number of parameter info entries.
292 : :
293 : : const sal_uInt8 EXC_FUNCFLAG_VOLATILE = 0x01; /// Result is volatile (e.g. NOW() function).
294 : : const sal_uInt8 EXC_FUNCFLAG_IMPORTONLY = 0x02; /// Only used in import filter.
295 : : const sal_uInt8 EXC_FUNCFLAG_EXPORTONLY = 0x04; /// Only used in export filter.
296 : :
297 : : // selected function IDs
298 : : const sal_uInt16 EXC_FUNCID_IF = 1;
299 : : const sal_uInt16 EXC_FUNCID_SUM = 4;
300 : : const sal_uInt16 EXC_FUNCID_AND = 36;
301 : : const sal_uInt16 EXC_FUNCID_OR = 37;
302 : : const sal_uInt16 EXC_FUNCID_CHOOSE = 100;
303 : : const sal_uInt16 EXC_FUNCID_EXTERNCALL = 255;
304 : :
305 : : /** Represents information for a spreadsheet function for import and export.
306 : :
307 : : The member mpParamInfos points to an array of type information structures
308 : : for all parameters of the function. The last initialized structure
309 : : describing a regular parameter (member meValid == EXC_PARAMVALID_ALWAYS) in
310 : : this array is used repeatedly for all following parameters supported by a
311 : : function.
312 : : */
313 : : struct XclFunctionInfo
314 : : {
315 : : OpCode meOpCode; /// Calc function opcode.
316 : : sal_uInt16 mnXclFunc; /// Excel function index.
317 : : sal_uInt8 mnMinParamCount; /// Minimum number of parameters.
318 : : sal_uInt8 mnMaxParamCount; /// Maximum number of parameters.
319 : : sal_uInt8 mnRetClass; /// Token class of the return value.
320 : : XclFuncParamInfo mpParamInfos[ EXC_FUNCINFO_PARAMINFO_COUNT ]; /// Information for all parameters.
321 : : sal_uInt8 mnFlags; /// Additional flags (EXC_FUNCFLAG_* constants).
322 : : const sal_Char* mpcMacroName; /// Function name, if simulated by a macro call (UTF-8).
323 : :
324 : : /** Returns true, if the function is volatile. */
325 : 0 : inline bool IsVolatile() const { return ::get_flag( mnFlags, EXC_FUNCFLAG_VOLATILE ); }
326 : : /** Returns true, if the function parameter count is fixed. */
327 [ # # ][ # # ]: 0 : inline bool IsFixedParamCount() const { return (mnXclFunc != EXC_FUNCID_EXTERNCALL) && (mnMinParamCount == mnMaxParamCount); }
328 : : /** Returns true, if the function is simulated by a macro call. */
329 : 52635 : inline bool IsMacroFunc() const { return mpcMacroName != 0; }
330 : : /** Returns the name of the external function as string. */
331 : : String GetMacroFuncName() const;
332 : : };
333 : :
334 : : // ----------------------------------------------------------------------------
335 : :
336 : : class XclRoot;
337 : :
338 : : /** Provides access to function info structs for all available functions. */
339 : 165 : class XclFunctionProvider
340 : : {
341 : : public:
342 : : explicit XclFunctionProvider( const XclRoot& rRoot );
343 : :
344 : : /** Returns the function data for an Excel function index, or 0 on error. */
345 : : const XclFunctionInfo* GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const;
346 : : /** Returns the function data for an Excel function simulated by a macro call, or 0 on error. */
347 : : const XclFunctionInfo* GetFuncInfoFromXclMacroName( const String& rXclMacroName ) const;
348 : : /** Returns the function data for a Calc opcode, or 0 on error. */
349 : : const XclFunctionInfo* GetFuncInfoFromOpCode( OpCode eOpCode ) const;
350 : :
351 : : private:
352 : : void FillXclFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd );
353 : : void FillScFuncMap( const XclFunctionInfo* pBeg, const XclFunctionInfo* pEnd );
354 : :
355 : : private:
356 : : typedef ::std::map< sal_uInt16, const XclFunctionInfo* > XclFuncMap;
357 : : typedef ::std::map< String, const XclFunctionInfo* > XclMacroNameMap;
358 : : typedef ::std::map< OpCode, const XclFunctionInfo* > ScFuncMap;
359 : :
360 : : XclFuncMap maXclFuncMap; /// Maps Excel function indexes to function data.
361 : : XclMacroNameMap maXclMacroNameMap; /// Maps macro function names to function data.
362 : : ScFuncMap maScFuncMap; /// Maps Calc opcodes to function data.
363 : : };
364 : :
365 : : // Token array ================================================================
366 : :
367 : : class XclImpStream;
368 : : class XclExpStream;
369 : :
370 : : /** Binary representation of an Excel token array. */
371 : 21 : class XclTokenArray
372 : : {
373 : : public:
374 : : /** Creates an empty token array. */
375 : : explicit XclTokenArray( bool bVolatile = false );
376 : : /** Creates a token array, swaps passed token vectors into own data. */
377 : : explicit XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile = false );
378 : :
379 : : /** Returns true, if the token array is empty. */
380 : 21 : inline bool Empty() const { return maTokVec.empty(); }
381 : : /** Returns the size of the token array in bytes. */
382 : : sal_uInt16 GetSize() const;
383 : : /** Returns read-only access to the byte vector storing token data. */
384 [ - + ]: 21 : inline const sal_uInt8* GetData() const { return maTokVec.empty() ? 0 : &maTokVec.front(); }
385 : : /** Returns true, if the formula contains a volatile function. */
386 : 0 : inline bool IsVolatile() const { return mbVolatile; }
387 : :
388 : : /** Reads the size field of the token array. */
389 : : void ReadSize( XclImpStream& rStrm );
390 : : /** Reads the tokens of the token array (without size field). */
391 : : void ReadArray( XclImpStream& rStrm );
392 : : /** Reads size field and the tokens. */
393 : : void Read( XclImpStream& rStrm );
394 : :
395 : : /** Writes the size field of the token array. */
396 : : void WriteSize( XclExpStream& rStrm ) const;
397 : : /** Writes the tokens of the token array (without size field). */
398 : : void WriteArray( XclExpStream& rStrm ) const;
399 : : /** Writes size field and the tokens. */
400 : : void Write( XclExpStream& rStrm ) const;
401 : :
402 : : /** Compares this token array with the passed. */
403 : : bool operator==( const XclTokenArray& rTokArr ) const;
404 : :
405 : : private:
406 : : ScfUInt8Vec maTokVec; /// Byte vector containing token data.
407 : : ScfUInt8Vec maExtDataVec; /// Byte vector containing extended data (arrays, stacked NLRs).
408 : : bool mbVolatile; /// True = Formula contains volatile function.
409 : : };
410 : :
411 : : typedef boost::shared_ptr< XclTokenArray > XclTokenArrayRef;
412 : :
413 : : /** Calls the Read() function at the passed token array. */
414 : : XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr );
415 : : /** Calls the Read() function at the passed token array. */
416 : : XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArrayRef& rxTokArr );
417 : : /** Calls the Write() function at the passed token array. */
418 : : XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArray& rTokArr );
419 : : /** Calls the Write() function at the passed token array. */
420 : : XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr );
421 : :
422 : : // ----------------------------------------------------------------------------
423 : :
424 : : namespace formula { class FormulaToken; }
425 : : class ScTokenArray;
426 : :
427 : : /** Special token array iterator for the Excel filters.
428 : :
429 : : Iterates over a Calc token array without modifying it (therefore the
430 : : iterator can be used with constant token arrays).
431 : :
432 : : Usage: Construct a new iterator object and pass a Calc token array, or use
433 : : the Init() function to assign another Calc token array. As long as the Is()
434 : : function returns true, the accessor functions can be used to get the
435 : : current Calc token.
436 : : */
437 : : class XclTokenArrayIterator
438 : : {
439 : : public:
440 : : explicit XclTokenArrayIterator();
441 : : explicit XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces );
442 : : /** Copy constructor that allows to change the skip-spaces mode. */
443 : : explicit XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces );
444 : :
445 : : void Init( const ScTokenArray& rScTokArr, bool bSkipSpaces );
446 : :
447 : 0 : inline bool Is() const { return mppScToken != 0; }
448 : 0 : inline bool operator!() const { return !Is(); }
449 [ # # ]: 0 : inline const ::formula::FormulaToken* Get() const { return mppScToken ? *mppScToken : 0; }
450 : 0 : inline const ::formula::FormulaToken* operator->() const { return Get(); }
451 : 0 : inline const ::formula::FormulaToken& operator*() const { return *Get(); }
452 : :
453 : : XclTokenArrayIterator& operator++();
454 : :
455 : : private:
456 : : void NextRawToken();
457 : : void SkipSpaces();
458 : :
459 : : private:
460 : : const ::formula::FormulaToken*const* mppScTokenBeg; /// Pointer to first token pointer of token array.
461 : : const ::formula::FormulaToken*const* mppScTokenEnd; /// Pointer behind last token pointer of token array.
462 : : const ::formula::FormulaToken*const* mppScToken; /// Pointer to current token pointer of token array.
463 : : bool mbSkipSpaces; /// true = Skip whitespace tokens.
464 : : };
465 : :
466 : : // ----------------------------------------------------------------------------
467 : :
468 : : /** Contains all cell references that can be extracted from a multiple operations formula. */
469 : 0 : struct XclMultipleOpRefs
470 : : {
471 : : ScAddress maFmlaScPos; /// Position of the (first) formula cell.
472 : : ScAddress maColFirstScPos;
473 : : ScAddress maColRelScPos;
474 : : ScAddress maRowFirstScPos;
475 : : ScAddress maRowRelScPos;
476 : : bool mbDblRefMode; /// true = One formula with row and column values.
477 : : };
478 : :
479 : : // ----------------------------------------------------------------------------
480 : :
481 : : /** A helper with Excel specific token array functions.
482 : :
483 : : The purpose to not add these functions to ScTokenArray is to prevent code
484 : : changes in low-level Calc headers and to keep the Excel specific source
485 : : code in the filter directory. Deriving from ScTokenArray is not viable
486 : : because that would need expensive copy-constructions of the token arrays.
487 : : */
488 : 55 : class XclTokenArrayHelper
489 : : {
490 : : public:
491 : : // token identifiers ------------------------------------------------------
492 : :
493 : : /** Returns the base token ID of the passed (classified) token ID. */
494 : : inline static sal_uInt8 GetBaseTokenId( sal_uInt8 nTokenId ) { return nTokenId & EXC_TOKID_MASK; }
495 : : /** Returns the classified token ID from a base ID and the token class. */
496 : : inline static sal_uInt8 GetTokenId( sal_uInt8 nBaseId, sal_uInt8 nTokenClass );
497 : :
498 : : /** Returns the token class of the passed token ID. */
499 : 0 : inline static sal_uInt8 GetTokenClass( sal_uInt8 nTokenId ) { return nTokenId & EXC_TOKCLASS_MASK; }
500 : : /** Changes the token class in the passed classified token ID. */
501 : : inline static void ChangeTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nTokenClass );
502 : :
503 : : // strings and string lists -----------------------------------------------
504 : :
505 : : /** Tries to extract a string from the passed token.
506 : : @param rString (out-parameter) The string contained in the token.
507 : : @return true = Passed token is a string token, rString parameter is valid. */
508 : : static bool GetTokenString( String& rString, const ::formula::FormulaToken& rScToken );
509 : :
510 : : /** Parses the passed formula and tries to find a single string token, i.e. "abc".
511 : : @param rString (out-parameter) The string contained in the formula.
512 : : @return true = String token found, rString parameter is valid. */
513 : : static bool GetString( String& rString, const ScTokenArray& rScTokArr );
514 : :
515 : : /** Parses the passed formula and tries to find a string token list, i.e. "abc";"def";"ghi".
516 : : @descr Returns the unquoted (!) strings in a single string, separated with the
517 : : passed character. If a comma is specified, the function will return abc,def,ghi from
518 : : the example above.
519 : : @param rStringList (out-parameter) All strings contained in the formula as list.
520 : : @param cSep List separator character.
521 : : @return true = String token list found, rString parameter is valid. */
522 : : static bool GetStringList( String& rStringList, const ScTokenArray& rScTokArr, sal_Unicode cSep );
523 : :
524 : : /** Tries to convert a formula that consists of a single string token to a list of strings.
525 : : @descr Example: The formula ="abc\ndef\nghi" will be converted to the formula
526 : : ="abc";"def";"ghi", if the LF character is specified as separator.
527 : : @param rScTokArr (in/out-parameter) The token array to modify.
528 : : @param cStringSep The separator in the source string.
529 : : @param bTrimLeadingSpaces true = remove leading spaces from each token. */
530 : : static void ConvertStringToList( ScTokenArray& rScTokArr, sal_Unicode cStringSep, bool bTrimLeadingSpaces );
531 : :
532 : : // shared formulas --------------------------------------------------------
533 : :
534 : : /** Tries to extract the definition of a shared formula from the passed token array.
535 : : @descr Shared formulas are stored as hidden defined names in Calc. This
536 : : function looks if the passed token array consists of the reference to
537 : : such a hidden defined name and returns its definition on success. */
538 : : static const ScTokenArray* GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr );
539 : :
540 : : // multiple operations ----------------------------------------------------
541 : :
542 : : /** Parses the passed formula and tries to extract references of a multiple operation.
543 : : @descr Requires that the formula contains a single MULTIPLE.OPERATION function call.
544 : : Spaces in the formula are silently ignored.
545 : : @return true = Multiple operation found, and all references successfully extracted. */
546 : : static bool GetMultipleOpRefs( XclMultipleOpRefs& rRefs, const ScTokenArray& rScTokArr );
547 : : };
548 : :
549 : : // ----------------------------------------------------------------------------
550 : :
551 : 22 : inline sal_uInt8 XclTokenArrayHelper::GetTokenId( sal_uInt8 nBaseId, sal_uInt8 nTokenClass )
552 : : {
553 : : OSL_ENSURE( !::get_flag( nBaseId, static_cast< sal_uInt8 >( ~EXC_TOKID_MASK ) ), "XclTokenArrayHelper::GetTokenId - invalid token ID" );
554 : : OSL_ENSURE( !::get_flag( nTokenClass, static_cast< sal_uInt8 >( ~EXC_TOKCLASS_MASK ) ), "XclTokenArrayHelper::GetTokenId - invalid token class" );
555 : 22 : return nBaseId | nTokenClass;
556 : : }
557 : :
558 : 0 : inline void XclTokenArrayHelper::ChangeTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nTokenClass )
559 : : {
560 : : OSL_ENSURE( !::get_flag( nTokenClass, static_cast< sal_uInt8 >( ~EXC_TOKCLASS_MASK ) ), "XclTokenArrayHelper::ChangeTokenClass - invalid token class" );
561 : 0 : ::set_flag( rnTokenId, EXC_TOKCLASS_MASK, false );
562 : 0 : ::set_flag( rnTokenId, nTokenClass );
563 : 0 : }
564 : :
565 : : // ============================================================================
566 : :
567 : : #endif
568 : :
569 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|