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