~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/lib/traceevent/parse-filter.c

Version: ~ [ linux-5.1-rc5 ] ~ [ linux-5.0.7 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.34 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.111 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.168 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.178 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.138 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.65 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp