root/tools/lib/traceevent/parse-filter.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. show_error
  2. free_token
  3. read_token
  4. filter_cmp
  5. find_filter_type
  6. add_filter_type
  7. tep_filter_alloc
  8. allocate_arg
  9. free_arg
  10. add_event
  11. event_match
  12. find_event
  13. free_events
  14. create_arg_item
  15. create_arg_op
  16. create_arg_exp
  17. create_arg_cmp
  18. add_right
  19. rotate_op_right
  20. add_left
  21. process_op
  22. check_op_done
  23. reparent_op_arg
  24. test_arg
  25. collapse_tree
  26. process_filter
  27. process_event
  28. filter_event
  29. filter_init_error_buf
  30. tep_filter_add_filter_str
  31. free_filter_type
  32. tep_filter_strerror
  33. tep_filter_remove_event
  34. tep_filter_reset
  35. tep_filter_free
  36. copy_filter_type
  37. tep_filter_copy
  38. get_comm
  39. get_value
  40. get_exp_value
  41. get_arg_value
  42. test_num
  43. get_field_str
  44. test_str
  45. test_op
  46. test_filter
  47. tep_event_filtered
  48. tep_filter_match
  49. op_to_str
  50. val_to_str
  51. field_to_str
  52. exp_to_str
  53. num_to_str
  54. str_to_str
  55. arg_to_str
  56. tep_filter_make_string
  57. tep_filter_compare

   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 
  20 static struct tep_format_field comm = {
  21         .name = "COMM",
  22 };
  23 
  24 static struct tep_format_field cpu = {
  25         .name = "CPU",
  26 };
  27 
  28 struct event_list {
  29         struct event_list       *next;
  30         struct tep_event        *event;
  31 };
  32 
  33 static 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 
  60 static void free_token(char *token)
  61 {
  62         tep_free_token(token);
  63 }
  64 
  65 static 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 
  96 static 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 
 110 static struct tep_filter_type *
 111 find_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 
 126 static struct tep_filter_type *
 127 add_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  */
 169 struct 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 
 184 static struct tep_filter_arg *allocate_arg(void)
 185 {
 186         return calloc(1, sizeof(struct tep_filter_arg));
 187 }
 188 
 189 static 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 
 231 static 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 
 246 static 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 
 258 static enum tep_errno
 259 find_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 
 325 static 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 
 336 static enum tep_errno
 337 create_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 
 398 static struct tep_filter_arg *
 399 create_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 
 413 static struct tep_filter_arg *
 414 create_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 
 428 static struct tep_filter_arg *
 429 create_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 
 444 static enum tep_errno
 445 add_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 
 609 static struct tep_filter_arg *
 610 rotate_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 
 619 static 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 
 647 enum op_type {
 648         OP_NONE,
 649         OP_BOOL,
 650         OP_NOT,
 651         OP_EXP,
 652         OP_CMP,
 653 };
 654 
 655 static 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 
 724 static 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 
 749 enum filter_vals {
 750         FILTER_VAL_NORM,
 751         FILTER_VAL_FALSE,
 752         FILTER_VAL_TRUE,
 753 };
 754 
 755 static enum tep_errno
 756 reparent_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) */
 808 static 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 */
 908 static 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 
 942 static enum tep_errno
 943 process_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 
