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