tools lib traceevent: Get rid of die() in reparent_op_arg()
[firefly-linux-kernel-4.4.55.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 enum pevent_errno 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 PEVENT_ERRNO__INVALID_ARG_TYPE;
671                 op->num.left = arg;
672                 break;
673         default:
674                 return PEVENT_ERRNO__INVALID_ARG_TYPE;
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 static enum pevent_errno
788 reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
789                 struct filter_arg *arg, char **error_str)
790 {
791         struct filter_arg *other_child;
792         struct filter_arg **ptr;
793
794         if (parent->type != FILTER_ARG_OP &&
795             arg->type != FILTER_ARG_OP) {
796                 show_error(error_str, "can not reparent other than OP");
797                 return PEVENT_ERRNO__REPARENT_NOT_OP;
798         }
799
800         /* Get the sibling */
801         if (old_child->op.right == arg) {
802                 ptr = &old_child->op.right;
803                 other_child = old_child->op.left;
804         } else if (old_child->op.left == arg) {
805                 ptr = &old_child->op.left;
806                 other_child = old_child->op.right;
807         } else {
808                 show_error(error_str, "Error in reparent op, find other child");
809                 return PEVENT_ERRNO__REPARENT_FAILED;
810         }
811
812         /* Detach arg from old_child */
813         *ptr = NULL;
814
815         /* Check for root */
816         if (parent == old_child) {
817                 free_arg(other_child);
818                 *parent = *arg;
819                 /* Free arg without recussion */
820                 free(arg);
821                 return 0;
822         }
823
824         if (parent->op.right == old_child)
825                 ptr = &parent->op.right;
826         else if (parent->op.left == old_child)
827                 ptr = &parent->op.left;
828         else {
829                 show_error(error_str, "Error in reparent op");
830                 return PEVENT_ERRNO__REPARENT_FAILED;
831         }
832
833         *ptr = arg;
834
835         free_arg(old_child);
836         return 0;
837 }
838
839 /* Returns either filter_vals (success) or pevent_errno (failfure) */
840 static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
841                     char **error_str)
842 {
843         int lval, rval;
844
845         switch (arg->type) {
846
847                 /* bad case */
848         case FILTER_ARG_BOOLEAN:
849                 return FILTER_VAL_FALSE + arg->boolean.value;
850
851                 /* good cases: */
852         case FILTER_ARG_STR:
853         case FILTER_ARG_VALUE:
854         case FILTER_ARG_FIELD:
855                 return FILTER_VAL_NORM;
856
857         case FILTER_ARG_EXP:
858                 lval = test_arg(arg, arg->exp.left, error_str);
859                 if (lval != FILTER_VAL_NORM)
860                         return lval;
861                 rval = test_arg(arg, arg->exp.right, error_str);
862                 if (rval != FILTER_VAL_NORM)
863                         return rval;
864                 return FILTER_VAL_NORM;
865
866         case FILTER_ARG_NUM:
867                 lval = test_arg(arg, arg->num.left, error_str);
868                 if (lval != FILTER_VAL_NORM)
869                         return lval;
870                 rval = test_arg(arg, arg->num.right, error_str);
871                 if (rval != FILTER_VAL_NORM)
872                         return rval;
873                 return FILTER_VAL_NORM;
874
875         case FILTER_ARG_OP:
876                 if (arg->op.type != FILTER_OP_NOT) {
877                         lval = test_arg(arg, arg->op.left, error_str);
878                         switch (lval) {
879                         case FILTER_VAL_NORM:
880                                 break;
881                         case FILTER_VAL_TRUE:
882                                 if (arg->op.type == FILTER_OP_OR)
883                                         return FILTER_VAL_TRUE;
884                                 rval = test_arg(arg, arg->op.right, error_str);
885                                 if (rval != FILTER_VAL_NORM)
886                                         return rval;
887
888                                 return reparent_op_arg(parent, arg, arg->op.right,
889                                                        error_str);
890
891                         case FILTER_VAL_FALSE:
892                                 if (arg->op.type == FILTER_OP_AND)
893                                         return FILTER_VAL_FALSE;
894                                 rval = test_arg(arg, arg->op.right, error_str);
895                                 if (rval != FILTER_VAL_NORM)
896                                         return rval;
897
898                                 return reparent_op_arg(parent, arg, arg->op.right,
899                                                        error_str);
900
901                         default:
902                                 return lval;
903                         }
904                 }
905
906                 rval = test_arg(arg, arg->op.right, error_str);
907                 switch (rval) {
908                 case FILTER_VAL_NORM:
909                 default:
910                         break;
911
912                 case FILTER_VAL_TRUE:
913                         if (arg->op.type == FILTER_OP_OR)
914                                 return FILTER_VAL_TRUE;
915                         if (arg->op.type == FILTER_OP_NOT)
916                                 return FILTER_VAL_FALSE;
917
918                         return reparent_op_arg(parent, arg, arg->op.left,
919                                                error_str);
920
921                 case FILTER_VAL_FALSE:
922                         if (arg->op.type == FILTER_OP_AND)
923                                 return FILTER_VAL_FALSE;
924                         if (arg->op.type == FILTER_OP_NOT)
925                                 return FILTER_VAL_TRUE;
926
927                         return reparent_op_arg(parent, arg, arg->op.left,
928                                                error_str);
929                 }
930
931                 return rval;
932         default:
933                 show_error(error_str, "bad arg in filter tree");
934                 return PEVENT_ERRNO__BAD_FILTER_ARG;
935         }
936         return FILTER_VAL_NORM;
937 }
938
939 /* Remove any unknown event fields */
940 static struct filter_arg *collapse_tree(struct filter_arg *arg, char **error_str)
941 {
942         enum filter_vals ret;
943
944         ret = test_arg(arg, arg, error_str);
945         switch (ret) {
946         case FILTER_VAL_NORM:
947                 break;
948
949         case FILTER_VAL_TRUE:
950         case FILTER_VAL_FALSE:
951                 free_arg(arg);
952                 arg = allocate_arg();
953                 if (arg) {
954                         arg->type = FILTER_ARG_BOOLEAN;
955                         arg->boolean.value = ret == FILTER_VAL_TRUE;
956                 } else {
957                         show_error(error_str, "Failed to allocate filter arg");
958                 }
959                 break;
960
961         default:
962                 /* test_arg() already set the error_str */
963                 free_arg(arg);
964                 arg = NULL;
965                 break;
966         }
967
968         return arg;
969 }
970
971 static int
972 process_filter(struct event_format *event, struct filter_arg **parg,
973                char **error_str, int not)
974 {
975         enum event_type type;
976         char *token = NULL;
977         struct filter_arg *current_op = NULL;
978         struct filter_arg *current_exp = NULL;
979         struct filter_arg *left_item = NULL;
980         struct filter_arg *arg = NULL;
981         enum op_type op_type;
982         enum filter_op_type btype;
983         enum filter_exp_type etype;
984         enum filter_cmp_type ctype;
985         int ret;
986
987         *parg = NULL;
988
989         do {
990                 free(token);
991                 type = read_token(&token);
992                 switch (type) {
993                 case EVENT_SQUOTE:
994                 case EVENT_DQUOTE:
995                 case EVENT_ITEM:
996                         arg = create_arg_item(event, token, type, error_str);
997                         if (!arg)
998                                 goto fail;
999                         if (!left_item)
1000                                 left_item = arg;
1001                         else if (current_exp) {
1002                                 ret = add_right(current_exp, arg, error_str);
1003                                 if (ret < 0)
1004                                         goto fail;
1005                                 left_item = NULL;
1006                                 /* Not's only one one expression */
1007                                 if (not) {
1008                                         arg = NULL;
1009                                         if (current_op)
1010                                                 goto fail_print;
1011                                         free(token);
1012                                         *parg = current_exp;
1013                                         return 0;
1014                                 }
1015                         } else
1016                                 goto fail_print;
1017                         arg = NULL;
1018                         break;
1019
1020                 case EVENT_DELIM:
1021                         if (*token == ',') {
1022                                 show_error(error_str,
1023                                            "Illegal token ','");
1024                                 goto fail;
1025                         }
1026
1027                         if (*token == '(') {
1028                                 if (left_item) {
1029                                         show_error(error_str,
1030                                                    "Open paren can not come after item");
1031                                         goto fail;
1032                                 }
1033                                 if (current_exp) {
1034                                         show_error(error_str,
1035                                                    "Open paren can not come after expression");
1036                                         goto fail;
1037                                 }
1038
1039                                 ret = process_filter(event, &arg, error_str, 0);
1040                                 if (ret != 1) {
1041                                         if (ret == 0)
1042                                                 show_error(error_str,
1043                                                            "Unbalanced number of '('");
1044                                         goto fail;
1045                                 }
1046                                 ret = 0;
1047
1048                                 /* A not wants just one expression */
1049                                 if (not) {
1050                                         if (current_op)
1051                                                 goto fail_print;
1052                                         *parg = arg;
1053                                         return 0;
1054                                 }
1055
1056                                 if (current_op)
1057                                         ret = add_right(current_op, arg, error_str);
1058                                 else
1059                                         current_exp = arg;
1060
1061                                 if (ret < 0)
1062                                         goto fail;
1063
1064                         } else { /* ')' */
1065                                 if (!current_op && !current_exp)
1066                                         goto fail_print;
1067
1068                                 /* Make sure everything is finished at this level */
1069                                 if (current_exp && !check_op_done(current_exp))
1070                                         goto fail_print;
1071                                 if (current_op && !check_op_done(current_op))
1072                                         goto fail_print;
1073
1074                                 if (current_op)
1075                                         *parg = current_op;
1076                                 else
1077                                         *parg = current_exp;
1078                                 return 1;
1079                         }
1080                         break;
1081
1082                 case EVENT_OP:
1083                         op_type = process_op(token, &btype, &ctype, &etype);
1084
1085                         /* All expect a left arg except for NOT */
1086                         switch (op_type) {
1087                         case OP_BOOL:
1088                                 /* Logic ops need a left expression */
1089                                 if (!current_exp && !current_op)
1090                                         goto fail_print;
1091                                 /* fall through */
1092                         case OP_NOT:
1093                                 /* logic only processes ops and exp */
1094                                 if (left_item)
1095                                         goto fail_print;
1096                                 break;
1097                         case OP_EXP:
1098                         case OP_CMP:
1099                                 if (!left_item)
1100                                         goto fail_print;
1101                                 break;
1102                         case OP_NONE:
1103                                 show_error(error_str,
1104                                            "Unknown op token %s", token);
1105                                 goto fail;
1106                         }
1107
1108                         ret = 0;
1109                         switch (op_type) {
1110                         case OP_BOOL:
1111                                 arg = create_arg_op(btype);
1112                                 if (arg == NULL)
1113                                         goto fail_alloc;
1114                                 if (current_op)
1115                                         ret = add_left(arg, current_op);
1116                                 else
1117                                         ret = add_left(arg, current_exp);
1118                                 current_op = arg;
1119                                 current_exp = NULL;
1120                                 break;
1121
1122                         case OP_NOT:
1123                                 arg = create_arg_op(btype);
1124                                 if (arg == NULL)
1125                                         goto fail_alloc;
1126                                 if (current_op)
1127                                         ret = add_right(current_op, arg, error_str);
1128                                 if (ret < 0)
1129                                         goto fail;
1130                                 current_exp = arg;
1131                                 ret = process_filter(event, &arg, error_str, 1);
1132                                 if (ret < 0)
1133                                         goto fail;
1134                                 ret = add_right(current_exp, arg, error_str);
1135                                 if (ret < 0)
1136                                         goto fail;
1137                                 break;
1138
1139                         case OP_EXP:
1140                         case OP_CMP:
1141                                 if (op_type == OP_EXP)
1142                                         arg = create_arg_exp(etype);
1143                                 else
1144                                         arg = create_arg_cmp(ctype);
1145                                 if (arg == NULL)
1146                                         goto fail_alloc;
1147
1148                                 if (current_op)
1149                                         ret = add_right(current_op, arg, error_str);
1150                                 if (ret < 0)
1151                                         goto fail;
1152                                 ret = add_left(arg, left_item);
1153                                 if (ret < 0) {
1154                                         arg = NULL;
1155                                         goto fail_print;
1156                                 }
1157                                 current_exp = arg;
1158                                 break;
1159                         default:
1160                                 break;
1161                         }
1162                         arg = NULL;
1163                         if (ret < 0)
1164                                 goto fail_print;
1165                         break;
1166                 case EVENT_NONE:
1167                         break;
1168                 case EVENT_ERROR:
1169                         goto fail_alloc;
1170                 default:
1171                         goto fail_print;
1172                 }
1173         } while (type != EVENT_NONE);
1174
1175         if (!current_op && !current_exp)
1176                 goto fail_print;
1177
1178         if (!current_op)
1179                 current_op = current_exp;
1180
1181         current_op = collapse_tree(current_op, error_str);
1182         if (current_op == NULL)
1183                 goto fail;
1184
1185         *parg = current_op;
1186
1187         return 0;
1188
1189  fail_alloc:
1190         show_error(error_str, "failed to allocate filter arg");
1191         goto fail;
1192  fail_print:
1193         show_error(error_str, "Syntax error");
1194  fail:
1195         free_arg(current_op);
1196         free_arg(current_exp);
1197         free_arg(arg);
1198         free(token);
1199         return -1;
1200 }
1201
1202 static int
1203 process_event(struct event_format *event, const char *filter_str,
1204               struct filter_arg **parg, char **error_str)
1205 {
1206         int ret;
1207
1208         pevent_buffer_init(filter_str, strlen(filter_str));
1209
1210         ret = process_filter(event, parg, error_str, 0);
1211         if (ret == 1) {
1212                 show_error(error_str,
1213                            "Unbalanced number of ')'");
1214                 return -1;
1215         }
1216         if (ret < 0)
1217                 return ret;
1218
1219         /* If parg is NULL, then make it into FALSE */
1220         if (!*parg) {
1221                 *parg = allocate_arg();
1222                 if (*parg == NULL) {
1223                         show_error(error_str, "failed to allocate filter arg");
1224                         return -1;
1225                 }
1226                 (*parg)->type = FILTER_ARG_BOOLEAN;
1227                 (*parg)->boolean.value = FILTER_FALSE;
1228         }
1229
1230         return 0;
1231 }
1232
1233 static int filter_event(struct event_filter *filter,
1234                         struct event_format *event,
1235                         const char *filter_str, char **error_str)
1236 {
1237         struct filter_type *filter_type;
1238         struct filter_arg *arg;
1239         int ret;
1240
1241         if (filter_str) {
1242                 ret = process_event(event, filter_str, &arg, error_str);
1243                 if (ret < 0)
1244                         return ret;
1245
1246         } else {
1247                 /* just add a TRUE arg */
1248                 arg = allocate_arg();
1249                 if (arg == NULL) {
1250                         show_error(error_str, "failed to allocate filter arg");
1251                         return -1;
1252                 }
1253                 arg->type = FILTER_ARG_BOOLEAN;
1254                 arg->boolean.value = FILTER_TRUE;
1255         }
1256
1257         filter_type = add_filter_type(filter, event->id);
1258         if (filter_type == NULL) {
1259                 show_error(error_str, "failed to add a new filter: %s",
1260                            filter_str ? filter_str : "true");
1261                 return -1;
1262         }
1263
1264         if (filter_type->filter)
1265                 free_arg(filter_type->filter);
1266         filter_type->filter = arg;
1267
1268         return 0;
1269 }
1270
1271 /**
1272  * pevent_filter_add_filter_str - add a new filter
1273  * @filter: the event filter to add to
1274  * @filter_str: the filter string that contains the filter
1275  * @error_str: string containing reason for failed filter
1276  *
1277  * Returns 0 if the filter was successfully added
1278  *   -1 if there was an error.
1279  *
1280  * On error, if @error_str points to a string pointer,
1281  * it is set to the reason that the filter failed.
1282  * This string must be freed with "free".
1283  */
1284 int pevent_filter_add_filter_str(struct event_filter *filter,
1285                                  const char *filter_str,
1286                                  char **error_str)
1287 {
1288         struct pevent *pevent = filter->pevent;
1289         struct event_list *event;
1290         struct event_list *events = NULL;
1291         const char *filter_start;
1292         const char *next_event;
1293         char *this_event;
1294         char *event_name = NULL;
1295         char *sys_name = NULL;
1296         char *sp;
1297         int rtn = 0;
1298         int len;
1299         int ret;
1300
1301         /* clear buffer to reset show error */
1302         pevent_buffer_init("", 0);
1303
1304         if (error_str)
1305                 *error_str = NULL;
1306
1307         filter_start = strchr(filter_str, ':');
1308         if (filter_start)
1309                 len = filter_start - filter_str;
1310         else
1311                 len = strlen(filter_str);
1312
1313
1314         do {
1315                 next_event = strchr(filter_str, ',');
1316                 if (next_event &&
1317                     (!filter_start || next_event < filter_start))
1318                         len = next_event - filter_str;
1319                 else if (filter_start)
1320                         len = filter_start - filter_str;
1321                 else
1322                         len = strlen(filter_str);
1323
1324                 this_event = malloc(len + 1);
1325                 if (this_event == NULL) {
1326                         show_error(error_str, "Memory allocation failure");
1327                         /* This can only happen when events is NULL, but still */
1328                         free_events(events);
1329                         return -1;
1330                 }
1331                 memcpy(this_event, filter_str, len);
1332                 this_event[len] = 0;
1333
1334                 if (next_event)
1335                         next_event++;
1336
1337                 filter_str = next_event;
1338
1339                 sys_name = strtok_r(this_event, "/", &sp);
1340                 event_name = strtok_r(NULL, "/", &sp);
1341
1342                 if (!sys_name) {
1343                         show_error(error_str, "No filter found");
1344                         /* This can only happen when events is NULL, but still */
1345                         free_events(events);
1346                         free(this_event);
1347                         return -1;
1348                 }
1349
1350                 /* Find this event */
1351                 ret = find_event(pevent, &events, strim(sys_name), strim(event_name));
1352                 if (ret < 0) {
1353                         if (ret == PEVENT_ERRNO__MEM_ALLOC_FAILED)
1354                                 show_error(error_str,
1355                                            "Memory allocation failure");
1356                         else if (event_name)
1357                                 show_error(error_str,
1358                                            "No event found under '%s.%s'",
1359                                            sys_name, event_name);
1360                         else
1361                                 show_error(error_str,
1362                                            "No event found under '%s'",
1363                                            sys_name);
1364                         free_events(events);
1365                         free(this_event);
1366                         return -1;
1367                 }
1368                 free(this_event);
1369         } while (filter_str);
1370
1371         /* Skip the ':' */
1372         if (filter_start)
1373                 filter_start++;
1374
1375         /* filter starts here */
1376         for (event = events; event; event = event->next) {
1377                 ret = filter_event(filter, event->event, filter_start,
1378                                    error_str);
1379                 /* Failures are returned if a parse error happened */
1380                 if (ret < 0)
1381                         rtn = ret;
1382
1383                 if (ret >= 0 && pevent->test_filters) {
1384                         char *test;
1385                         test = pevent_filter_make_string(filter, event->event->id);
1386                         printf(" '%s: %s'\n", event->event->name, test);
1387                         free(test);
1388                 }
1389         }
1390
1391         free_events(events);
1392
1393         if (rtn >= 0 && pevent->test_filters)
1394                 exit(0);
1395
1396         return rtn;
1397 }
1398
1399 static void free_filter_type(struct filter_type *filter_type)
1400 {
1401         free_arg(filter_type->filter);
1402 }
1403
1404 /**
1405  * pevent_filter_remove_event - remove a filter for an event
1406  * @filter: the event filter to remove from
1407  * @event_id: the event to remove a filter for
1408  *
1409  * Removes the filter saved for an event defined by @event_id
1410  * from the @filter.
1411  *
1412  * Returns 1: if an event was removed
1413  *   0: if the event was not found
1414  */
1415 int pevent_filter_remove_event(struct event_filter *filter,
1416                                int event_id)
1417 {
1418         struct filter_type *filter_type;
1419         unsigned long len;
1420
1421         if (!filter->filters)
1422                 return 0;
1423
1424         filter_type = find_filter_type(filter, event_id);
1425
1426         if (!filter_type)
1427                 return 0;
1428
1429         free_filter_type(filter_type);
1430
1431         /* The filter_type points into the event_filters array */
1432         len = (unsigned long)(filter->event_filters + filter->filters) -
1433                 (unsigned long)(filter_type + 1);
1434
1435         memmove(filter_type, filter_type + 1, len);
1436         filter->filters--;
1437
1438         memset(&filter->event_filters[filter->filters], 0,
1439                sizeof(*filter_type));
1440
1441         return 1;
1442 }
1443
1444 /**
1445  * pevent_filter_reset - clear all filters in a filter
1446  * @filter: the event filter to reset
1447  *
1448  * Removes all filters from a filter and resets it.
1449  */
1450 void pevent_filter_reset(struct event_filter *filter)
1451 {
1452         int i;
1453
1454         for (i = 0; i < filter->filters; i++)
1455                 free_filter_type(&filter->event_filters[i]);
1456
1457         free(filter->event_filters);
1458         filter->filters = 0;
1459         filter->event_filters = NULL;
1460 }
1461
1462 void pevent_filter_free(struct event_filter *filter)
1463 {
1464         pevent_unref(filter->pevent);
1465
1466         pevent_filter_reset(filter);
1467
1468         free(filter);
1469 }
1470
1471 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg);
1472
1473 static int copy_filter_type(struct event_filter *filter,
1474                              struct event_filter *source,
1475                              struct filter_type *filter_type)
1476 {
1477         struct filter_arg *arg;
1478         struct event_format *event;
1479         const char *sys;
1480         const char *name;
1481         char *str;
1482
1483         /* Can't assume that the pevent's are the same */
1484         sys = filter_type->event->system;
1485         name = filter_type->event->name;
1486         event = pevent_find_event_by_name(filter->pevent, sys, name);
1487         if (!event)
1488                 return -1;
1489
1490         str = arg_to_str(source, filter_type->filter);
1491         if (!str)
1492                 return -1;
1493
1494         if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
1495                 /* Add trivial event */
1496                 arg = allocate_arg();
1497                 if (arg == NULL)
1498                         return -1;
1499
1500                 arg->type = FILTER_ARG_BOOLEAN;
1501                 if (strcmp(str, "TRUE") == 0)
1502                         arg->boolean.value = 1;
1503                 else
1504                         arg->boolean.value = 0;
1505
1506                 filter_type = add_filter_type(filter, event->id);
1507                 if (filter_type == NULL)
1508                         return -1;
1509
1510                 filter_type->filter = arg;
1511
1512                 free(str);
1513                 return 0;
1514         }
1515
1516         filter_event(filter, event, str, NULL);
1517         free(str);
1518
1519         return 0;
1520 }
1521
1522 /**
1523  * pevent_filter_copy - copy a filter using another filter
1524  * @dest - the filter to copy to
1525  * @source - the filter to copy from
1526  *
1527  * Returns 0 on success and -1 if not all filters were copied
1528  */
1529 int pevent_filter_copy(struct event_filter *dest, struct event_filter *source)
1530 {
1531         int ret = 0;
1532         int i;
1533
1534         pevent_filter_reset(dest);
1535
1536         for (i = 0; i < source->filters; i++) {
1537                 if (copy_filter_type(dest, source, &source->event_filters[i]))
1538                         ret = -1;
1539         }
1540         return ret;
1541 }
1542
1543
1544 /**
1545  * pevent_update_trivial - update the trivial filters with the given filter
1546  * @dest - the filter to update
1547  * @source - the filter as the source of the update
1548  * @type - the type of trivial filter to update.
1549  *
1550  * Scan dest for trivial events matching @type to replace with the source.
1551  *
1552  * Returns 0 on success and -1 if there was a problem updating, but
1553  *   events may have still been updated on error.
1554  */
1555 int pevent_update_trivial(struct event_filter *dest, struct event_filter *source,
1556                           enum filter_trivial_type type)
1557 {
1558         struct pevent *src_pevent;
1559         struct pevent *dest_pevent;
1560         struct event_format *event;
1561         struct filter_type *filter_type;
1562         struct filter_arg *arg;
1563         char *str;
1564         int i;
1565
1566         src_pevent = source->pevent;
1567         dest_pevent = dest->pevent;
1568
1569         /* Do nothing if either of the filters has nothing to filter */
1570         if (!dest->filters || !source->filters)
1571                 return 0;
1572
1573         for (i = 0; i < dest->filters; i++) {
1574                 filter_type = &dest->event_filters[i];
1575                 arg = filter_type->filter;
1576                 if (arg->type != FILTER_ARG_BOOLEAN)
1577                         continue;
1578                 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) ||
1579                     (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE))
1580                         continue;
1581
1582                 event = filter_type->event;
1583
1584                 if (src_pevent != dest_pevent) {
1585                         /* do a look up */
1586                         event = pevent_find_event_by_name(src_pevent,
1587                                                           event->system,
1588                                                           event->name);
1589                         if (!event)
1590                                 return -1;
1591                 }
1592
1593                 str = pevent_filter_make_string(source, event->id);
1594                 if (!str)
1595                         continue;
1596
1597                 /* Don't bother if the filter is trivial too */
1598                 if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0)
1599                         filter_event(dest, event, str, NULL);
1600                 free(str);
1601         }
1602         return 0;
1603 }
1604
1605 /**
1606  * pevent_filter_clear_trivial - clear TRUE and FALSE filters
1607  * @filter: the filter to remove trivial filters from
1608  * @type: remove only true, false, or both
1609  *
1610  * Removes filters that only contain a TRUE or FALES boolean arg.
1611  *
1612  * Returns 0 on success and -1 if there was a problem.
1613  */
1614 int pevent_filter_clear_trivial(struct event_filter *filter,
1615                                  enum filter_trivial_type type)
1616 {
1617         struct filter_type *filter_type;
1618         int count = 0;
1619         int *ids = NULL;
1620         int i;
1621
1622         if (!filter->filters)
1623                 return 0;
1624
1625         /*
1626          * Two steps, first get all ids with trivial filters.
1627          *  then remove those ids.
1628          */
1629         for (i = 0; i < filter->filters; i++) {
1630                 int *new_ids;
1631
1632                 filter_type = &filter->event_filters[i];
1633                 if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1634                         continue;
1635                 switch (type) {
1636                 case FILTER_TRIVIAL_FALSE:
1637                         if (filter_type->filter->boolean.value)
1638                                 continue;
1639                 case FILTER_TRIVIAL_TRUE:
1640                         if (!filter_type->filter->boolean.value)
1641                                 continue;
1642                 default:
1643                         break;
1644                 }
1645
1646                 new_ids = realloc(ids, sizeof(*ids) * (count + 1));
1647                 if (!new_ids) {
1648                         free(ids);
1649                         return -1;
1650                 }
1651
1652                 ids = new_ids;
1653                 ids[count++] = filter_type->event_id;
1654         }
1655
1656         if (!count)
1657                 return 0;
1658
1659         for (i = 0; i < count; i++)
1660                 pevent_filter_remove_event(filter, ids[i]);
1661
1662         free(ids);
1663         return 0;
1664 }
1665
1666 /**
1667  * pevent_filter_event_has_trivial - return true event contains trivial filter
1668  * @filter: the filter with the information
1669  * @event_id: the id of the event to test
1670  * @type: trivial type to test for (TRUE, FALSE, EITHER)
1671  *
1672  * Returns 1 if the event contains a matching trivial type
1673  *  otherwise 0.
1674  */
1675 int pevent_filter_event_has_trivial(struct event_filter *filter,
1676                                     int event_id,
1677                                     enum filter_trivial_type type)
1678 {
1679         struct filter_type *filter_type;
1680
1681         if (!filter->filters)
1682                 return 0;
1683
1684         filter_type = find_filter_type(filter, event_id);
1685
1686         if (!filter_type)
1687                 return 0;
1688
1689         if (filter_type->filter->type != FILTER_ARG_BOOLEAN)
1690                 return 0;
1691
1692         switch (type) {
1693         case FILTER_TRIVIAL_FALSE:
1694                 return !filter_type->filter->boolean.value;
1695
1696         case FILTER_TRIVIAL_TRUE:
1697                 return filter_type->filter->boolean.value;
1698         default:
1699                 return 1;
1700         }
1701 }
1702
1703 static int test_filter(struct event_format *event,
1704                        struct filter_arg *arg, struct pevent_record *record);
1705
1706 static const char *
1707 get_comm(struct event_format *event, struct pevent_record *record)
1708 {
1709         const char *comm;
1710         int pid;
1711
1712         pid = pevent_data_pid(event->pevent, record);
1713         comm = pevent_data_comm_from_pid(event->pevent, pid);
1714         return comm;
1715 }
1716
1717 static unsigned long long
1718 get_value(struct event_format *event,
1719           struct format_field *field, struct pevent_record *record)
1720 {
1721         unsigned long long val;
1722
1723         /* Handle our dummy "comm" field */
1724         if (field == &comm) {
1725                 const char *name;
1726
1727                 name = get_comm(event, record);
1728                 return (unsigned long)name;
1729         }
1730
1731         pevent_read_number_field(field, record->data, &val);
1732
1733         if (!(field->flags & FIELD_IS_SIGNED))
1734                 return val;
1735
1736         switch (field->size) {
1737         case 1:
1738                 return (char)val;
1739         case 2:
1740                 return (short)val;
1741         case 4:
1742                 return (int)val;
1743         case 8:
1744                 return (long long)val;
1745         }
1746         return val;
1747 }
1748
1749 static unsigned long long
1750 get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record);
1751
1752 static unsigned long long
1753 get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
1754 {
1755         unsigned long long lval, rval;
1756
1757         lval = get_arg_value(event, arg->exp.left, record);
1758         rval = get_arg_value(event, arg->exp.right, record);
1759
1760         switch (arg->exp.type) {
1761         case FILTER_EXP_ADD:
1762                 return lval + rval;
1763
1764         case FILTER_EXP_SUB:
1765                 return lval - rval;
1766
1767         case FILTER_EXP_MUL:
1768                 return lval * rval;
1769
1770         case FILTER_EXP_DIV:
1771                 return lval / rval;
1772
1773         case FILTER_EXP_MOD:
1774                 return lval % rval;
1775
1776         case FILTER_EXP_RSHIFT:
1777                 return lval >> rval;
1778
1779         case FILTER_EXP_LSHIFT:
1780                 return lval << rval;
1781
1782         case FILTER_EXP_AND:
1783                 return lval & rval;
1784
1785         case FILTER_EXP_OR:
1786                 return lval | rval;
1787
1788         case FILTER_EXP_XOR:
1789                 return lval ^ rval;
1790
1791         case FILTER_EXP_NOT:
1792         default:
1793                 die("error in exp");
1794         }
1795         return 0;
1796 }
1797
1798 static unsigned long long
1799 get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record)
1800 {
1801         switch (arg->type) {
1802         case FILTER_ARG_FIELD:
1803                 return get_value(event, arg->field.field, record);
1804
1805         case FILTER_ARG_VALUE:
1806                 if (arg->value.type != FILTER_NUMBER)
1807                         die("must have number field!");
1808                 return arg->value.val;
1809
1810         case FILTER_ARG_EXP:
1811                 return get_exp_value(event, arg, record);
1812
1813         default:
1814                 die("oops in filter");
1815         }
1816         return 0;
1817 }
1818
1819 static int test_num(struct event_format *event,
1820                     struct filter_arg *arg, struct pevent_record *record)
1821 {
1822         unsigned long long lval, rval;
1823
1824         lval = get_arg_value(event, arg->num.left, record);
1825         rval = get_arg_value(event, arg->num.right, record);
1826
1827         switch (arg->num.type) {
1828         case FILTER_CMP_EQ:
1829                 return lval == rval;
1830
1831         case FILTER_CMP_NE:
1832                 return lval != rval;
1833
1834         case FILTER_CMP_GT:
1835                 return lval > rval;
1836
1837         case FILTER_CMP_LT:
1838                 return lval < rval;
1839
1840         case FILTER_CMP_GE:
1841                 return lval >= rval;
1842
1843         case FILTER_CMP_LE:
1844                 return lval <= rval;
1845
1846         default:
1847                 /* ?? */
1848                 return 0;
1849         }
1850 }
1851
1852 static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
1853 {
1854         struct event_format *event;
1855         struct pevent *pevent;
1856         unsigned long long addr;
1857         const char *val = NULL;
1858         char hex[64];
1859
1860         /* If the field is not a string convert it */
1861         if (arg->str.field->flags & FIELD_IS_STRING) {
1862                 val = record->data + arg->str.field->offset;
1863
1864                 /*
1865                  * We need to copy the data since we can't be sure the field
1866                  * is null terminated.
1867                  */
1868                 if (*(val + arg->str.field->size - 1)) {
1869                         /* copy it */
1870                         memcpy(arg->str.buffer, val, arg->str.field->size);
1871                         /* the buffer is already NULL terminated */
1872                         val = arg->str.buffer;
1873                 }
1874
1875         } else {
1876                 event = arg->str.field->event;
1877                 pevent = event->pevent;
1878                 addr = get_value(event, arg->str.field, record);
1879
1880                 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
1881                         /* convert to a kernel symbol */
1882                         val = pevent_find_function(pevent, addr);
1883
1884                 if (val == NULL) {
1885                         /* just use the hex of the string name */
1886                         snprintf(hex, 64, "0x%llx", addr);
1887                         val = hex;
1888                 }
1889         }
1890
1891         return val;
1892 }
1893
1894 static int test_str(struct event_format *event,
1895                     struct filter_arg *arg, struct pevent_record *record)
1896 {
1897         const char *val;
1898
1899         if (arg->str.field == &comm)
1900                 val = get_comm(event, record);
1901         else
1902                 val = get_field_str(arg, record);
1903
1904         switch (arg->str.type) {
1905         case FILTER_CMP_MATCH:
1906                 return strcmp(val, arg->str.val) == 0;
1907
1908         case FILTER_CMP_NOT_MATCH:
1909                 return strcmp(val, arg->str.val) != 0;
1910
1911         case FILTER_CMP_REGEX:
1912                 /* Returns zero on match */
1913                 return !regexec(&arg->str.reg, val, 0, NULL, 0);
1914
1915         case FILTER_CMP_NOT_REGEX:
1916                 return regexec(&arg->str.reg, val, 0, NULL, 0);
1917
1918         default:
1919                 /* ?? */
1920                 return 0;
1921         }
1922 }
1923
1924 static int test_op(struct event_format *event,
1925                    struct filter_arg *arg, struct pevent_record *record)
1926 {
1927         switch (arg->op.type) {
1928         case FILTER_OP_AND:
1929                 return test_filter(event, arg->op.left, record) &&
1930                         test_filter(event, arg->op.right, record);
1931
1932         case FILTER_OP_OR:
1933                 return test_filter(event, arg->op.left, record) ||
1934                         test_filter(event, arg->op.right, record);
1935
1936         case FILTER_OP_NOT:
1937                 return !test_filter(event, arg->op.right, record);
1938
1939         default:
1940                 /* ?? */
1941                 return 0;
1942         }
1943 }
1944
1945 static int test_filter(struct event_format *event,
1946                        struct filter_arg *arg, struct pevent_record *record)
1947 {
1948         switch (arg->type) {
1949         case FILTER_ARG_BOOLEAN:
1950                 /* easy case */
1951                 return arg->boolean.value;
1952
1953         case FILTER_ARG_OP:
1954                 return test_op(event, arg, record);
1955
1956         case FILTER_ARG_NUM:
1957                 return test_num(event, arg, record);
1958
1959         case FILTER_ARG_STR:
1960                 return test_str(event, arg, record);
1961
1962         case FILTER_ARG_EXP:
1963         case FILTER_ARG_VALUE:
1964         case FILTER_ARG_FIELD:
1965                 /*
1966                  * Expressions, fields and values evaluate
1967                  * to true if they return non zero
1968                  */
1969                 return !!get_arg_value(event, arg, record);
1970
1971         default:
1972                 die("oops!");
1973                 /* ?? */
1974                 return 0;
1975         }
1976 }
1977
1978 /**
1979  * pevent_event_filtered - return true if event has filter
1980  * @filter: filter struct with filter information
1981  * @event_id: event id to test if filter exists
1982  *
1983  * Returns 1 if filter found for @event_id
1984  *   otherwise 0;
1985  */
1986 int pevent_event_filtered(struct event_filter *filter,
1987                           int event_id)
1988 {
1989         struct filter_type *filter_type;
1990
1991         if (!filter->filters)
1992                 return 0;
1993
1994         filter_type = find_filter_type(filter, event_id);
1995
1996         return filter_type ? 1 : 0;
1997 }
1998
1999 /**
2000  * pevent_filter_match - test if a record matches a filter
2001  * @filter: filter struct with filter information
2002  * @record: the record to test against the filter
2003  *
2004  * Returns:
2005  *  1 - filter found for event and @record matches
2006  *  0 - filter found for event and @record does not match
2007  * -1 - no filter found for @record's event
2008  * -2 - if no filters exist
2009  */
2010 int pevent_filter_match(struct event_filter *filter,
2011                         struct pevent_record *record)
2012 {
2013         struct pevent *pevent = filter->pevent;
2014         struct filter_type *filter_type;
2015         int event_id;
2016
2017         if (!filter->filters)
2018                 return FILTER_NONE;
2019
2020         event_id = pevent_data_type(pevent, record);
2021
2022         filter_type = find_filter_type(filter, event_id);
2023
2024         if (!filter_type)
2025                 return FILTER_NOEXIST;
2026
2027         return test_filter(filter_type->event, filter_type->filter, record) ?
2028                 FILTER_MATCH : FILTER_MISS;
2029 }
2030
2031 static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
2032 {
2033         char *str = NULL;
2034         char *left = NULL;
2035         char *right = NULL;
2036         char *op = NULL;
2037         int left_val = -1;
2038         int right_val = -1;
2039         int val;
2040         int len;
2041
2042         switch (arg->op.type) {
2043         case FILTER_OP_AND:
2044                 op = "&&";
2045                 /* fall through */
2046         case FILTER_OP_OR:
2047                 if (!op)
2048                         op = "||";
2049
2050                 left = arg_to_str(filter, arg->op.left);
2051                 right = arg_to_str(filter, arg->op.right);
2052                 if (!left || !right)
2053                         break;
2054
2055                 /* Try to consolidate boolean values */
2056                 if (strcmp(left, "TRUE") == 0)
2057                         left_val = 1;
2058                 else if (strcmp(left, "FALSE") == 0)
2059                         left_val = 0;
2060
2061                 if (strcmp(right, "TRUE") == 0)
2062                         right_val = 1;
2063                 else if (strcmp(right, "FALSE") == 0)
2064                         right_val = 0;
2065
2066                 if (left_val >= 0) {
2067                         if ((arg->op.type == FILTER_OP_AND && !left_val) ||
2068                             (arg->op.type == FILTER_OP_OR && left_val)) {
2069                                 /* Just return left value */
2070                                 str = left;
2071                                 left = NULL;
2072                                 break;
2073                         }
2074                         if (right_val >= 0) {
2075                                 /* just evaluate this. */
2076                                 val = 0;
2077                                 switch (arg->op.type) {
2078                                 case FILTER_OP_AND:
2079                                         val = left_val && right_val;
2080                                         break;
2081                                 case FILTER_OP_OR:
2082                                         val = left_val || right_val;
2083                                         break;
2084                                 default:
2085                                         break;
2086                                 }
2087                                 str = malloc_or_die(6);
2088                                 if (val)
2089                                         strcpy(str, "TRUE");
2090                                 else
2091                                         strcpy(str, "FALSE");
2092                                 break;
2093                         }
2094                 }
2095                 if (right_val >= 0) {
2096                         if ((arg->op.type == FILTER_OP_AND && !right_val) ||
2097                             (arg->op.type == FILTER_OP_OR && right_val)) {
2098                                 /* Just return right value */
2099                                 str = right;
2100                                 right = NULL;
2101                                 break;
2102                         }
2103                         /* The right value is meaningless */
2104                         str = left;
2105                         left = NULL;
2106                         break;
2107                 }
2108
2109                 len = strlen(left) + strlen(right) + strlen(op) + 10;
2110                 str = malloc_or_die(len);
2111                 snprintf(str, len, "(%s) %s (%s)",
2112                          left, op, right);
2113                 break;
2114
2115         case FILTER_OP_NOT:
2116                 op = "!";
2117                 right = arg_to_str(filter, arg->op.right);
2118                 if (!right)
2119                         break;
2120
2121                 /* See if we can consolidate */
2122                 if (strcmp(right, "TRUE") == 0)
2123                         right_val = 1;
2124                 else if (strcmp(right, "FALSE") == 0)
2125                         right_val = 0;
2126                 if (right_val >= 0) {
2127                         /* just return the opposite */
2128                         str = malloc_or_die(6);
2129                         if (right_val)
2130                                 strcpy(str, "FALSE");
2131                         else
2132                                 strcpy(str, "TRUE");
2133                         break;
2134                 }
2135                 len = strlen(right) + strlen(op) + 3;
2136                 str = malloc_or_die(len);
2137                 snprintf(str, len, "%s(%s)", op, right);
2138                 break;
2139
2140         default:
2141                 /* ?? */
2142                 break;
2143         }
2144         free(left);
2145         free(right);
2146         return str;
2147 }
2148
2149 static char *val_to_str(struct event_filter *filter, struct filter_arg *arg)
2150 {
2151         char *str;
2152
2153         str = malloc_or_die(30);
2154
2155         snprintf(str, 30, "%lld", arg->value.val);
2156
2157         return str;
2158 }
2159
2160 static char *field_to_str(struct event_filter *filter, struct filter_arg *arg)
2161 {
2162         return strdup(arg->field.field->name);
2163 }
2164
2165 static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2166 {
2167         char *lstr;
2168         char *rstr;
2169         char *op;
2170         char *str = NULL;
2171         int len;
2172
2173         lstr = arg_to_str(filter, arg->exp.left);
2174         rstr = arg_to_str(filter, arg->exp.right);
2175         if (!lstr || !rstr)
2176                 goto out;
2177
2178         switch (arg->exp.type) {
2179         case FILTER_EXP_ADD:
2180                 op = "+";
2181                 break;
2182         case FILTER_EXP_SUB:
2183                 op = "-";
2184                 break;
2185         case FILTER_EXP_MUL:
2186                 op = "*";
2187                 break;
2188         case FILTER_EXP_DIV:
2189                 op = "/";
2190                 break;
2191         case FILTER_EXP_MOD:
2192                 op = "%";
2193                 break;
2194         case FILTER_EXP_RSHIFT:
2195                 op = ">>";
2196                 break;
2197         case FILTER_EXP_LSHIFT:
2198                 op = "<<";
2199                 break;
2200         case FILTER_EXP_AND:
2201                 op = "&";
2202                 break;
2203         case FILTER_EXP_OR:
2204                 op = "|";
2205                 break;
2206         case FILTER_EXP_XOR:
2207                 op = "^";
2208                 break;
2209         default:
2210                 die("oops in exp");
2211         }
2212
2213         len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
2214         str = malloc_or_die(len);
2215         snprintf(str, len, "%s %s %s", lstr, op, rstr);
2216 out:
2217         free(lstr);
2218         free(rstr);
2219
2220         return str;
2221 }
2222
2223 static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2224 {
2225         char *lstr;
2226         char *rstr;
2227         char *str = NULL;
2228         char *op = NULL;
2229         int len;
2230
2231         lstr = arg_to_str(filter, arg->num.left);
2232         rstr = arg_to_str(filter, arg->num.right);
2233         if (!lstr || !rstr)
2234                 goto out;
2235
2236         switch (arg->num.type) {
2237         case FILTER_CMP_EQ:
2238                 op = "==";
2239                 /* fall through */
2240         case FILTER_CMP_NE:
2241                 if (!op)
2242                         op = "!=";
2243                 /* fall through */
2244         case FILTER_CMP_GT:
2245                 if (!op)
2246                         op = ">";
2247                 /* fall through */
2248         case FILTER_CMP_LT:
2249                 if (!op)
2250                         op = "<";
2251                 /* fall through */
2252         case FILTER_CMP_GE:
2253                 if (!op)
2254                         op = ">=";
2255                 /* fall through */
2256         case FILTER_CMP_LE:
2257                 if (!op)
2258                         op = "<=";
2259
2260                 len = strlen(lstr) + strlen(op) + strlen(rstr) + 4;
2261                 str = malloc_or_die(len);
2262                 sprintf(str, "%s %s %s", lstr, op, rstr);
2263
2264                 break;
2265
2266         default:
2267                 /* ?? */
2268                 break;
2269         }
2270
2271 out:
2272         free(lstr);
2273         free(rstr);
2274         return str;
2275 }
2276
2277 static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
2278 {
2279         char *str = NULL;
2280         char *op = NULL;
2281         int len;
2282
2283         switch (arg->str.type) {
2284         case FILTER_CMP_MATCH:
2285                 op = "==";
2286                 /* fall through */
2287         case FILTER_CMP_NOT_MATCH:
2288                 if (!op)
2289                         op = "!=";
2290                 /* fall through */
2291         case FILTER_CMP_REGEX:
2292                 if (!op)
2293                         op = "=~";
2294                 /* fall through */
2295         case FILTER_CMP_NOT_REGEX:
2296                 if (!op)
2297                         op = "!~";
2298
2299                 len = strlen(arg->str.field->name) + strlen(op) +
2300                         strlen(arg->str.val) + 6;
2301                 str = malloc_or_die(len);
2302                 snprintf(str, len, "%s %s \"%s\"",
2303                          arg->str.field->name,
2304                          op, arg->str.val);
2305                 break;
2306
2307         default:
2308                 /* ?? */
2309                 break;
2310         }
2311         return str;
2312 }
2313
2314 static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
2315 {
2316         char *str;
2317
2318         switch (arg->type) {
2319         case FILTER_ARG_BOOLEAN:
2320                 str = malloc_or_die(6);
2321                 if (arg->boolean.value)
2322                         strcpy(str, "TRUE");
2323                 else
2324                         strcpy(str, "FALSE");
2325                 return str;
2326
2327         case FILTER_ARG_OP:
2328                 return op_to_str(filter, arg);
2329
2330         case FILTER_ARG_NUM:
2331                 return num_to_str(filter, arg);
2332
2333         case FILTER_ARG_STR:
2334                 return str_to_str(filter, arg);
2335
2336         case FILTER_ARG_VALUE:
2337                 return val_to_str(filter, arg);
2338
2339         case FILTER_ARG_FIELD:
2340                 return field_to_str(filter, arg);
2341
2342         case FILTER_ARG_EXP:
2343                 return exp_to_str(filter, arg);
2344
2345         default:
2346                 /* ?? */
2347                 return NULL;
2348         }
2349
2350 }
2351
2352 /**
2353  * pevent_filter_make_string - return a string showing the filter
2354  * @filter: filter struct with filter information
2355  * @event_id: the event id to return the filter string with
2356  *
2357  * Returns a string that displays the filter contents.
2358  *  This string must be freed with free(str).
2359  *  NULL is returned if no filter is found.
2360  */
2361 char *
2362 pevent_filter_make_string(struct event_filter *filter, int event_id)
2363 {
2364         struct filter_type *filter_type;
2365
2366         if (!filter->filters)
2367                 return NULL;
2368
2369         filter_type = find_filter_type(filter, event_id);
2370
2371         if (!filter_type)
2372                 return NULL;
2373
2374         return arg_to_str(filter, filter_type->filter);
2375 }
2376
2377 /**
2378  * pevent_filter_compare - compare two filters and return if they are the same
2379  * @filter1: Filter to compare with @filter2
2380  * @filter2: Filter to compare with @filter1
2381  *
2382  * Returns:
2383  *  1 if the two filters hold the same content.
2384  *  0 if they do not.
2385  */
2386 int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2)
2387 {
2388         struct filter_type *filter_type1;
2389         struct filter_type *filter_type2;
2390         char *str1, *str2;
2391         int result;
2392         int i;
2393
2394         /* Do the easy checks first */
2395         if (filter1->filters != filter2->filters)
2396                 return 0;
2397         if (!filter1->filters && !filter2->filters)
2398                 return 1;
2399
2400         /*
2401          * Now take a look at each of the events to see if they have the same
2402          * filters to them.
2403          */
2404         for (i = 0; i < filter1->filters; i++) {
2405                 filter_type1 = &filter1->event_filters[i];
2406                 filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2407                 if (!filter_type2)
2408                         break;
2409                 if (filter_type1->filter->type != filter_type2->filter->type)
2410                         break;
2411                 switch (filter_type1->filter->type) {
2412                 case FILTER_TRIVIAL_FALSE:
2413                 case FILTER_TRIVIAL_TRUE:
2414                         /* trivial types just need the type compared */
2415                         continue;
2416                 default:
2417                         break;
2418                 }
2419                 /* The best way to compare complex filters is with strings */
2420                 str1 = arg_to_str(filter1, filter_type1->filter);
2421                 str2 = arg_to_str(filter2, filter_type2->filter);
2422                 if (str1 && str2)
2423                         result = strcmp(str1, str2) != 0;
2424                 else
2425                         /* bail out if allocation fails */
2426                         result = 1;
2427
2428                 free(str1);
2429                 free(str2);
2430                 if (result)
2431                         break;
2432         }
2433
2434         if (i < filter1->filters)
2435                 return 0;
2436         return 1;
2437 }
2438