static int config_term(struct perf_event_attr *attr,
struct parse_events__term *term)
{
- switch (term->type) {
+#define CHECK_TYPE_VAL(type) \
+do { \
+ if (PARSE_EVENTS__TERM_TYPE_ ## type != term->type_val) \
+ return -EINVAL; \
+} while (0)
+
+ switch (term->type_term) {
case PARSE_EVENTS__TERM_TYPE_CONFIG:
+ CHECK_TYPE_VAL(NUM);
attr->config = term->val.num;
break;
case PARSE_EVENTS__TERM_TYPE_CONFIG1:
+ CHECK_TYPE_VAL(NUM);
attr->config1 = term->val.num;
break;
case PARSE_EVENTS__TERM_TYPE_CONFIG2:
+ CHECK_TYPE_VAL(NUM);
attr->config2 = term->val.num;
break;
case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
+ CHECK_TYPE_VAL(NUM);
attr->sample_period = term->val.num;
break;
case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
default:
return -EINVAL;
}
+
return 0;
+#undef CHECK_TYPE_VAL
}
static int config_attr(struct perf_event_attr *attr,
int parse_events__is_hardcoded_term(struct parse_events__term *term)
{
- return term->type <= PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX;
+ return term->type_term != PARSE_EVENTS__TERM_TYPE_USER;
}
-int parse_events__new_term(struct parse_events__term **_term, int type,
- char *config, char *str, long num)
+static int new_term(struct parse_events__term **_term, int type_val,
+ int type_term, char *config,
+ char *str, long num)
{
struct parse_events__term *term;
return -ENOMEM;
INIT_LIST_HEAD(&term->list);
- term->type = type;
+ term->type_val = type_val;
+ term->type_term = type_term;
term->config = config;
- switch (type) {
- case PARSE_EVENTS__TERM_TYPE_CONFIG:
- case PARSE_EVENTS__TERM_TYPE_CONFIG1:
- case PARSE_EVENTS__TERM_TYPE_CONFIG2:
- case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
- case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
+ switch (type_val) {
case PARSE_EVENTS__TERM_TYPE_NUM:
term->val.num = num;
break;
return 0;
}
+int parse_events__term_num(struct parse_events__term **term,
+ int type_term, char *config, long num)
+{
+ return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term,
+ config, NULL, num);
+}
+
+int parse_events__term_str(struct parse_events__term **term,
+ int type_term, char *config, char *str)
+{
+ return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term,
+ config, str, 0);
+}
+
void parse_events__free_terms(struct list_head *terms)
{
struct parse_events__term *term, *h;
#define EVENTS_HELP_MAX (128*1024)
enum {
+ PARSE_EVENTS__TERM_TYPE_NUM,
+ PARSE_EVENTS__TERM_TYPE_STR,
+};
+
+enum {
+ PARSE_EVENTS__TERM_TYPE_USER,
PARSE_EVENTS__TERM_TYPE_CONFIG,
PARSE_EVENTS__TERM_TYPE_CONFIG1,
PARSE_EVENTS__TERM_TYPE_CONFIG2,
PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD,
PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
- PARSE_EVENTS__TERM_TYPE_NUM,
- PARSE_EVENTS__TERM_TYPE_STR,
-
- PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX =
- PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
};
struct parse_events__term {
char *str;
long num;
} val;
- int type;
-
+ int type_val;
+ int type_term;
struct list_head list;
};
int parse_events__is_hardcoded_term(struct parse_events__term *term);
-int parse_events__new_term(struct parse_events__term **term, int type,
- char *config, char *str, long num);
+int parse_events__term_num(struct parse_events__term **_term,
+ int type_term, char *config, long num);
+int parse_events__term_str(struct parse_events__term **_term,
+ int type_term, char *config, char *str);
void parse_events__free_terms(struct list_head *terms);
int parse_events_modifier(struct list_head *list __used, char *str __used);
int parse_events_add_tracepoint(struct list_head *list, int *idx,
{
struct parse_events__term *term;
- ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_STR,
- $1, $3, 0));
+ ABORT_ON(parse_events__term_str(&term, PARSE_EVENTS__TERM_TYPE_USER,
+ $1, $3));
$$ = term;
}
|
{
struct parse_events__term *term;
- ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
- $1, NULL, $3));
+ ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER,
+ $1, $3));
$$ = term;
}
|
{
struct parse_events__term *term;
- ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
- $1, NULL, 1));
+ ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER,
+ $1, 1));
$$ = term;
}
|
{
struct parse_events__term *term;
- ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, $3));
+ ABORT_ON(parse_events__term_num(&term, $1, NULL, $3));
$$ = term;
}
|
{
struct parse_events__term *term;
- ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, 1));
+ ABORT_ON(parse_events__term_num(&term, $1, NULL, 1));
$$ = term;
}
if (parse_events__is_hardcoded_term(term))
return 0;
- if (term->type != PARSE_EVENTS__TERM_TYPE_NUM)
+ if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM)
return -EINVAL;
format = pmu_find_format(formats, term->config);
return -EINVAL;
}
+ /*
+ * XXX If we ever decide to go with string values for
+ * non-hardcoded terms, here's the place to translate
+ * them into value.
+ */
*vp |= pmu_format_value(format->bits, term->val.num);
return 0;
}
/* Simulated users input. */
static struct parse_events__term test_terms[] = {
{
- .config = (char *) "krava01",
- .val.num = 15,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava01",
+ .val.num = 15,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
{
- .config = (char *) "krava02",
- .val.num = 170,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava02",
+ .val.num = 170,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
{
- .config = (char *) "krava03",
- .val.num = 1,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava03",
+ .val.num = 1,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
{
- .config = (char *) "krava11",
- .val.num = 27,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava11",
+ .val.num = 27,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
{
- .config = (char *) "krava12",
- .val.num = 1,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava12",
+ .val.num = 1,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
{
- .config = (char *) "krava13",
- .val.num = 2,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava13",
+ .val.num = 2,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
{
- .config = (char *) "krava21",
- .val.num = 119,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava21",
+ .val.num = 119,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
{
- .config = (char *) "krava22",
- .val.num = 11,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava22",
+ .val.num = 11,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
{
- .config = (char *) "krava23",
- .val.num = 2,
- .type = PARSE_EVENTS__TERM_TYPE_NUM,
+ .config = (char *) "krava23",
+ .val.num = 2,
+ .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
+ .type_term = PARSE_EVENTS__TERM_TYPE_USER,
},
};
#define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term))