tools lib traceevent: Refactor process_filter()

So that it can return a proper pevent_errno value.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-11-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Namhyung Kim 2013-12-12 16:36:13 +09:00 committed by Arnaldo Carvalho de Melo
parent c8ea690dd0
commit 42d6194d13
2 changed files with 42 additions and 28 deletions

View file

@ -368,7 +368,11 @@ enum pevent_flag {
_PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \ _PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \
_PE(REPARENT_FAILED, "failed to reparent filter OP"), \ _PE(REPARENT_FAILED, "failed to reparent filter OP"), \
_PE(BAD_FILTER_ARG, "bad arg in filter tree"), \ _PE(BAD_FILTER_ARG, "bad arg in filter tree"), \
_PE(UNEXPECTED_TYPE, "unexpected type (not a value)") _PE(UNEXPECTED_TYPE, "unexpected type (not a value)"), \
_PE(ILLEGAL_TOKEN, "illegal token"), \
_PE(INVALID_PAREN, "open parenthesis cannot come here"), \
_PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \
_PE(UNKNOWN_TOKEN, "unknown token")
#undef _PE #undef _PE
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code #define _PE(__code, __str) PEVENT_ERRNO__ ## __code

View file

@ -937,9 +937,10 @@ static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
} }
/* Remove any unknown event fields */ /* Remove any unknown event fields */
static struct filter_arg *collapse_tree(struct filter_arg *arg, char **error_str) static int collapse_tree(struct filter_arg *arg,
struct filter_arg **arg_collapsed, char **error_str)
{ {
enum filter_vals ret; int ret;
ret = test_arg(arg, arg, error_str); ret = test_arg(arg, arg, error_str);
switch (ret) { switch (ret) {
@ -955,6 +956,7 @@ static struct filter_arg *collapse_tree(struct filter_arg *arg, char **error_str
arg->boolean.value = ret == FILTER_VAL_TRUE; arg->boolean.value = ret == FILTER_VAL_TRUE;
} else { } else {
show_error(error_str, "Failed to allocate filter arg"); show_error(error_str, "Failed to allocate filter arg");
ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
} }
break; break;
@ -965,10 +967,11 @@ static struct filter_arg *collapse_tree(struct filter_arg *arg, char **error_str
break; break;
} }
return arg; *arg_collapsed = arg;
return ret;
} }
static int static enum pevent_errno
process_filter(struct event_format *event, struct filter_arg **parg, process_filter(struct event_format *event, struct filter_arg **parg,
char **error_str, int not) char **error_str, int not)
{ {
@ -982,7 +985,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
enum filter_op_type btype; enum filter_op_type btype;
enum filter_exp_type etype; enum filter_exp_type etype;
enum filter_cmp_type ctype; enum filter_cmp_type ctype;
int ret; enum pevent_errno ret;
*parg = NULL; *parg = NULL;
@ -1007,20 +1010,20 @@ process_filter(struct event_format *event, struct filter_arg **parg,
if (not) { if (not) {
arg = NULL; arg = NULL;
if (current_op) if (current_op)
goto fail_print; goto fail_syntax;
free(token); free(token);
*parg = current_exp; *parg = current_exp;
return 0; return 0;
} }
} else } else
goto fail_print; goto fail_syntax;
arg = NULL; arg = NULL;
break; break;
case EVENT_DELIM: case EVENT_DELIM:
if (*token == ',') { if (*token == ',') {
show_error(error_str, show_error(error_str, "Illegal token ','");
"Illegal token ','"); ret = PEVENT_ERRNO__ILLEGAL_TOKEN;
goto fail; goto fail;
} }
@ -1028,19 +1031,23 @@ process_filter(struct event_format *event, struct filter_arg **parg,
if (left_item) { if (left_item) {
show_error(error_str, show_error(error_str,
"Open paren can not come after item"); "Open paren can not come after item");
ret = PEVENT_ERRNO__INVALID_PAREN;
goto fail; goto fail;
} }
if (current_exp) { if (current_exp) {
show_error(error_str, show_error(error_str,
"Open paren can not come after expression"); "Open paren can not come after expression");
ret = PEVENT_ERRNO__INVALID_PAREN;
goto fail; goto fail;
} }
ret = process_filter(event, &arg, error_str, 0); ret = process_filter(event, &arg, error_str, 0);
if (ret != 1) { if (ret != PEVENT_ERRNO__UNBALANCED_PAREN) {
if (ret == 0) if (ret == 0) {
show_error(error_str, show_error(error_str,
"Unbalanced number of '('"); "Unbalanced number of '('");
ret = PEVENT_ERRNO__UNBALANCED_PAREN;
}
goto fail; goto fail;
} }
ret = 0; ret = 0;
@ -1048,7 +1055,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
/* A not wants just one expression */ /* A not wants just one expression */
if (not) { if (not) {
if (current_op) if (current_op)
goto fail_print; goto fail_syntax;
*parg = arg; *parg = arg;
return 0; return 0;
} }
@ -1063,19 +1070,19 @@ process_filter(struct event_format *event, struct filter_arg **parg,
} else { /* ')' */ } else { /* ')' */
if (!current_op && !current_exp) if (!current_op && !current_exp)
goto fail_print; goto fail_syntax;
/* Make sure everything is finished at this level */ /* Make sure everything is finished at this level */
if (current_exp && !check_op_done(current_exp)) if (current_exp && !check_op_done(current_exp))
goto fail_print; goto fail_syntax;
if (current_op && !check_op_done(current_op)) if (current_op && !check_op_done(current_op))
goto fail_print; goto fail_syntax;
if (current_op) if (current_op)
*parg = current_op; *parg = current_op;
else else
*parg = current_exp; *parg = current_exp;
return 1; return PEVENT_ERRNO__UNBALANCED_PAREN;
} }
break; break;
@ -1087,21 +1094,22 @@ process_filter(struct event_format *event, struct filter_arg **parg,
case OP_BOOL: case OP_BOOL:
/* Logic ops need a left expression */ /* Logic ops need a left expression */
if (!current_exp && !current_op) if (!current_exp && !current_op)
goto fail_print; goto fail_syntax;
/* fall through */ /* fall through */
case OP_NOT: case OP_NOT:
/* logic only processes ops and exp */ /* logic only processes ops and exp */
if (left_item) if (left_item)
goto fail_print; goto fail_syntax;
break; break;
case OP_EXP: case OP_EXP:
case OP_CMP: case OP_CMP:
if (!left_item) if (!left_item)
goto fail_print; goto fail_syntax;
break; break;
case OP_NONE: case OP_NONE:
show_error(error_str, show_error(error_str,
"Unknown op token %s", token); "Unknown op token %s", token);
ret = PEVENT_ERRNO__UNKNOWN_TOKEN;
goto fail; goto fail;
} }
@ -1152,7 +1160,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
ret = add_left(arg, left_item); ret = add_left(arg, left_item);
if (ret < 0) { if (ret < 0) {
arg = NULL; arg = NULL;
goto fail_print; goto fail_syntax;
} }
current_exp = arg; current_exp = arg;
break; break;
@ -1161,25 +1169,25 @@ process_filter(struct event_format *event, struct filter_arg **parg,
} }
arg = NULL; arg = NULL;
if (ret < 0) if (ret < 0)
goto fail_print; goto fail_syntax;
break; break;
case EVENT_NONE: case EVENT_NONE:
break; break;
case EVENT_ERROR: case EVENT_ERROR:
goto fail_alloc; goto fail_alloc;
default: default:
goto fail_print; goto fail_syntax;
} }
} while (type != EVENT_NONE); } while (type != EVENT_NONE);
if (!current_op && !current_exp) if (!current_op && !current_exp)
goto fail_print; goto fail_syntax;
if (!current_op) if (!current_op)
current_op = current_exp; current_op = current_exp;
current_op = collapse_tree(current_op, error_str); ret = collapse_tree(current_op, parg, error_str);
if (current_op == NULL) if (ret < 0)
goto fail; goto fail;
*parg = current_op; *parg = current_op;
@ -1188,15 +1196,17 @@ process_filter(struct event_format *event, struct filter_arg **parg,
fail_alloc: fail_alloc:
show_error(error_str, "failed to allocate filter arg"); show_error(error_str, "failed to allocate filter arg");
ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
goto fail; goto fail;
fail_print: fail_syntax:
show_error(error_str, "Syntax error"); show_error(error_str, "Syntax error");
ret = PEVENT_ERRNO__SYNTAX_ERROR;
fail: fail:
free_arg(current_op); free_arg(current_op);
free_arg(current_exp); free_arg(current_exp);
free_arg(arg); free_arg(arg);
free(token); free(token);
return -1; return ret;
} }
static int static int