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