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, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 #include <sys/types.h>
28 #include "event-parse.h"
29 #include "event-utils.h"
33 static struct format_field comm = {
38 struct event_list *next;
39 struct event_format *event;
42 #define MAX_ERR_STR_SIZE 256
44 static void show_error(char **error_str, const char *fmt, ...)
46 unsigned long long index;
56 input = pevent_get_input_buf();
57 index = pevent_get_input_buf_ptr();
58 len = input ? strlen(input) : 0;
60 error = malloc_or_die(MAX_ERR_STR_SIZE + (len*2) + 3);
65 for (i = 1; i < len && i < index; i++)
68 error[len + i + 1] = '\n';
73 vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap);
79 static void free_token(char *token)
81 pevent_free_token(token);
84 static enum event_type read_token(char **tok)
91 type = pevent_read_token(&token);
92 } while (type == EVENT_NEWLINE || type == EVENT_SPACE);
94 /* If token is = or ! check to see if the next char is ~ */
96 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
97 pevent_peek_char() == '~') {
99 *tok = malloc_or_die(3);
100 sprintf(*tok, "%c%c", *token, '~');
102 /* Now remove the '~' from the buffer */
103 pevent_read_token(&token);
111 static int filter_cmp(const void *a, const void *b)
113 const struct filter_type *ea = a;
114 const struct filter_type *eb = b;
116 if (ea->event_id < eb->event_id)
119 if (ea->event_id > eb->event_id)
125 static struct filter_type *
126 find_filter_type(struct event_filter *filter, int id)
128 struct filter_type *filter_type;
129 struct filter_type key;
133 filter_type = bsearch(&key, filter->event_filters,
135 sizeof(*filter->event_filters),
141 static struct filter_type *
142 add_filter_type(struct event_filter *filter, int id)
144 struct filter_type *filter_type;
147 filter_type = find_filter_type(filter, id);
151 filter->event_filters = realloc(filter->event_filters,
152 sizeof(*filter->event_filters) *
153 (filter->filters + 1));
154 if (!filter->event_filters)
155 die("Could not allocate filter");
157 for (i = 0; i < filter->filters; i++) {
158 if (filter->event_filters[i].event_id > id)
162 if (i < filter->filters)
163 memmove(&filter->event_filters[i+1],
164 &filter->event_filters[i],
165 sizeof(*filter->event_filters) *
166 (filter->filters - i));
168 filter_type = &filter->event_filters[i];
169 filter_type->event_id = id;
170 filter_type->event = pevent_find_event(filter->pevent, id);
171 filter_type->filter = NULL;
179 * pevent_filter_alloc - create a new event filter
180 * @pevent: The pevent that this filter is associated with
182 struct event_filter *pevent_filter_alloc(struct pevent *pevent)
184 struct event_filter *filter;
186 filter = malloc_or_die(sizeof(*filter));
187 memset(filter, 0, sizeof(*filter));
188 filter->pevent = pevent;
194 static struct filter_arg *allocate_arg(void)
196 struct filter_arg *arg;
198 arg = malloc_or_die(sizeof(*arg));
199 memset(arg, 0, sizeof(*arg));
204 static void free_arg(struct filter_arg *arg)
210 case FILTER_ARG_NONE:
211 case FILTER_ARG_BOOLEAN:
217 regfree(&arg->str.reg);
218 free(arg->str.buffer);
222 free_arg(arg->op.left);
223 free_arg(arg->op.right);
231 static void add_event(struct event_list **events,
232 struct event_format *event)
234 struct event_list *list;
236 list = malloc_or_die(sizeof(*list));
237 list->next = *events;
242 static int event_match(struct event_format *event,
243 regex_t *sreg, regex_t *ereg)
246 return !regexec(sreg, event->system, 0, NULL, 0) &&
247 !regexec(ereg, event->name, 0, NULL, 0);
250 return !regexec(ereg, event->system, 0, NULL, 0) ||
251 !regexec(ereg, event->name, 0, NULL, 0);
255 find_event(struct pevent *pevent, struct event_list **events,
256 char *sys_name, char *event_name)
258 struct event_format *event;
267 /* if no name is given, then swap sys and name */
268 event_name = sys_name;
272 reg = malloc_or_die(strlen(event_name) + 3);
273 sprintf(reg, "^%s$", event_name);
275 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
282 reg = malloc_or_die(strlen(sys_name) + 3);
283 sprintf(reg, "^%s$", sys_name);
284 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
292 for (i = 0; i < pevent->nr_events; i++) {
293 event = pevent->events[i];
294 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
296 add_event(events, event);
310 static void free_events(struct event_list *events)
312 struct event_list *event;
316 events = events->next;
321 static struct filter_arg *
322 create_arg_item(struct event_format *event, const char *token,
323 enum event_type type, char **error_str)
325 struct format_field *field;
326 struct filter_arg *arg;
328 arg = allocate_arg();
334 arg->type = FILTER_ARG_VALUE;
336 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
337 arg->value.str = strdup(token);
339 die("malloc string");
342 /* if it is a number, then convert it */
343 if (isdigit(token[0])) {
344 arg->type = FILTER_ARG_VALUE;
345 arg->value.type = FILTER_NUMBER;
346 arg->value.val = strtoull(token, NULL, 0);
349 /* Consider this a field */
350 field = pevent_find_any_field(event, token);
352 if (strcmp(token, COMM) != 0) {
353 /* not a field, Make it false */
354 arg->type = FILTER_ARG_BOOLEAN;
355 arg->boolean.value = FILTER_FALSE;
358 /* If token is 'COMM' then it is special */
361 arg->type = FILTER_ARG_FIELD;
362 arg->field.field = field;
366 show_error(error_str, "expected a value but found %s",
373 static struct filter_arg *
374 create_arg_op(enum filter_op_type btype)
376 struct filter_arg *arg;
378 arg = allocate_arg();
379 arg->type = FILTER_ARG_OP;
380 arg->op.type = btype;
385 static struct filter_arg *
386 create_arg_exp(enum filter_exp_type etype)
388 struct filter_arg *arg;
390 arg = allocate_arg();
391 arg->type = FILTER_ARG_EXP;
392 arg->op.type = etype;
397 static struct filter_arg *
398 create_arg_cmp(enum filter_exp_type etype)
400 struct filter_arg *arg;
402 arg = allocate_arg();
403 /* Use NUM and change if necessary */
404 arg->type = FILTER_ARG_NUM;
405 arg->op.type = etype;
410 static int add_right(struct filter_arg *op, struct filter_arg *arg,
413 struct filter_arg *left;
435 * The arg must be num, str, or field
438 case FILTER_ARG_VALUE:
439 case FILTER_ARG_FIELD:
442 show_error(error_str,
448 * Depending on the type, we may need to
449 * convert this to a string or regex.
451 switch (arg->value.type) {
454 * A char should be converted to number if
455 * the string is 1 byte, and the compare
458 if (strlen(arg->value.str) == 1 &&
459 op->num.type != FILTER_CMP_REGEX &&
460 op->num.type != FILTER_CMP_NOT_REGEX) {
461 arg->value.type = FILTER_NUMBER;
467 /* convert op to a string arg */
468 op_type = op->num.type;
470 str = arg->value.str;
472 /* reset the op for the new field */
473 memset(op, 0, sizeof(*op));
476 * If left arg was a field not found then
477 * NULL the entire op.
479 if (left->type == FILTER_ARG_BOOLEAN) {
482 op->type = FILTER_ARG_BOOLEAN;
483 op->boolean.value = FILTER_FALSE;
487 /* Left arg must be a field */
488 if (left->type != FILTER_ARG_FIELD) {
489 show_error(error_str,
490 "Illegal lvalue for string comparison");
494 /* Make sure this is a valid string compare */
497 op_type = FILTER_CMP_MATCH;
500 op_type = FILTER_CMP_NOT_MATCH;
503 case FILTER_CMP_REGEX:
504 case FILTER_CMP_NOT_REGEX:
505 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB);
507 show_error(error_str,
508 "RegEx '%s' did not compute",
514 show_error(error_str,
515 "Illegal comparison for string");
519 op->type = FILTER_ARG_STR;
520 op->str.type = op_type;
521 op->str.field = left->field.field;
522 op->str.val = strdup(str);
524 die("malloc string");
526 * Need a buffer to copy data for tests
528 op->str.buffer = malloc_or_die(op->str.field->size + 1);
529 /* Null terminate this buffer */
530 op->str.buffer[op->str.field->size] = 0;
532 /* We no longer have left or right args */
541 switch (op->num.type) {
542 case FILTER_CMP_REGEX:
543 case FILTER_CMP_NOT_REGEX:
544 show_error(error_str,
545 "Op not allowed with integers");
552 /* numeric compare */
566 show_error(error_str,
571 static struct filter_arg *
572 rotate_op_right(struct filter_arg *a, struct filter_arg *b)
574 struct filter_arg *arg;
581 static int add_left(struct filter_arg *op, struct filter_arg *arg)
585 if (arg->type == FILTER_ARG_OP)
586 arg = rotate_op_right(arg, op);
594 if (arg->type == FILTER_ARG_OP)
595 arg = rotate_op_right(arg, op);
597 /* left arg of compares must be a field */
598 if (arg->type != FILTER_ARG_FIELD &&
599 arg->type != FILTER_ARG_BOOLEAN)
617 static enum op_type process_op(const char *token,
618 enum filter_op_type *btype,
619 enum filter_cmp_type *ctype,
620 enum filter_exp_type *etype)
622 *btype = FILTER_OP_NOT;
623 *etype = FILTER_EXP_NONE;
624 *ctype = FILTER_CMP_NONE;
626 if (strcmp(token, "&&") == 0)
627 *btype = FILTER_OP_AND;
628 else if (strcmp(token, "||") == 0)
629 *btype = FILTER_OP_OR;
630 else if (strcmp(token, "!") == 0)
633 if (*btype != FILTER_OP_NOT)
636 /* Check for value expressions */
637 if (strcmp(token, "+") == 0) {
638 *etype = FILTER_EXP_ADD;
639 } else if (strcmp(token, "-") == 0) {
640 *etype = FILTER_EXP_SUB;
641 } else if (strcmp(token, "*") == 0) {
642 *etype = FILTER_EXP_MUL;
643 } else if (strcmp(token, "/") == 0) {
644 *etype = FILTER_EXP_DIV;
645 } else if (strcmp(token, "%") == 0) {
646 *etype = FILTER_EXP_MOD;
647 } else if (strcmp(token, ">>") == 0) {
648 *etype = FILTER_EXP_RSHIFT;
649 } else if (strcmp(token, "<<") == 0) {
650 *etype = FILTER_EXP_LSHIFT;
651 } else if (strcmp(token, "&") == 0) {
652 *etype = FILTER_EXP_AND;
653 } else if (strcmp(token, "|") == 0) {
654 *etype = FILTER_EXP_OR;
655 } else if (strcmp(token, "^") == 0) {
656 *etype = FILTER_EXP_XOR;
657 } else if (strcmp(token, "~") == 0)
658 *etype = FILTER_EXP_NOT;
660 if (*etype != FILTER_EXP_NONE)
663 /* Check for compares */
664 if (strcmp(token, "==") == 0)
665 *ctype = FILTER_CMP_EQ;
666 else if (strcmp(token, "!=") == 0)
667 *ctype = FILTER_CMP_NE;
668 else if (strcmp(token, "<") == 0)
669 *ctype = FILTER_CMP_LT;
670 else if (strcmp(token, ">") == 0)
671 *ctype = FILTER_CMP_GT;
672 else if (strcmp(token, "<=") == 0)
673 *ctype = FILTER_CMP_LE;
674 else if (strcmp(token, ">=") == 0)
675 *ctype = FILTER_CMP_GE;
676 else if (strcmp(token, "=~") == 0)
677 *ctype = FILTER_CMP_REGEX;
678 else if (strcmp(token, "!~") == 0)
679 *ctype = FILTER_CMP_NOT_REGEX;
686 static int check_op_done(struct filter_arg *arg)
690 return arg->exp.right != NULL;
693 return arg->op.right != NULL;
696 return arg->num.right != NULL;
699 /* A string conversion is always done */
702 case FILTER_ARG_BOOLEAN:
703 /* field not found, is ok */
717 void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
718 struct filter_arg *arg)
720 struct filter_arg *other_child;
721 struct filter_arg **ptr;
723 if (parent->type != FILTER_ARG_OP &&
724 arg->type != FILTER_ARG_OP)
725 die("can not reparent other than OP");
727 /* Get the sibling */
728 if (old_child->op.right == arg) {
729 ptr = &old_child->op.right;
730 other_child = old_child->op.left;
731 } else if (old_child->op.left == arg) {
732 ptr = &old_child->op.left;
733 other_child = old_child->op.right;
735 die("Error in reparent op, find other child");
737 /* Detach arg from old_child */
741 if (parent == old_child) {
742 free_arg(other_child);
744 /* Free arg without recussion */
749 if (parent->op.right == old_child)
750 ptr = &parent->op.right;
751 else if (parent->op.left == old_child)
752 ptr = &parent->op.left;
754 die("Error in reparent op");
760 enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg)
762 enum filter_vals lval, rval;
767 case FILTER_ARG_BOOLEAN:
768 return FILTER_VAL_FALSE + arg->boolean.value;
772 case FILTER_ARG_VALUE:
773 case FILTER_ARG_FIELD:
774 return FILTER_VAL_NORM;
777 lval = test_arg(arg, arg->exp.left);
778 if (lval != FILTER_VAL_NORM)
780 rval = test_arg(arg, arg->exp.right);
781 if (rval != FILTER_VAL_NORM)
783 return FILTER_VAL_NORM;
786 lval = test_arg(arg, arg->num.left);
787 if (lval != FILTER_VAL_NORM)
789 rval = test_arg(arg, arg->num.right);
790 if (rval != FILTER_VAL_NORM)
792 return FILTER_VAL_NORM;
795 if (arg->op.type != FILTER_OP_NOT) {
796 lval = test_arg(arg, arg->op.left);
798 case FILTER_VAL_NORM:
800 case FILTER_VAL_TRUE:
801 if (arg->op.type == FILTER_OP_OR)
802 return FILTER_VAL_TRUE;
803 rval = test_arg(arg, arg->op.right);
804 if (rval != FILTER_VAL_NORM)
807 reparent_op_arg(parent, arg, arg->op.right);
808 return FILTER_VAL_NORM;
810 case FILTER_VAL_FALSE:
811 if (arg->op.type == FILTER_OP_AND)
812 return FILTER_VAL_FALSE;
813 rval = test_arg(arg, arg->op.right);
814 if (rval != FILTER_VAL_NORM)
817 reparent_op_arg(parent, arg, arg->op.right);
818 return FILTER_VAL_NORM;
822 rval = test_arg(arg, arg->op.right);
824 case FILTER_VAL_NORM:
826 case FILTER_VAL_TRUE:
827 if (arg->op.type == FILTER_OP_OR)
828 return FILTER_VAL_TRUE;
829 if (arg->op.type == FILTER_OP_NOT)
830 return FILTER_VAL_FALSE;
832 reparent_op_arg(parent, arg, arg->op.left);
833 return FILTER_VAL_NORM;
835 case FILTER_VAL_FALSE:
836 if (arg->op.type == FILTER_OP_AND)
837 return FILTER_VAL_FALSE;
838 if (arg->op.type == FILTER_OP_NOT)
839 return FILTER_VAL_TRUE;
841 reparent_op_arg(parent, arg, arg->op.left);
842 return FILTER_VAL_NORM;
845 return FILTER_VAL_NORM;
847 die("bad arg in filter tree");
849 return FILTER_VAL_NORM;
852 /* Remove any unknown event fields */
853 static struct filter_arg *collapse_tree(struct filter_arg *arg)
855 enum filter_vals ret;
857 ret = test_arg(arg, arg);
859 case FILTER_VAL_NORM:
862 case FILTER_VAL_TRUE:
863 case FILTER_VAL_FALSE:
865 arg = allocate_arg();
866 arg->type = FILTER_ARG_BOOLEAN;
867 arg->boolean.value = ret == FILTER_VAL_TRUE;
874 process_filter(struct event_format *event, struct filter_arg **parg,
875 char **error_str, int not)
877 enum event_type type;
879 struct filter_arg *current_op = NULL;
880 struct filter_arg *current_exp = NULL;
881 struct filter_arg *left_item = NULL;
882 struct filter_arg *arg = NULL;
883 enum op_type op_type;
884 enum filter_op_type btype;
885 enum filter_exp_type etype;
886 enum filter_cmp_type ctype;
893 type = read_token(&token);
898 arg = create_arg_item(event, token, type, error_str);
903 else if (current_exp) {
904 ret = add_right(current_exp, arg, error_str);
908 /* Not's only one one expression */
924 show_error(error_str,
925 "Illegal token ','");
931 show_error(error_str,
932 "Open paren can not come after item");
936 show_error(error_str,
937 "Open paren can not come after expression");
941 ret = process_filter(event, &arg, error_str, 0);
944 show_error(error_str,
945 "Unbalanced number of '('");
950 /* A not wants just one expression */
959 ret = add_right(current_op, arg, error_str);
967 if (!current_op && !current_exp)
970 /* Make sure everything is finished at this level */
971 if (current_exp && !check_op_done(current_exp))
973 if (current_op && !check_op_done(current_op))
985 op_type = process_op(token, &btype, &ctype, &etype);
987 /* All expect a left arg except for NOT */
990 /* Logic ops need a left expression */
991 if (!current_exp && !current_op)
995 /* logic only processes ops and exp */
1005 show_error(error_str,
1006 "Unknown op token %s", token);
1013 arg = create_arg_op(btype);
1015 ret = add_left(arg, current_op);
1017 ret = add_left(arg, current_exp);
1023 arg = create_arg_op(btype);
1025 ret = add_right(current_op, arg, error_str);
1029 ret = process_filter(event, &arg, error_str, 1);
1032 ret = add_right(current_exp, arg, error_str);
1039 if (op_type == OP_EXP)
1040 arg = create_arg_exp(etype);
1042 arg = create_arg_cmp(ctype);
1045 ret = add_right(current_op, arg, error_str);
1048 ret = add_left(arg, left_item);
1067 } while (type != EVENT_NONE);
1069 if (!current_op && !current_exp)
1073 current_op = current_exp;
1075 current_op = collapse_tree(current_op);
1082 show_error(error_str, "Syntax error");
1084 free_arg(current_op);
1085 free_arg(current_exp);
1092 process_event(struct event_format *event, const char *filter_str,
1093 struct filter_arg **parg, char **error_str)
1097 pevent_buffer_init(filter_str, strlen(filter_str));
1099 ret = process_filter(event, parg, error_str, 0);
1101 show_error(error_str,
1102 "Unbalanced number of ')'");
1108 /* If parg is NULL, then make it into FALSE */
1110 *parg = allocate_arg();
1111 (*parg)->type = FILTER_ARG_BOOLEAN;
1112 (*parg)->boolean.value = FILTER_FALSE;
1118 static int filter_event(struct event_filter *filter,
1119 struct event_format *event,
1120 const char *filter_str, char **error_str)
1122 struct filter_type *filter_type;
1123 struct filter_arg *arg;
1127 ret = process_event(event, filter_str, &arg, error_str);
1132 /* just add a TRUE arg */
1133 arg = allocate_arg();
1134 arg->type = FILTER_ARG_BOOLEAN;
1135 arg->boolean.value = FILTER_TRUE;
1138 filter_type = add_filter_type(filter, event->id);
1139 if (filter_type->filter)
1140 free_arg(filter_type->filter);
1141 filter_type->filter = arg;
1147 * pevent_filter_add_filter_str - add a new filter
1148 * @filter: the event filter to add to
1149 * @filter_str: the filter string that contains the filter
1150 * @error_str: string containing reason for failed filter
1152 * Returns 0 if the filter was successfully added
1153 * -1 if there was an error.
1155 * On error, if @error_str points to a string pointer,
1156 * it is set to the reason that the filter failed.
1157 * This string must be freed with "free".
1159 int pevent_filter_add_filter_str(struct event_filter *filter,
1160 const char *filter_str,
1163 struct pevent *pevent = filter->pevent;
1164 struct event_list *event;
1165 struct event_list *events = NULL;
1166 const char *filter_start;
1167 const char *next_event;
1169 char *event_name = NULL;
1170 char *sys_name = NULL;
1176 /* clear buffer to reset show error */
1177 pevent_buffer_init("", 0);
1182 filter_start = strchr(filter_str, ':');
1184 len = filter_start - filter_str;
1186 len = strlen(filter_str);
1190 next_event = strchr(filter_str, ',');
1192 (!filter_start || next_event < filter_start))
1193 len = next_event - filter_str;
1194 else if (filter_start)
1195 len = filter_start - filter_str;
1197 len = strlen(filter_str);
1199 this_event = malloc_or_die(len + 1);
1200 memcpy(this_event, filter_str, len);
1201 this_event[len] = 0;
1206 filter_str = next_event;
1208 sys_name = strtok_r(this_event, "/", &sp);
1209 event_name = strtok_r(NULL, "/", &sp);
1212 show_error(error_str, "No filter found");
1213 /* This can only happen when events is NULL, but still */
1214 free_events(events);
1219 /* Find this event */
1220 ret = find_event(pevent, &events, strim(sys_name), strim(event_name));
1223 show_error(error_str,
1224 "No event found under '%s.%s'",
1225 sys_name, event_name);
1227 show_error(error_str,
1228 "No event found under '%s'",
1230 free_events(events);
1235 } while (filter_str);
1241 /* filter starts here */
1242 for (event = events; event; event = event->next) {
1243 ret = filter_event(filter, event->event, filter_start,
1245 /* Failures are returned if a parse error happened */
1249 if (ret >= 0 && pevent->test_filters) {
1251 test = pevent_filter_make_string(filter, event->event->id);
1252 printf(" '%s: %s'\n", event->event->name, test);
1257 free_events(events);
1259 if (rtn >= 0 && pevent->test_filters)
1265 static void free_filter_type(struct filter_type *filter_type)
1267 free_arg(filter_type->filter);
1271 * pevent_filter_remove_event - remove a filter for an event
1272 * @filter: the event filter to remove from
1273 * @event_id: the event to remove a filter for
1275 * Removes the filter saved for an event defined by @event_id
1278 * Returns 1: if an event was removed
1279 * 0: if the event was not found
1281 int pevent_filter_remove_event(struct event_filter *filter,
1284 struct filter_type *filter_type;
1287 if (!filter->filters)
1290 filter_type = find_filter_type(filter, event_id);
1295 free_filter_type(filter_type);
1297 /* The filter_type points into the event_filters array */
1298 len = (unsigned long)(filter->event_filters + filter->filters) -
1299 (unsigned long)(filter_type + 1);
1301 memmove(filter_type, filter_type + 1, len);
1304 memset(&filter->event_filters[filter->filters], 0,
1305 sizeof(*filter_type));
1311 * pevent_filter_reset - clear all filters in a filter
1312 * @filter: the event filter to reset
1314 * Removes all filters from a filter and resets it.
1316 void pevent_filter_reset(struct event_filter *filter)
1320 for (i = 0; i < filter->filters; i++)
1321 free_filter_type(&filter->event_filters[i]);
1323 free(filter->event_filters);
1324 filter->filters = 0;
1325 filter->event_filters = NULL;
1328 void pevent_filter_free(struct event_filter *filter)
1330 pevent_unref(filter->pevent);
1332 pevent_filter_reset(filter);
1337 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg);
1339 static int copy_filter_type(struct event_filter *filter,
1340 struct event_filter *source,
1341 struct filter_type *filter_type)
1343 struct filter_arg *arg;
1344 struct event_format *event;
1349 /* Can't assume that the pevent's are the same */
1350 sys = filter_type->event->system;
1351 name = filter_type->event->name;
1352 event = pevent_find_event_by_name(filter->pevent, sys, name);
1356 str = arg_to_str(source, filter_type->filter);
1360 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
1361 /* Add trivial event */
1362 arg = allocate_arg();
1363 arg->type = FILTER_ARG_BOOLEAN;
1364 if (strcmp(str, "TRUE") == 0)
1365 arg->boolean.value = 1;
1367 arg->boolean.value = 0;
1369 filter_type = add_filter_type(filter, event->id);
1370 filter_type->filter = arg;
1376 filter_event(filter, event, str, NULL);
1383 * pevent_filter_copy - copy a filter using another filter
1384 * @dest - the filter to copy to
1385 * @source - the filter to copy from
1387 * Returns 0 on success and -1 if not all filters were copied
1389 int pevent_filter_copy(struct event_filter *dest, struct event_filter *source)
1394 pevent_filter_reset(dest);
1396 for (i = 0; i < source->filters; i++) {
1397 if (copy_filter_type(dest, source, &source->event_filters[i]))
1405 * pevent_update_trivial - update the trivial filters with the given filter
1406 * @dest - the filter to update
1407 * @source - the filter as the source of the update
1408 * @type - the type of trivial filter to update.
1410 * Scan dest for trivial events matching @type to replace with the source.
1412 * Returns 0 on success and -1 if there was a problem updating, but
1413 * events may have still been updated on error.
1415 int pevent_update_trivial(struct event_filter *dest, struct event_filter *source,
1416 enum filter_trivial_type type)
1418 struct pevent *src_pevent;
1419 struct pevent *dest_pevent;
1420 struct event_format *event;
1421 struct filter_type *filter_type;
1422 struct filter_arg *arg;
1426 src_pevent = source->pevent;
1427 dest_pevent = dest->pevent;
1429 /* Do nothing if either of the filters has nothing to filter */
1430 if (!dest->filters || !source->filters)
1433 for (i = 0; i < dest->filters; i++) {
1434 filter_type = &dest->event_filters[i];
1435 arg = filter_type->filter;
1436 if (arg->type != FILTER_ARG_BOOLEAN)
1438 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) ||
1439 (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE))
1442 event = filter_type->event;
1444 if (src_pevent != dest_pevent) {
1446 event = pevent_find_event_by_name(src_pevent,
1453 str = pevent_filter_make_string(source, event->id);
1457 /* Don't bother if the filter is trivial too */
1458 if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0)
1459 filter_event(dest, event, str, NULL);
1466 * pevent_filter_clear_trivial - clear TRUE and FALSE filters
1467 * @filter: the filter to remove trivial filters from
1468 * @type: remove only true, false, or both
1470 * Removes filters that only contain a TRUE or FALES boolean arg.
1472 void pevent_filter_clear_trivial(struct event_filter *filter,
1473 enum filter_trivial_type type)
1475 struct filter_type *filter_type;
1480 if (!filter->filters)
1484 * Two steps, first get all ids with trivial filters.
1485 * then remove those ids.
1487 for (i = 0; i < filter->filters; i++) {
1488 filter_type = &filter->event_filters[i];
1489 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1492 case FILTER_TRIVIAL_FALSE:
1493 if (filter_type->filter->boolean.value)
1495 case FILTER_TRIVIAL_TRUE:
1496 if (!filter_type->filter->boolean.value)
1502 ids = realloc(ids, sizeof(*ids) * (count + 1));
1504 die("Can't allocate ids");
1505 ids[count++] = filter_type->event_id;
1511 for (i = 0; i < count; i++)
1512 pevent_filter_remove_event(filter, ids[i]);
1518 * pevent_filter_event_has_trivial - return true event contains trivial filter
1519 * @filter: the filter with the information
1520 * @event_id: the id of the event to test
1521 * @type: trivial type to test for (TRUE, FALSE, EITHER)
1523 * Returns 1 if the event contains a matching trivial type
1526 int pevent_filter_event_has_trivial(struct event_filter *filter,
1528 enum filter_trivial_type type)
1530 struct filter_type *filter_type;
1532 if (!filter->filters)
1535 filter_type = find_filter_type(filter, event_id);
1540 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1544 case FILTER_TRIVIAL_FALSE:
1545 return !filter_type->filter->boolean.value;
1547 case FILTER_TRIVIAL_TRUE:
1548 return filter_type->filter->boolean.value;
1554 static int test_filter(struct event_format *event,
1555 struct filter_arg *arg, struct pevent_record *record);
1558 get_comm(struct event_format *event, struct pevent_record *record)
1563 pid = pevent_data_pid(event->pevent, record);
1564 comm = pevent_data_comm_from_pid(event->pevent, pid);
1568 static unsigned long long
1569 get_value(struct event_format *event,
1570 struct format_field *field, struct pevent_record *record)
1572 unsigned long long val;
1574 /* Handle our dummy "comm" field */
1575 if (field == &comm) {
1578 name = get_comm(event, record);
1579 return (unsigned long)name;
1582 pevent_read_number_field(field, record->data, &val);
1584 if (!(field->flags & FIELD_IS_SIGNED))
1587 switch (field->size) {
1595 return (long long)val;
1600 static unsigned long long
1601 get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record);
1603 static unsigned long long
1604 get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
1606 unsigned long long lval, rval;
1608 lval = get_arg_value(event, arg->exp.left, record);
1609 rval = get_arg_value(event, arg->exp.right, record);
1611 switch (arg->exp.type) {
1612 case FILTER_EXP_ADD:
1615 case FILTER_EXP_SUB:
1618 case FILTER_EXP_MUL:
1621 case FILTER_EXP_DIV:
1624 case FILTER_EXP_MOD:
1627 case FILTER_EXP_RSHIFT:
1628 return lval >> rval;
1630 case FILTER_EXP_LSHIFT:
1631 return lval << rval;
1633 case FILTER_EXP_AND:
1639 case FILTER_EXP_XOR:
1642 case FILTER_EXP_NOT:
1644 die("error in exp");
1649 static unsigned long long
1650 get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
1652 switch (arg->type) {
1653 case FILTER_ARG_FIELD:
1654 return get_value(event, arg->field.field, record);
1656 case FILTER_ARG_VALUE:
1657 if (arg->value.type != FILTER_NUMBER)
1658 die("must have number field!");
1659 return arg->value.val;
1661 case FILTER_ARG_EXP:
1662 return get_exp_value(event, arg, record);
1665 die("oops in filter");
1670 static int test_num(struct event_format *event,
1671 struct filter_arg *arg, struct pevent_record *record)
1673 unsigned long long lval, rval;
1675 lval = get_arg_value(event, arg->num.left, record);
1676 rval = get_arg_value(event, arg->num.right, record);
1678 switch (arg->num.type) {
1680 return lval == rval;
1683 return lval != rval;
1692 return lval >= rval;
1695 return lval <= rval;
1703 static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
1705 struct event_format *event;
1706 struct pevent *pevent;
1707 unsigned long long addr;
1708 const char *val = NULL;
1711 /* If the field is not a string convert it */
1712 if (arg->str.field->flags & FIELD_IS_STRING) {
1713 val = record->data + arg->str.field->offset;
1716 * We need to copy the data since we can't be sure the field
1717 * is null terminated.
1719 if (*(val + arg->str.field->size - 1)) {
1721 memcpy(arg->str.buffer, val, arg->str.field->size);
1722 /* the buffer is already NULL terminated */
1723 val = arg->str.buffer;
1727 event = arg->str.field->event;
1728 pevent = event->pevent;
1729 addr = get_value(event, arg->str.field, record);
1731 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
1732 /* convert to a kernel symbol */
1733 val = pevent_find_function(pevent, addr);
1736 /* just use the hex of the string name */
1737 snprintf(hex, 64, "0x%llx", addr);
1745 static int test_str(struct event_format *event,
1746 struct filter_arg *arg, struct pevent_record *record)
1750 if (arg->str.field == &comm)
1751 val = get_comm(event, record);
1753 val = get_field_str(arg, record);
1755 switch (arg->str.type) {
1756 case FILTER_CMP_MATCH:
1757 return strcmp(val, arg->str.val) == 0;
1759 case FILTER_CMP_NOT_MATCH:
1760 return strcmp(val, arg->str.val) != 0;
1762 case FILTER_CMP_REGEX:
1763 /* Returns zero on match */
1764 return !regexec(&arg->str.reg, val, 0, NULL, 0);
1766 case FILTER_CMP_NOT_REGEX:
1767 return regexec(&arg->str.reg, val, 0, NULL, 0);
1775 static int test_op(struct event_format *event,
1776 struct filter_arg *arg, struct pevent_record *record)
1778 switch (arg->op.type) {
1780 return test_filter(event, arg->op.left, record) &&
1781 test_filter(event, arg->op.right, record);
1784 return test_filter(event, arg->op.left, record) ||
1785 test_filter(event, arg->op.right, record);
1788 return !test_filter(event, arg->op.right, record);
1796 static int test_filter(struct event_format *event,
1797 struct filter_arg *arg, struct pevent_record *record)
1799 switch (arg->type) {
1800 case FILTER_ARG_BOOLEAN:
1802 return arg->boolean.value;
1805 return test_op(event, arg, record);
1807 case FILTER_ARG_NUM:
1808 return test_num(event, arg, record);
1810 case FILTER_ARG_STR:
1811 return test_str(event, arg, record);
1813 case FILTER_ARG_EXP:
1814 case FILTER_ARG_VALUE:
1815 case FILTER_ARG_FIELD:
1817 * Expressions, fields and values evaluate
1818 * to true if they return non zero
1820 return !!get_arg_value(event, arg, record);
1830 * pevent_event_filtered - return true if event has filter
1831 * @filter: filter struct with filter information
1832 * @event_id: event id to test if filter exists
1834 * Returns 1 if filter found for @event_id
1837 int pevent_event_filtered(struct event_filter *filter,
1840 struct filter_type *filter_type;
1842 if (!filter->filters)
1845 filter_type = find_filter_type(filter, event_id);
1847 return filter_type ? 1 : 0;
1851 * pevent_filter_match - test if a record matches a filter
1852 * @filter: filter struct with filter information
1853 * @record: the record to test against the filter
1856 * 1 - filter found for event and @record matches
1857 * 0 - filter found for event and @record does not match
1858 * -1 - no filter found for @record's event
1859 * -2 - if no filters exist
1861 int pevent_filter_match(struct event_filter *filter,
1862 struct pevent_record *record)
1864 struct pevent *pevent = filter->pevent;
1865 struct filter_type *filter_type;
1868 if (!filter->filters)
1871 event_id = pevent_data_type(pevent, record);
1873 filter_type = find_filter_type(filter, event_id);
1876 return FILTER_NOEXIST;
1878 return test_filter(filter_type->event, filter_type->filter, record) ?
1879 FILTER_MATCH : FILTER_MISS;
1882 static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
1893 switch (arg->op.type) {
1901 left = arg_to_str(filter, arg->op.left);
1902 right = arg_to_str(filter, arg->op.right);
1903 if (!left || !right)
1906 /* Try to consolidate boolean values */
1907 if (strcmp(left, "TRUE") == 0)
1909 else if (strcmp(left, "FALSE") == 0)
1912 if (strcmp(right, "TRUE") == 0)
1914 else if (strcmp(right, "FALSE") == 0)
1917 if (left_val >= 0) {
1918 if ((arg->op.type == FILTER_OP_AND && !left_val) ||
1919 (arg->op.type == FILTER_OP_OR && left_val)) {
1920 /* Just return left value */
1925 if (right_val >= 0) {
1926 /* just evaluate this. */
1928 switch (arg->op.type) {
1930 val = left_val && right_val;
1933 val = left_val || right_val;
1938 str = malloc_or_die(6);
1940 strcpy(str, "TRUE");
1942 strcpy(str, "FALSE");
1946 if (right_val >= 0) {
1947 if ((arg->op.type == FILTER_OP_AND && !right_val) ||
1948 (arg->op.type == FILTER_OP_OR && right_val)) {
1949 /* Just return right value */
1954 /* The right value is meaningless */
1960 len = strlen(left) + strlen(right) + strlen(op) + 10;
1961 str = malloc_or_die(len);
1962 snprintf(str, len, "(%s) %s (%s)",
1968 right = arg_to_str(filter, arg->op.right);
1972 /* See if we can consolidate */
1973 if (strcmp(right, "TRUE") == 0)
1975 else if (strcmp(right, "FALSE") == 0)
1977 if (right_val >= 0) {
1978 /* just return the opposite */
1979 str = malloc_or_die(6);
1981 strcpy(str, "FALSE");
1983 strcpy(str, "TRUE");
1986 len = strlen(right) + strlen(op) + 3;
1987 str = malloc_or_die(len);
1988 snprintf(str, len, "%s(%s)", op, right);
2000 static char *val_to_str(struct event_filter *filter, struct filter_arg *arg)
2004 str = malloc_or_die(30);
2006 snprintf(str, 30, "%lld", arg->value.val);
2011 static char *field_to_str(struct event_filter *filter, struct filter_arg *arg)
2013 return strdup(arg->field.field->name);
2016 static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2024 lstr = arg_to_str(filter, arg->exp.left);
2025 rstr = arg_to_str(filter, arg->exp.right);
2029 switch (arg->exp.type) {
2030 case FILTER_EXP_ADD:
2033 case FILTER_EXP_SUB:
2036 case FILTER_EXP_MUL:
2039 case FILTER_EXP_DIV:
2042 case FILTER_EXP_MOD:
2045 case FILTER_EXP_RSHIFT:
2048 case FILTER_EXP_LSHIFT:
2051 case FILTER_EXP_AND:
2057 case FILTER_EXP_XOR:
2064 len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
2065 str = malloc_or_die(len);
2066 snprintf(str, len, "%s %s %s", lstr, op, rstr);
2074 static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2082 lstr = arg_to_str(filter, arg->num.left);
2083 rstr = arg_to_str(filter, arg->num.right);
2087 switch (arg->num.type) {
2111 len = strlen(lstr) + strlen(op) + strlen(rstr) + 4;
2112 str = malloc_or_die(len);
2113 sprintf(str, "%s %s %s", lstr, op, rstr);
2128 static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
2134 switch (arg->str.type) {
2135 case FILTER_CMP_MATCH:
2138 case FILTER_CMP_NOT_MATCH:
2142 case FILTER_CMP_REGEX:
2146 case FILTER_CMP_NOT_REGEX:
2150 len = strlen(arg->str.field->name) + strlen(op) +
2151 strlen(arg->str.val) + 6;
2152 str = malloc_or_die(len);
2153 snprintf(str, len, "%s %s \"%s\"",
2154 arg->str.field->name,
2165 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
2169 switch (arg->type) {
2170 case FILTER_ARG_BOOLEAN:
2171 str = malloc_or_die(6);
2172 if (arg->boolean.value)
2173 strcpy(str, "TRUE");
2175 strcpy(str, "FALSE");
2179 return op_to_str(filter, arg);
2181 case FILTER_ARG_NUM:
2182 return num_to_str(filter, arg);
2184 case FILTER_ARG_STR:
2185 return str_to_str(filter, arg);
2187 case FILTER_ARG_VALUE:
2188 return val_to_str(filter, arg);
2190 case FILTER_ARG_FIELD:
2191 return field_to_str(filter, arg);
2193 case FILTER_ARG_EXP:
2194 return exp_to_str(filter, arg);
2204 * pevent_filter_make_string - return a string showing the filter
2205 * @filter: filter struct with filter information
2206 * @event_id: the event id to return the filter string with
2208 * Returns a string that displays the filter contents.
2209 * This string must be freed with free(str).
2210 * NULL is returned if no filter is found.
2213 pevent_filter_make_string(struct event_filter *filter, int event_id)
2215 struct filter_type *filter_type;
2217 if (!filter->filters)
2220 filter_type = find_filter_type(filter, event_id);
2225 return arg_to_str(filter, filter_type->filter);
2229 * pevent_filter_compare - compare two filters and return if they are the same
2230 * @filter1: Filter to compare with @filter2
2231 * @filter2: Filter to compare with @filter1
2234 * 1 if the two filters hold the same content.
2237 int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2)
2239 struct filter_type *filter_type1;
2240 struct filter_type *filter_type2;
2245 /* Do the easy checks first */
2246 if (filter1->filters != filter2->filters)
2248 if (!filter1->filters && !filter2->filters)
2252 * Now take a look at each of the events to see if they have the same
2255 for (i = 0; i < filter1->filters; i++) {
2256 filter_type1 = &filter1->event_filters[i];
2257 filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2260 if (filter_type1->filter->type != filter_type2->filter->type)
2262 switch (filter_type1->filter->type) {
2263 case FILTER_TRIVIAL_FALSE:
2264 case FILTER_TRIVIAL_TRUE:
2265 /* trivial types just need the type compared */
2270 /* The best way to compare complex filters is with strings */
2271 str1 = arg_to_str(filter1, filter_type1->filter);
2272 str2 = arg_to_str(filter2, filter_type2->filter);
2274 result = strcmp(str1, str2) != 0;
2276 /* bail out if allocation fails */
2285 if (i < filter1->filters)