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