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