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 } |