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