1 : /******************************************************************************
2 : * $Id: ods_formula_node.cpp 25340 2012-12-21 20:30:21Z 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 : #include "cpl_conv.h"
33 : #include "ods_formula.h"
34 :
35 : #ifndef PI
36 : #define PI 3.14159265358979323846
37 : #endif
38 :
39 : /************************************************************************/
40 : /* ods_formula_node() */
41 : /************************************************************************/
42 :
43 6 : ods_formula_node::ods_formula_node()
44 :
45 : {
46 6 : Initialize();
47 6 : }
48 :
49 : /************************************************************************/
50 : /* ods_formula_node(int) */
51 : /************************************************************************/
52 :
53 110 : ods_formula_node::ods_formula_node( int nValueIn )
54 :
55 : {
56 110 : Initialize();
57 :
58 110 : field_type = ODS_FIELD_TYPE_INTEGER;
59 110 : int_value = nValueIn;
60 110 : }
61 :
62 : /************************************************************************/
63 : /* ods_formula_node(double) */
64 : /************************************************************************/
65 :
66 62 : ods_formula_node::ods_formula_node( double dfValueIn )
67 :
68 : {
69 62 : Initialize();
70 :
71 62 : field_type = ODS_FIELD_TYPE_FLOAT;
72 62 : float_value = dfValueIn;
73 62 : }
74 :
75 : /************************************************************************/
76 : /* ods_formula_node(const char*) */
77 : /************************************************************************/
78 :
79 97 : ods_formula_node::ods_formula_node( const char *pszValueIn,
80 : ods_formula_field_type field_type_in )
81 :
82 : {
83 97 : Initialize();
84 :
85 97 : field_type = field_type_in;
86 97 : string_value = CPLStrdup( pszValueIn ? pszValueIn : "" );
87 97 : }
88 :
89 : /************************************************************************/
90 : /* ods_formula_node(ods_formula_op) */
91 : /************************************************************************/
92 :
93 167 : ods_formula_node::ods_formula_node( ods_formula_op eOpIn )
94 :
95 : {
96 167 : Initialize();
97 :
98 167 : eNodeType = SNT_OPERATION;
99 :
100 167 : eOp = eOpIn;
101 167 : }
102 :
103 : /************************************************************************/
104 : /* ods_formula_node(const ods_formula_node&) */
105 : /************************************************************************/
106 :
107 61 : ods_formula_node::ods_formula_node( const ods_formula_node& other )
108 : {
109 61 : eNodeType = other.eNodeType;
110 61 : eOp = other.eOp;
111 61 : field_type = other.field_type;
112 61 : int_value = other.int_value;
113 61 : float_value = other.float_value;
114 61 : string_value = other.string_value ? CPLStrdup(other.string_value) : NULL;
115 61 : nSubExprCount = other.nSubExprCount;
116 61 : if (nSubExprCount)
117 : {
118 : papoSubExpr = (ods_formula_node **)
119 0 : CPLMalloc( sizeof(void*) * nSubExprCount );
120 0 : for(int i=0;i<nSubExprCount;i++)
121 : {
122 0 : papoSubExpr[i] = new ods_formula_node( *(other.papoSubExpr[i]) );
123 : }
124 : }
125 : else
126 61 : papoSubExpr = NULL;
127 61 : }
128 :
129 : /************************************************************************/
130 : /* Initialize() */
131 : /************************************************************************/
132 :
133 442 : void ods_formula_node::Initialize()
134 :
135 : {
136 442 : eNodeType = SNT_CONSTANT;
137 442 : field_type = ODS_FIELD_TYPE_EMPTY;
138 442 : int_value = 0;
139 442 : float_value = 0;
140 442 : string_value = NULL;
141 442 : papoSubExpr = NULL;
142 442 : nSubExprCount = 0;
143 442 : }
144 :
145 : /************************************************************************/
146 : /* ~ods_formula_node() */
147 : /************************************************************************/
148 :
149 503 : ods_formula_node::~ods_formula_node()
150 :
151 : {
152 503 : CPLFree( string_value );
153 503 : FreeSubExpr();
154 503 : }
155 :
156 : /************************************************************************/
157 : /* PushSubExpression() */
158 : /************************************************************************/
159 :
160 283 : void ods_formula_node::PushSubExpression( ods_formula_node *child )
161 :
162 : {
163 283 : nSubExprCount++;
164 : papoSubExpr = (ods_formula_node **)
165 283 : CPLRealloc( papoSubExpr, sizeof(void*) * nSubExprCount );
166 :
167 283 : papoSubExpr[nSubExprCount-1] = child;
168 283 : }
169 :
170 : /************************************************************************/
171 : /* ReverseSubExpressions() */
172 : /************************************************************************/
173 :
174 14 : void ods_formula_node::ReverseSubExpressions()
175 :
176 : {
177 : int i;
178 23 : for( i = 0; i < nSubExprCount / 2; i++ )
179 : {
180 : ods_formula_node *temp;
181 :
182 9 : temp = papoSubExpr[i];
183 9 : papoSubExpr[i] = papoSubExpr[nSubExprCount - i - 1];
184 9 : papoSubExpr[nSubExprCount - i - 1] = temp;
185 : }
186 14 : }
187 :
188 : /************************************************************************/
189 : /* GetOperatorName() */
190 : /************************************************************************/
191 :
192 0 : static const char* ODSGetOperatorName( ods_formula_op eOp )
193 : {
194 0 : switch (eOp)
195 : {
196 0 : case ODS_OR : return "OR";
197 0 : case ODS_AND : return "AND";
198 0 : case ODS_NOT : return "NOT";
199 0 : case ODS_IF : return "IF";
200 :
201 0 : case ODS_PI : return "PI";
202 :
203 : //case ODS_T : return "T";
204 0 : case ODS_LEN : return "LEN";
205 0 : case ODS_LEFT : return "LEFT";
206 0 : case ODS_RIGHT : return "RIGHT";
207 0 : case ODS_MID : return "MID";
208 :
209 0 : case ODS_SUM : return "SUM";
210 0 : case ODS_AVERAGE : return "AVERAGE";
211 0 : case ODS_MIN : return "MIN";
212 0 : case ODS_MAX : return "MAX";
213 0 : case ODS_COUNT : return "COUNT";
214 0 : case ODS_COUNTA : return "COUNTA";
215 :
216 0 : case ODS_EQ : return "=";
217 0 : case ODS_NE : return "<>";
218 0 : case ODS_GE : return ">=";
219 0 : case ODS_LE : return "<=";
220 0 : case ODS_LT : return "<";
221 0 : case ODS_GT : return ">";
222 :
223 0 : case ODS_ADD : return "+";
224 0 : case ODS_SUBTRACT : return "-";
225 0 : case ODS_MULTIPLY : return "*";
226 0 : case ODS_DIVIDE : return "/";
227 0 : case ODS_MODULUS : return "MOD";
228 0 : case ODS_CONCAT : return "&";
229 :
230 0 : case ODS_LIST : return "*list*";
231 0 : case ODS_CELL : return "*cell*";
232 0 : case ODS_CELL_RANGE : return "*cell_range*";
233 : default:
234 : {
235 0 : const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(eOp);
236 0 : if (psSingleOp != NULL)
237 0 : return psSingleOp->pszName;
238 0 : return "*unknown*";
239 : }
240 : }
241 : }
242 :
243 : /************************************************************************/
244 : /* Dump() */
245 : /************************************************************************/
246 :
247 0 : void ods_formula_node::Dump( FILE * fp, int depth )
248 :
249 : {
250 : char spaces[60];
251 : int i;
252 :
253 0 : for( i = 0; i < depth*2 && i < (int) sizeof(spaces); i++ )
254 0 : spaces[i] = ' ';
255 0 : spaces[i] = '\0';
256 :
257 0 : if( eNodeType == SNT_CONSTANT )
258 : {
259 0 : if( field_type == ODS_FIELD_TYPE_INTEGER )
260 0 : fprintf( fp, "%s %d\n", spaces, int_value );
261 0 : else if( field_type == ODS_FIELD_TYPE_FLOAT )
262 0 : fprintf( fp, "%s %.15g\n", spaces, float_value );
263 : else
264 0 : fprintf( fp, "%s \"%s\"\n", spaces, string_value );
265 0 : return;
266 : }
267 :
268 0 : CPLAssert( eNodeType == SNT_OPERATION );
269 :
270 0 : fprintf( fp, "%s%s\n", spaces, ODSGetOperatorName(eOp) );
271 :
272 0 : for( i = 0; i < nSubExprCount; i++ )
273 0 : papoSubExpr[i]->Dump( fp, depth+1 );
274 : }
275 :
276 : /************************************************************************/
277 : /* FreeSubExpr() */
278 : /************************************************************************/
279 :
280 639 : void ods_formula_node::FreeSubExpr()
281 : {
282 : int i;
283 922 : for( i = 0; i < nSubExprCount; i++ )
284 283 : delete papoSubExpr[i];
285 639 : CPLFree( papoSubExpr );
286 :
287 639 : nSubExprCount = 0;
288 639 : papoSubExpr = NULL;
289 639 : }
290 :
291 : /************************************************************************/
292 : /* Evaluate() */
293 : /************************************************************************/
294 :
295 339 : int ods_formula_node::Evaluate(IODSCellEvaluator* poEvaluator)
296 : {
297 339 : if (eNodeType == SNT_CONSTANT)
298 192 : return TRUE;
299 :
300 147 : CPLAssert( eNodeType == SNT_OPERATION );
301 :
302 147 : switch (eOp)
303 : {
304 4 : case ODS_OR: return EvaluateOR(poEvaluator);
305 4 : case ODS_AND: return EvaluateAND(poEvaluator);
306 2 : case ODS_NOT: return EvaluateNOT(poEvaluator);
307 4 : case ODS_IF: return EvaluateIF(poEvaluator);
308 :
309 : case ODS_PI:
310 1 : eNodeType = SNT_CONSTANT;
311 1 : field_type = ODS_FIELD_TYPE_FLOAT;
312 1 : float_value = PI;
313 1 : return TRUE;
314 :
315 1 : case ODS_LEN : return EvaluateLEN(poEvaluator);
316 3 : case ODS_LEFT : return EvaluateLEFT(poEvaluator);
317 3 : case ODS_RIGHT : return EvaluateRIGHT(poEvaluator);
318 8 : case ODS_MID : return EvaluateMID(poEvaluator);
319 :
320 : case ODS_SUM:
321 : case ODS_AVERAGE:
322 : case ODS_MIN:
323 : case ODS_MAX:
324 : case ODS_COUNT:
325 : case ODS_COUNTA:
326 6 : return EvaluateListArgOp(poEvaluator);
327 :
328 : case ODS_ABS:
329 : case ODS_SQRT:
330 : case ODS_COS:
331 : case ODS_SIN:
332 : case ODS_TAN:
333 : case ODS_ACOS:
334 : case ODS_ASIN:
335 : case ODS_ATAN:
336 : case ODS_EXP:
337 : case ODS_LN:
338 : case ODS_LOG:
339 9 : return EvaluateSingleArgOp(poEvaluator);
340 :
341 :
342 10 : case ODS_EQ: return EvaluateEQ(poEvaluator);
343 10 : case ODS_NE: return EvaluateNE(poEvaluator);
344 10 : case ODS_LE: return EvaluateLE(poEvaluator);
345 10 : case ODS_GE: return EvaluateGE(poEvaluator);
346 14 : case ODS_LT: return EvaluateLT(poEvaluator);
347 10 : case ODS_GT: return EvaluateGT(poEvaluator);
348 :
349 : case ODS_ADD:
350 : case ODS_SUBTRACT:
351 : case ODS_MULTIPLY:
352 : case ODS_DIVIDE:
353 : case ODS_MODULUS:
354 9 : return EvaluateBinaryArithmetic(poEvaluator);
355 :
356 1 : case ODS_CONCAT: return EvaluateCONCAT(poEvaluator);
357 :
358 28 : case ODS_CELL: return EvaluateCELL(poEvaluator);
359 :
360 : default:
361 : {
362 : CPLError(CE_Failure, CPLE_AppDefined,
363 : "Unhandled case in Evaluate() for %s",
364 0 : ODSGetOperatorName(eOp));
365 0 : return FALSE;
366 : }
367 : }
368 : }
369 :
370 : /************************************************************************/
371 : /* EvaluateOR() */
372 : /************************************************************************/
373 :
374 4 : int ods_formula_node::EvaluateOR(IODSCellEvaluator* poEvaluator)
375 : {
376 4 : CPLAssert( eNodeType == SNT_OPERATION );
377 4 : CPLAssert( eOp == ODS_OR );
378 :
379 4 : CPLAssert(nSubExprCount == 1);
380 4 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_OPERATION );
381 4 : CPLAssert(papoSubExpr[0]->eOp == ODS_LIST );
382 4 : int bVal = FALSE;
383 12 : for(int i = 0; i < papoSubExpr[0]->nSubExprCount; i++)
384 : {
385 8 : if (!(papoSubExpr[0]->papoSubExpr[i]->Evaluate(poEvaluator)))
386 0 : return FALSE;
387 8 : CPLAssert(papoSubExpr[0]->papoSubExpr[i]->eNodeType == SNT_CONSTANT );
388 8 : if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_INTEGER)
389 : {
390 8 : bVal |= (papoSubExpr[0]->papoSubExpr[i]->int_value != 0);
391 : }
392 0 : else if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_FLOAT)
393 : {
394 0 : bVal |= (papoSubExpr[0]->papoSubExpr[i]->float_value != 0);
395 : }
396 : else
397 : {
398 : CPLError(CE_Failure, CPLE_NotSupported,
399 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
400 0 : return FALSE;
401 : }
402 : }
403 :
404 4 : FreeSubExpr();
405 :
406 4 : eNodeType = SNT_CONSTANT;
407 4 : field_type = ODS_FIELD_TYPE_INTEGER;
408 4 : int_value = bVal;
409 :
410 4 : return TRUE;
411 : }
412 :
413 : /************************************************************************/
414 : /* EvaluateAND() */
415 : /************************************************************************/
416 :
417 4 : int ods_formula_node::EvaluateAND(IODSCellEvaluator* poEvaluator)
418 : {
419 4 : CPLAssert( eNodeType == SNT_OPERATION );
420 4 : CPLAssert( eOp == ODS_AND );
421 :
422 4 : CPLAssert(nSubExprCount == 1);
423 4 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_OPERATION );
424 4 : CPLAssert(papoSubExpr[0]->eOp == ODS_LIST );
425 4 : int bVal = TRUE;
426 12 : for(int i = 0; i < papoSubExpr[0]->nSubExprCount; i++)
427 : {
428 8 : if (!(papoSubExpr[0]->papoSubExpr[i]->Evaluate(poEvaluator)))
429 0 : return FALSE;
430 8 : CPLAssert(papoSubExpr[0]->papoSubExpr[i]->eNodeType == SNT_CONSTANT );
431 8 : if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_INTEGER)
432 : {
433 8 : bVal &= (papoSubExpr[0]->papoSubExpr[i]->int_value != 0);
434 : }
435 0 : else if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_FLOAT)
436 : {
437 0 : bVal &= (papoSubExpr[0]->papoSubExpr[i]->float_value != 0);
438 : }
439 : else
440 : {
441 : CPLError(CE_Failure, CPLE_NotSupported,
442 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
443 0 : return FALSE;
444 : }
445 : }
446 :
447 4 : FreeSubExpr();
448 :
449 4 : eNodeType = SNT_CONSTANT;
450 4 : field_type = ODS_FIELD_TYPE_INTEGER;
451 4 : int_value = bVal;
452 :
453 4 : return TRUE;
454 : }
455 :
456 : /************************************************************************/
457 : /* EvaluateNOT() */
458 : /************************************************************************/
459 :
460 2 : int ods_formula_node::EvaluateNOT(IODSCellEvaluator* poEvaluator)
461 : {
462 2 : CPLAssert( eNodeType == SNT_OPERATION );
463 2 : CPLAssert( eOp == ODS_NOT );
464 :
465 2 : CPLAssert(nSubExprCount == 1);
466 2 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
467 0 : return FALSE;
468 2 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
469 :
470 2 : int bVal = FALSE;
471 2 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
472 : {
473 2 : bVal = !(papoSubExpr[0]->int_value != 0);
474 : }
475 0 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
476 : {
477 0 : bVal = !(papoSubExpr[0]->float_value != 0);
478 : }
479 : else
480 : {
481 : CPLError(CE_Failure, CPLE_NotSupported,
482 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
483 0 : return FALSE;
484 : }
485 :
486 2 : FreeSubExpr();
487 :
488 2 : eNodeType = SNT_CONSTANT;
489 2 : field_type = ODS_FIELD_TYPE_INTEGER;
490 2 : int_value = bVal;
491 :
492 2 : return TRUE;
493 : }
494 :
495 : /************************************************************************/
496 : /* EvaluateIF() */
497 : /************************************************************************/
498 :
499 4 : int ods_formula_node::EvaluateIF(IODSCellEvaluator* poEvaluator)
500 : {
501 4 : CPLAssert( eNodeType == SNT_OPERATION );
502 4 : CPLAssert( eOp == ODS_IF );
503 :
504 4 : CPLAssert(nSubExprCount == 2 || nSubExprCount == 3);
505 4 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
506 0 : return FALSE;
507 4 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
508 0 : return FALSE;
509 4 : if (nSubExprCount == 3 && !(papoSubExpr[2]->Evaluate(poEvaluator)))
510 0 : return FALSE;
511 :
512 4 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
513 4 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
514 4 : if (nSubExprCount == 3)
515 2 : CPLAssert(papoSubExpr[2]->eNodeType == SNT_CONSTANT );
516 :
517 4 : int bCond = FALSE;
518 4 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
519 : {
520 4 : bCond = (papoSubExpr[0]->int_value != 0);
521 : }
522 0 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
523 : {
524 0 : bCond = (papoSubExpr[0]->float_value != 0);
525 : }
526 : else
527 : {
528 : CPLError(CE_Failure, CPLE_NotSupported,
529 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
530 0 : return FALSE;
531 : }
532 :
533 4 : if (bCond)
534 : {
535 2 : eNodeType = SNT_CONSTANT;
536 2 : field_type = papoSubExpr[1]->field_type;
537 2 : if (field_type == ODS_FIELD_TYPE_INTEGER)
538 2 : int_value = papoSubExpr[1]->int_value;
539 0 : else if (field_type == ODS_FIELD_TYPE_FLOAT)
540 0 : float_value = papoSubExpr[1]->float_value;
541 0 : else if (field_type == ODS_FIELD_TYPE_STRING)
542 : {
543 0 : string_value = papoSubExpr[1]->string_value;
544 0 : papoSubExpr[1]->string_value = NULL;
545 : }
546 : }
547 2 : else if (nSubExprCount == 3)
548 : {
549 1 : eNodeType = SNT_CONSTANT;
550 1 : field_type = papoSubExpr[2]->field_type;
551 1 : if (field_type == ODS_FIELD_TYPE_INTEGER)
552 1 : int_value = papoSubExpr[2]->int_value;
553 0 : else if (field_type == ODS_FIELD_TYPE_FLOAT)
554 0 : float_value = papoSubExpr[2]->float_value;
555 0 : else if (field_type == ODS_FIELD_TYPE_STRING)
556 : {
557 0 : string_value = papoSubExpr[2]->string_value;
558 0 : papoSubExpr[2]->string_value = NULL;
559 : }
560 : }
561 : else
562 : {
563 1 : eNodeType = SNT_CONSTANT;
564 1 : field_type = ODS_FIELD_TYPE_INTEGER;
565 1 : int_value = FALSE;
566 : }
567 :
568 4 : FreeSubExpr();
569 :
570 4 : return TRUE;
571 : }
572 :
573 : /************************************************************************/
574 : /* EvaluateEQ() */
575 : /************************************************************************/
576 :
577 20 : int ods_formula_node::EvaluateEQ(IODSCellEvaluator* poEvaluator)
578 : {
579 20 : CPLAssert( eNodeType == SNT_OPERATION );
580 20 : CPLAssert( eOp == ODS_EQ );
581 :
582 20 : CPLAssert(nSubExprCount == 2);
583 20 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
584 0 : return FALSE;
585 20 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
586 0 : return FALSE;
587 :
588 20 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
589 20 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
590 :
591 20 : int bVal = FALSE;
592 20 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
593 : {
594 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
595 : {
596 4 : bVal = (papoSubExpr[0]->int_value == papoSubExpr[1]->int_value);
597 : }
598 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
599 : {
600 4 : bVal = (papoSubExpr[0]->int_value == papoSubExpr[1]->float_value);
601 : }
602 : }
603 12 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
604 : {
605 8 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
606 : {
607 4 : bVal = (papoSubExpr[0]->float_value == papoSubExpr[1]->int_value);
608 : }
609 4 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
610 : {
611 4 : bVal = (papoSubExpr[0]->float_value == papoSubExpr[1]->float_value);
612 : }
613 : }
614 4 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
615 : {
616 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
617 : {
618 4 : bVal = (strcmp(papoSubExpr[0]->string_value,
619 8 : papoSubExpr[1]->string_value) == 0);
620 : }
621 : }
622 : else
623 : {
624 : CPLError(CE_Failure, CPLE_NotSupported,
625 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
626 0 : return FALSE;
627 : }
628 :
629 20 : eNodeType = SNT_CONSTANT;
630 20 : field_type = ODS_FIELD_TYPE_INTEGER;
631 20 : int_value = bVal;
632 :
633 20 : FreeSubExpr();
634 :
635 20 : return TRUE;
636 : }
637 :
638 : /************************************************************************/
639 : /* EvaluateNE() */
640 : /************************************************************************/
641 :
642 10 : int ods_formula_node::EvaluateNE(IODSCellEvaluator* poEvaluator)
643 : {
644 10 : CPLAssert( eNodeType == SNT_OPERATION );
645 10 : CPLAssert( eOp == ODS_NE );
646 :
647 10 : eOp = ODS_EQ;
648 10 : if (!EvaluateEQ(poEvaluator))
649 0 : return FALSE;
650 :
651 10 : int_value = !int_value;
652 10 : return TRUE;
653 : }
654 :
655 : /************************************************************************/
656 : /* GetCase() */
657 : /************************************************************************/
658 :
659 : typedef enum
660 : {
661 : CASE_LOWER,
662 : CASE_UPPER,
663 : CASE_UNKNOWN,
664 : } CaseType;
665 :
666 24 : static CaseType GetCase(const char* pszStr)
667 : {
668 24 : int bInit = TRUE;
669 : char ch;
670 24 : CaseType eCase = CASE_UNKNOWN;
671 72 : while((ch = *(pszStr++)) != '\0')
672 : {
673 24 : if (bInit)
674 : {
675 28 : if (ch >= 'a' && ch <= 'z')
676 4 : eCase = CASE_LOWER;
677 40 : else if (ch >= 'A' && ch <= 'Z')
678 20 : eCase = CASE_UPPER;
679 : else
680 0 : return CASE_UNKNOWN;
681 : }
682 0 : else if (ch >= 'a' && ch <= 'z' && eCase == CASE_LOWER)
683 : ;
684 0 : else if (ch >= 'A' && ch <= 'Z' && eCase == CASE_UPPER)
685 : ;
686 : else
687 0 : return CASE_UNKNOWN;
688 : }
689 24 : return eCase;
690 : }
691 :
692 : /************************************************************************/
693 : /* EvaluateLE() */
694 : /************************************************************************/
695 :
696 10 : int ods_formula_node::EvaluateLE(IODSCellEvaluator* poEvaluator)
697 : {
698 10 : CPLAssert( eNodeType == SNT_OPERATION );
699 10 : CPLAssert( eOp == ODS_LE );
700 :
701 10 : CPLAssert(nSubExprCount == 2);
702 10 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
703 0 : return FALSE;
704 10 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
705 0 : return FALSE;
706 :
707 10 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
708 10 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
709 :
710 10 : int bVal = FALSE;
711 10 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
712 : {
713 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
714 : {
715 2 : bVal = (papoSubExpr[0]->int_value <= papoSubExpr[1]->int_value);
716 : }
717 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
718 : {
719 2 : bVal = (papoSubExpr[0]->int_value <= papoSubExpr[1]->float_value);
720 : }
721 : else
722 0 : bVal = TRUE;
723 : }
724 6 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
725 : {
726 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
727 : {
728 2 : bVal = (papoSubExpr[0]->float_value <= papoSubExpr[1]->int_value);
729 : }
730 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
731 : {
732 2 : bVal = (papoSubExpr[0]->float_value <= papoSubExpr[1]->float_value);
733 : }
734 : else
735 0 : bVal = TRUE;
736 : }
737 2 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
738 : {
739 2 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
740 : {
741 4 : if (GetCase(papoSubExpr[0]->string_value) ==
742 2 : GetCase(papoSubExpr[1]->string_value))
743 2 : bVal = (strcmp(papoSubExpr[0]->string_value,
744 4 : papoSubExpr[1]->string_value) <= 0);
745 : else
746 0 : bVal = (strcasecmp(papoSubExpr[0]->string_value,
747 0 : papoSubExpr[1]->string_value) <= 0);
748 : }
749 : }
750 : else
751 : {
752 : CPLError(CE_Failure, CPLE_NotSupported,
753 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
754 0 : return FALSE;
755 : }
756 :
757 10 : eNodeType = SNT_CONSTANT;
758 10 : field_type = ODS_FIELD_TYPE_INTEGER;
759 10 : int_value = bVal;
760 :
761 10 : FreeSubExpr();
762 :
763 10 : return TRUE;
764 : }
765 :
766 : /************************************************************************/
767 : /* EvaluateGE() */
768 : /************************************************************************/
769 :
770 10 : int ods_formula_node::EvaluateGE(IODSCellEvaluator* poEvaluator)
771 : {
772 10 : CPLAssert( eNodeType == SNT_OPERATION );
773 10 : CPLAssert( eOp == ODS_GE );
774 :
775 10 : CPLAssert(nSubExprCount == 2);
776 10 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
777 0 : return FALSE;
778 10 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
779 0 : return FALSE;
780 :
781 10 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
782 10 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
783 :
784 10 : int bVal = FALSE;
785 10 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
786 : {
787 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
788 : {
789 2 : bVal = (papoSubExpr[0]->int_value >= papoSubExpr[1]->int_value);
790 : }
791 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
792 : {
793 2 : bVal = (papoSubExpr[0]->int_value >= papoSubExpr[1]->float_value);
794 : }
795 : }
796 6 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
797 : {
798 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
799 : {
800 2 : bVal = (papoSubExpr[0]->float_value >= papoSubExpr[1]->int_value);
801 : }
802 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
803 : {
804 2 : bVal = (papoSubExpr[0]->float_value >= papoSubExpr[1]->float_value);
805 : }
806 : }
807 2 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
808 : {
809 2 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
810 : {
811 4 : if (GetCase(papoSubExpr[0]->string_value) ==
812 2 : GetCase(papoSubExpr[1]->string_value))
813 2 : bVal = (strcmp(papoSubExpr[0]->string_value,
814 4 : papoSubExpr[1]->string_value) >= 0);
815 : else
816 0 : bVal = (strcasecmp(papoSubExpr[0]->string_value,
817 0 : papoSubExpr[1]->string_value) >= 0);
818 : }
819 : else
820 0 : bVal = TRUE;
821 : }
822 : else
823 : {
824 : CPLError(CE_Failure, CPLE_NotSupported,
825 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
826 0 : return FALSE;
827 : }
828 :
829 10 : eNodeType = SNT_CONSTANT;
830 10 : field_type = ODS_FIELD_TYPE_INTEGER;
831 10 : int_value = bVal;
832 :
833 10 : FreeSubExpr();
834 :
835 10 : return TRUE;
836 : }
837 :
838 : /************************************************************************/
839 : /* EvaluateLT() */
840 : /************************************************************************/
841 :
842 14 : int ods_formula_node::EvaluateLT(IODSCellEvaluator* poEvaluator)
843 : {
844 14 : CPLAssert( eNodeType == SNT_OPERATION );
845 14 : CPLAssert( eOp == ODS_LT );
846 :
847 14 : CPLAssert(nSubExprCount == 2);
848 14 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
849 0 : return FALSE;
850 14 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
851 0 : return FALSE;
852 :
853 14 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
854 14 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
855 :
856 14 : int bVal = FALSE;
857 14 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
858 : {
859 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
860 : {
861 2 : bVal = (papoSubExpr[0]->int_value < papoSubExpr[1]->int_value);
862 : }
863 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
864 : {
865 2 : bVal = (papoSubExpr[0]->int_value < papoSubExpr[1]->float_value);
866 : }
867 : else
868 0 : bVal = TRUE;
869 : }
870 10 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
871 : {
872 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
873 : {
874 2 : bVal = (papoSubExpr[0]->float_value < papoSubExpr[1]->int_value);
875 : }
876 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
877 : {
878 2 : bVal = (papoSubExpr[0]->float_value < papoSubExpr[1]->float_value);
879 : }
880 : else
881 0 : bVal = TRUE;
882 : }
883 6 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
884 : {
885 6 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
886 : {
887 12 : if (GetCase(papoSubExpr[0]->string_value) ==
888 6 : GetCase(papoSubExpr[1]->string_value))
889 2 : bVal = (strcmp(papoSubExpr[0]->string_value,
890 4 : papoSubExpr[1]->string_value) < 0);
891 : else
892 4 : bVal = (strcasecmp(papoSubExpr[0]->string_value,
893 8 : papoSubExpr[1]->string_value) < 0);
894 : }
895 : }
896 : else
897 : {
898 : CPLError(CE_Failure, CPLE_NotSupported,
899 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
900 0 : return FALSE;
901 : }
902 :
903 14 : eNodeType = SNT_CONSTANT;
904 14 : field_type = ODS_FIELD_TYPE_INTEGER;
905 14 : int_value = bVal;
906 :
907 14 : FreeSubExpr();
908 :
909 14 : return TRUE;
910 : }
911 :
912 : /************************************************************************/
913 : /* EvaluateGT() */
914 : /************************************************************************/
915 :
916 10 : int ods_formula_node::EvaluateGT(IODSCellEvaluator* poEvaluator)
917 : {
918 10 : CPLAssert( eNodeType == SNT_OPERATION );
919 10 : CPLAssert( eOp == ODS_GT );
920 :
921 10 : CPLAssert(nSubExprCount == 2);
922 10 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
923 0 : return FALSE;
924 10 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
925 0 : return FALSE;
926 :
927 10 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
928 10 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
929 :
930 10 : int bVal = FALSE;
931 10 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
932 : {
933 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
934 : {
935 2 : bVal = (papoSubExpr[0]->int_value > papoSubExpr[1]->int_value);
936 : }
937 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
938 : {
939 2 : bVal = (papoSubExpr[0]->int_value > papoSubExpr[1]->float_value);
940 : }
941 : }
942 6 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
943 : {
944 4 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
945 : {
946 2 : bVal = (papoSubExpr[0]->float_value > papoSubExpr[1]->int_value);
947 : }
948 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
949 : {
950 2 : bVal = (papoSubExpr[0]->float_value > papoSubExpr[1]->float_value);
951 : }
952 : }
953 2 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING)
954 : {
955 2 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING)
956 : {
957 4 : if (GetCase(papoSubExpr[0]->string_value) ==
958 2 : GetCase(papoSubExpr[1]->string_value))
959 2 : bVal = (strcmp(papoSubExpr[0]->string_value,
960 4 : papoSubExpr[1]->string_value) > 0);
961 : else
962 0 : bVal = (strcasecmp(papoSubExpr[0]->string_value,
963 0 : papoSubExpr[1]->string_value) > 0);
964 : }
965 : else
966 0 : bVal = TRUE;
967 : }
968 : else
969 : {
970 : CPLError(CE_Failure, CPLE_NotSupported,
971 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
972 0 : return FALSE;
973 : }
974 :
975 10 : eNodeType = SNT_CONSTANT;
976 10 : field_type = ODS_FIELD_TYPE_INTEGER;
977 10 : int_value = bVal;
978 :
979 10 : FreeSubExpr();
980 :
981 10 : return TRUE;
982 : }
983 :
984 : /************************************************************************/
985 : /* EvaluateSingleArgOp() */
986 : /************************************************************************/
987 :
988 9 : int ods_formula_node::EvaluateSingleArgOp(IODSCellEvaluator* poEvaluator)
989 : {
990 9 : CPLAssert( eNodeType == SNT_OPERATION );
991 :
992 9 : const SingleOpStruct* psSingleOp = ODSGetSingleOpEntry(eOp);
993 9 : CPLAssert(psSingleOp);
994 :
995 9 : CPLAssert(nSubExprCount == 1);
996 9 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
997 0 : return FALSE;
998 :
999 9 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1000 9 : double dfVal = 0;
1001 :
1002 9 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
1003 : {
1004 1 : dfVal = psSingleOp->pfnEval(papoSubExpr[0]->int_value);
1005 : }
1006 8 : else if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
1007 : {
1008 8 : dfVal = psSingleOp->pfnEval(papoSubExpr[0]->float_value);
1009 : }
1010 : else
1011 : {
1012 : CPLError(CE_Failure, CPLE_NotSupported, "Bad argument type for %s",
1013 0 : psSingleOp->pszName);
1014 0 : return FALSE;
1015 : }
1016 :
1017 9 : eNodeType = SNT_CONSTANT;
1018 9 : field_type = ODS_FIELD_TYPE_FLOAT;
1019 9 : float_value = dfVal;
1020 :
1021 9 : FreeSubExpr();
1022 :
1023 9 : return TRUE;
1024 : }
1025 :
1026 : /************************************************************************/
1027 : /* EvaluateBinaryArithmetic() */
1028 : /************************************************************************/
1029 :
1030 9 : int ods_formula_node::EvaluateBinaryArithmetic(IODSCellEvaluator* poEvaluator)
1031 : {
1032 9 : CPLAssert( eNodeType == SNT_OPERATION );
1033 9 : CPLAssert( eOp >= ODS_ADD && eOp<= ODS_MODULUS );
1034 :
1035 9 : CPLAssert(nSubExprCount == 2);
1036 9 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1037 0 : return FALSE;
1038 9 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1039 0 : return FALSE;
1040 :
1041 9 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1042 9 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1043 :
1044 9 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_INTEGER)
1045 : {
1046 6 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
1047 : {
1048 : int nVal;
1049 4 : switch (eOp)
1050 : {
1051 1 : case ODS_ADD : nVal = (papoSubExpr[0]->int_value + papoSubExpr[1]->int_value); break;
1052 1 : case ODS_SUBTRACT : nVal = (papoSubExpr[0]->int_value - papoSubExpr[1]->int_value); break;
1053 1 : case ODS_MULTIPLY : nVal = (papoSubExpr[0]->int_value * papoSubExpr[1]->int_value); break;
1054 : case ODS_DIVIDE :
1055 1 : if (papoSubExpr[1]->int_value != 0)
1056 1 : nVal = (papoSubExpr[0]->int_value / papoSubExpr[1]->int_value);
1057 : else
1058 0 : return FALSE;
1059 1 : break;
1060 : case ODS_MODULUS :
1061 0 : if (papoSubExpr[1]->int_value != 0)
1062 0 : nVal = (papoSubExpr[0]->int_value % papoSubExpr[1]->int_value);
1063 : else
1064 0 : return FALSE;
1065 0 : break;
1066 0 : default: nVal = 0; CPLAssert(0);
1067 : }
1068 :
1069 4 : eNodeType = SNT_CONSTANT;
1070 4 : field_type = ODS_FIELD_TYPE_INTEGER;
1071 4 : int_value = nVal;
1072 :
1073 4 : FreeSubExpr();
1074 :
1075 4 : return TRUE;
1076 : }
1077 2 : else if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
1078 : {
1079 2 : papoSubExpr[0]->field_type = ODS_FIELD_TYPE_FLOAT;
1080 2 : papoSubExpr[0]->float_value = papoSubExpr[0]->int_value;
1081 : }
1082 : else
1083 : {
1084 : CPLError(CE_Failure, CPLE_NotSupported,
1085 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
1086 0 : return FALSE;
1087 : }
1088 : }
1089 :
1090 5 : if (papoSubExpr[0]->field_type == ODS_FIELD_TYPE_FLOAT)
1091 : {
1092 5 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_INTEGER)
1093 : {
1094 2 : papoSubExpr[1]->field_type = ODS_FIELD_TYPE_FLOAT;
1095 2 : papoSubExpr[1]->float_value = papoSubExpr[1]->int_value;
1096 : }
1097 :
1098 5 : if (papoSubExpr[1]->field_type == ODS_FIELD_TYPE_FLOAT)
1099 : {
1100 : float dfVal;
1101 5 : switch (eOp)
1102 : {
1103 0 : case ODS_ADD : dfVal = (papoSubExpr[0]->float_value + papoSubExpr[1]->float_value); break;
1104 0 : case ODS_SUBTRACT : dfVal = (papoSubExpr[0]->float_value - papoSubExpr[1]->float_value); break;
1105 3 : case ODS_MULTIPLY : dfVal = (papoSubExpr[0]->float_value * papoSubExpr[1]->float_value); break;
1106 : case ODS_DIVIDE :
1107 1 : if (papoSubExpr[1]->float_value != 0)
1108 1 : dfVal = (papoSubExpr[0]->float_value / papoSubExpr[1]->float_value);
1109 : else
1110 0 : return FALSE;
1111 1 : break;
1112 : case ODS_MODULUS :
1113 1 : if (papoSubExpr[1]->float_value != 0)
1114 1 : dfVal = fmod(papoSubExpr[0]->float_value, papoSubExpr[1]->float_value);
1115 : else
1116 0 : return FALSE;
1117 1 : break;
1118 0 : default: dfVal = 0.0; CPLAssert(0);
1119 : }
1120 :
1121 5 : eNodeType = SNT_CONSTANT;
1122 5 : field_type = ODS_FIELD_TYPE_FLOAT;
1123 5 : float_value = dfVal;
1124 :
1125 5 : FreeSubExpr();
1126 :
1127 5 : return TRUE;
1128 : }
1129 : else
1130 : {
1131 : CPLError(CE_Failure, CPLE_NotSupported,
1132 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
1133 0 : return FALSE;
1134 : }
1135 : }
1136 : else
1137 : {
1138 : CPLError(CE_Failure, CPLE_NotSupported,
1139 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
1140 0 : return FALSE;
1141 : }
1142 : }
1143 :
1144 :
1145 : /************************************************************************/
1146 : /* TransformToString() */
1147 : /************************************************************************/
1148 :
1149 17 : std::string ods_formula_node::TransformToString() const
1150 : {
1151 : char szTmp[128];
1152 17 : if (field_type == ODS_FIELD_TYPE_INTEGER)
1153 : {
1154 0 : snprintf(szTmp, sizeof(szTmp), "%d", int_value);
1155 0 : return szTmp;
1156 : }
1157 17 : else if (field_type == ODS_FIELD_TYPE_FLOAT)
1158 : {
1159 0 : snprintf(szTmp, sizeof(szTmp), "%.16g", float_value);
1160 0 : return szTmp;
1161 : }
1162 17 : else if (field_type == ODS_FIELD_TYPE_STRING)
1163 : {
1164 17 : return string_value;
1165 : }
1166 : else
1167 : {
1168 0 : return "";
1169 : }
1170 : }
1171 :
1172 : /************************************************************************/
1173 : /* EvaluateCONCAT() */
1174 : /************************************************************************/
1175 :
1176 1 : int ods_formula_node::EvaluateCONCAT(IODSCellEvaluator* poEvaluator)
1177 : {
1178 1 : CPLAssert( eNodeType == SNT_OPERATION );
1179 1 : CPLAssert( eOp == ODS_CONCAT );
1180 :
1181 1 : CPLAssert(nSubExprCount == 2);
1182 1 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1183 0 : return FALSE;
1184 1 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1185 0 : return FALSE;
1186 :
1187 1 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1188 1 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1189 :
1190 1 : std::string osLeft(papoSubExpr[0]->TransformToString());
1191 1 : std::string osRight(papoSubExpr[1]->TransformToString());
1192 :
1193 1 : eNodeType = SNT_CONSTANT;
1194 1 : field_type = ODS_FIELD_TYPE_STRING;
1195 1 : string_value = CPLStrdup((osLeft + osRight).c_str());
1196 :
1197 1 : FreeSubExpr();
1198 :
1199 1 : return TRUE;
1200 : }
1201 :
1202 : /************************************************************************/
1203 : /* GetRowCol() */
1204 : /************************************************************************/
1205 :
1206 40 : static int GetRowCol(const char* pszCell, int& nRow, int& nCol)
1207 : {
1208 : int i;
1209 :
1210 40 : if (pszCell[0] != '.')
1211 : {
1212 : CPLError(CE_Failure, CPLE_AppDefined,
1213 0 : "Invalid cell %s", pszCell);
1214 0 : return FALSE;
1215 : }
1216 :
1217 40 : nCol = 0;
1218 80 : for(i=1; pszCell[i]>='A' && pszCell[i]<='Z';i++)
1219 : {
1220 40 : nCol = nCol * 26 + (pszCell[i] - 'A');
1221 : }
1222 40 : nRow = atoi(pszCell + i) - 1;
1223 :
1224 40 : return TRUE;
1225 : }
1226 :
1227 : /************************************************************************/
1228 : /* EvaluateListArgOp() */
1229 : /************************************************************************/
1230 :
1231 6 : int ods_formula_node::EvaluateListArgOp(IODSCellEvaluator* poEvaluator)
1232 : {
1233 6 : CPLAssert( eNodeType == SNT_OPERATION );
1234 6 : CPLAssert( eOp >= ODS_SUM && eOp <= ODS_COUNTA );
1235 :
1236 6 : CPLAssert(nSubExprCount == 1);
1237 6 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_OPERATION );
1238 6 : CPLAssert(papoSubExpr[0]->eOp == ODS_LIST );
1239 :
1240 6 : std::vector<double> adfVal;
1241 : int i;
1242 :
1243 6 : int nCount = 0, nCountA = 0;
1244 :
1245 13 : for(i=0;i<papoSubExpr[0]->nSubExprCount;i++)
1246 : {
1247 19 : if (papoSubExpr[0]->papoSubExpr[i]->eNodeType == SNT_OPERATION &&
1248 6 : papoSubExpr[0]->papoSubExpr[i]->eOp == ODS_CELL_RANGE)
1249 : {
1250 6 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->nSubExprCount == 2);
1251 6 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[0]->eNodeType == SNT_CONSTANT);
1252 6 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING);
1253 6 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[1]->eNodeType == SNT_CONSTANT);
1254 6 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[1]->field_type == ODS_FIELD_TYPE_STRING);
1255 :
1256 6 : if (poEvaluator == NULL)
1257 : {
1258 0 : CPLError(CE_Failure, CPLE_AppDefined, "No cell evaluator provided");
1259 0 : return FALSE;
1260 : }
1261 :
1262 6 : const char* psz1 = papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[0]->string_value;
1263 6 : const char* psz2 = papoSubExpr[0]->papoSubExpr[i]->papoSubExpr[1]->string_value;
1264 6 : int nRow1 = 0,nCol1 = 0;
1265 6 : if (!GetRowCol(psz1, nRow1, nCol1))
1266 0 : return FALSE;
1267 6 : int nRow2 = 0,nCol2 = 0;
1268 6 : if (!GetRowCol(psz2, nRow2, nCol2))
1269 0 : return FALSE;
1270 :
1271 6 : std::vector<ods_formula_node> aoOutValues;
1272 6 : if (poEvaluator->EvaluateRange(nRow1, nCol1, nRow2, nCol2, aoOutValues))
1273 : {
1274 30 : for(size_t j = 0; j < aoOutValues.size(); j++)
1275 : {
1276 24 : if (aoOutValues[j].eNodeType == SNT_CONSTANT)
1277 : {
1278 24 : if (aoOutValues[j].field_type == ODS_FIELD_TYPE_INTEGER)
1279 : {
1280 0 : adfVal.push_back(aoOutValues[j].int_value);
1281 0 : nCount ++;
1282 0 : nCountA ++;
1283 : }
1284 24 : else if (aoOutValues[j].field_type == ODS_FIELD_TYPE_FLOAT)
1285 : {
1286 12 : adfVal.push_back(aoOutValues[j].float_value);
1287 12 : nCount ++;
1288 12 : nCountA ++;
1289 : }
1290 12 : else if (aoOutValues[j].field_type == ODS_FIELD_TYPE_STRING)
1291 : {
1292 6 : nCountA ++;
1293 : }
1294 : }
1295 : }
1296 6 : }
1297 : }
1298 : else
1299 : {
1300 1 : if (!(papoSubExpr[0]->papoSubExpr[i]->Evaluate(poEvaluator)))
1301 0 : return FALSE;
1302 :
1303 1 : CPLAssert (papoSubExpr[0]->papoSubExpr[i]->eNodeType == SNT_CONSTANT );
1304 1 : if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_INTEGER)
1305 : {
1306 1 : adfVal.push_back(papoSubExpr[0]->papoSubExpr[i]->int_value);
1307 1 : nCount ++;
1308 1 : nCountA ++;
1309 : }
1310 0 : else if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_FLOAT)
1311 : {
1312 0 : adfVal.push_back(papoSubExpr[0]->papoSubExpr[i]->float_value);
1313 0 : nCount ++;
1314 0 : nCountA ++;
1315 : }
1316 0 : else if (eOp == ODS_COUNT || eOp == ODS_COUNTA)
1317 : {
1318 0 : if (papoSubExpr[0]->papoSubExpr[i]->field_type == ODS_FIELD_TYPE_STRING)
1319 0 : nCountA ++;
1320 : }
1321 : else
1322 : {
1323 :
1324 : CPLError(CE_Failure, CPLE_NotSupported,
1325 0 : "Bad argument type for %s", ODSGetOperatorName(eOp));
1326 0 : return FALSE;
1327 : }
1328 : }
1329 : }
1330 :
1331 6 : if (eOp == ODS_COUNT)
1332 : {
1333 1 : eNodeType = SNT_CONSTANT;
1334 1 : field_type = ODS_FIELD_TYPE_INTEGER;
1335 1 : int_value = nCount;
1336 :
1337 1 : FreeSubExpr();
1338 1 : return TRUE;
1339 : }
1340 :
1341 5 : if (eOp == ODS_COUNTA)
1342 : {
1343 1 : eNodeType = SNT_CONSTANT;
1344 1 : field_type = ODS_FIELD_TYPE_INTEGER;
1345 1 : int_value = nCountA;
1346 :
1347 1 : FreeSubExpr();
1348 1 : return TRUE;
1349 : }
1350 :
1351 4 : double dfVal = 0;
1352 :
1353 4 : switch(eOp)
1354 : {
1355 : case ODS_SUM:
1356 : {
1357 3 : for(i=0;i<(int)adfVal.size();i++)
1358 : {
1359 2 : dfVal += adfVal[i];
1360 : }
1361 1 : break;
1362 : }
1363 :
1364 : case ODS_AVERAGE:
1365 : {
1366 3 : for(i=0;i<(int)adfVal.size();i++)
1367 : {
1368 2 : dfVal += adfVal[i];
1369 : }
1370 1 : dfVal /= adfVal.size();
1371 1 : break;
1372 : }
1373 :
1374 : case ODS_MIN:
1375 : {
1376 1 : dfVal = (adfVal.size() == 0) ? 0 :adfVal[0];
1377 3 : for(i=1;i<(int)adfVal.size();i++)
1378 : {
1379 2 : if (adfVal[i] < dfVal) dfVal = adfVal[i];
1380 : }
1381 1 : break;
1382 : }
1383 :
1384 : case ODS_MAX:
1385 : {
1386 1 : dfVal = (adfVal.size() == 0) ? 0 :adfVal[0];
1387 2 : for(i=1;i<(int)adfVal.size();i++)
1388 : {
1389 1 : if (adfVal[i] > dfVal) dfVal = adfVal[i];
1390 : }
1391 : break;
1392 : }
1393 :
1394 : default:
1395 : break;
1396 : }
1397 :
1398 4 : eNodeType = SNT_CONSTANT;
1399 4 : field_type = ODS_FIELD_TYPE_FLOAT;
1400 4 : float_value = dfVal;
1401 :
1402 4 : FreeSubExpr();
1403 :
1404 4 : return TRUE;
1405 : }
1406 :
1407 : /************************************************************************/
1408 : /* EvaluateCELL() */
1409 : /************************************************************************/
1410 :
1411 28 : int ods_formula_node::EvaluateCELL(IODSCellEvaluator* poEvaluator)
1412 : {
1413 28 : CPLAssert( eNodeType == SNT_OPERATION );
1414 28 : CPLAssert( eOp == ODS_CELL );
1415 :
1416 28 : CPLAssert(nSubExprCount == 1);
1417 28 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1418 28 : CPLAssert(papoSubExpr[0]->field_type == ODS_FIELD_TYPE_STRING );
1419 :
1420 28 : if (poEvaluator == NULL)
1421 : {
1422 0 : CPLError(CE_Failure, CPLE_AppDefined, "No cell evaluator provided");
1423 0 : return FALSE;
1424 : }
1425 :
1426 28 : int nRow = 0,nCol = 0;
1427 28 : if (!GetRowCol(papoSubExpr[0]->string_value, nRow, nCol))
1428 0 : return FALSE;
1429 :
1430 28 : std::vector<ods_formula_node> aoOutValues;
1431 28 : if (poEvaluator->EvaluateRange(nRow, nCol, nRow, nCol, aoOutValues) &&
1432 : aoOutValues.size() == 1)
1433 : {
1434 19 : if (aoOutValues[0].eNodeType == SNT_CONSTANT)
1435 : {
1436 19 : FreeSubExpr();
1437 :
1438 19 : eNodeType = aoOutValues[0].eNodeType;
1439 19 : field_type = aoOutValues[0].field_type;
1440 19 : int_value = aoOutValues[0].int_value;
1441 19 : float_value = aoOutValues[0].float_value;
1442 19 : string_value = aoOutValues[0].string_value ? CPLStrdup(aoOutValues[0].string_value) : NULL;
1443 :
1444 19 : return TRUE;
1445 : }
1446 : }
1447 :
1448 9 : return FALSE;
1449 : }
1450 :
1451 : /************************************************************************/
1452 : /* EvaluateLEN() */
1453 : /************************************************************************/
1454 :
1455 1 : int ods_formula_node::EvaluateLEN(IODSCellEvaluator* poEvaluator)
1456 : {
1457 1 : CPLAssert( eNodeType == SNT_OPERATION );
1458 :
1459 1 : CPLAssert(nSubExprCount == 1);
1460 1 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1461 0 : return FALSE;
1462 :
1463 1 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1464 :
1465 1 : std::string osVal = papoSubExpr[0]->TransformToString();
1466 :
1467 1 : eNodeType = SNT_CONSTANT;
1468 1 : field_type = ODS_FIELD_TYPE_INTEGER;
1469 1 : int_value = strlen(osVal.c_str()); // FIXME : UTF8 support
1470 :
1471 1 : FreeSubExpr();
1472 :
1473 1 : return TRUE;
1474 : }
1475 :
1476 : /************************************************************************/
1477 : /* EvaluateLEFT() */
1478 : /************************************************************************/
1479 :
1480 3 : int ods_formula_node::EvaluateLEFT(IODSCellEvaluator* poEvaluator)
1481 : {
1482 3 : CPLAssert( eNodeType == SNT_OPERATION );
1483 :
1484 3 : CPLAssert(nSubExprCount == 2);
1485 3 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1486 0 : return FALSE;
1487 3 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1488 0 : return FALSE;
1489 :
1490 3 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1491 3 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1492 :
1493 3 : std::string osVal = papoSubExpr[0]->TransformToString();
1494 :
1495 3 : if (papoSubExpr[1]->field_type != ODS_FIELD_TYPE_INTEGER)
1496 0 : return FALSE;
1497 :
1498 : // FIXME : UTF8 support
1499 3 : int nVal = papoSubExpr[1]->int_value;
1500 3 : if (nVal < 0)
1501 0 : return FALSE;
1502 :
1503 3 : osVal = osVal.substr(0,nVal);
1504 :
1505 3 : eNodeType = SNT_CONSTANT;
1506 3 : field_type = ODS_FIELD_TYPE_STRING;
1507 3 : string_value = CPLStrdup(osVal.c_str());
1508 :
1509 3 : FreeSubExpr();
1510 :
1511 3 : return TRUE;
1512 : }
1513 :
1514 : /************************************************************************/
1515 : /* EvaluateRIGHT() */
1516 : /************************************************************************/
1517 :
1518 3 : int ods_formula_node::EvaluateRIGHT(IODSCellEvaluator* poEvaluator)
1519 : {
1520 3 : CPLAssert( eNodeType == SNT_OPERATION );
1521 :
1522 3 : CPLAssert(nSubExprCount == 2);
1523 3 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1524 0 : return FALSE;
1525 3 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1526 0 : return FALSE;
1527 :
1528 3 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1529 3 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1530 :
1531 3 : std::string osVal = papoSubExpr[0]->TransformToString();
1532 :
1533 3 : if (papoSubExpr[1]->field_type != ODS_FIELD_TYPE_INTEGER)
1534 0 : return FALSE;
1535 :
1536 : // FIXME : UTF8 support
1537 3 : size_t nLen = osVal.size();
1538 3 : int nVal = papoSubExpr[1]->int_value;
1539 3 : if (nVal < 0)
1540 0 : return FALSE;
1541 :
1542 3 : if (nLen > (size_t) nVal)
1543 2 : osVal = osVal.substr(nLen-nVal);
1544 :
1545 3 : eNodeType = SNT_CONSTANT;
1546 3 : field_type = ODS_FIELD_TYPE_STRING;
1547 3 : string_value = CPLStrdup(osVal.c_str());
1548 :
1549 3 : FreeSubExpr();
1550 :
1551 3 : return TRUE;
1552 : }
1553 :
1554 : /************************************************************************/
1555 : /* EvaluateMID() */
1556 : /************************************************************************/
1557 :
1558 8 : int ods_formula_node::EvaluateMID(IODSCellEvaluator* poEvaluator)
1559 : {
1560 8 : CPLAssert( eNodeType == SNT_OPERATION );
1561 :
1562 8 : CPLAssert(nSubExprCount == 3);
1563 8 : if (!(papoSubExpr[0]->Evaluate(poEvaluator)))
1564 0 : return FALSE;
1565 8 : if (!(papoSubExpr[1]->Evaluate(poEvaluator)))
1566 0 : return FALSE;
1567 8 : if (!(papoSubExpr[2]->Evaluate(poEvaluator)))
1568 0 : return FALSE;
1569 :
1570 8 : CPLAssert(papoSubExpr[0]->eNodeType == SNT_CONSTANT );
1571 8 : CPLAssert(papoSubExpr[1]->eNodeType == SNT_CONSTANT );
1572 8 : CPLAssert(papoSubExpr[2]->eNodeType == SNT_CONSTANT );
1573 :
1574 8 : std::string osVal = papoSubExpr[0]->TransformToString();
1575 :
1576 8 : if (papoSubExpr[1]->field_type != ODS_FIELD_TYPE_INTEGER)
1577 0 : return FALSE;
1578 :
1579 8 : if (papoSubExpr[2]->field_type != ODS_FIELD_TYPE_INTEGER)
1580 0 : return FALSE;
1581 :
1582 : // FIXME : UTF8 support
1583 8 : size_t nLen = osVal.size();
1584 8 : int nStart = papoSubExpr[1]->int_value;
1585 8 : int nExtractLen = papoSubExpr[2]->int_value;
1586 8 : if (nStart <= 0)
1587 1 : return FALSE;
1588 7 : if (nExtractLen < 0)
1589 0 : return FALSE;
1590 :
1591 7 : if ((size_t)nStart <= nLen)
1592 : {
1593 6 : if (nStart-1 + nExtractLen >= (int)nLen)
1594 3 : osVal = osVal.substr(nStart - 1);
1595 : else
1596 3 : osVal = osVal.substr(nStart - 1, nExtractLen);
1597 : }
1598 : else
1599 1 : osVal = "";
1600 :
1601 7 : eNodeType = SNT_CONSTANT;
1602 7 : field_type = ODS_FIELD_TYPE_STRING;
1603 7 : string_value = CPLStrdup(osVal.c_str());
1604 :
1605 7 : FreeSubExpr();
1606 :
1607 7 : return TRUE;
1608 : }
|