1182 static enum tep_errno
1183 process_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 
1207 static enum tep_errno
1208 filter_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 
1243 static 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  */
1259 enum 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 
1354 static 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  */
1368 int 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  */
1396 int 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  */
1431 void 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 
1443 void 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 
1452 static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg);
1453 
1454 static 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  */
1515 int 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 
1529 static int test_filter(struct tep_event *event, struct tep_filter_arg *arg,
1530                        struct tep_record *record, enum tep_errno *err);
1531 
1532 static const char *
1533 get_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 
1543 static unsigned long long
1544 get_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 
1579 static unsigned long long
1580 get_arg_value(struct tep_event *event, struct tep_filter_arg *arg,
1581               struct tep_record *record, enum tep_errno *err);
1582 
1583 static unsigned long long
1584 get_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 
1638 static unsigned long long
1639 get_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 
1663 static 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 
1704 static 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 
1754 static 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 
1785 static 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 
1807 static 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  */
1855 int 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  */
1879 enum 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 
1906 static 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                                 asprintf(&str, val ? "TRUE" : "FALSE");
1962                                 break;
1963                         }
1964                 }
1965                 if (right_val >= 0) {
1966                         if ((arg->op.type == TEP_FILTER_OP_AND && !right_val) ||
1967                             (arg->op.type == TEP_FILTER_OP_OR && right_val)) {
1968                                 /* Just return right value */
1969                                 str = right;
1970                                 right = NULL;
1971                                 break;
1972                         }
1973                         /* The right value is meaningless */
1974                         str = left;
1975                         left = NULL;
1976                         break;
1977                 }
1978 
1979                 asprintf(&str, "(%s) %s (%s)", left, op, right);
1980                 break;
1981 
1982         case TEP_FILTER_OP_NOT:
1983                 op = "!";
1984                 right = arg_to_str(filter, arg->op.right);
1985                 if (!right)
1986                         break;
1987 
1988                 /* See if we can consolidate */
1989                 if (strcmp(right, "TRUE") == 0)
1990                         right_val = 1;
1991                 else if (strcmp(right, "FALSE") == 0)
1992                         right_val = 0;
1993                 if (right_val >= 0) {
1994                         /* just return the opposite */
1995                         asprintf(&str, right_val ? "FALSE" : "TRUE");
1996                         break;
1997                 }
1998                 asprintf(&str, "%s(%s)", op, right);
1999                 break;
2000 
2001         default:
2002                 /* ?? */
2003                 break;
2004         }
2005         free(left);
2006         free(right);
2007         return str;
2008 }
2009 
2010 static char *val_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2011 {
2012         char *str = NULL;
2013 
2014         asprintf(&str, "%lld", arg->value.val);
2015 
2016         return str;
2017 }
2018 
2019 static char *field_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2020 {
2021         return strdup(arg->field.field->name);
2022 }
2023 
2024 static char *exp_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2025 {
2026         char *lstr;
2027         char *rstr;
2028         char *op;
2029         char *str = NULL;
2030 
2031         lstr = arg_to_str(filter, arg->exp.left);
2032         rstr = arg_to_str(filter, arg->exp.right);
2033         if (!lstr || !rstr)
2034                 goto out;
2035 
2036         switch (arg->exp.type) {
2037         case TEP_FILTER_EXP_ADD:
2038                 op = "+";
2039                 break;
2040         case TEP_FILTER_EXP_SUB:
2041                 op = "-";
2042                 break;
2043         case TEP_FILTER_EXP_MUL:
2044                 op = "*";
2045                 break;
2046         case TEP_FILTER_EXP_DIV:
2047                 op = "/";
2048                 break;
2049         case TEP_FILTER_EXP_MOD:
2050                 op = "%";
2051                 break;
2052         case TEP_FILTER_EXP_RSHIFT:
2053                 op = ">>";
2054                 break;
2055         case TEP_FILTER_EXP_LSHIFT:
2056                 op = "<<";
2057                 break;
2058         case TEP_FILTER_EXP_AND:
2059                 op = "&";
2060                 break;
2061         case TEP_FILTER_EXP_OR:
2062                 op = "|";
2063                 break;
2064         case TEP_FILTER_EXP_XOR:
2065                 op = "^";
2066                 break;
2067         default:
2068                 op = "[ERROR IN EXPRESSION TYPE]";
2069                 break;
2070         }
2071 
2072         asprintf(&str, "%s %s %s", lstr, op, rstr);
2073 out:
2074         free(lstr);
2075         free(rstr);
2076 
2077         return str;
2078 }
2079 
2080 static char *num_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2081 {
2082         char *lstr;
2083         char *rstr;
2084         char *str = NULL;
2085         char *op = NULL;
2086 
2087         lstr = arg_to_str(filter, arg->num.left);
2088         rstr = arg_to_str(filter, arg->num.right);
2089         if (!lstr || !rstr)
2090                 goto out;
2091 
2092         switch (arg->num.type) {
2093         case TEP_FILTER_CMP_EQ:
2094                 op = "==";
2095                 /* fall through */
2096         case TEP_FILTER_CMP_NE:
2097                 if (!op)
2098                         op = "!=";
2099                 /* fall through */
2100         case TEP_FILTER_CMP_GT:
2101                 if (!op)
2102                         op = ">";
2103                 /* fall through */
2104         case TEP_FILTER_CMP_LT:
2105                 if (!op)
2106                         op = "<";
2107                 /* fall through */
2108         case TEP_FILTER_CMP_GE:
2109                 if (!op)
2110                         op = ">=";
2111                 /* fall through */
2112         case TEP_FILTER_CMP_LE:
2113                 if (!op)
2114                         op = "<=";
2115 
2116                 asprintf(&str, "%s %s %s", lstr, op, rstr);
2117                 break;
2118 
2119         default:
2120                 /* ?? */
2121                 break;
2122         }
2123 
2124 out:
2125         free(lstr);
2126         free(rstr);
2127         return str;
2128 }
2129 
2130 static char *str_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2131 {
2132         char *str = NULL;
2133         char *op = NULL;
2134 
2135         switch (arg->str.type) {
2136         case TEP_FILTER_CMP_MATCH:
2137                 op = "==";
2138                 /* fall through */
2139         case TEP_FILTER_CMP_NOT_MATCH:
2140                 if (!op)
2141                         op = "!=";
2142                 /* fall through */
2143         case TEP_FILTER_CMP_REGEX:
2144                 if (!op)
2145                         op = "=~";
2146                 /* fall through */
2147         case TEP_FILTER_CMP_NOT_REGEX:
2148                 if (!op)
2149                         op = "!~";
2150 
2151                 asprintf(&str, "%s %s \"%s\"",
2152                          arg->str.field->name, op, arg->str.val);
2153                 break;
2154 
2155         default:
2156                 /* ?? */
2157                 break;
2158         }
2159         return str;
2160 }
2161 
2162 static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
2163 {
2164         char *str = NULL;
2165 
2166         switch (arg->type) {
2167         case TEP_FILTER_ARG_BOOLEAN:
2168                 asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE");
2169                 return str;
2170 
2171         case TEP_FILTER_ARG_OP:
2172                 return op_to_str(filter, arg);
2173 
2174         case TEP_FILTER_ARG_NUM:
2175                 return num_to_str(filter, arg);
2176 
2177         case TEP_FILTER_ARG_STR:
2178                 return str_to_str(filter, arg);
2179 
2180         case TEP_FILTER_ARG_VALUE:
2181                 return val_to_str(filter, arg);
2182 
2183         case TEP_FILTER_ARG_FIELD:
2184                 return field_to_str(filter, arg);
2185 
2186         case TEP_FILTER_ARG_EXP:
2187                 return exp_to_str(filter, arg);
2188 
2189         default:
2190                 /* ?? */
2191                 return NULL;
2192         }
2193 
2194 }
2195 
2196 /**
2197  * tep_filter_make_string - return a string showing the filter
2198  * @filter: filter struct with filter information
2199  * @event_id: the event id to return the filter string with
2200  *
2201  * Returns a string that displays the filter contents.
2202  *  This string must be freed with free(str).
2203  *  NULL is returned if no filter is found or allocation failed.
2204  */
2205 char *
2206 tep_filter_make_string(struct tep_event_filter *filter, int event_id)
2207 {
2208         struct tep_filter_type *filter_type;
2209 
2210         if (!filter->filters)
2211                 return NULL;
2212 
2213         filter_type = find_filter_type(filter, event_id);
2214 
2215         if (!filter_type)
2216                 return NULL;
2217 
2218         return arg_to_str(filter, filter_type->filter);
2219 }
2220 
2221 /**
2222  * tep_filter_compare - compare two filters and return if they are the same
2223  * @filter1: Filter to compare with @filter2
2224  * @filter2: Filter to compare with @filter1
2225  *
2226  * Returns:
2227  *  1 if the two filters hold the same content.
2228  *  0 if they do not.
2229  */
2230 int tep_filter_compare(struct tep_event_filter *filter1, struct tep_event_filter *filter2)
2231 {
2232         struct tep_filter_type *filter_type1;
2233         struct tep_filter_type *filter_type2;
2234         char *str1, *str2;
2235         int result;
2236         int i;
2237 
2238         /* Do the easy checks first */
2239         if (filter1->filters != filter2->filters)
2240                 return 0;
2241         if (!filter1->filters && !filter2->filters)
2242                 return 1;
2243 
2244         /*
2245          * Now take a look at each of the events to see if they have the same
2246          * filters to them.
2247          */
2248         for (i = 0; i < filter1->filters; i++) {
2249                 filter_type1 = &filter1->event_filters[i];
2250                 filter_type2 = find_filter_type(filter2, filter_type1->event_id);
2251                 if (!filter_type2)
2252                         break;
2253                 if (filter_type1->filter->type != filter_type2->filter->type)
2254                         break;
2255                 /* The best way to compare complex filters is with strings */
2256                 str1 = arg_to_str(filter1, filter_type1->filter);
2257                 str2 = arg_to_str(filter2, filter_type2->filter);
2258                 if (str1 && str2)
2259                         result = strcmp(str1, str2) != 0;
2260                 else
2261                         /* bail out if allocation fails */
2262                         result = 1;
2263 
2264                 free(str1);
2265                 free(str2);
2266                 if (result)
2267                         break;
2268         }
2269 
2270         if (i < filter1->filters)
2271                 return 0;
2272         return 1;
2273 }
2274 

/* [<][>][^][v][top][bottom][index][help] */