]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/blob - tools/lib/traceevent/parse-filter.c
ARM: mxs_defconfig: Improve USB related support
[can-eth-gw-linux.git] / tools / lib / traceevent / parse-filter.c
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
33 static struct format_field comm = {
34         .name = "COMM",
35 };
36
37 struct event_list {
38         struct event_list       *next;
39         struct event_format     *event;
40 };
41
42 #define MAX_ERR_STR_SIZE 256
43
44 static 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
79 static void free_token(char *token)
80 {
81         pevent_free_token(token);
82 }
83
84 static 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 */
99                 *tok = malloc_or_die(3);
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
111 static 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
125 static struct filter_type *
126 find_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
141 static struct filter_type *
142 add_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
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");
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  */
182 struct 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
194 static 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
204 static 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
231 static 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
242 static 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
254 static int
255 find_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
310 static 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
321 static struct filter_arg *
322 create_arg_item(struct event_format *event, const char *token,
323                 enum event_type type, char **error_str)
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;
355                                 arg->boolean.value = FILTER_FALSE;
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
373 static struct filter_arg *
374 create_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
385 static struct filter_arg *
386 create_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
397 static struct filter_arg *
398 create_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
410 static 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;
483                                 op->boolean.value = FILTER_FALSE;
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
571 static struct filter_arg *
572 rotate_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
581 static 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
609 enum op_type {
610         OP_NONE,
611         OP_BOOL,
612         OP_NOT,
613         OP_EXP,
614         OP_CMP,
615 };
616
617 static 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
686 static 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
711 enum filter_vals {
712         FILTER_VAL_NORM,
713         FILTER_VAL_FALSE,
714         FILTER_VAL_TRUE,
715 };
716
717 void 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
760 enum 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:
768                 return FILTER_VAL_FALSE + arg->boolean.value;
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 */
853 static 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;
867                 arg->boolean.value = ret == FILTER_VAL_TRUE;
868         }
869
870         return arg;
871 }
872
873 static int
874 process_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
1091 static int
1092 process_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;
1112                 (*parg)->boolean.value = FILTER_FALSE;
1113         }
1114
1115         return 0;
1116 }
1117
1118 static 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;
1135                 arg->boolean.value = FILTER_TRUE;
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  */
1159 int 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
1265 static 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  */
1281 int 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  */
1316 void 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
1328 void 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
1337 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg);
1338
1339 static 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)
1365                         arg->boolean.value = 1;
1366                 else
1367                         arg->boolean.value = 0;
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  */
1389 int 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  */
1415 int 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;
1438                 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) ||
1439                     (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE))
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  */
1472 void 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;
1477         int *ids = NULL;
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:
1493                         if (filter_type->filter->boolean.value)
1494                                 continue;
1495                 case FILTER_TRIVIAL_TRUE:
1496                         if (!filter_type->filter->boolean.value)
1497                                 continue;
1498                 default:
1499                         break;
1500                 }
1501
1502                 ids = realloc(ids, sizeof(*ids) * (count + 1));
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  */
1526 int 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:
1545                 return !filter_type->filter->boolean.value;
1546
1547         case FILTER_TRIVIAL_TRUE:
1548                 return filter_type->filter->boolean.value;
1549         default:
1550                 return 1;
1551         }
1552 }
1553
1554 static int test_filter(struct event_format *event,
1555                        struct filter_arg *arg, struct pevent_record *record);
1556
1557 static const char *
1558 get_comm(struct event_format *event, struct pevent_record *record)
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
1568 static unsigned long long
1569 get_value(struct event_format *event,
1570           struct format_field *field, struct pevent_record *record)
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);
1579                 return (unsigned long)name;
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
1600 static unsigned long long
1601 get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record);
1602
1603 static unsigned long long
1604 get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
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
1649 static unsigned long long
1650 get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
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
1670 static int test_num(struct event_format *event,
1671                     struct filter_arg *arg, struct pevent_record *record)
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
1703 static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
1704 {
1705         struct event_format *event;
1706         struct pevent *pevent;
1707         unsigned long long addr;
1708         const char *val = NULL;
1709         char hex[64];
1710
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                 }
1740         }
1741
1742         return val;
1743 }
1744
1745 static int test_str(struct event_format *event,
1746                     struct filter_arg *arg, struct pevent_record *record)
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
1775 static int test_op(struct event_format *event,
1776                    struct filter_arg *arg, struct pevent_record *record)
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
1796 static int test_filter(struct event_format *event,
1797                        struct filter_arg *arg, struct pevent_record *record)
1798 {
1799         switch (arg->type) {
1800         case FILTER_ARG_BOOLEAN:
1801                 /* easy case */
1802                 return arg->boolean.value;
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  */
1837 int 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  */
1861 int pevent_filter_match(struct event_filter *filter,
1862                         struct pevent_record *record)
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
1882 static 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
2000 static 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
2011 static char *field_to_str(struct event_filter *filter, struct filter_arg *arg)
2012 {
2013         return strdup(arg->field.field->name);
2014 }
2015
2016 static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2017 {
2018         char *lstr;
2019         char *rstr;
2020         char *op;
2021         char *str = NULL;
2022         int len;
2023
2024         lstr = arg_to_str(filter, arg->exp.left);
2025         rstr = arg_to_str(filter, arg->exp.right);
2026         if (!lstr || !rstr)
2027                 goto out;
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);
2067 out:
2068         free(lstr);
2069         free(rstr);
2070
2071         return str;
2072 }
2073
2074 static 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);
2084         if (!lstr || !rstr)
2085                 goto out;
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
2122 out:
2123         free(lstr);
2124         free(rstr);
2125         return str;
2126 }
2127
2128 static 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
2165 static 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);
2172                 if (arg->boolean.value)
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  */
2212 char *
2213 pevent_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  */
2237 int 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);
2273                 if (str1 && str2)
2274                         result = strcmp(str1, str2) != 0;
2275                 else
2276                         /* bail out if allocation fails */
2277                         result = 1;
2278
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