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