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