src/server/util/object.c

changeset 423
bb7cff720dd0
parent 421
437562f5681d
child 424
3df9258cd3cc
equal deleted inserted replaced
422:76f2f5d532d0 423:bb7cff720dd0
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include <cx/string.h> 29 #include <cx/string.h>
30 #include <cx/linked_list.h>
31 #include <cx/compare.h>
30 32
31 #include "../public/nsapi.h" 33 #include "../public/nsapi.h"
32 34
33 #include "object.h" 35 #include "object.h"
34 36 #include "util.h"
35 #include "pool.h" 37 #include "pool.h"
36 #include "../daemon/func.h" 38 #include "../daemon/func.h"
37 39
38 40
39 41
104 context->dtable_index = 0; 106 context->dtable_index = 0;
105 context->objset_index = -1; 107 context->objset_index = -1;
106 context->last_req_code = REQ_NOACTION; 108 context->last_req_code = REQ_NOACTION;
107 } 109 }
108 110
111
112 /* ------------------------------ Expression ------------------------------ */
113
114 Expression* condition_create(pool_handle_t *pool, CxList *tokens) {
115
116
117
118 return NULL;
119 }
120
121
122 typedef struct {
123 pool_handle_t *pool;
124 CxList *op_stack;
125 CxList *ex_stack;
126 CxList *tokens;
127 size_t *pos;
128 int expect_value;
129 } ExprParser;
130
131 typedef struct {
132 NSAPIExpressionOperator operator;
133 int expect_value;
134 int open_parenthesis;
135 } ExprOpStackItem;
136
137 static void expr_free(pool_handle_t *pool, NSAPIExpression *expr) {
138 if(expr->left) {
139 expr_free(pool, expr->left);
140 }
141 if(expr->right) {
142 expr_free(pool, expr->right);
143 }
144 if(expr->type == NSAPI_EXPRESSION_STRING && expr->value.str.ptr) {
145 pool_free(pool, (char*)expr->value.str.ptr);
146 } else if(expr->type == NSAPI_EXPRESSION_VARIABLE && expr->value.var.ptr) {
147 pool_free(pool, (char*)expr->value.var.ptr);
148 }
149 pool_free(pool, expr);
150 }
151
152 static NSAPIExpressionOperator expr_operator(cxstring token) {
153 if(!cx_strcmp(token, cx_str("+"))) {
154 return NSAPI_EXPRESSION_ADD;
155 } else if(!cx_strcmp(token, cx_str("-"))) {
156 return NSAPI_EXPRESSION_SUB;
157 } else if(!cx_strcmp(token, cx_str("*"))) {
158 return NSAPI_EXPRESSION_MUL;
159 } else if(!cx_strcmp(token, cx_str("/"))) {
160 return NSAPI_EXPRESSION_DIV;
161 } else if(!cx_strcmp(token, cx_str("%"))) {
162 return NSAPI_EXPRESSION_MOD;
163 } else if(!cx_strcmp(token, cx_str("not"))) {
164 return NSAPI_EXPRESSION_NOT;
165 } else if(!cx_strcmp(token, cx_str("and"))) {
166 return NSAPI_EXPRESSION_AND;
167 } else if(!cx_strcmp(token, cx_str("or"))) {
168 return NSAPI_EXPRESSION_OR;
169 } else if(!cx_strcmp(token, cx_str("xor"))) {
170 return NSAPI_EXPRESSION_XOR;
171 } else if(!cx_strcmp(token, cx_str("=="))) {
172 return NSAPI_EXPRESSION_EQ;
173 } else if(!cx_strcmp(token, cx_str("!="))) {
174 return NSAPI_EXPRESSION_NEQ;
175 } else if(!cx_strcmp(token, cx_str(">"))) {
176 return NSAPI_EXPRESSION_GT;
177 } else if(!cx_strcmp(token, cx_str("<"))) {
178 return NSAPI_EXPRESSION_LT;
179 } else if(!cx_strcmp(token, cx_str(">="))) {
180 return NSAPI_EXPRESSION_GE;
181 } else if(!cx_strcmp(token, cx_str("<="))) {
182 return NSAPI_EXPRESSION_LE;
183 }
184 return NSAPI_EXPRESSION_NOOP;
185 }
186
187 static int token_is_int(cxstring token) {
188 for(size_t i=0;i<token.length;i++) {
189 if(!isdigit(token.ptr[i])) {
190 return 0;
191 }
192 }
193 return 1;
194 }
195
196 static int expr_set_value(pool_handle_t *pool, NSAPIExpression *expr, cxstring token) {
197 if(token.length >= 2 && token.ptr[0] == '\"' && token.ptr[token.length-1] == '\"') {
198 expr->value.str = cx_strcast(cx_strdup_a(pool_allocator(pool), cx_strsubsl(token, 1, token.length-2)));
199 expr->type = NSAPI_EXPRESSION_STRING;
200 } else if(token.length >= 2 && token.ptr[0] == '$' && isalpha(token.ptr[1])) {
201 expr->value.var = cx_strcast(cx_strdup_a(pool_allocator(pool), cx_strsubs(token, 1)));
202 expr->type = NSAPI_EXPRESSION_VARIABLE;
203 } else if(token_is_int(token)) {
204 if(!util_strtoint(token.ptr, &expr->value.i)) {
205 return 1;
206 }
207 expr->type = NSAPI_EXPRESSION_INT;
208 } else if(!strcmp(token.ptr, "true")) {
209 expr->type = NSAPI_EXPRESSION_BOOL;
210 expr->value.b = 1;
211 } else if(!strcmp(token.ptr, "false")) {
212 expr->type = NSAPI_EXPRESSION_BOOL;
213 expr->value.b = 0;
214 } else {
215 return 1;
216 }
217 // TODO: double
218 return 0;
219 }
220
221 cxstring expr_next_token(CxList *tokens, size_t *pos) {
222 cxstring *token = cxListAt(tokens, *pos);
223 if(token) {
224 (*pos)++;
225 return *token;
226 }
227 return (cxstring){NULL, 0};
228 }
229
230 NSAPIExpression* expr_parser_pop(ExprParser *parser) {
231 CxList *stack = parser->ex_stack;
232 if(stack->size == 0) {
233 return NULL;
234 }
235 NSAPIExpression *ret = cxListAt(stack, stack->size-1);
236 cxListRemove(stack, stack->size-1);
237 return ret;
238 }
239
240 // takes items from ex_stack and adds a new operator expression to ex_stack
241 static int expr_add_operator(ExprParser *parser, ExprOpStackItem *op) {
242 NSAPIExpression *exp = pool_malloc(parser->pool, sizeof(NSAPIExpression));
243 exp->operator = op->operator;
244 // op->expect_value == TRUE means, that the operator was found in a case
245 // a value was expected.
246 // For example: 1 + - 2
247 // After + a value is expected, but there is the - operator
248 // in that case, the - operator is a unary expression
249 if(op->expect_value) {
250 // We expected a value but got an operator? This must be an unary operator
251 exp->type = NSAPI_EXPRESSION_UNARY;
252 exp->left = expr_parser_pop(parser);
253 exp->right = NULL;
254 } else {
255 // binary operator
256 exp->type = NSAPI_EXPRESSION_BINARY;
257 exp->right = expr_parser_pop(parser);
258 exp->left = expr_parser_pop(parser);
259 }
260
261 if(!exp->left && !exp->right) {
262 return 1; // error
263 }
264
265 cxListAdd(parser->ex_stack, exp);
266
267 parser->expect_value = TRUE;
268 return 0;
269 }
270
271 // converts the token to a value expression (int, bool, str, ...)
272 // and adds it to parser->ex_stack
273 // sets parser->expect_value to false
274 static int expr_add_value(ExprParser *parser, cxstring token) {
275 NSAPIExpression *exp = pool_malloc(parser->pool, sizeof(NSAPIExpression));
276 ZERO(exp, sizeof(NSAPIExpression));
277 if(expr_set_value(parser->pool, exp, token)) {
278 return 1;
279 }
280 cxListAdd(parser->ex_stack, exp);
281 parser->expect_value = FALSE;
282 return 0;
283 }
284
285
286 static NSAPIExpression* expr_parse_expr(ExprParser *parser) {
287 CxList *op_stack = parser->op_stack;
288 CxList *ex_stack = parser->ex_stack;
289
290 // Shunting yard algorithm
291 cxstring token = expr_next_token(parser->tokens, parser->pos);
292 for(;token.ptr;token=expr_next_token(parser->tokens, parser->pos)) {
293 NSAPIExpressionOperator op = expr_operator(token);
294 if(op != NSAPI_EXPRESSION_NOOP) {
295 ExprOpStackItem new_op;
296 new_op.operator = op;
297 new_op.expect_value = parser->expect_value;
298 new_op.open_parenthesis = FALSE;
299 while(op_stack->size > 0) {
300 ExprOpStackItem *stack_item = cxListAt(op_stack, op_stack->size-1);
301 if(stack_item->operator == NSAPI_EXPRESSION_NOOP) {
302 break;
303 }
304 // check presedence
305 if(op >= stack_item->operator) {
306 break;
307 }
308 if(expr_add_operator(parser, stack_item)) {
309 return NULL;
310 }
311 cxListRemove(op_stack, op_stack->size-1);
312 }
313 cxListAdd(op_stack, &new_op);
314 parser->expect_value = TRUE;
315 } else if(token.length == 1 && token.ptr[0] == '(') {
316 ExprOpStackItem new_op;
317 new_op.operator = NSAPI_EXPRESSION_NOOP;
318 new_op.expect_value = 0;
319 new_op.open_parenthesis = 1;
320 cxListAdd(op_stack, &new_op);
321 parser->expect_value = TRUE;
322 } else if(token.length == 1 && token.ptr[0] == ')') {
323 int found_open_bracket = FALSE;
324 while(op_stack->size > 0) {
325 ExprOpStackItem *stack_item = cxListAt(op_stack, op_stack->size-1);
326 cxListRemove(op_stack, op_stack->size-1);
327 if(stack_item->open_parenthesis) {
328 found_open_bracket = TRUE;
329 break;
330 } else {
331 if(expr_add_operator(parser, stack_item)) {
332 return NULL;
333 }
334 }
335 }
336 if(!found_open_bracket) {
337 return NULL;
338 }
339 parser->expect_value = FALSE;
340 } else {
341 if(expr_add_value(parser, token)) {
342 return NULL;
343 }
344 }
345 }
346
347 while(op_stack->size > 0) {
348 ExprOpStackItem *stack_item = cxListAt(op_stack, op_stack->size-1);
349 if(stack_item->open_parenthesis) {
350 return NULL;
351 }
352 if(expr_add_operator(parser, stack_item)) {
353 return NULL;
354 }
355 cxListRemove(op_stack, op_stack->size-1);
356 }
357
358 if(ex_stack->size != 1) {
359 return NULL;
360 }
361
362 return cxListAt(ex_stack, 0);
363 }
364
365 NSAPIExpression* expr_parse_logical_expr(pool_handle_t *pool, CxList *tokens, size_t *pos) {
366 CxList *op_stack = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(ExprOpStackItem));
367 CxList *ex_stack = cxPointerLinkedListCreate(pool_allocator(pool), cx_cmp_ptr);
368
369 ExprParser parser;
370 parser.pool = pool;
371 parser.op_stack = op_stack;
372 parser.ex_stack = ex_stack;
373 parser.tokens = tokens;
374 parser.pos = pos;
375 parser.expect_value = TRUE;
376
377 NSAPIExpression *ret = expr_parse_expr(&parser);
378 cxListDestroy(op_stack);
379 cxListDestroy(ex_stack);
380
381 return ret;
382 }
383
384
385
109 int condition_evaluate(Condition *condition, Session *sn, Request *rq) { 386 int condition_evaluate(Condition *condition, Session *sn, Request *rq) {
110 return 1; 387 return 1;
111 } 388 }

mercurial