xref: /trunk/main/oox/inc/oox/xls/formulabase.hxx (revision 9b004a7b05cb3557beee722aecdce5c60ff2a1e9)
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