Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: LGPL-2.1
0002 /*
0003  * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
0004  *
0005  */
0006 #include <stdio.h>
0007 #include <stdlib.h>
0008 #include <string.h>
0009 #include <stdarg.h>
0010 #include <errno.h>
0011 #include <sys/types.h>
0012 
0013 #include "event-parse.h"
0014 #include "event-parse-local.h"
0015 #include "event-utils.h"
0016 
0017 #define COMM "COMM"
0018 #define CPU "CPU"
0019 
0020 static struct tep_format_field comm = {
0021     .name = "COMM",
0022 };
0023 
0024 static struct tep_format_field cpu = {
0025     .name = "CPU",
0026 };
0027 
0028 struct event_list {
0029     struct event_list   *next;
0030     struct tep_event    *event;
0031 };
0032 
0033 static void show_error(char *error_buf, const char *fmt, ...)
0034 {
0035     unsigned long long index;
0036     const char *input;
0037     va_list ap;
0038     int len;
0039     int i;
0040 
0041     input = get_input_buf();
0042     index = get_input_buf_ptr();
0043     len = input ? strlen(input) : 0;
0044 
0045     if (len) {
0046         strcpy(error_buf, input);
0047         error_buf[len] = '\n';
0048         for (i = 1; i < len && i < index; i++)
0049             error_buf[len+i] = ' ';
0050         error_buf[len + i] = '^';
0051         error_buf[len + i + 1] = '\n';
0052         len += i+2;
0053     }
0054 
0055     va_start(ap, fmt);
0056     vsnprintf(error_buf + len, TEP_FILTER_ERROR_BUFSZ - len, fmt, ap);
0057     va_end(ap);
0058 }
0059 
0060 static enum tep_event_type filter_read_token(char **tok)
0061 {
0062     enum tep_event_type type;
0063     char *token = NULL;
0064 
0065     do {
0066         free_token(token);
0067         type = read_token(&token);
0068     } while (type == TEP_EVENT_NEWLINE || type == TEP_EVENT_SPACE);
0069 
0070     /* If token is = or ! check to see if the next char is ~ */
0071     if (token &&
0072         (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
0073         peek_char() == '~') {
0074         /* append it */
0075         *tok = malloc(3);
0076         if (*tok == NULL) {
0077             free_token(token);
0078             return TEP_EVENT_ERROR;
0079         }
0080         sprintf(*tok, "%c%c", *token, '~');
0081         free_token(token);
0082         /* Now remove the '~' from the buffer */
0083         read_token(&token);
0084         free_token(token);
0085     } else
0086         *tok = token;
0087 
0088     return type;
0089 }
0090 
0091 static int filter_cmp(const void *a, const void *b)
0092 {
0093     const struct tep_filter_type *ea = a;
0094     const struct tep_filter_type *eb = b;
0095 
0096     if (ea->event_id < eb->event_id)
0097         return -1;
0098 
0099     if (ea->event_id > eb->event_id)
0100         return 1;
0101 
0102     return 0;
0103 }
0104 
0105 static struct tep_filter_type *
0106 find_filter_type(struct tep_event_filter *filter, int id)
0107 {
0108     struct tep_filter_type *filter_type;
0109     struct tep_filter_type key;
0110 
0111     key.event_id = id;
0112 
0113     filter_type = bsearch(&key, filter->event_filters,
0114                   filter->filters,
0115                   sizeof(*filter->event_filters),
0116                   filter_cmp);
0117 
0118     return filter_type;
0119 }
0120 
0121 static struct tep_filter_type *
0122 add_filter_type(struct tep_event_filter *filter, int id)
0123 {
0124     struct tep_filter_type *filter_type;
0125     int i;
0126 
0127     filter_type = find_filter_type(filter, id);
0128     if (filter_type)
0129         return filter_type;
0130 
0131     filter_type = realloc(filter->event_filters,
0132                   sizeof(*filter->event_filters) *
0133                   (filter->filters + 1));
0134     if (!filter_type)
0135         return NULL;
0136 
0137     filter->event_filters = filter_type;
0138 
0139     for (i = 0; i < filter->filters; i++) {
0140         if (filter->event_filters[i].event_id > id)
0141             break;
0142     }
0143 
0144     if (i < filter->filters)
0145         memmove(&filter->event_filters[i+1],
0146             &filter->event_filters[i],
0147             sizeof(*filter->event_filters) *
0148             (filter->filters - i));
0149 
0150     filter_type = &filter->event_filters[i];
0151     filter_type->event_id = id;
0152     filter_type->event = tep_find_event(filter->tep, id);
0153     filter_type->filter = NULL;
0154 
0155     filter->filters++;
0156 
0157     return filter_type;
0158 }
0159 
0160 /**
0161  * tep_filter_alloc - create a new event filter
0162  * @tep: The tep that this filter is associated with
0163  */
0164 struct tep_event_filter *tep_filter_alloc(struct tep_handle *tep)
0165 {
0166     struct tep_event_filter *filter;
0167 
0168     filter = malloc(sizeof(*filter));
0169     if (filter == NULL)
0170         return NULL;
0171 
0172     memset(filter, 0, sizeof(*filter));
0173     filter->tep = tep;
0174     tep_ref(tep);
0175 
0176     return filter;
0177 }
0178 
0179 static struct tep_filter_arg *allocate_arg(void)
0180 {
0181     return calloc(1, sizeof(struct tep_filter_arg));
0182 }
0183 
0184 static void free_arg(struct tep_filter_arg *arg)
0185 {
0186     if (!arg)
0187         return;
0188 
0189     switch (arg->type) {
0190     case TEP_FILTER_ARG_NONE:
0191     case TEP_FILTER_ARG_BOOLEAN:
0192         break;
0193 
0194     case TEP_FILTER_ARG_NUM:
0195         free_arg(arg->num.left);
0196         free_arg(arg->num.right);
0197         break;
0198 
0199     case TEP_FILTER_ARG_EXP:
0200         free_arg(arg->exp.left);
0201         free_arg(arg->exp.right);
0202         break;
0203 
0204     case TEP_FILTER_ARG_STR:
0205         free(arg->str.val);
0206         regfree(&arg->str.reg);
0207         free(arg->str.buffer);
0208         break;
0209 
0210     case TEP_FILTER_ARG_VALUE:
0211         if (arg->value.type == TEP_FILTER_STRING ||
0212             arg->value.type == TEP_FILTER_CHAR)
0213             free(arg->value.str);
0214         break;
0215 
0216     case TEP_FILTER_ARG_OP:
0217         free_arg(arg->op.left);
0218         free_arg(arg->op.right);
0219     default:
0220         break;
0221     }
0222 
0223     free(arg);
0224 }
0225 
0226 static int add_event(struct event_list **events,
0227              struct tep_event *event)
0228 {
0229     struct event_list *list;
0230 
0231     list = malloc(sizeof(*list));
0232     if (list == NULL)
0233         return -1;
0234 
0235     list->next = *events;
0236     *events = list;
0237     list->event = event;
0238     return 0;
0239 }
0240 
0241 static int event_match(struct tep_event *event,
0242                regex_t *sreg, regex_t *ereg)
0243 {
0244     if (sreg) {
0245         return !regexec(sreg, event->system, 0, NULL, 0) &&
0246             !regexec(ereg, event->name, 0, NULL, 0);
0247     }
0248 
0249     return !regexec(ereg, event->system, 0, NULL, 0) ||
0250         !regexec(ereg, event->name, 0, NULL, 0);
0251 }
0252 
0253 static enum tep_errno
0254 find_event(struct tep_handle *tep, struct event_list **events,
0255        char *sys_name, char *event_name)
0256 {
0257     struct tep_event *event;
0258     regex_t ereg;
0259     regex_t sreg;
0260     int match = 0;
0261     int fail = 0;
0262     char *reg;
0263     int ret;
0264     int i;
0265 
0266     if (!event_name) {
0267         /* if no name is given, then swap sys and name */
0268         event_name = sys_name;
0269         sys_name = NULL;
0270     }
0271 
0272     ret = asprintf(&reg, "^%s$", event_name);
0273     if (ret < 0)
0274         return TEP_ERRNO__MEM_ALLOC_FAILED;
0275 
0276     ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
0277     free(reg);
0278 
0279     if (ret)
0280         return TEP_ERRNO__INVALID_EVENT_NAME;
0281 
0282     if (sys_name) {
0283         ret = asprintf(&reg, "^%s$", sys_name);
0284         if (ret < 0) {
0285             regfree(&ereg);
0286             return TEP_ERRNO__MEM_ALLOC_FAILED;
0287         }
0288 
0289         ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
0290         free(reg);
0291         if (ret) {
0292             regfree(&ereg);
0293             return TEP_ERRNO__INVALID_EVENT_NAME;
0294         }
0295     }
0296 
0297     for (i = 0; i < tep->nr_events; i++) {
0298         event = tep->events[i];
0299         if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
0300             match = 1;
0301             if (add_event(events, event) < 0) {
0302                 fail = 1;
0303                 break;
0304             }
0305         }
0306     }
0307 
0308     regfree(&ereg);
0309     if (sys_name)
0310         regfree(&sreg);
0311 
0312     if (!match)
0313         return TEP_ERRNO__EVENT_NOT_FOUND;
0314     if (fail)
0315         return TEP_ERRNO__MEM_ALLOC_FAILED;
0316 
0317     return 0;
0318 }
0319 
0320 static void free_events(struct event_list *events)
0321 {
0322     struct event_list *event;
0323 
0324     while (events) {
0325         event = events;
0326         events = events->next;
0327         free(event);
0328     }
0329 }
0330 
0331 static enum tep_errno
0332 create_arg_item(struct tep_event *event, const char *token,
0333         enum tep_event_type type, struct tep_filter_arg **parg, char *error_str)
0334 {
0335     struct tep_format_field *field;
0336     struct tep_filter_arg *arg;
0337 
0338     arg = allocate_arg();
0339     if (arg == NULL) {
0340         show_error(error_str, "failed to allocate filter arg");
0341         return TEP_ERRNO__MEM_ALLOC_FAILED;
0342     }
0343 
0344     switch (type) {
0345 
0346     case TEP_EVENT_SQUOTE:
0347     case TEP_EVENT_DQUOTE:
0348         arg->type = TEP_FILTER_ARG_VALUE;
0349         arg->value.type =
0350             type == TEP_EVENT_DQUOTE ? TEP_FILTER_STRING : TEP_FILTER_CHAR;
0351         arg->value.str = strdup(token);
0352         if (!arg->value.str) {
0353             free_arg(arg);
0354             show_error(error_str, "failed to allocate string filter arg");
0355             return TEP_ERRNO__MEM_ALLOC_FAILED;
0356         }
0357         break;
0358     case TEP_EVENT_ITEM:
0359         /* if it is a number, then convert it */
0360         if (isdigit(token[0])) {
0361             arg->type = TEP_FILTER_ARG_VALUE;
0362             arg->value.type = TEP_FILTER_NUMBER;
0363             arg->value.val = strtoull(token, NULL, 0);
0364             break;
0365         }
0366         /* Consider this a field */
0367         field = tep_find_any_field(event, token);
0368         if (!field) {
0369             /* If token is 'COMM' or 'CPU' then it is special */
0370             if (strcmp(token, COMM) == 0) {
0371                 field = &comm;
0372             } else if (strcmp(token, CPU) == 0) {
0373                 field = &cpu;
0374             } else {
0375                 /* not a field, Make it false */
0376                 arg->type = TEP_FILTER_ARG_BOOLEAN;
0377                 arg->boolean.value = TEP_FILTER_FALSE;
0378                 break;
0379             }
0380         }
0381         arg->type = TEP_FILTER_ARG_FIELD;
0382         arg->field.field = field;
0383         break;
0384     default:
0385         free_arg(arg);
0386         show_error(error_str, "expected a value but found %s", token);
0387         return TEP_ERRNO__UNEXPECTED_TYPE;
0388     }
0389     *parg = arg;
0390     return 0;
0391 }
0392 
0393 static struct tep_filter_arg *
0394 create_arg_op(enum tep_filter_op_type btype)
0395 {
0396     struct tep_filter_arg *arg;
0397 
0398     arg = allocate_arg();
0399     if (!arg)
0400         return NULL;
0401 
0402     arg->type = TEP_FILTER_ARG_OP;
0403     arg->op.type = btype;
0404 
0405     return arg;
0406 }
0407 
0408 static struct tep_filter_arg *
0409 create_arg_exp(enum tep_filter_exp_type etype)
0410 {
0411     struct tep_filter_arg *arg;
0412 
0413     arg = allocate_arg();
0414     if (!arg)
0415         return NULL;
0416 
0417     arg->type = TEP_FILTER_ARG_EXP;
0418     arg->exp.type = etype;
0419 
0420     return arg;
0421 }
0422 
0423 static struct tep_filter_arg *
0424 create_arg_cmp(enum tep_filter_cmp_type ctype)
0425 {
0426     struct tep_filter_arg *arg;
0427 
0428     arg = allocate_arg();
0429     if (!arg)
0430         return NULL;
0431 
0432     /* Use NUM and change if necessary */
0433     arg->type = TEP_FILTER_ARG_NUM;
0434     arg->num.type = ctype;
0435 
0436     return arg;
0437 }
0438 
0439 static enum tep_errno
0440 add_right(struct tep_filter_arg *op, struct tep_filter_arg *arg, char *error_str)
0441 {
0442     struct tep_filter_arg *left;
0443     char *str;
0444     int op_type;
0445     int ret;
0446 
0447     switch (op->type) {
0448     case TEP_FILTER_ARG_EXP:
0449         if (op->exp.right)
0450             goto out_fail;
0451         op->exp.right = arg;
0452         break;
0453 
0454     case TEP_FILTER_ARG_OP:
0455         if (op->op.right)
0456             goto out_fail;
0457         op->op.right = arg;
0458         break;
0459 
0460     case TEP_FILTER_ARG_NUM:
0461         if (op->op.right)
0462             goto out_fail;
0463         /*
0464          * The arg must be num, str, or field
0465          */
0466         switch (arg->type) {
0467         case TEP_FILTER_ARG_VALUE:
0468         case TEP_FILTER_ARG_FIELD:
0469             break;
0470         default:
0471             show_error(error_str, "Illegal rvalue");
0472             return TEP_ERRNO__ILLEGAL_RVALUE;
0473         }
0474 
0475         /*
0476          * Depending on the type, we may need to
0477          * convert this to a string or regex.
0478          */
0479         switch (arg->value.type) {
0480         case TEP_FILTER_CHAR:
0481             /*
0482              * A char should be converted to number if
0483              * the string is 1 byte, and the compare
0484              * is not a REGEX.
0485              */
0486             if (strlen(arg->value.str) == 1 &&
0487                 op->num.type != TEP_FILTER_CMP_REGEX &&
0488                 op->num.type != TEP_FILTER_CMP_NOT_REGEX) {
0489                 arg->value.type = TEP_FILTER_NUMBER;
0490                 goto do_int;
0491             }
0492             /* fall through */
0493         case TEP_FILTER_STRING:
0494 
0495             /* convert op to a string arg */
0496             op_type = op->num.type;
0497             left = op->num.left;
0498             str = arg->value.str;
0499 
0500             /* reset the op for the new field */
0501             memset(op, 0, sizeof(*op));
0502 
0503             /*
0504              * If left arg was a field not found then
0505              * NULL the entire op.
0506              */
0507             if (left->type == TEP_FILTER_ARG_BOOLEAN) {
0508                 free_arg(left);
0509                 free_arg(arg);
0510                 op->type = TEP_FILTER_ARG_BOOLEAN;
0511                 op->boolean.value = TEP_FILTER_FALSE;
0512                 break;
0513             }
0514 
0515             /* Left arg must be a field */
0516             if (left->type != TEP_FILTER_ARG_FIELD) {
0517                 show_error(error_str,
0518                        "Illegal lvalue for string comparison");
0519                 return TEP_ERRNO__ILLEGAL_LVALUE;
0520             }
0521 
0522             /* Make sure this is a valid string compare */
0523             switch (op_type) {
0524             case TEP_FILTER_CMP_EQ:
0525                 op_type = TEP_FILTER_CMP_MATCH;
0526                 break;
0527             case TEP_FILTER_CMP_NE:
0528                 op_type = TEP_FILTER_CMP_NOT_MATCH;
0529                 break;
0530 
0531             case TEP_FILTER_CMP_REGEX:
0532             case TEP_FILTER_CMP_NOT_REGEX:
0533                 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB);
0534                 if (ret) {
0535                     show_error(error_str,
0536                            "RegEx '%s' did not compute",
0537                            str);
0538                     return TEP_ERRNO__INVALID_REGEX;
0539                 }
0540                 break;
0541             default:
0542                 show_error(error_str,
0543                        "Illegal comparison for string");
0544                 return TEP_ERRNO__ILLEGAL_STRING_CMP;
0545             }
0546 
0547             op->type = TEP_FILTER_ARG_STR;
0548             op->str.type = op_type;
0549             op->str.field = left->field.field;
0550             op->str.val = strdup(str);
0551             if (!op->str.val) {
0552                 show_error(error_str, "Failed to allocate string filter");
0553                 return TEP_ERRNO__MEM_ALLOC_FAILED;
0554             }
0555             /*
0556              * Need a buffer to copy data for tests
0557              */
0558             op->str.buffer = malloc(op->str.field->size + 1);
0559             if (!op->str.buffer) {
0560                 show_error(error_str, "Failed to allocate string filter");
0561                 return TEP_ERRNO__MEM_ALLOC_FAILED;
0562             }
0563             /* Null terminate this buffer */
0564             op->str.buffer[op->str.field->size] = 0;
0565 
0566             /* We no longer have left or right args */
0567             free_arg(arg);
0568             free_arg(left);
0569 
0570             break;
0571 
0572         case TEP_FILTER_NUMBER:
0573 
0574  do_int:
0575             switch (op->num.type) {
0576             case TEP_FILTER_CMP_REGEX:
0577             case TEP_FILTER_CMP_NOT_REGEX:
0578                 show_error(error_str,
0579                        "Op not allowed with integers");
0580                 return TEP_ERRNO__ILLEGAL_INTEGER_CMP;
0581 
0582             default:
0583                 break;
0584             }
0585 
0586             /* numeric compare */
0587             op->num.right = arg;
0588             break;
0589         default:
0590             goto out_fail;
0591         }
0592         break;
0593     default:
0594         goto out_fail;
0595     }
0596 
0597     return 0;
0598 
0599  out_fail:
0600     show_error(error_str, "Syntax error");
0601     return TEP_ERRNO__SYNTAX_ERROR;
0602 }
0603 
0604 static struct tep_filter_arg *
0605 rotate_op_right(struct tep_filter_arg *a, struct tep_filter_arg *b)
0606 {
0607     struct tep_filter_arg *arg;
0608 
0609     arg = a->op.right;
0610     a->op.right = b;
0611     return arg;
0612 }
0613 
0614 static enum tep_errno add_left(struct tep_filter_arg *op, struct tep_filter_arg *arg)
0615 {
0616     switch (op->type) {
0617     case TEP_FILTER_ARG_EXP:
0618         if (arg->type == TEP_FILTER_ARG_OP)
0619             arg = rotate_op_right(arg, op);
0620         op->exp.left = arg;
0621         break;
0622 
0623     case TEP_FILTER_ARG_OP:
0624         op->op.left = arg;
0625         break;
0626     case TEP_FILTER_ARG_NUM:
0627         if (arg->type == TEP_FILTER_ARG_OP)
0628             arg = rotate_op_right(arg, op);
0629 
0630         /* left arg of compares must be a field */
0631         if (arg->type != TEP_FILTER_ARG_FIELD &&
0632             arg->type != TEP_FILTER_ARG_BOOLEAN)
0633             return TEP_ERRNO__INVALID_ARG_TYPE;
0634         op->num.left = arg;
0635         break;
0636     default:
0637         return TEP_ERRNO__INVALID_ARG_TYPE;
0638     }
0639     return 0;
0640 }
0641 
0642 enum op_type {
0643     OP_NONE,
0644     OP_BOOL,
0645     OP_NOT,
0646     OP_EXP,
0647     OP_CMP,
0648 };
0649 
0650 static enum op_type process_op(const char *token,
0651                    enum tep_filter_op_type *btype,
0652                    enum tep_filter_cmp_type *ctype,
0653                    enum tep_filter_exp_type *etype)
0654 {
0655     *btype = TEP_FILTER_OP_NOT;
0656     *etype = TEP_FILTER_EXP_NONE;
0657     *ctype = TEP_FILTER_CMP_NONE;
0658 
0659     if (strcmp(token, "&&") == 0)
0660         *btype = TEP_FILTER_OP_AND;
0661     else if (strcmp(token, "||") == 0)
0662         *btype = TEP_FILTER_OP_OR;
0663     else if (strcmp(token, "!") == 0)
0664         return OP_NOT;
0665 
0666     if (*btype != TEP_FILTER_OP_NOT)
0667         return OP_BOOL;
0668 
0669     /* Check for value expressions */
0670     if (strcmp(token, "+") == 0) {
0671         *etype = TEP_FILTER_EXP_ADD;
0672     } else if (strcmp(token, "-") == 0) {
0673         *etype = TEP_FILTER_EXP_SUB;
0674     } else if (strcmp(token, "*") == 0) {
0675         *etype = TEP_FILTER_EXP_MUL;
0676     } else if (strcmp(token, "/") == 0) {
0677         *etype = TEP_FILTER_EXP_DIV;
0678     } else if (strcmp(token, "%") == 0) {
0679         *etype = TEP_FILTER_EXP_MOD;
0680     } else if (strcmp(token, ">>") == 0) {
0681         *etype = TEP_FILTER_EXP_RSHIFT;
0682     } else if (strcmp(token, "<<") == 0) {
0683         *etype = TEP_FILTER_EXP_LSHIFT;
0684     } else if (strcmp(token, "&") == 0) {
0685         *etype = TEP_FILTER_EXP_AND;
0686     } else if (strcmp(token, "|") == 0) {
0687         *etype = TEP_FILTER_EXP_OR;
0688     } else if (strcmp(token, "^") == 0) {
0689         *etype = TEP_FILTER_EXP_XOR;
0690     } else if (strcmp(token, "~") == 0)
0691         *etype = TEP_FILTER_EXP_NOT;
0692 
0693     if (*etype != TEP_FILTER_EXP_NONE)
0694         return OP_EXP;
0695 
0696     /* Check for compares */
0697     if (strcmp(token, "==") == 0)
0698         *ctype = TEP_FILTER_CMP_EQ;
0699     else if (strcmp(token, "!=") == 0)
0700         *ctype = TEP_FILTER_CMP_NE;
0701     else if (strcmp(token, "<") == 0)
0702         *ctype = TEP_FILTER_CMP_LT;
0703     else if (strcmp(token, ">") == 0)
0704         *ctype = TEP_FILTER_CMP_GT;
0705     else if (strcmp(token, "<=") == 0)
0706         *ctype = TEP_FILTER_CMP_LE;
0707     else if (strcmp(token, ">=") == 0)
0708         *ctype = TEP_FILTER_CMP_GE;
0709     else if (strcmp(token, "=~") == 0)
0710         *ctype = TEP_FILTER_CMP_REGEX;
0711     else if (strcmp(token, "!~") == 0)
0712         *ctype = TEP_FILTER_CMP_NOT_REGEX;
0713     else
0714         return OP_NONE;
0715 
0716     return OP_CMP;
0717 }
0718 
0719 static int check_op_done(struct tep_filter_arg *arg)
0720 {
0721     switch (arg->type) {
0722     case TEP_FILTER_ARG_EXP:
0723         return arg->exp.right != NULL;
0724 
0725     case TEP_FILTER_ARG_OP:
0726         return arg->op.right != NULL;
0727 
0728     case TEP_FILTER_ARG_NUM:
0729         return arg->num.right != NULL;
0730 
0731     case TEP_FILTER_ARG_STR:
0732         /* A string conversion is always done */
0733         return 1;
0734 
0735     case TEP_FILTER_ARG_BOOLEAN:
0736         /* field not found, is ok */
0737         return 1;
0738 
0739     default:
0740         return 0;
0741     }
0742 }
0743 
0744 enum filter_vals {
0745     FILTER_VAL_NORM,
0746     FILTER_VAL_FALSE,
0747     FILTER_VAL_TRUE,
0748 };
0749 
0750 static enum tep_errno
0751 reparent_op_arg(struct tep_filter_arg *parent, struct tep_filter_arg *old_child,
0752         struct tep_filter_arg *arg, char *error_str)
0753 {
0754     struct tep_filter_arg *other_child;
0755     struct tep_filter_arg **ptr;
0756 
0757     if (parent->type != TEP_FILTER_ARG_OP &&
0758         arg->type != TEP_FILTER_ARG_OP) {
0759         show_error(error_str, "can not reparent other than OP");
0760         return TEP_ERRNO__REPARENT_NOT_OP;
0761     }
0762 
0763     /* Get the sibling */
0764     if (old_child->op.right == arg) {
0765         ptr = &old_child->op.right;
0766         other_child = old_child->op.left;
0767     } else if (old_child->op.left == arg) {
0768         ptr = &old_child->op.left;
0769         other_child = old_child->op.right;
0770     } else {
0771         show_error(error_str, "Error in reparent op, find other child");
0772         return TEP_ERRNO__REPARENT_FAILED;
0773     }
0774 
0775     /* Detach arg from old_child */
0776     *ptr = NULL;
0777 
0778     /* Check for root */
0779     if (parent == old_child) {
0780         free_arg(other_child);
0781         *parent = *arg;
0782         /* Free arg without recussion */
0783         free(arg);
0784         return 0;
0785     }
0786 
0787     if (parent->op.right == old_child)
0788         ptr = &parent->op.right;
0789     else if (parent->op.left == old_child)
0790         ptr = &parent->op.left;
0791     else {
0792         show_error(error_str, "Error in reparent op");
0793         return TEP_ERRNO__REPARENT_FAILED;
0794     }
0795 
0796     *ptr = arg;
0797 
0798     free_arg(old_child);
0799     return 0;
0800 }
0801 
0802 /* Returns either filter_vals (success) or tep_errno (failfure) */
0803 static int test_arg(struct tep_filter_arg *parent, struct tep_filter_arg *arg,
0804             char *error_str)
0805 {
0806     int lval, rval;
0807 
0808     switch (arg->type) {
0809 
0810         /* bad case */
0811     case TEP_FILTER_ARG_BOOLEAN:
0812         return FILTER_VAL_FALSE + arg->boolean.value;
0813 
0814         /* good cases: */
0815     case TEP_FILTER_ARG_STR:
0816     case TEP_FILTER_ARG_VALUE:
0817     case TEP_FILTER_ARG_FIELD:
0818         return FILTER_VAL_NORM;
0819 
0820     case TEP_FILTER_ARG_EXP:
0821         lval = test_arg(arg, arg->exp.left, error_str);
0822         if (lval != FILTER_VAL_NORM)
0823             return lval;
0824         rval = test_arg(arg, arg->exp.right, error_str);
0825         if (rval != FILTER_VAL_NORM)
0826             return rval;
0827         return FILTER_VAL_NORM;
0828 
0829     case TEP_FILTER_ARG_NUM:
0830         lval = test_arg(arg, arg->num.left, error_str);
0831         if (lval != FILTER_VAL_NORM)
0832             return lval;
0833         rval = test_arg(arg, arg->num.right, error_str);
0834         if (rval != FILTER_VAL_NORM)
0835             return rval;
0836         return FILTER_VAL_NORM;
0837 
0838     case TEP_FILTER_ARG_OP:
0839         if (arg->op.type != TEP_FILTER_OP_NOT) {
0840             lval = test_arg(arg, arg->op.left, error_str);
0841             switch (lval) {
0842             case FILTER_VAL_NORM:
0843                 break;
0844             case FILTER_VAL_TRUE:
0845                 if (arg->op.type == TEP_FILTER_OP_OR)
0846                     return FILTER_VAL_TRUE;
0847                 rval = test_arg(arg, arg->op.right, error_str);
0848                 if (rval != FILTER_VAL_NORM)
0849                     return rval;
0850 
0851                 return reparent_op_arg(parent, arg, arg->op.right,
0852                                error_str);
0853 
0854             case FILTER_VAL_FALSE:
0855                 if (arg->op.type == TEP_FILTER_OP_AND)
0856                     return FILTER_VAL_FALSE;
0857                 rval = test_arg(arg, arg->op.right, error_str);
0858                 if (rval != FILTER_VAL_NORM)
0859                     return rval;
0860 
0861                 return reparent_op_arg(parent, arg, arg->op.right,
0862                                error_str);
0863 
0864             default:
0865                 return lval;
0866             }
0867         }
0868 
0869         rval = test_arg(arg, arg->op.right, error_str);
0870         switch (rval) {
0871         case FILTER_VAL_NORM:
0872         default:
0873             break;
0874 
0875         case FILTER_VAL_TRUE:
0876             if (arg->op.type == TEP_FILTER_OP_OR)
0877                 return FILTER_VAL_TRUE;
0878             if (arg->op.type == TEP_FILTER_OP_NOT)
0879                 return FILTER_VAL_FALSE;
0880 
0881             return reparent_op_arg(parent, arg, arg->op.left,
0882                            error_str);
0883 
0884         case FILTER_VAL_FALSE:
0885             if (arg->op.type == TEP_FILTER_OP_AND)
0886                 return FILTER_VAL_FALSE;
0887             if (arg->op.type == TEP_FILTER_OP_NOT)
0888                 return FILTER_VAL_TRUE;
0889 
0890             return reparent_op_arg(parent, arg, arg->op.left,
0891                            error_str);
0892         }
0893 
0894         return rval;
0895     default:
0896         show_error(error_str, "bad arg in filter tree");
0897         return TEP_ERRNO__BAD_FILTER_ARG;
0898     }
0899     return FILTER_VAL_NORM;
0900 }
0901 
0902 /* Remove any unknown event fields */
0903 static int collapse_tree(struct tep_filter_arg *arg,
0904              struct tep_filter_arg **arg_collapsed, char *error_str)
0905 {
0906     int ret;
0907 
0908     ret = test_arg(arg, arg, error_str);
0909     switch (ret) {
0910     case FILTER_VAL_NORM:
0911         break;
0912 
0913     case FILTER_VAL_TRUE:
0914     case FILTER_VAL_FALSE:
0915         free_arg(arg);
0916         arg = allocate_arg();
0917         if (arg) {
0918             arg->type = TEP_FILTER_ARG_BOOLEAN;
0919             arg->boolean.value = ret == FILTER_VAL_TRUE;
0920         } else {
0921             show_error(error_str, "Failed to allocate filter arg");
0922             ret = TEP_ERRNO__MEM_ALLOC_FAILED;
0923         }
0924         break;
0925 
0926     default:
0927         /* test_arg() already set the error_str */
0928         free_arg(arg);
0929         arg = NULL;
0930         break;
0931     }
0932 
0933     *arg_collapsed = arg;
0934     return ret;
0935 }
0936 
0937 static enum tep_errno
0938 process_filter(struct tep_event *event, struct tep_filter_arg **parg,
0939            char *error_str, int not)
0940 {
0941     enum tep_event_type type;
0942     char *token = NULL;
0943     struct tep_filter_arg *current_op = NULL;
0944     struct tep_filter_arg *current_exp = NULL;
0945     struct tep_filter_arg *left_item = NULL;
0946     struct tep_filter_arg *arg = NULL;
0947     enum op_type op_type;
0948     enum tep_filter_op_type btype;
0949     enum tep_filter_exp_type etype;
0950     enum tep_filter_cmp_type ctype;
0951     enum tep_errno ret;
0952 
0953     *parg = NULL;
0954 
0955     do {
0956         free(token);
0957         type = filter_read_token(&token);
0958         switch (type) {
0959         case TEP_EVENT_SQUOTE:
0960         case TEP_EVENT_DQUOTE:
0961         case TEP_EVENT_ITEM:
0962             ret = create_arg_item(event, token, type, &arg, error_str);
0963             if (ret < 0)
0964                 goto fail;
0965             if (!left_item)
0966                 left_item = arg;
0967             else if (current_exp) {
0968                 ret = add_right(current_exp, arg, error_str);
0969                 if (ret < 0)
0970                     goto fail;
0971                 left_item = NULL;
0972                 /* Not's only one one expression */
0973                 if (not) {
0974                     arg = NULL;
0975                     if (current_op)
0976                         goto fail_syntax;
0977                     free(token);
0978                     *parg = current_exp;
0979                     return 0;
0980                 }
0981             } else
0982                 goto fail_syntax;
0983             arg = NULL;
0984             break;
0985 
0986         case TEP_EVENT_DELIM:
0987             if (*token == ',') {
0988                 show_error(error_str, "Illegal token ','");
0989                 ret = TEP_ERRNO__ILLEGAL_TOKEN;
0990                 goto fail;
0991             }
0992 
0993             if (*token == '(') {
0994                 if (left_item) {
0995                     show_error(error_str,
0996                            "Open paren can not come after item");
0997                     ret = TEP_ERRNO__INVALID_PAREN;
0998                     goto fail;
0999                 }
1000                 if (current_exp) {
1001                     show_error(error_str,
1002                            "Open paren can not come after expression");
1003                     ret = TEP_ERRNO__INVALID_PAREN;
1004                     goto fail;
1005                 }
1006 
1007                 ret = process_filter(event, &arg, error_str, 0);
1008                 if (ret != TEP_ERRNO__UNBALANCED_PAREN) {
1009                     if (ret == 0) {
1010                         show_error(error_str,
1011                                "Unbalanced number of '('");
1012                         ret = TEP_ERRNO__UNBALANCED_PAREN;
1013                     }
1014                     goto fail;
1015                 }
1016                 ret = 0;
1017 
1018                 /* A not wants just one expression */
1019                 if (not) {
1020                     if (current_op)
1021                         goto fail_syntax;
1022                     *parg = arg;
1023                     return 0;
1024                 }
1025 
1026                 if (current_op)
1027                     ret = add_right(current_op, arg, error_str);
1028                 else
1029                     current_exp = arg;
1030 
1031                 if (ret < 0)
1032                     goto fail;
1033 
1034             } else { /* ')' */
1035                 if (!current_op && !current_exp)
1036                     goto fail_syntax;
1037 
1038                 /* Make sure everything is finished at this level */
1039                 if (current_exp && !check_op_done(current_exp))
1040                     goto fail_syntax;
1041                 if (current_op && !check_op_done(current_op))
1042                     goto fail_syntax;
1043 
1044                 if (current_op)
1045                     *parg = current_op;
1046                 else
1047                     *parg = current_exp;
1048                 free(token);
1049                 return TEP_ERRNO__UNBALANCED_PAREN;
1050             }
1051             break;
1052 
1053         case TEP_EVENT_OP:
1054             op_type = process_op(token, &btype, &ctype, &etype);
1055 
1056             /* All expect a left arg except for NOT */
1057             switch (op_type) {
1058             case OP_BOOL:
1059                 /* Logic ops need a left expression */
1060                 if (!current_exp && !current_op)
1061                     goto fail_syntax;
1062                 /* fall through */
1063             case OP_NOT:
1064                 /* logic only processes ops and exp */
1065                 if (left_item)
1066                     goto fail_syntax;
1067                 break;
1068             case OP_EXP:
1069             case OP_CMP:
1070                 if (!left_item)
1071                     goto fail_syntax;
1072                 break;
1073             case OP_NONE:
1074                 show_error(error_str,
1075                        "Unknown op token %s", token);
1076                 ret = TEP_ERRNO__UNKNOWN_TOKEN;
1077                 goto fail;
1078             }
1079 
1080             ret = 0;
1081             switch (op_type) {
1082             case OP_BOOL:
1083                 arg = create_arg_op(btype);
1084                 if (arg == NULL)
1085                     goto fail_alloc;
1086                 if (current_op)
1087                     ret = add_left(arg, current_op);
1088                 else
1089                     ret = add_left(arg, current_exp);
1090                 current_op = arg;
1091                 current_exp = NULL;
1092                 break;
1093 
1094             case OP_NOT:
1095                 arg = create_arg_op(btype);
1096                 if (arg == NULL)
1097                     goto fail_alloc;
1098                 if (current_op)
1099                     ret = add_right(current_op, arg, error_str);
1100                 if (ret < 0)
1101                     goto fail;
1102                 current_exp = arg;
1103                 ret = process_filter(event, &arg, error_str, 1);
1104                 if (ret < 0)
1105                     goto fail;
1106                 ret = add_right(current_exp, arg, error_str);
1107                 if (ret < 0)
1108                     goto fail;
1109                 break;
1110 
1111             case OP_EXP:
1112             case OP_CMP:
1113                 if (op_type == OP_EXP)
1114                     arg = create_arg_exp(etype);
1115                 else
1116                     arg = create_arg_cmp(ctype);
1117                 if (arg == NULL)
1118                     goto fail_alloc;
1119 
1120                 if (current_op)
1121                     ret = add_right(current_op, arg, error_str);
1122                 if (ret < 0)
1123                     goto fail;
1124                 ret = add_left(arg, left_item);
1125                 if (ret < 0) {
1126                     arg = NULL;
1127                     goto fail_syntax;
1128                 }
1129                 current_exp = arg;
1130                 break;
1131             default:
1132                 break;
1133             }
1134             arg = NULL;
1135             if (ret < 0)
1136                 goto fail_syntax;
1137             break;
1138         case TEP_EVENT_NONE:
1139             break;
1140         case TEP_EVENT_ERROR:
1141             goto fail_alloc;
1142         default:
1143             goto fail_syntax;
1144         }
1145     } while (type != TEP_EVENT_NONE);
1146 
1147     if (!current_op && !current_exp)
1148         goto fail_syntax;
1149 
1150     if (!current_op)
1151         current_op = current_exp;
1152 
1153     ret = collapse_tree(current_op, parg, error_str);
1154     /* collapse_tree() may free current_op, and updates parg accordingly */
1155     current_op = NULL;
1156     if (ret < 0)
1157         goto fail;
1158 
1159     free(token);
1160     return 0;
1161 
1162  fail_alloc:
1163     show_error(error_str, "failed to allocate filter arg");
1164     ret = TEP_ERRNO__MEM_ALLOC_FAILED;
1165     goto fail;
1166  fail_syntax:
1167     show_error(error_str, "Syntax error");
1168     ret = TEP_ERRNO__SYNTAX_ERROR;
1169  fail:
1170     free_arg(current_op);
1171     free_arg(current_exp);
1172     free_arg(arg);
1173     free(token);
1174     return ret;
1175 }
1176 
1177 static enum tep_errno
1178 process_event(struct tep_event *event, const char *filter_str,
1179           struct tep_filter_arg **parg, char *error_str)
1180 {
1181     int ret;
1182 
1183     init_input_buf(filter_str, strlen(filter_str));
1184 
1185     ret = process_filter(event, parg, error_str, 0);
1186     if (ret < 0)
1187         return ret;
1188 
1189     /* If parg is NULL, then make it into FALSE */
1190     if (!*parg) {
1191         *parg = allocate_arg();
1192         if (*parg == NULL)
1193             return TEP_ERRNO__MEM_ALLOC_FAILED;
1194 
1195         (*parg)->type = TEP_FILTER_ARG_BOOLEAN;
1196         (*parg)->boolean.value = TEP_FILTER_FALSE;
1197     }
1198 
1199     return 0;
1200 }
1201 
1202 static enum tep_errno
1203 filter_event(struct tep_event_filter *filter, struct tep_event *event,
1204          const char *filter_str, char *error_str)
1205 {
1206     struct tep_filter_type *filter_type;
1207     struct tep_filter_arg *arg;
1208     enum tep_errno ret;
1209 
1210     if (filter_str) {
1211         ret = process_event(event, filter_str, &arg, error_str);
1212         if (ret < 0)
1213             return ret;
1214 
1215     } else {
1216         /* just add a TRUE arg */
1217         arg = allocate_arg();
1218         if (arg == NULL)
1219             return TEP_ERRNO__MEM_ALLOC_FAILED;
1220 
1221         arg->type = TEP_FILTER_ARG_BOOLEAN;
1222         arg->boolean.value = TEP_FILTER_TRUE;
1223     }
1224 
1225     filter_type = add_filter_type(filter, event->id);
1226     if (filter_type == NULL) {
1227         free_arg(arg);
1228         return TEP_ERRNO__MEM_ALLOC_FAILED;
1229     }
1230 
1231     if (filter_type->filter)
1232         free_arg(filter_type->filter);
1233     filter_type->filter = arg;
1234 
1235     return 0;
1236 }
1237 
1238 static void filter_init_error_buf(struct tep_event_filter *filter)
1239 {
1240     /* clear buffer to reset show error */
1241     init_input_buf("", 0);
1242     filter->error_buffer[0] = '\0';
1243 }
1244 
1245 /**
1246  * tep_filter_add_filter_str - add a new filter
1247  * @filter: the event filter to add to
1248  * @filter_str: the filter string that contains the filter
1249  *
1250  * Returns 0 if the filter was successfully added or a
1251  * negative error code.  Use tep_filter_strerror() to see
1252  * actual error message in case of error.
1253  */
1254 enum tep_errno tep_filter_add_filter_str(struct tep_event_filter *filter,
1255                      const char *filter_str)
1256 {
1257     struct tep_handle *tep = filter->tep;
1258     struct event_list *event;
1259     struct event_list *events = NULL;
1260     const char *filter_start;
1261     const char *next_event;
1262     char *this_event;
1263     char *event_name = NULL;
1264     char *sys_name = NULL;
1265     char *sp;
1266     enum tep_errno rtn = 0; /* TEP_ERRNO__SUCCESS */
1267     int len;
1268     int ret;
1269 
1270     filter_init_error_buf(filter);
1271 
1272     filter_start = strchr(filter_str, ':');
1273     if (filter_start)
1274         len = filter_start - filter_str;
1275     else
1276         len = strlen(filter_str);
1277 
1278     do {
1279         next_event = strchr(filter_str, ',');
1280         if (next_event &&
1281             (!filter_start || next_event < filter_start))
1282             len = next_event - filter_str;
1283         else if (filter_start)
1284             len = filter_start - filter_str;
1285         else
1286             len = strlen(filter_str);
1287 
1288         this_event = malloc(len + 1);
1289         if (this_event == NULL) {
1290             /* This can only happen when events is NULL, but still */
1291             free_events(events);
1292             return TEP_ERRNO__MEM_ALLOC_FAILED;
1293         }
1294         memcpy(this_event, filter_str, len);
1295         this_event[len] = 0;
1296 
1297         if (next_event)
1298             next_event++;
1299 
1300         filter_str = next_event;
1301 
1302         sys_name = strtok_r(this_event, "/", &sp);
1303         event_name = strtok_r(NULL, "/", &sp);
1304 
1305         if (!sys_name) {
1306             /* This can only happen when events is NULL, but still */
1307             free_events(events);
1308             free(this_event);
1309             return TEP_ERRNO__FILTER_NOT_FOUND;
1310         }
1311 
1312         /* Find this event */
1313         ret = find_event(tep, &events, strim(sys_name), strim(event_name));
1314         if (ret < 0) {
1315             free_events(events);
1316             free(this_event);
1317             return ret;
1318         }
1319         free(this_event);
1320     } while (filter_str);
1321 
1322     /* Skip the ':' */
1323     if (filter_start)
1324         filter_start++;
1325 
1326     /* filter starts here */
1327     for (event = events; event; event = event->next) {
1328         ret = filter_event(filter, event->event, filter_start,
1329                    filter->error_buffer);
1330         /* Failures are returned if a parse error happened */
1331         if (ret < 0)
1332             rtn = ret;
1333 
1334         if (ret >= 0 && tep->test_filters) {
1335             char *test;
1336             test = tep_filter_make_string(filter, event->event->id);
1337             if (test) {
1338                 printf(" '%s: %s'\n", event->event->name, test);
1339                 free(test);
1340             }
1341         }
1342     }
1343 
1344     free_events(events);
1345 
1346     return rtn;
1347 }
1348 
1349 static void free_filter_type(struct tep_filter_type *filter_type)
1350 {
1351     free_arg(filter_type->filter);
1352 }
1353 
1354 /**
1355  * tep_filter_strerror - fill error message in a buffer
1356  * @filter: the event filter contains error
1357  * @err: the error code
1358  * @buf: the buffer to be filled in
1359  * @buflen: the size of the buffer
1360  *
1361  * Returns 0 if message was filled successfully, -1 if error
1362  */
1363 int tep_filter_strerror(struct tep_event_filter *filter, enum tep_errno err,
1364             char *buf, size_t buflen)
1365 {
1366     if (err <= __TEP_ERRNO__START || err >= __TEP_ERRNO__END)
1367         return -1;
1368 
1369     if (strlen(filter->error_buffer) > 0) {
1370         size_t len = snprintf(buf, buflen, "%s", filter->error_buffer);
1371 
1372         if (len > buflen)
1373             return -1;
1374         return 0;
1375     }
1376 
1377     return tep_strerror(filter->tep, err, buf, buflen);
1378 }
1379 
1380 /**
1381  * tep_filter_remove_event - remove a filter for an event
1382  * @filter: the event filter to remove from
1383  * @event_id: the event to remove a filter for
1384  *
1385  * Removes the filter saved for an event defined by @event_id
1386  * from the @filter.
1387  *
1388  * Returns 1: if an event was removed
1389  *   0: if the event was not found
1390  */
1391 int tep_filter_remove_event(struct tep_event_filter *filter,
1392                 int event_id)
1393 {
1394     struct tep_filter_type *filter_type;
1395     unsigned long len;
1396 
1397     if (!filter->filters)
1398         return 0;
1399 
1400     filter_type = find_filter_type(filter, event_id);
1401 
1402     if (!filter_type)
1403         return 0;
1404 
1405     free_filter_type(filter_type);
1406 
1407     /* The filter_type points into the event_filters array */
1408     len = (unsigned long)(filter->event_filters + filter->filters) -
1409         (unsigned long)(filter_type + 1);
1410 
1411     memmove(filter_type, filter_type + 1, len);
1412     filter->filters--;
1413 
1414     memset(&filter->event_filters[filter->filters], 0,
1415            sizeof(*filter_type));
1416 
1417     return 1;
1418 }
1419 
1420 /**
1421  * tep_filter_reset - clear all filters in a filter
1422  * @filter: the event filter to reset
1423  *
1424  * Removes all filters from a filter and resets it.
1425  */
1426 void tep_filter_reset(struct tep_event_filter *filter)
1427 {
1428     int i;
1429 
1430     for (i = 0; i < filter->filters; i++)
1431         free_filter_type(&filter->event_filters[i]);
1432 
1433     free(filter->event_filters);
1434     filter->filters = 0;
1435     filter->event_filters = NULL;
1436 }
1437 
1438 void tep_filter_free(struct tep_event_filter *filter)
1439 {
1440     tep_unref(filter->tep);
1441 
1442     tep_filter_reset(filter);
1443 
1444     free(filter);
1445 }
1446 
1447 static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg);
1448 
1449 static int copy_filter_type(struct tep_event_filter *filter,
1450                 struct tep_event_filter *source,
1451                 struct tep_filter_type *filter_type)
1452 {
1453     struct tep_filter_arg *arg;
1454     struct tep_event *event;
1455     const char *sys;
1456     const char *name;
1457     char *str;
1458 
1459     /* Can't assume that the tep's are the same */
1460     sys = filter_type->event->system;
1461     name = filter_type->event->name;
1462     event = tep_find_event_by_name(filter->tep, sys, name);
1463     if (!event)
1464         return -1;
1465 
1466     str = arg_to_str(source, filter_type->filter);
1467     if (!str)
1468         return -1;
1469 
1470     if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
1471         /* Add trivial event */
1472         arg = allocate_arg();
1473         if (arg == NULL) {
1474             free(str);
1475             return -1;
1476         }
1477 
1478         arg->type = TEP_FILTER_ARG_BOOLEAN;
1479         if (strcmp(str, "TRUE") == 0)
1480             arg->boolean.value = 1;
1481         else
1482             arg->boolean.value = 0;
1483 
1484         filter_type = add_filter_type(filter, event->id);
1485         if (filter_type == NULL) {
1486             free(str);
1487             free_arg(arg);
1488             return -1;
1489         }
1490 
1491         filter_type->filter = arg;
1492 
1493         free(str);
1494         return 0;
1495     }
1496 
1497     filter_event(filter, event, str, NULL);
1498     free(str);
1499 
1500     return 0;
1501 }
1502 
1503 /**
1504  * tep_filter_copy - copy a filter using another filter
1505  * @dest - the filter to copy to
1506  * @source - the filter to copy from
1507  *
1508  * Returns 0 on success and -1 if not all filters were copied
1509  */
1510 int tep_filter_copy(struct tep_event_filter *dest, struct tep_event_filter *source)
1511 {
1512     int ret = 0;
1513     int i;
1514 
1515     tep_filter_reset(dest);
1516 
1517     for (i = 0; i < source->filters; i++) {
1518         if (copy_filter_type(dest, source, &source->event_filters[i]))
1519             ret = -1;
1520     }
1521     return ret;
1522 }
1523 
1524 static int test_filter(struct tep_event *event, struct tep_filter_arg *arg,
1525                struct tep_record *record, enum tep_errno *err);
1526 
1527 static const char *
1528 get_comm(struct tep_event *event, struct tep_record *record)
1529 {
1530     const char *comm;
1531     int pid;
1532 
1533     pid = tep_data_pid(event->tep, record);
1534     comm = tep_data_comm_from_pid(event->tep, pid);
1535     return comm;
1536 }
1537 
1538 static unsigned long long
1539 get_value(struct tep_event *event,
1540       struct tep_format_field *field, struct tep_record *record)
1541 {
1542     unsigned long long val;
1543 
1544     /* Handle our dummy "comm" field */
1545     if (field == &comm) {
1546         const char *name;
1547 
1548         name = get_comm(event, record);
1549         return (unsigned long)name;
1550     }
1551 
1552     /* Handle our dummy "cpu" field */
1553     if (field == &cpu)
1554         return record->cpu;
1555 
1556     tep_read_number_field(field, record->data, &val);
1557 
1558     if (!(field->flags & TEP_FIELD_IS_SIGNED))
1559         return val;
1560 
1561     switch (field->size) {
1562     case 1:
1563         return (char)val;
1564     case 2:
1565         return (short)val;
1566     case 4:
1567         return (int)val;
1568     case 8:
1569         return (long long)val;
1570     }
1571     return val;
1572 }
1573 
1574 static unsigned long long
1575 get_arg_value(struct tep_event *event, struct tep_filter_arg *arg,
1576           struct tep_record *record, enum tep_errno *err);
1577 
1578 static unsigned long long
1579 get_exp_value(struct tep_event *event, struct tep_filter_arg *arg,
1580           struct tep_record *record, enum tep_errno *err)
1581 {
1582     unsigned long long lval, rval;
1583 
1584     lval = get_arg_value(event, arg->exp.left, record, err);
1585     rval = get_arg_value(event, arg->exp.right, record, err);
1586 
1587     if (*err) {
1588         /*
1589          * There was an error, no need to process anymore.
1590          */
1591         return 0;
1592     }
1593 
1594     switch (arg->exp.type) {
1595     case TEP_FILTER_EXP_ADD:
1596         return lval + rval;
1597 
1598     case TEP_FILTER_EXP_SUB:
1599         return lval - rval;
1600 
1601     case TEP_FILTER_EXP_MUL:
1602         return lval * rval;
1603 
1604     case TEP_FILTER_EXP_DIV:
1605         return lval / rval;
1606 
1607     case TEP_FILTER_EXP_MOD:
1608         return lval % rval;
1609 
1610     case TEP_FILTER_EXP_RSHIFT:
1611         return lval >> rval;
1612 
1613     case TEP_FILTER_EXP_LSHIFT:
1614         return lval << rval;
1615 
1616     case TEP_FILTER_EXP_AND:
1617         return lval & rval;
1618 
1619     case TEP_FILTER_EXP_OR:
1620         return lval | rval;
1621 
1622     case TEP_FILTER_EXP_XOR:
1623         return lval ^ rval;
1624 
1625     case TEP_FILTER_EXP_NOT:
1626     default:
1627         if (!*err)
1628             *err = TEP_ERRNO__INVALID_EXP_TYPE;
1629     }
1630     return 0;
1631 }
1632 
1633 static unsigned long long
1634 get_arg_value(struct tep_event *event, struct tep_filter_arg *arg,
1635           struct tep_record *record, enum tep_errno *err)
1636 {
1637     switch (arg->type) {
1638     case TEP_FILTER_ARG_FIELD:
1639         return get_value(event, arg->field.field, record);
1640 
1641     case TEP_FILTER_ARG_VALUE:
1642         if (arg->value.type != TEP_FILTER_NUMBER) {
1643             if (!*err)
1644                 *err = TEP_ERRNO__NOT_A_NUMBER;
1645         }
1646         return arg->value.val;
1647 
1648     case TEP_FILTER_ARG_EXP:
1649         return get_exp_value(event, arg, record, err);
1650 
1651     default:
1652         if (!*err)
1653             *err = TEP_ERRNO__INVALID_ARG_TYPE;
1654     }
1655     return 0;
1656 }
1657 
1658 static int test_num(struct tep_event *event, struct tep_filter_arg *arg,
1659             struct tep_record *record, enum tep_errno *err)
1660 {
1661     unsigned long long lval, rval;
1662 
1663     lval = get_arg_value(event, arg->num.left, record, err);
1664     rval = get_arg_value(event, arg->num.right, record, err);
1665 
1666     if (*err) {
1667         /*
1668          * There was an error, no need to process anymore.
1669          */
1670         return 0;
1671     }
1672 
1673     switch (arg->num.type) {
1674     case TEP_FILTER_CMP_EQ:
1675         return lval == rval;
1676 
1677     case TEP_FILTER_CMP_NE:
1678         return lval != rval;
1679 
1680     case TEP_FILTER_CMP_GT:
1681         return lval > rval;
1682 
1683     case TEP_FILTER_CMP_LT:
1684         return lval < rval;
1685 
1686     case TEP_FILTER_CMP_GE:
1687         return lval >= rval;
1688 
1689     case TEP_FILTER_CMP_LE:
1690         return lval <= rval;
1691 
1692     default:
1693         if (!*err)
1694             *err = TEP_ERRNO__ILLEGAL_INTEGER_CMP;
1695         return 0;
1696     }
1697 }
1698 
1699 static const char *get_field_str(struct tep_filter_arg *arg, struct tep_record *record)
1700 {
1701     struct tep_event *event;
1702     struct tep_handle *tep;
1703     unsigned long long addr;
1704     const char *val = NULL;
1705     unsigned int size;
1706     char hex[64];
1707 
1708     /* If the field is not a string convert it */
1709     if (arg->str.field->flags & TEP_FIELD_IS_STRING) {
1710         val = record->data + arg->str.field->offset;
1711         size = arg->str.field->size;
1712 
1713         if (arg->str.field->flags & TEP_FIELD_IS_DYNAMIC) {
1714             addr = *(unsigned int *)val;
1715             size = addr >> 16;
1716             addr &= 0xffff;
1717             if (arg->str.field->flags & TEP_FIELD_IS_RELATIVE)
1718                 addr += arg->str.field->offset + arg->str.field->size;
1719             val = record->data + addr;
1720         }
1721 
1722         /*
1723          * We need to copy the data since we can't be sure the field
1724          * is null terminated.
1725          */
1726         if (*(val + size - 1)) {
1727             /* copy it */
1728             memcpy(arg->str.buffer, val, arg->str.field->size);
1729             /* the buffer is already NULL terminated */
1730             val = arg->str.buffer;
1731         }
1732 
1733     } else {
1734         event = arg->str.field->event;
1735         tep = event->tep;
1736         addr = get_value(event, arg->str.field, record);
1737 
1738         if (arg->str.field->flags & (TEP_FIELD_IS_POINTER | TEP_FIELD_IS_LONG))
1739             /* convert to a kernel symbol */
1740             val = tep_find_function(tep, addr);
1741 
1742         if (val == NULL) {
1743             /* just use the hex of the string name */
1744             snprintf(hex, 64, "0x%llx", addr);
1745             val = hex;
1746         }
1747     }
1748 
1749     return val;
1750 }
1751 
1752 static int test_str(struct tep_event *event, struct tep_filter_arg *arg,
1753             struct tep_record *record, enum tep_errno *err)
1754 {
1755     const char *val;
1756 
1757     if (arg->str.field == &comm)
1758         val = get_comm(event, record);
1759     else
1760         val = get_field_str(arg, record);
1761 
1762     switch (arg->str.type) {
1763     case TEP_FILTER_CMP_MATCH:
1764         return strcmp(val, arg->str.val) == 0;
1765 
1766     case TEP_FILTER_CMP_NOT_MATCH:
1767         return strcmp(val, arg->str.val) != 0;
1768 
1769     case TEP_FILTER_CMP_REGEX:
1770         /* Returns zero on match */
1771         return !regexec(&arg->str.reg, val, 0, NULL, 0);
1772 
1773     case TEP_FILTER_CMP_NOT_REGEX:
1774         return regexec(&arg->str.reg, val, 0, NULL, 0);
1775 
1776     default:
1777         if (!*err)
1778             *err = TEP_ERRNO__ILLEGAL_STRING_CMP;
1779         return 0;
1780     }
1781 }
1782 
1783 static int test_op(struct tep_event *event, struct tep_filter_arg *arg,
1784            struct tep_record *record, enum tep_errno *err)
1785 {
1786     switch (arg->op.type) {
1787     case TEP_FILTER_OP_AND:
1788         return test_filter(event, arg->op.left, record, err) &&
1789             test_filter(event, arg->op.right, record, err);
1790 
1791     case TEP_FILTER_OP_OR:
1792         return test_filter(event, arg->op.left, record, err) ||
1793             test_filter(event, arg->op.right, record, err);
1794 
1795     case TEP_FILTER_OP_NOT:
1796         return !test_filter(event, arg->op.right, record, err);
1797 
1798     default:
1799         if (!*err)
1800             *err = TEP_ERRNO__INVALID_OP_TYPE;
1801         return 0;
1802     }
1803 }
1804 
1805 static int test_filter(struct tep_event *event, struct tep_filter_arg *arg,
1806                struct tep_record *record, enum tep_errno *err)
1807 {
1808     if (*err) {
1809         /*
1810          * There was an error, no need to process anymore.
1811          */
1812         return 0;
1813     }
1814 
1815     switch (arg->type) {
1816     case TEP_FILTER_ARG_BOOLEAN:
1817         /* easy case */
1818         return arg->boolean.value;
1819 
1820     case TEP_FILTER_ARG_OP:
1821         return test_op(event, arg, record, err);
1822 
1823     case TEP_FILTER_ARG_NUM:
1824         return test_num(event, arg, record, err);
1825 
1826     case TEP_FILTER_ARG_STR:
1827         return test_str(event, arg, record, err);
1828 
1829     case TEP_FILTER_ARG_EXP:
1830     case TEP_FILTER_ARG_VALUE:
1831     case TEP_FILTER_ARG_FIELD:
1832         /*
1833          * Expressions, fields and values evaluate
1834          * to true if they return non zero
1835          */
1836         return !!get_arg_value(event, arg, record, err);
1837 
1838     default:
1839         if (!*err)
1840             *err = TEP_ERRNO__INVALID_ARG_TYPE;
1841         return 0;
1842     }
1843 }
1844 
1845 /**
1846  * tep_event_filtered - return true if event has filter
1847  * @filter: filter struct with filter information
1848  * @event_id: event id to test if filter exists
1849  *
1850  * Returns 1 if filter found for @event_id
1851  *   otherwise 0;
1852  */
1853 int tep_event_filtered(struct tep_event_filter *filter, int event_id)
1854 {
1855     struct tep_filter_type *filter_type;
1856 
1857     if (!filter->filters)
1858         return 0;
1859 
1860     filter_type = find_filter_type(filter, event_id);
1861 
1862     return filter_type ? 1 : 0;
1863 }
1864 
1865 /**
1866  * tep_filter_match - test if a record matches a filter
1867  * @filter: filter struct with filter information
1868  * @record: the record to test against the filter
1869  *
1870  * Returns: match result or error code (prefixed with TEP_ERRNO__)
1871  * FILTER_MATCH - filter found for event and @record matches
1872  * FILTER_MISS  - filter found for event and @record does not match
1873  * FILTER_NOT_FOUND - no filter found for @record's event
1874  * NO_FILTER - if no filters exist
1875  * otherwise - error occurred during test
1876  */
1877 enum tep_errno tep_filter_match(struct tep_event_filter *filter,
1878                 struct tep_record *record)
1879 {
1880     struct tep_handle *tep = filter->tep;
1881     struct tep_filter_type *filter_type;
1882     int event_id;
1883     int ret;
1884     enum tep_errno err = 0;
1885 
1886     filter_init_error_buf(filter);
1887 
1888     if (!filter->filters)
1889         return TEP_ERRNO__NO_FILTER;
1890 
1891     event_id = tep_data_type(tep, record);
1892 
1893     filter_type = find_filter_type(filter, event_id);
1894     if (!filter_type)
1895         return TEP_ERRNO__FILTER_NOT_FOUND;
1896 
1897     ret = test_filter(filter_type->event, filter_type->filter, record, &err);
1898     if (err)
1899         return err;
1900 
1901     return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS;
1902 }
1903 
1904 static char *op_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
1905 {
1906     char *str = NULL;
1907     char *left = NULL;
1908     char *right = NULL;
1909     char *op = NULL;
1910     int left_val = -1;
1911     int right_val = -1;
1912     int val;
1913 
1914     switch (arg->op.type) {
1915     case TEP_FILTER_OP_AND:
1916         op = "&&";
1917         /* fall through */
1918     case TEP_FILTER_OP_OR:
1919         if (!op)
1920             op = "||";
1921 
1922         left = arg_to_str(filter, arg->op.left);
1923         right = arg_to_str(filter, arg->op.right);
1924         if (!left || !right)
1925             break;
1926 
1927         /* Try to consolidate boolean values */
1928         if (strcmp(left, "TRUE") == 0)
1929             left_val = 1;
1930         else if (strcmp(left, "FALSE") == 0)
1931             left_val = 0;
1932 
1933         if (strcmp(right, "TRUE") == 0)
1934             right_val = 1;
1935         else if (strcmp(right, "FALSE") == 0)
1936             right_val = 0;
1937 
1938         if (left_val >= 0) {
1939             if ((arg->op.type == TEP_FILTER_OP_AND && !left_val) ||
1940                 (arg->op.type == TEP_FILTER_OP_OR && left_val)) {
1941                 /* Just return left value */
1942                 str = left;
1943                 left = NULL;
1944                 break;
1945             }
1946             if (right_val >= 0) {
1947                 /* just evaluate this. */
1948                 val = 0;
1949                 switch (arg->op.type) {
1950                 case TEP_FILTER_OP_AND:
1951                     val = left_val && right_val;
1952                     break;
1953                 case TEP_FILTER_OP_OR:
1954                     val = left_val || right_val;
1955                     break;
1956                 default:
1957                     break;
1958                 }
1959                 if (asprintf(&str, val ? "TRUE" : "FALSE") < 0)
1960                     str = NULL;
1961                 break;
1962             }
1963         }
1964         if (right_val >= 0) {
1965             if ((arg->op.type == TEP_FILTER_OP_AND && !right_val) ||
1966                 (arg->op.type == TEP_FILTER_OP_OR && right_val)) {
1967                 /* Just return right value */
1968                 str = right;
1969                 right = NULL;
1970                 break;
1971             }
1972             /* The right value is meaningless */
1973             str = left;
1974             left = NULL;
1975             break;
1976         }
1977 
1978         if (asprintf(&str, "(%s) %s (%s)", left, op, right) < 0)
1979             str = NULL;
1980         break;
1981 
1982     case TEP_FILTER_OP_NOT:
1983         op = "!";
1984         right = arg_to_str(filter, arg->op.right);
1985         if (!right)
1986             break;
1987 
1988         /* See if we can consolidate */
1989         if (strcmp(right, "TRUE") == 0)
1990             right_val = 1;
1991         else if (strcmp(right, "FALSE") == 0)
1992             right_val = 0;
1993         if (right_val >= 0) {
1994             /* just return the opposite */
1995             if (asprintf(&str, right_val ? "FALSE" : "TRUE") < 0)
1996                 str = NULL;
1997             break;
1998         }
1999         if (asprintf(&str, "%s(%s)", op, right) < 0)
2000             str = NULL;
2001         break;
2002 
2003     default:
2004         /* ?? */
2005         break;
2006     }
2007     free(left);
2008     free(right);
2009     return str;
2010 }
2011 
2012 static char *val_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2013 {
2014     char *str = NULL;
2015 
2016     if (asprintf(&str, "%lld", arg->value.val) < 0)
2017         str = NULL;
2018 
2019     return str;
2020 }
2021 
2022 static char *field_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2023 {
2024     return strdup(arg->field.field->name);
2025 }
2026 
2027 static char *exp_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2028 {
2029     char *lstr;
2030     char *rstr;
2031     char *op;
2032     char *str = NULL;
2033 
2034     lstr = arg_to_str(filter, arg->exp.left);
2035     rstr = arg_to_str(filter, arg->exp.right);
2036     if (!lstr || !rstr)
2037         goto out;
2038 
2039     switch (arg->exp.type) {
2040     case TEP_FILTER_EXP_ADD:
2041         op = "+";
2042         break;
2043     case TEP_FILTER_EXP_SUB:
2044         op = "-";
2045         break;
2046     case TEP_FILTER_EXP_MUL:
2047         op = "*";
2048         break;
2049     case TEP_FILTER_EXP_DIV:
2050         op = "/";
2051         break;
2052     case TEP_FILTER_EXP_MOD:
2053         op = "%";
2054         break;
2055     case TEP_FILTER_EXP_RSHIFT:
2056         op = ">>";
2057         break;
2058     case TEP_FILTER_EXP_LSHIFT:
2059         op = "<<";
2060         break;
2061     case TEP_FILTER_EXP_AND:
2062         op = "&";
2063         break;
2064     case TEP_FILTER_EXP_OR:
2065         op = "|";
2066         break;
2067     case TEP_FILTER_EXP_XOR:
2068         op = "^";
2069         break;
2070     default:
2071         op = "[ERROR IN EXPRESSION TYPE]";
2072         break;
2073     }
2074 
2075     if (asprintf(&str, "%s %s %s", lstr, op, rstr) < 0)
2076         str = NULL;
2077 out:
2078     free(lstr);
2079     free(rstr);
2080 
2081     return str;
2082 }
2083 
2084 static char *num_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2085 {
2086     char *lstr;
2087     char *rstr;
2088     char *str = NULL;
2089     char *op = NULL;
2090 
2091     lstr = arg_to_str(filter, arg->num.left);
2092     rstr = arg_to_str(filter, arg->num.right);
2093     if (!lstr || !rstr)
2094         goto out;
2095 
2096     switch (arg->num.type) {
2097     case TEP_FILTER_CMP_EQ:
2098         op = "==";
2099         /* fall through */
2100     case TEP_FILTER_CMP_NE:
2101         if (!op)
2102             op = "!=";
2103         /* fall through */
2104     case TEP_FILTER_CMP_GT:
2105         if (!op)
2106             op = ">";
2107         /* fall through */
2108     case TEP_FILTER_CMP_LT:
2109         if (!op)
2110             op = "<";
2111         /* fall through */
2112     case TEP_FILTER_CMP_GE:
2113         if (!op)
2114             op = ">=";
2115         /* fall through */
2116     case TEP_FILTER_CMP_LE:
2117         if (!op)
2118             op = "<=";
2119 
2120         if (asprintf(&str, "%s %s %s", lstr, op, rstr) < 0)
2121             str = NULL;
2122         break;
2123 
2124     default:
2125         /* ?? */
2126         break;
2127     }
2128 
2129 out:
2130     free(lstr);
2131     free(rstr);
2132     return str;
2133 }
2134 
2135 static char *str_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2136 {
2137     char *str = NULL;
2138     char *op = NULL;
2139 
2140     switch (arg->str.type) {
2141     case TEP_FILTER_CMP_MATCH:
2142         op = "==";
2143         /* fall through */
2144     case TEP_FILTER_CMP_NOT_MATCH:
2145         if (!op)
2146             op = "!=";
2147         /* fall through */
2148     case TEP_FILTER_CMP_REGEX:
2149         if (!op)
2150             op = "=~";
2151         /* fall through */
2152     case TEP_FILTER_CMP_NOT_REGEX:
2153         if (!op)
2154             op = "!~";
2155 
2156         if (asprintf(&str, "%s %s \"%s\"",
2157              arg->str.field->name, op, arg->str.val) < 0)
2158             str = NULL;
2159         break;
2160 
2161     default:
2162         /* ?? */
2163         break;
2164     }
2165     return str;
2166 }
2167 
2168 static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2169 {
2170     char *str = NULL;
2171 
2172     switch (arg->type) {
2173     case TEP_FILTER_ARG_BOOLEAN:
2174         if (asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE") < 0)
2175             str = NULL;
2176         return str;
2177 
2178     case TEP_FILTER_ARG_OP:
2179         return op_to_str(filter, arg);
2180 
2181     case TEP_FILTER_ARG_NUM:
2182         return num_to_str(filter, arg);
2183 
2184     case TEP_FILTER_ARG_STR:
2185         return str_to_str(filter, arg);
2186 
2187     case TEP_FILTER_ARG_VALUE:
2188         return val_to_str(filter, arg);
2189 
2190     case TEP_FILTER_ARG_FIELD:
2191         return field_to_str(filter, arg);
2192 
2193     case TEP_FILTER_ARG_EXP:
2194         return exp_to_str(filter, arg);
2195 
2196     default:
2197         /* ?? */
2198         return NULL;
2199     }
2200 
2201 }
2202 
2203 /**
2204  * tep_filter_make_string - return a string showing the filter
2205  * @filter: filter struct with filter information
2206  * @event_id: the event id to return the filter string with
2207  *
2208  * Returns a string that displays the filter contents.
2209  *  This string must be freed with free(str).
2210  *  NULL is returned if no filter is found or allocation failed.
2211  */
2212 char *
2213 tep_filter_make_string(struct tep_event_filter *filter, int event_id)
2214 {
2215     struct tep_filter_type *filter_type;
2216 
2217     if (!filter->filters)
2218         return NULL;
2219 
2220     filter_type = find_filter_type(filter, event_id);
2221 
2222     if (!filter_type)
2223         return NULL;
2224 
2225     return arg_to_str(filter, filter_type->filter);
2226 }
2227 
2228 /**
2229  * tep_filter_compare - compare two filters and return if they are the same
2230  * @filter1: Filter to compare with @filter2
2231  * @filter2: Filter to compare with @filter1
2232  *
2233  * Returns:
2234  *  1 if the two filters hold the same content.
2235  *  0 if they do not.
2236  */
2237 int tep_filter_compare(struct tep_event_filter *filter1, struct tep_event_filter *filter2)
2238 {
2239     struct tep_filter_type *filter_type1;
2240     struct tep_filter_type *filter_type2;
2241     char *str1, *str2;
2242     int result;
2243     int i;
2244 
2245     /* Do the easy checks first */
2246     if (filter1->filters != filter2->filters)
2247         return 0;
2248     if (!filter1->filters && !filter2->filters)
2249         return 1;
2250 
2251     /*
2252      * Now take a look at each of the events to see if they have the same
2253      * filters to them.
2254      */
2255     for (i = 0; i < filter1->filters; i++) {
2256         filter_type1 = &filter1->event_filters[i];
2257         filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2258         if (!filter_type2)
2259             break;
2260         if (filter_type1->filter->type != filter_type2->filter->type)
2261             break;
2262         /* The best way to compare complex filters is with strings */
2263         str1 = arg_to_str(filter1, filter_type1->filter);
2264         str2 = arg_to_str(filter2, filter_type2->filter);
2265         if (str1 && str2)
2266             result = strcmp(str1, str2) != 0;
2267         else
2268             /* bail out if allocation fails */
2269             result = 1;
2270 
2271         free(str1);
2272         free(str2);
2273         if (result)
2274             break;
2275     }
2276 
2277     if (i < filter1->filters)
2278         return 0;
2279     return 1;
2280 }
2281