diff options
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r-- | tools/perf/builtin-script.c | 82 |
1 files changed, 79 insertions, 3 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 7c6e4b2f401a..b363e7b292b2 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -1030,6 +1030,68 @@ static int list_available_scripts(const struct option *opt __maybe_unused, | |||
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | /* | 1032 | /* |
1033 | * Some scripts specify the required events in their "xxx-record" file, | ||
1034 | * this function will check if the events in perf.data match those | ||
1035 | * mentioned in the "xxx-record". | ||
1036 | * | ||
1037 | * Fixme: All existing "xxx-record" are all in good formats "-e event ", | ||
1038 | * which is covered well now. And new parsing code should be added to | ||
1039 | * cover the future complexing formats like event groups etc. | ||
1040 | */ | ||
1041 | static int check_ev_match(char *dir_name, char *scriptname, | ||
1042 | struct perf_session *session) | ||
1043 | { | ||
1044 | char filename[MAXPATHLEN], evname[128]; | ||
1045 | char line[BUFSIZ], *p; | ||
1046 | struct perf_evsel *pos; | ||
1047 | int match, len; | ||
1048 | FILE *fp; | ||
1049 | |||
1050 | sprintf(filename, "%s/bin/%s-record", dir_name, scriptname); | ||
1051 | |||
1052 | fp = fopen(filename, "r"); | ||
1053 | if (!fp) | ||
1054 | return -1; | ||
1055 | |||
1056 | while (fgets(line, sizeof(line), fp)) { | ||
1057 | p = ltrim(line); | ||
1058 | if (*p == '#') | ||
1059 | continue; | ||
1060 | |||
1061 | while (strlen(p)) { | ||
1062 | p = strstr(p, "-e"); | ||
1063 | if (!p) | ||
1064 | break; | ||
1065 | |||
1066 | p += 2; | ||
1067 | p = ltrim(p); | ||
1068 | len = strcspn(p, " \t"); | ||
1069 | if (!len) | ||
1070 | break; | ||
1071 | |||
1072 | snprintf(evname, len + 1, "%s", p); | ||
1073 | |||
1074 | match = 0; | ||
1075 | list_for_each_entry(pos, | ||
1076 | &session->evlist->entries, node) { | ||
1077 | if (!strcmp(perf_evsel__name(pos), evname)) { | ||
1078 | match = 1; | ||
1079 | break; | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1083 | if (!match) { | ||
1084 | fclose(fp); | ||
1085 | return -1; | ||
1086 | } | ||
1087 | } | ||
1088 | } | ||
1089 | |||
1090 | fclose(fp); | ||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | /* | ||
1033 | * Return -1 if none is found, otherwise the actual scripts number. | 1095 | * Return -1 if none is found, otherwise the actual scripts number. |
1034 | * | 1096 | * |
1035 | * Currently the only user of this function is the script browser, which | 1097 | * Currently the only user of this function is the script browser, which |
@@ -1039,17 +1101,23 @@ static int list_available_scripts(const struct option *opt __maybe_unused, | |||
1039 | int find_scripts(char **scripts_array, char **scripts_path_array) | 1101 | int find_scripts(char **scripts_array, char **scripts_path_array) |
1040 | { | 1102 | { |
1041 | struct dirent *script_next, *lang_next, script_dirent, lang_dirent; | 1103 | struct dirent *script_next, *lang_next, script_dirent, lang_dirent; |
1042 | char scripts_path[MAXPATHLEN]; | 1104 | char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; |
1043 | DIR *scripts_dir, *lang_dir; | 1105 | DIR *scripts_dir, *lang_dir; |
1044 | char lang_path[MAXPATHLEN]; | 1106 | struct perf_session *session; |
1045 | char *temp; | 1107 | char *temp; |
1046 | int i = 0; | 1108 | int i = 0; |
1047 | 1109 | ||
1110 | session = perf_session__new(input_name, O_RDONLY, 0, false, NULL); | ||
1111 | if (!session) | ||
1112 | return -1; | ||
1113 | |||
1048 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); | 1114 | snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); |
1049 | 1115 | ||
1050 | scripts_dir = opendir(scripts_path); | 1116 | scripts_dir = opendir(scripts_path); |
1051 | if (!scripts_dir) | 1117 | if (!scripts_dir) { |
1118 | perf_session__delete(session); | ||
1052 | return -1; | 1119 | return -1; |
1120 | } | ||
1053 | 1121 | ||
1054 | for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { | 1122 | for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { |
1055 | snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, | 1123 | snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, |
@@ -1077,10 +1145,18 @@ int find_scripts(char **scripts_array, char **scripts_path_array) | |||
1077 | snprintf(scripts_array[i], | 1145 | snprintf(scripts_array[i], |
1078 | (temp - script_dirent.d_name) + 1, | 1146 | (temp - script_dirent.d_name) + 1, |
1079 | "%s", script_dirent.d_name); | 1147 | "%s", script_dirent.d_name); |
1148 | |||
1149 | if (check_ev_match(lang_path, | ||
1150 | scripts_array[i], session)) | ||
1151 | continue; | ||
1152 | |||
1080 | i++; | 1153 | i++; |
1081 | } | 1154 | } |
1155 | closedir(lang_dir); | ||
1082 | } | 1156 | } |
1083 | 1157 | ||
1158 | closedir(scripts_dir); | ||
1159 | perf_session__delete(session); | ||
1084 | return i; | 1160 | return i; |
1085 | } | 1161 | } |
1086 | 1162 | ||