Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Component: ODS formula Engine
5 : * Purpose: Implementation of the ods_formula_node class used to represent a
6 : * node in a ODS expression.
7 : * Author: Even Rouault <even dot rouault at spatialys.com>
8 : *
9 : ******************************************************************************
10 : * Copyright (C) 2010 Frank Warmerdam <warmerdam@pobox.com>
11 : * Copyright (c) 2012, Even Rouault <even dot rouault at spatialys.com>
12 : *
13 : * SPDX-License-Identifier: MIT
14 : ****************************************************************************/
15 :
16 : #ifndef ODS_FORMULA_H_INCLUDED_
17 : #define ODS_FORMULA_H_INCLUDED_
18 :
19 : #include "cpl_conv.h"
20 : #include "cpl_string.h"
21 :
22 : #include <vector>
23 :
24 : #if defined(_WIN32)
25 : #define strcasecmp stricmp
26 : #endif
27 :
28 : typedef enum
29 : {
30 : ODS_OR,
31 : ODS_AND,
32 : ODS_NOT,
33 : ODS_IF,
34 :
35 : ODS_PI,
36 :
37 : ODS_SUM,
38 : ODS_AVERAGE,
39 : ODS_MIN,
40 : ODS_MAX,
41 : ODS_COUNT,
42 : ODS_COUNTA,
43 :
44 : // ODS_T,
45 : ODS_LEN,
46 : ODS_LEFT,
47 : ODS_RIGHT,
48 : ODS_MID,
49 :
50 : ODS_ABS,
51 : ODS_SQRT,
52 : ODS_COS,
53 : ODS_SIN,
54 : ODS_TAN,
55 : ODS_ACOS,
56 : ODS_ASIN,
57 : ODS_ATAN,
58 : ODS_EXP,
59 : ODS_LN,
60 : ODS_LOG,
61 :
62 : ODS_EQ,
63 : ODS_NE,
64 : ODS_LE,
65 : ODS_GE,
66 : ODS_LT,
67 : ODS_GT,
68 :
69 : ODS_ADD,
70 : ODS_SUBTRACT,
71 : ODS_MULTIPLY,
72 : ODS_DIVIDE,
73 : ODS_MODULUS,
74 :
75 : ODS_CONCAT,
76 :
77 : ODS_LIST,
78 :
79 : ODS_CELL,
80 : ODS_CELL_RANGE,
81 :
82 : ODS_INVALID
83 : } ods_formula_op;
84 :
85 : typedef enum
86 : {
87 : ODS_FIELD_TYPE_INTEGER,
88 : ODS_FIELD_TYPE_FLOAT,
89 : ODS_FIELD_TYPE_STRING,
90 : ODS_FIELD_TYPE_EMPTY
91 : } ods_formula_field_type;
92 :
93 : typedef enum
94 : {
95 : SNT_CONSTANT,
96 : SNT_OPERATION
97 : } ods_formula_node_type;
98 :
99 : class IODSCellEvaluator;
100 :
101 : // cppcheck-suppress copyCtorAndEqOperator
102 : class ods_formula_node
103 : {
104 : private:
105 : void FreeSubExpr();
106 : std::string TransformToString() const;
107 :
108 : bool EvaluateOR(IODSCellEvaluator *poEvaluator);
109 : bool EvaluateAND(IODSCellEvaluator *poEvaluator);
110 : bool EvaluateNOT(IODSCellEvaluator *poEvaluator);
111 : bool EvaluateIF(IODSCellEvaluator *poEvaluator);
112 :
113 : bool EvaluateLEN(IODSCellEvaluator *poEvaluator);
114 : bool EvaluateLEFT(IODSCellEvaluator *poEvaluator);
115 : bool EvaluateRIGHT(IODSCellEvaluator *poEvaluator);
116 : bool EvaluateMID(IODSCellEvaluator *poEvaluator);
117 :
118 : bool EvaluateListArgOp(IODSCellEvaluator *poEvaluator);
119 :
120 : bool EvaluateSingleArgOp(IODSCellEvaluator *poEvaluator);
121 :
122 : bool EvaluateEQ(IODSCellEvaluator *poEvaluator);
123 : bool EvaluateNE(IODSCellEvaluator *poEvaluator);
124 : bool EvaluateLE(IODSCellEvaluator *poEvaluator);
125 : bool EvaluateGE(IODSCellEvaluator *poEvaluator);
126 : bool EvaluateLT(IODSCellEvaluator *poEvaluator);
127 : bool EvaluateGT(IODSCellEvaluator *poEvaluator);
128 :
129 : bool EvaluateBinaryArithmetic(IODSCellEvaluator *poEvaluator);
130 :
131 : bool EvaluateCONCAT(IODSCellEvaluator *poEvaluator);
132 :
133 : bool EvaluateCELL(IODSCellEvaluator *poEvaluator);
134 :
135 : public:
136 : ods_formula_node();
137 :
138 : explicit ods_formula_node(
139 : const char *,
140 : ods_formula_field_type field_type_in = ODS_FIELD_TYPE_STRING);
141 : // cppcheck-suppress noExplicitConstructor
142 : explicit ods_formula_node(int);
143 : // cppcheck-suppress noExplicitConstructor
144 : explicit ods_formula_node(double);
145 : // cppcheck-suppress noExplicitConstructor
146 : explicit ods_formula_node(ods_formula_op);
147 :
148 : ods_formula_node(const ods_formula_node &other);
149 :
150 : ~ods_formula_node();
151 :
152 : void Initialize();
153 : void Dump(FILE *fp, int depth);
154 :
155 : bool Evaluate(IODSCellEvaluator *poEvaluator);
156 :
157 : ods_formula_node_type eNodeType;
158 : ods_formula_field_type field_type;
159 :
160 : /* only for SNT_OPERATION */
161 : void PushSubExpression(ods_formula_node *);
162 : void ReverseSubExpressions();
163 : ods_formula_op eOp;
164 : int nSubExprCount;
165 : ods_formula_node **papoSubExpr;
166 :
167 : /* only for SNT_CONSTANT */
168 : char *string_value;
169 : int int_value;
170 : double float_value;
171 : };
172 :
173 : class ods_formula_parse_context
174 : {
175 : public:
176 110 : ods_formula_parse_context()
177 110 : : nStartToken(0), pszInput(nullptr), pszNext(nullptr), poRoot(nullptr)
178 : {
179 110 : }
180 :
181 : int nStartToken;
182 : const char *pszInput;
183 : const char *pszNext;
184 :
185 : ods_formula_node *poRoot;
186 : };
187 :
188 : class IODSCellEvaluator
189 : {
190 : public:
191 : virtual int EvaluateRange(int nRow1, int nCol1, int nRow2, int nCol2,
192 : std::vector<ods_formula_node> &aoOutValues) = 0;
193 :
194 110 : virtual ~IODSCellEvaluator()
195 110 : {
196 110 : }
197 :
198 : int m_nDepth = 0;
199 : };
200 :
201 : ods_formula_node *ods_formula_compile(const char *expr);
202 :
203 : typedef struct
204 : {
205 : const char *pszName;
206 : ods_formula_op eOp;
207 : double (*pfnEval)(double);
208 : } SingleOpStruct;
209 :
210 : const SingleOpStruct *ODSGetSingleOpEntry(const char *pszName);
211 : const SingleOpStruct *ODSGetSingleOpEntry(ods_formula_op eOp);
212 :
213 : #endif /* def ODS_FORMULA_H_INCLUDED_ */
|