1 // SPDX-License-Identifier: LGPL-2.1
3 * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
11 #include <sys/types.h>
13 #include "event-parse.h"
14 #include "event-parse-local.h"
15 #include "event-utils.h"
20 static struct tep_format_field comm
= {
24 static struct tep_format_field cpu
= {
29 struct event_list
*next
;
30 struct tep_event
*event
;
33 static void show_error(char *error_buf
, const char *fmt
, ...)
35 unsigned long long index
;
41 input
= get_input_buf();
42 index
= get_input_buf_ptr();
43 len
= input
? strlen(input
) : 0;
46 strcpy(error_buf
, input
);
47 error_buf
[len
] = '\n';
48 for (i
= 1; i
< len
&& i
< index
; i
++)
49 error_buf
[len
+i
] = ' ';
50 error_buf
[len
+ i
] = '^';
51 error_buf
[len
+ i
+ 1] = '\n';
56 vsnprintf(error_buf
+ len
, TEP_FILTER_ERROR_BUFSZ
- len
, fmt
, ap
);
60 static enum tep_event_type
filter_read_token(char **tok
)
62 enum tep_event_type type
;
67 type
= read_token(&token
);
68 } while (type
== TEP_EVENT_NEWLINE
|| type
== TEP_EVENT_SPACE
);
70 /* If token is = or ! check to see if the next char is ~ */
72 (strcmp(token
, "=") == 0 || strcmp(token
, "!") == 0) &&
78 return TEP_EVENT_ERROR
;
80 sprintf(*tok
, "%c%c", *token
, '~');
82 /* Now remove the '~' from the buffer */
91 static int filter_cmp(const void *a
, const void *b
)
93 const struct tep_filter_type
*ea
= a
;
94 const struct tep_filter_type
*eb
= b
;
96 if (ea
->event_id
< eb
->event_id
)
99 if (ea
->event_id
> eb
->event_id
)
105 static struct tep_filter_type
*
106 find_filter_type(struct tep_event_filter
*filter
, int id
)
108 struct tep_filter_type
*filter_type
;
109 struct tep_filter_type key
;
113 filter_type
= bsearch(&key
, filter
->event_filters
,
115 sizeof(*filter
->event_filters
),
121 static struct tep_filter_type
*
122 add_filter_type(struct tep_event_filter
*filter
, int id
)
124 struct tep_filter_type
*filter_type
;
127 filter_type
= find_filter_type(filter
, id
);
131 filter_type
= realloc(filter
->event_filters
,
132 sizeof(*filter
->event_filters
) *
133 (filter
->filters
+ 1));
137 filter
->event_filters
= filter_type
;
139 for (i
= 0; i
< filter
->filters
; i
++) {
140 if (filter
->event_filters
[i
].event_id
> id
)
144 if (i
< filter
->filters
)
145 memmove(&filter
->event_filters
[i
+1],
146 &filter
->event_filters
[i
],
147 sizeof(*filter
->event_filters
) *
148 (filter
->filters
- i
));
150 filter_type
= &filter
->event_filters
[i
];
151 filter_type
->event_id
= id
;
152 filter_type
->event
= tep_find_event(filter
->tep
, id
);
153 filter_type
->filter
= NULL
;
161 * tep_filter_alloc - create a new event filter
162 * @tep: The tep that this filter is associated with
164 struct tep_event_filter
*tep_filter_alloc(struct tep_handle
*tep
)
166 struct tep_event_filter
*filter
;
168 filter
= malloc(sizeof(*filter
));
172 memset(filter
, 0, sizeof(*filter
));
179 static struct tep_filter_arg
*allocate_arg(void)
181 return calloc(1, sizeof(struct tep_filter_arg
));
184 static void free_arg(struct tep_filter_arg
*arg
)
190 case TEP_FILTER_ARG_NONE
:
191 case TEP_FILTER_ARG_BOOLEAN
:
194 case TEP_FILTER_ARG_NUM
:
195 free_arg(arg
->num
.left
);
196 free_arg(arg
->num
.right
);
199 case TEP_FILTER_ARG_EXP
:
200 free_arg(arg
->exp
.left
);
201 free_arg(arg
->exp
.right
);
204 case TEP_FILTER_ARG_STR
:
206 regfree(&arg
->str
.reg
);
207 free(arg
->str
.buffer
);
210 case TEP_FILTER_ARG_VALUE
:
211 if (arg
->value
.type
== TEP_FILTER_STRING
||
212 arg
->value
.type
== TEP_FILTER_CHAR
)
213 free(arg
->value
.str
);
216 case TEP_FILTER_ARG_OP
:
217 free_arg(arg
->op
.left
);
218 free_arg(arg
->op
.right
);
226 static int add_event(struct event_list
**events
,
227 struct tep_event
*event
)
229 struct event_list
*list
;
231 list
= malloc(sizeof(*list
));
235 list
->next
= *events
;
241 static int event_match(struct tep_event
*event
,
242 regex_t
*sreg
, regex_t
*ereg
)
245 return !regexec(sreg
, event
->system
, 0, NULL
, 0) &&
246 !regexec(ereg
, event
->name
, 0, NULL
, 0);
249 return !regexec(ereg
, event
->system
, 0, NULL
, 0) ||
250 !regexec(ereg
, event
->name
, 0, NULL
, 0);
253 static enum tep_errno
254 find_event(struct tep_handle
*tep
, struct event_list
**events
,
255 char *sys_name
, char *event_name
)
257 struct tep_event
*event
;
267 /* if no name is given, then swap sys and name */
268 event_name
= sys_name
;
272 ret
= asprintf(®
, "^%s$", event_name
);
274 return TEP_ERRNO__MEM_ALLOC_FAILED
;
276 ret
= regcomp(&ereg
, reg
, REG_ICASE
|REG_NOSUB
);
280 return TEP_ERRNO__INVALID_EVENT_NAME
;
283 ret
= asprintf(®
, "^%s$", sys_name
);
286 return TEP_ERRNO__MEM_ALLOC_FAILED
;
289 ret
= regcomp(&sreg
, reg
, REG_ICASE
|REG_NOSUB
);
293 return TEP_ERRNO__INVALID_EVENT_NAME
;
297 for (i
= 0; i
< tep
->nr_events
; i
++) {
298 event
= tep
->events
[i
];
299 if (event_match(event
, sys_name
? &sreg
: NULL
, &ereg
)) {
301 if (add_event(events
, event
) < 0) {
313 return TEP_ERRNO__EVENT_NOT_FOUND
;
315 return TEP_ERRNO__MEM_ALLOC_FAILED
;
320 static void free_events(struct event_list
*events
)
322 struct event_list
*event
;
326 events
= events
->next
;
331 static enum tep_errno
332 create_arg_item(struct tep_event
*event
, const char *token
,
333 enum tep_event_type type
, struct tep_filter_arg
**parg
, char *error_str
)
335 struct tep_format_field
*field
;
336 struct tep_filter_arg
*arg
;
338 arg
= allocate_arg();
340 show_error(error_str
, "failed to allocate filter arg");
341 return TEP_ERRNO__MEM_ALLOC_FAILED
;
346 case TEP_EVENT_SQUOTE
:
347 case TEP_EVENT_DQUOTE
:
348 arg
->type
= TEP_FILTER_ARG_VALUE
;
350 type
== TEP_EVENT_DQUOTE
? TEP_FILTER_STRING
: TEP_FILTER_CHAR
;
351 arg
->value
.str
= strdup(token
);
352 if (!arg
->value
.str
) {
354 show_error(error_str
, "failed to allocate string filter arg");
355 return TEP_ERRNO__MEM_ALLOC_FAILED
;
359 /* if it is a number, then convert it */
360 if (isdigit(token
[0])) {
361 arg
->type
= TEP_FILTER_ARG_VALUE
;
362 arg
->value
.type
= TEP_FILTER_NUMBER
;
363 arg
->value
.val
= strtoull(token
, NULL
, 0);
366 /* Consider this a field */
367 field
= tep_find_any_field(event
, token
);
369 /* If token is 'COMM' or 'CPU' then it is special */
370 if (strcmp(token
, COMM
) == 0) {
372 } else if (strcmp(token
, CPU
) == 0) {
375 /* not a field, Make it false */
376 arg
->type
= TEP_FILTER_ARG_BOOLEAN
;
377 arg
->boolean
.value
= TEP_FILTER_FALSE
;
381 arg
->type
= TEP_FILTER_ARG_FIELD
;
382 arg
->field
.field
= field
;
386 show_error(error_str
, "expected a value but found %s", token
);
387 return TEP_ERRNO__UNEXPECTED_TYPE
;
393 static struct tep_filter_arg
*
394 create_arg_op(enum tep_filter_op_type btype
)
396 struct tep_filter_arg
*arg
;
398 arg
= allocate_arg();
402 arg
->type
= TEP_FILTER_ARG_OP
;
403 arg
->op
.type
= btype
;
408 static struct tep_filter_arg
*
409 create_arg_exp(enum tep_filter_exp_type etype
)
411 struct tep_filter_arg
*arg
;
413 arg
= allocate_arg();
417 arg
->type
= TEP_FILTER_ARG_EXP
;
418 arg
->exp
.type
= etype
;
423 static struct tep_filter_arg
*
424 create_arg_cmp(enum tep_filter_cmp_type ctype
)
426 struct tep_filter_arg
*arg
;
428 arg
= allocate_arg();
432 /* Use NUM and change if necessary */
433 arg
->type
= TEP_FILTER_ARG_NUM
;
434 arg
->num
.type
= ctype
;
439 static enum tep_errno
440 add_right(struct tep_filter_arg
*op
, struct tep_filter_arg
*arg
, char *error_str
)
442 struct tep_filter_arg
*left
;
448 case TEP_FILTER_ARG_EXP
:
454 case TEP_FILTER_ARG_OP
:
460 case TEP_FILTER_ARG_NUM
:
464 * The arg must be num, str, or field
467 case TEP_FILTER_ARG_VALUE
:
468 case TEP_FILTER_ARG_FIELD
:
471 show_error(error_str
, "Illegal rvalue");
472 return TEP_ERRNO__ILLEGAL_RVALUE
;
476 * Depending on the type, we may need to
477 * convert this to a string or regex.
479 switch (arg
->value
.type
) {
480 case TEP_FILTER_CHAR
:
482 * A char should be converted to number if
483 * the string is 1 byte, and the compare
486 if (strlen(arg
->value
.str
) == 1 &&
487 op
->num
.type
!= TEP_FILTER_CMP_REGEX
&&
488 op
->num
.type
!= TEP_FILTER_CMP_NOT_REGEX
) {
489 arg
->value
.type
= TEP_FILTER_NUMBER
;
493 case TEP_FILTER_STRING
:
495 /* convert op to a string arg */
496 op_type
= op
->num
.type
;
498 str
= arg
->value
.str
;
500 /* reset the op for the new field */
501 memset(op
, 0, sizeof(*op
));
504 * If left arg was a field not found then
505 * NULL the entire op.
507 if (left
->type
== TEP_FILTER_ARG_BOOLEAN
) {
510 op
->type
= TEP_FILTER_ARG_BOOLEAN
;
511 op
->boolean
.value
= TEP_FILTER_FALSE
;
515 /* Left arg must be a field */
516 if (left
->type
!= TEP_FILTER_ARG_FIELD
) {
517 show_error(error_str
,
518 "Illegal lvalue for string comparison");
519 return TEP_ERRNO__ILLEGAL_LVALUE
;
522 /* Make sure this is a valid string compare */
524 case TEP_FILTER_CMP_EQ
:
525 op_type
= TEP_FILTER_CMP_MATCH
;
527 case TEP_FILTER_CMP_NE
:
528 op_type
= TEP_FILTER_CMP_NOT_MATCH
;
531 case TEP_FILTER_CMP_REGEX
:
532 case TEP_FILTER_CMP_NOT_REGEX
:
533 ret
= regcomp(&op
->str
.reg
, str
, REG_ICASE
|REG_NOSUB
);
535 show_error(error_str
,
536 "RegEx '%s' did not compute",
538 return TEP_ERRNO__INVALID_REGEX
;
542 show_error(error_str
,
543 "Illegal comparison for string");
544 return TEP_ERRNO__ILLEGAL_STRING_CMP
;
547 op
->type
= TEP_FILTER_ARG_STR
;
548 op
->str
.type
= op_type
;
549 op
->str
.field
= left
->field
.field
;
550 op
->str
.val
= strdup(str
);
552 show_error(error_str
, "Failed to allocate string filter");
553 return TEP_ERRNO__MEM_ALLOC_FAILED
;
556 * Need a buffer to copy data for tests
558 op
->str
.buffer
= malloc(op
->str
.field
->size
+ 1);
559 if (!op
->str
.buffer
) {
560 show_error(error_str
, "Failed to allocate string filter");
561 return TEP_ERRNO__MEM_ALLOC_FAILED
;
563 /* Null terminate this buffer */
564 op
->str
.buffer
[op
->str
.field
->size
] = 0;
566 /* We no longer have left or right args */
572 case TEP_FILTER_NUMBER
:
575 switch (op
->num
.type
) {
576 case TEP_FILTER_CMP_REGEX
:
577 case TEP_FILTER_CMP_NOT_REGEX
:
578 show_error(error_str
,
579 "Op not allowed with integers");
580 return TEP_ERRNO__ILLEGAL_INTEGER_CMP
;
586 /* numeric compare */
600 show_error(error_str
, "Syntax error");
601 return TEP_ERRNO__SYNTAX_ERROR
;
604 static struct tep_filter_arg
*
605 rotate_op_right(struct tep_filter_arg
*a
, struct tep_filter_arg
*b
)
607 struct tep_filter_arg
*arg
;
614 static enum tep_errno
add_left(struct tep_filter_arg
*op
, struct tep_filter_arg
*arg
)
617 case TEP_FILTER_ARG_EXP
:
618 if (arg
->type
== TEP_FILTER_ARG_OP
)
619 arg
= rotate_op_right(arg
, op
);
623 case TEP_FILTER_ARG_OP
:
626 case TEP_FILTER_ARG_NUM
:
627 if (arg
->type
== TEP_FILTER_ARG_OP
)
628 arg
= rotate_op_right(arg
, op
);
630 /* left arg of compares must be a field */
631 if (arg
->type
!= TEP_FILTER_ARG_FIELD
&&
632 arg
->type
!= TEP_FILTER_ARG_BOOLEAN
)
633 return TEP_ERRNO__INVALID_ARG_TYPE
;
637 return TEP_ERRNO__INVALID_ARG_TYPE
;
650 static enum op_type
process_op(const char *token
,
651 enum tep_filter_op_type
*btype
,
652 enum tep_filter_cmp_type
*ctype
,
653 enum tep_filter_exp_type
*etype
)
655 *btype
= TEP_FILTER_OP_NOT
;
656 *etype
= TEP_FILTER_EXP_NONE
;
657 *ctype
= TEP_FILTER_CMP_NONE
;
659 if (strcmp(token
, "&&") == 0)
660 *btype
= TEP_FILTER_OP_AND
;
661 else if (strcmp(token
, "||") == 0)
662 *btype
= TEP_FILTER_OP_OR
;
663 else if (strcmp(token
, "!") == 0)
666 if (*btype
!= TEP_FILTER_OP_NOT
)
669 /* Check for value expressions */
670 if (strcmp(token
, "+") == 0) {
671 *etype
= TEP_FILTER_EXP_ADD
;
672 } else if (strcmp(token
, "-") == 0) {
673 *etype
= TEP_FILTER_EXP_SUB
;
674 } else if (strcmp(token
, "*") == 0) {
675 *etype
= TEP_FILTER_EXP_MUL
;
676 } else if (strcmp(token
, "/") == 0) {
677 *etype
= TEP_FILTER_EXP_DIV
;
678 } else if (strcmp(token
, "%") == 0) {
679 *etype
= TEP_FILTER_EXP_MOD
;
680 } else if (strcmp(token
, ">>") == 0) {
681 *etype
= TEP_FILTER_EXP_RSHIFT
;
682 } else if (strcmp(token
, "<<") == 0) {
683 *etype
= TEP_FILTER_EXP_LSHIFT
;
684 } else if (strcmp(token
, "&") == 0) {
685 *etype
= TEP_FILTER_EXP_AND
;
686 } else if (strcmp(token
, "|") == 0) {
687 *etype
= TEP_FILTER_EXP_OR
;
688 } else if (strcmp(token
, "^") == 0) {
689 *etype
= TEP_FILTER_EXP_XOR
;
690 } else if (strcmp(token
, "~") == 0)
691 *etype
= TEP_FILTER_EXP_NOT
;
693 if (*etype
!= TEP_FILTER_EXP_NONE
)
696 /* Check for compares */
697 if (strcmp(token
, "==") == 0)
698 *ctype
= TEP_FILTER_CMP_EQ
;
699 else if (strcmp(token
, "!=") == 0)
700 *ctype
= TEP_FILTER_CMP_NE
;
701 else if (strcmp(token
, "<") == 0)
702 *ctype
= TEP_FILTER_CMP_LT
;
703 else if (strcmp(token
, ">") == 0)
704 *ctype
= TEP_FILTER_CMP_GT
;
705 else if (strcmp(token
, "<=") == 0)
706 *ctype
= TEP_FILTER_CMP_LE
;
707 else if (strcmp(token
, ">=") == 0)
708 *ctype
= TEP_FILTER_CMP_GE
;
709 else if (strcmp(token
, "=~") == 0)
710 *ctype
= TEP_FILTER_CMP_REGEX
;
711 else if (strcmp(token
, "!~") == 0)
712 *ctype
= TEP_FILTER_CMP_NOT_REGEX
;
719 static int check_op_done(struct tep_filter_arg
*arg
)
722 case TEP_FILTER_ARG_EXP
:
723 return arg
->exp
.right
!= NULL
;
725 case TEP_FILTER_ARG_OP
:
726 return arg
->op
.right
!= NULL
;
728 case TEP_FILTER_ARG_NUM
:
729 return arg
->num
.right
!= NULL
;
731 case TEP_FILTER_ARG_STR
:
732 /* A string conversion is always done */
735 case TEP_FILTER_ARG_BOOLEAN
:
736 /* field not found, is ok */
750 static enum tep_errno
751 reparent_op_arg(struct tep_filter_arg
*parent
, struct tep_filter_arg
*old_child
,
752 struct tep_filter_arg
*arg
, char *error_str
)
754 struct tep_filter_arg
*other_child
;
755 struct tep_filter_arg
**ptr
;
757 if (parent
->type
!= TEP_FILTER_ARG_OP
&&
758 arg
->type
!= TEP_FILTER_ARG_OP
) {
759 show_error(error_str
, "can not reparent other than OP");
760 return TEP_ERRNO__REPARENT_NOT_OP
;
763 /* Get the sibling */
764 if (old_child
->op
.right
== arg
) {
765 ptr
= &old_child
->op
.right
;
766 other_child
= old_child
->op
.left
;
767 } else if (old_child
->op
.left
== arg
) {
768 ptr
= &old_child
->op
.left
;
769 other_child
= old_child
->op
.right
;
771 show_error(error_str
, "Error in reparent op, find other child");
772 return TEP_ERRNO__REPARENT_FAILED
;
775 /* Detach arg from old_child */
779 if (parent
== old_child
) {
780 free_arg(other_child
);
782 /* Free arg without recussion */
787 if (parent
->op
.right
== old_child
)
788 ptr
= &parent
->op
.right
;
789 else if (parent
->op
.left
== old_child
)
790 ptr
= &parent
->op
.left
;
792 show_error(error_str
, "Error in reparent op");
793 return TEP_ERRNO__REPARENT_FAILED
;
802 /* Returns either filter_vals (success) or tep_errno (failfure) */
803 static int test_arg(struct tep_filter_arg
*parent
, struct tep_filter_arg
*arg
,
811 case TEP_FILTER_ARG_BOOLEAN
:
812 return FILTER_VAL_FALSE
+ arg
->boolean
.value
;
815 case TEP_FILTER_ARG_STR
:
816 case TEP_FILTER_ARG_VALUE
:
817 case TEP_FILTER_ARG_FIELD
:
818 return FILTER_VAL_NORM
;
820 case TEP_FILTER_ARG_EXP
:
821 lval
= test_arg(arg
, arg
->exp
.left
, error_str
);
822 if (lval
!= FILTER_VAL_NORM
)
824 rval
= test_arg(arg
, arg
->exp
.right
, error_str
);
825 if (rval
!= FILTER_VAL_NORM
)
827 return FILTER_VAL_NORM
;
829 case TEP_FILTER_ARG_NUM
:
830 lval
= test_arg(arg
, arg
->num
.left
, error_str
);
831 if (lval
!= FILTER_VAL_NORM
)
833 rval
= test_arg(arg
, arg
->num
.right
, error_str
);
834 if (rval
!= FILTER_VAL_NORM
)
836 return FILTER_VAL_NORM
;
838 case TEP_FILTER_ARG_OP
:
839 if (arg
->op
.type
!= TEP_FILTER_OP_NOT
) {
840 lval
= test_arg(arg
, arg
->op
.left
, error_str
);
842 case FILTER_VAL_NORM
:
844 case FILTER_VAL_TRUE
:
845 if (arg
->op
.type
== TEP_FILTER_OP_OR
)
846 return FILTER_VAL_TRUE
;
847 rval
= test_arg(arg
, arg
->op
.right
, error_str
);
848 if (rval
!= FILTER_VAL_NORM
)
851 return reparent_op_arg(parent
, arg
, arg
->op
.right
,
854 case FILTER_VAL_FALSE
:
855 if (arg
->op
.type
== TEP_FILTER_OP_AND
)
856 return FILTER_VAL_FALSE
;
857 rval
= test_arg(arg
, arg
->op
.right
, error_str
);
858 if (rval
!= FILTER_VAL_NORM
)
861 return reparent_op_arg(parent
, arg
, arg
->op
.right
,
869 rval
= test_arg(arg
, arg
->op
.right
, error_str
);
871 case FILTER_VAL_NORM
:
875 case FILTER_VAL_TRUE
:
876 if (arg
->op
.type
== TEP_FILTER_OP_OR
)
877 return FILTER_VAL_TRUE
;
878 if (arg
->op
.type
== TEP_FILTER_OP_NOT
)
879 return FILTER_VAL_FALSE
;
881 return reparent_op_arg(parent
, arg
, arg
->op
.left
,
884 case FILTER_VAL_FALSE
:
885 if (arg
->op
.type
== TEP_FILTER_OP_AND
)
886 return FILTER_VAL_FALSE
;
887 if (arg
->op
.type
== TEP_FILTER_OP_NOT
)
888 return FILTER_VAL_TRUE
;
890 return reparent_op_arg(parent
, arg
, arg
->op
.left
,
896 show_error(error_str
, "bad arg in filter tree");
897 return TEP_ERRNO__BAD_FILTER_ARG
;
899 return FILTER_VAL_NORM
;
902 /* Remove any unknown event fields */
903 static int collapse_tree(struct tep_filter_arg
*arg
,
904 struct tep_filter_arg
**arg_collapsed
, char *error_str
)
908 ret
= test_arg(arg
, arg
, error_str
);
910 case FILTER_VAL_NORM
:
913 case FILTER_VAL_TRUE
:
914 case FILTER_VAL_FALSE
:
916 arg
= allocate_arg();
918 arg
->type
= TEP_FILTER_ARG_BOOLEAN
;
919 arg
->boolean
.value
= ret
== FILTER_VAL_TRUE
;
921 show_error(error_str
, "Failed to allocate filter arg");
922 ret
= TEP_ERRNO__MEM_ALLOC_FAILED
;
927 /* test_arg() already set the error_str */
933 *arg_collapsed
= arg
;
937 static enum tep_errno
938 process_filter(struct tep_event
*event
, struct tep_filter_arg
**parg
,
939 char *error_str
, int not)
941 enum tep_event_type type
;
943 struct tep_filter_arg
*current_op
= NULL
;
944 struct tep_filter_arg
*current_exp
= NULL
;
945 struct tep_filter_arg
*left_item
= NULL
;
946 struct tep_filter_arg
*arg
= NULL
;
947 enum op_type op_type
;
948 enum tep_filter_op_type btype
;
949 enum tep_filter_exp_type etype
;
950 enum tep_filter_cmp_type ctype
;
957 type
= filter_read_token(&token
);
959 case TEP_EVENT_SQUOTE
:
960 case TEP_EVENT_DQUOTE
:
962 ret
= create_arg_item(event
, token
, type
, &arg
, error_str
);
967 else if (current_exp
) {
968 ret
= add_right(current_exp
, arg
, error_str
);
972 /* Not's only one one expression */
986 case TEP_EVENT_DELIM
:
988 show_error(error_str
, "Illegal token ','");
989 ret
= TEP_ERRNO__ILLEGAL_TOKEN
;
995 show_error(error_str
,
996 "Open paren can not come after item");
997 ret
= TEP_ERRNO__INVALID_PAREN
;
1001 show_error(error_str
,
1002 "Open paren can not come after expression");
1003 ret
= TEP_ERRNO__INVALID_PAREN
;
1007 ret
= process_filter(event
, &arg
, error_str
, 0);
1008 if (ret
!= TEP_ERRNO__UNBALANCED_PAREN
) {
1010 show_error(error_str
,
1011 "Unbalanced number of '('");
1012 ret
= TEP_ERRNO__UNBALANCED_PAREN
;
1018 /* A not wants just one expression */
1027 ret
= add_right(current_op
, arg
, error_str
);
1035 if (!current_op
&& !current_exp
)
1038 /* Make sure everything is finished at this level */
1039 if (current_exp
&& !check_op_done(current_exp
))
1041 if (current_op
&& !check_op_done(current_op
))
1047 *parg
= current_exp
;
1049 return TEP_ERRNO__UNBALANCED_PAREN
;
1054 op_type
= process_op(token
, &btype
, &ctype
, &etype
);
1056 /* All expect a left arg except for NOT */
1059 /* Logic ops need a left expression */
1060 if (!current_exp
&& !current_op
)
1064 /* logic only processes ops and exp */
1074 show_error(error_str
,
1075 "Unknown op token %s", token
);
1076 ret
= TEP_ERRNO__UNKNOWN_TOKEN
;
1083 arg
= create_arg_op(btype
);
1087 ret
= add_left(arg
, current_op
);
1089 ret
= add_left(arg
, current_exp
);
1095 arg
= create_arg_op(btype
);
1099 ret
= add_right(current_op
, arg
, error_str
);
1103 ret
= process_filter(event
, &arg
, error_str
, 1);
1106 ret
= add_right(current_exp
, arg
, error_str
);
1113 if (op_type
== OP_EXP
)
1114 arg
= create_arg_exp(etype
);
1116 arg
= create_arg_cmp(ctype
);
1121 ret
= add_right(current_op
, arg
, error_str
);
1124 ret
= add_left(arg
, left_item
);
1138 case TEP_EVENT_NONE
:
1140 case TEP_EVENT_ERROR
:
1145 } while (type
!= TEP_EVENT_NONE
);
1147 if (!current_op
&& !current_exp
)
1151 current_op
= current_exp
;
1153 ret
= collapse_tree(current_op
, parg
, error_str
);
1154 /* collapse_tree() may free current_op, and updates parg accordingly */
1163 show_error(error_str
, "failed to allocate filter arg");
1164 ret
= TEP_ERRNO__MEM_ALLOC_FAILED
;
1167 show_error(error_str
, "Syntax error");
1168 ret
= TEP_ERRNO__SYNTAX_ERROR
;
1170 free_arg(current_op
);
1171 free_arg(current_exp
);
1177 static enum tep_errno
1178 process_event(struct tep_event
*event
, const char *filter_str
,
1179 struct tep_filter_arg
**parg
, char *error_str
)
1183 init_input_buf(filter_str
, strlen(filter_str
));
1185 ret
= process_filter(event
, parg
, error_str
, 0);
1189 /* If parg is NULL, then make it into FALSE */
1191 *parg
= allocate_arg();
1193 return TEP_ERRNO__MEM_ALLOC_FAILED
;
1195 (*parg
)->type
= TEP_FILTER_ARG_BOOLEAN
;
1196 (*parg
)->boolean
.value
= TEP_FILTER_FALSE
;
1202 static enum tep_errno
1203 filter_event(struct tep_event_filter
*filter
, struct tep_event
*event
,
1204 const char *filter_str
, char *error_str
)
1206 struct tep_filter_type
*filter_type
;
1207 struct tep_filter_arg
*arg
;
1211 ret
= process_event(event
, filter_str
, &arg
, error_str
);
1216 /* just add a TRUE arg */
1217 arg
= allocate_arg();
1219 return TEP_ERRNO__MEM_ALLOC_FAILED
;
1221 arg
->type
= TEP_FILTER_ARG_BOOLEAN
;
1222 arg
->boolean
.value
= TEP_FILTER_TRUE
;
1225 filter_type
= add_filter_type(filter
, event
->id
);
1226 if (filter_type
== NULL
) {
1228 return TEP_ERRNO__MEM_ALLOC_FAILED
;
1231 if (filter_type
->filter
)
1232 free_arg(filter_type
->filter
);
1233 filter_type
->filter
= arg
;
1238 static void filter_init_error_buf(struct tep_event_filter
*filter
)
1240 /* clear buffer to reset show error */
1241 init_input_buf("", 0);
1242 filter
->error_buffer
[0] = '\0';
1246 * tep_filter_add_filter_str - add a new filter
1247 * @filter: the event filter to add to
1248 * @filter_str: the filter string that contains the filter
1250 * Returns 0 if the filter was successfully added or a
1251 * negative error code. Use tep_filter_strerror() to see
1252 * actual error message in case of error.
1254 enum tep_errno
tep_filter_add_filter_str(struct tep_event_filter
*filter
,
1255 const char *filter_str
)
1257 struct tep_handle
*tep
= filter
->tep
;
1258 struct event_list
*event
;
1259 struct event_list
*events
= NULL
;
1260 const char *filter_start
;
1261 const char *next_event
;
1263 char *event_name
= NULL
;
1264 char *sys_name
= NULL
;
1266 enum tep_errno rtn
= 0; /* TEP_ERRNO__SUCCESS */
1270 filter_init_error_buf(filter
);
1272 filter_start
= strchr(filter_str
, ':');
1274 len
= filter_start
- filter_str
;
1276 len
= strlen(filter_str
);
1279 next_event
= strchr(filter_str
, ',');
1281 (!filter_start
|| next_event
< filter_start
))
1282 len
= next_event
- filter_str
;
1283 else if (filter_start
)
1284 len
= filter_start
- filter_str
;
1286 len
= strlen(filter_str
);
1288 this_event
= malloc(len
+ 1);
1289 if (this_event
== NULL
) {
1290 /* This can only happen when events is NULL, but still */
1291 free_events(events
);
1292 return TEP_ERRNO__MEM_ALLOC_FAILED
;
1294 memcpy(this_event
, filter_str
, len
);
1295 this_event
[len
] = 0;
1300 filter_str
= next_event
;
1302 sys_name
= strtok_r(this_event
, "/", &sp
);
1303 event_name
= strtok_r(NULL
, "/", &sp
);
1306 /* This can only happen when events is NULL, but still */
1307 free_events(events
);
1309 return TEP_ERRNO__FILTER_NOT_FOUND
;
1312 /* Find this event */
1313 ret
= find_event(tep
, &events
, strim(sys_name
), strim(event_name
));
1315 free_events(events
);
1320 } while (filter_str
);
1326 /* filter starts here */
1327 for (event
= events
; event
; event
= event
->next
) {
1328 ret
= filter_event(filter
, event
->event
, filter_start
,
1329 filter
->error_buffer
);
1330 /* Failures are returned if a parse error happened */
1334 if (ret
>= 0 && tep
->test_filters
) {
1336 test
= tep_filter_make_string(filter
, event
->event
->id
);
1338 printf(" '%s: %s'\n", event
->event
->name
, test
);
1344 free_events(events
);
1349 static void free_filter_type(struct tep_filter_type
*filter_type
)
1351 free_arg(filter_type
->filter
);
1355 * tep_filter_strerror - fill error message in a buffer
1356 * @filter: the event filter contains error
1357 * @err: the error code
1358 * @buf: the buffer to be filled in
1359 * @buflen: the size of the buffer
1361 * Returns 0 if message was filled successfully, -1 if error
1363 int tep_filter_strerror(struct tep_event_filter
*filter
, enum tep_errno err
,
1364 char *buf
, size_t buflen
)
1366 if (err
<= __TEP_ERRNO__START
|| err
>= __TEP_ERRNO__END
)
1369 if (strlen(filter
->error_buffer
) > 0) {
1370 size_t len
= snprintf(buf
, buflen
, "%s", filter
->error_buffer
);
1377 return tep_strerror(filter
->tep
, err
, buf
, buflen
);
1381 * tep_filter_remove_event - remove a filter for an event
1382 * @filter: the event filter to remove from
1383 * @event_id: the event to remove a filter for
1385 * Removes the filter saved for an event defined by @event_id
1388 * Returns 1: if an event was removed
1389 * 0: if the event was not found
1391 int tep_filter_remove_event(struct tep_event_filter
*filter
,
1394 struct tep_filter_type
*filter_type
;
1397 if (!filter
->filters
)
1400 filter_type
= find_filter_type(filter
, event_id
);
1405 free_filter_type(filter_type
);
1407 /* The filter_type points into the event_filters array */
1408 len
= (unsigned long)(filter
->event_filters
+ filter
->filters
) -
1409 (unsigned long)(filter_type
+ 1);
1411 memmove(filter_type
, filter_type
+ 1, len
);
1414 memset(&filter
->event_filters
[filter
->filters
], 0,
1415 sizeof(*filter_type
));
1421 * tep_filter_reset - clear all filters in a filter
1422 * @filter: the event filter to reset
1424 * Removes all filters from a filter and resets it.
1426 void tep_filter_reset(struct tep_event_filter
*filter
)
1430 for (i
= 0; i
< filter
->filters
; i
++)
1431 free_filter_type(&filter
->event_filters
[i
]);
1433 free(filter
->event_filters
);
1434 filter
->filters
= 0;
1435 filter
->event_filters
= NULL
;
1438 void tep_filter_free(struct tep_event_filter
*filter
)
1440 tep_unref(filter
->tep
);
1442 tep_filter_reset(filter
);
1447 static char *arg_to_str(struct tep_event_filter
*filter
, struct tep_filter_arg
*arg
);
1449 static int copy_filter_type(struct tep_event_filter
*filter
,
1450 struct tep_event_filter
*source
,
1451 struct tep_filter_type
*filter_type
)
1453 struct tep_filter_arg
*arg
;
1454 struct tep_event
*event
;
1459 /* Can't assume that the tep's are the same */
1460 sys
= filter_type
->event
->system
;
1461 name
= filter_type
->event
->name
;
1462 event
= tep_find_event_by_name(filter
->tep
, sys
, name
);
1466 str
= arg_to_str(source
, filter_type
->filter
);
1470 if (strcmp(str
, "TRUE") == 0 || strcmp(str
, "FALSE") == 0) {
1471 /* Add trivial event */
1472 arg
= allocate_arg();
1478 arg
->type
= TEP_FILTER_ARG_BOOLEAN
;
1479 if (strcmp(str
, "TRUE") == 0)
1480 arg
->boolean
.value
= 1;
1482 arg
->boolean
.value
= 0;
1484 filter_type
= add_filter_type(filter
, event
->id
);
1485 if (filter_type
== NULL
) {
1491 filter_type
->filter
= arg
;
1497 filter_event(filter
, event
, str
, NULL
);
1504 * tep_filter_copy - copy a filter using another filter
1505 * @dest - the filter to copy to
1506 * @source - the filter to copy from
1508 * Returns 0 on success and -1 if not all filters were copied
1510 int tep_filter_copy(struct tep_event_filter
*dest
, struct tep_event_filter
*source
)
1515 tep_filter_reset(dest
);
1517 for (i
= 0; i
< source
->filters
; i
++) {
1518 if (copy_filter_type(dest
, source
, &source
->event_filters
[i
]))
1524 static int test_filter(struct tep_event
*event
, struct tep_filter_arg
*arg
,
1525 struct tep_record
*record
, enum tep_errno
*err
);
1528 get_comm(struct tep_event
*event
, struct tep_record
*record
)
1533 pid
= tep_data_pid(event
->tep
, record
);
1534 comm
= tep_data_comm_from_pid(event
->tep
, pid
);
1538 static unsigned long long
1539 get_value(struct tep_event
*event
,
1540 struct tep_format_field
*field
, struct tep_record
*record
)
1542 unsigned long long val
;
1544 /* Handle our dummy "comm" field */
1545 if (field
== &comm
) {
1548 name
= get_comm(event
, record
);
1549 return (unsigned long)name
;
1552 /* Handle our dummy "cpu" field */
1556 tep_read_number_field(field
, record
->data
, &val
);
1558 if (!(field
->flags
& TEP_FIELD_IS_SIGNED
))
1561 switch (field
->size
) {
1569 return (long long)val
;
1574 static unsigned long long
1575 get_arg_value(struct tep_event
*event
, struct tep_filter_arg
*arg
,
1576 struct tep_record
*record
, enum tep_errno
*err
);
1578 static unsigned long long
1579 get_exp_value(struct tep_event
*event
, struct tep_filter_arg
*arg
,
1580 struct tep_record
*record
, enum tep_errno
*err
)
1582 unsigned long long lval
, rval
;
1584 lval
= get_arg_value(event
, arg
->exp
.left
, record
, err
);
1585 rval
= get_arg_value(event
, arg
->exp
.right
, record
, err
);
1589 * There was an error, no need to process anymore.
1594 switch (arg
->exp
.type
) {
1595 case TEP_FILTER_EXP_ADD
:
1598 case TEP_FILTER_EXP_SUB
:
1601 case TEP_FILTER_EXP_MUL
:
1604 case TEP_FILTER_EXP_DIV
:
1607 case TEP_FILTER_EXP_MOD
:
1610 case TEP_FILTER_EXP_RSHIFT
:
1611 return lval
>> rval
;
1613 case TEP_FILTER_EXP_LSHIFT
:
1614 return lval
<< rval
;
1616 case TEP_FILTER_EXP_AND
:
1619 case TEP_FILTER_EXP_OR
:
1622 case TEP_FILTER_EXP_XOR
:
1625 case TEP_FILTER_EXP_NOT
:
1628 *err
= TEP_ERRNO__INVALID_EXP_TYPE
;
1633 static unsigned long long
1634 get_arg_value(struct tep_event
*event
, struct tep_filter_arg
*arg
,
1635 struct tep_record
*record
, enum tep_errno
*err
)
1637 switch (arg
->type
) {
1638 case TEP_FILTER_ARG_FIELD
:
1639 return get_value(event
, arg
->field
.field
, record
);
1641 case TEP_FILTER_ARG_VALUE
:
1642 if (arg
->value
.type
!= TEP_FILTER_NUMBER
) {
1644 *err
= TEP_ERRNO__NOT_A_NUMBER
;
1646 return arg
->value
.val
;
1648 case TEP_FILTER_ARG_EXP
:
1649 return get_exp_value(event
, arg
, record
, err
);
1653 *err
= TEP_ERRNO__INVALID_ARG_TYPE
;
1658 static int test_num(struct tep_event
*event
, struct tep_filter_arg
*arg
,
1659 struct tep_record
*record
, enum tep_errno
*err
)
1661 unsigned long long lval
, rval
;
1663 lval
= get_arg_value(event
, arg
->num
.left
, record
, err
);
1664 rval
= get_arg_value(event
, arg
->num
.right
, record
, err
);
1668 * There was an error, no need to process anymore.
1673 switch (arg
->num
.type
) {
1674 case TEP_FILTER_CMP_EQ
:
1675 return lval
== rval
;
1677 case TEP_FILTER_CMP_NE
:
1678 return lval
!= rval
;
1680 case TEP_FILTER_CMP_GT
:
1683 case TEP_FILTER_CMP_LT
:
1686 case TEP_FILTER_CMP_GE
:
1687 return lval
>= rval
;
1689 case TEP_FILTER_CMP_LE
:
1690 return lval
<= rval
;
1694 *err
= TEP_ERRNO__ILLEGAL_INTEGER_CMP
;
1699 static const char *get_field_str(struct tep_filter_arg
*arg
, struct tep_record
*record
)
1701 struct tep_event
*event
;
1702 struct tep_handle
*tep
;
1703 unsigned long long addr
;
1704 const char *val
= NULL
;
1708 /* If the field is not a string convert it */
1709 if (arg
->str
.field
->flags
& TEP_FIELD_IS_STRING
) {
1710 val
= record
->data
+ arg
->str
.field
->offset
;
1711 size
= arg
->str
.field
->size
;
1713 if (arg
->str
.field
->flags
& TEP_FIELD_IS_DYNAMIC
) {
1714 addr
= *(unsigned int *)val
;
1715 val
= record
->data
+ (addr
& 0xffff);
1720 * We need to copy the data since we can't be sure the field
1721 * is null terminated.
1723 if (*(val
+ size
- 1)) {
1725 memcpy(arg
->str
.buffer
, val
, arg
->str
.field
->size
);
1726 /* the buffer is already NULL terminated */
1727 val
= arg
->str
.buffer
;
1731 event
= arg
->str
.field
->event
;
1733 addr
= get_value(event
, arg
->str
.field
, record
);
1735 if (arg
->str
.field
->flags
& (TEP_FIELD_IS_POINTER
| TEP_FIELD_IS_LONG
))
1736 /* convert to a kernel symbol */
1737 val
= tep_find_function(tep
, addr
);
1740 /* just use the hex of the string name */
1741 snprintf(hex
, 64, "0x%llx", addr
);
1749 static int test_str(struct tep_event
*event
, struct tep_filter_arg
*arg
,
1750 struct tep_record
*record
, enum tep_errno
*err
)
1754 if (arg
->str
.field
== &comm
)
1755 val
= get_comm(event
, record
);
1757 val
= get_field_str(arg
, record
);
1759 switch (arg
->str
.type
) {
1760 case TEP_FILTER_CMP_MATCH
:
1761 return strcmp(val
, arg
->str
.val
) == 0;
1763 case TEP_FILTER_CMP_NOT_MATCH
:
1764 return strcmp(val
, arg
->str
.val
) != 0;
1766 case TEP_FILTER_CMP_REGEX
:
1767 /* Returns zero on match */
1768 return !regexec(&arg
->str
.reg
, val
, 0, NULL
, 0);
1770 case TEP_FILTER_CMP_NOT_REGEX
:
1771 return regexec(&arg
->str
.reg
, val
, 0, NULL
, 0);
1775 *err
= TEP_ERRNO__ILLEGAL_STRING_CMP
;
1780 static int test_op(struct tep_event
*event
, struct tep_filter_arg
*arg
,
1781 struct tep_record
*record
, enum tep_errno
*err
)
1783 switch (arg
->op
.type
) {
1784 case TEP_FILTER_OP_AND
:
1785 return test_filter(event
, arg
->op
.left
, record
, err
) &&
1786 test_filter(event
, arg
->op
.right
, record
, err
);
1788 case TEP_FILTER_OP_OR
:
1789 return test_filter(event
, arg
->op
.left
, record
, err
) ||
1790 test_filter(event
, arg
->op
.right
, record
, err
);
1792 case TEP_FILTER_OP_NOT
:
1793 return !test_filter(event
, arg
->op
.right
, record
, err
);
1797 *err
= TEP_ERRNO__INVALID_OP_TYPE
;
1802 static int test_filter(struct tep_event
*event
, struct tep_filter_arg
*arg
,
1803 struct tep_record
*record
, enum tep_errno
*err
)
1807 * There was an error, no need to process anymore.
1812 switch (arg
->type
) {
1813 case TEP_FILTER_ARG_BOOLEAN
:
1815 return arg
->boolean
.value
;
1817 case TEP_FILTER_ARG_OP
:
1818 return test_op(event
, arg
, record
, err
);
1820 case TEP_FILTER_ARG_NUM
:
1821 return test_num(event
, arg
, record
, err
);
1823 case TEP_FILTER_ARG_STR
:
1824 return test_str(event
, arg
, record
, err
);
1826 case TEP_FILTER_ARG_EXP
:
1827 case TEP_FILTER_ARG_VALUE
:
1828 case TEP_FILTER_ARG_FIELD
:
1830 * Expressions, fields and values evaluate
1831 * to true if they return non zero
1833 return !!get_arg_value(event
, arg
, record
, err
);
1837 *err
= TEP_ERRNO__INVALID_ARG_TYPE
;
1843 * tep_event_filtered - return true if event has filter
1844 * @filter: filter struct with filter information
1845 * @event_id: event id to test if filter exists
1847 * Returns 1 if filter found for @event_id
1850 int tep_event_filtered(struct tep_event_filter
*filter
, int event_id
)
1852 struct tep_filter_type
*filter_type
;
1854 if (!filter
->filters
)
1857 filter_type
= find_filter_type(filter
, event_id
);
1859 return filter_type
? 1 : 0;
1863 * tep_filter_match - test if a record matches a filter
1864 * @filter: filter struct with filter information
1865 * @record: the record to test against the filter
1867 * Returns: match result or error code (prefixed with TEP_ERRNO__)
1868 * FILTER_MATCH - filter found for event and @record matches
1869 * FILTER_MISS - filter found for event and @record does not match
1870 * FILTER_NOT_FOUND - no filter found for @record's event
1871 * NO_FILTER - if no filters exist
1872 * otherwise - error occurred during test
1874 enum tep_errno
tep_filter_match(struct tep_event_filter
*filter
,
1875 struct tep_record
*record
)
1877 struct tep_handle
*tep
= filter
->tep
;
1878 struct tep_filter_type
*filter_type
;
1881 enum tep_errno err
= 0;
1883 filter_init_error_buf(filter
);
1885 if (!filter
->filters
)
1886 return TEP_ERRNO__NO_FILTER
;
1888 event_id
= tep_data_type(tep
, record
);
1890 filter_type
= find_filter_type(filter
, event_id
);
1892 return TEP_ERRNO__FILTER_NOT_FOUND
;
1894 ret
= test_filter(filter_type
->event
, filter_type
->filter
, record
, &err
);
1898 return ret
? TEP_ERRNO__FILTER_MATCH
: TEP_ERRNO__FILTER_MISS
;
1901 static char *op_to_str(struct tep_event_filter
*filter
, struct tep_filter_arg
*arg
)
1911 switch (arg
->op
.type
) {
1912 case TEP_FILTER_OP_AND
:
1915 case TEP_FILTER_OP_OR
:
1919 left
= arg_to_str(filter
, arg
->op
.left
);
1920 right
= arg_to_str(filter
, arg
->op
.right
);
1921 if (!left
|| !right
)
1924 /* Try to consolidate boolean values */
1925 if (strcmp(left
, "TRUE") == 0)
1927 else if (strcmp(left
, "FALSE") == 0)
1930 if (strcmp(right
, "TRUE") == 0)
1932 else if (strcmp(right
, "FALSE") == 0)
1935 if (left_val
>= 0) {
1936 if ((arg
->op
.type
== TEP_FILTER_OP_AND
&& !left_val
) ||
1937 (arg
->op
.type
== TEP_FILTER_OP_OR
&& left_val
)) {
1938 /* Just return left value */
1943 if (right_val
>= 0) {
1944 /* just evaluate this. */
1946 switch (arg
->op
.type
) {
1947 case TEP_FILTER_OP_AND
:
1948 val
= left_val
&& right_val
;
1950 case TEP_FILTER_OP_OR
:
1951 val
= left_val
|| right_val
;
1956 if (asprintf(&str
, val
? "TRUE" : "FALSE") < 0)
1961 if (right_val
>= 0) {
1962 if ((arg
->op
.type
== TEP_FILTER_OP_AND
&& !right_val
) ||
1963 (arg
->op
.type
== TEP_FILTER_OP_OR
&& right_val
)) {
1964 /* Just return right value */
1969 /* The right value is meaningless */
1975 if (asprintf(&str
, "(%s) %s (%s)", left
, op
, right
) < 0)
1979 case TEP_FILTER_OP_NOT
:
1981 right
= arg_to_str(filter
, arg
->op
.right
);
1985 /* See if we can consolidate */
1986 if (strcmp(right
, "TRUE") == 0)
1988 else if (strcmp(right
, "FALSE") == 0)
1990 if (right_val
>= 0) {
1991 /* just return the opposite */
1992 if (asprintf(&str
, right_val
? "FALSE" : "TRUE") < 0)
1996 if (asprintf(&str
, "%s(%s)", op
, right
) < 0)
2009 static char *val_to_str(struct tep_event_filter
*filter
, struct tep_filter_arg
*arg
)
2013 if (asprintf(&str
, "%lld", arg
->value
.val
) < 0)
2019 static char *field_to_str(struct tep_event_filter
*filter
, struct tep_filter_arg
*arg
)
2021 return strdup(arg
->field
.field
->name
);
2024 static char *exp_to_str(struct tep_event_filter
*filter
, struct tep_filter_arg
*arg
)
2031 lstr
= arg_to_str(filter
, arg
->exp
.left
);
2032 rstr
= arg_to_str(filter
, arg
->exp
.right
);
2036 switch (arg
->exp
.type
) {
2037 case TEP_FILTER_EXP_ADD
:
2040 case TEP_FILTER_EXP_SUB
:
2043 case TEP_FILTER_EXP_MUL
:
2046 case TEP_FILTER_EXP_DIV
:
2049 case TEP_FILTER_EXP_MOD
:
2052 case TEP_FILTER_EXP_RSHIFT
:
2055 case TEP_FILTER_EXP_LSHIFT
:
2058 case TEP_FILTER_EXP_AND
:
2061 case TEP_FILTER_EXP_OR
:
2064 case TEP_FILTER_EXP_XOR
:
2068 op
= "[ERROR IN EXPRESSION TYPE]";
2072 if (asprintf(&str
, "%s %s %s", lstr
, op
, rstr
) < 0)
2081 static char *num_to_str(struct tep_event_filter
*filter
, struct tep_filter_arg
*arg
)
2088 lstr
= arg_to_str(filter
, arg
->num
.left
);
2089 rstr
= arg_to_str(filter
, arg
->num
.right
);
2093 switch (arg
->num
.type
) {
2094 case TEP_FILTER_CMP_EQ
:
2097 case TEP_FILTER_CMP_NE
:
2101 case TEP_FILTER_CMP_GT
:
2105 case TEP_FILTER_CMP_LT
:
2109 case TEP_FILTER_CMP_GE
:
2113 case TEP_FILTER_CMP_LE
:
2117 if (asprintf(&str
, "%s %s %s", lstr
, op
, rstr
) < 0)
2132 static char *str_to_str(struct tep_event_filter
*filter
, struct tep_filter_arg
*arg
)
2137 switch (arg
->str
.type
) {
2138 case TEP_FILTER_CMP_MATCH
:
2141 case TEP_FILTER_CMP_NOT_MATCH
:
2145 case TEP_FILTER_CMP_REGEX
:
2149 case TEP_FILTER_CMP_NOT_REGEX
:
2153 if (asprintf(&str
, "%s %s \"%s\"",
2154 arg
->str
.field
->name
, op
, arg
->str
.val
) < 0)
2165 static char *arg_to_str(struct tep_event_filter
*filter
, struct tep_filter_arg
*arg
)
2169 switch (arg
->type
) {
2170 case TEP_FILTER_ARG_BOOLEAN
:
2171 if (asprintf(&str
, arg
->boolean
.value
? "TRUE" : "FALSE") < 0)
2175 case TEP_FILTER_ARG_OP
:
2176 return op_to_str(filter
, arg
);
2178 case TEP_FILTER_ARG_NUM
:
2179 return num_to_str(filter
, arg
);
2181 case TEP_FILTER_ARG_STR
:
2182 return str_to_str(filter
, arg
);
2184 case TEP_FILTER_ARG_VALUE
:
2185 return val_to_str(filter
, arg
);
2187 case TEP_FILTER_ARG_FIELD
:
2188 return field_to_str(filter
, arg
);
2190 case TEP_FILTER_ARG_EXP
:
2191 return exp_to_str(filter
, arg
);
2201 * tep_filter_make_string - return a string showing the filter
2202 * @filter: filter struct with filter information
2203 * @event_id: the event id to return the filter string with
2205 * Returns a string that displays the filter contents.
2206 * This string must be freed with free(str).
2207 * NULL is returned if no filter is found or allocation failed.
2210 tep_filter_make_string(struct tep_event_filter
*filter
, int event_id
)
2212 struct tep_filter_type
*filter_type
;
2214 if (!filter
->filters
)
2217 filter_type
= find_filter_type(filter
, event_id
);
2222 return arg_to_str(filter
, filter_type
->filter
);
2226 * tep_filter_compare - compare two filters and return if they are the same
2227 * @filter1: Filter to compare with @filter2
2228 * @filter2: Filter to compare with @filter1
2231 * 1 if the two filters hold the same content.
2234 int tep_filter_compare(struct tep_event_filter
*filter1
, struct tep_event_filter
*filter2
)
2236 struct tep_filter_type
*filter_type1
;
2237 struct tep_filter_type
*filter_type2
;
2242 /* Do the easy checks first */
2243 if (filter1
->filters
!= filter2
->filters
)
2245 if (!filter1
->filters
&& !filter2
->filters
)
2249 * Now take a look at each of the events to see if they have the same
2252 for (i
= 0; i
< filter1
->filters
; i
++) {
2253 filter_type1
= &filter1
->event_filters
[i
];
2254 filter_type2
= find_filter_type(filter2
, filter_type1
->event_id
);
2257 if (filter_type1
->filter
->type
!= filter_type2
->filter
->type
)
2259 /* The best way to compare complex filters is with strings */
2260 str1
= arg_to_str(filter1
, filter_type1
->filter
);
2261 str2
= arg_to_str(filter2
, filter_type2
->filter
);
2263 result
= strcmp(str1
, str2
) != 0;
2265 /* bail out if allocation fails */
2274 if (i
< filter1
->filters
)