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