diff options
-rw-r--r-- | tools/perf/util/trace-event-parse.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 3e643f5da202..7aeedb09ea7d 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
@@ -1046,6 +1046,35 @@ out_free: | |||
1046 | return EVENT_ERROR; | 1046 | return EVENT_ERROR; |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | static enum event_type | ||
1050 | process_array(struct event *event, struct print_arg *top, char **tok) | ||
1051 | { | ||
1052 | struct print_arg *arg; | ||
1053 | enum event_type type; | ||
1054 | char *token = NULL; | ||
1055 | |||
1056 | arg = malloc_or_die(sizeof(*arg)); | ||
1057 | memset(arg, 0, sizeof(*arg)); | ||
1058 | |||
1059 | *tok = NULL; | ||
1060 | type = process_arg(event, arg, &token); | ||
1061 | if (test_type_token(type, token, EVENT_OP, (char *)"]")) | ||
1062 | goto out_free; | ||
1063 | |||
1064 | top->op.right = arg; | ||
1065 | |||
1066 | free_token(token); | ||
1067 | type = read_token_item(&token); | ||
1068 | *tok = token; | ||
1069 | |||
1070 | return type; | ||
1071 | |||
1072 | out_free: | ||
1073 | free_token(*tok); | ||
1074 | free_arg(arg); | ||
1075 | return EVENT_ERROR; | ||
1076 | } | ||
1077 | |||
1049 | static int get_op_prio(char *op) | 1078 | static int get_op_prio(char *op) |
1050 | { | 1079 | { |
1051 | if (!op[1]) { | 1080 | if (!op[1]) { |
@@ -1192,6 +1221,18 @@ process_op(struct event *event, struct print_arg *arg, char **tok) | |||
1192 | 1221 | ||
1193 | arg->op.right = right; | 1222 | arg->op.right = right; |
1194 | 1223 | ||
1224 | } else if (strcmp(token, "[") == 0) { | ||
1225 | |||
1226 | left = malloc_or_die(sizeof(*left)); | ||
1227 | *left = *arg; | ||
1228 | |||
1229 | arg->type = PRINT_OP; | ||
1230 | arg->op.op = token; | ||
1231 | arg->op.left = left; | ||
1232 | |||
1233 | arg->op.prio = 0; | ||
1234 | type = process_array(event, arg, tok); | ||
1235 | |||
1195 | } else { | 1236 | } else { |
1196 | die("unknown op '%s'", token); | 1237 | die("unknown op '%s'", token); |
1197 | /* the arg is now the left side */ | 1238 | /* the arg is now the left side */ |
@@ -1931,6 +1972,7 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
1931 | { | 1972 | { |
1932 | unsigned long long val = 0; | 1973 | unsigned long long val = 0; |
1933 | unsigned long long left, right; | 1974 | unsigned long long left, right; |
1975 | struct print_arg *larg; | ||
1934 | 1976 | ||
1935 | switch (arg->type) { | 1977 | switch (arg->type) { |
1936 | case PRINT_NULL: | 1978 | case PRINT_NULL: |
@@ -1957,6 +1999,26 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
1957 | return 0; | 1999 | return 0; |
1958 | break; | 2000 | break; |
1959 | case PRINT_OP: | 2001 | case PRINT_OP: |
2002 | if (strcmp(arg->op.op, "[") == 0) { | ||
2003 | /* | ||
2004 | * Arrays are special, since we don't want | ||
2005 | * to read the arg as is. | ||
2006 | */ | ||
2007 | if (arg->op.left->type != PRINT_FIELD) | ||
2008 | goto default_op; /* oops, all bets off */ | ||
2009 | larg = arg->op.left; | ||
2010 | if (!larg->field.field) { | ||
2011 | larg->field.field = | ||
2012 | find_any_field(event, larg->field.name); | ||
2013 | if (!larg->field.field) | ||
2014 | die("field %s not found", larg->field.name); | ||
2015 | } | ||
2016 | right = eval_num_arg(data, size, event, arg->op.right); | ||
2017 | val = read_size(data + larg->field.field->offset + | ||
2018 | right * long_size, long_size); | ||
2019 | break; | ||
2020 | } | ||
2021 | default_op: | ||
1960 | left = eval_num_arg(data, size, event, arg->op.left); | 2022 | left = eval_num_arg(data, size, event, arg->op.left); |
1961 | right = eval_num_arg(data, size, event, arg->op.right); | 2023 | right = eval_num_arg(data, size, event, arg->op.right); |
1962 | switch (arg->op.op[0]) { | 2024 | switch (arg->op.op[0]) { |