tizen 2.4 release
[adaptation/xorg/driver/xserver-xorg-module-xdbg.git] / common / ds / bool_exp_parser.c
1 /**************************************************************************
2
3 xserver-xorg-video-exynos
4
5 Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
19 of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <strings.h>
34 #include <stdlib.h>
35
36 #include "bool_exp_tokenizer.h"
37 #include "bool_exp_parser.h"
38 #include "bintree.h"
39
40 typedef struct _TOKEN_DATA * TOKEN_DATA;
41
42 struct _TOKEN_DATA
43 {
44     const char ** string;
45     TOKEN last_token;
46     const char * last_symbol;
47     int symbol_len;
48 };
49
50 static BINARY_TREE_NODE bool_exp_parse_line (BINARY_TREE tree, TOKEN_DATA token);
51
52 #define PARSE_DEBUG 0
53
54 #if PARSE_DEBUG
55 #define process_token(t) _process_token(t, __LINE__)
56 static void _process_token (TOKEN_DATA token, int line)
57 #else
58 static void process_token (TOKEN_DATA token)
59 #endif
60 {
61     do
62     {
63         token->last_symbol = *(token->string);
64         token->last_token = get_next_token (token->string);
65         token->symbol_len = *(token->string) - token->last_symbol;
66
67     }
68     while (token->last_token == BET_SPACE);
69 #if PARSE_DEBUG
70     printf ("token : %d remained string : [%s] (line:%d)\n", token->last_token, *token->string, line);
71 #endif
72 }
73
74 static BINARY_TREE_NODE bool_exp_parse_statement (BINARY_TREE tree, TOKEN_DATA token)
75 {
76     BINARY_TREE_NODE node = NULL;
77     PARSE_DATA data = NULL;
78
79 #if PARSE_DEBUG
80     printf ("%s:%d (token->last_token %d)\n", __FILE__, __LINE__, token->last_token);
81 #endif
82
83     if (token->last_token == BET_L_BR)
84     {
85         process_token (token);
86
87         node = bool_exp_parse_line (tree, token);
88         if (node == NULL)
89         {
90             return NULL;
91         }
92
93         if (token->last_token != BET_R_BR)
94         {
95             goto fail;
96         }
97         process_token (token);
98
99         return node;
100     }
101
102     if (token->last_token != BET_SYMBOL)
103         goto fail;
104
105     node = bintree_create_node (tree);
106
107     data = (PARSE_DATA) bintree_get_node_data (node);
108
109     strncpy (data->variable_name, token->last_symbol, token->symbol_len);
110     data->variable_name[token->symbol_len] = '\0';
111
112     if (!strcasecmp (data->variable_name, "all"))
113     {
114         data->node_type = ALL;
115         process_token (token);
116
117         return node;
118     }
119
120     data->node_type = DATA;
121
122     process_token (token);
123
124     switch (token->last_token)
125     {
126     case BET_NOT_EQ:
127         data->compare = NOT_EQ;
128         break;
129     case BET_EQUAL:
130         data->compare = EQUAL;
131         break;
132     case BET_LSS_THAN:
133         data->compare = LESS;
134         break;
135     case BET_LSS_EQ:
136         data->compare = LESS_EQ;
137         break;
138     case BET_GRT_THAN:
139         data->compare = GREATER;
140         break;
141     case BET_GRT_EQ:
142         data->compare = GREATER_EQ;
143         break;
144     default:
145         goto fail;
146     }
147
148     process_token (token);
149
150     if (token->last_token == BET_NUMBER)
151     {
152         data->value_type = INTEGER;
153         data->value.integer = atoi (token->last_symbol);
154     }
155     else if (token->last_token == BET_SYMBOL)
156     {
157         data->value_type = STRING;
158         strncpy (data->value.string, token->last_symbol, token->symbol_len);
159         data->value.string[token->symbol_len] = '\0';
160     }
161     else
162     {
163         goto fail;
164     }
165
166     process_token (token);
167
168     return node;
169
170 fail:
171     if (node)
172         bintree_remove_node_recursive (node);
173
174     return NULL;
175 }
176
177 static BINARY_TREE_NODE bool_exp_parse_line (BINARY_TREE tree, TOKEN_DATA token)
178 {
179     BINARY_TREE_NODE node = NULL;
180     BINARY_TREE_NODE left = NULL;
181     BINARY_TREE_NODE right = NULL;
182
183     PARSE_DATA data;
184
185 #if PARSE_DEBUG
186     printf ("%s:%d\n", __FILE__, __LINE__);
187 #endif
188
189     node = bool_exp_parse_statement (tree, token);
190     if (node == NULL)
191     {
192         printf ("PARSE statement error\n");
193         goto fail;
194     }
195
196     while (token->last_token == BET_AND)
197     {
198         left = node;
199         node = NULL;
200
201         process_token (token);
202         right = bool_exp_parse_statement (tree, token);
203         if (right == NULL)
204             goto fail;
205
206         node = bintree_create_node (tree);
207
208         data = (PARSE_DATA) bintree_get_node_data (node);
209         data->node_type = AND;
210         bintree_set_left_child (node, left);
211         bintree_set_right_child (node, right);
212     }
213
214     if (token->last_token == BET_OR)
215     {
216         left = node;
217         node = NULL;
218
219         process_token (token);
220         right = bool_exp_parse_line (tree, token);
221         if (right == NULL)
222             goto fail;
223
224         node = bintree_create_node (tree);
225
226         data = (PARSE_DATA) bintree_get_node_data (node);
227         data->node_type = OR;
228         bintree_set_left_child (node, left);
229         bintree_set_right_child (node, right);
230     }
231
232     return node;
233
234 fail:
235     if (left)
236         bintree_remove_node_recursive (left);
237     return NULL;
238 }
239
240 BINARY_TREE bool_exp_parse (const char * string)
241 {
242     BINARY_TREE tree = bintree_create_tree (sizeof (struct _PARSE_DATA));
243     BINARY_TREE_NODE node;
244
245     struct _TOKEN_DATA token;
246
247     if (!tree)
248         return NULL;
249
250     token.string = &string;
251     process_token (&token);
252
253     node = bool_exp_parse_line (tree, &token);
254     if (node == NULL)
255     {
256         bintree_destroy_tree (tree);
257         return NULL;
258     }
259
260     bintree_set_head (tree, node);
261
262     return tree;
263 }