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() == '~') {
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 if (!filter->filters)
152 filter->event_filters =
153 malloc_or_die(sizeof(*filter->event_filters));
155 filter->event_filters =
156 realloc(filter->event_filters,
157 sizeof(*filter->event_filters) *
158 (filter->filters + 1));
159 if (!filter->event_filters)
160 die("Could not allocate filter");
163 for (i = 0; i < filter->filters; i++) {
164 if (filter->event_filters[i].event_id > id)
168 if (i < filter->filters)
169 memmove(&filter->event_filters[i+1],
170 &filter->event_filters[i],
171 sizeof(*filter->event_filters) *
172 (filter->filters - i));
174 filter_type = &filter->event_filters[i];
175 filter_type->event_id = id;
176 filter_type->event = pevent_find_event(filter->pevent, id);
177 filter_type->filter = NULL;
185 * pevent_filter_alloc - create a new event filter
186 * @pevent: The pevent that this filter is associated with
188 struct event_filter *pevent_filter_alloc(struct pevent *pevent)
190 struct event_filter *filter;
192 filter = malloc_or_die(sizeof(*filter));
193 memset(filter, 0, sizeof(*filter));
194 filter->pevent = pevent;
200 static struct filter_arg *allocate_arg(void)
202 struct filter_arg *arg;
204 arg = malloc_or_die(sizeof(*arg));
205 memset(arg, 0, sizeof(*arg));
210 static void free_arg(struct filter_arg *arg)
216 case FILTER_ARG_NONE:
217 case FILTER_ARG_BOOLEAN:
223 regfree(&arg->str.reg);
224 free(arg->str.buffer);
228 free_arg(arg->op.left);
229 free_arg(arg->op.right);
237 static void add_event(struct event_list **events,
238 struct event_format *event)
240 struct event_list *list;
242 list = malloc_or_die(sizeof(*list));
243 list->next = *events;
248 static int event_match(struct event_format *event,
249 regex_t *sreg, regex_t *ereg)
252 return !regexec(sreg, event->system, 0, NULL, 0) &&
253 !regexec(ereg, event->name, 0, NULL, 0);
256 return !regexec(ereg, event->system, 0, NULL, 0) ||
257 !regexec(ereg, event->name, 0, NULL, 0);
261 find_event(struct pevent *pevent, struct event_list **events,
262 char *sys_name, char *event_name)
264 struct event_format *event;
273 /* if no name is given, then swap sys and name */
274 event_name = sys_name;
278 reg = malloc_or_die(strlen(event_name) + 3);
279 sprintf(reg, "^%s$", event_name);
281 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
288 reg = malloc_or_die(strlen(sys_name) + 3);
289 sprintf(reg, "^%s$", sys_name);
290 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
298 for (i = 0; i < pevent->nr_events; i++) {
299 event = pevent->events[i];
300 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
302 add_event(events, event);
316 static void free_events(struct event_list *events)
318 struct event_list *event;
322 events = events->next;
327 static struct filter_arg *
328 create_arg_item(struct event_format *event, const char *token,
329 enum event_type type, char **error_str)
331 struct format_field *field;
332 struct filter_arg *arg;
334 arg = allocate_arg();
340 arg->type = FILTER_ARG_VALUE;
342 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
343 arg->value.str = strdup(token);
345 die("malloc string");
348 /* if it is a number, then convert it */
349 if (isdigit(token[0])) {
350 arg->type = FILTER_ARG_VALUE;
351 arg->value.type = FILTER_NUMBER;
352 arg->value.val = strtoull(token, NULL, 0);
355 /* Consider this a field */
356 field = pevent_find_any_field(event, token);
358 if (strcmp(token, COMM) != 0) {
359 /* not a field, Make it false */
360 arg->type = FILTER_ARG_BOOLEAN;
361 arg->boolean.value = FILTER_FALSE;
364 /* If token is 'COMM' then it is special */
367 arg->type = FILTER_ARG_FIELD;
368 arg->field.field = field;
372 show_error(error_str, "expected a value but found %s",
379 static struct filter_arg *
380 create_arg_op(enum filter_op_type btype)
382 struct filter_arg *arg;
384 arg = allocate_arg();
385 arg->type = FILTER_ARG_OP;
386 arg->op.type = btype;
391 static struct filter_arg *
392 create_arg_exp(enum filter_exp_type etype)
394 struct filter_arg *arg;
396 arg = allocate_arg();
397 arg->type = FILTER_ARG_EXP;
398 arg->op.type = etype;
403 static struct filter_arg *
404 create_arg_cmp(enum filter_exp_type etype)
406 struct filter_arg *arg;
408 arg = allocate_arg();
409 /* Use NUM and change if necessary */
410 arg->type = FILTER_ARG_NUM;
411 arg->op.type = etype;
416 static int add_right(struct filter_arg *op, struct filter_arg *arg,
419 struct filter_arg *left;
441 * The arg must be num, str, or field
444 case FILTER_ARG_VALUE:
445 case FILTER_ARG_FIELD:
448 show_error(error_str,
454 * Depending on the type, we may need to
455 * convert this to a string or regex.
457 switch (arg->value.type) {
460 * A char should be converted to number if
461 * the string is 1 byte, and the compare
464 if (strlen(arg->value.str) == 1 &&
465 op->num.type != FILTER_CMP_REGEX &&
466 op->num.type != FILTER_CMP_NOT_REGEX) {
467 arg->value.type = FILTER_NUMBER;
473 /* convert op to a string arg */
474 op_type = op->num.type;
476 str = arg->value.str;
478 /* reset the op for the new field */
479 memset(op, 0, sizeof(*op));
482 * If left arg was a field not found then
483 * NULL the entire op.
485 if (left->type == FILTER_ARG_BOOLEAN) {
488 op->type = FILTER_ARG_BOOLEAN;
489 op->boolean.value = FILTER_FALSE;
493 /* Left arg must be a field */
494 if (left->type != FILTER_ARG_FIELD) {
495 show_error(error_str,
496 "Illegal lvalue for string comparison");
500 /* Make sure this is a valid string compare */
503 op_type = FILTER_CMP_MATCH;
506 op_type = FILTER_CMP_NOT_MATCH;
509 case FILTER_CMP_REGEX:
510 case FILTER_CMP_NOT_REGEX:
511 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB);
513 show_error(error_str,
514 "RegEx '%s' did not compute",
520 show_error(error_str,
521 "Illegal comparison for string");
525 op->type = FILTER_ARG_STR;
526 op->str.type = op_type;
527 op->str.field = left->field.field;
528 op->str.val = strdup(str);
530 die("malloc string");
532 * Need a buffer to copy data for tests
534 op->str.buffer = malloc_or_die(op->str.field->size + 1);
535 /* Null terminate this buffer */
536 op->str.buffer[op->str.field->size] = 0;
538 /* We no longer have left or right args */
547 switch (op->num.type) {
548 case FILTER_CMP_REGEX:
549 case FILTER_CMP_NOT_REGEX:
550 show_error(error_str,
551 "Op not allowed with integers");
558 /* numeric compare */
572 show_error(error_str,
577 static struct filter_arg *
578 rotate_op_right(struct filter_arg *a, struct filter_arg *b)
580 struct filter_arg *arg;
587 static int add_left(struct filter_arg *op, struct filter_arg *arg)
591 if (arg->type == FILTER_ARG_OP)
592 arg = rotate_op_right(arg, op);
600 if (arg->type == FILTER_ARG_OP)
601 arg = rotate_op_right(arg, op);
603 /* left arg of compares must be a field */
604 if (arg->type != FILTER_ARG_FIELD &&
605 arg->type != FILTER_ARG_BOOLEAN)
623 static enum op_type process_op(const char *token,
624 enum filter_op_type *btype,
625 enum filter_cmp_type *ctype,
626 enum filter_exp_type *etype)
628 *btype = FILTER_OP_NOT;
629 *etype = FILTER_EXP_NONE;
630 *ctype = FILTER_CMP_NONE;
632 if (strcmp(token, "&&") == 0)
633 *btype = FILTER_OP_AND;
634 else if (strcmp(token, "||") == 0)
635 *btype = FILTER_OP_OR;
636 else if (strcmp(token, "!") == 0)
639 if (*btype != FILTER_OP_NOT)
642 /* Check for value expressions */
643 if (strcmp(token, "+") == 0) {
644 *etype = FILTER_EXP_ADD;
645 } else if (strcmp(token, "-") == 0) {
646 *etype = FILTER_EXP_SUB;
647 } else if (strcmp(token, "*") == 0) {
648 *etype = FILTER_EXP_MUL;
649 } else if (strcmp(token, "/") == 0) {
650 *etype = FILTER_EXP_DIV;
651 } else if (strcmp(token, "%") == 0) {
652 *etype = FILTER_EXP_MOD;
653 } else if (strcmp(token, ">>") == 0) {
654 *etype = FILTER_EXP_RSHIFT;
655 } else if (strcmp(token, "<<") == 0) {
656 *etype = FILTER_EXP_LSHIFT;
657 } else if (strcmp(token, "&") == 0) {
658 *etype = FILTER_EXP_AND;
659 } else if (strcmp(token, "|") == 0) {
660 *etype = FILTER_EXP_OR;
661 } else if (strcmp(token, "^") == 0) {
662 *etype = FILTER_EXP_XOR;
663 } else if (strcmp(token, "~") == 0)
664 *etype = FILTER_EXP_NOT;
666 if (*etype != FILTER_EXP_NONE)
669 /* Check for compares */
670 if (strcmp(token, "==") == 0)
671 *ctype = FILTER_CMP_EQ;
672 else if (strcmp(token, "!=") == 0)
673 *ctype = FILTER_CMP_NE;
674 else if (strcmp(token, "<") == 0)
675 *ctype = FILTER_CMP_LT;
676 else if (strcmp(token, ">") == 0)
677 *ctype = FILTER_CMP_GT;
678 else if (strcmp(token, "<=") == 0)
679 *ctype = FILTER_CMP_LE;
680 else if (strcmp(token, ">=") == 0)
681 *ctype = FILTER_CMP_GE;
682 else if (strcmp(token, "=~") == 0)
683 *ctype = FILTER_CMP_REGEX;
684 else if (strcmp(token, "!~") == 0)
685 *ctype = FILTER_CMP_NOT_REGEX;
692 static int check_op_done(struct filter_arg *arg)
696 return arg->exp.right != NULL;
699 return arg->op.right != NULL;
702 return arg->num.right != NULL;
705 /* A string conversion is always done */
708 case FILTER_ARG_BOOLEAN:
709 /* field not found, is ok */
723 void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
724 struct filter_arg *arg)
726 struct filter_arg *other_child;
727 struct filter_arg **ptr;
729 if (parent->type != FILTER_ARG_OP &&
730 arg->type != FILTER_ARG_OP)
731 die("can not reparent other than OP");
733 /* Get the sibling */
734 if (old_child->op.right == arg) {
735 ptr = &old_child->op.right;
736 other_child = old_child->op.left;
737 } else if (old_child->op.left == arg) {
738 ptr = &old_child->op.left;
739 other_child = old_child->op.right;
741 die("Error in reparent op, find other child");
743 /* Detach arg from old_child */
747 if (parent == old_child) {
748 free_arg(other_child);
750 /* Free arg without recussion */
755 if (parent->op.right == old_child)
756 ptr = &parent->op.right;
757 else if (parent->op.left == old_child)
758 ptr = &parent->op.left;
760 die("Error in reparent op");
766 enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg)
768 enum filter_vals lval, rval;
773 case FILTER_ARG_BOOLEAN:
774 return FILTER_VAL_FALSE + arg->boolean.value;
778 case FILTER_ARG_VALUE:
779 case FILTER_ARG_FIELD:
780 return FILTER_VAL_NORM;
783 lval = test_arg(arg, arg->exp.left);
784 if (lval != FILTER_VAL_NORM)
786 rval = test_arg(arg, arg->exp.right);
787 if (rval != FILTER_VAL_NORM)
789 return FILTER_VAL_NORM;
792 lval = test_arg(arg, arg->num.left);
793 if (lval != FILTER_VAL_NORM)
795 rval = test_arg(arg, arg->num.right);
796 if (rval != FILTER_VAL_NORM)
798 return FILTER_VAL_NORM;
801 if (arg->op.type != FILTER_OP_NOT) {
802 lval = test_arg(arg, arg->op.left);
804 case FILTER_VAL_NORM:
806 case FILTER_VAL_TRUE:
807 if (arg->op.type == FILTER_OP_OR)
808 return FILTER_VAL_TRUE;
809 rval = test_arg(arg, arg->op.right);
810 if (rval != FILTER_VAL_NORM)
813 reparent_op_arg(parent, arg, arg->op.right);
814 return FILTER_VAL_NORM;
816 case FILTER_VAL_FALSE:
817 if (arg->op.type == FILTER_OP_AND)
818 return FILTER_VAL_FALSE;
819 rval = test_arg(arg, arg->op.right);
820 if (rval != FILTER_VAL_NORM)
823 reparent_op_arg(parent, arg, arg->op.right);
824 return FILTER_VAL_NORM;
828 rval = test_arg(arg, arg->op.right);
830 case FILTER_VAL_NORM:
832 case FILTER_VAL_TRUE:
833 if (arg->op.type == FILTER_OP_OR)
834 return FILTER_VAL_TRUE;
835 if (arg->op.type == FILTER_OP_NOT)
836 return FILTER_VAL_FALSE;
838 reparent_op_arg(parent, arg, arg->op.left);
839 return FILTER_VAL_NORM;
841 case FILTER_VAL_FALSE:
842 if (arg->op.type == FILTER_OP_AND)
843 return FILTER_VAL_FALSE;
844 if (arg->op.type == FILTER_OP_NOT)
845 return FILTER_VAL_TRUE;
847 reparent_op_arg(parent, arg, arg->op.left);
848 return FILTER_VAL_NORM;
851 return FILTER_VAL_NORM;
853 die("bad arg in filter tree");
855 return FILTER_VAL_NORM;
858 /* Remove any unknown event fields */
859 static struct filter_arg *collapse_tree(struct filter_arg *arg)
861 enum filter_vals ret;
863 ret = test_arg(arg, arg);
865 case FILTER_VAL_NORM:
868 case FILTER_VAL_TRUE:
869 case FILTER_VAL_FALSE:
871 arg = allocate_arg();
872 arg->type = FILTER_ARG_BOOLEAN;
873 arg->boolean.value = ret == FILTER_VAL_TRUE;
880 process_filter(struct event_format *event, struct filter_arg **parg,
881 char **error_str, int not)
883 enum event_type type;
885 struct filter_arg *current_op = NULL;
886 struct filter_arg *current_exp = NULL;
887 struct filter_arg *left_item = NULL;
888 struct filter_arg *arg = NULL;
889 enum op_type op_type;
890 enum filter_op_type btype;
891 enum filter_exp_type etype;
892 enum filter_cmp_type ctype;
899 type = read_token(&token);
904 arg = create_arg_item(event, token, type, error_str);
909 else if (current_exp) {
910 ret = add_right(current_exp, arg, error_str);
914 /* Not's only one one expression */
930 show_error(error_str,
931 "Illegal token ','");
937 show_error(error_str,
938 "Open paren can not come after item");
942 show_error(error_str,
943 "Open paren can not come after expression");
947 ret = process_filter(event, &arg, error_str, 0);
950 show_error(error_str,
951 "Unbalanced number of '('");
956 /* A not wants just one expression */
965 ret = add_right(current_op, arg, error_str);
973 if (!current_op && !current_exp)
976 /* Make sure everything is finished at this level */
977 if (current_exp && !check_op_done(current_exp))
979 if (current_op && !check_op_done(current_op))
991 op_type = process_op(token, &btype, &ctype, &etype);
993 /* All expect a left arg except for NOT */
996 /* Logic ops need a left expression */
997 if (!current_exp && !current_op)
1001 /* logic only processes ops and exp */
1011 show_error(error_str,
1012 "Unknown op token %s", token);
1019 arg = create_arg_op(btype);
1021 ret = add_left(arg, current_op);
1023 ret = add_left(arg, current_exp);
1029 arg = create_arg_op(btype);
1031 ret = add_right(current_op, arg, error_str);
1035 ret = process_filter(event, &arg, error_str, 1);
1038 ret = add_right(current_exp, arg, error_str);
1045 if (op_type == OP_EXP)
1046 arg = create_arg_exp(etype);
1048 arg = create_arg_cmp(ctype);
1051 ret = add_right(current_op, arg, error_str);
1054 ret = add_left(arg, left_item);
1073 } while (type != EVENT_NONE);
1075 if (!current_op && !current_exp)
1079 current_op = current_exp;
1081 current_op = collapse_tree(current_op);
1088 show_error(error_str, "Syntax error");
1090 free_arg(current_op);
1091 free_arg(current_exp);
1098 process_event(struct event_format *event, const char *filter_str,
1099 struct filter_arg **parg, char **error_str)
1103 pevent_buffer_init(filter_str, strlen(filter_str));
1105 ret = process_filter(event, parg, error_str, 0);
1107 show_error(error_str,
1108 "Unbalanced number of ')'");
1114 /* If parg is NULL, then make it into FALSE */
1116 *parg = allocate_arg();
1117 (*parg)->type = FILTER_ARG_BOOLEAN;
1118 (*parg)->boolean.value = FILTER_FALSE;
1124 static int filter_event(struct event_filter *filter,
1125 struct event_format *event,
1126 const char *filter_str, char **error_str)
1128 struct filter_type *filter_type;
1129 struct filter_arg *arg;
1133 ret = process_event(event, filter_str, &arg, error_str);
1138 /* just add a TRUE arg */
1139 arg = allocate_arg();
1140 arg->type = FILTER_ARG_BOOLEAN;
1141 arg->boolean.value = FILTER_TRUE;
1144 filter_type = add_filter_type(filter, event->id);
1145 if (filter_type->filter)
1146 free_arg(filter_type->filter);
1147 filter_type->filter = arg;
1153 * pevent_filter_add_filter_str - add a new filter
1154 * @filter: the event filter to add to
1155 * @filter_str: the filter string that contains the filter
1156 * @error_str: string containing reason for failed filter
1158 * Returns 0 if the filter was successfully added
1159 * -1 if there was an error.
1161 * On error, if @error_str points to a string pointer,
1162 * it is set to the reason that the filter failed.
1163 * This string must be freed with "free".
1165 int pevent_filter_add_filter_str(struct event_filter *filter,
1166 const char *filter_str,
1169 struct pevent *pevent = filter->pevent;
1170 struct event_list *event;
1171 struct event_list *events = NULL;
1172 const char *filter_start;
1173 const char *next_event;
1175 char *event_name = NULL;
1176 char *sys_name = NULL;
1182 /* clear buffer to reset show error */
1183 pevent_buffer_init("", 0);
1188 filter_start = strchr(filter_str, ':');
1190 len = filter_start - filter_str;
1192 len = strlen(filter_str);
1196 next_event = strchr(filter_str, ',');
1198 (!filter_start || next_event < filter_start))
1199 len = next_event - filter_str;
1200 else if (filter_start)
1201 len = filter_start - filter_str;
1203 len = strlen(filter_str);
1205 this_event = malloc_or_die(len + 1);
1206 memcpy(this_event, filter_str, len);
1207 this_event[len] = 0;
1212 filter_str = next_event;
1214 sys_name = strtok_r(this_event, "/", &sp);
1215 event_name = strtok_r(NULL, "/", &sp);
1218 show_error(error_str, "No filter found");
1219 /* This can only happen when events is NULL, but still */
1220 free_events(events);
1225 /* Find this event */
1226 ret = find_event(pevent, &events, strim(sys_name), strim(event_name));
1229 show_error(error_str,
1230 "No event found under '%s.%s'",
1231 sys_name, event_name);
1233 show_error(error_str,
1234 "No event found under '%s'",
1236 free_events(events);
1241 } while (filter_str);
1247 /* filter starts here */
1248 for (event = events; event; event = event->next) {
1249 ret = filter_event(filter, event->event, filter_start,
1251 /* Failures are returned if a parse error happened */
1255 if (ret >= 0 && pevent->test_filters) {
1257 test = pevent_filter_make_string(filter, event->event->id);
1258 printf(" '%s: %s'\n", event->event->name, test);
1263 free_events(events);
1265 if (rtn >= 0 && pevent->test_filters)
1271 static void free_filter_type(struct filter_type *filter_type)
1273 free_arg(filter_type->filter);
1277 * pevent_filter_remove_event - remove a filter for an event
1278 * @filter: the event filter to remove from
1279 * @event_id: the event to remove a filter for
1281 * Removes the filter saved for an event defined by @event_id
1284 * Returns 1: if an event was removed
1285 * 0: if the event was not found
1287 int pevent_filter_remove_event(struct event_filter *filter,
1290 struct filter_type *filter_type;
1293 if (!filter->filters)
1296 filter_type = find_filter_type(filter, event_id);
1301 free_filter_type(filter_type);
1303 /* The filter_type points into the event_filters array */
1304 len = (unsigned long)(filter->event_filters + filter->filters) -
1305 (unsigned long)(filter_type + 1);
1307 memmove(filter_type, filter_type + 1, len);
1310 memset(&filter->event_filters[filter->filters], 0,
1311 sizeof(*filter_type));
1317 * pevent_filter_reset - clear all filters in a filter
1318 * @filter: the event filter to reset
1320 * Removes all filters from a filter and resets it.
1322 void pevent_filter_reset(struct event_filter *filter)
1326 for (i = 0; i < filter->filters; i++)
1327 free_filter_type(&filter->event_filters[i]);
1329 free(filter->event_filters);
1330 filter->filters = 0;
1331 filter->event_filters = NULL;
1334 void pevent_filter_free(struct event_filter *filter)
1336 pevent_unref(filter->pevent);
1338 pevent_filter_reset(filter);
1343 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg);
1345 static int copy_filter_type(struct event_filter *filter,
1346 struct event_filter *source,
1347 struct filter_type *filter_type)
1349 struct filter_arg *arg;
1350 struct event_format *event;
1355 /* Can't assume that the pevent's are the same */
1356 sys = filter_type->event->system;
1357 name = filter_type->event->name;
1358 event = pevent_find_event_by_name(filter->pevent, sys, name);
1362 str = arg_to_str(source, filter_type->filter);
1366 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
1367 /* Add trivial event */
1368 arg = allocate_arg();
1369 arg->type = FILTER_ARG_BOOLEAN;
1370 if (strcmp(str, "TRUE") == 0)
1371 arg->boolean.value = 1;
1373 arg->boolean.value = 0;
1375 filter_type = add_filter_type(filter, event->id);
1376 filter_type->filter = arg;
1382 filter_event(filter, event, str, NULL);
1389 * pevent_filter_copy - copy a filter using another filter
1390 * @dest - the filter to copy to
1391 * @source - the filter to copy from
1393 * Returns 0 on success and -1 if not all filters were copied
1395 int pevent_filter_copy(struct event_filter *dest, struct event_filter *source)
1400 pevent_filter_reset(dest);
1402 for (i = 0; i < source->filters; i++) {
1403 if (copy_filter_type(dest, source, &source->event_filters[i]))
1411 * pevent_update_trivial - update the trivial filters with the given filter
1412 * @dest - the filter to update
1413 * @source - the filter as the source of the update
1414 * @type - the type of trivial filter to update.
1416 * Scan dest for trivial events matching @type to replace with the source.
1418 * Returns 0 on success and -1 if there was a problem updating, but
1419 * events may have still been updated on error.
1421 int pevent_update_trivial(struct event_filter *dest, struct event_filter *source,
1422 enum filter_trivial_type type)
1424 struct pevent *src_pevent;
1425 struct pevent *dest_pevent;
1426 struct event_format *event;
1427 struct filter_type *filter_type;
1428 struct filter_arg *arg;
1432 src_pevent = source->pevent;
1433 dest_pevent = dest->pevent;
1435 /* Do nothing if either of the filters has nothing to filter */
1436 if (!dest->filters || !source->filters)
1439 for (i = 0; i < dest->filters; i++) {
1440 filter_type = &dest->event_filters[i];
1441 arg = filter_type->filter;
1442 if (arg->type != FILTER_ARG_BOOLEAN)
1444 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) ||
1445 (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE))
1448 event = filter_type->event;
1450 if (src_pevent != dest_pevent) {
1452 event = pevent_find_event_by_name(src_pevent,
1459 str = pevent_filter_make_string(source, event->id);
1463 /* Don't bother if the filter is trivial too */
1464 if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0)
1465 filter_event(dest, event, str, NULL);
1472 * pevent_filter_clear_trivial - clear TRUE and FALSE filters
1473 * @filter: the filter to remove trivial filters from
1474 * @type: remove only true, false, or both
1476 * Removes filters that only contain a TRUE or FALES boolean arg.
1478 void pevent_filter_clear_trivial(struct event_filter *filter,
1479 enum filter_trivial_type type)
1481 struct filter_type *filter_type;
1486 if (!filter->filters)
1490 * Two steps, first get all ids with trivial filters.
1491 * then remove those ids.
1493 for (i = 0; i < filter->filters; i++) {
1494 filter_type = &filter->event_filters[i];
1495 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1498 case FILTER_TRIVIAL_FALSE:
1499 if (filter_type->filter->boolean.value)
1501 case FILTER_TRIVIAL_TRUE:
1502 if (!filter_type->filter->boolean.value)
1508 ids = realloc(ids, sizeof(*ids) * (count + 1));
1510 ids = malloc(sizeof(*ids));
1512 die("Can't allocate ids");
1513 ids[count++] = filter_type->event_id;
1519 for (i = 0; i < count; i++)
1520 pevent_filter_remove_event(filter, ids[i]);
1526 * pevent_filter_event_has_trivial - return true event contains trivial filter
1527 * @filter: the filter with the information
1528 * @event_id: the id of the event to test
1529 * @type: trivial type to test for (TRUE, FALSE, EITHER)
1531 * Returns 1 if the event contains a matching trivial type
1534 int pevent_filter_event_has_trivial(struct event_filter *filter,
1536 enum filter_trivial_type type)
1538 struct filter_type *filter_type;
1540 if (!filter->filters)
1543 filter_type = find_filter_type(filter, event_id);
1548 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1552 case FILTER_TRIVIAL_FALSE:
1553 return !filter_type->filter->boolean.value;
1555 case FILTER_TRIVIAL_TRUE:
1556 return filter_type->filter->boolean.value;
1562 static int test_filter(struct event_format *event,
1563 struct filter_arg *arg, struct pevent_record *record);
1566 get_comm(struct event_format *event, struct pevent_record *record)
1571 pid = pevent_data_pid(event->pevent, record);
1572 comm = pevent_data_comm_from_pid(event->pevent, pid);
1576 static unsigned long long
1577 get_value(struct event_format *event,
1578 struct format_field *field, struct pevent_record *record)
1580 unsigned long long val;
1582 /* Handle our dummy "comm" field */
1583 if (field == &comm) {
1586 name = get_comm(event, record);
1587 return (unsigned long)name;
1590 pevent_read_number_field(field, record->data, &val);
1592 if (!(field->flags & FIELD_IS_SIGNED))
1595 switch (field->size) {
1603 return (long long)val;
1608 static unsigned long long
1609 get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record);
1611 static unsigned long long
1612 get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
1614 unsigned long long lval, rval;
1616 lval = get_arg_value(event, arg->exp.left, record);
1617 rval = get_arg_value(event, arg->exp.right, record);
1619 switch (arg->exp.type) {
1620 case FILTER_EXP_ADD:
1623 case FILTER_EXP_SUB:
1626 case FILTER_EXP_MUL:
1629 case FILTER_EXP_DIV:
1632 case FILTER_EXP_MOD:
1635 case FILTER_EXP_RSHIFT:
1636 return lval >> rval;
1638 case FILTER_EXP_LSHIFT:
1639 return lval << rval;
1641 case FILTER_EXP_AND:
1647 case FILTER_EXP_XOR:
1650 case FILTER_EXP_NOT:
1652 die("error in exp");
1657 static unsigned long long
1658 get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
1660 switch (arg->type) {
1661 case FILTER_ARG_FIELD:
1662 return get_value(event, arg->field.field, record);
1664 case FILTER_ARG_VALUE:
1665 if (arg->value.type != FILTER_NUMBER)
1666 die("must have number field!");
1667 return arg->value.val;
1669 case FILTER_ARG_EXP:
1670 return get_exp_value(event, arg, record);
1673 die("oops in filter");
1678 static int test_num(struct event_format *event,
1679 struct filter_arg *arg, struct pevent_record *record)
1681 unsigned long long lval, rval;
1683 lval = get_arg_value(event, arg->num.left, record);
1684 rval = get_arg_value(event, arg->num.right, record);
1686 switch (arg->num.type) {
1688 return lval == rval;
1691 return lval != rval;
1700 return lval >= rval;
1703 return lval <= rval;
1711 static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
1713 struct event_format *event;
1714 struct pevent *pevent;
1715 unsigned long long addr;
1716 const char *val = NULL;
1719 /* If the field is not a string convert it */
1720 if (arg->str.field->flags & FIELD_IS_STRING) {
1721 val = record->data + arg->str.field->offset;
1724 * We need to copy the data since we can't be sure the field
1725 * is null terminated.
1727 if (*(val + arg->str.field->size - 1)) {
1729 memcpy(arg->str.buffer, val, arg->str.field->size);
1730 /* the buffer is already NULL terminated */
1731 val = arg->str.buffer;
1735 event = arg->str.field->event;
1736 pevent = event->pevent;
1737 addr = get_value(event, arg->str.field, record);
1739 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
1740 /* convert to a kernel symbol */
1741 val = pevent_find_function(pevent, addr);
1744 /* just use the hex of the string name */
1745 snprintf(hex, 64, "0x%llx", addr);
1753 static int test_str(struct event_format *event,
1754 struct filter_arg *arg, struct pevent_record *record)
1758 if (arg->str.field == &comm)
1759 val = get_comm(event, record);
1761 val = get_field_str(arg, record);
1763 switch (arg->str.type) {
1764 case FILTER_CMP_MATCH:
1765 return strcmp(val, arg->str.val) == 0;
1767 case FILTER_CMP_NOT_MATCH:
1768 return strcmp(val, arg->str.val) != 0;
1770 case FILTER_CMP_REGEX:
1771 /* Returns zero on match */
1772 return !regexec(&arg->str.reg, val, 0, NULL, 0);
1774 case FILTER_CMP_NOT_REGEX:
1775 return regexec(&arg->str.reg, val, 0, NULL, 0);
1783 static int test_op(struct event_format *event,
1784 struct filter_arg *arg, struct pevent_record *record)
1786 switch (arg->op.type) {
1788 return test_filter(event, arg->op.left, record) &&
1789 test_filter(event, arg->op.right, record);
1792 return test_filter(event, arg->op.left, record) ||
1793 test_filter(event, arg->op.right, record);
1796 return !test_filter(event, arg->op.right, record);
1804 static int test_filter(struct event_format *event,
1805 struct filter_arg *arg, struct pevent_record *record)
1807 switch (arg->type) {
1808 case FILTER_ARG_BOOLEAN:
1810 return arg->boolean.value;
1813 return test_op(event, arg, record);
1815 case FILTER_ARG_NUM:
1816 return test_num(event, arg, record);
1818 case FILTER_ARG_STR:
1819 return test_str(event, arg, record);
1821 case FILTER_ARG_EXP:
1822 case FILTER_ARG_VALUE:
1823 case FILTER_ARG_FIELD:
1825 * Expressions, fields and values evaluate
1826 * to true if they return non zero
1828 return !!get_arg_value(event, arg, record);
1838 * pevent_event_filtered - return true if event has filter
1839 * @filter: filter struct with filter information
1840 * @event_id: event id to test if filter exists
1842 * Returns 1 if filter found for @event_id
1845 int pevent_event_filtered(struct event_filter *filter,
1848 struct filter_type *filter_type;
1850 if (!filter->filters)
1853 filter_type = find_filter_type(filter, event_id);
1855 return filter_type ? 1 : 0;
1859 * pevent_filter_match - test if a record matches a filter
1860 * @filter: filter struct with filter information
1861 * @record: the record to test against the filter
1864 * 1 - filter found for event and @record matches
1865 * 0 - filter found for event and @record does not match
1866 * -1 - no filter found for @record's event
1867 * -2 - if no filters exist
1869 int pevent_filter_match(struct event_filter *filter,
1870 struct pevent_record *record)
1872 struct pevent *pevent = filter->pevent;
1873 struct filter_type *filter_type;
1876 if (!filter->filters)
1879 event_id = pevent_data_type(pevent, record);
1881 filter_type = find_filter_type(filter, event_id);
1884 return FILTER_NOEXIST;
1886 return test_filter(filter_type->event, filter_type->filter, record) ?
1887 FILTER_MATCH : FILTER_MISS;
1890 static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
1901 switch (arg->op.type) {
1909 left = arg_to_str(filter, arg->op.left);
1910 right = arg_to_str(filter, arg->op.right);
1911 if (!left || !right)
1914 /* Try to consolidate boolean values */
1915 if (strcmp(left, "TRUE") == 0)
1917 else if (strcmp(left, "FALSE") == 0)
1920 if (strcmp(right, "TRUE") == 0)
1922 else if (strcmp(right, "FALSE") == 0)
1925 if (left_val >= 0) {
1926 if ((arg->op.type == FILTER_OP_AND && !left_val) ||
1927 (arg->op.type == FILTER_OP_OR && left_val)) {
1928 /* Just return left value */
1933 if (right_val >= 0) {
1934 /* just evaluate this. */
1936 switch (arg->op.type) {
1938 val = left_val && right_val;
1941 val = left_val || right_val;
1946 str = malloc_or_die(6);
1948 strcpy(str, "TRUE");
1950 strcpy(str, "FALSE");
1954 if (right_val >= 0) {
1955 if ((arg->op.type == FILTER_OP_AND && !right_val) ||
1956 (arg->op.type == FILTER_OP_OR && right_val)) {
1957 /* Just return right value */
1962 /* The right value is meaningless */
1968 len = strlen(left) + strlen(right) + strlen(op) + 10;
1969 str = malloc_or_die(len);
1970 snprintf(str, len, "(%s) %s (%s)",
1976 right = arg_to_str(filter, arg->op.right);
1980 /* See if we can consolidate */
1981 if (strcmp(right, "TRUE") == 0)
1983 else if (strcmp(right, "FALSE") == 0)
1985 if (right_val >= 0) {
1986 /* just return the opposite */
1987 str = malloc_or_die(6);
1989 strcpy(str, "FALSE");
1991 strcpy(str, "TRUE");
1994 len = strlen(right) + strlen(op) + 3;
1995 str = malloc_or_die(len);
1996 snprintf(str, len, "%s(%s)", op, right);
2008 static char *val_to_str(struct event_filter *filter, struct filter_arg *arg)
2012 str = malloc_or_die(30);
2014 snprintf(str, 30, "%lld", arg->value.val);
2019 static char *field_to_str(struct event_filter *filter, struct filter_arg *arg)
2021 return strdup(arg->field.field->name);
2024 static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2032 lstr = arg_to_str(filter, arg->exp.left);
2033 rstr = arg_to_str(filter, arg->exp.right);
2035 switch (arg->exp.type) {
2036 case FILTER_EXP_ADD:
2039 case FILTER_EXP_SUB:
2042 case FILTER_EXP_MUL:
2045 case FILTER_EXP_DIV:
2048 case FILTER_EXP_MOD:
2051 case FILTER_EXP_RSHIFT:
2054 case FILTER_EXP_LSHIFT:
2057 case FILTER_EXP_AND:
2063 case FILTER_EXP_XOR:
2070 len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
2071 str = malloc_or_die(len);
2072 snprintf(str, len, "%s %s %s", lstr, op, rstr);
2079 static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2087 lstr = arg_to_str(filter, arg->num.left);
2088 rstr = arg_to_str(filter, arg->num.right);
2090 switch (arg->num.type) {
2114 len = strlen(lstr) + strlen(op) + strlen(rstr) + 4;
2115 str = malloc_or_die(len);
2116 sprintf(str, "%s %s %s", lstr, op, rstr);
2130 static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
2136 switch (arg->str.type) {
2137 case FILTER_CMP_MATCH:
2140 case FILTER_CMP_NOT_MATCH:
2144 case FILTER_CMP_REGEX:
2148 case FILTER_CMP_NOT_REGEX:
2152 len = strlen(arg->str.field->name) + strlen(op) +
2153 strlen(arg->str.val) + 6;
2154 str = malloc_or_die(len);
2155 snprintf(str, len, "%s %s \"%s\"",
2156 arg->str.field->name,
2167 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
2171 switch (arg->type) {
2172 case FILTER_ARG_BOOLEAN:
2173 str = malloc_or_die(6);
2174 if (arg->boolean.value)
2175 strcpy(str, "TRUE");
2177 strcpy(str, "FALSE");
2181 return op_to_str(filter, arg);
2183 case FILTER_ARG_NUM:
2184 return num_to_str(filter, arg);
2186 case FILTER_ARG_STR:
2187 return str_to_str(filter, arg);
2189 case FILTER_ARG_VALUE:
2190 return val_to_str(filter, arg);
2192 case FILTER_ARG_FIELD:
2193 return field_to_str(filter, arg);
2195 case FILTER_ARG_EXP:
2196 return exp_to_str(filter, arg);
2206 * pevent_filter_make_string - return a string showing the filter
2207 * @filter: filter struct with filter information
2208 * @event_id: the event id to return the filter string with
2210 * Returns a string that displays the filter contents.
2211 * This string must be freed with free(str).
2212 * NULL is returned if no filter is found.
2215 pevent_filter_make_string(struct event_filter *filter, int event_id)
2217 struct filter_type *filter_type;
2219 if (!filter->filters)
2222 filter_type = find_filter_type(filter, event_id);
2227 return arg_to_str(filter, filter_type->filter);
2231 * pevent_filter_compare - compare two filters and return if they are the same
2232 * @filter1: Filter to compare with @filter2
2233 * @filter2: Filter to compare with @filter1
2236 * 1 if the two filters hold the same content.
2239 int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2)
2241 struct filter_type *filter_type1;
2242 struct filter_type *filter_type2;
2247 /* Do the easy checks first */
2248 if (filter1->filters != filter2->filters)
2250 if (!filter1->filters && !filter2->filters)
2254 * Now take a look at each of the events to see if they have the same
2257 for (i = 0; i < filter1->filters; i++) {
2258 filter_type1 = &filter1->event_filters[i];
2259 filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2262 if (filter_type1->filter->type != filter_type2->filter->type)
2264 switch (filter_type1->filter->type) {
2265 case FILTER_TRIVIAL_FALSE:
2266 case FILTER_TRIVIAL_TRUE:
2267 /* trivial types just need the type compared */
2272 /* The best way to compare complex filters is with strings */
2273 str1 = arg_to_str(filter1, filter_type1->filter);
2274 str2 = arg_to_str(filter2, filter_type2->filter);
2275 result = strcmp(str1, str2) != 0;
2282 if (i < filter1->filters)