src/server/util/object.c

changeset 107
7e81699d1f77
parent 92
382bff43c6eb
child 261
f2c772336ecd
equal deleted inserted replaced
106:b122f34ddc80 107:7e81699d1f77
125 125
126 return cond; 126 return cond;
127 } 127 }
128 128
129 Expression* expression_from_str(pool_handle_t *pool, char *expr, size_t len) { 129 Expression* expression_from_str(pool_handle_t *pool, char *expr, size_t len) {
130 char str_qc = 0; // 0 or the quote char 130 return NULL;
131 char c_brace = 0;
132 int brace_count = 0;
133
134 Expression *expression = pool_malloc(pool, sizeof(Expression));
135 ZERO(expression, sizeof(Expression));
136
137 Expression *ex = expression;
138 /*
139 * 0: first operand
140 * 1: second operand
141 * 2: next expression
142 */
143 int optoken = 0;
144 int token_start = 0; // index of token begin
145 int i;
146 for(i=0;i<=len;i++) {
147 char c = i == len ? ' ' : expr[i];
148
149 if(brace_count > 0) {
150 if(c == c_brace) {
151 char *token = expr + token_start;
152 int token_len = i - token_start;
153 printf("Token {");
154 fwrite(token, token_len, 1, stdout);
155 printf("}\n");
156
157
158
159 // reset token_start
160 token_start = -1;
161 }
162 } else {
163 if((c == '(' || c == '[') && !str_qc) {
164 brace_count++;
165 if(brace_count == 1) {
166 if(c == '(') {
167 c_brace = ')';
168 } else {
169 c_brace = ']';
170 }
171 token_start = i+1;
172 }
173 } else if(c == str_qc) {
174 str_qc = 0;
175 } else if(c == '\'' || c == '\"') {
176 if(token_start != -1) {
177 // error
178 printf("error: token_start != -1");
179 return NULL;
180 }
181 token_start = i;
182 str_qc = c;
183 } else if(c < 33 && token_start != -1 && !str_qc) {
184 char *token = expr + token_start;
185 int token_len = i - token_start;
186 //printf("Token {");
187 //fwrite(token, token_len, 1, stdout);
188 //printf("}[%u]\n", token_len);
189
190 int token_type = expr_token_type(token, token_len);
191 switch(optoken) {
192 case 0: {
193 // first operand
194 if(token_type == 1) {
195 ex->optype[1] = EXPR_OP_NULL;
196 ex->opdata[1] = NULL;
197 ex->expr_operator = expr_operator(
198 token,
199 token_len);
200 break;
201 } else {
202 expr_set_op(pool, &ex->optype[0], &ex->opdata[0], token, token_len);
203 }
204 optoken++;
205 break;
206 }
207 case 1: {
208 // second operand
209 if(token_type == 1) {
210 Operator op = expr_operator(
211 token,
212 token_len);
213 if(op != OP_AND && op != OP_OR && op != OP_XOR) {
214 ex->expr_operator = op;
215 break;
216 } // else: jump to case 2
217 } else if(ex->expr_operator != 0) {
218 expr_set_op(pool, &ex->optype[1], &ex->opdata[1], token, token_len);
219 optoken++;
220 break;
221 } else {
222 // syntax error
223 fprintf(stderr, "expr: missing operator(1)\n");
224 return NULL;
225 }
226 }
227 case 2: {
228 // next
229 if(token_type == 1) {
230 ex->next_operator = expr_operator(
231 token,
232 token_len);
233 optoken = 0;
234 Expression *next_expr = pool_malloc(
235 pool,
236 sizeof(Expression));
237 ZERO(next_expr, sizeof(Expression));
238 ex->next = next_expr;
239 ex = next_expr;
240 break;
241 } else {
242 // syntax error
243 fprintf(stderr, "expr: missing operator(2)\n");
244 return NULL;
245 }
246 }
247 }
248
249 // reset token_start
250 token_start = -1;
251 } else if(c > 32 && token_start == -1) {
252 token_start = i;
253 }
254 }
255 }
256
257 return expression;
258 } 131 }
259 132
260 Operator expr_operator(char *token, size_t len) { 133 int condition_evaluate(Condition *condition, Session *sn, Request *rq) {
261 if(!strncmp(token, "not", len) || !strncmp(token, "!", len)) { 134 return 1;
262 return OP_NOT;
263 } else if(!strncmp(token, "and", len) || !strncmp(token, "&&", len)) {
264 return OP_AND;
265 } else if(!strncmp(token, "or", len) || !strncmp(token, "||", len)) {
266 return OP_OR;
267 } else if(!strncmp(token, "xor", len) || !strncmp(token, "^", len)) {
268 return OP_XOR;
269 } else if(!strncmp(token, "=", len)) {
270 return OP_WILDCARD;
271 } else if(!strncmp(token, "=~", len)) {
272 return OP_REGEX;
273 } else if(!strncmp(token, "!~", len)) {
274 return OP_NREGEX;
275 } else if(!strncmp(token, "+", len)) {
276 return OP_ADD;
277 } else if(!strncmp(token, "-", len)) {
278 return OP_SUB;
279 } else if(!strncmp(token, ".", len)) {
280 return OP_CAT;
281 } else if(!strncmp(token, "defined", len)) {
282 return OP_DEF;
283 } else if(!strncmp(token, "-d", len)) {
284 return OP_DEXISTS;
285 } else if(!strncmp(token, "-e", len)) {
286 return OP_FDEXISTS;
287 } else if(!strncmp(token, "-f", len)) {
288 return OP_FEXISTS;
289 } else if(!strncmp(token, "-l", len)) {
290 return OP_LEXISTS;
291 } else if(!strncmp(token, "-r", len)) {
292 return OP_READABLE;
293 } else if(!strncmp(token, "-s", len)) {
294 return OP_FSIZE;
295 } else if(!strncmp(token, "-U", len)) {
296 return OP_UMAP;
297 } else if(!strncmp(token, "<", len)) {
298 return OP_LESS;
299 } else if(!strncmp(token, "<=", len)) {
300 return OP_LESSEQ;
301 } else if(!strncmp(token, ">", len)) {
302 return OP_GREATER;
303 } else if(!strncmp(token, ">=", len)) {
304 return OP_GREATEREQ;
305 } else if(!strncmp(token, "lt", len)) {
306 return OP_STRLESS;
307 } else if(!strncmp(token, "le", len)) {
308 return OP_STRLESSEQ;
309 } else if(!strncmp(token, "gt", len)) {
310 return OP_GREATER;
311 } else if(!strncmp(token, "ge", len)) {
312 return OP_STRGREATEREQ;
313 } else if(!strncmp(token, "==", len)) {
314 return OP_EQUAL;
315 } else if(!strncmp(token, "!=", len)) {
316 return OP_NOTEQUAL;
317 } else if(!strncmp(token, "eq", len)) {
318 return OP_STREQUAL;
319 } else if(!strncmp(token, "ne", len)) {
320 return OP_STRNOTEQUAL;
321 }
322 return OP_NOOP;
323 } 135 }
324
325 int expr_token_type(char *token, size_t len) {
326 char c = token[0];
327 if(c == '$' || c == '"' || c == '\'') {
328 return 0;
329 } else {
330 if(expr_operator(token, len) == OP_NOOP) {
331 return 0;
332 } else {
333 return 1;
334 }
335 }
336 }
337
338 void expr_set_op(pool_handle_t *pool, OperandType *type, void **val, char *token, size_t len) {
339 char c = token[0];
340 if(c == '$') {
341 *type = EXPR_OP_VAR;
342 sstr_t s = sstrn(token+1, len-1);
343 s = sstrdup_pool(pool, s);
344 *val = s.ptr;
345 } else if(c == '"' || c == '\'') {
346 *type = EXPR_OP_STRING;
347 sstr_t s = sstrn(token+1, len-2);
348 //s = sstrdup_pool(pool, s);
349 *val = s.ptr;
350 }
351 }
352
353
354 int condition_evaluate(Condition *condition, Session *sn, Request *rq) {
355 return expression_evaluate(condition->expression, sn, rq);
356 }
357
358 int expression_evaluate(Expression *ex, Session *sn, Request *rq) {
359 int ret = 0;
360
361 int last_eval = 0;
362 Operator expr_lconn = OP_NOOP; // logical connective between 2 expressions
363 while(ex) {
364 int eval = 0;
365
366 if(!ex->opdata[1]) {
367 /*
368 * Only one operand. Can be:
369 * boolean with or without not operator
370 * defined operator
371 * file/directory/link exists operator
372 */
373 int not_op = 0;
374 switch(ex->expr_operator) {
375 case OP_NOT: {
376 not_op = 1;
377 }
378 case OP_NOOP: {
379 // must be boolean
380 // TODO
381 }
382 }
383
384 } else {
385 void *ops[2];
386 VarType types[2];
387 for(int i=0;i<2;i++) {
388 switch(ex->optype[i]) {
389 case EXPR_OP_STRING: {
390 ops[i] = ex->opdata[i];
391 types[i] = VAR_STRING;
392 break;
393 }
394 case EXPR_OP_VAR: {
395 if(!expr_get_var(ex->opdata[i], sn, rq, &ops[i], &types[i]));
396 break;
397 }
398 }
399 }
400
401 if(types[0] != types[1]) {
402 fprintf(stderr, "Condition: incompatible types\n");
403 return 0;
404 }
405
406 if(types[0] == VAR_STRING) {
407 switch(ex->expr_operator) {
408 case OP_WILDCARD: {
409 eval = !shexp_match(ops[0], ops[1]);
410 break;
411 }
412 case OP_STREQUAL: {
413 eval = !strcmp(ops[0], ops[1]);
414 break;
415 }
416 }
417 }
418 }
419
420
421 // evaluate logical connective between last 2 expressions
422 switch(expr_lconn) {
423 case OP_AND: {
424 if(!last_eval || !eval) {
425 return 0;
426 }
427 break;
428 }
429 case OP_OR: {
430 if(!last_eval && !eval) {
431 return 0;
432 }
433 }
434 case OP_XOR: {
435 if(last_eval == eval) {
436 return 0;
437 }
438 }
439 }
440
441 last_eval = eval;
442 // switch to next expression
443 if(ex->next) {
444 expr_lconn = ex->next_operator;
445 }
446 ex = ex->next;
447 }
448
449 return last_eval;
450 }
451
452 int expr_get_var(char *var, Session *sn, Request *rq, void **val, VarType *t) {
453 if(!strcmp(var, "path")) {
454 char *ppath = pblock_findval("ppath", rq->vars);
455 if(ppath) {
456 *t = VAR_STRING;
457 *val = ppath;
458 return 1;
459 }
460 } else if(!strcmp(var, "uri")) {
461 char *uri = pblock_findval("uri", rq->reqpb);
462 if(uri) {
463 *t = VAR_STRING;
464 *val = uri;
465 return 1;
466 }
467 }
468
469 *val = NULL;
470 *t = 0;
471 return 0;
472 }
473

mercurial