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(MAX_ERR_STR_SIZE + (len*2) + 3);
62 * Maybe it's due to len is too long.
63 * Retry without the input buffer part.
67 error = malloc(MAX_ERR_STR_SIZE);
78 for (i = 1; i < len && i < index; i++)
81 error[len + i + 1] = '\n';
86 vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap);
92 static void free_token(char *token)
94 pevent_free_token(token);
97 static enum event_type read_token(char **tok)
104 type = pevent_read_token(&token);
105 } while (type == EVENT_NEWLINE || type == EVENT_SPACE);
107 /* If token is = or ! check to see if the next char is ~ */
109 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
110 pevent_peek_char() == '~') {
117 sprintf(*tok, "%c%c", *token, '~');
119 /* Now remove the '~' from the buffer */
120 pevent_read_token(&token);
128 static int filter_cmp(const void *a, const void *b)
130 const struct filter_type *ea = a;
131 const struct filter_type *eb = b;
133 if (ea->event_id < eb->event_id)
136 if (ea->event_id > eb->event_id)
142 static struct filter_type *
143 find_filter_type(struct event_filter *filter, int id)
145 struct filter_type *filter_type;
146 struct filter_type key;
150 filter_type = bsearch(&key, filter->event_filters,
152 sizeof(*filter->event_filters),
158 static struct filter_type *
159 add_filter_type(struct event_filter *filter, int id)
161 struct filter_type *filter_type;
164 filter_type = find_filter_type(filter, id);
168 filter_type = realloc(filter->event_filters,
169 sizeof(*filter->event_filters) *
170 (filter->filters + 1));
174 filter->event_filters = filter_type;
176 for (i = 0; i < filter->filters; i++) {
177 if (filter->event_filters[i].event_id > id)
181 if (i < filter->filters)
182 memmove(&filter->event_filters[i+1],
183 &filter->event_filters[i],
184 sizeof(*filter->event_filters) *
185 (filter->filters - i));
187 filter_type = &filter->event_filters[i];
188 filter_type->event_id = id;
189 filter_type->event = pevent_find_event(filter->pevent, id);
190 filter_type->filter = NULL;
198 * pevent_filter_alloc - create a new event filter
199 * @pevent: The pevent that this filter is associated with
201 struct event_filter *pevent_filter_alloc(struct pevent *pevent)
203 struct event_filter *filter;
205 filter = malloc(sizeof(*filter));
209 memset(filter, 0, sizeof(*filter));
210 filter->pevent = pevent;
216 static struct filter_arg *allocate_arg(void)
218 return calloc(1, sizeof(struct filter_arg));
221 static void free_arg(struct filter_arg *arg)
227 case FILTER_ARG_NONE:
228 case FILTER_ARG_BOOLEAN:
232 free_arg(arg->num.left);
233 free_arg(arg->num.right);
237 free_arg(arg->exp.left);
238 free_arg(arg->exp.right);
243 regfree(&arg->str.reg);
244 free(arg->str.buffer);
247 case FILTER_ARG_VALUE:
248 if (arg->value.type == FILTER_STRING ||
249 arg->value.type == FILTER_CHAR)
250 free(arg->value.str);
254 free_arg(arg->op.left);
255 free_arg(arg->op.right);
263 static int add_event(struct event_list **events,
264 struct event_format *event)
266 struct event_list *list;
268 list = malloc(sizeof(*list));
272 list->next = *events;
278 static int event_match(struct event_format *event,
279 regex_t *sreg, regex_t *ereg)
282 return !regexec(sreg, event->system, 0, NULL, 0) &&
283 !regexec(ereg, event->name, 0, NULL, 0);
286 return !regexec(ereg, event->system, 0, NULL, 0) ||
287 !regexec(ereg, event->name, 0, NULL, 0);
290 static enum pevent_errno
291 find_event(struct pevent *pevent, struct event_list **events,
292 char *sys_name, char *event_name)
294 struct event_format *event;
304 /* if no name is given, then swap sys and name */
305 event_name = sys_name;
309 reg = malloc(strlen(event_name) + 3);
311 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
313 sprintf(reg, "^%s$", event_name);
315 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
319 return PEVENT_ERRNO__INVALID_EVENT_NAME;
322 reg = malloc(strlen(sys_name) + 3);
325 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
328 sprintf(reg, "^%s$", sys_name);
329 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
333 return PEVENT_ERRNO__INVALID_EVENT_NAME;
337 for (i = 0; i < pevent->nr_events; i++) {
338 event = pevent->events[i];
339 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
341 if (add_event(events, event) < 0) {
353 return PEVENT_ERRNO__EVENT_NOT_FOUND;
355 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
360 static void free_events(struct event_list *events)
362 struct event_list *event;
366 events = events->next;
371 static enum pevent_errno
372 create_arg_item(struct event_format *event, const char *token,
373 enum event_type type, struct filter_arg **parg, char **error_str)
375 struct format_field *field;
376 struct filter_arg *arg;
378 arg = allocate_arg();
380 show_error(error_str, "failed to allocate filter arg");
381 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
388 arg->type = FILTER_ARG_VALUE;
390 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
391 arg->value.str = strdup(token);
392 if (!arg->value.str) {
394 show_error(error_str, "failed to allocate string filter arg");
395 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
399 /* if it is a number, then convert it */
400 if (isdigit(token[0])) {
401 arg->type = FILTER_ARG_VALUE;
402 arg->value.type = FILTER_NUMBER;
403 arg->value.val = strtoull(token, NULL, 0);
406 /* Consider this a field */
407 field = pevent_find_any_field(event, token);
409 if (strcmp(token, COMM) != 0) {
410 /* not a field, Make it false */
411 arg->type = FILTER_ARG_BOOLEAN;
412 arg->boolean.value = FILTER_FALSE;
415 /* If token is 'COMM' then it is special */
418 arg->type = FILTER_ARG_FIELD;
419 arg->field.field = field;
423 show_error(error_str, "expected a value but found %s", token);
424 return PEVENT_ERRNO__UNEXPECTED_TYPE;
430 static struct filter_arg *
431 create_arg_op(enum filter_op_type btype)
433 struct filter_arg *arg;
435 arg = allocate_arg();
439 arg->type = FILTER_ARG_OP;
440 arg->op.type = btype;
445 static struct filter_arg *
446 create_arg_exp(enum filter_exp_type etype)
448 struct filter_arg *arg;
450 arg = allocate_arg();
454 arg->type = FILTER_ARG_EXP;
455 arg->op.type = etype;
460 static struct filter_arg *
461 create_arg_cmp(enum filter_exp_type etype)
463 struct filter_arg *arg;
465 arg = allocate_arg();
469 /* Use NUM and change if necessary */
470 arg->type = FILTER_ARG_NUM;
471 arg->op.type = etype;
476 static enum pevent_errno
477 add_right(struct filter_arg *op, struct filter_arg *arg, char **error_str)
479 struct filter_arg *left;
501 * The arg must be num, str, or field
504 case FILTER_ARG_VALUE:
505 case FILTER_ARG_FIELD:
508 show_error(error_str, "Illegal rvalue");
509 return PEVENT_ERRNO__ILLEGAL_RVALUE;
513 * Depending on the type, we may need to
514 * convert this to a string or regex.
516 switch (arg->value.type) {
519 * A char should be converted to number if
520 * the string is 1 byte, and the compare
523 if (strlen(arg->value.str) == 1 &&
524 op->num.type != FILTER_CMP_REGEX &&
525 op->num.type != FILTER_CMP_NOT_REGEX) {
526 arg->value.type = FILTER_NUMBER;
532 /* convert op to a string arg */
533 op_type = op->num.type;
535 str = arg->value.str;
537 /* reset the op for the new field */
538 memset(op, 0, sizeof(*op));
541 * If left arg was a field not found then
542 * NULL the entire op.
544 if (left->type == FILTER_ARG_BOOLEAN) {
547 op->type = FILTER_ARG_BOOLEAN;
548 op->boolean.value = FILTER_FALSE;
552 /* Left arg must be a field */
553 if (left->type != FILTER_ARG_FIELD) {
554 show_error(error_str,
555 "Illegal lvalue for string comparison");
556 return PEVENT_ERRNO__ILLEGAL_LVALUE;
559 /* Make sure this is a valid string compare */
562 op_type = FILTER_CMP_MATCH;
565 op_type = FILTER_CMP_NOT_MATCH;
568 case FILTER_CMP_REGEX:
569 case FILTER_CMP_NOT_REGEX:
570 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB);
572 show_error(error_str,
573 "RegEx '%s' did not compute",
575 return PEVENT_ERRNO__INVALID_REGEX;
579 show_error(error_str,
580 "Illegal comparison for string");
581 return PEVENT_ERRNO__ILLEGAL_STRING_CMP;
584 op->type = FILTER_ARG_STR;
585 op->str.type = op_type;
586 op->str.field = left->field.field;
587 op->str.val = strdup(str);
589 show_error(error_str, "Failed to allocate string filter");
590 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
593 * Need a buffer to copy data for tests
595 op->str.buffer = malloc(op->str.field->size + 1);
596 if (!op->str.buffer) {
597 show_error(error_str, "Failed to allocate string filter");
598 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
600 /* Null terminate this buffer */
601 op->str.buffer[op->str.field->size] = 0;
603 /* We no longer have left or right args */
612 switch (op->num.type) {
613 case FILTER_CMP_REGEX:
614 case FILTER_CMP_NOT_REGEX:
615 show_error(error_str,
616 "Op not allowed with integers");
617 return PEVENT_ERRNO__ILLEGAL_INTEGER_CMP;
623 /* numeric compare */
637 show_error(error_str, "Syntax error");
638 return PEVENT_ERRNO__SYNTAX_ERROR;
641 static struct filter_arg *
642 rotate_op_right(struct filter_arg *a, struct filter_arg *b)
644 struct filter_arg *arg;
651 static enum pevent_errno add_left(struct filter_arg *op, struct filter_arg *arg)
655 if (arg->type == FILTER_ARG_OP)
656 arg = rotate_op_right(arg, op);
664 if (arg->type == FILTER_ARG_OP)
665 arg = rotate_op_right(arg, op);
667 /* left arg of compares must be a field */
668 if (arg->type != FILTER_ARG_FIELD &&
669 arg->type != FILTER_ARG_BOOLEAN)
670 return PEVENT_ERRNO__INVALID_ARG_TYPE;
674 return PEVENT_ERRNO__INVALID_ARG_TYPE;
687 static enum op_type process_op(const char *token,
688 enum filter_op_type *btype,
689 enum filter_cmp_type *ctype,
690 enum filter_exp_type *etype)
692 *btype = FILTER_OP_NOT;
693 *etype = FILTER_EXP_NONE;
694 *ctype = FILTER_CMP_NONE;
696 if (strcmp(token, "&&") == 0)
697 *btype = FILTER_OP_AND;
698 else if (strcmp(token, "||") == 0)
699 *btype = FILTER_OP_OR;
700 else if (strcmp(token, "!") == 0)
703 if (*btype != FILTER_OP_NOT)
706 /* Check for value expressions */
707 if (strcmp(token, "+") == 0) {
708 *etype = FILTER_EXP_ADD;
709 } else if (strcmp(token, "-") == 0) {
710 *etype = FILTER_EXP_SUB;
711 } else if (strcmp(token, "*") == 0) {
712 *etype = FILTER_EXP_MUL;
713 } else if (strcmp(token, "/") == 0) {
714 *etype = FILTER_EXP_DIV;
715 } else if (strcmp(token, "%") == 0) {
716 *etype = FILTER_EXP_MOD;
717 } else if (strcmp(token, ">>") == 0) {
718 *etype = FILTER_EXP_RSHIFT;
719 } else if (strcmp(token, "<<") == 0) {
720 *etype = FILTER_EXP_LSHIFT;
721 } else if (strcmp(token, "&") == 0) {
722 *etype = FILTER_EXP_AND;
723 } else if (strcmp(token, "|") == 0) {
724 *etype = FILTER_EXP_OR;
725 } else if (strcmp(token, "^") == 0) {
726 *etype = FILTER_EXP_XOR;
727 } else if (strcmp(token, "~") == 0)
728 *etype = FILTER_EXP_NOT;
730 if (*etype != FILTER_EXP_NONE)
733 /* Check for compares */
734 if (strcmp(token, "==") == 0)
735 *ctype = FILTER_CMP_EQ;
736 else if (strcmp(token, "!=") == 0)
737 *ctype = FILTER_CMP_NE;
738 else if (strcmp(token, "<") == 0)
739 *ctype = FILTER_CMP_LT;
740 else if (strcmp(token, ">") == 0)
741 *ctype = FILTER_CMP_GT;
742 else if (strcmp(token, "<=") == 0)
743 *ctype = FILTER_CMP_LE;
744 else if (strcmp(token, ">=") == 0)
745 *ctype = FILTER_CMP_GE;
746 else if (strcmp(token, "=~") == 0)
747 *ctype = FILTER_CMP_REGEX;
748 else if (strcmp(token, "!~") == 0)
749 *ctype = FILTER_CMP_NOT_REGEX;
756 static int check_op_done(struct filter_arg *arg)
760 return arg->exp.right != NULL;
763 return arg->op.right != NULL;
766 return arg->num.right != NULL;
769 /* A string conversion is always done */
772 case FILTER_ARG_BOOLEAN:
773 /* field not found, is ok */
787 static enum pevent_errno
788 reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
789 struct filter_arg *arg, char **error_str)
791 struct filter_arg *other_child;
792 struct filter_arg **ptr;
794 if (parent->type != FILTER_ARG_OP &&
795 arg->type != FILTER_ARG_OP) {
796 show_error(error_str, "can not reparent other than OP");
797 return PEVENT_ERRNO__REPARENT_NOT_OP;
800 /* Get the sibling */
801 if (old_child->op.right == arg) {
802 ptr = &old_child->op.right;
803 other_child = old_child->op.left;
804 } else if (old_child->op.left == arg) {
805 ptr = &old_child->op.left;
806 other_child = old_child->op.right;
808 show_error(error_str, "Error in reparent op, find other child");
809 return PEVENT_ERRNO__REPARENT_FAILED;
812 /* Detach arg from old_child */
816 if (parent == old_child) {
817 free_arg(other_child);
819 /* Free arg without recussion */
824 if (parent->op.right == old_child)
825 ptr = &parent->op.right;
826 else if (parent->op.left == old_child)
827 ptr = &parent->op.left;
829 show_error(error_str, "Error in reparent op");
830 return PEVENT_ERRNO__REPARENT_FAILED;
839 /* Returns either filter_vals (success) or pevent_errno (failfure) */
840 static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
848 case FILTER_ARG_BOOLEAN:
849 return FILTER_VAL_FALSE + arg->boolean.value;
853 case FILTER_ARG_VALUE:
854 case FILTER_ARG_FIELD:
855 return FILTER_VAL_NORM;
858 lval = test_arg(arg, arg->exp.left, error_str);
859 if (lval != FILTER_VAL_NORM)
861 rval = test_arg(arg, arg->exp.right, error_str);
862 if (rval != FILTER_VAL_NORM)
864 return FILTER_VAL_NORM;
867 lval = test_arg(arg, arg->num.left, error_str);
868 if (lval != FILTER_VAL_NORM)
870 rval = test_arg(arg, arg->num.right, error_str);
871 if (rval != FILTER_VAL_NORM)
873 return FILTER_VAL_NORM;
876 if (arg->op.type != FILTER_OP_NOT) {
877 lval = test_arg(arg, arg->op.left, error_str);
879 case FILTER_VAL_NORM:
881 case FILTER_VAL_TRUE:
882 if (arg->op.type == FILTER_OP_OR)
883 return FILTER_VAL_TRUE;
884 rval = test_arg(arg, arg->op.right, error_str);
885 if (rval != FILTER_VAL_NORM)
888 return reparent_op_arg(parent, arg, arg->op.right,
891 case FILTER_VAL_FALSE:
892 if (arg->op.type == FILTER_OP_AND)
893 return FILTER_VAL_FALSE;
894 rval = test_arg(arg, arg->op.right, error_str);
895 if (rval != FILTER_VAL_NORM)
898 return reparent_op_arg(parent, arg, arg->op.right,
906 rval = test_arg(arg, arg->op.right, error_str);
908 case FILTER_VAL_NORM:
912 case FILTER_VAL_TRUE:
913 if (arg->op.type == FILTER_OP_OR)
914 return FILTER_VAL_TRUE;
915 if (arg->op.type == FILTER_OP_NOT)
916 return FILTER_VAL_FALSE;
918 return reparent_op_arg(parent, arg, arg->op.left,
921 case FILTER_VAL_FALSE:
922 if (arg->op.type == FILTER_OP_AND)
923 return FILTER_VAL_FALSE;
924 if (arg->op.type == FILTER_OP_NOT)
925 return FILTER_VAL_TRUE;
927 return reparent_op_arg(parent, arg, arg->op.left,
933 show_error(error_str, "bad arg in filter tree");
934 return PEVENT_ERRNO__BAD_FILTER_ARG;
936 return FILTER_VAL_NORM;
939 /* Remove any unknown event fields */
940 static int collapse_tree(struct filter_arg *arg,
941 struct filter_arg **arg_collapsed, char **error_str)
945 ret = test_arg(arg, arg, error_str);
947 case FILTER_VAL_NORM:
950 case FILTER_VAL_TRUE:
951 case FILTER_VAL_FALSE:
953 arg = allocate_arg();
955 arg->type = FILTER_ARG_BOOLEAN;
956 arg->boolean.value = ret == FILTER_VAL_TRUE;
958 show_error(error_str, "Failed to allocate filter arg");
959 ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
964 /* test_arg() already set the error_str */
970 *arg_collapsed = arg;
974 static enum pevent_errno
975 process_filter(struct event_format *event, struct filter_arg **parg,
976 char **error_str, int not)
978 enum event_type type;
980 struct filter_arg *current_op = NULL;
981 struct filter_arg *current_exp = NULL;
982 struct filter_arg *left_item = NULL;
983 struct filter_arg *arg = NULL;
984 enum op_type op_type;
985 enum filter_op_type btype;
986 enum filter_exp_type etype;
987 enum filter_cmp_type ctype;
988 enum pevent_errno ret;
994 type = read_token(&token);
999 ret = create_arg_item(event, token, type, &arg, error_str);
1004 else if (current_exp) {
1005 ret = add_right(current_exp, arg, error_str);
1009 /* Not's only one one expression */
1015 *parg = current_exp;
1024 if (*token == ',') {
1025 show_error(error_str, "Illegal token ','");
1026 ret = PEVENT_ERRNO__ILLEGAL_TOKEN;
1030 if (*token == '(') {
1032 show_error(error_str,
1033 "Open paren can not come after item");
1034 ret = PEVENT_ERRNO__INVALID_PAREN;
1038 show_error(error_str,
1039 "Open paren can not come after expression");
1040 ret = PEVENT_ERRNO__INVALID_PAREN;
1044 ret = process_filter(event, &arg, error_str, 0);
1045 if (ret != PEVENT_ERRNO__UNBALANCED_PAREN) {
1047 show_error(error_str,
1048 "Unbalanced number of '('");
1049 ret = PEVENT_ERRNO__UNBALANCED_PAREN;
1055 /* A not wants just one expression */
1064 ret = add_right(current_op, arg, error_str);
1072 if (!current_op && !current_exp)
1075 /* Make sure everything is finished at this level */
1076 if (current_exp && !check_op_done(current_exp))
1078 if (current_op && !check_op_done(current_op))
1084 *parg = current_exp;
1085 return PEVENT_ERRNO__UNBALANCED_PAREN;
1090 op_type = process_op(token, &btype, &ctype, &etype);
1092 /* All expect a left arg except for NOT */
1095 /* Logic ops need a left expression */
1096 if (!current_exp && !current_op)
1100 /* logic only processes ops and exp */
1110 show_error(error_str,
1111 "Unknown op token %s", token);
1112 ret = PEVENT_ERRNO__UNKNOWN_TOKEN;
1119 arg = create_arg_op(btype);
1123 ret = add_left(arg, current_op);
1125 ret = add_left(arg, current_exp);
1131 arg = create_arg_op(btype);
1135 ret = add_right(current_op, arg, error_str);
1139 ret = process_filter(event, &arg, error_str, 1);
1142 ret = add_right(current_exp, arg, error_str);
1149 if (op_type == OP_EXP)
1150 arg = create_arg_exp(etype);
1152 arg = create_arg_cmp(ctype);
1157 ret = add_right(current_op, arg, error_str);
1160 ret = add_left(arg, left_item);
1181 } while (type != EVENT_NONE);
1183 if (!current_op && !current_exp)
1187 current_op = current_exp;
1189 ret = collapse_tree(current_op, parg, error_str);
1198 show_error(error_str, "failed to allocate filter arg");
1199 ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
1202 show_error(error_str, "Syntax error");
1203 ret = PEVENT_ERRNO__SYNTAX_ERROR;
1205 free_arg(current_op);
1206 free_arg(current_exp);
1212 static enum pevent_errno
1213 process_event(struct event_format *event, const char *filter_str,
1214 struct filter_arg **parg, char **error_str)
1218 pevent_buffer_init(filter_str, strlen(filter_str));
1220 ret = process_filter(event, parg, error_str, 0);
1224 /* If parg is NULL, then make it into FALSE */
1226 *parg = allocate_arg();
1228 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
1230 (*parg)->type = FILTER_ARG_BOOLEAN;
1231 (*parg)->boolean.value = FILTER_FALSE;
1237 static enum pevent_errno
1238 filter_event(struct event_filter *filter, struct event_format *event,
1239 const char *filter_str, char **error_str)
1241 struct filter_type *filter_type;
1242 struct filter_arg *arg;
1243 enum pevent_errno ret;
1246 ret = process_event(event, filter_str, &arg, error_str);
1251 /* just add a TRUE arg */
1252 arg = allocate_arg();
1254 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
1256 arg->type = FILTER_ARG_BOOLEAN;
1257 arg->boolean.value = FILTER_TRUE;
1260 filter_type = add_filter_type(filter, event->id);
1261 if (filter_type == NULL)
1262 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
1264 if (filter_type->filter)
1265 free_arg(filter_type->filter);
1266 filter_type->filter = arg;
1272 * pevent_filter_add_filter_str - add a new filter
1273 * @filter: the event filter to add to
1274 * @filter_str: the filter string that contains the filter
1276 * Returns 0 if the filter was successfully added or a
1277 * negative error code.
1279 enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
1280 const char *filter_str)
1282 struct pevent *pevent = filter->pevent;
1283 struct event_list *event;
1284 struct event_list *events = NULL;
1285 const char *filter_start;
1286 const char *next_event;
1288 char *event_name = NULL;
1289 char *sys_name = NULL;
1291 enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */
1294 char *error_str = NULL;
1296 /* clear buffer to reset show error */
1297 pevent_buffer_init("", 0);
1299 filter_start = strchr(filter_str, ':');
1301 len = filter_start - filter_str;
1303 len = strlen(filter_str);
1306 next_event = strchr(filter_str, ',');
1308 (!filter_start || next_event < filter_start))
1309 len = next_event - filter_str;
1310 else if (filter_start)
1311 len = filter_start - filter_str;
1313 len = strlen(filter_str);
1315 this_event = malloc(len + 1);
1316 if (this_event == NULL) {
1317 /* This can only happen when events is NULL, but still */
1318 free_events(events);
1319 return PEVENT_ERRNO__MEM_ALLOC_FAILED;
1321 memcpy(this_event, filter_str, len);
1322 this_event[len] = 0;
1327 filter_str = next_event;
1329 sys_name = strtok_r(this_event, "/", &sp);
1330 event_name = strtok_r(NULL, "/", &sp);
1333 /* This can only happen when events is NULL, but still */
1334 free_events(events);
1336 return PEVENT_ERRNO__FILTER_NOT_FOUND;
1339 /* Find this event */
1340 ret = find_event(pevent, &events, strim(sys_name), strim(event_name));
1342 free_events(events);
1347 } while (filter_str);
1353 /* filter starts here */
1354 for (event = events; event; event = event->next) {
1355 ret = filter_event(filter, event->event, filter_start,
1357 /* Failures are returned if a parse error happened */
1361 if (ret >= 0 && pevent->test_filters) {
1363 test = pevent_filter_make_string(filter, event->event->id);
1364 printf(" '%s: %s'\n", event->event->name, test);
1369 free_events(events);
1371 if (rtn >= 0 && pevent->test_filters)
1377 static void free_filter_type(struct filter_type *filter_type)
1379 free_arg(filter_type->filter);
1383 * pevent_filter_remove_event - remove a filter for an event
1384 * @filter: the event filter to remove from
1385 * @event_id: the event to remove a filter for
1387 * Removes the filter saved for an event defined by @event_id
1390 * Returns 1: if an event was removed
1391 * 0: if the event was not found
1393 int pevent_filter_remove_event(struct event_filter *filter,
1396 struct filter_type *filter_type;
1399 if (!filter->filters)
1402 filter_type = find_filter_type(filter, event_id);
1407 free_filter_type(filter_type);
1409 /* The filter_type points into the event_filters array */
1410 len = (unsigned long)(filter->event_filters + filter->filters) -
1411 (unsigned long)(filter_type + 1);
1413 memmove(filter_type, filter_type + 1, len);
1416 memset(&filter->event_filters[filter->filters], 0,
1417 sizeof(*filter_type));
1423 * pevent_filter_reset - clear all filters in a filter
1424 * @filter: the event filter to reset
1426 * Removes all filters from a filter and resets it.
1428 void pevent_filter_reset(struct event_filter *filter)
1432 for (i = 0; i < filter->filters; i++)
1433 free_filter_type(&filter->event_filters[i]);
1435 free(filter->event_filters);
1436 filter->filters = 0;
1437 filter->event_filters = NULL;
1440 void pevent_filter_free(struct event_filter *filter)
1442 pevent_unref(filter->pevent);
1444 pevent_filter_reset(filter);
1449 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg);
1451 static int copy_filter_type(struct event_filter *filter,
1452 struct event_filter *source,
1453 struct filter_type *filter_type)
1455 struct filter_arg *arg;
1456 struct event_format *event;
1461 /* Can't assume that the pevent's are the same */
1462 sys = filter_type->event->system;
1463 name = filter_type->event->name;
1464 event = pevent_find_event_by_name(filter->pevent, sys, name);
1468 str = arg_to_str(source, filter_type->filter);
1472 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
1473 /* Add trivial event */
1474 arg = allocate_arg();
1478 arg->type = 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)
1488 filter_type->filter = arg;
1494 filter_event(filter, event, str, NULL);
1501 * pevent_filter_copy - copy a filter using another filter
1502 * @dest - the filter to copy to
1503 * @source - the filter to copy from
1505 * Returns 0 on success and -1 if not all filters were copied
1507 int pevent_filter_copy(struct event_filter *dest, struct event_filter *source)
1512 pevent_filter_reset(dest);
1514 for (i = 0; i < source->filters; i++) {
1515 if (copy_filter_type(dest, source, &source->event_filters[i]))
1523 * pevent_update_trivial - update the trivial filters with the given filter
1524 * @dest - the filter to update
1525 * @source - the filter as the source of the update
1526 * @type - the type of trivial filter to update.
1528 * Scan dest for trivial events matching @type to replace with the source.
1530 * Returns 0 on success and -1 if there was a problem updating, but
1531 * events may have still been updated on error.
1533 int pevent_update_trivial(struct event_filter *dest, struct event_filter *source,
1534 enum filter_trivial_type type)
1536 struct pevent *src_pevent;
1537 struct pevent *dest_pevent;
1538 struct event_format *event;
1539 struct filter_type *filter_type;
1540 struct filter_arg *arg;
1544 src_pevent = source->pevent;
1545 dest_pevent = dest->pevent;
1547 /* Do nothing if either of the filters has nothing to filter */
1548 if (!dest->filters || !source->filters)
1551 for (i = 0; i < dest->filters; i++) {
1552 filter_type = &dest->event_filters[i];
1553 arg = filter_type->filter;
1554 if (arg->type != FILTER_ARG_BOOLEAN)
1556 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) ||
1557 (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE))
1560 event = filter_type->event;
1562 if (src_pevent != dest_pevent) {
1564 event = pevent_find_event_by_name(src_pevent,
1571 str = pevent_filter_make_string(source, event->id);
1575 /* Don't bother if the filter is trivial too */
1576 if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0)
1577 filter_event(dest, event, str, NULL);
1584 * pevent_filter_clear_trivial - clear TRUE and FALSE filters
1585 * @filter: the filter to remove trivial filters from
1586 * @type: remove only true, false, or both
1588 * Removes filters that only contain a TRUE or FALES boolean arg.
1590 * Returns 0 on success and -1 if there was a problem.
1592 int pevent_filter_clear_trivial(struct event_filter *filter,
1593 enum filter_trivial_type type)
1595 struct filter_type *filter_type;
1600 if (!filter->filters)
1604 * Two steps, first get all ids with trivial filters.
1605 * then remove those ids.
1607 for (i = 0; i < filter->filters; i++) {
1610 filter_type = &filter->event_filters[i];
1611 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1614 case FILTER_TRIVIAL_FALSE:
1615 if (filter_type->filter->boolean.value)
1617 case FILTER_TRIVIAL_TRUE:
1618 if (!filter_type->filter->boolean.value)
1624 new_ids = realloc(ids, sizeof(*ids) * (count + 1));
1631 ids[count++] = filter_type->event_id;
1637 for (i = 0; i < count; i++)
1638 pevent_filter_remove_event(filter, ids[i]);
1645 * pevent_filter_event_has_trivial - return true event contains trivial filter
1646 * @filter: the filter with the information
1647 * @event_id: the id of the event to test
1648 * @type: trivial type to test for (TRUE, FALSE, EITHER)
1650 * Returns 1 if the event contains a matching trivial type
1653 int pevent_filter_event_has_trivial(struct event_filter *filter,
1655 enum filter_trivial_type type)
1657 struct filter_type *filter_type;
1659 if (!filter->filters)
1662 filter_type = find_filter_type(filter, event_id);
1667 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1671 case FILTER_TRIVIAL_FALSE:
1672 return !filter_type->filter->boolean.value;
1674 case FILTER_TRIVIAL_TRUE:
1675 return filter_type->filter->boolean.value;
1681 static int test_filter(struct event_format *event, struct filter_arg *arg,
1682 struct pevent_record *record, enum pevent_errno *err);
1685 get_comm(struct event_format *event, struct pevent_record *record)
1690 pid = pevent_data_pid(event->pevent, record);
1691 comm = pevent_data_comm_from_pid(event->pevent, pid);
1695 static unsigned long long
1696 get_value(struct event_format *event,
1697 struct format_field *field, struct pevent_record *record)
1699 unsigned long long val;
1701 /* Handle our dummy "comm" field */
1702 if (field == &comm) {
1705 name = get_comm(event, record);
1706 return (unsigned long)name;
1709 pevent_read_number_field(field, record->data, &val);
1711 if (!(field->flags & FIELD_IS_SIGNED))
1714 switch (field->size) {
1722 return (long long)val;
1727 static unsigned long long
1728 get_arg_value(struct event_format *event, struct filter_arg *arg,
1729 struct pevent_record *record, enum pevent_errno *err);
1731 static unsigned long long
1732 get_exp_value(struct event_format *event, struct filter_arg *arg,
1733 struct pevent_record *record, enum pevent_errno *err)
1735 unsigned long long lval, rval;
1737 lval = get_arg_value(event, arg->exp.left, record, err);
1738 rval = get_arg_value(event, arg->exp.right, record, err);
1742 * There was an error, no need to process anymore.
1747 switch (arg->exp.type) {
1748 case FILTER_EXP_ADD:
1751 case FILTER_EXP_SUB:
1754 case FILTER_EXP_MUL:
1757 case FILTER_EXP_DIV:
1760 case FILTER_EXP_MOD:
1763 case FILTER_EXP_RSHIFT:
1764 return lval >> rval;
1766 case FILTER_EXP_LSHIFT:
1767 return lval << rval;
1769 case FILTER_EXP_AND:
1775 case FILTER_EXP_XOR:
1778 case FILTER_EXP_NOT:
1781 *err = PEVENT_ERRNO__INVALID_EXP_TYPE;
1786 static unsigned long long
1787 get_arg_value(struct event_format *event, struct filter_arg *arg,
1788 struct pevent_record *record, enum pevent_errno *err)
1790 switch (arg->type) {
1791 case FILTER_ARG_FIELD:
1792 return get_value(event, arg->field.field, record);
1794 case FILTER_ARG_VALUE:
1795 if (arg->value.type != FILTER_NUMBER) {
1797 *err = PEVENT_ERRNO__NOT_A_NUMBER;
1799 return arg->value.val;
1801 case FILTER_ARG_EXP:
1802 return get_exp_value(event, arg, record, err);
1806 *err = PEVENT_ERRNO__INVALID_ARG_TYPE;
1811 static int test_num(struct event_format *event, struct filter_arg *arg,
1812 struct pevent_record *record, enum pevent_errno *err)
1814 unsigned long long lval, rval;
1816 lval = get_arg_value(event, arg->num.left, record, err);
1817 rval = get_arg_value(event, arg->num.right, record, err);
1821 * There was an error, no need to process anymore.
1826 switch (arg->num.type) {
1828 return lval == rval;
1831 return lval != rval;
1840 return lval >= rval;
1843 return lval <= rval;
1847 *err = PEVENT_ERRNO__ILLEGAL_INTEGER_CMP;
1852 static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
1854 struct event_format *event;
1855 struct pevent *pevent;
1856 unsigned long long addr;
1857 const char *val = NULL;
1860 /* If the field is not a string convert it */
1861 if (arg->str.field->flags & FIELD_IS_STRING) {
1862 val = record->data + arg->str.field->offset;
1865 * We need to copy the data since we can't be sure the field
1866 * is null terminated.
1868 if (*(val + arg->str.field->size - 1)) {
1870 memcpy(arg->str.buffer, val, arg->str.field->size);
1871 /* the buffer is already NULL terminated */
1872 val = arg->str.buffer;
1876 event = arg->str.field->event;
1877 pevent = event->pevent;
1878 addr = get_value(event, arg->str.field, record);
1880 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
1881 /* convert to a kernel symbol */
1882 val = pevent_find_function(pevent, addr);
1885 /* just use the hex of the string name */
1886 snprintf(hex, 64, "0x%llx", addr);
1894 static int test_str(struct event_format *event, struct filter_arg *arg,
1895 struct pevent_record *record, enum pevent_errno *err)
1899 if (arg->str.field == &comm)
1900 val = get_comm(event, record);
1902 val = get_field_str(arg, record);
1904 switch (arg->str.type) {
1905 case FILTER_CMP_MATCH:
1906 return strcmp(val, arg->str.val) == 0;
1908 case FILTER_CMP_NOT_MATCH:
1909 return strcmp(val, arg->str.val) != 0;
1911 case FILTER_CMP_REGEX:
1912 /* Returns zero on match */
1913 return !regexec(&arg->str.reg, val, 0, NULL, 0);
1915 case FILTER_CMP_NOT_REGEX:
1916 return regexec(&arg->str.reg, val, 0, NULL, 0);
1920 *err = PEVENT_ERRNO__ILLEGAL_STRING_CMP;
1925 static int test_op(struct event_format *event, struct filter_arg *arg,
1926 struct pevent_record *record, enum pevent_errno *err)
1928 switch (arg->op.type) {
1930 return test_filter(event, arg->op.left, record, err) &&
1931 test_filter(event, arg->op.right, record, err);
1934 return test_filter(event, arg->op.left, record, err) ||
1935 test_filter(event, arg->op.right, record, err);
1938 return !test_filter(event, arg->op.right, record, err);
1942 *err = PEVENT_ERRNO__INVALID_OP_TYPE;
1947 static int test_filter(struct event_format *event, struct filter_arg *arg,
1948 struct pevent_record *record, enum pevent_errno *err)
1952 * There was an error, no need to process anymore.
1957 switch (arg->type) {
1958 case FILTER_ARG_BOOLEAN:
1960 return arg->boolean.value;
1963 return test_op(event, arg, record, err);
1965 case FILTER_ARG_NUM:
1966 return test_num(event, arg, record, err);
1968 case FILTER_ARG_STR:
1969 return test_str(event, arg, record, err);
1971 case FILTER_ARG_EXP:
1972 case FILTER_ARG_VALUE:
1973 case FILTER_ARG_FIELD:
1975 * Expressions, fields and values evaluate
1976 * to true if they return non zero
1978 return !!get_arg_value(event, arg, record, err);
1982 *err = PEVENT_ERRNO__INVALID_ARG_TYPE;
1988 * pevent_event_filtered - return true if event has filter
1989 * @filter: filter struct with filter information
1990 * @event_id: event id to test if filter exists
1992 * Returns 1 if filter found for @event_id
1995 int pevent_event_filtered(struct event_filter *filter, int event_id)
1997 struct filter_type *filter_type;
1999 if (!filter->filters)
2002 filter_type = find_filter_type(filter, event_id);
2004 return filter_type ? 1 : 0;
2008 * pevent_filter_match - test if a record matches a filter
2009 * @filter: filter struct with filter information
2010 * @record: the record to test against the filter
2012 * Returns: match result or error code (prefixed with PEVENT_ERRNO__)
2013 * FILTER_MATCH - filter found for event and @record matches
2014 * FILTER_MISS - filter found for event and @record does not match
2015 * FILTER_NOT_FOUND - no filter found for @record's event
2016 * NO_FILTER - if no filters exist
2017 * otherwise - error occurred during test
2019 enum pevent_errno pevent_filter_match(struct event_filter *filter,
2020 struct pevent_record *record)
2022 struct pevent *pevent = filter->pevent;
2023 struct filter_type *filter_type;
2026 enum pevent_errno err = 0;
2028 if (!filter->filters)
2029 return PEVENT_ERRNO__NO_FILTER;
2031 event_id = pevent_data_type(pevent, record);
2033 filter_type = find_filter_type(filter, event_id);
2035 return PEVENT_ERRNO__FILTER_NOT_FOUND;
2037 ret = test_filter(filter_type->event, filter_type->filter, record, &err);
2041 return ret ? PEVENT_ERRNO__FILTER_MATCH : PEVENT_ERRNO__FILTER_MISS;
2044 static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
2055 switch (arg->op.type) {
2063 left = arg_to_str(filter, arg->op.left);
2064 right = arg_to_str(filter, arg->op.right);
2065 if (!left || !right)
2068 /* Try to consolidate boolean values */
2069 if (strcmp(left, "TRUE") == 0)
2071 else if (strcmp(left, "FALSE") == 0)
2074 if (strcmp(right, "TRUE") == 0)
2076 else if (strcmp(right, "FALSE") == 0)
2079 if (left_val >= 0) {
2080 if ((arg->op.type == FILTER_OP_AND && !left_val) ||
2081 (arg->op.type == FILTER_OP_OR && left_val)) {
2082 /* Just return left value */
2087 if (right_val >= 0) {
2088 /* just evaluate this. */
2090 switch (arg->op.type) {
2092 val = left_val && right_val;
2095 val = left_val || right_val;
2100 str = malloc_or_die(6);
2102 strcpy(str, "TRUE");
2104 strcpy(str, "FALSE");
2108 if (right_val >= 0) {
2109 if ((arg->op.type == FILTER_OP_AND && !right_val) ||
2110 (arg->op.type == FILTER_OP_OR && right_val)) {
2111 /* Just return right value */
2116 /* The right value is meaningless */
2122 len = strlen(left) + strlen(right) + strlen(op) + 10;
2123 str = malloc_or_die(len);
2124 snprintf(str, len, "(%s) %s (%s)",
2130 right = arg_to_str(filter, arg->op.right);
2134 /* See if we can consolidate */
2135 if (strcmp(right, "TRUE") == 0)
2137 else if (strcmp(right, "FALSE") == 0)
2139 if (right_val >= 0) {
2140 /* just return the opposite */
2141 str = malloc_or_die(6);
2143 strcpy(str, "FALSE");
2145 strcpy(str, "TRUE");
2148 len = strlen(right) + strlen(op) + 3;
2149 str = malloc_or_die(len);
2150 snprintf(str, len, "%s(%s)", op, right);
2162 static char *val_to_str(struct event_filter *filter, struct filter_arg *arg)
2166 str = malloc_or_die(30);
2168 snprintf(str, 30, "%lld", arg->value.val);
2173 static char *field_to_str(struct event_filter *filter, struct filter_arg *arg)
2175 return strdup(arg->field.field->name);
2178 static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2186 lstr = arg_to_str(filter, arg->exp.left);
2187 rstr = arg_to_str(filter, arg->exp.right);
2191 switch (arg->exp.type) {
2192 case FILTER_EXP_ADD:
2195 case FILTER_EXP_SUB:
2198 case FILTER_EXP_MUL:
2201 case FILTER_EXP_DIV:
2204 case FILTER_EXP_MOD:
2207 case FILTER_EXP_RSHIFT:
2210 case FILTER_EXP_LSHIFT:
2213 case FILTER_EXP_AND:
2219 case FILTER_EXP_XOR:
2226 len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
2227 str = malloc_or_die(len);
2228 snprintf(str, len, "%s %s %s", lstr, op, rstr);
2236 static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2244 lstr = arg_to_str(filter, arg->num.left);
2245 rstr = arg_to_str(filter, arg->num.right);
2249 switch (arg->num.type) {
2273 len = strlen(lstr) + strlen(op) + strlen(rstr) + 4;
2274 str = malloc_or_die(len);
2275 sprintf(str, "%s %s %s", lstr, op, rstr);
2290 static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
2296 switch (arg->str.type) {
2297 case FILTER_CMP_MATCH:
2300 case FILTER_CMP_NOT_MATCH:
2304 case FILTER_CMP_REGEX:
2308 case FILTER_CMP_NOT_REGEX:
2312 len = strlen(arg->str.field->name) + strlen(op) +
2313 strlen(arg->str.val) + 6;
2314 str = malloc_or_die(len);
2315 snprintf(str, len, "%s %s \"%s\"",
2316 arg->str.field->name,
2327 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
2331 switch (arg->type) {
2332 case FILTER_ARG_BOOLEAN:
2333 str = malloc_or_die(6);
2334 if (arg->boolean.value)
2335 strcpy(str, "TRUE");
2337 strcpy(str, "FALSE");
2341 return op_to_str(filter, arg);
2343 case FILTER_ARG_NUM:
2344 return num_to_str(filter, arg);
2346 case FILTER_ARG_STR:
2347 return str_to_str(filter, arg);
2349 case FILTER_ARG_VALUE:
2350 return val_to_str(filter, arg);
2352 case FILTER_ARG_FIELD:
2353 return field_to_str(filter, arg);
2355 case FILTER_ARG_EXP:
2356 return exp_to_str(filter, arg);
2366 * pevent_filter_make_string - return a string showing the filter
2367 * @filter: filter struct with filter information
2368 * @event_id: the event id to return the filter string with
2370 * Returns a string that displays the filter contents.
2371 * This string must be freed with free(str).
2372 * NULL is returned if no filter is found.
2375 pevent_filter_make_string(struct event_filter *filter, int event_id)
2377 struct filter_type *filter_type;
2379 if (!filter->filters)
2382 filter_type = find_filter_type(filter, event_id);
2387 return arg_to_str(filter, filter_type->filter);
2391 * pevent_filter_compare - compare two filters and return if they are the same
2392 * @filter1: Filter to compare with @filter2
2393 * @filter2: Filter to compare with @filter1
2396 * 1 if the two filters hold the same content.
2399 int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2)
2401 struct filter_type *filter_type1;
2402 struct filter_type *filter_type2;
2407 /* Do the easy checks first */
2408 if (filter1->filters != filter2->filters)
2410 if (!filter1->filters && !filter2->filters)
2414 * Now take a look at each of the events to see if they have the same
2417 for (i = 0; i < filter1->filters; i++) {
2418 filter_type1 = &filter1->event_filters[i];
2419 filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2422 if (filter_type1->filter->type != filter_type2->filter->type)
2424 switch (filter_type1->filter->type) {
2425 case FILTER_TRIVIAL_FALSE:
2426 case FILTER_TRIVIAL_TRUE:
2427 /* trivial types just need the type compared */
2432 /* The best way to compare complex filters is with strings */
2433 str1 = arg_to_str(filter1, filter_type1->filter);
2434 str2 = arg_to_str(filter2, filter_type2->filter);
2436 result = strcmp(str1, str2) != 0;
2438 /* bail out if allocation fails */
2447 if (i < filter1->filters)