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