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