xref: /aoo41x/main/sc/source/core/inc/parclass.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef SC_PARCLASS_HXX
29 #define SC_PARCLASS_HXX
30 
31 #include "formula/opcode.hxx"
32 #include <sys/types.h>  // size_t
33 
34 namespace formula
35 {
36     class FormulaToken;
37 }
38 
39 class ScParameterClassification
40 {
41 public:
42 
43     enum Type
44     {
45         Unknown = 0,    // MUST be zero for initialization mechanism!
46 
47         /** Out of bounds, function doesn't expect that many parameters.
48             However, not necessarily returned. */
49         Bounds,
50 
51         /** In array formula: single value to be passed. Results in JumpMatrix
52             being created and multiple calls to function. Functions handling a
53             formula::svDoubleRef by means of DoubleRefToPosSingleRef() or
54             PopDoubleRefOrSingleRef() or GetDouble() or GetString() should have
55             this. */
56         Value,
57 
58         /** In array formula: area reference must stay reference. Otherwise
59             don't care. Functions handling a formula::svDoubleRef by means of
60             PopDoubleRefOrSingleRef() should not have this. */
61         Reference,
62 
63         /** In array formula: convert area reference to array. Function will be
64             called only once if no Value type is involved. Functions able to
65             handle a svMatrix parameter but not a formula::svDoubleRef parameter as area
66             should have this. */
67         Array,
68 
69         /** Area reference must be converted to array in any case, and must
70             also be propagated to subsequent operators and functions being part
71             of a parameter of this function. */
72         ForceArray,
73 
74         /** Area reference is not converted to array, but ForceArray must be
75             propagated to subsequent operators and functions being part of a
76             parameter of this function. Used with functions that treat
77             references separately from arrays, but need the forced array
78             calculation of parameters that are not references.*/
79         ReferenceOrForceArray
80     };
81 
82                                 /// MUST be called once before any other method.
83     static  void                Init();
84 
85     static  void                Exit();
86 
87                                 /** Get one parameter type for function eOp.
88                                     @param nParameter
89                                         Which parameter, 0-based */
90     static  Type                GetParameterType( const formula::FormulaToken* pToken,
91                                         sal_uInt16 nParameter);
92 
93                                 /** Whether OpCode has a parameter of type
94                                     ForceArray or ReferenceOrForceArray. */
95     static  inline  bool        HasForceArray( OpCode eOp)
96                                     {
97                                         return 0 <= (short)eOp &&
98                                             eOp <= SC_OPCODE_LAST_OPCODE_ID &&
99                                             pData[eOp].bHasForceArray;
100                                     }
101 
102 private:
103 
104     struct CommonData
105     {
106         const static size_t nMaxParams = 7;
107 
108         Type        nParam[nMaxParams];
109         bool        bRepeatLast;
110     };
111 
112     // SUNWS7 needs a forward declared friend, otherwise members of the outer
113     // class are not accessible (in this case CommonData).
114     struct RawData;
115     friend struct ScParameterClassification::RawData;
116     struct RawData
117     {
118         OpCode      eOp;
119         CommonData  aData;
120     };
121 
122     struct RunData;
123     friend struct ScParameterClassification::RunData;
124     struct RunData
125     {
126         CommonData  aData;
127         sal_uInt8        nMinParams;         // fix or minimum, or repeat start
128         bool        bHasForceArray;
129     };
130 
131     static  const RawData       pRawData[];
132     static  RunData*            pData;
133 
134     // ocExternal AddIns
135     static  Type                GetExternalParameterType(
136                                     const formula::FormulaToken* pToken, sal_uInt16 nParameter);
137 
138 #if OSL_DEBUG_LEVEL > 1
139     // Generate documentation to stdout if environment variable
140     // OOO_CALC_GENPARCLASSDOC is set.
141     static  void                GenerateDocumentation();
142 
143     /* OpCodes not specified in the implementation are taken from the global
144      * function list and all parameters, if any, are assumed to be of type
145      * Value. This could also be done in the product version if needed, but we
146      * don't want to spoil startup time. However, doing so could propagate the
147      * minimum parameter count to the formula compiler, which, together with
148      * additional information about optional parameters, could react on missing
149      * parameters then. */
150     static  void                MergeArgumentsFromFunctionResource();
151 
152                                 /** Minimum number of parameters, or fix number
153                                     of parameters if HasRepeatParameters()
154                                     returns sal_False. For opcodes not specified in
155                                     the implementation a parameter count of 1
156                                     is assumed, for opcodes out of range 0 is
157                                     assumed. If HasRepeatParameters() returns
158                                     sal_True, information is NOT related to whether
159                                     any parameters are optional, only the type
160                                     of parameters is significant. */
161     static  inline  sal_uInt8        GetMinimumParameters( OpCode eOp)
162                                     {
163                                         if ( eOp <= SC_OPCODE_LAST_OPCODE_ID )
164                                             return pData[eOp].aData.nParam[0]
165                                                 == Unknown ? 1 :
166                                                 pData[eOp].nMinParams;
167                                         return 0;
168                                     }
169 
170                                 /** Whether last parameter type is repeated. */
171     static  inline  bool        HasRepeatParameters( OpCode eOp)
172                                     {
173                                         return eOp <= SC_OPCODE_LAST_OPCODE_ID
174                                             && pData[eOp].aData.bRepeatLast;
175                                     }
176 #endif // OSL_DEBUG_LEVEL
177 };
178 
179 #endif // SC_PARCLASS_HXX
180 
181