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