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