1 : /******************************************************************************
2 : * $Id: ods_formula.h 23831 2012-01-30 23:12:23Z rouault $
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 mines dash paris dot org>
8 : *
9 : ******************************************************************************
10 : * Copyright (C) 2010 Frank Warmerdam <warmerdam@pobox.com>
11 : * Copyright (c) 2012, Even Rouault <even dot rouault at mines dash paris dot org>
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #ifndef _ODS_FORMULA_H_INCLUDED_
33 : #define _ODS_FORMULA_H_INCLUDED_
34 :
35 : #include "cpl_conv.h"
36 : #include "cpl_string.h"
37 :
38 : #include <vector>
39 :
40 : #if defined(_WIN32) && !defined(_WIN32_WCE)
41 : # define strcasecmp stricmp
42 : #elif defined(_WIN32_WCE)
43 : # define strcasecmp _stricmp
44 : #endif
45 :
46 : typedef enum {
47 : ODS_OR,
48 : ODS_AND,
49 : ODS_NOT,
50 : ODS_IF,
51 :
52 : ODS_PI,
53 :
54 : ODS_SUM,
55 : ODS_AVERAGE,
56 : ODS_MIN,
57 : ODS_MAX,
58 : ODS_COUNT,
59 : ODS_COUNTA,
60 :
61 : //ODS_T,
62 : ODS_LEN,
63 : ODS_LEFT,
64 : ODS_RIGHT,
65 : ODS_MID,
66 :
67 : ODS_ABS,
68 : ODS_SQRT,
69 : ODS_COS,
70 : ODS_SIN,
71 : ODS_TAN,
72 : ODS_ACOS,
73 : ODS_ASIN,
74 : ODS_ATAN,
75 : ODS_EXP,
76 : ODS_LN,
77 : ODS_LOG,
78 :
79 : ODS_EQ,
80 : ODS_NE,
81 : ODS_LE,
82 : ODS_GE,
83 : ODS_LT,
84 : ODS_GT,
85 :
86 : ODS_ADD,
87 : ODS_SUBTRACT,
88 : ODS_MULTIPLY,
89 : ODS_DIVIDE,
90 : ODS_MODULUS,
91 :
92 : ODS_CONCAT,
93 :
94 : ODS_LIST,
95 :
96 : ODS_CELL,
97 : ODS_CELL_RANGE,
98 : } ods_formula_op;
99 :
100 : typedef enum {
101 : ODS_FIELD_TYPE_INTEGER,
102 : ODS_FIELD_TYPE_FLOAT,
103 : ODS_FIELD_TYPE_STRING,
104 : ODS_FIELD_TYPE_EMPTY
105 : } ods_formula_field_type;
106 :
107 : typedef enum {
108 : SNT_CONSTANT,
109 : SNT_OPERATION
110 : } ods_formula_node_type;
111 :
112 : class IODSCellEvaluator;
113 :
114 : class ods_formula_node {
115 : private:
116 : void FreeSubExpr();
117 : std::string TransformToString() const;
118 :
119 : int EvaluateOR(IODSCellEvaluator* poEvaluator);
120 : int EvaluateAND(IODSCellEvaluator* poEvaluator);
121 : int EvaluateNOT(IODSCellEvaluator* poEvaluator);
122 : int EvaluateIF(IODSCellEvaluator* poEvaluator);
123 :
124 : int EvaluateLEN(IODSCellEvaluator* poEvaluator);
125 : int EvaluateLEFT(IODSCellEvaluator* poEvaluator);
126 : int EvaluateRIGHT(IODSCellEvaluator* poEvaluator);
127 : int EvaluateMID(IODSCellEvaluator* poEvaluator);
128 :
129 : int EvaluateListArgOp(IODSCellEvaluator* poEvaluator);
130 :
131 : int EvaluateSingleArgOp(IODSCellEvaluator* poEvaluator);
132 :
133 : int EvaluateEQ(IODSCellEvaluator* poEvaluator);
134 : int EvaluateNE(IODSCellEvaluator* poEvaluator);
135 : int EvaluateLE(IODSCellEvaluator* poEvaluator);
136 : int EvaluateGE(IODSCellEvaluator* poEvaluator);
137 : int EvaluateLT(IODSCellEvaluator* poEvaluator);
138 : int EvaluateGT(IODSCellEvaluator* poEvaluator);
139 :
140 : int EvaluateBinaryArithmetic(IODSCellEvaluator* poEvaluator);
141 :
142 : int EvaluateCONCAT(IODSCellEvaluator* poEvaluator);
143 :
144 : int EvaluateCELL(IODSCellEvaluator* poEvaluator);
145 :
146 : public:
147 : ods_formula_node();
148 :
149 : ods_formula_node( const char *, ods_formula_field_type field_type_in = ODS_FIELD_TYPE_STRING );
150 : ods_formula_node( int );
151 : ods_formula_node( double );
152 : ods_formula_node( ods_formula_op );
153 :
154 : ods_formula_node( const ods_formula_node& other );
155 :
156 : ~ods_formula_node();
157 :
158 : void Initialize();
159 : void Dump( FILE *fp, int depth );
160 :
161 : int Evaluate(IODSCellEvaluator* poEvaluator);
162 :
163 : ods_formula_node_type eNodeType;
164 : ods_formula_field_type field_type;
165 :
166 : /* only for SNT_OPERATION */
167 : void PushSubExpression( ods_formula_node * );
168 : void ReverseSubExpressions();
169 : ods_formula_op eOp;
170 : int nSubExprCount;
171 : ods_formula_node **papoSubExpr;
172 :
173 : /* only for SNT_CONSTANT */
174 : char *string_value;
175 : int int_value;
176 : double float_value;
177 : };
178 :
179 : class ods_formula_parse_context {
180 : public:
181 116 : ods_formula_parse_context() : nStartToken(0), poRoot(NULL) {}
182 :
183 : int nStartToken;
184 : const char *pszInput;
185 : const char *pszNext;
186 :
187 : ods_formula_node *poRoot;
188 : };
189 :
190 : class IODSCellEvaluator
191 110 : {
192 : public:
193 : virtual int EvaluateRange(int nRow1, int nCol1, int nRow2, int nCol2,
194 : std::vector<ods_formula_node>& aoOutValues) = 0;
195 : };
196 :
197 : int ods_formulaparse( ods_formula_parse_context *context );
198 : int ods_formulalex( ods_formula_node **ppNode, ods_formula_parse_context *context );
199 : ods_formula_node* ods_formula_compile( const char *expr );
200 :
201 : typedef struct
202 : {
203 : const char *pszName;
204 : ods_formula_op eOp;
205 : double (*pfnEval)(double);
206 : } SingleOpStruct;
207 :
208 : const SingleOpStruct* ODSGetSingleOpEntry(const char* pszName);
209 : const SingleOpStruct* ODSGetSingleOpEntry(ods_formula_op eOp);
210 :
211 : #endif /* def _ODS_FORMULA_H_INCLUDED_ */
|