perf tools: Add static terms support for parse_events_error

Allowing static terms like 'name,period,config,config1..' processing to
report back error.

  $ perf record -e 'cpu/event=1,name=1/' ls
  event syntax error: '..=1,name=1/'
                                 \___ expected string value

  $ perf record -e 'cpu/event=1,period=krava/' ls
  event syntax error: '..,period=krava/'
                                 \___ expected numeric value

  $ perf record -e 'cpu/config=krava1/' ls
  event syntax error: '../config=krava1/'
                                 \___ expected numeric value

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1429729824-13932-8-git-send-email-jolsa@kernel.org
[ Renamed 'error' variables to 'err', not to clash with util.h error() ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Jiri Olsa 2015-04-22 21:10:22 +02:00 committed by Arnaldo Carvalho de Melo
parent e64b020ba1
commit 3b0e371cc0
1 changed files with 29 additions and 10 deletions

View File

@ -545,13 +545,31 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
return add_event(list, idx, &attr, NULL);
}
static int config_term(struct perf_event_attr *attr,
struct parse_events_term *term)
static int check_type_val(struct parse_events_term *term,
struct parse_events_error *err,
int type)
{
#define CHECK_TYPE_VAL(type) \
do { \
if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \
return -EINVAL; \
if (type == term->type_val)
return 0;
if (err) {
err->idx = term->err_val;
if (type == PARSE_EVENTS__TERM_TYPE_NUM)
err->str = strdup("expected numeric value");
else
err->str = strdup("expected string value");
}
return -EINVAL;
}
static int config_term(struct perf_event_attr *attr,
struct parse_events_term *term,
struct parse_events_error *err)
{
#define CHECK_TYPE_VAL(type) \
do { \
if (check_type_val(term, err, PARSE_EVENTS__TERM_TYPE_ ## type)) \
return -EINVAL; \
} while (0)
switch (term->type_term) {
@ -595,12 +613,13 @@ do { \
}
static int config_attr(struct perf_event_attr *attr,
struct list_head *head)
struct list_head *head,
struct parse_events_error *err)
{
struct parse_events_term *term;
list_for_each_entry(term, head, list)
if (config_term(attr, term))
if (config_term(attr, term, err))
return -EINVAL;
return 0;
@ -617,7 +636,7 @@ int parse_events_add_numeric(struct list_head *list, int *idx,
attr.config = config;
if (head_config &&
config_attr(&attr, head_config))
config_attr(&attr, head_config, NULL))
return -EINVAL;
return add_event(list, idx, &attr, NULL);
@ -672,7 +691,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
* Configure hardcoded terms first, no need to check
* return value when called with fail == 0 ;)
*/
if (config_attr(&attr, head_config))
if (config_attr(&attr, head_config, data->error))
return -EINVAL;
if (perf_pmu__config(pmu, &attr, head_config, data->error))