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