aboutsummaryrefslogtreecommitdiffstats
path: root/parse-filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse-filter.c')
-rw-r--r--parse-filter.c257
1 files changed, 187 insertions, 70 deletions
diff --git a/parse-filter.c b/parse-filter.c
index 0890589..973a702 100644
--- a/parse-filter.c
+++ b/parse-filter.c
@@ -298,10 +298,6 @@ static void free_events(struct event_list *events)
298} 298}
299 299
300static enum event_type 300static enum event_type
301process_filter(struct event_format *event, struct filter_arg **parg,
302 enum event_type type, char **tok, char **error_str);
303
304static enum event_type
305process_paren(struct event_format *event, struct filter_arg **parg, 301process_paren(struct event_format *event, struct filter_arg **parg,
306 char **tok, char **error_str); 302 char **tok, char **error_str);
307 303
@@ -310,22 +306,26 @@ process_not(struct event_format *event, struct filter_arg **parg,
310 char **tok, char **error_str); 306 char **tok, char **error_str);
311 307
312static enum event_type 308static enum event_type
309process_value_token(struct event_format *event, struct filter_arg **parg,
310 enum event_type type, char **tok, char **error_str);
311
312static enum event_type
313process_op_token(struct event_format *event, struct filter_arg *larg, 313process_op_token(struct event_format *event, struct filter_arg *larg,
314 struct filter_arg **parg, enum event_type type, char **tok, 314 struct filter_arg **parg, enum event_type type, char **tok,
315 char **error_str); 315 char **error_str);
316 316
317static enum event_type
318process_op(struct event_format *event, struct filter_arg *larg,
319 struct filter_arg **parg, char **tok, char **error_str);
320
321/* 317/*
318 * process_token
319 * Called when a new expression is found. Processes an op, or
320 * ends early if a ')' is found.
321 *
322 * Output: tok, parg 322 * Output: tok, parg
323 */ 323 */
324static enum event_type 324static enum event_type
325process_token(struct event_format *event, struct filter_arg **parg, 325process_token(struct event_format *event, struct filter_arg **parg,
326 char **tok, char **error_str, int cont) 326 char **tok, char **error_str)
327{ 327{
328 struct filter_arg *arg; 328 struct filter_arg *arg = NULL;
329 enum event_type type; 329 enum event_type type;
330 char *token; 330 char *token;
331 331
@@ -334,37 +334,109 @@ process_token(struct event_format *event, struct filter_arg **parg,
334 334
335 type = read_token(&token); 335 type = read_token(&token);
336 336
337 if (type == EVENT_ITEM) { 337 /*
338 type = process_filter(event, parg, type, &token, error_str); 338 * This is a start of a new expresion. We expect to find
339 * a item or a parenthesis.
340 */
341 switch (type) {
342 case EVENT_SQUOTE:
343 case EVENT_DQUOTE:
344 case EVENT_ITEM:
345 type = process_value_token(event, &arg, type, &token, error_str);
346 if (type == EVENT_ERROR) {
347 free_token(token);
348 return type;
349 }
350 type = read_token(&token);
351 break;
352 case EVENT_DELIM:
353 if (strcmp(token, "(") != 0)
354 break;
339 355
340 } else if (type == EVENT_DELIM && strcmp(token, "(") == 0) {
341 free_token(token); 356 free_token(token);
342 type = process_paren(event, parg, &token, error_str); 357 type = process_paren(event, &arg, &token, error_str);
358 if (type == EVENT_NONE) {
359 *tok = token;
360 *parg = arg;
361 return type;
362 }
363 if (arg) {
364 /*
365 * If the parenthesis was a full expression,
366 * then just return it. Otherwise, we may still
367 * need to find an op.
368 */
369 switch (arg->type) {
370 case FILTER_ARG_OP:
371 case FILTER_ARG_NUM:
372 case FILTER_ARG_STR:
373 *tok = token;
374 *parg = arg;
375 return type;
376 default:
377 break;
378 }
379 }
380 break;
343 381
344 } else if (type == EVENT_OP && strcmp(token, "!") == 0) { 382 case EVENT_OP:
345 type = process_not(event, parg, &token, error_str); 383 if (strcmp(token, "!") != 0)
346 } else { 384 break;
347 if (type == EVENT_NONE) 385
348 show_error(error_str, "unexpected end of filter"); 386 /*
349 else 387 * A not is its own filter, it just negates,
350 show_error(error_str, "unexpected token '%s'", token); 388 * process it by itself.
351 type = EVENT_ERROR; 389 */
390 *tok = token;
391 type = process_not(event, parg, tok, error_str);
392 return type;
393
394 default:
395 break;
352 } 396 }
353 397
354 *tok = token; 398 for (;;) {
355 while (cont && type != EVENT_ERROR) { 399 if (type == EVENT_NONE) {
356 if (type != EVENT_OP) 400 show_error(error_str, "unexpected end of filter");
357 break; 401 type = EVENT_ERROR;
358 /* continue */ 402
359 arg = *parg; 403 } else if (type == EVENT_DELIM && strcmp(token, ")") == 0) {
404 /* Parenthesis call this and may return at anytime. */
405 *tok = token;
406 *parg = arg;
407 return type;
408
409 } else if (type != EVENT_OP) {
410 show_error(error_str, "Expected an OP but found %s", token);
411 type = EVENT_ERROR;
412 }
413
414 if (type == EVENT_ERROR) {
415 free_token(token);
416 return type;
417 }
418
419 *tok = token;
360 *parg = NULL; 420 *parg = NULL;
361 type = process_op_token(event, arg, parg, type, tok, error_str); 421 type = process_op_token(event, arg, parg, type, tok, error_str);
362 }
363 422
364 if (type == EVENT_ERROR) { 423 if (type == EVENT_ERROR) {
365 free_arg(*parg); 424 free_arg(*parg);
366 *parg = NULL; 425 *parg = NULL;
367 return EVENT_ERROR; 426 return EVENT_ERROR;
427 }
428
429 if (!(*parg) || (*parg)->type != FILTER_ARG_EXP)
430 break;
431
432 /*
433 * This op was an expression (value return)
434 * It's not fine by itself, there had better be an OP
435 * after it.
436 */
437 token = *tok;
438 *tok = NULL;
439 arg = *parg;
368 } 440 }
369 441
370 return type; 442 return type;
@@ -387,7 +459,7 @@ process_bool(struct event_format *event, struct filter_arg *larg,
387 btype = strcmp(*tok, "&&") == 0 ? 459 btype = strcmp(*tok, "&&") == 0 ?
388 FILTER_OP_AND : FILTER_OP_OR; 460 FILTER_OP_AND : FILTER_OP_OR;
389 461
390 type = process_token(event, &rarg, tok, error_str, 0); 462 type = process_token(event, &rarg, tok, error_str);
391 if (type == EVENT_ERROR) { 463 if (type == EVENT_ERROR) {
392 free_arg(larg); 464 free_arg(larg);
393 *parg = NULL; 465 *parg = NULL;
@@ -396,7 +468,7 @@ process_bool(struct event_format *event, struct filter_arg *larg,
396 468
397 /* 469 /*
398 * If larg or rarg is null then if this is AND, the whole expression 470 * If larg or rarg is null then if this is AND, the whole expression
399 * becomes NULL, elso if this is an OR, then we use the non NULL 471 * becomes NULL, else if this is an OR, then we use the non NULL
400 * condition. 472 * condition.
401 */ 473 */
402 if (!larg || !rarg) { 474 if (!larg || !rarg) {
@@ -417,9 +489,18 @@ process_bool(struct event_format *event, struct filter_arg *larg,
417 arg->op.left = larg; 489 arg->op.left = larg;
418 arg->op.right = rarg; 490 arg->op.right = rarg;
419 491
420 *parg = arg;
421 492
422 return type; 493 /*
494 * If the next token is also a boolean expression, then
495 * make the next boolean the parent..
496 */
497 if (type != EVENT_OP ||
498 (strcmp(*tok, "&&") != 0 && strcmp(*tok, "||") != 0)) {
499 *parg = arg;
500 return type;
501 }
502
503 return process_bool(event, arg, parg, tok, error_str);
423} 504}
424 505
425/* 506/*
@@ -482,22 +563,50 @@ process_value_token(struct event_format *event, struct filter_arg **parg,
482} 563}
483 564
484/* 565/*
485 * Output: parg 566 * Output: parg, tok
486 */ 567 */
487static enum event_type 568static enum event_type
488process_value(struct event_format *event, struct filter_arg **parg, 569process_value(struct event_format *event, struct filter_arg **parg,
489 char **error_str) 570 enum event_type *orig_type, char **tok, char **error_str)
490{ 571{
491 enum event_type type; 572 enum event_type type;
492 char *token; 573 char *token;
493 574
575 *tok = NULL;
494 type = read_token(&token); 576 type = read_token(&token);
495 type = process_value_token(event, parg, type, &token, error_str); 577 *orig_type = type;
496 free_token(token); 578 if (type == EVENT_DELIM && strcmp(token, "(") == 0) {
579 type = process_paren(event, parg, &token, error_str);
580 /* Must be a expression or value */
581 if (type == EVENT_ERROR || !(*parg)) {
582 free_token(token);
583 return type;
584 }
585 switch ((*parg)->type) {
586 case FILTER_ARG_BOOLEAN:
587 case FILTER_ARG_VALUE:
588 case FILTER_ARG_FIELD:
589 case FILTER_ARG_EXP:
590 break;
591 default:
592 show_error(error_str, "expected a value");
593 free_token(token);
594 return EVENT_ERROR;
595 }
596 } else {
597 type = process_value_token(event, parg, type, &token, error_str);
598 free_token(token);
599 if (type == EVENT_ERROR)
600 return type;
601 type = read_token(&token);
602 }
603
604 *tok = token;
497 return type; 605 return type;
498} 606}
499 607
500/* 608/*
609 * Input: larg
501 * Output: parg, tok 610 * Output: parg, tok
502 */ 611 */
503static enum event_type 612static enum event_type
@@ -507,18 +616,21 @@ process_cmp(struct event_format *event, enum filter_cmp_type op_type,
507{ 616{
508 struct filter_arg *arg; 617 struct filter_arg *arg;
509 struct filter_arg *rarg; 618 struct filter_arg *rarg;
619 enum event_type orig_type;
510 enum event_type type; 620 enum event_type type;
511 int ret; 621 int ret;
512 622
513 *parg = NULL; 623 *parg = NULL;
514 624
515 type = process_value(event, &rarg, error_str); 625 type = process_value(event, &rarg, &orig_type, tok, error_str);
516 if (type == EVENT_ERROR) 626 if (type == EVENT_ERROR) {
627 free_arg(rarg);
517 return type; 628 return type;
629 }
518 630
519 arg = allocate_arg(); 631 arg = allocate_arg();
520 /* 632 /*
521 * If either arg is NULL if right was field not found. 633 * If either arg is NULL or right was field not found.
522 * Then make the entire expression NULL. (will turn to FALSE) 634 * Then make the entire expression NULL. (will turn to FALSE)
523 */ 635 */
524 if (!larg || !rarg) { 636 if (!larg || !rarg) {
@@ -529,7 +641,7 @@ process_cmp(struct event_format *event, enum filter_cmp_type op_type,
529 goto cont; 641 goto cont;
530 } 642 }
531 643
532 switch (type) { 644 switch (orig_type) {
533 case EVENT_SQUOTE: 645 case EVENT_SQUOTE:
534 /* treat this as a character if string is of length 1? */ 646 /* treat this as a character if string is of length 1? */
535 if (strlen(rarg->str.val) == 1) { 647 if (strlen(rarg->str.val) == 1) {
@@ -620,10 +732,11 @@ process_cmp(struct event_format *event, enum filter_cmp_type op_type,
620 } 732 }
621 cont: 733 cont:
622 *parg = arg; 734 *parg = arg;
623 return read_token(tok); 735 return type;
624} 736}
625 737
626/* 738/*
739 * Input: larg
627 * Output: parg, tok 740 * Output: parg, tok
628 */ 741 */
629static enum event_type 742static enum event_type
@@ -633,11 +746,14 @@ process_exp(struct event_format *event, enum filter_exp_type etype,
633{ 746{
634 struct filter_arg *rarg; 747 struct filter_arg *rarg;
635 struct filter_arg *arg; 748 struct filter_arg *arg;
749 enum event_type orig_type;
636 enum event_type type; 750 enum event_type type;
637 751
638 type = process_value(event, &rarg, error_str); 752 type = process_value(event, &rarg, &orig_type, tok, error_str);
639 if (type == EVENT_ERROR) 753 if (type == EVENT_ERROR) {
754 free_arg(rarg);
640 return type; 755 return type;
756 }
641 757
642 /* larg can be NULL if a field did not match */ 758 /* larg can be NULL if a field did not match */
643 if (!larg) { 759 if (!larg) {
@@ -655,7 +771,8 @@ process_exp(struct event_format *event, enum filter_exp_type etype,
655 771
656 cont: 772 cont:
657 /* still need a cmp */ 773 /* still need a cmp */
658 return process_op(event, arg, parg, tok, error_str); 774 type = process_op_token(event, arg, parg, type, tok, error_str);
775 return type;
659} 776}
660 777
661/* 778/*
@@ -742,31 +859,25 @@ process_op_token(struct event_format *event, struct filter_arg *larg,
742} 859}
743 860
744static enum event_type 861static enum event_type
745process_op(struct event_format *event, struct filter_arg *larg,
746 struct filter_arg **parg, char **tok, char **error_str)
747{
748 enum event_type type;
749
750 *tok = NULL;
751 type = read_token(tok);
752 type = process_op_token(event, larg, parg, type, tok, error_str);
753
754 return type;
755}
756
757static enum event_type
758process_filter(struct event_format *event, struct filter_arg **parg, 862process_filter(struct event_format *event, struct filter_arg **parg,
759 enum event_type type, char **tok, char **error_str) 863 char **tok, char **error_str)
760{ 864{
761 struct filter_arg *larg = NULL; 865 struct filter_arg *larg = NULL;
866 enum event_type type;
762 867
763 *parg = NULL; 868 *parg = NULL;
764
765 type = process_value_token(event, &larg, type, tok, error_str);
766 free_token(*tok);
767 *tok = NULL; 869 *tok = NULL;
768 870
769 return process_op(event, larg, parg, tok, error_str); 871 type = process_token(event, parg, tok, error_str);
872
873 if (type == EVENT_OP &&
874 (strcmp(*tok, "&&") == 0 || strcmp(*tok, "||") == 0)) {
875 larg = *parg;
876 *parg = NULL;
877 type = process_bool(event, larg, parg, tok, error_str);
878 }
879
880 return type;
770} 881}
771 882
772static enum event_type 883static enum event_type
@@ -778,11 +889,17 @@ process_paren(struct event_format *event, struct filter_arg **parg,
778 889
779 *parg = NULL; 890 *parg = NULL;
780 891
781 type = process_token(event, &arg, tok, error_str, 0); 892 type = process_token(event, &arg, tok, error_str);
782 if (type == EVENT_ERROR) { 893 if (type == EVENT_ERROR) {
783 free_arg(arg); 894 free_arg(arg);
784 return type; 895 return type;
785 } 896 }
897
898 if (type == EVENT_OP &&
899 (strcmp(*tok, "&&") == 0 || strcmp(*tok, "||") == 0)) {
900 type = process_bool(event, arg, parg, tok, error_str);
901 }
902
786 if (type != EVENT_DELIM || strcmp(*tok, ")") != 0) { 903 if (type != EVENT_DELIM || strcmp(*tok, ")") != 0) {
787 if (*tok) 904 if (*tok)
788 show_error(error_str, 905 show_error(error_str,
@@ -815,7 +932,7 @@ process_not(struct event_format *event, struct filter_arg **parg,
815 arg->op.type = FILTER_OP_NOT; 932 arg->op.type = FILTER_OP_NOT;
816 933
817 arg->op.left = NULL; 934 arg->op.left = NULL;
818 type = process_token(event, &arg->op.right, tok, error_str, 0); 935 type = process_token(event, &arg->op.right, tok, error_str);
819 if (type == EVENT_ERROR) { 936 if (type == EVENT_ERROR) {
820 free_arg(arg); 937 free_arg(arg);
821 *parg = NULL; 938 *parg = NULL;
@@ -844,7 +961,7 @@ process_event(struct event_format *event, const char *filter_str,
844 961
845 pevent_buffer_init(filter_str, strlen(filter_str)); 962 pevent_buffer_init(filter_str, strlen(filter_str));
846 963
847 type = process_token(event, parg, &token, error_str, 1); 964 type = process_filter(event, parg, &token, error_str);
848 965
849 if (type == EVENT_ERROR) 966 if (type == EVENT_ERROR)
850 return -1; 967 return -1;