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