|
@@ -1029,6 +1029,68 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
|
|
|
exit(0);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Some scripts specify the required events in their "xxx-record" file,
|
|
|
+ * this function will check if the events in perf.data match those
|
|
|
+ * mentioned in the "xxx-record".
|
|
|
+ *
|
|
|
+ * Fixme: All existing "xxx-record" are all in good formats "-e event ",
|
|
|
+ * which is covered well now. And new parsing code should be added to
|
|
|
+ * cover the future complexing formats like event groups etc.
|
|
|
+ */
|
|
|
+static int check_ev_match(char *dir_name, char *scriptname,
|
|
|
+ struct perf_session *session)
|
|
|
+{
|
|
|
+ char filename[MAXPATHLEN], evname[128];
|
|
|
+ char line[BUFSIZ], *p;
|
|
|
+ struct perf_evsel *pos;
|
|
|
+ int match, len;
|
|
|
+ FILE *fp;
|
|
|
+
|
|
|
+ sprintf(filename, "%s/bin/%s-record", dir_name, scriptname);
|
|
|
+
|
|
|
+ fp = fopen(filename, "r");
|
|
|
+ if (!fp)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ while (fgets(line, sizeof(line), fp)) {
|
|
|
+ p = ltrim(line);
|
|
|
+ if (*p == '#')
|
|
|
+ continue;
|
|
|
+
|
|
|
+ while (strlen(p)) {
|
|
|
+ p = strstr(p, "-e");
|
|
|
+ if (!p)
|
|
|
+ break;
|
|
|
+
|
|
|
+ p += 2;
|
|
|
+ p = ltrim(p);
|
|
|
+ len = strcspn(p, " \t");
|
|
|
+ if (!len)
|
|
|
+ break;
|
|
|
+
|
|
|
+ snprintf(evname, len + 1, "%s", p);
|
|
|
+
|
|
|
+ match = 0;
|
|
|
+ list_for_each_entry(pos,
|
|
|
+ &session->evlist->entries, node) {
|
|
|
+ if (!strcmp(perf_evsel__name(pos), evname)) {
|
|
|
+ match = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!match) {
|
|
|
+ fclose(fp);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fclose(fp);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Return -1 if none is found, otherwise the actual scripts number.
|
|
|
*
|
|
@@ -1039,17 +1101,23 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
|
|
|
int find_scripts(char **scripts_array, char **scripts_path_array)
|
|
|
{
|
|
|
struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
|
|
|
- char scripts_path[MAXPATHLEN];
|
|
|
+ char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
|
|
|
DIR *scripts_dir, *lang_dir;
|
|
|
- char lang_path[MAXPATHLEN];
|
|
|
+ struct perf_session *session;
|
|
|
char *temp;
|
|
|
int i = 0;
|
|
|
|
|
|
+ session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
|
|
|
+ if (!session)
|
|
|
+ return -1;
|
|
|
+
|
|
|
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
|
|
|
|
|
|
scripts_dir = opendir(scripts_path);
|
|
|
- if (!scripts_dir)
|
|
|
+ if (!scripts_dir) {
|
|
|
+ perf_session__delete(session);
|
|
|
return -1;
|
|
|
+ }
|
|
|
|
|
|
for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
|
|
|
snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
|
|
@@ -1077,10 +1145,18 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
|
|
|
snprintf(scripts_array[i],
|
|
|
(temp - script_dirent.d_name) + 1,
|
|
|
"%s", script_dirent.d_name);
|
|
|
+
|
|
|
+ if (check_ev_match(lang_path,
|
|
|
+ scripts_array[i], session))
|
|
|
+ continue;
|
|
|
+
|
|
|
i++;
|
|
|
}
|
|
|
+ closedir(lang_dir);
|
|
|
}
|
|
|
|
|
|
+ closedir(scripts_dir);
|
|
|
+ perf_session__delete(session);
|
|
|
return i;
|
|
|
}
|
|
|
|