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