2 * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation;
8 * version 2.1 of the License (not later!)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, see <http://www.gnu.org/licenses>
18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 #include <sys/types.h>
27 #include "event-parse.h"
28 #include "event-utils.h"
32 static struct format_field comm
= {
37 struct event_list
*next
;
38 struct event_format
*event
;
41 #define MAX_ERR_STR_SIZE 256
43 static void show_error(char **error_str
, const char *fmt
, ...)
45 unsigned long long index
;
55 input
= pevent_get_input_buf();
56 index
= pevent_get_input_buf_ptr();
57 len
= input
? strlen(input
) : 0;
59 error
= malloc_or_die(MAX_ERR_STR_SIZE
+ (len
*2) + 3);
64 for (i
= 1; i
< len
&& i
< index
; i
++)
67 error
[len
+ i
+ 1] = '\n';
72 vsnprintf(error
+ len
, MAX_ERR_STR_SIZE
, fmt
, ap
);
78 static void free_token(char *token
)
80 pevent_free_token(token
);
83 static enum event_type
read_token(char **tok
)
90 type
= pevent_read_token(&token
);
91 } while (type
== EVENT_NEWLINE
|| type
== EVENT_SPACE
);
93 /* If token is = or ! check to see if the next char is ~ */
95 (strcmp(token
, "=") == 0 || strcmp(token
, "!") == 0) &&
96 pevent_peek_char() == '~') {
98 *tok
= malloc_or_die(3);
99 sprintf(*tok
, "%c%c", *token
, '~');
101 /* Now remove the '~' from the buffer */
102 pevent_read_token(&token
);
110 static int filter_cmp(const void *a
, const void *b
)
112 const struct filter_type
*ea
= a
;
113 const struct filter_type
*eb
= b
;
115 if (ea
->event_id
< eb
->event_id
)
118 if (ea
->event_id
> eb
->event_id
)
124 static struct filter_type
*
125 find_filter_type(struct event_filter
*filter
, int id
)
127 struct filter_type
*filter_type
;
128 struct filter_type key
;
132 filter_type
= bsearch(&key
, filter
->event_filters
,
134 sizeof(*filter
->event_filters
),
140 static struct filter_type
*
141 add_filter_type(struct event_filter
*filter
, int id
)
143 struct filter_type
*filter_type
;
146 filter_type
= find_filter_type(filter
, id
);
150 filter
->event_filters
= realloc(filter
->event_filters
,
151 sizeof(*filter
->event_filters
) *
152 (filter
->filters
+ 1));
153 if (!filter
->event_filters
)
154 die("Could not allocate filter");
156 for (i
= 0; i
< filter
->filters
; i
++) {
157 if (filter
->event_filters
[i
].event_id
> id
)
161 if (i
< filter
->filters
)
162 memmove(&filter
->event_filters
[i
+1],
163 &filter
->event_filters
[i
],
164 sizeof(*filter
->event_filters
) *
165 (filter
->filters
- i
));
167 filter_type
= &filter
->event_filters
[i
];
168 filter_type
->event_id
= id
;
169 filter_type
->event
= pevent_find_event(filter
->pevent
, id
);
170 filter_type
->filter
= NULL
;
178 * pevent_filter_alloc - create a new event filter
179 * @pevent: The pevent that this filter is associated with
181 struct event_filter
*pevent_filter_alloc(struct pevent
*pevent
)
183 struct event_filter
*filter
;
185 filter
= malloc_or_die(sizeof(*filter
));
186 memset(filter
, 0, sizeof(*filter
));
187 filter
->pevent
= pevent
;
193 static struct filter_arg
*allocate_arg(void)
195 struct filter_arg
*arg
;
197 arg
= malloc_or_die(sizeof(*arg
));
198 memset(arg
, 0, sizeof(*arg
));
203 static void free_arg(struct filter_arg
*arg
)
209 case FILTER_ARG_NONE
:
210 case FILTER_ARG_BOOLEAN
:
214 free_arg(arg
->num
.left
);
215 free_arg(arg
->num
.right
);
219 free_arg(arg
->exp
.left
);
220 free_arg(arg
->exp
.right
);
225 regfree(&arg
->str
.reg
);
226 free(arg
->str
.buffer
);
229 case FILTER_ARG_VALUE
:
230 if (arg
->value
.type
== FILTER_STRING
||
231 arg
->value
.type
== FILTER_CHAR
)
232 free(arg
->value
.str
);
236 free_arg(arg
->op
.left
);
237 free_arg(arg
->op
.right
);
245 static void add_event(struct event_list
**events
,
246 struct event_format
*event
)
248 struct event_list
*list
;
250 list
= malloc_or_die(sizeof(*list
));
251 list
->next
= *events
;
256 static int event_match(struct event_format
*event
,
257 regex_t
*sreg
, regex_t
*ereg
)
260 return !regexec(sreg
, event
->system
, 0, NULL
, 0) &&
261 !regexec(ereg
, event
->name
, 0, NULL
, 0);
264 return !regexec(ereg
, event
->system
, 0, NULL
, 0) ||
265 !regexec(ereg
, event
->name
, 0, NULL
, 0);
269 find_event(struct pevent
*pevent
, struct event_list
**events
,
270 char *sys_name
, char *event_name
)
272 struct event_format
*event
;
281 /* if no name is given, then swap sys and name */
282 event_name
= sys_name
;
286 reg
= malloc_or_die(strlen(event_name
) + 3);
287 sprintf(reg
, "^%s$", event_name
);
289 ret
= regcomp(&ereg
, reg
, REG_ICASE
|REG_NOSUB
);
296 reg
= malloc_or_die(strlen(sys_name
) + 3);
297 sprintf(reg
, "^%s$", sys_name
);
298 ret
= regcomp(&sreg
, reg
, REG_ICASE
|REG_NOSUB
);
306 for (i
= 0; i
< pevent
->nr_events
; i
++) {
307 event
= pevent
->events
[i
];
308 if (event_match(event
, sys_name
? &sreg
: NULL
, &ereg
)) {
310 add_event(events
, event
);
324 static void free_events(struct event_list
*events
)
326 struct event_list
*event
;
330 events
= events
->next
;
335 static struct filter_arg
*
336 create_arg_item(struct event_format
*event
, const char *token
,
337 enum event_type type
, char **error_str
)
339 struct format_field
*field
;
340 struct filter_arg
*arg
;
342 arg
= allocate_arg();
348 arg
->type
= FILTER_ARG_VALUE
;
350 type
== EVENT_DQUOTE
? FILTER_STRING
: FILTER_CHAR
;
351 arg
->value
.str
= strdup(token
);
353 die("malloc string");
356 /* if it is a number, then convert it */
357 if (isdigit(token
[0])) {
358 arg
->type
= FILTER_ARG_VALUE
;
359 arg
->value
.type
= FILTER_NUMBER
;
360 arg
->value
.val
= strtoull(token
, NULL
, 0);
363 /* Consider this a field */
364 field
= pevent_find_any_field(event
, token
);
366 if (strcmp(token
, COMM
) != 0) {
367 /* not a field, Make it false */
368 arg
->type
= FILTER_ARG_BOOLEAN
;
369 arg
->boolean
.value
= FILTER_FALSE
;
372 /* If token is 'COMM' then it is special */
375 arg
->type
= FILTER_ARG_FIELD
;
376 arg
->field
.field
= field
;
380 show_error(error_str
, "expected a value but found %s",
387 static struct filter_arg
*
388 create_arg_op(enum filter_op_type btype
)
390 struct filter_arg
*arg
;
392 arg
= allocate_arg();
393 arg
->type
= FILTER_ARG_OP
;
394 arg
->op
.type
= btype
;
399 static struct filter_arg
*
400 create_arg_exp(enum filter_exp_type etype
)
402 struct filter_arg
*arg
;
404 arg
= allocate_arg();
405 arg
->type
= FILTER_ARG_EXP
;
406 arg
->op
.type
= etype
;
411 static struct filter_arg
*
412 create_arg_cmp(enum filter_exp_type etype
)
414 struct filter_arg
*arg
;
416 arg
= allocate_arg();
417 /* Use NUM and change if necessary */
418 arg
->type
= FILTER_ARG_NUM
;
419 arg
->op
.type
= etype
;
424 static int add_right(struct filter_arg
*op
, struct filter_arg
*arg
,
427 struct filter_arg
*left
;
449 * The arg must be num, str, or field
452 case FILTER_ARG_VALUE
:
453 case FILTER_ARG_FIELD
:
456 show_error(error_str
,
462 * Depending on the type, we may need to
463 * convert this to a string or regex.
465 switch (arg
->value
.type
) {
468 * A char should be converted to number if
469 * the string is 1 byte, and the compare
472 if (strlen(arg
->value
.str
) == 1 &&
473 op
->num
.type
!= FILTER_CMP_REGEX
&&
474 op
->num
.type
!= FILTER_CMP_NOT_REGEX
) {
475 arg
->value
.type
= FILTER_NUMBER
;
481 /* convert op to a string arg */
482 op_type
= op
->num
.type
;
484 str
= arg
->value
.str
;
486 /* reset the op for the new field */
487 memset(op
, 0, sizeof(*op
));
490 * If left arg was a field not found then
491 * NULL the entire op.
493 if (left
->type
== FILTER_ARG_BOOLEAN
) {
496 op
->type
= FILTER_ARG_BOOLEAN
;
497 op
->boolean
.value
= FILTER_FALSE
;
501 /* Left arg must be a field */
502 if (left
->type
!= FILTER_ARG_FIELD
) {
503 show_error(error_str
,
504 "Illegal lvalue for string comparison");
508 /* Make sure this is a valid string compare */
511 op_type
= FILTER_CMP_MATCH
;
514 op_type
= FILTER_CMP_NOT_MATCH
;
517 case FILTER_CMP_REGEX
:
518 case FILTER_CMP_NOT_REGEX
:
519 ret
= regcomp(&op
->str
.reg
, str
, REG_ICASE
|REG_NOSUB
);
521 show_error(error_str
,
522 "RegEx '%s' did not compute",
528 show_error(error_str
,
529 "Illegal comparison for string");
533 op
->type
= FILTER_ARG_STR
;
534 op
->str
.type
= op_type
;
535 op
->str
.field
= left
->field
.field
;
536 op
->str
.val
= strdup(str
);
538 die("malloc string");
540 * Need a buffer to copy data for tests
542 op
->str
.buffer
= malloc_or_die(op
->str
.field
->size
+ 1);
543 /* Null terminate this buffer */
544 op
->str
.buffer
[op
->str
.field
->size
] = 0;
546 /* We no longer have left or right args */
555 switch (op
->num
.type
) {
556 case FILTER_CMP_REGEX
:
557 case FILTER_CMP_NOT_REGEX
:
558 show_error(error_str
,
559 "Op not allowed with integers");
566 /* numeric compare */
580 show_error(error_str
,
585 static struct filter_arg
*
586 rotate_op_right(struct filter_arg
*a
, struct filter_arg
*b
)
588 struct filter_arg
*arg
;
595 static int add_left(struct filter_arg
*op
, struct filter_arg
*arg
)
599 if (arg
->type
== FILTER_ARG_OP
)
600 arg
= rotate_op_right(arg
, op
);
608 if (arg
->type
== FILTER_ARG_OP
)
609 arg
= rotate_op_right(arg
, op
);
611 /* left arg of compares must be a field */
612 if (arg
->type
!= FILTER_ARG_FIELD
&&
613 arg
->type
!= FILTER_ARG_BOOLEAN
)
631 static enum op_type
process_op(const char *token
,
632 enum filter_op_type
*btype
,
633 enum filter_cmp_type
*ctype
,
634 enum filter_exp_type
*etype
)
636 *btype
= FILTER_OP_NOT
;
637 *etype
= FILTER_EXP_NONE
;
638 *ctype
= FILTER_CMP_NONE
;
640 if (strcmp(token
, "&&") == 0)
641 *btype
= FILTER_OP_AND
;
642 else if (strcmp(token
, "||") == 0)
643 *btype
= FILTER_OP_OR
;
644 else if (strcmp(token
, "!") == 0)
647 if (*btype
!= FILTER_OP_NOT
)
650 /* Check for value expressions */
651 if (strcmp(token
, "+") == 0) {
652 *etype
= FILTER_EXP_ADD
;
653 } else if (strcmp(token
, "-") == 0) {
654 *etype
= FILTER_EXP_SUB
;
655 } else if (strcmp(token
, "*") == 0) {
656 *etype
= FILTER_EXP_MUL
;
657 } else if (strcmp(token
, "/") == 0) {
658 *etype
= FILTER_EXP_DIV
;
659 } else if (strcmp(token
, "%") == 0) {
660 *etype
= FILTER_EXP_MOD
;
661 } else if (strcmp(token
, ">>") == 0) {
662 *etype
= FILTER_EXP_RSHIFT
;
663 } else if (strcmp(token
, "<<") == 0) {
664 *etype
= FILTER_EXP_LSHIFT
;
665 } else if (strcmp(token
, "&") == 0) {
666 *etype
= FILTER_EXP_AND
;
667 } else if (strcmp(token
, "|") == 0) {
668 *etype
= FILTER_EXP_OR
;
669 } else if (strcmp(token
, "^") == 0) {
670 *etype
= FILTER_EXP_XOR
;
671 } else if (strcmp(token
, "~") == 0)
672 *etype
= FILTER_EXP_NOT
;
674 if (*etype
!= FILTER_EXP_NONE
)
677 /* Check for compares */
678 if (strcmp(token
, "==") == 0)
679 *ctype
= FILTER_CMP_EQ
;
680 else if (strcmp(token
, "!=") == 0)
681 *ctype
= FILTER_CMP_NE
;
682 else if (strcmp(token
, "<") == 0)
683 *ctype
= FILTER_CMP_LT
;
684 else if (strcmp(token
, ">") == 0)
685 *ctype
= FILTER_CMP_GT
;
686 else if (strcmp(token
, "<=") == 0)
687 *ctype
= FILTER_CMP_LE
;
688 else if (strcmp(token
, ">=") == 0)
689 *ctype
= FILTER_CMP_GE
;
690 else if (strcmp(token
, "=~") == 0)
691 *ctype
= FILTER_CMP_REGEX
;
692 else if (strcmp(token
, "!~") == 0)
693 *ctype
= FILTER_CMP_NOT_REGEX
;
700 static int check_op_done(struct filter_arg
*arg
)
704 return arg
->exp
.right
!= NULL
;
707 return arg
->op
.right
!= NULL
;
710 return arg
->num
.right
!= NULL
;
713 /* A string conversion is always done */
716 case FILTER_ARG_BOOLEAN
:
717 /* field not found, is ok */
731 void reparent_op_arg(struct filter_arg
*parent
, struct filter_arg
*old_child
,
732 struct filter_arg
*arg
)
734 struct filter_arg
*other_child
;
735 struct filter_arg
**ptr
;
737 if (parent
->type
!= FILTER_ARG_OP
&&
738 arg
->type
!= FILTER_ARG_OP
)
739 die("can not reparent other than OP");
741 /* Get the sibling */
742 if (old_child
->op
.right
== arg
) {
743 ptr
= &old_child
->op
.right
;
744 other_child
= old_child
->op
.left
;
745 } else if (old_child
->op
.left
== arg
) {
746 ptr
= &old_child
->op
.left
;
747 other_child
= old_child
->op
.right
;
749 die("Error in reparent op, find other child");
751 /* Detach arg from old_child */
755 if (parent
== old_child
) {
756 free_arg(other_child
);
758 /* Free arg without recussion */
763 if (parent
->op
.right
== old_child
)
764 ptr
= &parent
->op
.right
;
765 else if (parent
->op
.left
== old_child
)
766 ptr
= &parent
->op
.left
;
768 die("Error in reparent op");
774 enum filter_vals
test_arg(struct filter_arg
*parent
, struct filter_arg
*arg
)
776 enum filter_vals lval
, rval
;
781 case FILTER_ARG_BOOLEAN
:
782 return FILTER_VAL_FALSE
+ arg
->boolean
.value
;
786 case FILTER_ARG_VALUE
:
787 case FILTER_ARG_FIELD
:
788 return FILTER_VAL_NORM
;
791 lval
= test_arg(arg
, arg
->exp
.left
);
792 if (lval
!= FILTER_VAL_NORM
)
794 rval
= test_arg(arg
, arg
->exp
.right
);
795 if (rval
!= FILTER_VAL_NORM
)
797 return FILTER_VAL_NORM
;
800 lval
= test_arg(arg
, arg
->num
.left
);
801 if (lval
!= FILTER_VAL_NORM
)
803 rval
= test_arg(arg
, arg
->num
.right
);
804 if (rval
!= FILTER_VAL_NORM
)
806 return FILTER_VAL_NORM
;
809 if (arg
->op
.type
!= FILTER_OP_NOT
) {
810 lval
= test_arg(arg
, arg
->op
.left
);
812 case FILTER_VAL_NORM
:
814 case FILTER_VAL_TRUE
:
815 if (arg
->op
.type
== FILTER_OP_OR
)
816 return FILTER_VAL_TRUE
;
817 rval
= test_arg(arg
, arg
->op
.right
);
818 if (rval
!= FILTER_VAL_NORM
)
821 reparent_op_arg(parent
, arg
, arg
->op
.right
);
822 return FILTER_VAL_NORM
;
824 case FILTER_VAL_FALSE
:
825 if (arg
->op
.type
== FILTER_OP_AND
)
826 return FILTER_VAL_FALSE
;
827 rval
= test_arg(arg
, arg
->op
.right
);
828 if (rval
!= FILTER_VAL_NORM
)
831 reparent_op_arg(parent
, arg
, arg
->op
.right
);
832 return FILTER_VAL_NORM
;
836 rval
= test_arg(arg
, arg
->op
.right
);
838 case FILTER_VAL_NORM
:
840 case FILTER_VAL_TRUE
:
841 if (arg
->op
.type
== FILTER_OP_OR
)
842 return FILTER_VAL_TRUE
;
843 if (arg
->op
.type
== FILTER_OP_NOT
)
844 return FILTER_VAL_FALSE
;
846 reparent_op_arg(parent
, arg
, arg
->op
.left
);
847 return FILTER_VAL_NORM
;
849 case FILTER_VAL_FALSE
:
850 if (arg
->op
.type
== FILTER_OP_AND
)
851 return FILTER_VAL_FALSE
;
852 if (arg
->op
.type
== FILTER_OP_NOT
)
853 return FILTER_VAL_TRUE
;
855 reparent_op_arg(parent
, arg
, arg
->op
.left
);
856 return FILTER_VAL_NORM
;
859 return FILTER_VAL_NORM
;
861 die("bad arg in filter tree");
863 return FILTER_VAL_NORM
;
866 /* Remove any unknown event fields */
867 static struct filter_arg
*collapse_tree(struct filter_arg
*arg
)
869 enum filter_vals ret
;
871 ret
= test_arg(arg
, arg
);
873 case FILTER_VAL_NORM
:
876 case FILTER_VAL_TRUE
:
877 case FILTER_VAL_FALSE
:
879 arg
= allocate_arg();
880 arg
->type
= FILTER_ARG_BOOLEAN
;
881 arg
->boolean
.value
= ret
== FILTER_VAL_TRUE
;
888 process_filter(struct event_format
*event
, struct filter_arg
**parg
,
889 char **error_str
, int not)
891 enum event_type type
;
893 struct filter_arg
*current_op
= NULL
;
894 struct filter_arg
*current_exp
= NULL
;
895 struct filter_arg
*left_item
= NULL
;
896 struct filter_arg
*arg
= NULL
;
897 enum op_type op_type
;
898 enum filter_op_type btype
;
899 enum filter_exp_type etype
;
900 enum filter_cmp_type ctype
;
907 type
= read_token(&token
);
912 arg
= create_arg_item(event
, token
, type
, error_str
);
917 else if (current_exp
) {
918 ret
= add_right(current_exp
, arg
, error_str
);
922 /* Not's only one one expression */
938 show_error(error_str
,
939 "Illegal token ','");
945 show_error(error_str
,
946 "Open paren can not come after item");
950 show_error(error_str
,
951 "Open paren can not come after expression");
955 ret
= process_filter(event
, &arg
, error_str
, 0);
958 show_error(error_str
,
959 "Unbalanced number of '('");
964 /* A not wants just one expression */
973 ret
= add_right(current_op
, arg
, error_str
);
981 if (!current_op
&& !current_exp
)
984 /* Make sure everything is finished at this level */
985 if (current_exp
&& !check_op_done(current_exp
))
987 if (current_op
&& !check_op_done(current_op
))
999 op_type
= process_op(token
, &btype
, &ctype
, &etype
);
1001 /* All expect a left arg except for NOT */
1004 /* Logic ops need a left expression */
1005 if (!current_exp
&& !current_op
)
1009 /* logic only processes ops and exp */
1019 show_error(error_str
,
1020 "Unknown op token %s", token
);
1027 arg
= create_arg_op(btype
);
1029 ret
= add_left(arg
, current_op
);
1031 ret
= add_left(arg
, current_exp
);
1037 arg
= create_arg_op(btype
);
1039 ret
= add_right(current_op
, arg
, error_str
);
1043 ret
= process_filter(event
, &arg
, error_str
, 1);
1046 ret
= add_right(current_exp
, arg
, error_str
);
1053 if (op_type
== OP_EXP
)
1054 arg
= create_arg_exp(etype
);
1056 arg
= create_arg_cmp(ctype
);
1059 ret
= add_right(current_op
, arg
, error_str
);
1062 ret
= add_left(arg
, left_item
);
1081 } while (type
!= EVENT_NONE
);
1083 if (!current_op
&& !current_exp
)
1087 current_op
= current_exp
;
1089 current_op
= collapse_tree(current_op
);
1096 show_error(error_str
, "Syntax error");
1098 free_arg(current_op
);
1099 free_arg(current_exp
);
1106 process_event(struct event_format
*event
, const char *filter_str
,
1107 struct filter_arg
**parg
, char **error_str
)
1111 pevent_buffer_init(filter_str
, strlen(filter_str
));
1113 ret
= process_filter(event
, parg
, error_str
, 0);
1115 show_error(error_str
,
1116 "Unbalanced number of ')'");
1122 /* If parg is NULL, then make it into FALSE */
1124 *parg
= allocate_arg();
1125 (*parg
)->type
= FILTER_ARG_BOOLEAN
;
1126 (*parg
)->boolean
.value
= FILTER_FALSE
;
1132 static int filter_event(struct event_filter
*filter
,
1133 struct event_format
*event
,
1134 const char *filter_str
, char **error_str
)
1136 struct filter_type
*filter_type
;
1137 struct filter_arg
*arg
;
1141 ret
= process_event(event
, filter_str
, &arg
, error_str
);
1146 /* just add a TRUE arg */
1147 arg
= allocate_arg();
1148 arg
->type
= FILTER_ARG_BOOLEAN
;
1149 arg
->boolean
.value
= FILTER_TRUE
;
1152 filter_type
= add_filter_type(filter
, event
->id
);
1153 if (filter_type
->filter
)
1154 free_arg(filter_type
->filter
);
1155 filter_type
->filter
= arg
;
1161 * pevent_filter_add_filter_str - add a new filter
1162 * @filter: the event filter to add to
1163 * @filter_str: the filter string that contains the filter
1164 * @error_str: string containing reason for failed filter
1166 * Returns 0 if the filter was successfully added
1167 * -1 if there was an error.
1169 * On error, if @error_str points to a string pointer,
1170 * it is set to the reason that the filter failed.
1171 * This string must be freed with "free".
1173 int pevent_filter_add_filter_str(struct event_filter
*filter
,
1174 const char *filter_str
,
1177 struct pevent
*pevent
= filter
->pevent
;
1178 struct event_list
*event
;
1179 struct event_list
*events
= NULL
;
1180 const char *filter_start
;
1181 const char *next_event
;
1183 char *event_name
= NULL
;
1184 char *sys_name
= NULL
;
1190 /* clear buffer to reset show error */
1191 pevent_buffer_init("", 0);
1196 filter_start
= strchr(filter_str
, ':');
1198 len
= filter_start
- filter_str
;
1200 len
= strlen(filter_str
);
1204 next_event
= strchr(filter_str
, ',');
1206 (!filter_start
|| next_event
< filter_start
))
1207 len
= next_event
- filter_str
;
1208 else if (filter_start
)
1209 len
= filter_start
- filter_str
;
1211 len
= strlen(filter_str
);
1213 this_event
= malloc_or_die(len
+ 1);
1214 memcpy(this_event
, filter_str
, len
);
1215 this_event
[len
] = 0;
1220 filter_str
= next_event
;
1222 sys_name
= strtok_r(this_event
, "/", &sp
);
1223 event_name
= strtok_r(NULL
, "/", &sp
);
1226 show_error(error_str
, "No filter found");
1227 /* This can only happen when events is NULL, but still */
1228 free_events(events
);
1233 /* Find this event */
1234 ret
= find_event(pevent
, &events
, strim(sys_name
), strim(event_name
));
1237 show_error(error_str
,
1238 "No event found under '%s.%s'",
1239 sys_name
, event_name
);
1241 show_error(error_str
,
1242 "No event found under '%s'",
1244 free_events(events
);
1249 } while (filter_str
);
1255 /* filter starts here */
1256 for (event
= events
; event
; event
= event
->next
) {
1257 ret
= filter_event(filter
, event
->event
, filter_start
,
1259 /* Failures are returned if a parse error happened */
1263 if (ret
>= 0 && pevent
->test_filters
) {
1265 test
= pevent_filter_make_string(filter
, event
->event
->id
);
1266 printf(" '%s: %s'\n", event
->event
->name
, test
);
1271 free_events(events
);
1273 if (rtn
>= 0 && pevent
->test_filters
)
1279 static void free_filter_type(struct filter_type
*filter_type
)
1281 free_arg(filter_type
->filter
);
1285 * pevent_filter_remove_event - remove a filter for an event
1286 * @filter: the event filter to remove from
1287 * @event_id: the event to remove a filter for
1289 * Removes the filter saved for an event defined by @event_id
1292 * Returns 1: if an event was removed
1293 * 0: if the event was not found
1295 int pevent_filter_remove_event(struct event_filter
*filter
,
1298 struct filter_type
*filter_type
;
1301 if (!filter
->filters
)
1304 filter_type
= find_filter_type(filter
, event_id
);
1309 free_filter_type(filter_type
);
1311 /* The filter_type points into the event_filters array */
1312 len
= (unsigned long)(filter
->event_filters
+ filter
->filters
) -
1313 (unsigned long)(filter_type
+ 1);
1315 memmove(filter_type
, filter_type
+ 1, len
);
1318 memset(&filter
->event_filters
[filter
->filters
], 0,
1319 sizeof(*filter_type
));
1325 * pevent_filter_reset - clear all filters in a filter
1326 * @filter: the event filter to reset
1328 * Removes all filters from a filter and resets it.
1330 void pevent_filter_reset(struct event_filter
*filter
)
1334 for (i
= 0; i
< filter
->filters
; i
++)
1335 free_filter_type(&filter
->event_filters
[i
]);
1337 free(filter
->event_filters
);
1338 filter
->filters
= 0;
1339 filter
->event_filters
= NULL
;
1342 void pevent_filter_free(struct event_filter
*filter
)
1344 pevent_unref(filter
->pevent
);
1346 pevent_filter_reset(filter
);
1351 static char *arg_to_str(struct event_filter
*filter
, struct filter_arg
*arg
);
1353 static int copy_filter_type(struct event_filter
*filter
,
1354 struct event_filter
*source
,
1355 struct filter_type
*filter_type
)
1357 struct filter_arg
*arg
;
1358 struct event_format
*event
;
1363 /* Can't assume that the pevent's are the same */
1364 sys
= filter_type
->event
->system
;
1365 name
= filter_type
->event
->name
;
1366 event
= pevent_find_event_by_name(filter
->pevent
, sys
, name
);
1370 str
= arg_to_str(source
, filter_type
->filter
);
1374 if (strcmp(str
, "TRUE") == 0 || strcmp(str
, "FALSE") == 0) {
1375 /* Add trivial event */
1376 arg
= allocate_arg();
1377 arg
->type
= FILTER_ARG_BOOLEAN
;
1378 if (strcmp(str
, "TRUE") == 0)
1379 arg
->boolean
.value
= 1;
1381 arg
->boolean
.value
= 0;
1383 filter_type
= add_filter_type(filter
, event
->id
);
1384 filter_type
->filter
= arg
;
1390 filter_event(filter
, event
, str
, NULL
);
1397 * pevent_filter_copy - copy a filter using another filter
1398 * @dest - the filter to copy to
1399 * @source - the filter to copy from
1401 * Returns 0 on success and -1 if not all filters were copied
1403 int pevent_filter_copy(struct event_filter
*dest
, struct event_filter
*source
)
1408 pevent_filter_reset(dest
);
1410 for (i
= 0; i
< source
->filters
; i
++) {
1411 if (copy_filter_type(dest
, source
, &source
->event_filters
[i
]))
1419 * pevent_update_trivial - update the trivial filters with the given filter
1420 * @dest - the filter to update
1421 * @source - the filter as the source of the update
1422 * @type - the type of trivial filter to update.
1424 * Scan dest for trivial events matching @type to replace with the source.
1426 * Returns 0 on success and -1 if there was a problem updating, but
1427 * events may have still been updated on error.
1429 int pevent_update_trivial(struct event_filter
*dest
, struct event_filter
*source
,
1430 enum filter_trivial_type type
)
1432 struct pevent
*src_pevent
;
1433 struct pevent
*dest_pevent
;
1434 struct event_format
*event
;
1435 struct filter_type
*filter_type
;
1436 struct filter_arg
*arg
;
1440 src_pevent
= source
->pevent
;
1441 dest_pevent
= dest
->pevent
;
1443 /* Do nothing if either of the filters has nothing to filter */
1444 if (!dest
->filters
|| !source
->filters
)
1447 for (i
= 0; i
< dest
->filters
; i
++) {
1448 filter_type
= &dest
->event_filters
[i
];
1449 arg
= filter_type
->filter
;
1450 if (arg
->type
!= FILTER_ARG_BOOLEAN
)
1452 if ((arg
->boolean
.value
&& type
== FILTER_TRIVIAL_FALSE
) ||
1453 (!arg
->boolean
.value
&& type
== FILTER_TRIVIAL_TRUE
))
1456 event
= filter_type
->event
;
1458 if (src_pevent
!= dest_pevent
) {
1460 event
= pevent_find_event_by_name(src_pevent
,
1467 str
= pevent_filter_make_string(source
, event
->id
);
1471 /* Don't bother if the filter is trivial too */
1472 if (strcmp(str
, "TRUE") != 0 && strcmp(str
, "FALSE") != 0)
1473 filter_event(dest
, event
, str
, NULL
);
1480 * pevent_filter_clear_trivial - clear TRUE and FALSE filters
1481 * @filter: the filter to remove trivial filters from
1482 * @type: remove only true, false, or both
1484 * Removes filters that only contain a TRUE or FALES boolean arg.
1486 void pevent_filter_clear_trivial(struct event_filter
*filter
,
1487 enum filter_trivial_type type
)
1489 struct filter_type
*filter_type
;
1494 if (!filter
->filters
)
1498 * Two steps, first get all ids with trivial filters.
1499 * then remove those ids.
1501 for (i
= 0; i
< filter
->filters
; i
++) {
1502 filter_type
= &filter
->event_filters
[i
];
1503 if (filter_type
->filter
->type
!= FILTER_ARG_BOOLEAN
)
1506 case FILTER_TRIVIAL_FALSE
:
1507 if (filter_type
->filter
->boolean
.value
)
1509 case FILTER_TRIVIAL_TRUE
:
1510 if (!filter_type
->filter
->boolean
.value
)
1516 ids
= realloc(ids
, sizeof(*ids
) * (count
+ 1));
1518 die("Can't allocate ids");
1519 ids
[count
++] = filter_type
->event_id
;
1525 for (i
= 0; i
< count
; i
++)
1526 pevent_filter_remove_event(filter
, ids
[i
]);
1532 * pevent_filter_event_has_trivial - return true event contains trivial filter
1533 * @filter: the filter with the information
1534 * @event_id: the id of the event to test
1535 * @type: trivial type to test for (TRUE, FALSE, EITHER)
1537 * Returns 1 if the event contains a matching trivial type
1540 int pevent_filter_event_has_trivial(struct event_filter
*filter
,
1542 enum filter_trivial_type type
)
1544 struct filter_type
*filter_type
;
1546 if (!filter
->filters
)
1549 filter_type
= find_filter_type(filter
, event_id
);
1554 if (filter_type
->filter
->type
!= FILTER_ARG_BOOLEAN
)
1558 case FILTER_TRIVIAL_FALSE
:
1559 return !filter_type
->filter
->boolean
.value
;
1561 case FILTER_TRIVIAL_TRUE
:
1562 return filter_type
->filter
->boolean
.value
;
1568 static int test_filter(struct event_format
*event
,
1569 struct filter_arg
*arg
, struct pevent_record
*record
);
1572 get_comm(struct event_format
*event
, struct pevent_record
*record
)
1577 pid
= pevent_data_pid(event
->pevent
, record
);
1578 comm
= pevent_data_comm_from_pid(event
->pevent
, pid
);
1582 static unsigned long long
1583 get_value(struct event_format
*event
,
1584 struct format_field
*field
, struct pevent_record
*record
)
1586 unsigned long long val
;
1588 /* Handle our dummy "comm" field */
1589 if (field
== &comm
) {
1592 name
= get_comm(event
, record
);
1593 return (unsigned long)name
;
1596 pevent_read_number_field(field
, record
->data
, &val
);
1598 if (!(field
->flags
& FIELD_IS_SIGNED
))
1601 switch (field
->size
) {
1609 return (long long)val
;
1614 static unsigned long long
1615 get_arg_value(struct event_format
*event
, struct filter_arg
*arg
, struct pevent_record
*record
);
1617 static unsigned long long
1618 get_exp_value(struct event_format
*event
, struct filter_arg
*arg
, struct pevent_record
*record
)
1620 unsigned long long lval
, rval
;
1622 lval
= get_arg_value(event
, arg
->exp
.left
, record
);
1623 rval
= get_arg_value(event
, arg
->exp
.right
, record
);
1625 switch (arg
->exp
.type
) {
1626 case FILTER_EXP_ADD
:
1629 case FILTER_EXP_SUB
:
1632 case FILTER_EXP_MUL
:
1635 case FILTER_EXP_DIV
:
1638 case FILTER_EXP_MOD
:
1641 case FILTER_EXP_RSHIFT
:
1642 return lval
>> rval
;
1644 case FILTER_EXP_LSHIFT
:
1645 return lval
<< rval
;
1647 case FILTER_EXP_AND
:
1653 case FILTER_EXP_XOR
:
1656 case FILTER_EXP_NOT
:
1658 die("error in exp");
1663 static unsigned long long
1664 get_arg_value(struct event_format
*event
, struct filter_arg
*arg
, struct pevent_record
*record
)
1666 switch (arg
->type
) {
1667 case FILTER_ARG_FIELD
:
1668 return get_value(event
, arg
->field
.field
, record
);
1670 case FILTER_ARG_VALUE
:
1671 if (arg
->value
.type
!= FILTER_NUMBER
)
1672 die("must have number field!");
1673 return arg
->value
.val
;
1675 case FILTER_ARG_EXP
:
1676 return get_exp_value(event
, arg
, record
);
1679 die("oops in filter");
1684 static int test_num(struct event_format
*event
,
1685 struct filter_arg
*arg
, struct pevent_record
*record
)
1687 unsigned long long lval
, rval
;
1689 lval
= get_arg_value(event
, arg
->num
.left
, record
);
1690 rval
= get_arg_value(event
, arg
->num
.right
, record
);
1692 switch (arg
->num
.type
) {
1694 return lval
== rval
;
1697 return lval
!= rval
;
1706 return lval
>= rval
;
1709 return lval
<= rval
;
1717 static const char *get_field_str(struct filter_arg
*arg
, struct pevent_record
*record
)
1719 struct event_format
*event
;
1720 struct pevent
*pevent
;
1721 unsigned long long addr
;
1722 const char *val
= NULL
;
1725 /* If the field is not a string convert it */
1726 if (arg
->str
.field
->flags
& FIELD_IS_STRING
) {
1727 val
= record
->data
+ arg
->str
.field
->offset
;
1730 * We need to copy the data since we can't be sure the field
1731 * is null terminated.
1733 if (*(val
+ arg
->str
.field
->size
- 1)) {
1735 memcpy(arg
->str
.buffer
, val
, arg
->str
.field
->size
);
1736 /* the buffer is already NULL terminated */
1737 val
= arg
->str
.buffer
;
1741 event
= arg
->str
.field
->event
;
1742 pevent
= event
->pevent
;
1743 addr
= get_value(event
, arg
->str
.field
, record
);
1745 if (arg
->str
.field
->flags
& (FIELD_IS_POINTER
| FIELD_IS_LONG
))
1746 /* convert to a kernel symbol */
1747 val
= pevent_find_function(pevent
, addr
);
1750 /* just use the hex of the string name */
1751 snprintf(hex
, 64, "0x%llx", addr
);
1759 static int test_str(struct event_format
*event
,
1760 struct filter_arg
*arg
, struct pevent_record
*record
)
1764 if (arg
->str
.field
== &comm
)
1765 val
= get_comm(event
, record
);
1767 val
= get_field_str(arg
, record
);
1769 switch (arg
->str
.type
) {
1770 case FILTER_CMP_MATCH
:
1771 return strcmp(val
, arg
->str
.val
) == 0;
1773 case FILTER_CMP_NOT_MATCH
:
1774 return strcmp(val
, arg
->str
.val
) != 0;
1776 case FILTER_CMP_REGEX
:
1777 /* Returns zero on match */
1778 return !regexec(&arg
->str
.reg
, val
, 0, NULL
, 0);
1780 case FILTER_CMP_NOT_REGEX
:
1781 return regexec(&arg
->str
.reg
, val
, 0, NULL
, 0);
1789 static int test_op(struct event_format
*event
,
1790 struct filter_arg
*arg
, struct pevent_record
*record
)
1792 switch (arg
->op
.type
) {
1794 return test_filter(event
, arg
->op
.left
, record
) &&
1795 test_filter(event
, arg
->op
.right
, record
);
1798 return test_filter(event
, arg
->op
.left
, record
) ||
1799 test_filter(event
, arg
->op
.right
, record
);
1802 return !test_filter(event
, arg
->op
.right
, record
);
1810 static int test_filter(struct event_format
*event
,
1811 struct filter_arg
*arg
, struct pevent_record
*record
)
1813 switch (arg
->type
) {
1814 case FILTER_ARG_BOOLEAN
:
1816 return arg
->boolean
.value
;
1819 return test_op(event
, arg
, record
);
1821 case FILTER_ARG_NUM
:
1822 return test_num(event
, arg
, record
);
1824 case FILTER_ARG_STR
:
1825 return test_str(event
, arg
, record
);
1827 case FILTER_ARG_EXP
:
1828 case FILTER_ARG_VALUE
:
1829 case FILTER_ARG_FIELD
:
1831 * Expressions, fields and values evaluate
1832 * to true if they return non zero
1834 return !!get_arg_value(event
, arg
, record
);
1844 * pevent_event_filtered - return true if event has filter
1845 * @filter: filter struct with filter information
1846 * @event_id: event id to test if filter exists
1848 * Returns 1 if filter found for @event_id
1851 int pevent_event_filtered(struct event_filter
*filter
,
1854 struct filter_type
*filter_type
;
1856 if (!filter
->filters
)
1859 filter_type
= find_filter_type(filter
, event_id
);
1861 return filter_type
? 1 : 0;
1865 * pevent_filter_match - test if a record matches a filter
1866 * @filter: filter struct with filter information
1867 * @record: the record to test against the filter
1870 * 1 - filter found for event and @record matches
1871 * 0 - filter found for event and @record does not match
1872 * -1 - no filter found for @record's event
1873 * -2 - if no filters exist
1875 int pevent_filter_match(struct event_filter
*filter
,
1876 struct pevent_record
*record
)
1878 struct pevent
*pevent
= filter
->pevent
;
1879 struct filter_type
*filter_type
;
1882 if (!filter
->filters
)
1885 event_id
= pevent_data_type(pevent
, record
);
1887 filter_type
= find_filter_type(filter
, event_id
);
1890 return FILTER_NOEXIST
;
1892 return test_filter(filter_type
->event
, filter_type
->filter
, record
) ?
1893 FILTER_MATCH
: FILTER_MISS
;
1896 static char *op_to_str(struct event_filter
*filter
, struct filter_arg
*arg
)
1907 switch (arg
->op
.type
) {
1915 left
= arg_to_str(filter
, arg
->op
.left
);
1916 right
= arg_to_str(filter
, arg
->op
.right
);
1917 if (!left
|| !right
)
1920 /* Try to consolidate boolean values */
1921 if (strcmp(left
, "TRUE") == 0)
1923 else if (strcmp(left
, "FALSE") == 0)
1926 if (strcmp(right
, "TRUE") == 0)
1928 else if (strcmp(right
, "FALSE") == 0)
1931 if (left_val
>= 0) {
1932 if ((arg
->op
.type
== FILTER_OP_AND
&& !left_val
) ||
1933 (arg
->op
.type
== FILTER_OP_OR
&& left_val
)) {
1934 /* Just return left value */
1939 if (right_val
>= 0) {
1940 /* just evaluate this. */
1942 switch (arg
->op
.type
) {
1944 val
= left_val
&& right_val
;
1947 val
= left_val
|| right_val
;
1952 str
= malloc_or_die(6);
1954 strcpy(str
, "TRUE");
1956 strcpy(str
, "FALSE");
1960 if (right_val
>= 0) {
1961 if ((arg
->op
.type
== FILTER_OP_AND
&& !right_val
) ||
1962 (arg
->op
.type
== FILTER_OP_OR
&& right_val
)) {
1963 /* Just return right value */
1968 /* The right value is meaningless */
1974 len
= strlen(left
) + strlen(right
) + strlen(op
) + 10;
1975 str
= malloc_or_die(len
);
1976 snprintf(str
, len
, "(%s) %s (%s)",
1982 right
= arg_to_str(filter
, arg
->op
.right
);
1986 /* See if we can consolidate */
1987 if (strcmp(right
, "TRUE") == 0)
1989 else if (strcmp(right
, "FALSE") == 0)
1991 if (right_val
>= 0) {
1992 /* just return the opposite */
1993 str
= malloc_or_die(6);
1995 strcpy(str
, "FALSE");
1997 strcpy(str
, "TRUE");
2000 len
= strlen(right
) + strlen(op
) + 3;
2001 str
= malloc_or_die(len
);
2002 snprintf(str
, len
, "%s(%s)", op
, right
);
2014 static char *val_to_str(struct event_filter
*filter
, struct filter_arg
*arg
)
2018 str
= malloc_or_die(30);
2020 snprintf(str
, 30, "%lld", arg
->value
.val
);
2025 static char *field_to_str(struct event_filter
*filter
, struct filter_arg
*arg
)
2027 return strdup(arg
->field
.field
->name
);
2030 static char *exp_to_str(struct event_filter
*filter
, struct filter_arg
*arg
)
2038 lstr
= arg_to_str(filter
, arg
->exp
.left
);
2039 rstr
= arg_to_str(filter
, arg
->exp
.right
);
2043 switch (arg
->exp
.type
) {
2044 case FILTER_EXP_ADD
:
2047 case FILTER_EXP_SUB
:
2050 case FILTER_EXP_MUL
:
2053 case FILTER_EXP_DIV
:
2056 case FILTER_EXP_MOD
:
2059 case FILTER_EXP_RSHIFT
:
2062 case FILTER_EXP_LSHIFT
:
2065 case FILTER_EXP_AND
:
2071 case FILTER_EXP_XOR
:
2078 len
= strlen(op
) + strlen(lstr
) + strlen(rstr
) + 4;
2079 str
= malloc_or_die(len
);
2080 snprintf(str
, len
, "%s %s %s", lstr
, op
, rstr
);
2088 static char *num_to_str(struct event_filter
*filter
, struct filter_arg
*arg
)
2096 lstr
= arg_to_str(filter
, arg
->num
.left
);
2097 rstr
= arg_to_str(filter
, arg
->num
.right
);
2101 switch (arg
->num
.type
) {
2125 len
= strlen(lstr
) + strlen(op
) + strlen(rstr
) + 4;
2126 str
= malloc_or_die(len
);
2127 sprintf(str
, "%s %s %s", lstr
, op
, rstr
);
2142 static char *str_to_str(struct event_filter
*filter
, struct filter_arg
*arg
)
2148 switch (arg
->str
.type
) {
2149 case FILTER_CMP_MATCH
:
2152 case FILTER_CMP_NOT_MATCH
:
2156 case FILTER_CMP_REGEX
:
2160 case FILTER_CMP_NOT_REGEX
:
2164 len
= strlen(arg
->str
.field
->name
) + strlen(op
) +
2165 strlen(arg
->str
.val
) + 6;
2166 str
= malloc_or_die(len
);
2167 snprintf(str
, len
, "%s %s \"%s\"",
2168 arg
->str
.field
->name
,
2179 static char *arg_to_str(struct event_filter
*filter
, struct filter_arg
*arg
)
2183 switch (arg
->type
) {
2184 case FILTER_ARG_BOOLEAN
:
2185 str
= malloc_or_die(6);
2186 if (arg
->boolean
.value
)
2187 strcpy(str
, "TRUE");
2189 strcpy(str
, "FALSE");
2193 return op_to_str(filter
, arg
);
2195 case FILTER_ARG_NUM
:
2196 return num_to_str(filter
, arg
);
2198 case FILTER_ARG_STR
:
2199 return str_to_str(filter
, arg
);
2201 case FILTER_ARG_VALUE
:
2202 return val_to_str(filter
, arg
);
2204 case FILTER_ARG_FIELD
:
2205 return field_to_str(filter
, arg
);
2207 case FILTER_ARG_EXP
:
2208 return exp_to_str(filter
, arg
);
2218 * pevent_filter_make_string - return a string showing the filter
2219 * @filter: filter struct with filter information
2220 * @event_id: the event id to return the filter string with
2222 * Returns a string that displays the filter contents.
2223 * This string must be freed with free(str).
2224 * NULL is returned if no filter is found.
2227 pevent_filter_make_string(struct event_filter
*filter
, int event_id
)
2229 struct filter_type
*filter_type
;
2231 if (!filter
->filters
)
2234 filter_type
= find_filter_type(filter
, event_id
);
2239 return arg_to_str(filter
, filter_type
->filter
);
2243 * pevent_filter_compare - compare two filters and return if they are the same
2244 * @filter1: Filter to compare with @filter2
2245 * @filter2: Filter to compare with @filter1
2248 * 1 if the two filters hold the same content.
2251 int pevent_filter_compare(struct event_filter
*filter1
, struct event_filter
*filter2
)
2253 struct filter_type
*filter_type1
;
2254 struct filter_type
*filter_type2
;
2259 /* Do the easy checks first */
2260 if (filter1
->filters
!= filter2
->filters
)
2262 if (!filter1
->filters
&& !filter2
->filters
)
2266 * Now take a look at each of the events to see if they have the same
2269 for (i
= 0; i
< filter1
->filters
; i
++) {
2270 filter_type1
= &filter1
->event_filters
[i
];
2271 filter_type2
= find_filter_type(filter2
, filter_type1
->event_id
);
2274 if (filter_type1
->filter
->type
!= filter_type2
->filter
->type
)
2276 switch (filter_type1
->filter
->type
) {
2277 case FILTER_TRIVIAL_FALSE
:
2278 case FILTER_TRIVIAL_TRUE
:
2279 /* trivial types just need the type compared */
2284 /* The best way to compare complex filters is with strings */
2285 str1
= arg_to_str(filter1
, filter_type1
->filter
);
2286 str2
= arg_to_str(filter2
, filter_type2
->filter
);
2288 result
= strcmp(str1
, str2
) != 0;
2290 /* bail out if allocation fails */
2299 if (i
< filter1
->filters
)