1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3 * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 *
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <stdarg.h>
10 #include <errno.h>
11 #include <sys/types.h>
12
13 #include "event-parse.h"
14 #include "event-utils.h"
15
16 #define COMM "COMM"
17 #define CPU "CPU"
18
19 static struct format_field comm = {
20 .name = "COMM",
21 };
22
23 static struct format_field cpu = {
24 .name = "CPU",
25 };
26
27 struct event_list {
28 struct event_list *next;
29 struct event_format *event;
30 };
31
show_error(char * error_buf,const char * fmt,...)32 static void show_error(char *error_buf, const char *fmt, ...)
33 {
34 unsigned long long index;
35 const char *input;
36 va_list ap;
37 int len;
38 int i;
39
40 input = tep_get_input_buf();
41 index = tep_get_input_buf_ptr();
42 len = input ? strlen(input) : 0;
43
44 if (len) {
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';
51 len += i+2;
52 }
53
54 va_start(ap, fmt);
55 vsnprintf(error_buf + len, TEP_FILTER_ERROR_BUFSZ - len, fmt, ap);
56 va_end(ap);
57 }
58
free_token(char * token)59 static void free_token(char *token)
60 {
61 tep_free_token(token);
62 }
63
read_token(char ** tok)64 static enum event_type read_token(char **tok)
65 {
66 enum event_type type;
67 char *token = NULL;
68
69 do {
70 free_token(token);
71 type = tep_read_token(&token);
72 } while (type == EVENT_NEWLINE || type == EVENT_SPACE);
73
74 /* If token is = or ! check to see if the next char is ~ */
75 if (token &&
76 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
77 tep_peek_char() == '~') {
78 /* append it */
79 *tok = malloc(3);
80 if (*tok == NULL) {
81 free_token(token);
82 return EVENT_ERROR;
83 }
84 sprintf(*tok, "%c%c", *token, '~');
85 free_token(token);
86 /* Now remove the '~' from the buffer */
87 tep_read_token(&token);
88 free_token(token);
89 } else
90 *tok = token;
91
92 return type;
93 }
94
filter_cmp(const void * a,const void * b)95 static int filter_cmp(const void *a, const void *b)
96 {
97 const struct filter_type *ea = a;
98 const struct filter_type *eb = b;
99
100 if (ea->event_id < eb->event_id)
101 return -1;
102
103 if (ea->event_id > eb->event_id)
104 return 1;
105
106 return 0;
107 }
108
109 static struct filter_type *
find_filter_type(struct event_filter * filter,int id)110 find_filter_type(struct event_filter *filter, int id)
111 {
112 struct filter_type *filter_type;
113 struct filter_type key;
114
115 key.event_id = id;
116
117 filter_type = bsearch(&key, filter->event_filters,
118 filter->filters,
119 sizeof(*filter->event_filters),
120 filter_cmp);
121
122 return filter_type;
123 }
124
125 static struct filter_type *
add_filter_type(struct event_filter * filter,int id)126 add_filter_type(struct event_filter *filter, int id)
127 {
128 struct filter_type *filter_type;
129 int i;
130
131 filter_type = find_filter_type(filter, id);
132 if (filter_type)
133 return filter_type;
134
135 filter_type = realloc(filter->event_filters,
136 sizeof(*filter->event_filters) *
137 (filter->filters + 1));
138 if (!filter_type)
139 return NULL;
140
141 filter->event_filters = filter_type;
142
143 for (i = 0; i < filter->filters; i++) {
144 if (filter->event_filters[i].event_id > id)
145 break;
146 }
147
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));
153
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;
158
159 filter->filters++;
160
161 return filter_type;
162 }
163
164 /**
165 * tep_filter_alloc - create a new event filter
166 * @pevent: The pevent that this filter is associated with
167 */
tep_filter_alloc(struct tep_handle * pevent)168 struct event_filter *tep_filter_alloc(struct tep_handle *pevent)
169 {
170 struct event_filter *filter;
171
172 filter = malloc(sizeof(*filter));
173 if (filter == NULL)
174 return NULL;
175
176 memset(filter, 0, sizeof(*filter));
177 filter->pevent = pevent;
178 tep_ref(pevent);
179
180 return filter;
181 }
182
allocate_arg(void)183 static struct filter_arg *allocate_arg(void)
184 {
185 return calloc(1, sizeof(struct filter_arg));
186 }
187
free_arg(struct filter_arg * arg)188 static void free_arg(struct filter_arg *arg)
189 {
190 if (!arg)
191 return;
192
193 switch (arg->type) {
194 case FILTER_ARG_NONE:
195 case FILTER_ARG_BOOLEAN:
196 break;
197
198 case FILTER_ARG_NUM:
199 free_arg(arg->num.left);
200 free_arg(arg->num.right);
201 break;
202
203 case FILTER_ARG_EXP:
204 free_arg(arg->exp.left);
205 free_arg(arg->exp.right);
206 break;
207
208 case FILTER_ARG_STR:
209 free(arg->str.val);
210 regfree(&arg->str.reg);
211 free(arg->str.buffer);
212 break;
213
214 case FILTER_ARG_VALUE:
215 if (arg->value.type == FILTER_STRING ||
216 arg->value.type == FILTER_CHAR)
217 free(arg->value.str);
218 break;
219
220 case FILTER_ARG_OP:
221 free_arg(arg->op.left);
222 free_arg(arg->op.right);
223 default:
224 break;
225 }
226
227 free(arg);
228 }
229
add_event(struct event_list ** events,struct event_format * event)230 static int add_event(struct event_list **events,
231 struct event_format *event)
232 {
233 struct event_list *list;
234
235 list = malloc(sizeof(*list));
236 if (list == NULL)
237 return -1;
238
239 list->next = *events;
240 *events = list;
241 list->event = event;
242 return 0;
243 }
244
event_match(struct event_format * event,regex_t * sreg,regex_t * ereg)245 static int event_match(struct event_format *event,
246 regex_t *sreg, regex_t *ereg)
247 {
248 if (sreg) {
249 return !regexec(sreg, event->system, 0, NULL, 0) &&
250 !regexec(ereg, event->name, 0, NULL, 0);
251 }
252
253 return !regexec(ereg, event->system, 0, NULL, 0) ||
254 !regexec(ereg, event->name, 0, NULL, 0);
255 }
256
257 static enum tep_errno
find_event(struct tep_handle * pevent,struct event_list ** events,char * sys_name,char * event_name)258 find_event(struct tep_handle *pevent, struct event_list **events,
259 char *sys_name, char *event_name)
260 {
261 struct event_format *event;
262 regex_t ereg;
263 regex_t sreg;
264 int match = 0;
265 int fail = 0;
266 char *reg;
267 int ret;
268 int i;
269
270 if (!event_name) {
271 /* if no name is given, then swap sys and name */
272 event_name = sys_name;
273 sys_name = NULL;
274 }
275
276 ret = asprintf(®, "^%s$", event_name);
277 if (ret < 0)
278 return TEP_ERRNO__MEM_ALLOC_FAILED;
279
280 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
281 free(reg);
282
283 if (ret)
284 return TEP_ERRNO__INVALID_EVENT_NAME;
285
286 if (sys_name) {
287 ret = asprintf(®, "^%s$", sys_name);
288 if (ret < 0) {
289 regfree(&ereg);
290 return TEP_ERRNO__MEM_ALLOC_FAILED;
291 }
292
293 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
294 free(reg);
295 if (ret) {
296 regfree(&ereg);
297 return TEP_ERRNO__INVALID_EVENT_NAME;
298 }
299 }
300
301 for (i = 0; i < pevent->nr_events; i++) {
302 event = pevent->events[i];
303 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
304 match = 1;
305 if (add_event(events, event) < 0) {
306 fail = 1;
307 break;
308 }
309 }
310 }
311
312 regfree(&ereg);
313 if (sys_name)
314 regfree(&sreg);
315
316 if (!match)
317 return TEP_ERRNO__EVENT_NOT_FOUND;
318 if (fail)
319 return TEP_ERRNO__MEM_ALLOC_FAILED;
320
321 return 0;
322 }
323
free_events(struct event_list * events)324 static void free_events(struct event_list *events)
325 {
326 struct event_list *event;
327
328 while (events) {
329 event = events;
330 events = events->next;
331 free(event);
332 }
333 }
334
335 static enum tep_errno
create_arg_item(struct event_format * event,const char * token,enum event_type type,struct filter_arg ** parg,char * error_str)336 create_arg_item(struct event_format *event, const char *token,
337 enum event_type type, struct filter_arg **parg, char *error_str)
338 {
339 struct format_field *field;
340 struct filter_arg *arg;
341
342 arg = allocate_arg();
343 if (arg == NULL) {
344 show_error(error_str, "failed to allocate filter arg");
345 return TEP_ERRNO__MEM_ALLOC_FAILED;
346 }
347
348 switch (type) {
349
350 case EVENT_SQUOTE:
351 case EVENT_DQUOTE:
352 arg->type = FILTER_ARG_VALUE;
353 arg->value.type =
354 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
355 arg->value.str = strdup(token);
356 if (!arg->value.str) {
357 free_arg(arg);
358 show_error(error_str, "failed to allocate string filter arg");
359 return TEP_ERRNO__MEM_ALLOC_FAILED;
360 }
361 break;
362 case EVENT_ITEM:
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);
368 break;
369 }
370 /* Consider this a field */
371 field = tep_find_any_field(event, token);
372 if (!field) {
373 /* If token is 'COMM' or 'CPU' then it is special */
374 if (strcmp(token, COMM) == 0) {
375 field = &comm;
376 } else if (strcmp(token, CPU) == 0) {
377 field = &cpu;
378 } else {
379 /* not a field, Make it false */
380 arg->type = FILTER_ARG_BOOLEAN;
381 arg->boolean.value = FILTER_FALSE;
382 break;
383 }
384 }
385 arg->type = FILTER_ARG_FIELD;
386 arg->field.field = field;
387 break;
388 default:
389 free_arg(arg);
390 show_error(error_str, "expected a value but found %s", token);
391 return TEP_ERRNO__UNEXPECTED_TYPE;
392 }
393 *parg = arg;
394 return 0;
395 }
396
397 static struct filter_arg *
create_arg_op(enum filter_op_type btype)398 create_arg_op(enum filter_op_type btype)
399 {
400 struct filter_arg *arg;
401
402 arg = allocate_arg();
403 if (!arg)
404 return NULL;
405
406 arg->type = FILTER_ARG_OP;
407 arg->op.type = btype;
408
409 return arg;
410 }
411
412 static struct filter_arg *
create_arg_exp(enum filter_exp_type etype)413 create_arg_exp(enum filter_exp_type etype)
414 {
415 struct filter_arg *arg;
416
417 arg = allocate_arg();
418 if (!arg)
419 return NULL;
420
421 arg->type = FILTER_ARG_EXP;
422 arg->exp.type = etype;
423
424 return arg;
425 }
426
427 static struct filter_arg *
create_arg_cmp(enum filter_cmp_type ctype)428 create_arg_cmp(enum filter_cmp_type ctype)
429 {
430 struct filter_arg *arg;
431
432 arg = allocate_arg();
433 if (!arg)
434 return NULL;
435
436 /* Use NUM and change if necessary */
437 arg->type = FILTER_ARG_NUM;
438 arg->num.type = ctype;
439
440 return arg;
441 }
442
443 static enum tep_errno
add_right(struct filter_arg * op,struct filter_arg * arg,char * error_str)444 add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
445 {
446 struct filter_arg *left;
447 char *str;
448 int op_type;
449 int ret;
450
451 switch (op->type) {
452 case FILTER_ARG_EXP:
453 if (op->exp.right)
454 goto out_fail;
455 op->exp.right = arg;
456 break;
457
458 case FILTER_ARG_OP:
459 if (op->op.right)
460 goto out_fail;
461 op->op.right = arg;
462 break;
463
464 case FILTER_ARG_NUM:
465 if (op->op.right)
466 goto out_fail;
467 /*
468 * The arg must be num, str, or field
469 */
470 switch (arg->type) {
471 case FILTER_ARG_VALUE:
472 case FILTER_ARG_FIELD:
473 break;
474 default:
475 show_error(error_str, "Illegal rvalue");
476 return TEP_ERRNO__ILLEGAL_RVALUE;
477 }
478
479 /*
480 * Depending on the type, we may need to
481 * convert this to a string or regex.
482 */
483 switch (arg->value.type) {
484 case FILTER_CHAR:
485 /*
486 * A char should be converted to number if
487 * the string is 1 byte, and the compare
488 * is not a REGEX.
489 */
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;
494 goto do_int;
495 }
496 /* fall through */
497 case FILTER_STRING:
498
499 /* convert op to a string arg */
500 op_type = op->num.type;
501 left = op->num.left;
502 str = arg->value.str;
503
504 /* reset the op for the new field */
505 memset(op, 0, sizeof(*op));
506
507 /*
508 * If left arg was a field not found then
509 * NULL the entire op.
510 */
511 if (left->type == FILTER_ARG_BOOLEAN) {
512 free_arg(left);
513 free_arg(arg);
514 op->type = FILTER_ARG_BOOLEAN;
515 op->boolean.value = FILTER_FALSE;
516 break;
517 }
518
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;
524 }
525
526 /* Make sure this is a valid string compare */
527 switch (op_type) {
528 case FILTER_CMP_EQ:
529 op_type = FILTER_CMP_MATCH;
530 break;
531 case FILTER_CMP_NE:
532 op_type = FILTER_CMP_NOT_MATCH;
533 break;
534
535 case FILTER_CMP_REGEX:
536 case FILTER_CMP_NOT_REGEX:
537 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB);
538 if (ret) {
539 show_error(error_str,
540 "RegEx '%s' did not compute",
541 str);
542 return TEP_ERRNO__INVALID_REGEX;
543 }
544 break;
545 default:
546 show_error(error_str,
547 "Illegal comparison for string");
548 return TEP_ERRNO__ILLEGAL_STRING_CMP;
549 }
550
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);
555 if (!op->str.val) {
556 show_error(error_str, "Failed to allocate string filter");
557 return TEP_ERRNO__MEM_ALLOC_FAILED;
558 }
559 /*
560 * Need a buffer to copy data for tests
561 */
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;
566 }
567 /* Null terminate this buffer */
568 op->str.buffer[op->str.field->size] = 0;
569
570 /* We no longer have left or right args */
571 free_arg(arg);
572 free_arg(left);
573
574 break;
575
576 case FILTER_NUMBER:
577
578 do_int:
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;
585
586 default:
587 break;
588 }
589
590 /* numeric compare */
591 op->num.right = arg;
592 break;
593 default:
594 goto out_fail;
595 }
596 break;
597 default:
598 goto out_fail;
599 }
600
601 return 0;
602
603 out_fail:
604 show_error(error_str, "Syntax error");
605 return TEP_ERRNO__SYNTAX_ERROR;
606 }
607
608 static struct filter_arg *
rotate_op_right(struct filter_arg * a,struct filter_arg * b)609 rotate_op_right(struct filter_arg *a, struct filter_arg *b)
610 {
611 struct filter_arg *arg;
612
613 arg = a->op.right;
614 a->op.right = b;
615 return arg;
616 }
617
add_left(struct filter_arg * op,struct filter_arg * arg)618 static enum tep_errno add_left(struct filter_arg *op, struct filter_arg *arg)
619 {
620 switch (op->type) {
621 case FILTER_ARG_EXP:
622 if (arg->type == FILTER_ARG_OP)
623 arg = rotate_op_right(arg, op);
624 op->exp.left = arg;
625 break;
626
627 case FILTER_ARG_OP:
628 op->op.left = arg;
629 break;
630 case FILTER_ARG_NUM:
631 if (arg->type == FILTER_ARG_OP)
632 arg = rotate_op_right(arg, op);
633
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;
638 op->num.left = arg;
639 break;
640 default:
641 return TEP_ERRNO__INVALID_ARG_TYPE;
642 }
643 return 0;
644 }
645
646 enum op_type {
647 OP_NONE,
648 OP_BOOL,
649 OP_NOT,
650 OP_EXP,
651 OP_CMP,
652 };
653
process_op(const char * token,enum filter_op_type * btype,enum filter_cmp_type * ctype,enum filter_exp_type * etype)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)
658 {
659 *btype = FILTER_OP_NOT;
660 *etype = FILTER_EXP_NONE;
661 *ctype = FILTER_CMP_NONE;
662
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)
668 return OP_NOT;
669
670 if (*btype != FILTER_OP_NOT)
671 return OP_BOOL;
672
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;
696
697 if (*etype != FILTER_EXP_NONE)
698 return OP_EXP;
699
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;
717 else
718 return OP_NONE;
719
720 return OP_CMP;
721 }
722
check_op_done(struct filter_arg * arg)723 static int check_op_done(struct filter_arg *arg)
724 {
725 switch (arg->type) {
726 case FILTER_ARG_EXP:
727 return arg->exp.right != NULL;
728
729 case FILTER_ARG_OP:
730 return arg->op.right != NULL;
731
732 case FILTER_ARG_NUM:
733 return arg->num.right != NULL;
734
735 case FILTER_ARG_STR:
736 /* A string conversion is always done */
737 return 1;
738
739 case FILTER_ARG_BOOLEAN:
740 /* field not found, is ok */
741 return 1;
742
743 default:
744 return 0;
745 }
746 }
747
748 enum filter_vals {
749 FILTER_VAL_NORM,
750 FILTER_VAL_FALSE,
751 FILTER_VAL_TRUE,
752 };
753
754 static enum tep_errno
reparent_op_arg(struct filter_arg * parent,struct filter_arg * old_child,struct filter_arg * arg,char * error_str)755 reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
756 struct filter_arg *arg, char *error_str)
757 {
758 struct filter_arg *other_child;
759 struct filter_arg **ptr;
760
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;
765 }
766
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;
774 } else {
775 show_error(error_str, "Error in reparent op, find other child");
776 return TEP_ERRNO__REPARENT_FAILED;
777 }
778
779 /* Detach arg from old_child */
780 *ptr = NULL;
781
782 /* Check for root */
783 if (parent == old_child) {
784 free_arg(other_child);
785 *parent = *arg;
786 /* Free arg without recussion */
787 free(arg);
788 return 0;
789 }
790
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;
795 else {
796 show_error(error_str, "Error in reparent op");
797 return TEP_ERRNO__REPARENT_FAILED;
798 }
799
800 *ptr = arg;
801
802 free_arg(old_child);
803 return 0;
804 }
805
806 /* Returns either filter_vals (success) or tep_errno (failfure) */
test_arg(struct filter_arg * parent,struct filter_arg * arg,char * error_str)807 static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
808 char *error_str)
809 {
810 int lval, rval;
811
812 switch (arg->type) {
813
814 /* bad case */
815 case FILTER_ARG_BOOLEAN:
816 return FILTER_VAL_FALSE + arg->boolean.value;
817
818 /* good cases: */
819 case FILTER_ARG_STR:
820 case FILTER_ARG_VALUE:
821 case FILTER_ARG_FIELD:
822 return FILTER_VAL_NORM;
823
824 case FILTER_ARG_EXP:
825 lval = test_arg(arg, arg->exp.left, error_str);
826 if (lval != FILTER_VAL_NORM)
827 return lval;
828 rval = test_arg(arg, arg->exp.right, error_str);
829 if (rval != FILTER_VAL_NORM)
830 return rval;
831 return FILTER_VAL_NORM;
832
833 case FILTER_ARG_NUM:
834 lval = test_arg(arg, arg->num.left, error_str);
835 if (lval != FILTER_VAL_NORM)
836 return lval;
837 rval = test_arg(arg, arg->num.right, error_str);
838 if (rval != FILTER_VAL_NORM)
839 return rval;
840 return FILTER_VAL_NORM;
841
842 case FILTER_ARG_OP:
843 if (arg->op.type != FILTER_OP_NOT) {
844 lval = test_arg(arg, arg->op.left, error_str);
845 switch (lval) {
846 case FILTER_VAL_NORM:
847 break;
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)
853 return rval;
854
855 return reparent_op_arg(parent, arg, arg->op.right,
856 error_str);
857
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)
863 return rval;
864
865 return reparent_op_arg(parent, arg, arg->op.right,
866 error_str);
867
868 default:
869 return lval;
870 }
871 }
872
873 rval = test_arg(arg, arg->op.right, error_str);
874 switch (rval) {
875 case FILTER_VAL_NORM:
876 default:
877 break;
878
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;
884
885 return reparent_op_arg(parent, arg, arg->op.left,
886 error_str);
887
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;
893
894 return reparent_op_arg(parent, arg, arg->op.left,
895 error_str);
896 }
897
898 return rval;
899 default:
900 show_error(error_str, "bad arg in filter tree");
901 return TEP_ERRNO__BAD_FILTER_ARG;
902 }
903 return FILTER_VAL_NORM;
904 }
905
906 /* Remove any unknown event fields */
collapse_tree(struct filter_arg * arg,struct filter_arg ** arg_collapsed,char * error_str)907 static int collapse_tree(struct filter_arg *arg,
908 struct filter_arg **arg_collapsed, char *error_str)
909 {
910 int ret;
911
912 ret = test_arg(arg, arg, error_str);
913 switch (ret) {
914 case FILTER_VAL_NORM:
915 break;
916
917 case FILTER_VAL_TRUE:
918 case FILTER_VAL_FALSE:
919 free_arg(arg);
920 arg = allocate_arg();
921 if (arg) {
922 arg->type = FILTER_ARG_BOOLEAN;
923 arg->boolean.value = ret == FILTER_VAL_TRUE;
924 } else {
925 show_error(error_str, "Failed to allocate filter arg");
926 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
927 }
928 break;
929
930 default:
931 /* test_arg() already set the error_str */
932 free_arg(arg);
933 arg = NULL;
934 break;
935 }
936
937 *arg_collapsed = arg;
938 return ret;
939 }
940
941 static enum tep_errno
process_filter(struct event_format * event,struct filter_arg ** parg,char * error_str,int not)942 process_filter(struct event_format *event, struct filter_arg **parg,
943 char *error_str, int not)
944 {
945 enum event_type type;
946 char *token = NULL;
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;
955 enum tep_errno ret;
956
957 *parg = NULL;
958
959 do {
960 free(token);
961 type = read_token(&token);
962 switch (type) {
963 case EVENT_SQUOTE:
964 case EVENT_DQUOTE:
965 case EVENT_ITEM:
966 ret = create_arg_item(event, token, type, &arg, error_str);
967 if (ret < 0)
968 goto fail;
969 if (!left_item)
970 left_item = arg;
971 else if (current_exp) {
972 ret = add_right(current_exp, arg, error_str);
973 if (ret < 0)
974 goto fail;
975 left_item = NULL;
976 /* Not's only one one expression */
977 if (not) {
978 arg = NULL;
979 if (current_op)
980 goto fail_syntax;
981 free(token);
982 *parg = current_exp;
983 return 0;
984 }
985 } else
986 goto fail_syntax;
987 arg = NULL;
988 break;
989
990 case EVENT_DELIM:
991 if (*token == ',') {
992 show_error(error_str, "Illegal token ','");
993 ret = TEP_ERRNO__ILLEGAL_TOKEN;
994 goto fail;
995 }
996
997 if (*token == '(') {
998 if (left_item) {
999 show_error(error_str,
1000 "Open paren can not come after item");
1001 ret = TEP_ERRNO__INVALID_PAREN;
1002 goto fail;
1003 }
1004 if (current_exp) {
1005 show_error(error_str,
1006 "Open paren can not come after expression");
1007 ret = TEP_ERRNO__INVALID_PAREN;
1008 goto fail;
1009 }
1010
1011 ret = process_filter(event, &arg, error_str, 0);
1012 if (ret != TEP_ERRNO__UNBALANCED_PAREN) {
1013 if (ret == 0) {
1014 show_error(error_str,
1015 "Unbalanced number of '('");
1016 ret = TEP_ERRNO__UNBALANCED_PAREN;
1017 }
1018 goto fail;
1019 }
1020 ret = 0;
1021
1022 /* A not wants just one expression */
1023 if (not) {
1024 if (current_op)
1025 goto fail_syntax;
1026 *parg = arg;
1027 return 0;
1028 }
1029
1030 if (current_op)
1031 ret = add_right(current_op, arg, error_str);
1032 else
1033 current_exp = arg;
1034
1035 if (ret < 0)
1036 goto fail;
1037
1038 } else { /* ')' */
1039 if (!current_op && !current_exp)
1040 goto fail_syntax;
1041
1042 /* Make sure everything is finished at this level */
1043 if (current_exp && !check_op_done(current_exp))
1044 goto fail_syntax;
1045 if (current_op && !check_op_done(current_op))
1046 goto fail_syntax;
1047
1048 if (current_op)
1049 *parg = current_op;
1050 else
1051 *parg = current_exp;
1052 free(token);
1053 return TEP_ERRNO__UNBALANCED_PAREN;
1054 }
1055 break;
1056
1057 case EVENT_OP:
1058 op_type = process_op(token, &btype, &ctype, &etype);
1059
1060 /* All expect a left arg except for NOT */
1061 switch (op_type) {
1062 case OP_BOOL:
1063 /* Logic ops need a left expression */
1064 if (!current_exp && !current_op)
1065 goto fail_syntax;
1066 /* fall through */
1067 case OP_NOT:
1068 /* logic only processes ops and exp */
1069 if (left_item)
1070 goto fail_syntax;
1071 break;
1072 case OP_EXP:
1073 case OP_CMP:
1074 if (!left_item)
1075 goto fail_syntax;
1076 break;
1077 case OP_NONE:
1078 show_error(error_str,
1079 "Unknown op token %s", token);
1080 ret = TEP_ERRNO__UNKNOWN_TOKEN;
1081 goto fail;
1082 }
1083
1084 ret = 0;
1085 switch (op_type) {
1086 case OP_BOOL:
1087 arg = create_arg_op(btype);
1088 if (arg == NULL)
1089 goto fail_alloc;
1090 if (current_op)
1091 ret = add_left(arg, current_op);
1092 else
1093 ret = add_left(arg, current_exp);
1094 current_op = arg;
1095 current_exp = NULL;
1096 break;
1097
1098 case OP_NOT:
1099 arg = create_arg_op(btype);
1100 if (arg == NULL)
1101 goto fail_alloc;
1102 if (current_op)
1103 ret = add_right(current_op, arg, error_str);
1104 if (ret < 0)
1105 goto fail;
1106 current_exp = arg;
1107 ret = process_filter(event, &arg, error_str, 1);
1108 if (ret < 0)
1109 goto fail;
1110 ret = add_right(current_exp, arg, error_str);
1111 if (ret < 0)
1112 goto fail;
1113 break;
1114
1115 case OP_EXP:
1116 case OP_CMP:
1117 if (op_type == OP_EXP)
1118 arg = create_arg_exp(etype);
1119 else
1120 arg = create_arg_cmp(ctype);
1121 if (arg == NULL)
1122 goto fail_alloc;
1123
1124 if (current_op)
1125 ret = add_right(current_op, arg, error_str);
1126 if (ret < 0)
1127 goto fail;
1128 ret = add_left(arg, left_item);
1129 if (ret < 0) {
1130 arg = NULL;
1131 goto fail_syntax;
1132 }
1133 current_exp = arg;
1134 break;
1135 default:
1136 break;
1137 }
1138 arg = NULL;
1139 if (ret < 0)
1140 goto fail_syntax;
1141 break;
1142 case EVENT_NONE:
1143 break;
1144 case EVENT_ERROR:
1145 goto fail_alloc;
1146 default:
1147 goto fail_syntax;
1148 }
1149 } while (type != EVENT_NONE);
1150
1151 if (!current_op && !current_exp)
1152 goto fail_syntax;
1153
1154 if (!current_op)
1155 current_op = current_exp;
1156
1157 ret = collapse_tree(current_op, parg, error_str);
1158 /* collapse_tree() may free current_op, and updates parg accordingly */
1159 current_op = NULL;
1160 if (ret < 0)
1161 goto fail;
1162
1163 free(token);
1164 return 0;
1165
1166 fail_alloc:
1167 show_error(error_str, "failed to allocate filter arg");
1168 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
1169 goto fail;
1170 fail_syntax:
1171 show_error(error_str, "Syntax error");
1172 ret = TEP_ERRNO__SYNTAX_ERROR;
1173 fail:
1174 free_arg(current_op);
1175 free_arg(current_exp);
1176 free_arg(arg);
1177 free(token);
1178 return ret;
1179 }
1180
1181 static enum tep_errno
process_event(struct event_format * event,const char * filter_str,struct filter_arg ** parg,char * error_str)1182 process_event(struct event_format *event, const char *filter_str,
1183 struct filter_arg **parg, char *error_str)
1184 {
1185 int ret;
1186
1187 tep_buffer_init(filter_str, strlen(filter_str));
1188
1189 ret = process_filter(event, parg, error_str, 0);
1190 if (ret < 0)
1191 return ret;
1192
1193 /* If parg is NULL, then make it into FALSE */
1194 if (!*parg) {
1195 *parg = allocate_arg();
1196 if (*parg == NULL)
1197 return TEP_ERRNO__MEM_ALLOC_FAILED;
1198
1199 (*parg)->type = FILTER_ARG_BOOLEAN;
1200 (*parg)->boolean.value = FILTER_FALSE;
1201 }
1202
1203 return 0;
1204 }
1205
1206 static enum tep_errno
filter_event(struct event_filter * filter,struct event_format * event,const char * filter_str,char * error_str)1207 filter_event(struct event_filter *filter, struct event_format *event,
1208 const char *filter_str, char *error_str)
1209 {
1210 struct filter_type *filter_type;
1211 struct filter_arg *arg;
1212 enum tep_errno ret;
1213
1214 if (filter_str) {
1215 ret = process_event(event, filter_str, &arg, error_str);
1216 if (ret < 0)
1217 return ret;
1218
1219 } else {
1220 /* just add a TRUE arg */
1221 arg = allocate_arg();
1222 if (arg == NULL)
1223 return TEP_ERRNO__MEM_ALLOC_FAILED;
1224
1225 arg->type = FILTER_ARG_BOOLEAN;
1226 arg->boolean.value = FILTER_TRUE;
1227 }
1228
1229 filter_type = add_filter_type(filter, event->id);
1230 if (filter_type == NULL)
1231 return TEP_ERRNO__MEM_ALLOC_FAILED;
1232
1233 if (filter_type->filter)
1234 free_arg(filter_type->filter);
1235 filter_type->filter = arg;
1236
1237 return 0;
1238 }
1239
filter_init_error_buf(struct event_filter * filter)1240 static void filter_init_error_buf(struct event_filter *filter)
1241 {
1242 /* clear buffer to reset show error */
1243 tep_buffer_init("", 0);
1244 filter->error_buffer[0] = '\0';
1245 }
1246
1247 /**
1248 * tep_filter_add_filter_str - add a new filter
1249 * @filter: the event filter to add to
1250 * @filter_str: the filter string that contains the filter
1251 *
1252 * Returns 0 if the filter was successfully added or a
1253 * negative error code. Use tep_filter_strerror() to see
1254 * actual error message in case of error.
1255 */
tep_filter_add_filter_str(struct event_filter * filter,const char * filter_str)1256 enum tep_errno tep_filter_add_filter_str(struct event_filter *filter,
1257 const char *filter_str)
1258 {
1259 struct tep_handle *pevent = filter->pevent;
1260 struct event_list *event;
1261 struct event_list *events = NULL;
1262 const char *filter_start;
1263 const char *next_event;
1264 char *this_event;
1265 char *event_name = NULL;
1266 char *sys_name = NULL;
1267 char *sp;
1268 enum tep_errno rtn = 0; /* TEP_ERRNO__SUCCESS */
1269 int len;
1270 int ret;
1271
1272 filter_init_error_buf(filter);
1273
1274 filter_start = strchr(filter_str, ':');
1275 if (filter_start)
1276 len = filter_start - filter_str;
1277 else
1278 len = strlen(filter_str);
1279
1280 do {
1281 next_event = strchr(filter_str, ',');
1282 if (next_event &&
1283 (!filter_start || next_event < filter_start))
1284 len = next_event - filter_str;
1285 else if (filter_start)
1286 len = filter_start - filter_str;
1287 else
1288 len = strlen(filter_str);
1289
1290 this_event = malloc(len + 1);
1291 if (this_event == NULL) {
1292 /* This can only happen when events is NULL, but still */
1293 free_events(events);
1294 return TEP_ERRNO__MEM_ALLOC_FAILED;
1295 }
1296 memcpy(this_event, filter_str, len);
1297 this_event[len] = 0;
1298
1299 if (next_event)
1300 next_event++;
1301
1302 filter_str = next_event;
1303
1304 sys_name = strtok_r(this_event, "/", &sp);
1305 event_name = strtok_r(NULL, "/", &sp);
1306
1307 if (!sys_name) {
1308 /* This can only happen when events is NULL, but still */
1309 free_events(events);
1310 free(this_event);
1311 return TEP_ERRNO__FILTER_NOT_FOUND;
1312 }
1313
1314 /* Find this event */
1315 ret = find_event(pevent, &events, strim(sys_name), strim(event_name));
1316 if (ret < 0) {
1317 free_events(events);
1318 free(this_event);
1319 return ret;
1320 }
1321 free(this_event);
1322 } while (filter_str);
1323
1324 /* Skip the ':' */
1325 if (filter_start)
1326 filter_start++;
1327
1328 /* filter starts here */
1329 for (event = events; event; event = event->next) {
1330 ret = filter_event(filter, event->event, filter_start,
1331 filter->error_buffer);
1332 /* Failures are returned if a parse error happened */
1333 if (ret < 0)
1334 rtn = ret;
1335
1336 if (ret >= 0 && pevent->test_filters) {
1337 char *test;
1338 test = tep_filter_make_string(filter, event->event->id);
1339 if (test) {
1340 printf(" '%s: %s'\n", event->event->name, test);
1341 free(test);
1342 }
1343 }
1344 }
1345
1346 free_events(events);
1347
1348 if (rtn >= 0 && pevent->test_filters)
1349 exit(0);
1350
1351 return rtn;
1352 }
1353
free_filter_type(struct filter_type * filter_type)1354 static void free_filter_type(struct filter_type *filter_type)
1355 {
1356 free_arg(filter_type->filter);
1357 }
1358
1359 /**
1360 * tep_filter_strerror - fill error message in a buffer
1361 * @filter: the event filter contains error
1362 * @err: the error code
1363 * @buf: the buffer to be filled in
1364 * @buflen: the size of the buffer
1365 *
1366 * Returns 0 if message was filled successfully, -1 if error
1367 */
tep_filter_strerror(struct event_filter * filter,enum tep_errno err,char * buf,size_t buflen)1368 int tep_filter_strerror(struct event_filter *filter, enum tep_errno err,
1369 char *buf, size_t buflen)
1370 {
1371 if (err <= __TEP_ERRNO__START || err >= __TEP_ERRNO__END)
1372 return -1;
1373
1374 if (strlen(filter->error_buffer) > 0) {
1375 size_t len = snprintf(buf, buflen, "%s", filter->error_buffer);
1376
1377 if (len > buflen)
1378 return -1;
1379 return 0;
1380 }
1381
1382 return tep_strerror(filter->pevent, err, buf, buflen);
1383 }
1384
1385 /**
1386 * tep_filter_remove_event - remove a filter for an event
1387 * @filter: the event filter to remove from
1388 * @event_id: the event to remove a filter for
1389 *
1390 * Removes the filter saved for an event defined by @event_id
1391 * from the @filter.
1392 *
1393 * Returns 1: if an event was removed
1394 * 0: if the event was not found
1395 */
tep_filter_remove_event(struct event_filter * filter,int event_id)1396 int tep_filter_remove_event(struct event_filter *filter,
1397 int event_id)
1398 {
1399 struct filter_type *filter_type;
1400 unsigned long len;
1401
1402 if (!filter->filters)
1403 return 0;
1404
1405 filter_type = find_filter_type(filter, event_id);
1406
1407 if (!filter_type)
1408 return 0;
1409
1410 free_filter_type(filter_type);
1411
1412 /* The filter_type points into the event_filters array */
1413 len = (unsigned long)(filter->event_filters + filter->filters) -
1414 (unsigned long)(filter_type + 1);
1415
1416 memmove(filter_type, filter_type + 1, len);
1417 filter->filters--;
1418
1419 memset(&filter->event_filters[filter->filters], 0,
1420 sizeof(*filter_type));
1421
1422 return 1;
1423 }
1424
1425 /**
1426 * tep_filter_reset - clear all filters in a filter
1427 * @filter: the event filter to reset
1428 *
1429 * Removes all filters from a filter and resets it.
1430 */
tep_filter_reset(struct event_filter * filter)1431 void tep_filter_reset(struct event_filter *filter)
1432 {
1433 int i;
1434
1435 for (i = 0; i < filter->filters; i++)
1436 free_filter_type(&filter->event_filters[i]);
1437
1438 free(filter->event_filters);
1439 filter->filters = 0;
1440 filter->event_filters = NULL;
1441 }
1442
tep_filter_free(struct event_filter * filter)1443 void tep_filter_free(struct event_filter *filter)
1444 {
1445 tep_unref(filter->pevent);
1446
1447 tep_filter_reset(filter);
1448
1449 free(filter);
1450 }
1451
1452 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg);
1453
copy_filter_type(struct event_filter * filter,struct event_filter * source,struct filter_type * filter_type)1454 static int copy_filter_type(struct event_filter *filter,
1455 struct event_filter *source,
1456 struct filter_type *filter_type)
1457 {
1458 struct filter_arg *arg;
1459 struct event_format *event;
1460 const char *sys;
1461 const char *name;
1462 char *str;
1463
1464 /* Can't assume that the pevent's are the same */
1465 sys = filter_type->event->system;
1466 name = filter_type->event->name;
1467 event = tep_find_event_by_name(filter->pevent, sys, name);
1468 if (!event)
1469 return -1;
1470
1471 str = arg_to_str(source, filter_type->filter);
1472 if (!str)
1473 return -1;
1474
1475 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
1476 /* Add trivial event */
1477 arg = allocate_arg();
1478 if (arg == NULL)
1479 return -1;
1480
1481 arg->type = FILTER_ARG_BOOLEAN;
1482 if (strcmp(str, "TRUE") == 0)
1483 arg->boolean.value = 1;
1484 else
1485 arg->boolean.value = 0;
1486
1487 filter_type = add_filter_type(filter, event->id);
1488 if (filter_type == NULL)
1489 return -1;
1490
1491 filter_type->filter = arg;
1492
1493 free(str);
1494 return 0;
1495 }
1496
1497 filter_event(filter, event, str, NULL);
1498 free(str);
1499
1500 return 0;
1501 }
1502
1503 /**
1504 * tep_filter_copy - copy a filter using another filter
1505 * @dest - the filter to copy to
1506 * @source - the filter to copy from
1507 *
1508 * Returns 0 on success and -1 if not all filters were copied
1509 */
tep_filter_copy(struct event_filter * dest,struct event_filter * source)1510 int tep_filter_copy(struct event_filter *dest, struct event_filter *source)
1511 {
1512 int ret = 0;
1513 int i;
1514
1515 tep_filter_reset(dest);
1516
1517 for (i = 0; i < source->filters; i++) {
1518 if (copy_filter_type(dest, source, &source->event_filters[i]))
1519 ret = -1;
1520 }
1521 return ret;
1522 }
1523
1524
1525 /**
1526 * tep_update_trivial - update the trivial filters with the given filter
1527 * @dest - the filter to update
1528 * @source - the filter as the source of the update
1529 * @type - the type of trivial filter to update.
1530 *
1531 * Scan dest for trivial events matching @type to replace with the source.
1532 *
1533 * Returns 0 on success and -1 if there was a problem updating, but
1534 * events may have still been updated on error.
1535 */
tep_update_trivial(struct event_filter * dest,struct event_filter * source,enum filter_trivial_type type)1536 int tep_update_trivial(struct event_filter *dest, struct event_filter *source,
1537 enum filter_trivial_type type)
1538 {
1539 struct tep_handle *src_pevent;
1540 struct tep_handle *dest_pevent;
1541 struct event_format *event;
1542 struct filter_type *filter_type;
1543 struct filter_arg *arg;
1544 char *str;
1545 int i;
1546
1547 src_pevent = source->pevent;
1548 dest_pevent = dest->pevent;
1549
1550 /* Do nothing if either of the filters has nothing to filter */
1551 if (!dest->filters || !source->filters)
1552 return 0;
1553
1554 for (i = 0; i < dest->filters; i++) {
1555 filter_type = &dest->event_filters[i];
1556 arg = filter_type->filter;
1557 if (arg->type != FILTER_ARG_BOOLEAN)
1558 continue;
1559 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) ||
1560 (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE))
1561 continue;
1562
1563 event = filter_type->event;
1564
1565 if (src_pevent != dest_pevent) {
1566 /* do a look up */
1567 event = tep_find_event_by_name(src_pevent,
1568 event->system,
1569 event->name);
1570 if (!event)
1571 return -1;
1572 }
1573
1574 str = tep_filter_make_string(source, event->id);
1575 if (!str)
1576 continue;
1577
1578 /* Don't bother if the filter is trivial too */
1579 if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0)
1580 filter_event(dest, event, str, NULL);
1581 free(str);
1582 }
1583 return 0;
1584 }
1585
1586 /**
1587 * tep_filter_clear_trivial - clear TRUE and FALSE filters
1588 * @filter: the filter to remove trivial filters from
1589 * @type: remove only true, false, or both
1590 *
1591 * Removes filters that only contain a TRUE or FALES boolean arg.
1592 *
1593 * Returns 0 on success and -1 if there was a problem.
1594 */
tep_filter_clear_trivial(struct event_filter * filter,enum filter_trivial_type type)1595 int tep_filter_clear_trivial(struct event_filter *filter,
1596 enum filter_trivial_type type)
1597 {
1598 struct filter_type *filter_type;
1599 int count = 0;
1600 int *ids = NULL;
1601 int i;
1602
1603 if (!filter->filters)
1604 return 0;
1605
1606 /*
1607 * Two steps, first get all ids with trivial filters.
1608 * then remove those ids.
1609 */
1610 for (i = 0; i < filter->filters; i++) {
1611 int *new_ids;
1612
1613 filter_type = &filter->event_filters[i];
1614 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1615 continue;
1616 switch (type) {
1617 case FILTER_TRIVIAL_FALSE:
1618 if (filter_type->filter->boolean.value)
1619 continue;
1620 break;
1621 case FILTER_TRIVIAL_TRUE:
1622 if (!filter_type->filter->boolean.value)
1623 continue;
1624 default:
1625 break;
1626 }
1627
1628 new_ids = realloc(ids, sizeof(*ids) * (count + 1));
1629 if (!new_ids) {
1630 free(ids);
1631 return -1;
1632 }
1633
1634 ids = new_ids;
1635 ids[count++] = filter_type->event_id;
1636 }
1637
1638 if (!count)
1639 return 0;
1640
1641 for (i = 0; i < count; i++)
1642 tep_filter_remove_event(filter, ids[i]);
1643
1644 free(ids);
1645 return 0;
1646 }
1647
1648 /**
1649 * tep_filter_event_has_trivial - return true event contains trivial filter
1650 * @filter: the filter with the information
1651 * @event_id: the id of the event to test
1652 * @type: trivial type to test for (TRUE, FALSE, EITHER)
1653 *
1654 * Returns 1 if the event contains a matching trivial type
1655 * otherwise 0.
1656 */
tep_filter_event_has_trivial(struct event_filter * filter,int event_id,enum filter_trivial_type type)1657 int tep_filter_event_has_trivial(struct event_filter *filter,
1658 int event_id,
1659 enum filter_trivial_type type)
1660 {
1661 struct filter_type *filter_type;
1662
1663 if (!filter->filters)
1664 return 0;
1665
1666 filter_type = find_filter_type(filter, event_id);
1667
1668 if (!filter_type)
1669 return 0;
1670
1671 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1672 return 0;
1673
1674 switch (type) {
1675 case FILTER_TRIVIAL_FALSE:
1676 return !filter_type->filter->boolean.value;
1677
1678 case FILTER_TRIVIAL_TRUE:
1679 return filter_type->filter->boolean.value;
1680 default:
1681 return 1;
1682 }
1683 }
1684
1685 static int test_filter(struct event_format *event, struct filter_arg *arg,
1686 struct tep_record *record, enum tep_errno *err);
1687
1688 static const char *
get_comm(struct event_format * event,struct tep_record * record)1689 get_comm(struct event_format *event, struct tep_record *record)
1690 {
1691 const char *comm;
1692 int pid;
1693
1694 pid = tep_data_pid(event->pevent, record);
1695 comm = tep_data_comm_from_pid(event->pevent, pid);
1696 return comm;
1697 }
1698
1699 static unsigned long long
get_value(struct event_format * event,struct format_field * field,struct tep_record * record)1700 get_value(struct event_format *event,
1701 struct format_field *field, struct tep_record *record)
1702 {
1703 unsigned long long val;
1704
1705 /* Handle our dummy "comm" field */
1706 if (field == &comm) {
1707 const char *name;
1708
1709 name = get_comm(event, record);
1710 return (unsigned long)name;
1711 }
1712
1713 /* Handle our dummy "cpu" field */
1714 if (field == &cpu)
1715 return record->cpu;
1716
1717 tep_read_number_field(field, record->data, &val);
1718
1719 if (!(field->flags & FIELD_IS_SIGNED))
1720 return val;
1721
1722 switch (field->size) {
1723 case 1:
1724 return (char)val;
1725 case 2:
1726 return (short)val;
1727 case 4:
1728 return (int)val;
1729 case 8:
1730 return (long long)val;
1731 }
1732 return val;
1733 }
1734
1735 static unsigned long long
1736 get_arg_value(struct event_format *event, struct filter_arg *arg,
1737 struct tep_record *record, enum tep_errno *err);
1738
1739 static unsigned long long
get_exp_value(struct event_format * event,struct filter_arg * arg,struct tep_record * record,enum tep_errno * err)1740 get_exp_value(struct event_format *event, struct filter_arg *arg,
1741 struct tep_record *record, enum tep_errno *err)
1742 {
1743 unsigned long long lval, rval;
1744
1745 lval = get_arg_value(event, arg->exp.left, record, err);
1746 rval = get_arg_value(event, arg->exp.right, record, err);
1747
1748 if (*err) {
1749 /*
1750 * There was an error, no need to process anymore.
1751 */
1752 return 0;
1753 }
1754
1755 switch (arg->exp.type) {
1756 case FILTER_EXP_ADD:
1757 return lval + rval;
1758
1759 case FILTER_EXP_SUB:
1760 return lval - rval;
1761
1762 case FILTER_EXP_MUL:
1763 return lval * rval;
1764
1765 case FILTER_EXP_DIV:
1766 return lval / rval;
1767
1768 case FILTER_EXP_MOD:
1769 return lval % rval;
1770
1771 case FILTER_EXP_RSHIFT:
1772 return lval >> rval;
1773
1774 case FILTER_EXP_LSHIFT:
1775 return lval << rval;
1776
1777 case FILTER_EXP_AND:
1778 return lval & rval;
1779
1780 case FILTER_EXP_OR:
1781 return lval | rval;
1782
1783 case FILTER_EXP_XOR:
1784 return lval ^ rval;
1785
1786 case FILTER_EXP_NOT:
1787 default:
1788 if (!*err)
1789 *err = TEP_ERRNO__INVALID_EXP_TYPE;
1790 }
1791 return 0;
1792 }
1793
1794 static unsigned long long
get_arg_value(struct event_format * event,struct filter_arg * arg,struct tep_record * record,enum tep_errno * err)1795 get_arg_value(struct event_format *event, struct filter_arg *arg,
1796 struct tep_record *record, enum tep_errno *err)
1797 {
1798 switch (arg->type) {
1799 case FILTER_ARG_FIELD:
1800 return get_value(event, arg->field.field, record);
1801
1802 case FILTER_ARG_VALUE:
1803 if (arg->value.type != FILTER_NUMBER) {
1804 if (!*err)
1805 *err = TEP_ERRNO__NOT_A_NUMBER;
1806 }
1807 return arg->value.val;
1808
1809 case FILTER_ARG_EXP:
1810 return get_exp_value(event, arg, record, err);
1811
1812 default:
1813 if (!*err)
1814 *err = TEP_ERRNO__INVALID_ARG_TYPE;
1815 }
1816 return 0;
1817 }
1818
test_num(struct event_format * event,struct filter_arg * arg,struct tep_record * record,enum tep_errno * err)1819 static int test_num(struct event_format *event, struct filter_arg *arg,
1820 struct tep_record *record, enum tep_errno *err)
1821 {
1822 unsigned long long lval, rval;
1823
1824 lval = get_arg_value(event, arg->num.left, record, err);
1825 rval = get_arg_value(event, arg->num.right, record, err);
1826
1827 if (*err) {
1828 /*
1829 * There was an error, no need to process anymore.
1830 */
1831 return 0;
1832 }
1833
1834 switch (arg->num.type) {
1835 case FILTER_CMP_EQ:
1836 return lval == rval;
1837
1838 case FILTER_CMP_NE:
1839 return lval != rval;
1840
1841 case FILTER_CMP_GT:
1842 return lval > rval;
1843
1844 case FILTER_CMP_LT:
1845 return lval < rval;
1846
1847 case FILTER_CMP_GE:
1848 return lval >= rval;
1849
1850 case FILTER_CMP_LE:
1851 return lval <= rval;
1852
1853 default:
1854 if (!*err)
1855 *err = TEP_ERRNO__ILLEGAL_INTEGER_CMP;
1856 return 0;
1857 }
1858 }
1859
get_field_str(struct filter_arg * arg,struct tep_record * record)1860 static const char *get_field_str(struct filter_arg *arg, struct tep_record *record)
1861 {
1862 struct event_format *event;
1863 struct tep_handle *pevent;
1864 unsigned long long addr;
1865 const char *val = NULL;
1866 unsigned int size;
1867 char hex[64];
1868
1869 /* If the field is not a string convert it */
1870 if (arg->str.field->flags & FIELD_IS_STRING) {
1871 val = record->data + arg->str.field->offset;
1872 size = arg->str.field->size;
1873
1874 if (arg->str.field->flags & FIELD_IS_DYNAMIC) {
1875 addr = *(unsigned int *)val;
1876 val = record->data + (addr & 0xffff);
1877 size = addr >> 16;
1878 }
1879
1880 /*
1881 * We need to copy the data since we can't be sure the field
1882 * is null terminated.
1883 */
1884 if (*(val + size - 1)) {
1885 /* copy it */
1886 memcpy(arg->str.buffer, val, arg->str.field->size);
1887 /* the buffer is already NULL terminated */
1888 val = arg->str.buffer;
1889 }
1890
1891 } else {
1892 event = arg->str.field->event;
1893 pevent = event->pevent;
1894 addr = get_value(event, arg->str.field, record);
1895
1896 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
1897 /* convert to a kernel symbol */
1898 val = tep_find_function(pevent, addr);
1899
1900 if (val == NULL) {
1901 /* just use the hex of the string name */
1902 snprintf(hex, 64, "0x%llx", addr);
1903 val = hex;
1904 }
1905 }
1906
1907 return val;
1908 }
1909
test_str(struct event_format * event,struct filter_arg * arg,struct tep_record * record,enum tep_errno * err)1910 static int test_str(struct event_format *event, struct filter_arg *arg,
1911 struct tep_record *record, enum tep_errno *err)
1912 {
1913 const char *val;
1914
1915 if (arg->str.field == &comm)
1916 val = get_comm(event, record);
1917 else
1918 val = get_field_str(arg, record);
1919
1920 switch (arg->str.type) {
1921 case FILTER_CMP_MATCH:
1922 return strcmp(val, arg->str.val) == 0;
1923
1924 case FILTER_CMP_NOT_MATCH:
1925 return strcmp(val, arg->str.val) != 0;
1926
1927 case FILTER_CMP_REGEX:
1928 /* Returns zero on match */
1929 return !regexec(&arg->str.reg, val, 0, NULL, 0);
1930
1931 case FILTER_CMP_NOT_REGEX:
1932 return regexec(&arg->str.reg, val, 0, NULL, 0);
1933
1934 default:
1935 if (!*err)
1936 *err = TEP_ERRNO__ILLEGAL_STRING_CMP;
1937 return 0;
1938 }
1939 }
1940
test_op(struct event_format * event,struct filter_arg * arg,struct tep_record * record,enum tep_errno * err)1941 static int test_op(struct event_format *event, struct filter_arg *arg,
1942 struct tep_record *record, enum tep_errno *err)
1943 {
1944 switch (arg->op.type) {
1945 case FILTER_OP_AND:
1946 return test_filter(event, arg->op.left, record, err) &&
1947 test_filter(event, arg->op.right, record, err);
1948
1949 case FILTER_OP_OR:
1950 return test_filter(event, arg->op.left, record, err) ||
1951 test_filter(event, arg->op.right, record, err);
1952
1953 case FILTER_OP_NOT:
1954 return !test_filter(event, arg->op.right, record, err);
1955
1956 default:
1957 if (!*err)
1958 *err = TEP_ERRNO__INVALID_OP_TYPE;
1959 return 0;
1960 }
1961 }
1962
test_filter(struct event_format * event,struct filter_arg * arg,struct tep_record * record,enum tep_errno * err)1963 static int test_filter(struct event_format *event, struct filter_arg *arg,
1964 struct tep_record *record, enum tep_errno *err)
1965 {
1966 if (*err) {
1967 /*
1968 * There was an error, no need to process anymore.
1969 */
1970 return 0;
1971 }
1972
1973 switch (arg->type) {
1974 case FILTER_ARG_BOOLEAN:
1975 /* easy case */
1976 return arg->boolean.value;
1977
1978 case FILTER_ARG_OP:
1979 return test_op(event, arg, record, err);
1980
1981 case FILTER_ARG_NUM:
1982 return test_num(event, arg, record, err);
1983
1984 case FILTER_ARG_STR:
1985 return test_str(event, arg, record, err);
1986
1987 case FILTER_ARG_EXP:
1988 case FILTER_ARG_VALUE:
1989 case FILTER_ARG_FIELD:
1990 /*
1991 * Expressions, fields and values evaluate
1992 * to true if they return non zero
1993 */
1994 return !!get_arg_value(event, arg, record, err);
1995
1996 default:
1997 if (!*err)
1998 *err = TEP_ERRNO__INVALID_ARG_TYPE;
1999 return 0;
2000 }
2001 }
2002
2003 /**
2004 * tep_event_filtered - return true if event has filter
2005 * @filter: filter struct with filter information
2006 * @event_id: event id to test if filter exists
2007 *
2008 * Returns 1 if filter found for @event_id
2009 * otherwise 0;
2010 */
tep_event_filtered(struct event_filter * filter,int event_id)2011 int tep_event_filtered(struct event_filter *filter, int event_id)
2012 {
2013 struct filter_type *filter_type;
2014
2015 if (!filter->filters)
2016 return 0;
2017
2018 filter_type = find_filter_type(filter, event_id);
2019
2020 return filter_type ? 1 : 0;
2021 }
2022
2023 /**
2024 * tep_filter_match - test if a record matches a filter
2025 * @filter: filter struct with filter information
2026 * @record: the record to test against the filter
2027 *
2028 * Returns: match result or error code (prefixed with TEP_ERRNO__)
2029 * FILTER_MATCH - filter found for event and @record matches
2030 * FILTER_MISS - filter found for event and @record does not match
2031 * FILTER_NOT_FOUND - no filter found for @record's event
2032 * NO_FILTER - if no filters exist
2033 * otherwise - error occurred during test
2034 */
tep_filter_match(struct event_filter * filter,struct tep_record * record)2035 enum tep_errno tep_filter_match(struct event_filter *filter,
2036 struct tep_record *record)
2037 {
2038 struct tep_handle *pevent = filter->pevent;
2039 struct filter_type *filter_type;
2040 int event_id;
2041 int ret;
2042 enum tep_errno err = 0;
2043
2044 filter_init_error_buf(filter);
2045
2046 if (!filter->filters)
2047 return TEP_ERRNO__NO_FILTER;
2048
2049 event_id = tep_data_type(pevent, record);
2050
2051 filter_type = find_filter_type(filter, event_id);
2052 if (!filter_type)
2053 return TEP_ERRNO__FILTER_NOT_FOUND;
2054
2055 ret = test_filter(filter_type->event, filter_type->filter, record, &err);
2056 if (err)
2057 return err;
2058
2059 return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS;
2060 }
2061
op_to_str(struct event_filter * filter,struct filter_arg * arg)2062 static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
2063 {
2064 char *str = NULL;
2065 char *left = NULL;
2066 char *right = NULL;
2067 char *op = NULL;
2068 int left_val = -1;
2069 int right_val = -1;
2070 int val;
2071
2072 switch (arg->op.type) {
2073 case FILTER_OP_AND:
2074 op = "&&";
2075 /* fall through */
2076 case FILTER_OP_OR:
2077 if (!op)
2078 op = "||";
2079
2080 left = arg_to_str(filter, arg->op.left);
2081 right = arg_to_str(filter, arg->op.right);
2082 if (!left || !right)
2083 break;
2084
2085 /* Try to consolidate boolean values */
2086 if (strcmp(left, "TRUE") == 0)
2087 left_val = 1;
2088 else if (strcmp(left, "FALSE") == 0)
2089 left_val = 0;
2090
2091 if (strcmp(right, "TRUE") == 0)
2092 right_val = 1;
2093 else if (strcmp(right, "FALSE") == 0)
2094 right_val = 0;
2095
2096 if (left_val >= 0) {
2097 if ((arg->op.type == FILTER_OP_AND && !left_val) ||
2098 (arg->op.type == FILTER_OP_OR && left_val)) {
2099 /* Just return left value */
2100 str = left;
2101 left = NULL;
2102 break;
2103 }
2104 if (right_val >= 0) {
2105 /* just evaluate this. */
2106 val = 0;
2107 switch (arg->op.type) {
2108 case FILTER_OP_AND:
2109 val = left_val && right_val;
2110 break;
2111 case FILTER_OP_OR:
2112 val = left_val || right_val;
2113 break;
2114 default:
2115 break;
2116 }
2117 asprintf(&str, val ? "TRUE" : "FALSE");
2118 break;
2119 }
2120 }
2121 if (right_val >= 0) {
2122 if ((arg->op.type == FILTER_OP_AND && !right_val) ||
2123 (arg->op.type == FILTER_OP_OR && right_val)) {
2124 /* Just return right value */
2125 str = right;
2126 right = NULL;
2127 break;
2128 }
2129 /* The right value is meaningless */
2130 str = left;
2131 left = NULL;
2132 break;
2133 }
2134
2135 asprintf(&str, "(%s) %s (%s)", left, op, right);
2136 break;
2137
2138 case FILTER_OP_NOT:
2139 op = "!";
2140 right = arg_to_str(filter, arg->op.right);
2141 if (!right)
2142 break;
2143
2144 /* See if we can consolidate */
2145 if (strcmp(right, "TRUE") == 0)
2146 right_val = 1;
2147 else if (strcmp(right, "FALSE") == 0)
2148 right_val = 0;
2149 if (right_val >= 0) {
2150 /* just return the opposite */
2151 asprintf(&str, right_val ? "FALSE" : "TRUE");
2152 break;
2153 }
2154 asprintf(&str, "%s(%s)", op, right);
2155 break;
2156
2157 default:
2158 /* ?? */
2159 break;
2160 }
2161 free(left);
2162 free(right);
2163 return str;
2164 }
2165
val_to_str(struct event_filter * filter,struct filter_arg * arg)2166 static char *val_to_str(struct event_filter *filter, struct filter_arg *arg)
2167 {
2168 char *str = NULL;
2169
2170 asprintf(&str, "%lld", arg->value.val);
2171
2172 return str;
2173 }
2174
field_to_str(struct event_filter * filter,struct filter_arg * arg)2175 static char *field_to_str(struct event_filter *filter, struct filter_arg *arg)
2176 {
2177 return strdup(arg->field.field->name);
2178 }
2179
exp_to_str(struct event_filter * filter,struct filter_arg * arg)2180 static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2181 {
2182 char *lstr;
2183 char *rstr;
2184 char *op;
2185 char *str = NULL;
2186
2187 lstr = arg_to_str(filter, arg->exp.left);
2188 rstr = arg_to_str(filter, arg->exp.right);
2189 if (!lstr || !rstr)
2190 goto out;
2191
2192 switch (arg->exp.type) {
2193 case FILTER_EXP_ADD:
2194 op = "+";
2195 break;
2196 case FILTER_EXP_SUB:
2197 op = "-";
2198 break;
2199 case FILTER_EXP_MUL:
2200 op = "*";
2201 break;
2202 case FILTER_EXP_DIV:
2203 op = "/";
2204 break;
2205 case FILTER_EXP_MOD:
2206 op = "%";
2207 break;
2208 case FILTER_EXP_RSHIFT:
2209 op = ">>";
2210 break;
2211 case FILTER_EXP_LSHIFT:
2212 op = "<<";
2213 break;
2214 case FILTER_EXP_AND:
2215 op = "&";
2216 break;
2217 case FILTER_EXP_OR:
2218 op = "|";
2219 break;
2220 case FILTER_EXP_XOR:
2221 op = "^";
2222 break;
2223 default:
2224 op = "[ERROR IN EXPRESSION TYPE]";
2225 break;
2226 }
2227
2228 asprintf(&str, "%s %s %s", lstr, op, rstr);
2229 out:
2230 free(lstr);
2231 free(rstr);
2232
2233 return str;
2234 }
2235
num_to_str(struct event_filter * filter,struct filter_arg * arg)2236 static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2237 {
2238 char *lstr;
2239 char *rstr;
2240 char *str = NULL;
2241 char *op = NULL;
2242
2243 lstr = arg_to_str(filter, arg->num.left);
2244 rstr = arg_to_str(filter, arg->num.right);
2245 if (!lstr || !rstr)
2246 goto out;
2247
2248 switch (arg->num.type) {
2249 case FILTER_CMP_EQ:
2250 op = "==";
2251 /* fall through */
2252 case FILTER_CMP_NE:
2253 if (!op)
2254 op = "!=";
2255 /* fall through */
2256 case FILTER_CMP_GT:
2257 if (!op)
2258 op = ">";
2259 /* fall through */
2260 case FILTER_CMP_LT:
2261 if (!op)
2262 op = "<";
2263 /* fall through */
2264 case FILTER_CMP_GE:
2265 if (!op)
2266 op = ">=";
2267 /* fall through */
2268 case FILTER_CMP_LE:
2269 if (!op)
2270 op = "<=";
2271
2272 asprintf(&str, "%s %s %s", lstr, op, rstr);
2273 break;
2274
2275 default:
2276 /* ?? */
2277 break;
2278 }
2279
2280 out:
2281 free(lstr);
2282 free(rstr);
2283 return str;
2284 }
2285
str_to_str(struct event_filter * filter,struct filter_arg * arg)2286 static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
2287 {
2288 char *str = NULL;
2289 char *op = NULL;
2290
2291 switch (arg->str.type) {
2292 case FILTER_CMP_MATCH:
2293 op = "==";
2294 /* fall through */
2295 case FILTER_CMP_NOT_MATCH:
2296 if (!op)
2297 op = "!=";
2298 /* fall through */
2299 case FILTER_CMP_REGEX:
2300 if (!op)
2301 op = "=~";
2302 /* fall through */
2303 case FILTER_CMP_NOT_REGEX:
2304 if (!op)
2305 op = "!~";
2306
2307 asprintf(&str, "%s %s \"%s\"",
2308 arg->str.field->name, op, arg->str.val);
2309 break;
2310
2311 default:
2312 /* ?? */
2313 break;
2314 }
2315 return str;
2316 }
2317
arg_to_str(struct event_filter * filter,struct filter_arg * arg)2318 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
2319 {
2320 char *str = NULL;
2321
2322 switch (arg->type) {
2323 case FILTER_ARG_BOOLEAN:
2324 asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE");
2325 return str;
2326
2327 case FILTER_ARG_OP:
2328 return op_to_str(filter, arg);
2329
2330 case FILTER_ARG_NUM:
2331 return num_to_str(filter, arg);
2332
2333 case FILTER_ARG_STR:
2334 return str_to_str(filter, arg);
2335
2336 case FILTER_ARG_VALUE:
2337 return val_to_str(filter, arg);
2338
2339 case FILTER_ARG_FIELD:
2340 return field_to_str(filter, arg);
2341
2342 case FILTER_ARG_EXP:
2343 return exp_to_str(filter, arg);
2344
2345 default:
2346 /* ?? */
2347 return NULL;
2348 }
2349
2350 }
2351
2352 /**
2353 * tep_filter_make_string - return a string showing the filter
2354 * @filter: filter struct with filter information
2355 * @event_id: the event id to return the filter string with
2356 *
2357 * Returns a string that displays the filter contents.
2358 * This string must be freed with free(str).
2359 * NULL is returned if no filter is found or allocation failed.
2360 */
2361 char *
tep_filter_make_string(struct event_filter * filter,int event_id)2362 tep_filter_make_string(struct event_filter *filter, int event_id)
2363 {
2364 struct filter_type *filter_type;
2365
2366 if (!filter->filters)
2367 return NULL;
2368
2369 filter_type = find_filter_type(filter, event_id);
2370
2371 if (!filter_type)
2372 return NULL;
2373
2374 return arg_to_str(filter, filter_type->filter);
2375 }
2376
2377 /**
2378 * tep_filter_compare - compare two filters and return if they are the same
2379 * @filter1: Filter to compare with @filter2
2380 * @filter2: Filter to compare with @filter1
2381 *
2382 * Returns:
2383 * 1 if the two filters hold the same content.
2384 * 0 if they do not.
2385 */
tep_filter_compare(struct event_filter * filter1,struct event_filter * filter2)2386 int tep_filter_compare(struct event_filter *filter1, struct event_filter *filter2)
2387 {
2388 struct filter_type *filter_type1;
2389 struct filter_type *filter_type2;
2390 char *str1, *str2;
2391 int result;
2392 int i;
2393
2394 /* Do the easy checks first */
2395 if (filter1->filters != filter2->filters)
2396 return 0;
2397 if (!filter1->filters && !filter2->filters)
2398 return 1;
2399
2400 /*
2401 * Now take a look at each of the events to see if they have the same
2402 * filters to them.
2403 */
2404 for (i = 0; i < filter1->filters; i++) {
2405 filter_type1 = &filter1->event_filters[i];
2406 filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2407 if (!filter_type2)
2408 break;
2409 if (filter_type1->filter->type != filter_type2->filter->type)
2410 break;
2411 switch (filter_type1->filter->type) {
2412 case FILTER_TRIVIAL_FALSE:
2413 case FILTER_TRIVIAL_TRUE:
2414 /* trivial types just need the type compared */
2415 continue;
2416 default:
2417 break;
2418 }
2419 /* The best way to compare complex filters is with strings */
2420 str1 = arg_to_str(filter1, filter_type1->filter);
2421 str2 = arg_to_str(filter2, filter_type2->filter);
2422 if (str1 && str2)
2423 result = strcmp(str1, str2) != 0;
2424 else
2425 /* bail out if allocation fails */
2426 result = 1;
2427
2428 free(str1);
2429 free(str2);
2430 if (result)
2431 break;
2432 }
2433
2434 if (i < filter1->filters)
2435 return 0;
2436 return 1;
2437 }
2438
2439