Change app icon
[apps/home/calculator.git] / src / calculator_parser.c
1 /*
2 *
3 * Copyright 2012  Samsung Electronics Co., Ltd
4 *
5 * Licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *    http://floralicense.org/license
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include <math.h>               /* For math functions, cos(), sin(), etc. */
20 #include <dlog.h>
21 #include <string.h>
22 #include <stdbool.h>
23
24 #include "calc-main.h"
25 #include "calc-string.h"
26 #include "calc-expression.h"
27 #include "calculator_parser.h"
28
29 #define  DECNUMDIGITS 34
30 #include "decnumber/decNumber.h"
31
32 #define CALCULATOR_MAX_FUNC_NUMBER                              16              /**<maximum num of function*/
33
34 extern char decimal_ch;
35 static char g_stack[MAX_EXPRESSION_LENGTH];
36
37 static calculator_parentheses_data_t g_parentheses_data[MAX_PARENTHESES_NUM];
38
39 static int oper_num = 0;
40
41 static const function_t g_functions[CALCULATOR_MAX_FUNC_NUMBER] = {
42         {"x^y", "^", 1, '^', FUNCTION_POSTFIX, OPERATOR_TYPE_BINARY,
43          CALCULATOR_CALCULATE_PRIORITY_HIGH, FALSE},
44         {"ln", "ln", 2, 'L', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
45          CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
46         {"sqrt", "sqrt", 4, 'q', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
47          CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
48         {"10^x", "10^", 3, 'T', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
49          CALCULATOR_CALCULATE_PRIORITY_HIGHER, FALSE},
50         {"x!", "!", 1, '!', FUNCTION_POSTFIX, OPERATOR_TYPE_UNARY,
51          CALCULATOR_CALCULATE_PRIORITY_HIGHEST, FALSE},
52         {"1/x", "/", 1, 'x', FUNCTION_POSTFIX, OPERATOR_TYPE_UNARY,
53          CALCULATOR_CALCULATE_PRIORITY_HIGHEST, FALSE},
54         {"sin", "sin", 3, 's', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
55          CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
56         {"cos", "cos", 3, 'c', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
57          CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
58         {"tan", "tan", 3, 't', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
59          CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
60         {"Pi", "p", 1, 'p', FUNCTION_CONSTANT, OPERATOR_TYPE_INVALID,
61          CALCULATOR_CALCULATE_PRIORITY_INVALID, FALSE},
62         {"e", "e", 1, 'e', FUNCTION_CONSTANT, OPERATOR_TYPE_INVALID,
63          CALCULATOR_CALCULATE_PRIORITY_INVALID, FALSE},
64         {"log", "log", 3, 'l', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
65          CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
66         {"abs", "abs", 3, 'b', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
67          CALCULATOR_CALCULATE_PRIORITY_HIGHER, TRUE},
68         {"2^x", "2^", 2, '2', FUNCTION_PREFIX, OPERATOR_TYPE_UNARY,
69          CALCULATOR_CALCULATE_PRIORITY_HIGHER, FALSE},
70         {"xCy", "C", 1, 'C', FUNCTION_POSTFIX, OPERATOR_TYPE_BINARY,
71          CALCULATOR_CALCULATE_PRIORITY_HIGH, FALSE},
72         {"xPy", "P", 1, 'P', FUNCTION_POSTFIX, OPERATOR_TYPE_BINARY,
73          CALCULATOR_CALCULATE_PRIORITY_HIGH, FALSE},
74 };
75
76 #define CALCULATOR_GET_NODE_DATA(t)     ((calculator_node_data_t*)(((GNode*)(t))->data))/**<to get data from GNode structure*/
77
78 /**
79 * @describe
80 *
81 *
82 * @param    out_tree
83 * @param    to_insert
84 * @param    const_node
85 * @return    gboolean
86 * @exception
87 */
88 static gboolean
89 __calculator_calculate_insert_node(GNode ** out_tree, GNode * to_insert,
90                                    GNode * const_node)
91 {
92         GNode *upper_node = NULL;
93         GNode *node = NULL;
94         calculator_node_data_t *node_data = NULL;
95
96         if ((!out_tree) || (!*out_tree) || (!to_insert)) {
97                 return FALSE;
98         }
99
100         upper_node = *out_tree;
101         node = upper_node;
102
103         while (CALCULATOR_GET_NODE_DATA(upper_node)->node_calcu_priority >
104                CALCULATOR_GET_NODE_DATA(to_insert)->node_calcu_priority) {
105                 if (G_NODE_IS_ROOT(upper_node)) {
106                         g_node_insert(to_insert, -1, upper_node);
107                         CALCULATOR_GET_NODE_DATA(to_insert)->children_num++;
108
109                         if (const_node) {
110                                 g_node_insert(*out_tree, -1, const_node);       //value of last node's priority>= upper_node's > to_insert's
111                                 CALCULATOR_GET_NODE_DATA(*out_tree)->
112                                     children_num++;
113                         }
114                         break;
115                 }
116                 node = upper_node;
117                 upper_node = upper_node->parent;
118         }
119
120         if (CALCULATOR_GET_NODE_DATA(upper_node)->node_calcu_priority ==
121             CALCULATOR_GET_NODE_DATA(to_insert)->node_calcu_priority) {
122                 if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type ==
123                     OPERATOR_TYPE_BINARY) {
124                         GNode *parent_node = NULL;
125
126                         if (!G_NODE_IS_ROOT(upper_node)) {
127                                 parent_node = upper_node->parent;
128                                 g_node_unlink(upper_node);
129                                 g_node_insert(parent_node, -1, to_insert);
130                         }
131
132                         g_node_insert(to_insert, -1, upper_node);
133                         CALCULATOR_GET_NODE_DATA(to_insert)->children_num++;
134
135                         if (const_node) {
136                                 g_node_insert(*out_tree, -1, const_node);
137                                 CALCULATOR_GET_NODE_DATA(*out_tree)->
138                                     children_num++;
139                         }
140                 } else if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type ==
141                            OPERATOR_TYPE_UNARY) {
142                         GNode *tmp_node = NULL;
143
144                         if (const_node) {
145                                 node_data =
146                                     g_malloc0(sizeof(calculator_node_data_t));
147                                 node_data->cur_operator = 'x';
148                                 node_data->negative_flag = 1;
149                                 node_data->operator_type = OPERATOR_TYPE_BINARY;
150                                 node_data->node_calcu_priority =
151                                     CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
152                                 tmp_node = g_node_new(node_data);
153
154                                 if (CALCULATOR_GET_NODE_DATA(to_insert)->
155                                     cur_operator != '!') {
156                                         __calculator_calculate_insert_node
157                                             (out_tree, tmp_node, const_node);
158                                 } else  //(CALCULATOR_GET_NODE_DATA(to_insert)->cur_operator == '!')
159                                 {
160                                         g_node_insert(to_insert, -1,
161                                                       const_node);
162                                         CALCULATOR_GET_NODE_DATA(to_insert)->
163                                             children_num++;
164                                 }
165
166                                 g_node_insert(*out_tree, -1, to_insert);
167                                 CALCULATOR_GET_NODE_DATA(*out_tree)->
168                                     children_num++;
169                         } else {
170                                 g_node_insert(upper_node, -1, to_insert);       //combine from right
171                                 CALCULATOR_GET_NODE_DATA(upper_node)->
172                                     children_num++;
173                         }
174                 }
175         } else if (CALCULATOR_GET_NODE_DATA(upper_node)->node_calcu_priority <
176                    CALCULATOR_GET_NODE_DATA(to_insert)->node_calcu_priority) {
177                 if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type ==
178                     OPERATOR_TYPE_BINARY) {
179                         if (node != upper_node) {
180                                 g_node_unlink(node);
181                                 CALCULATOR_GET_NODE_DATA(upper_node)->
182                                     children_num--;
183
184                                 g_node_insert(to_insert, -1, node);
185                                 CALCULATOR_GET_NODE_DATA(to_insert)->
186                                     children_num++;
187                         }
188
189                         if (const_node) {
190                                 if (CALCULATOR_GET_NODE_DATA(*out_tree)->
191                                     node_calcu_priority >
192                                     CALCULATOR_GET_NODE_DATA(to_insert)->
193                                     node_calcu_priority) {
194                                         g_node_insert(*out_tree, -1,
195                                                       const_node);
196                                         CALCULATOR_GET_NODE_DATA(*out_tree)->
197                                             children_num++;
198                                 } else {
199                                         g_node_insert(to_insert, -1,
200                                                       const_node);
201                                         CALCULATOR_GET_NODE_DATA(to_insert)->
202                                             children_num++;
203                                 }
204                         }
205
206                         g_node_insert(upper_node, -1, to_insert);
207                         CALCULATOR_GET_NODE_DATA(upper_node)->children_num++;
208                 }
209
210                 else if (CALCULATOR_GET_NODE_DATA(to_insert)->operator_type == OPERATOR_TYPE_UNARY)     //upper_node must be equal to node equalized to *out_tree, for no functions' prority higher than unary operator
211                 {
212                         if (const_node) {
213
214                                 if (CALCULATOR_GET_NODE_DATA(to_insert)->
215                                     cur_operator != '!') {
216                                         GNode *tmp_node = NULL;
217
218                                         node_data =
219                                             g_malloc0(sizeof
220                                                       (calculator_node_data_t));
221                                         node_data->cur_operator = 'x';
222                                         node_data->negative_flag = 1;
223                                         node_data->operator_type =
224                                             OPERATOR_TYPE_BINARY;
225                                         node_data->node_calcu_priority =
226                                             CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
227                                         tmp_node = g_node_new(node_data);
228
229                                         __calculator_calculate_insert_node
230                                             (out_tree, tmp_node, const_node);
231                                 } else  //(CALCULATOR_GET_NODE_DATA(to_insert)->cur_operator == '!')
232                                 {
233                                         g_node_insert(to_insert, -1,
234                                                       const_node);
235                                         CALCULATOR_GET_NODE_DATA(to_insert)->
236                                             children_num++;
237                                 }
238                         }
239
240                         g_node_insert(*out_tree, -1, to_insert);
241                         CALCULATOR_GET_NODE_DATA(*out_tree)->children_num++;
242                 }
243
244         }
245
246         *out_tree = to_insert;
247         return TRUE;
248 }
249
250 /**
251 * @describe
252 *
253 *
254 * @param    node
255 * @param    data
256 * @return    gboolean
257 * @exception
258 */
259 static gboolean
260 __calculator_tree_destroy_traverse_func(GNode * node, gpointer data)
261 {
262         if (CALCULATOR_GET_NODE_DATA(node)) {
263                 g_free(CALCULATOR_GET_NODE_DATA(node));
264         }
265         g_node_destroy(node);
266         return FALSE;
267 }
268
269 /**
270 * @describe
271 *
272 *
273 * @param    tree
274 * @return    gboolean
275 * @exception
276 */
277 static gboolean __calculator_tree_destroy_all(GNode ** tree)
278 {
279         guint depth = 0;
280         GNode *root = NULL;
281
282         if (*tree) {
283                 root = g_node_get_root(*tree);
284                 depth = g_node_max_height(root);
285                 g_node_traverse(root, G_POST_ORDER, G_TRAVERSE_ALL, depth,
286                                 __calculator_tree_destroy_traverse_func, NULL);
287
288                 *tree = NULL;
289         }
290         return TRUE;
291 }
292
293 /**
294 * @describe
295 *
296 *
297 * @param    result
298 * @param    error_msg
299 * @return    gboolean
300 * @exception
301 */
302 static gboolean __calculator_check_overflow(double result, char *error_msg)
303 {
304         if ((result > CALCULATOR_MAX_RESULT_SUM2)
305             || (result < CALCULATOR_MIN_RESULT_SUM2)) {
306                 strcat(error_msg, CALC_MSG_OUT_OF_RANGE);
307                 return FALSE;
308         }
309         return TRUE;
310 }
311
312 /**
313 * @describe
314 *   add parenthesis between function and paremeter.
315 *
316 * @param    exp
317 * @param    func
318 * @return    void
319 * @exception
320 */
321 static void __calculator_expression_add_parenthesis(char *exp, const char *func)
322 {
323         char *p = exp;
324         char *digit = "0123456789.";
325
326         while ((p = strstr(p, func)) != NULL) {
327                 p = p + strlen(func);
328                 if (*p != '(') {
329                         int l = strspn(p, digit);
330                         string_insert(exp, p - exp, "(");
331                         string_insert(exp, p - exp + l + 1, ")");
332                         p += l + 2;
333                 }
334         }
335 }
336
337 /**
338 * @describe
339 *   If sin/cos/tan function omitted parenthesis, add it
340 *
341 * @param    exp
342 * @return    void
343 * @exception
344 */
345 static void __calculator_expression_tri_func_parenthesis(char *exp)
346 {
347         __calculator_expression_add_parenthesis(exp, "sin");
348         __calculator_expression_add_parenthesis(exp, "cos");
349         __calculator_expression_add_parenthesis(exp, "tan");
350 }
351
352 /**
353 * @describe
354 *   record every matching parentheses position
355 *
356 * @param    string
357 * @param    end_pos
358 * @param    error_msg
359 * @return    bool
360 * @exception
361 */
362 static bool
363 __calculator_calculate_formula_scan(char *string, int *end_idx, char *error_msg)
364 {
365         CALC_FUN_BEG();
366         gint i = 0;
367         gchar *p = NULL;
368
369         p = string;
370         memset(g_parentheses_data, 0x0, sizeof(g_parentheses_data));
371
372         __calculator_expression_tri_func_parenthesis(string);
373
374         while (*p != '\0') {
375                 if (*p == '(') {
376                         while (g_parentheses_data[i].start_pos) {
377                                 i++;
378                         }
379                         g_parentheses_data[i].start_pos = p;
380                 }
381                 if (*p == ')') {
382                         while (g_parentheses_data[i].end_pos) {
383                                 i--;
384                         }
385                         if (g_parentheses_data[i].start_pos) {
386                                 g_parentheses_data[i].end_pos = p;
387                         }
388                 }
389                 p++;
390         }
391         *end_idx = p - 1 - string;
392         CALC_FUN_END();
393         return TRUE;
394 }
395
396 /**
397 * @describe
398 *
399 *
400 * @param    n
401 * @param    err_msg
402 * @return    double
403 * @exception
404 */
405 static double __calculator_calculate_factorial(double n, char *err_msg)
406 {
407         if (n < 0) {
408                 strcat(err_msg, CALC_MSG_INVALID_FAC);
409                 return -1;
410         } else if (n >= 30) {
411                 strcat(err_msg, CALC_MSG_OUT_OF_RANGE);
412                 return -1;
413         }
414
415         double i = 0;
416         double result = 1;
417         for (i = 2; i <= n; ++i) {
418                 result *= i;
419         }
420         return result;
421 }
422
423 /**
424 * @describe
425 *   Judge the op is a operator, if yes, give fucntion type
426 *
427 * @param    op
428 * @param    function
429 * @return    gboolean
430 * @exception
431 */
432 static gboolean __calculator_util_get_operator(char *op, function_t * function)
433 {
434         gint i = 0;
435         gboolean ret = FALSE;
436         if ((*op == decimal_ch) || (*op == '(') || (*op == ')')) {
437                 ret = FALSE;
438         } else if (isdigit(*op)) {
439                 ret = FALSE;
440         } else if ((*op == '+') || (*op == '-') || (*op == 'x') || (*op == '/')) {
441                 function->category = FUNCTION_POSTFIX;
442                 function->function_char = *op;
443                 function->func_name = NULL;
444                 function->func_string = NULL;
445                 function->has_parentheses = FALSE;
446                 function->op_type = OPERATOR_TYPE_BINARY;
447                 if ((*op == '+') || (*op == '-')) {
448                         function->priority = CALCULATOR_CALCULATE_PRIORITY_LOW;
449                 } else {
450                         function->priority = CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
451                 }
452                 function->str_len = 1;
453                 ret = TRUE;
454         } else {
455                 for (i = 0; i < CALCULATOR_MAX_FUNC_NUMBER; i++) {
456                         if (!strncmp
457                             (op, g_functions[i].func_string,
458                              strlen(g_functions[i].func_string))) {
459                                 memcpy(function, &g_functions[i],
460                                        sizeof(function_t));
461                                 ret = TRUE;
462                                 break;
463                         }
464                 }
465         }
466         return ret;
467 }
468
469 /* search function, if have, return TRUE and get the length of current function;else return FALSE */
470 gboolean __calculator_search_function(char *op, int* len)
471 {
472         gint i = 0;
473         gboolean ret = FALSE;
474         for (i = 0; i < CALCULATOR_MAX_FUNC_NUMBER; i++) {
475                 if (!strncmp(op, g_functions[i].func_string, strlen(g_functions[i].func_string))) {
476                         ret = TRUE;
477                         if(len){
478                                 *len = strlen(g_functions[i].func_string);
479                         }
480                         break;
481                 }
482         }
483         return ret;
484 }
485
486 /**
487 * @describe
488 *
489 *
490 * @param    pos
491 * @return    calculator_parentheses_data_t*
492 * @exception
493 */
494 static calculator_parentheses_data_t
495     *__calculator_calculate_get_parentheses_info(gchar * pos)
496 {
497         calculator_parentheses_data_t *found = NULL;
498         gint i = 0;
499
500         while ((g_parentheses_data[i].start_pos) ||
501                (g_parentheses_data[i].end_pos)) {
502                 if (g_parentheses_data[i].start_pos == pos) {
503                         found = &g_parentheses_data[i];
504                         break;
505                 } else if (g_parentheses_data[i].end_pos == pos) {
506                         found = &g_parentheses_data[i];
507                         break;
508                 }
509                 i++;
510         }
511
512         return found;
513 }
514
515 /**
516 * @describe
517 *
518 *
519 * @param    tmp_result
520 * @param    out_tree
521 * @param    start_pos
522 * @param    end_pos
523 * @param    error_msg
524 * @return    gboolean
525 * @exception
526 */
527 static gboolean
528 __calculator_calculate_formula_parse(double *tmp_result, GNode ** out_tree,
529                                      char *start_pos, int end_idx,
530                                      char *error_msg)
531 {
532         CALC_FUN_BEG();
533         char *end_pos = start_pos + end_idx;
534         gchar *p = NULL;
535         gchar *q = NULL;
536         gchar tmp[MAX_RESULT_LENGTH];
537         gint i = 0;
538         calculator_state_t calculator_state = CALCULATOR_OPERAND_INPUT;
539         calculator_node_data_t *node_data = NULL;
540         GNode *tree = NULL;
541         GNode *new_node = NULL;
542         GNode *last_node = NULL;        //to proc parentheses
543         calculator_parentheses_data_t *p_data = NULL;
544         gint negative_sign = 1;
545         function_t function = { 0 };
546
547         memset(tmp, 0x00, sizeof(tmp));
548
549         if (start_pos > end_pos) {
550                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
551                 return FALSE;
552         }
553
554         /* Scan from start to end of string */
555         for (p = start_pos; p <= end_pos;) {
556                 q = p;          /* Point to start of string */
557                 if (q != NULL && __calculator_util_get_operator(q, &function))  //('.'::'('::')') and digits are four exceptions
558                 {
559                         oper_num++;
560                         if (oper_num > MAX_OPERATOR_NUM) {
561                                 strcat(error_msg, CALC_MSG_MAX_OP);
562                                 return false;
563                         }
564
565                         p = q + function.str_len;       /* Shift */
566                         if ((NULL == p) && (function.category != FUNCTION_CONSTANT)) {
567                                 return false;
568                         }
569                         if ((NULL != p) && (*p == decimal_ch)) {
570                                 printf("p:%s\n", p);
571                                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
572                                 return false;
573                         }
574                         calculator_state = CALCULATOR_OPERATOR_INPUT;
575                         if (i != 0)     //save the before operator,create a node.such as 345sin(),save 345
576                         {
577                                 i = 0;
578
579                                 node_data = g_malloc0(sizeof(calculator_node_data_t));
580                                 strcpy(node_data->tmp_result, tmp);
581                                 memset(tmp, 0x00, sizeof(tmp));
582                                 node_data->negative_flag = 1;
583                                 node_data->negative_flag *= negative_sign;
584                                 new_node = g_node_new(node_data);
585                                 negative_sign = 1;
586                         } else {
587                                 if (!new_node)  //no leaf node before, first factor's "+/-" sign allowed.
588                                 {
589                                         if (((function.op_type ==OPERATOR_TYPE_BINARY)&& (function.function_char != '-'))
590                                             ||
591                                             ((function.op_type ==OPERATOR_TYPE_UNARY) && (function.category == FUNCTION_POSTFIX))) {
592                                                 strcat(error_msg,CALC_MSG_WRONG_FORMAT);
593                                                 return FALSE;
594                                         } else if (function.function_char == '-') {
595                                                 negative_sign = -1;
596                                                 continue;
597                                         }
598                                 }
599                         }
600
601                         if (function.category == FUNCTION_CONSTANT)     //Pi, e
602                         {
603                                 if (new_node)   //have the operator like 345,now it will 345*Pi
604                                 {
605                                         node_data = g_malloc0(sizeof(calculator_node_data_t));
606                                         node_data->cur_operator = 'x';
607                                         node_data->negative_flag = 1;
608                                         node_data->operator_type = OPERATOR_TYPE_BINARY;
609                                         node_data->node_calcu_priority = CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
610                                         tree = g_node_new(node_data);
611
612                                         if (last_node == NULL)  //first node
613                                         {
614                                                 g_node_insert(tree, -1, new_node);
615                                                 CALCULATOR_GET_NODE_DATA(tree)->children_num++;
616                                         } else {
617                                                 if (CALCULATOR_GET_NODE_DATA(last_node)->children_num >
618                                                     CALCULATOR_GET_NODE_DATA(last_node)->operator_type) {
619                                                         strcat(error_msg, CALC_MSG_WRONG_FORMAT);
620                                                         return FALSE;
621                                                 }
622                                                 __calculator_calculate_insert_node(&last_node, tree, new_node);
623                                         }
624                                         new_node = NULL;
625                                         last_node = tree;
626
627                                 }       //Pi will like a leaf
628                                 node_data = g_malloc0(sizeof(calculator_node_data_t));
629                                 if (function.function_char == 'p') {
630                                         strcpy(node_data->tmp_result, PI_STR);
631                                 } else if (function.function_char == 'e') {
632                                         strcpy(node_data->tmp_result, EXPONENT_STR);
633                                 }
634                                 node_data->cur_operator = function.function_char;
635                                 node_data->node_calcu_priority = function.priority;
636                                 node_data->negative_flag = 1;
637                                 node_data->negative_flag *= negative_sign;
638                                 new_node = g_node_new(node_data);
639                                 negative_sign = 1;
640                                 continue;
641                         } else if (function.category == FUNCTION_PREFIX)        //sin()
642                         {
643                                 if (!last_node) //first node
644                                 {
645                                         if (new_node) {
646                                                 node_data = g_malloc0(sizeof(calculator_node_data_t));
647                                                 node_data->cur_operator = 'x';
648                                                 node_data->negative_flag = 1;
649                                                 node_data->operator_type = OPERATOR_TYPE_BINARY;
650                                                 node_data->node_calcu_priority = CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
651                                                 tree = g_node_new(node_data);
652
653                                                 g_node_insert(tree, -1, new_node);
654                                                 CALCULATOR_GET_NODE_DATA(tree)->children_num++;
655
656                                                 last_node = tree;
657                                                 new_node = NULL;
658                                         }
659                                 }
660
661                         }
662
663                         node_data = g_malloc0(sizeof(calculator_node_data_t));
664                         node_data->cur_operator = function.function_char;
665                         node_data->node_calcu_priority = function.priority;
666                         node_data->operator_type = function.op_type;
667                         node_data->negative_flag = 1;
668                         tree = g_node_new(node_data);
669
670                         if (last_node == NULL)  //first node
671                         {
672                                 if (new_node) {
673                                         g_node_insert(tree, -1, new_node);
674                                         CALCULATOR_GET_NODE_DATA(tree)->children_num++;
675                                 }
676                         } else {
677                                 if (CALCULATOR_GET_NODE_DATA(last_node)->children_num >
678                                     CALCULATOR_GET_NODE_DATA(last_node)->operator_type) {
679                                         strcat(error_msg, CALC_MSG_WRONG_FORMAT);
680                                         return FALSE;
681                                 }
682                                 __calculator_calculate_insert_node(&last_node, tree, new_node);
683                         }
684                         last_node = tree;
685                         new_node = NULL;
686                 } else {
687                         p++;    /* Shift */
688                 }
689
690                 if (NULL == q) {
691                         strcat(error_msg, CALC_MSG_WRONG_FORMAT);       //add for "6((" ,then "="
692                         return FALSE;
693                 }               //added by zhaodanni for prevent
694                 else if (*q == decimal_ch) {
695                         if (!isdigit(*p) || (calculator_state == CALCULATOR_OPERAND_FRACTION_INPUT)) {
696                         } else {
697                                 calculator_state = CALCULATOR_OPERAND_FRACTION_INPUT;
698                         }
699                         tmp[i++] = *q;
700                 } else if (*q == '(') {
701                         if (__calculator_util_get_operator(p, &function)) {
702                                 if ((function.category == FUNCTION_POSTFIX) && ((*p != '+') && (*p != '-')))    //"(*","(/", not allowed.
703                                 {
704                                         strcat(error_msg, CALC_MSG_WRONG_FORMAT);
705                                         return FALSE;
706                                 }
707                         }
708                         if ((new_node)
709                             &&
710                             (!strcmp(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, PI_STR)
711                              || !strcmp(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, EXPONENT_STR))) {
712                                 node_data =g_malloc0(sizeof(calculator_node_data_t));
713                                 node_data->cur_operator = 'x';
714                                 node_data->negative_flag = 1;
715                                 node_data->operator_type = OPERATOR_TYPE_BINARY;
716                                 node_data->node_calcu_priority = CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
717                                 tree = g_node_new(node_data);
718
719                                 if (last_node) {
720                                         __calculator_calculate_insert_node(&last_node, tree, new_node);
721                                 } else {
722                                         g_node_insert(tree, -1, new_node);
723                                         CALCULATOR_GET_NODE_DATA(tree)->children_num++;
724                                 }
725                                 last_node = tree;
726                                 new_node = NULL;
727                         }
728
729                         if (i != 0) {
730                                 i = 0;
731
732                                 node_data = g_malloc0(sizeof(calculator_node_data_t));
733                                 strcpy(node_data->tmp_result, tmp);
734                                 memset(tmp, 0x00, sizeof(tmp));
735                                 node_data->negative_flag = 1;
736                                 node_data->negative_flag *= negative_sign;
737                                 negative_sign = 1;
738                                 new_node = g_node_new(node_data);
739
740                                 node_data = g_malloc0(sizeof(calculator_node_data_t));
741                                 node_data->cur_operator = 'x';
742                                 node_data->negative_flag = 1;
743                                 node_data->operator_type = OPERATOR_TYPE_BINARY;
744                                 node_data->node_calcu_priority =CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
745                                 tree = g_node_new(node_data);
746
747                                 if (last_node == NULL)  //first node
748                                 {
749                                         g_node_insert(tree, -1, new_node);
750                                         CALCULATOR_GET_NODE_DATA(tree)->children_num++;
751                                 } else {
752                                         if (CALCULATOR_GET_NODE_DATA(last_node)->children_num >
753                                             CALCULATOR_GET_NODE_DATA(last_node)->operator_type) {
754                                                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
755                                                 return FALSE;
756                                         }
757
758                                         __calculator_calculate_insert_node(&last_node, tree, new_node);
759                                 }
760                                 last_node = tree;
761                                 new_node = NULL;
762                         }
763
764                         p_data = __calculator_calculate_get_parentheses_info(q);
765                         if (!p_data) {
766                                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
767                                 return FALSE;
768                         }
769                         p = p_data->end_pos;
770                 } else if (*q == ')') {
771                         if (*p == decimal_ch)   //").", not allowed.
772                         {
773                                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
774                                 return FALSE;
775                         }
776
777                         p_data = __calculator_calculate_get_parentheses_info(q);
778                         if (!p_data) {
779                                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
780                                 return FALSE;
781                         }
782                         if (!__calculator_calculate_formula_parse(NULL, &new_node, (p_data->start_pos + 1),
783                              (p_data->end_pos - 1) - (p_data->start_pos + 1), error_msg)) {
784                                 if (new_node != NULL) {
785                                         __calculator_tree_destroy_all(&new_node);
786                                 } else {
787                                         LOGD("current node is null\n");
788                                 }
789                                 return FALSE;
790                         }
791                         if (new_node) {
792                                 CALCULATOR_GET_NODE_DATA(new_node)->negative_flag *= negative_sign;
793                         }
794                         negative_sign = 1;
795
796                         if ((*p == '(') || (isdigit(*p))) {
797                                 node_data = g_malloc0(sizeof(calculator_node_data_t));
798                                 node_data->cur_operator = 'x';
799                                 node_data->negative_flag = 1;
800                                 node_data->operator_type = OPERATOR_TYPE_BINARY;
801                                 node_data->node_calcu_priority = CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
802                                 tree = g_node_new(node_data);
803
804                                 if (last_node == NULL)  //first node
805                                 {
806                                         if (new_node) {
807                                                 g_node_insert(tree, -1,
808                                                               new_node);
809                                                 CALCULATOR_GET_NODE_DATA(tree)->
810                                                     children_num++;
811                                         }
812                                 } else {
813                                         if (CALCULATOR_GET_NODE_DATA
814                                             (last_node)->children_num >
815                                             CALCULATOR_GET_NODE_DATA
816                                             (last_node)->operator_type) {
817                                                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
818                                                 return FALSE;
819                                         }
820
821                                         __calculator_calculate_insert_node
822                                             (&last_node, tree, new_node);
823                                 }
824                                 last_node = tree;
825                                 new_node = NULL;
826                         }
827                 } else if (isdigit(*q)) {
828                         if (new_node) {
829                                 node_data = g_malloc0(sizeof(calculator_node_data_t));
830                                 node_data->cur_operator = 'x';
831                                 node_data->negative_flag = 1;
832                                 node_data->operator_type = OPERATOR_TYPE_BINARY;
833                                 node_data->node_calcu_priority = CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
834                                 tree = g_node_new(node_data);
835
836                                 if (last_node) {
837                                         __calculator_calculate_insert_node(&last_node, tree, new_node);
838                                 } else {
839                                         g_node_insert(tree, -1, new_node);
840                                         CALCULATOR_GET_NODE_DATA(tree)->children_num++;
841                                 }
842                                 last_node = tree;
843                                 new_node = NULL;
844                         }
845                         calculator_state = CALCULATOR_OPERAND_INPUT;
846                         tmp[i++] = *q;
847                 }/*for unvalid input ,such as "clipborad"*/
848                 else if ((*q != '+') && (*q != '-') && (*q != 'x')
849                          && (*q != '/')) {
850                         if (!__calculator_search_function(q, NULL)) {
851                                 printf("q=%s,line=%d\n", q, __LINE__);
852                                 strcat(error_msg, "invalid input");
853                                 return FALSE;
854                         }
855                 }
856         }
857
858         if (i != 0)             //last digit number
859         {
860                 //if ((new_node) && (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == PI || CALCULATOR_GET_NODE_DATA(new_node)->tmp_result == EXPONENT))
861                 if ((new_node)
862                     &&
863                     (!strcmp
864                      (CALCULATOR_GET_NODE_DATA(new_node)->tmp_result, PI_STR)
865                      || !strcmp(CALCULATOR_GET_NODE_DATA(new_node)->tmp_result,
866                                 EXPONENT_STR))) {
867                         node_data = g_malloc0(sizeof(calculator_node_data_t));
868                         node_data->cur_operator = 'x';
869                         node_data->negative_flag = 1;
870                         node_data->operator_type = OPERATOR_TYPE_BINARY;
871                         node_data->node_calcu_priority = CALCULATOR_CALCULATE_PRIORITY_MIDDLE;
872                         tree = g_node_new(node_data);
873
874                         if (last_node) {
875                                 __calculator_calculate_insert_node(&last_node, tree, new_node);
876                         } else {
877                                 g_node_insert(tree, -1, new_node);
878                                 CALCULATOR_GET_NODE_DATA(tree)->children_num++;
879                         }
880                         last_node = tree;
881                         new_node = NULL;
882                 }
883                 i = 0;
884
885                 node_data = g_malloc0(sizeof(calculator_node_data_t));
886                 strcpy(node_data->tmp_result, tmp);
887                 memset(tmp, 0x00, sizeof(tmp));
888                 node_data->negative_flag = 1;
889                 node_data->negative_flag *= negative_sign;
890                 negative_sign = 1;
891                 new_node = g_node_new(node_data);
892
893                 if (last_node != NULL) {
894                         if (CALCULATOR_GET_NODE_DATA(last_node)->children_num >
895                             CALCULATOR_GET_NODE_DATA(last_node)->operator_type) {
896                                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
897                                 return FALSE;
898                         } else {
899                                 g_node_insert(last_node, -1, new_node);
900                                 CALCULATOR_GET_NODE_DATA(last_node)->
901                                     children_num++;
902                         }
903                         new_node = NULL;
904                 }
905         }
906
907         if (new_node != NULL) {
908                 CALCULATOR_GET_NODE_DATA(new_node)->negative_flag *=
909                     negative_sign;
910                 negative_sign = 1;
911
912                 if (last_node != NULL) {
913                         if (CALCULATOR_GET_NODE_DATA(last_node)->children_num >
914                             CALCULATOR_GET_NODE_DATA(last_node)->operator_type) {
915                                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
916                                 return FALSE;
917                         } else {
918                                 g_node_insert(last_node, -1, new_node);
919                                 CALCULATOR_GET_NODE_DATA(last_node)->
920                                     children_num++;
921                         }
922                 } else {
923                         last_node = new_node;
924                 }
925                 new_node = NULL;
926         }
927         *out_tree = g_node_get_root(last_node);
928         CALC_FUN_END();
929         return TRUE;
930 }
931
932 /**
933 * @describe
934 *
935 *
936 * @param        node
937 * @param        data
938 * @return       gboolean
939 * @exception
940 */
941 static gboolean
942 __calculator_calculate_exec_traverse_func(GNode * node, gpointer data)
943 {
944         gdouble operand0, operand1 = 0.0;
945         double tmp_ret = 0.0;
946         decNumber doperand0, doperand1, dresult;
947         decContext set;
948         char dec_result[DECNUMDIGITS + 14];
949         char dec_result_tmp[MAX_RESULT_LENGTH] = { 0 };
950         char *error_msg = (char *)data;
951         char op0buf[MAX_RESULT_LENGTH] = { 0 };
952         char op1buf[MAX_RESULT_LENGTH] = { 0 };
953         if (CALCULATOR_GET_NODE_DATA(node)->children_num !=
954             CALCULATOR_GET_NODE_DATA(node)->operator_type) {
955                 strcat(error_msg, CALC_MSG_NUM_AFTER_OP);
956                 return TRUE;    //break the recursion
957         }
958
959         decContextTestEndian(0);
960         decContextDefault(&set, DEC_INIT_BASE);
961         set.digits = DECNUMDIGITS;
962
963         if (CALCULATOR_GET_NODE_DATA(node->children)->negative_flag == -1) {
964                 strcat(op0buf, "-");
965                 CALCULATOR_GET_NODE_DATA(node->children)->negative_flag = 1;
966         }
967         strcat(op0buf, CALCULATOR_GET_NODE_DATA(node->children)->tmp_result);
968         operand0 = atof(op0buf);
969         decNumberFromString(&doperand0, op0buf, &set);
970
971         if (CALCULATOR_GET_NODE_DATA(node)->operator_type == OPERATOR_TYPE_BINARY) {
972                 if (CALCULATOR_GET_NODE_DATA
973                     (node->children->next)->negative_flag == -1) {
974                         strcat(op1buf, "-");
975                         CALCULATOR_GET_NODE_DATA(node->children->next)->negative_flag = 1;
976                 }
977                 strcat(op1buf, CALCULATOR_GET_NODE_DATA(node->children->next)->tmp_result);
978                 operand1 = atof(op1buf);
979                 decNumberFromString(&doperand1, op1buf, &set);
980         }
981         switch (CALCULATOR_GET_NODE_DATA(node)->cur_operator) {
982         case '+':
983                 decNumberAdd(&dresult, &doperand0, &doperand1, &set);
984                 decNumberToString(&dresult, dec_result);
985                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
986                 break;
987         case '-':
988                 decNumberSubtract(&dresult, &doperand0, &doperand1, &set);
989                 decNumberToString(&dresult, dec_result);
990                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
991                 break;
992         case 'x':
993                 decNumberMultiply(&dresult, &doperand0, &doperand1, &set);
994                 decNumberToString(&dresult, dec_result);
995                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
996                 break;
997         case '/':
998                 if (FLOAT_EQUAL(operand1, 0)) {
999                         strcat(error_msg, CALC_MSG_DIVIDE_BY_ZERO);
1000                         return TRUE;    //break the recursion
1001                 } else {
1002                         decNumberDivide(&dresult, &doperand0, &doperand1, &set);
1003                         decNumberToString(&dresult, dec_result);
1004                         strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1005                 }
1006                 break;
1007         case '^':
1008                 if (operand0 < 0) {
1009                         gdouble power = 0.0;
1010                         power = floor(operand1);
1011                         if (!FLOAT_EQUAL(power, operand1))      //operand1 is not an integer
1012                         {
1013                                 return TRUE;
1014                         }
1015                 }
1016                 tmp_ret =pow(operand0, operand1);
1017                 if (fabs(tmp_ret - 0) < 0.000001) {
1018                         snprintf(dec_result_tmp, sizeof(dec_result_tmp), "%.99f", tmp_ret);
1019                 } else {
1020                         snprintf(dec_result_tmp, sizeof(dec_result_tmp), "%lf", tmp_ret);
1021                 }
1022                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result_tmp);
1023                 if (!__calculator_check_overflow(atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result), error_msg)) {
1024                         return TRUE;
1025                 }
1026                 break;
1027         case '!':
1028                 if (operand0 < 0) {
1029                         gdouble power = 0.0;
1030                         power = floor(operand1);
1031                         if (!FLOAT_EQUAL(power, operand1))      //operand1 is not an integer
1032                         {
1033                                 strcat(error_msg, CALC_MSG_INVALID_FAC);
1034                                 return TRUE;
1035                         }
1036                 }
1037                 if (strlen(error_msg) != 0) {
1038                         return TRUE;
1039                 }
1040                 tmp_ret = __calculator_calculate_factorial(operand0, error_msg);
1041                 snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
1042                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1043                 if (strlen(error_msg) != 0) {
1044                         return TRUE;
1045                 }
1046                 break;
1047
1048         case 'L':
1049                 if (operand0 < 0) {
1050                         return TRUE;
1051                 } else if (FLOAT_EQUAL(operand0, 0)) {
1052                         return TRUE;
1053                 }
1054                 set.emax = 999999;
1055                 set.emin = -999999;
1056                 decNumberLn(&dresult, &doperand0, &set);
1057                 decNumberToString(&dresult, dec_result);
1058                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1059                 if (!__calculator_check_overflow
1060                     (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
1061                      error_msg)) {
1062                         return TRUE;
1063                 }
1064                 break;
1065         case 'q':
1066                 if (operand0 < 0) {
1067                         strcat(error_msg, CALC_MSG_INVALID_SQUARE);
1068                         return TRUE;
1069                 }
1070                 decNumberSquareRoot(&dresult, &doperand0, &set);
1071                 decNumberToString(&dresult, dec_result);
1072                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1073
1074                 if (!__calculator_check_overflow
1075                     (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
1076                      error_msg)) {
1077                         return TRUE;
1078                 }
1079                 break;
1080         case 's':
1081                 tmp_ret = sin(operand0 * RADIAN_FACTOR);
1082                 snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
1083                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1084                 if (!__calculator_check_overflow
1085                     (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
1086                      error_msg)) {
1087                         return TRUE;
1088                 }
1089                 break;
1090         case 'c':
1091                 tmp_ret = cos(operand0 * RADIAN_FACTOR);
1092                 snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
1093                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1094
1095                 if (!__calculator_check_overflow
1096                     (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
1097                      error_msg)) {
1098                         return TRUE;
1099                 }
1100                 break;
1101         case 't':
1102                 if (FLOAT_EQUAL(fmod(operand0, 180), 90) || FLOAT_EQUAL(fmod(operand0, 180), -90))      //revise by bfl
1103                 {
1104                         return TRUE;
1105                 }
1106                 tmp_ret = tan(operand0 * RADIAN_FACTOR);
1107                 snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
1108                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1109                 if (!__calculator_check_overflow
1110                     (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
1111                      error_msg)) {
1112                         return TRUE;
1113                 }
1114                 break;
1115         case 'l':
1116                 if (operand0 < 0) {
1117                         strcat(error_msg, CALC_MSG_INVALID_LOG);
1118                         return TRUE;
1119                 } else if (FLOAT_EQUAL(operand0, 0)) {
1120                         strcat(error_msg, CALC_MSG_INVALID_LOG);
1121                         return TRUE;
1122                 }
1123                 set.emax = 999999;
1124                 set.emin = -999999;
1125                 decNumberLog10(&dresult, &doperand0, &set);
1126                 decNumberToString(&dresult, dec_result);
1127                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1128                 if (!__calculator_check_overflow
1129                     (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
1130                      error_msg)) {
1131                         return TRUE;
1132                 }
1133                 break;
1134         case 'b':
1135                 tmp_ret = fabs(operand0);
1136                 snprintf(dec_result, sizeof(dec_result), "%lf", tmp_ret);
1137                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1138                 if (!__calculator_check_overflow
1139                     (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
1140                      error_msg)) {
1141                         return TRUE;
1142                 }
1143                 break;
1144
1145         case '2':
1146                 decNumberFromString(&doperand1, "2", &set);
1147                 decNumberPower(&dresult, &doperand1, &doperand0, &set);
1148                 decNumberToString(&dresult, dec_result);
1149                 strcpy(CALCULATOR_GET_NODE_DATA(node)->tmp_result, dec_result);
1150                 if (!__calculator_check_overflow
1151                     (atof(CALCULATOR_GET_NODE_DATA(node)->tmp_result),
1152                      error_msg)) {
1153                         return TRUE;
1154                 }
1155                 break;
1156
1157         default:
1158                 break;
1159         }
1160         /*CALCULATOR_GET_NODE_DATA(node)->tmp_result *=
1161             CALCULATOR_GET_NODE_DATA(node)->negative_flag;
1162         CALCULATOR_GET_NODE_DATA(node)->negative_flag = 1;*/
1163
1164         return FALSE;
1165 }
1166
1167 /**
1168 * @describe
1169 *
1170 *
1171 * @param    tree
1172 * @param    result
1173 * @param    error_msg
1174 * @return    gboolean
1175 * @exception
1176 */
1177 static gboolean
1178 __calculator_calculate_exec(GNode * tree, double **result, char *error_msg)
1179 {
1180         guint depth = 0;
1181         depth = g_node_max_height(tree);
1182
1183         if (depth < 1) {
1184                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
1185                 return FALSE;   //break the recursion
1186         } else if (depth == 1) {
1187                 **result = atof(CALCULATOR_GET_NODE_DATA(tree)->tmp_result);
1188                 **result *= CALCULATOR_GET_NODE_DATA(tree)->negative_flag;
1189                 return TRUE;
1190         }
1191         g_node_traverse(tree,
1192                         G_POST_ORDER,
1193                         G_TRAVERSE_NON_LEAFS,
1194                         depth,
1195                         __calculator_calculate_exec_traverse_func,
1196                         (gpointer) error_msg);
1197
1198         if (strlen(error_msg) > 0) {
1199                 return FALSE;
1200         } else {
1201                 **result = atof(CALCULATOR_GET_NODE_DATA(tree)->tmp_result);
1202         }
1203         return TRUE;
1204 }
1205
1206 /**
1207 * @describe
1208 *
1209 *
1210 * @param    tmp_result
1211 * @return    gboolean
1212 * @exception
1213 */
1214
1215 #if 0
1216
1217 /*
1218 bool calculator_calculate_truncate_result(double* tmp_result)
1219 {
1220
1221         return TRUE;
1222 }
1223 */
1224 #endif
1225
1226 /**
1227 * @describe
1228 *
1229 *
1230 * @param    szInputString
1231 * @return    int
1232 * @exception
1233 */
1234 int calculator_get_open_braket(const char *szInputString)
1235 {
1236         int nReversIndex = strlen(szInputString) - 1;
1237         int nOpenCnt = 0;
1238         int nCloseCnt = 0;
1239
1240         while (nReversIndex >= 0) {
1241                 if (szInputString[nReversIndex] == '(') {
1242                         nOpenCnt++;
1243                 } else if (szInputString[nReversIndex] == ')') {
1244                         nCloseCnt++;
1245                 }
1246                 nReversIndex--;
1247         }
1248         return (nOpenCnt - nCloseCnt);
1249 }
1250
1251 /**
1252 * @describe
1253 *
1254 *
1255 * @param    szInput
1256 * @param    [out]pDigitCnt : count of digit before point(.)
1257 * @param    [out]pPointCnt: count of digit after point(.)
1258 * @return    int
1259 * @exception
1260 */
1261 bool calculator_get_digits_number(char *szInput, int *pDigitCnt, int *pPointCnt)
1262 {
1263         int nLen = strlen(szInput);
1264         int nIndex;
1265
1266         int nTempCnt = 0;
1267         int nTempCntb = 0;
1268
1269         *pDigitCnt = 0;
1270         *pPointCnt = 0;
1271
1272         if (nLen > 0) {
1273                 for (nIndex = nLen - 1; nIndex >= 0; nIndex--) {
1274                         if (isdigit(szInput[nIndex])) {
1275                                 nTempCnt++;
1276                         } else if (szInput[nIndex] == decimal_ch) {
1277                                 *pPointCnt = nTempCnt;
1278                                 nTempCnt = 0;
1279                                 break;
1280                         }
1281                 }
1282                 for (nIndex = 0; nIndex < nLen; nIndex++) {
1283                         if (isdigit(szInput[nIndex])) {
1284                                 nTempCntb++;
1285                         } else if (szInput[nIndex] == decimal_ch) {
1286                                 *pDigitCnt = nTempCntb;
1287                                 break;
1288                         }
1289                 }
1290                 //*pDigitCnt = nTempCntb;
1291         }
1292         return true;
1293 }
1294
1295 /**
1296 * @describe
1297 *
1298 *
1299 * @param    str
1300 * @param    error_msg
1301 * @return    bool
1302 * @exception
1303 */
1304 bool calculator_expression_length_check(char *str, char *error_msg)
1305 {
1306         int is_digit = 0, has_dot = 0;
1307         int idx = 0, nCount = 0, nDigitCnt = 0, nPointCnt = 0;
1308         char *p = NULL;
1309         char c;
1310
1311 #if 0
1312 /*
1313
1314         if(strlen(str) > CALCULATOR_MAX_INPUT_DIGIT_NUMBER_POR)
1315         {
1316                 strcat(error_msg, CALC_MSG_MAX_INPUT);
1317                 return FALSE;
1318         }
1319 */
1320 #endif
1321
1322         p = str;
1323         while (idx < strlen(str)) {
1324                 c = p[idx];
1325
1326                 if (isdigit(c)) {
1327                         if (is_digit == 0) {
1328                                 is_digit = 1;
1329
1330                                 nDigitCnt = 1;
1331                                 nCount = 1;
1332                         } else {
1333                                 nCount++;
1334                                 if (nCount > MAX_NUM_LENGTH) {
1335                                         strcat(error_msg, CALC_MSG_MAX_DIGIT);
1336                                         return FALSE;
1337                                 }
1338
1339                                 if (has_dot == 0) {
1340                                         nDigitCnt++;
1341                                 } else {
1342                                         nPointCnt++;
1343
1344 #if 0                           //YangQ
1345                                         /*
1346                                            if(nPointCnt > CALCULATORUI_MAX_INPUT_DECIMALS)
1347                                            {
1348                                            strcat(error_msg, CALC_MSG_MAX_DEC_DIGIT);
1349                                            PTAG;
1350                                            return FALSE;
1351                                            }
1352                                          */
1353 #endif
1354                                 }
1355                         }
1356                 }
1357                 else if (c == decimal_ch) {
1358                         if (has_dot == 1) {
1359                                 return FALSE;
1360                         } else {
1361                                 has_dot = 1;
1362                         }
1363                 } else {
1364                         if (is_digit == 1) {
1365                                 is_digit = 0;
1366                                 has_dot = 0;
1367                                 nCount = 0;
1368                                 nDigitCnt = 0;
1369                                 nPointCnt = 0;
1370                         }
1371                 }
1372
1373                 idx++;
1374         }
1375
1376         return TRUE;
1377
1378 }
1379
1380 /**
1381 * @describe
1382 *
1383 *
1384 * @param    string
1385 * @param    result
1386 * @param    error_msg
1387 * @return    bool
1388 * @exception
1389 */
1390 bool calculator_calculate(gchar * string, gdouble * result, char *error_msg)
1391 {
1392 #if 1                           //YangQ add.
1393         string_replace(string, "E+", "x10^");
1394         string_replace(string, "E-", "x0.1^");
1395 #endif
1396         GNode *tree = NULL;
1397         int end_idx = 0;
1398
1399         memset(error_msg, 0, MAX_ERROR_MESSAGE_LENGTH);
1400         memset(g_stack, 0, sizeof(g_stack));
1401         oper_num = 0;
1402
1403         strncpy(g_stack, string, MAX_EXPRESSION_LENGTH - 1);
1404         g_stack[MAX_EXPRESSION_LENGTH - 1] = '\0';
1405
1406         char *digit = "0123456789pe";
1407         if (strcspn(g_stack, digit) == strlen(g_stack)) {       /* no digit in expression */
1408                 strcat(error_msg, CALC_MSG_WRONG_FORMAT);
1409                 return FALSE;
1410         }
1411
1412         if (!calculator_expression_length_check(g_stack, error_msg)) {
1413                 return FALSE;
1414         }
1415         if (!__calculator_calculate_formula_scan(g_stack, &end_idx, error_msg)) {
1416                 return FALSE;
1417         }
1418
1419         if (!__calculator_calculate_formula_parse
1420             (result, &tree, g_stack, end_idx, error_msg)) {
1421                 if (tree != NULL) {
1422                         __calculator_tree_destroy_all(&tree);
1423                 } else {
1424                         LOGD("current tree is null\n");
1425                 }
1426                 return FALSE;
1427         }
1428         if (!__calculator_calculate_exec(tree, &result, error_msg)) {
1429                 if (tree != NULL) {
1430                         __calculator_tree_destroy_all(&tree);
1431                 }
1432                 return FALSE;
1433         }
1434         if (!__calculator_check_overflow(*result, error_msg)) {
1435                 if (tree != NULL) {
1436                         __calculator_tree_destroy_all(&tree);
1437                 }
1438                 return FALSE;
1439         }
1440
1441         if (tree != NULL) {
1442                 __calculator_tree_destroy_all(&tree);
1443         }
1444         oper_num = 0;
1445         return TRUE;
1446 }