1 // SPDX-License-Identifier: LGPL-2.1
3 * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
11 #include <sys/types.h>
13 #include "event-parse.h"
14 #include "event-utils.h"
19 static struct format_field comm = {
23 static struct format_field cpu = {
28 struct event_list *next;
29 struct event_format *event;
32 static void show_error(char *error_buf, const char *fmt, ...)
34 unsigned long long index;
40 input = tep_get_input_buf();
41 index = tep_get_input_buf_ptr();
42 len = input ? strlen(input) : 0;
45 strcpy(error_buf, input);
46 error_buf[len] = '\n';
47 for (i = 1; i < len && i < index; i++)
48 error_buf[len+i] = ' ';
49 error_buf[len + i] = '^';
50 error_buf[len + i + 1] = '\n';
55 vsnprintf(error_buf + len, TEP_FILTER_ERROR_BUFSZ - len, fmt, ap);
59 static void free_token(char *token)
61 tep_free_token(token);
64 static enum event_type read_token(char **tok)
71 type = tep_read_token(&token);
72 } while (type == EVENT_NEWLINE || type == EVENT_SPACE);
74 /* If token is = or ! check to see if the next char is ~ */
76 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
77 tep_peek_char() == '~') {
84 sprintf(*tok, "%c%c", *token, '~');
86 /* Now remove the '~' from the buffer */
87 tep_read_token(&token);
95 static int filter_cmp(const void *a, const void *b)
97 const struct filter_type *ea = a;
98 const struct filter_type *eb = b;
100 if (ea->event_id < eb->event_id)
103 if (ea->event_id > eb->event_id)
109 static struct filter_type *
110 find_filter_type(struct event_filter *filter, int id)
112 struct filter_type *filter_type;
113 struct filter_type key;
117 filter_type = bsearch(&key, filter->event_filters,
119 sizeof(*filter->event_filters),
125 static struct filter_type *
126 add_filter_type(struct event_filter *filter, int id)
128 struct filter_type *filter_type;
131 filter_type = find_filter_type(filter, id);
135 filter_type = realloc(filter->event_filters,
136 sizeof(*filter->event_filters) *
137 (filter->filters + 1));
141 filter->event_filters = filter_type;
143 for (i = 0; i < filter->filters; i++) {
144 if (filter->event_filters[i].event_id > id)
148 if (i < filter->filters)
149 memmove(&filter->event_filters[i+1],
150 &filter->event_filters[i],
151 sizeof(*filter->event_filters) *
152 (filter->filters - i));
154 filter_type = &filter->event_filters[i];
155 filter_type->event_id = id;
156 filter_type->event = tep_find_event(filter->pevent, id);
157 filter_type->filter = NULL;
165 * tep_filter_alloc - create a new event filter
166 * @pevent: The pevent that this filter is associated with
168 struct event_filter *tep_filter_alloc(struct tep_handle *pevent)
170 struct event_filter *filter;
172 filter = malloc(sizeof(*filter));
176 memset(filter, 0, sizeof(*filter));
177 filter->pevent = pevent;
183 static struct filter_arg *allocate_arg(void)
185 return calloc(1, sizeof(struct filter_arg));
188 static void free_arg(struct filter_arg *arg)
194 case FILTER_ARG_NONE:
195 case FILTER_ARG_BOOLEAN:
199 free_arg(arg->num.left);
200 free_arg(arg->num.right);
204 free_arg(arg->exp.left);
205 free_arg(arg->exp.right);
210 regfree(&arg->str.reg);
211 free(arg->str.buffer);
214 case FILTER_ARG_VALUE:
215 if (arg->value.type == FILTER_STRING ||
216 arg->value.type == FILTER_CHAR)
217 free(arg->value.str);
221 free_arg(arg->op.left);
222 free_arg(arg->op.right);
230 static int add_event(struct event_list **events,
231 struct event_format *event)
233 struct event_list *list;
235 list = malloc(sizeof(*list));
239 list->next = *events;
245 static int event_match(struct event_format *event,
246 regex_t *sreg, regex_t *ereg)
249 return !regexec(sreg, event->system, 0, NULL, 0) &&
250 !regexec(ereg, event->name, 0, NULL, 0);
253 return !regexec(ereg, event->system, 0, NULL, 0) ||
254 !regexec(ereg, event->name, 0, NULL, 0);
257 static enum tep_errno
258 find_event(struct tep_handle *pevent, struct event_list **events,
259 char *sys_name, char *event_name)
261 struct event_format *event;
271 /* if no name is given, then swap sys and name */
272 event_name = sys_name;
276 ret = asprintf(®, "^%s$", event_name);
278 return TEP_ERRNO__MEM_ALLOC_FAILED;
280 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
284 return TEP_ERRNO__INVALID_EVENT_NAME;
287 ret = asprintf(®, "^%s$", sys_name);
290 return TEP_ERRNO__MEM_ALLOC_FAILED;
293 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
297 return TEP_ERRNO__INVALID_EVENT_NAME;
301 for (i = 0; i < pevent->nr_events; i++) {
302 event = pevent->events[i];
303 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
305 if (add_event(events, event) < 0) {
317 return TEP_ERRNO__EVENT_NOT_FOUND;
319 return TEP_ERRNO__MEM_ALLOC_FAILED;
324 static void free_events(struct event_list *events)
326 struct event_list *event;
330 events = events->next;
335 static enum tep_errno
336 create_arg_item(struct event_format *event, const char *token,
337 enum event_type type, struct filter_arg **parg, char *error_str)
339 struct format_field *field;
340 struct filter_arg *arg;
342 arg = allocate_arg();
344 show_error(error_str, "failed to allocate filter arg");
345 return TEP_ERRNO__MEM_ALLOC_FAILED;
352 arg->type = FILTER_ARG_VALUE;
354 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
355 arg->value.str = strdup(token);
356 if (!arg->value.str) {
358 show_error(error_str, "failed to allocate string filter arg");
359 return TEP_ERRNO__MEM_ALLOC_FAILED;
363 /* if it is a number, then convert it */
364 if (isdigit(token[0])) {
365 arg->type = FILTER_ARG_VALUE;
366 arg->value.type = FILTER_NUMBER;
367 arg->value.val = strtoull(token, NULL, 0);
370 /* Consider this a field */
371 field = tep_find_any_field(event, token);
373 /* If token is 'COMM' or 'CPU' then it is special */
374 if (strcmp(token, COMM) == 0) {
376 } else if (strcmp(token, CPU) == 0) {
379 /* not a field, Make it false */
380 arg->type = FILTER_ARG_BOOLEAN;
381 arg->boolean.value = FILTER_FALSE;
385 arg->type = FILTER_ARG_FIELD;
386 arg->field.field = field;
390 show_error(error_str, "expected a value but found %s", token);
391 return TEP_ERRNO__UNEXPECTED_TYPE;
397 static struct filter_arg *
398 create_arg_op(enum filter_op_type btype)
400 struct filter_arg *arg;
402 arg = allocate_arg();
406 arg->type = FILTER_ARG_OP;
407 arg->op.type = btype;
412 static struct filter_arg *
413 create_arg_exp(enum filter_exp_type etype)
415 struct filter_arg *arg;
417 arg = allocate_arg();
421 arg->type = FILTER_ARG_EXP;
422 arg->exp.type = etype;
427 static struct filter_arg *
428 create_arg_cmp(enum filter_cmp_type ctype)
430 struct filter_arg *arg;
432 arg = allocate_arg();
436 /* Use NUM and change if necessary */
437 arg->type = FILTER_ARG_NUM;
438 arg->num.type = ctype;
443 static enum tep_errno
444 add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
446 struct filter_arg *left;
468 * The arg must be num, str, or field
471 case FILTER_ARG_VALUE:
472 case FILTER_ARG_FIELD:
475 show_error(error_str, "Illegal rvalue");
476 return TEP_ERRNO__ILLEGAL_RVALUE;
480 * Depending on the type, we may need to
481 * convert this to a string or regex.
483 switch (arg->value.type) {
486 * A char should be converted to number if
487 * the string is 1 byte, and the compare
490 if (strlen(arg->value.str) == 1 &&
491 op->num.type != FILTER_CMP_REGEX &&
492 op->num.type != FILTER_CMP_NOT_REGEX) {
493 arg->value.type = FILTER_NUMBER;
499 /* convert op to a string arg */
500 op_type = op->num.type;
502 str = arg->value.str;
504 /* reset the op for the new field */
505 memset(op, 0, sizeof(*op));
508 * If left arg was a field not found then
509 * NULL the entire op.
511 if (left->type == FILTER_ARG_BOOLEAN) {
514 op->type = FILTER_ARG_BOOLEAN;
515 op->boolean.value = FILTER_FALSE;
519 /* Left arg must be a field */
520 if (left->type != FILTER_ARG_FIELD) {
521 show_error(error_str,
522 "Illegal lvalue for string comparison");
523 return TEP_ERRNO__ILLEGAL_LVALUE;
526 /* Make sure this is a valid string compare */
529 op_type = FILTER_CMP_MATCH;
532 op_type = FILTER_CMP_NOT_MATCH;
535 case FILTER_CMP_REGEX:
536 case FILTER_CMP_NOT_REGEX:
537 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB);
539 show_error(error_str,
540 "RegEx '%s' did not compute",
542 return TEP_ERRNO__INVALID_REGEX;
546 show_error(error_str,
547 "Illegal comparison for string");
548 return TEP_ERRNO__ILLEGAL_STRING_CMP;
551 op->type = FILTER_ARG_STR;
552 op->str.type = op_type;
553 op->str.field = left->field.field;
554 op->str.val = strdup(str);
556 show_error(error_str, "Failed to allocate string filter");
557 return TEP_ERRNO__MEM_ALLOC_FAILED;
560 * Need a buffer to copy data for tests
562 op->str.buffer = malloc(op->str.field->size + 1);
563 if (!op->str.buffer) {
564 show_error(error_str, "Failed to allocate string filter");
565 return TEP_ERRNO__MEM_ALLOC_FAILED;
567 /* Null terminate this buffer */
568 op->str.buffer[op->str.field->size] = 0;
570 /* We no longer have left or right args */
579 switch (op->num.type) {
580 case FILTER_CMP_REGEX:
581 case FILTER_CMP_NOT_REGEX:
582 show_error(error_str,
583 "Op not allowed with integers");
584 return TEP_ERRNO__ILLEGAL_INTEGER_CMP;
590 /* numeric compare */
604 show_error(error_str, "Syntax error");
605 return TEP_ERRNO__SYNTAX_ERROR;
608 static struct filter_arg *
609 rotate_op_right(struct filter_arg *a, struct filter_arg *b)
611 struct filter_arg *arg;
618 static enum tep_errno add_left(struct filter_arg *op, struct filter_arg *arg)
622 if (arg->type == FILTER_ARG_OP)
623 arg = rotate_op_right(arg, op);
631 if (arg->type == FILTER_ARG_OP)
632 arg = rotate_op_right(arg, op);
634 /* left arg of compares must be a field */
635 if (arg->type != FILTER_ARG_FIELD &&
636 arg->type != FILTER_ARG_BOOLEAN)
637 return TEP_ERRNO__INVALID_ARG_TYPE;
641 return TEP_ERRNO__INVALID_ARG_TYPE;
654 static enum op_type process_op(const char *token,
655 enum filter_op_type *btype,
656 enum filter_cmp_type *ctype,
657 enum filter_exp_type *etype)
659 *btype = FILTER_OP_NOT;
660 *etype = FILTER_EXP_NONE;
661 *ctype = FILTER_CMP_NONE;
663 if (strcmp(token, "&&") == 0)
664 *btype = FILTER_OP_AND;
665 else if (strcmp(token, "||") == 0)
666 *btype = FILTER_OP_OR;
667 else if (strcmp(token, "!") == 0)
670 if (*btype != FILTER_OP_NOT)
673 /* Check for value expressions */
674 if (strcmp(token, "+") == 0) {
675 *etype = FILTER_EXP_ADD;
676 } else if (strcmp(token, "-") == 0) {
677 *etype = FILTER_EXP_SUB;
678 } else if (strcmp(token, "*") == 0) {
679 *etype = FILTER_EXP_MUL;
680 } else if (strcmp(token, "/") == 0) {
681 *etype = FILTER_EXP_DIV;
682 } else if (strcmp(token, "%") == 0) {
683 *etype = FILTER_EXP_MOD;
684 } else if (strcmp(token, ">>") == 0) {
685 *etype = FILTER_EXP_RSHIFT;
686 } else if (strcmp(token, "<<") == 0) {
687 *etype = FILTER_EXP_LSHIFT;
688 } else if (strcmp(token, "&") == 0) {
689 *etype = FILTER_EXP_AND;
690 } else if (strcmp(token, "|") == 0) {
691 *etype = FILTER_EXP_OR;
692 } else if (strcmp(token, "^") == 0) {
693 *etype = FILTER_EXP_XOR;
694 } else if (strcmp(token, "~") == 0)
695 *etype = FILTER_EXP_NOT;
697 if (*etype != FILTER_EXP_NONE)
700 /* Check for compares */
701 if (strcmp(token, "==") == 0)
702 *ctype = FILTER_CMP_EQ;
703 else if (strcmp(token, "!=") == 0)
704 *ctype = FILTER_CMP_NE;
705 else if (strcmp(token, "<") == 0)
706 *ctype = FILTER_CMP_LT;
707 else if (strcmp(token, ">") == 0)
708 *ctype = FILTER_CMP_GT;
709 else if (strcmp(token, "<=") == 0)
710 *ctype = FILTER_CMP_LE;
711 else if (strcmp(token, ">=") == 0)
712 *ctype = FILTER_CMP_GE;
713 else if (strcmp(token, "=~") == 0)
714 *ctype = FILTER_CMP_REGEX;
715 else if (strcmp(token, "!~") == 0)
716 *ctype = FILTER_CMP_NOT_REGEX;
723 static int check_op_done(struct filter_arg *arg)
727 return arg->exp.right != NULL;
730 return arg->op.right != NULL;
733 return arg->num.right != NULL;
736 /* A string conversion is always done */
739 case FILTER_ARG_BOOLEAN:
740 /* field not found, is ok */
754 static enum tep_errno
755 reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
756 struct filter_arg *arg, char *error_str)
758 struct filter_arg *other_child;
759 struct filter_arg **ptr;
761 if (parent->type != FILTER_ARG_OP &&
762 arg->type != FILTER_ARG_OP) {
763 show_error(error_str, "can not reparent other than OP");
764 return TEP_ERRNO__REPARENT_NOT_OP;
767 /* Get the sibling */
768 if (old_child->op.right == arg) {
769 ptr = &old_child->op.right;
770 other_child = old_child->op.left;
771 } else if (old_child->op.left == arg) {
772 ptr = &old_child->op.left;
773 other_child = old_child->op.right;
775 show_error(error_str, "Error in reparent op, find other child");
776 return TEP_ERRNO__REPARENT_FAILED;
779 /* Detach arg from old_child */
783 if (parent == old_child) {
784 free_arg(other_child);
786 /* Free arg without recussion */
791 if (parent->op.right == old_child)
792 ptr = &parent->op.right;
793 else if (parent->op.left == old_child)
794 ptr = &parent->op.left;
796 show_error(error_str, "Error in reparent op");
797 return TEP_ERRNO__REPARENT_FAILED;
806 /* Returns either filter_vals (success) or tep_errno (failfure) */
807 static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
815 case FILTER_ARG_BOOLEAN:
816 return FILTER_VAL_FALSE + arg->boolean.value;
820 case FILTER_ARG_VALUE:
821 case FILTER_ARG_FIELD:
822 return FILTER_VAL_NORM;
825 lval = test_arg(arg, arg->exp.left, error_str);
826 if (lval != FILTER_VAL_NORM)
828 rval = test_arg(arg, arg->exp.right, error_str);
829 if (rval != FILTER_VAL_NORM)
831 return FILTER_VAL_NORM;
834 lval = test_arg(arg, arg->num.left, error_str);
835 if (lval != FILTER_VAL_NORM)
837 rval = test_arg(arg, arg->num.right, error_str);
838 if (rval != FILTER_VAL_NORM)
840 return FILTER_VAL_NORM;
843 if (arg->op.type != FILTER_OP_NOT) {
844 lval = test_arg(arg, arg->op.left, error_str);
846 case FILTER_VAL_NORM:
848 case FILTER_VAL_TRUE:
849 if (arg->op.type == FILTER_OP_OR)
850 return FILTER_VAL_TRUE;
851 rval = test_arg(arg, arg->op.right, error_str);
852 if (rval != FILTER_VAL_NORM)
855 return reparent_op_arg(parent, arg, arg->op.right,
858 case FILTER_VAL_FALSE:
859 if (arg->op.type == FILTER_OP_AND)
860 return FILTER_VAL_FALSE;
861 rval = test_arg(arg, arg->op.right, error_str);
862 if (rval != FILTER_VAL_NORM)
865 return reparent_op_arg(parent, arg, arg->op.right,
873 rval = test_arg(arg, arg->op.right, error_str);
875 case FILTER_VAL_NORM:
879 case FILTER_VAL_TRUE:
880 if (arg->op.type == FILTER_OP_OR)
881 return FILTER_VAL_TRUE;
882 if (arg->op.type == FILTER_OP_NOT)
883 return FILTER_VAL_FALSE;
885 return reparent_op_arg(parent, arg, arg->op.left,
888 case FILTER_VAL_FALSE:
889 if (arg->op.type == FILTER_OP_AND)
890 return FILTER_VAL_FALSE;
891 if (arg->op.type == FILTER_OP_NOT)
892 return FILTER_VAL_TRUE;
894 return reparent_op_arg(parent, arg, arg->op.left,
900 show_error(error_str, "bad arg in filter tree");
901 return TEP_ERRNO__BAD_FILTER_ARG;
903 return FILTER_VAL_NORM;
906 /* Remove any unknown event fields */
907 static int collapse_tree(struct filter_arg *arg,
908 struct filter_arg **arg_collapsed, char *error_str)
912 ret = test_arg(arg, arg, error_str);
914 case FILTER_VAL_NORM:
917 case FILTER_VAL_TRUE:
918 case FILTER_VAL_FALSE:
920 arg = allocate_arg();
922 arg->type = FILTER_ARG_BOOLEAN;
923 arg->boolean.value = ret == FILTER_VAL_TRUE;
925 show_error(error_str, "Failed to allocate filter arg");
926 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
931 /* test_arg() already set the error_str */
937 *arg_collapsed = arg;
941 static enum tep_errno
942 process_filter(struct event_format *event, struct filter_arg **parg,
943 char *error_str, int not)
945 enum event_type type;
947 struct filter_arg *current_op = NULL;
948 struct filter_arg *current_exp = NULL;
949 struct filter_arg *left_item = NULL;
950 struct filter_arg *arg = NULL;
951 enum op_type op_type;
952 enum filter_op_type btype;
953 enum filter_exp_type etype;
954 enum filter_cmp_type ctype;
961 type = read_token(&token);
966 ret = create_arg_item(event, token, type, &arg, error_str);
971 else if (current_exp) {
972 ret = add_right(current_exp, arg, error_str);
976 /* Not's only one one expression */
992 show_error(error_str, "Illegal token ','");
993 ret = TEP_ERRNO__ILLEGAL_TOKEN;
999 show_error(error_str,
1000 "Open paren can not come after item");
1001 ret = TEP_ERRNO__INVALID_PAREN;
1005 show_error(error_str,
1006 "Open paren can not come after expression");
1007 ret = TEP_ERRNO__INVALID_PAREN;
1011 ret = process_filter(event, &arg, error_str, 0);
1012 if (ret != TEP_ERRNO__UNBALANCED_PAREN) {
1014 show_error(error_str,
1015 "Unbalanced number of '('");
1016 ret = TEP_ERRNO__UNBALANCED_PAREN;
1022 /* A not wants just one expression */
1031 ret = add_right(current_op, arg, error_str);
1039 if (!current_op && !current_exp)
1042 /* Make sure everything is finished at this level */
1043 if (current_exp && !check_op_done(current_exp))
1045 if (current_op && !check_op_done(current_op))
1051 *parg = current_exp;
1053 return TEP_ERRNO__UNBALANCED_PAREN;
1058 op_type = process_op(token, &btype, &ctype, &etype);
1060 /* All expect a left arg except for NOT */
1063 /* Logic ops need a left expression */
1064 if (!current_exp && !current_op)
1068 /* logic only processes ops and exp */
1078 show_error(error_str,
1079 "Unknown op token %s", token);
1080 ret = TEP_ERRNO__UNKNOWN_TOKEN;
1087 arg = create_arg_op(btype);
1091 ret = add_left(arg, current_op);
1093 ret = add_left(arg, current_exp);
1099 arg = create_arg_op(btype);
1103 ret = add_right(current_op, arg, error_str);
1107 ret = process_filter(event, &arg, error_str, 1);
1110 ret = add_right(current_exp, arg, error_str);
1117 if (op_type == OP_EXP)
1118 arg = create_arg_exp(etype);
1120 arg = create_arg_cmp(ctype);
1125 ret = add_right(current_op, arg, error_str);
1128 ret = add_left(arg, left_item);
1149 } while (type != EVENT_NONE);
1151 if (!current_op && !current_exp)
1155 current_op = current_exp;
1157 ret = collapse_tree(current_op, parg, error_str);
1158 /* collapse_tree() may free current_op, and updates parg accordingly */
1167 show_error(error_str, "failed to allocate filter arg");
1168 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
1171 show_error(error_str, "Syntax error");
1172 ret = TEP_ERRNO__SYNTAX_ERROR;
1174 free_arg(current_op);
1175 free_arg(current_exp);
1181 static enum tep_errno
1182 process_event(struct event_format *event, const char *filter_str,
1183 struct filter_arg **parg, char *error_str)
1187 tep_buffer_init(filter_str, strlen(filter_str));
1189 ret = process_filter(event, parg, error_str, 0);
1193 /* If parg is NULL, then make it into FALSE */
1195 *parg = allocate_arg();
1197 return TEP_ERRNO__MEM_ALLOC_FAILED;
1199 (*parg)->type = FILTER_ARG_BOOLEAN;
1200 (*parg)->boolean.value = FILTER_FALSE;
1206 static enum tep_errno
1207 filter_event(struct event_filter *filter, struct event_format *event,
1208 const char *filter_str, char *error_str)
1210 struct filter_type *filter_type;
1211 struct filter_arg *arg;
1215 ret = process_event(event, filter_str, &arg, error_str);
1220 /* just add a TRUE arg */
1221 arg = allocate_arg();
1223 return TEP_ERRNO__MEM_ALLOC_FAILED;
1225 arg->type = FILTER_ARG_BOOLEAN;
1226 arg->boolean.value = FILTER_TRUE;
1229 filter_type = add_filter_type(filter, event->id);
1230 if (filter_type == NULL) {
1232 return TEP_ERRNO__MEM_ALLOC_FAILED;
1235 if (filter_type->filter)
1236 free_arg(filter_type->filter);
1237 filter_type->filter = arg;
1242 static void filter_init_error_buf(struct event_filter *filter)
1244 /* clear buffer to reset show error */
1245 tep_buffer_init("", 0);
1246 filter->error_buffer[0] = '\0';
1250 * tep_filter_add_filter_str - add a new filter
1251 * @filter: the event filter to add to
1252 * @filter_str: the filter string that contains the filter
1254 * Returns 0 if the filter was successfully added or a
1255 * negative error code. Use tep_filter_strerror() to see
1256 * actual error message in case of error.
1258 enum tep_errno tep_filter_add_filter_str(struct event_filter *filter,
1259 const char *filter_str)
1261 struct tep_handle *pevent = filter->pevent;
1262 struct event_list *event;
1263 struct event_list *events = NULL;
1264 const char *filter_start;
1265 const char *next_event;
1267 char *event_name = NULL;
1268 char *sys_name = NULL;
1270 enum tep_errno rtn = 0; /* TEP_ERRNO__SUCCESS */
1274 filter_init_error_buf(filter);
1276 filter_start = strchr(filter_str, ':');
1278 len = filter_start - filter_str;
1280 len = strlen(filter_str);
1283 next_event = strchr(filter_str, ',');
1285 (!filter_start || next_event < filter_start))
1286 len = next_event - filter_str;
1287 else if (filter_start)
1288 len = filter_start - filter_str;
1290 len = strlen(filter_str);
1292 this_event = malloc(len + 1);
1293 if (this_event == NULL) {
1294 /* This can only happen when events is NULL, but still */
1295 free_events(events);
1296 return TEP_ERRNO__MEM_ALLOC_FAILED;
1298 memcpy(this_event, filter_str, len);
1299 this_event[len] = 0;
1304 filter_str = next_event;
1306 sys_name = strtok_r(this_event, "/", &sp);
1307 event_name = strtok_r(NULL, "/", &sp);
1310 /* This can only happen when events is NULL, but still */
1311 free_events(events);
1313 return TEP_ERRNO__FILTER_NOT_FOUND;
1316 /* Find this event */
1317 ret = find_event(pevent, &events, strim(sys_name), strim(event_name));
1319 free_events(events);
1324 } while (filter_str);
1330 /* filter starts here */
1331 for (event = events; event; event = event->next) {
1332 ret = filter_event(filter, event->event, filter_start,
1333 filter->error_buffer);
1334 /* Failures are returned if a parse error happened */
1338 if (ret >= 0 && pevent->test_filters) {
1340 test = tep_filter_make_string(filter, event->event->id);
1342 printf(" '%s: %s'\n", event->event->name, test);
1348 free_events(events);
1350 if (rtn >= 0 && pevent->test_filters)
1356 static void free_filter_type(struct filter_type *filter_type)
1358 free_arg(filter_type->filter);
1362 * tep_filter_strerror - fill error message in a buffer
1363 * @filter: the event filter contains error
1364 * @err: the error code
1365 * @buf: the buffer to be filled in
1366 * @buflen: the size of the buffer
1368 * Returns 0 if message was filled successfully, -1 if error
1370 int tep_filter_strerror(struct event_filter *filter, enum tep_errno err,
1371 char *buf, size_t buflen)
1373 if (err <= __TEP_ERRNO__START || err >= __TEP_ERRNO__END)
1376 if (strlen(filter->error_buffer) > 0) {
1377 size_t len = snprintf(buf, buflen, "%s", filter->error_buffer);
1384 return tep_strerror(filter->pevent, err, buf, buflen);
1388 * tep_filter_remove_event - remove a filter for an event
1389 * @filter: the event filter to remove from
1390 * @event_id: the event to remove a filter for
1392 * Removes the filter saved for an event defined by @event_id
1395 * Returns 1: if an event was removed
1396 * 0: if the event was not found
1398 int tep_filter_remove_event(struct event_filter *filter,
1401 struct filter_type *filter_type;
1404 if (!filter->filters)
1407 filter_type = find_filter_type(filter, event_id);
1412 free_filter_type(filter_type);
1414 /* The filter_type points into the event_filters array */
1415 len = (unsigned long)(filter->event_filters + filter->filters) -
1416 (unsigned long)(filter_type + 1);
1418 memmove(filter_type, filter_type + 1, len);
1421 memset(&filter->event_filters[filter->filters], 0,
1422 sizeof(*filter_type));
1428 * tep_filter_reset - clear all filters in a filter
1429 * @filter: the event filter to reset
1431 * Removes all filters from a filter and resets it.
1433 void tep_filter_reset(struct event_filter *filter)
1437 for (i = 0; i < filter->filters; i++)
1438 free_filter_type(&filter->event_filters[i]);
1440 free(filter->event_filters);
1441 filter->filters = 0;
1442 filter->event_filters = NULL;
1445 void tep_filter_free(struct event_filter *filter)
1447 tep_unref(filter->pevent);
1449 tep_filter_reset(filter);
1454 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg);
1456 static int copy_filter_type(struct event_filter *filter,
1457 struct event_filter *source,
1458 struct filter_type *filter_type)
1460 struct filter_arg *arg;
1461 struct event_format *event;
1466 /* Can't assume that the pevent's are the same */
1467 sys = filter_type->event->system;
1468 name = filter_type->event->name;
1469 event = tep_find_event_by_name(filter->pevent, sys, name);
1473 str = arg_to_str(source, filter_type->filter);
1477 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
1478 /* Add trivial event */
1479 arg = allocate_arg();
1485 arg->type = FILTER_ARG_BOOLEAN;
1486 if (strcmp(str, "TRUE") == 0)
1487 arg->boolean.value = 1;
1489 arg->boolean.value = 0;
1491 filter_type = add_filter_type(filter, event->id);
1492 if (filter_type == NULL) {
1498 filter_type->filter = arg;
1504 filter_event(filter, event, str, NULL);
1511 * tep_filter_copy - copy a filter using another filter
1512 * @dest - the filter to copy to
1513 * @source - the filter to copy from
1515 * Returns 0 on success and -1 if not all filters were copied
1517 int tep_filter_copy(struct event_filter *dest, struct event_filter *source)
1522 tep_filter_reset(dest);
1524 for (i = 0; i < source->filters; i++) {
1525 if (copy_filter_type(dest, source, &source->event_filters[i]))
1533 * tep_update_trivial - update the trivial filters with the given filter
1534 * @dest - the filter to update
1535 * @source - the filter as the source of the update
1536 * @type - the type of trivial filter to update.
1538 * Scan dest for trivial events matching @type to replace with the source.
1540 * Returns 0 on success and -1 if there was a problem updating, but
1541 * events may have still been updated on error.
1543 int tep_update_trivial(struct event_filter *dest, struct event_filter *source,
1544 enum filter_trivial_type type)
1546 struct tep_handle *src_pevent;
1547 struct tep_handle *dest_pevent;
1548 struct event_format *event;
1549 struct filter_type *filter_type;
1550 struct filter_arg *arg;
1554 src_pevent = source->pevent;
1555 dest_pevent = dest->pevent;
1557 /* Do nothing if either of the filters has nothing to filter */
1558 if (!dest->filters || !source->filters)
1561 for (i = 0; i < dest->filters; i++) {
1562 filter_type = &dest->event_filters[i];
1563 arg = filter_type->filter;
1564 if (arg->type != FILTER_ARG_BOOLEAN)
1566 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) ||
1567 (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE))
1570 event = filter_type->event;
1572 if (src_pevent != dest_pevent) {
1574 event = tep_find_event_by_name(src_pevent,
1581 str = tep_filter_make_string(source, event->id);
1585 /* Don't bother if the filter is trivial too */
1586 if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0)
1587 filter_event(dest, event, str, NULL);
1594 * tep_filter_clear_trivial - clear TRUE and FALSE filters
1595 * @filter: the filter to remove trivial filters from
1596 * @type: remove only true, false, or both
1598 * Removes filters that only contain a TRUE or FALES boolean arg.
1600 * Returns 0 on success and -1 if there was a problem.
1602 int tep_filter_clear_trivial(struct event_filter *filter,
1603 enum filter_trivial_type type)
1605 struct filter_type *filter_type;
1610 if (!filter->filters)
1614 * Two steps, first get all ids with trivial filters.
1615 * then remove those ids.
1617 for (i = 0; i < filter->filters; i++) {
1620 filter_type = &filter->event_filters[i];
1621 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1624 case FILTER_TRIVIAL_FALSE:
1625 if (filter_type->filter->boolean.value)
1628 case FILTER_TRIVIAL_TRUE:
1629 if (!filter_type->filter->boolean.value)
1635 new_ids = realloc(ids, sizeof(*ids) * (count + 1));
1642 ids[count++] = filter_type->event_id;
1648 for (i = 0; i < count; i++)
1649 tep_filter_remove_event(filter, ids[i]);
1656 * tep_filter_event_has_trivial - return true event contains trivial filter
1657 * @filter: the filter with the information
1658 * @event_id: the id of the event to test
1659 * @type: trivial type to test for (TRUE, FALSE, EITHER)
1661 * Returns 1 if the event contains a matching trivial type
1664 int tep_filter_event_has_trivial(struct event_filter *filter,
1666 enum filter_trivial_type type)
1668 struct filter_type *filter_type;
1670 if (!filter->filters)
1673 filter_type = find_filter_type(filter, event_id);
1678 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1682 case FILTER_TRIVIAL_FALSE:
1683 return !filter_type->filter->boolean.value;
1685 case FILTER_TRIVIAL_TRUE:
1686 return filter_type->filter->boolean.value;
1692 static int test_filter(struct event_format *event, struct filter_arg *arg,
1693 struct tep_record *record, enum tep_errno *err);
1696 get_comm(struct event_format *event, struct tep_record *record)
1701 pid = tep_data_pid(event->pevent, record);
1702 comm = tep_data_comm_from_pid(event->pevent, pid);
1706 static unsigned long long
1707 get_value(struct event_format *event,
1708 struct format_field *field, struct tep_record *record)
1710 unsigned long long val;
1712 /* Handle our dummy "comm" field */
1713 if (field == &comm) {
1716 name = get_comm(event, record);
1717 return (unsigned long)name;
1720 /* Handle our dummy "cpu" field */
1724 tep_read_number_field(field, record->data, &val);
1726 if (!(field->flags & FIELD_IS_SIGNED))
1729 switch (field->size) {
1737 return (long long)val;
1742 static unsigned long long
1743 get_arg_value(struct event_format *event, struct filter_arg *arg,
1744 struct tep_record *record, enum tep_errno *err);
1746 static unsigned long long
1747 get_exp_value(struct event_format *event, struct filter_arg *arg,
1748 struct tep_record *record, enum tep_errno *err)
1750 unsigned long long lval, rval;
1752 lval = get_arg_value(event, arg->exp.left, record, err);
1753 rval = get_arg_value(event, arg->exp.right, record, err);
1757 * There was an error, no need to process anymore.
1762 switch (arg->exp.type) {
1763 case FILTER_EXP_ADD:
1766 case FILTER_EXP_SUB:
1769 case FILTER_EXP_MUL:
1772 case FILTER_EXP_DIV:
1775 case FILTER_EXP_MOD:
1778 case FILTER_EXP_RSHIFT:
1779 return lval >> rval;
1781 case FILTER_EXP_LSHIFT:
1782 return lval << rval;
1784 case FILTER_EXP_AND:
1790 case FILTER_EXP_XOR:
1793 case FILTER_EXP_NOT:
1796 *err = TEP_ERRNO__INVALID_EXP_TYPE;
1801 static unsigned long long
1802 get_arg_value(struct event_format *event, struct filter_arg *arg,
1803 struct tep_record *record, enum tep_errno *err)
1805 switch (arg->type) {
1806 case FILTER_ARG_FIELD:
1807 return get_value(event, arg->field.field, record);
1809 case FILTER_ARG_VALUE:
1810 if (arg->value.type != FILTER_NUMBER) {
1812 *err = TEP_ERRNO__NOT_A_NUMBER;
1814 return arg->value.val;
1816 case FILTER_ARG_EXP:
1817 return get_exp_value(event, arg, record, err);
1821 *err = TEP_ERRNO__INVALID_ARG_TYPE;
1826 static int test_num(struct event_format *event, struct filter_arg *arg,
1827 struct tep_record *record, enum tep_errno *err)
1829 unsigned long long lval, rval;
1831 lval = get_arg_value(event, arg->num.left, record, err);
1832 rval = get_arg_value(event, arg->num.right, record, err);
1836 * There was an error, no need to process anymore.
1841 switch (arg->num.type) {
1843 return lval == rval;
1846 return lval != rval;
1855 return lval >= rval;
1858 return lval <= rval;
1862 *err = TEP_ERRNO__ILLEGAL_INTEGER_CMP;
1867 static const char *get_field_str(struct filter_arg *arg, struct tep_record *record)
1869 struct event_format *event;
1870 struct tep_handle *pevent;
1871 unsigned long long addr;
1872 const char *val = NULL;
1876 /* If the field is not a string convert it */
1877 if (arg->str.field->flags & FIELD_IS_STRING) {
1878 val = record->data + arg->str.field->offset;
1879 size = arg->str.field->size;
1881 if (arg->str.field->flags & FIELD_IS_DYNAMIC) {
1882 addr = *(unsigned int *)val;
1883 val = record->data + (addr & 0xffff);
1888 * We need to copy the data since we can't be sure the field
1889 * is null terminated.
1891 if (*(val + size - 1)) {
1893 memcpy(arg->str.buffer, val, arg->str.field->size);
1894 /* the buffer is already NULL terminated */
1895 val = arg->str.buffer;
1899 event = arg->str.field->event;
1900 pevent = event->pevent;
1901 addr = get_value(event, arg->str.field, record);
1903 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
1904 /* convert to a kernel symbol */
1905 val = tep_find_function(pevent, addr);
1908 /* just use the hex of the string name */
1909 snprintf(hex, 64, "0x%llx", addr);
1917 static int test_str(struct event_format *event, struct filter_arg *arg,
1918 struct tep_record *record, enum tep_errno *err)
1922 if (arg->str.field == &comm)
1923 val = get_comm(event, record);
1925 val = get_field_str(arg, record);
1927 switch (arg->str.type) {
1928 case FILTER_CMP_MATCH:
1929 return strcmp(val, arg->str.val) == 0;
1931 case FILTER_CMP_NOT_MATCH:
1932 return strcmp(val, arg->str.val) != 0;
1934 case FILTER_CMP_REGEX:
1935 /* Returns zero on match */
1936 return !regexec(&arg->str.reg, val, 0, NULL, 0);
1938 case FILTER_CMP_NOT_REGEX:
1939 return regexec(&arg->str.reg, val, 0, NULL, 0);
1943 *err = TEP_ERRNO__ILLEGAL_STRING_CMP;
1948 static int test_op(struct event_format *event, struct filter_arg *arg,
1949 struct tep_record *record, enum tep_errno *err)
1951 switch (arg->op.type) {
1953 return test_filter(event, arg->op.left, record, err) &&
1954 test_filter(event, arg->op.right, record, err);
1957 return test_filter(event, arg->op.left, record, err) ||
1958 test_filter(event, arg->op.right, record, err);
1961 return !test_filter(event, arg->op.right, record, err);
1965 *err = TEP_ERRNO__INVALID_OP_TYPE;
1970 static int test_filter(struct event_format *event, struct filter_arg *arg,
1971 struct tep_record *record, enum tep_errno *err)
1975 * There was an error, no need to process anymore.
1980 switch (arg->type) {
1981 case FILTER_ARG_BOOLEAN:
1983 return arg->boolean.value;
1986 return test_op(event, arg, record, err);
1988 case FILTER_ARG_NUM:
1989 return test_num(event, arg, record, err);
1991 case FILTER_ARG_STR:
1992 return test_str(event, arg, record, err);
1994 case FILTER_ARG_EXP:
1995 case FILTER_ARG_VALUE:
1996 case FILTER_ARG_FIELD:
1998 * Expressions, fields and values evaluate
1999 * to true if they return non zero
2001 return !!get_arg_value(event, arg, record, err);
2005 *err = TEP_ERRNO__INVALID_ARG_TYPE;
2011 * tep_event_filtered - return true if event has filter
2012 * @filter: filter struct with filter information
2013 * @event_id: event id to test if filter exists
2015 * Returns 1 if filter found for @event_id
2018 int tep_event_filtered(struct event_filter *filter, int event_id)
2020 struct filter_type *filter_type;
2022 if (!filter->filters)
2025 filter_type = find_filter_type(filter, event_id);
2027 return filter_type ? 1 : 0;
2031 * tep_filter_match - test if a record matches a filter
2032 * @filter: filter struct with filter information
2033 * @record: the record to test against the filter
2035 * Returns: match result or error code (prefixed with TEP_ERRNO__)
2036 * FILTER_MATCH - filter found for event and @record matches
2037 * FILTER_MISS - filter found for event and @record does not match
2038 * FILTER_NOT_FOUND - no filter found for @record's event
2039 * NO_FILTER - if no filters exist
2040 * otherwise - error occurred during test
2042 enum tep_errno tep_filter_match(struct event_filter *filter,
2043 struct tep_record *record)
2045 struct tep_handle *pevent = filter->pevent;
2046 struct filter_type *filter_type;
2049 enum tep_errno err = 0;
2051 filter_init_error_buf(filter);
2053 if (!filter->filters)
2054 return TEP_ERRNO__NO_FILTER;
2056 event_id = tep_data_type(pevent, record);
2058 filter_type = find_filter_type(filter, event_id);
2060 return TEP_ERRNO__FILTER_NOT_FOUND;
2062 ret = test_filter(filter_type->event, filter_type->filter, record, &err);
2066 return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS;
2069 static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
2079 switch (arg->op.type) {
2087 left = arg_to_str(filter, arg->op.left);
2088 right = arg_to_str(filter, arg->op.right);
2089 if (!left || !right)
2092 /* Try to consolidate boolean values */
2093 if (strcmp(left, "TRUE") == 0)
2095 else if (strcmp(left, "FALSE") == 0)
2098 if (strcmp(right, "TRUE") == 0)
2100 else if (strcmp(right, "FALSE") == 0)
2103 if (left_val >= 0) {
2104 if ((arg->op.type == FILTER_OP_AND && !left_val) ||
2105 (arg->op.type == FILTER_OP_OR && left_val)) {
2106 /* Just return left value */
2111 if (right_val >= 0) {
2112 /* just evaluate this. */
2114 switch (arg->op.type) {
2116 val = left_val && right_val;
2119 val = left_val || right_val;
2124 asprintf(&str, val ? "TRUE" : "FALSE");
2128 if (right_val >= 0) {
2129 if ((arg->op.type == FILTER_OP_AND && !right_val) ||
2130 (arg->op.type == FILTER_OP_OR && right_val)) {
2131 /* Just return right value */
2136 /* The right value is meaningless */
2142 asprintf(&str, "(%s) %s (%s)", left, op, right);
2147 right = arg_to_str(filter, arg->op.right);
2151 /* See if we can consolidate */
2152 if (strcmp(right, "TRUE") == 0)
2154 else if (strcmp(right, "FALSE") == 0)
2156 if (right_val >= 0) {
2157 /* just return the opposite */
2158 asprintf(&str, right_val ? "FALSE" : "TRUE");
2161 asprintf(&str, "%s(%s)", op, right);
2173 static char *val_to_str(struct event_filter *filter, struct filter_arg *arg)
2177 asprintf(&str, "%lld", arg->value.val);
2182 static char *field_to_str(struct event_filter *filter, struct filter_arg *arg)
2184 return strdup(arg->field.field->name);
2187 static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2194 lstr = arg_to_str(filter, arg->exp.left);
2195 rstr = arg_to_str(filter, arg->exp.right);
2199 switch (arg->exp.type) {
2200 case FILTER_EXP_ADD:
2203 case FILTER_EXP_SUB:
2206 case FILTER_EXP_MUL:
2209 case FILTER_EXP_DIV:
2212 case FILTER_EXP_MOD:
2215 case FILTER_EXP_RSHIFT:
2218 case FILTER_EXP_LSHIFT:
2221 case FILTER_EXP_AND:
2227 case FILTER_EXP_XOR:
2231 op = "[ERROR IN EXPRESSION TYPE]";
2235 asprintf(&str, "%s %s %s", lstr, op, rstr);
2243 static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2250 lstr = arg_to_str(filter, arg->num.left);
2251 rstr = arg_to_str(filter, arg->num.right);
2255 switch (arg->num.type) {
2279 asprintf(&str, "%s %s %s", lstr, op, rstr);
2293 static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
2298 switch (arg->str.type) {
2299 case FILTER_CMP_MATCH:
2302 case FILTER_CMP_NOT_MATCH:
2306 case FILTER_CMP_REGEX:
2310 case FILTER_CMP_NOT_REGEX:
2314 asprintf(&str, "%s %s \"%s\"",
2315 arg->str.field->name, op, arg->str.val);
2325 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
2329 switch (arg->type) {
2330 case FILTER_ARG_BOOLEAN:
2331 asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE");
2335 return op_to_str(filter, arg);
2337 case FILTER_ARG_NUM:
2338 return num_to_str(filter, arg);
2340 case FILTER_ARG_STR:
2341 return str_to_str(filter, arg);
2343 case FILTER_ARG_VALUE:
2344 return val_to_str(filter, arg);
2346 case FILTER_ARG_FIELD:
2347 return field_to_str(filter, arg);
2349 case FILTER_ARG_EXP:
2350 return exp_to_str(filter, arg);
2360 * tep_filter_make_string - return a string showing the filter
2361 * @filter: filter struct with filter information
2362 * @event_id: the event id to return the filter string with
2364 * Returns a string that displays the filter contents.
2365 * This string must be freed with free(str).
2366 * NULL is returned if no filter is found or allocation failed.
2369 tep_filter_make_string(struct event_filter *filter, int event_id)
2371 struct filter_type *filter_type;
2373 if (!filter->filters)
2376 filter_type = find_filter_type(filter, event_id);
2381 return arg_to_str(filter, filter_type->filter);
2385 * tep_filter_compare - compare two filters and return if they are the same
2386 * @filter1: Filter to compare with @filter2
2387 * @filter2: Filter to compare with @filter1
2390 * 1 if the two filters hold the same content.
2393 int tep_filter_compare(struct event_filter *filter1, struct event_filter *filter2)
2395 struct filter_type *filter_type1;
2396 struct filter_type *filter_type2;
2401 /* Do the easy checks first */
2402 if (filter1->filters != filter2->filters)
2404 if (!filter1->filters && !filter2->filters)
2408 * Now take a look at each of the events to see if they have the same
2411 for (i = 0; i < filter1->filters; i++) {
2412 filter_type1 = &filter1->event_filters[i];
2413 filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2416 if (filter_type1->filter->type != filter_type2->filter->type)
2418 switch (filter_type1->filter->type) {
2419 case FILTER_TRIVIAL_FALSE:
2420 case FILTER_TRIVIAL_TRUE:
2421 /* trivial types just need the type compared */
2426 /* The best way to compare complex filters is with strings */
2427 str1 = arg_to_str(filter1, filter_type1->filter);
2428 str2 = arg_to_str(filter2, filter_type2->filter);
2430 result = strcmp(str1, str2) != 0;
2432 /* bail out if allocation fails */
2441 if (i < filter1->filters)