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