{
bool found = false;
struct evsel *evsel, *tmp;
- struct parse_events_error err = { .idx = 0, };
- int ret = parse_events(evlist, "probe:vfs_getname*", &err);
+ struct parse_events_error err;
+ int ret;
- if (ret)
+ bzero(&err, sizeof(err));
+ ret = parse_events(evlist, "probe:vfs_getname*", &err);
+ if (ret) {
+ free(err.str);
+ free(err.help);
+ free(err.first_str);
+ free(err.first_help);
return false;
+ }
evlist__for_each_entry_safe(evlist, evsel, tmp) {
if (!strstarts(perf_evsel__name(evsel), "probe:vfs_getname"))
* wrong in more detail.
*/
if (trace.perfconfig_events != NULL) {
- struct parse_events_error parse_err = { .idx = 0, };
+ struct parse_events_error parse_err;
+ bzero(&parse_err, sizeof(parse_err));
err = parse_events(trace.evlist, trace.perfconfig_events, &parse_err);
if (err) {
parse_events_print_error(&parse_err, trace.perfconfig_events);
free(help);
return;
}
- WARN_ONCE(err->str, "WARNING: multiple event parsing errors\n");
- err->idx = idx;
- free(err->str);
- err->str = str;
- free(err->help);
- err->help = help;
+ switch (err->num_errors) {
+ case 0:
+ err->idx = idx;
+ err->str = str;
+ err->help = help;
+ break;
+ case 1:
+ err->first_idx = err->idx;
+ err->idx = idx;
+ err->first_str = err->str;
+ err->str = str;
+ err->first_help = err->help;
+ err->help = help;
+ break;
+ default:
+ WARN_ONCE(1, "WARNING: multiple event parsing errors\n");
+ free(err->str);
+ err->str = str;
+ free(err->help);
+ err->help = help;
+ break;
+ }
+ err->num_errors++;
}
struct tracepoint_path *tracepoint_id_to_path(u64 config)
if (asprintf(&err_str,
"Cannot find PMU `%s'. Missing kernel support?",
name) >= 0)
- parse_events__handle_error(err, -1, err_str, NULL);
+ parse_events__handle_error(err, 0, err_str, NULL);
return -EINVAL;
}
return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col;
}
-void parse_events_print_error(struct parse_events_error *err,
- const char *event)
+static void __parse_events_print_error(int err_idx, const char *err_str,
+ const char *err_help, const char *event)
{
const char *str = "invalid or unsupported event: ";
char _buf[MAX_WIDTH];
char *buf = (char *) event;
int idx = 0;
-
- if (err->str) {
+ if (err_str) {
/* -2 for extra '' in the final fprintf */
int width = get_term_width() - 2;
int len_event = strlen(event);
buf = _buf;
/* We're cutting from the beginning. */
- if (err->idx > max_err_idx)
- cut = err->idx - max_err_idx;
+ if (err_idx > max_err_idx)
+ cut = err_idx - max_err_idx;
strncpy(buf, event + cut, max_len);
buf[max_len] = 0;
}
- idx = len_str + err->idx - cut;
+ idx = len_str + err_idx - cut;
}
fprintf(stderr, "%s'%s'\n", str, buf);
if (idx) {
- fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err->str);
- if (err->help)
- fprintf(stderr, "\n%s\n", err->help);
- zfree(&err->str);
- zfree(&err->help);
+ fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err_str);
+ if (err_help)
+ fprintf(stderr, "\n%s\n", err_help);
+ }
+}
+
+void parse_events_print_error(struct parse_events_error *err,
+ const char *event)
+{
+ if (!err->num_errors)
+ return;
+
+ __parse_events_print_error(err->idx, err->str, err->help, event);
+ zfree(&err->str);
+ zfree(&err->help);
+
+ if (err->num_errors > 1) {
+ fputs("\nInitial error:\n", stderr);
+ __parse_events_print_error(err->first_idx, err->first_str,
+ err->first_help, event);
+ zfree(&err->first_str);
+ zfree(&err->first_help);
}
}
int unset __maybe_unused)
{
struct evlist *evlist = *(struct evlist **)opt->value;
- struct parse_events_error err = { .idx = 0, };
- int ret = parse_events(evlist, str, &err);
+ struct parse_events_error err;
+ int ret;
+
+ bzero(&err, sizeof(err));
+ ret = parse_events(evlist, str, &err);
if (ret) {
parse_events_print_error(&err, str);