builtin-trace.c (586bc5cce88be993dad584c3936c49f945368551) | builtin-trace.c (4b9c0c596ea826ef784eb83f663c5351ed01ba6d) |
---|---|
1#include "builtin.h" 2 3#include "util/util.h" 4#include "util/cache.h" 5#include "util/symbol.h" 6#include "util/thread.h" 7#include "util/header.h" 8#include "util/exec_cmd.h" --- 260 unchanged lines hidden (view full) --- 269 } 270 } 271 272 script_name = strdup(script); 273 274 return 0; 275} 276 | 1#include "builtin.h" 2 3#include "util/util.h" 4#include "util/cache.h" 5#include "util/symbol.h" 6#include "util/thread.h" 7#include "util/header.h" 8#include "util/exec_cmd.h" --- 260 unchanged lines hidden (view full) --- 269 } 270 } 271 272 script_name = strdup(script); 273 274 return 0; 275} 276 |
277#define for_each_lang(scripts_dir, lang_dirent, lang_next) \ 278 while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ 279 lang_next) \ 280 if (lang_dirent.d_type == DT_DIR && \ 281 (strcmp(lang_dirent.d_name, ".")) && \ 282 (strcmp(lang_dirent.d_name, ".."))) 283 284#define for_each_script(lang_dir, script_dirent, script_next) \ 285 while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ 286 script_next) \ 287 if (script_dirent.d_type != DT_DIR) 288 289 290#define RECORD_SUFFIX "-record" 291#define REPORT_SUFFIX "-report" 292 293struct script_desc { 294 struct list_head node; 295 char *name; 296 char *half_liner; 297 char *args; 298}; 299 300LIST_HEAD(script_descs); 301 302static struct script_desc *script_desc__new(const char *name) 303{ 304 struct script_desc *s = zalloc(sizeof(*s)); 305 306 if (s != NULL) 307 s->name = strdup(name); 308 309 return s; 310} 311 312static void script_desc__delete(struct script_desc *s) 313{ 314 free(s->name); 315 free(s); 316} 317 318static void script_desc__add(struct script_desc *s) 319{ 320 list_add_tail(&s->node, &script_descs); 321} 322 323static struct script_desc *script_desc__find(const char *name) 324{ 325 struct script_desc *s; 326 327 list_for_each_entry(s, &script_descs, node) 328 if (strcasecmp(s->name, name) == 0) 329 return s; 330 return NULL; 331} 332 333static struct script_desc *script_desc__findnew(const char *name) 334{ 335 struct script_desc *s = script_desc__find(name); 336 337 if (s) 338 return s; 339 340 s = script_desc__new(name); 341 if (!s) 342 goto out_delete_desc; 343 344 script_desc__add(s); 345 346 return s; 347 348out_delete_desc: 349 script_desc__delete(s); 350 351 return NULL; 352} 353 354static char *ends_with(char *str, const char *suffix) 355{ 356 size_t suffix_len = strlen(suffix); 357 char *p = str; 358 359 if (strlen(str) > suffix_len) { 360 p = str + strlen(str) - suffix_len; 361 if (!strncmp(p, suffix, suffix_len)) 362 return p; 363 } 364 365 return NULL; 366} 367 368static char *ltrim(char *str) 369{ 370 int len = strlen(str); 371 372 while (len && isspace(*str)) { 373 len--; 374 str++; 375 } 376 377 return str; 378} 379 380static int read_script_info(struct script_desc *desc, const char *filename) 381{ 382 char line[BUFSIZ], *p; 383 FILE *fp; 384 385 fp = fopen(filename, "r"); 386 if (!fp) 387 return -1; 388 389 while (fgets(line, sizeof(line), fp)) { 390 p = ltrim(line); 391 if (strlen(p) == 0) 392 continue; 393 if (*p != '#') 394 continue; 395 p++; 396 if (strlen(p) && *p == '!') 397 continue; 398 399 p = ltrim(p); 400 if (strlen(p) && p[strlen(p) - 1] == '\n') 401 p[strlen(p) - 1] = '\0'; 402 403 if (!strncmp(p, "description:", strlen("description:"))) { 404 p += strlen("description:"); 405 desc->half_liner = strdup(ltrim(p)); 406 continue; 407 } 408 409 if (!strncmp(p, "args:", strlen("args:"))) { 410 p += strlen("args:"); 411 desc->args = strdup(ltrim(p)); 412 continue; 413 } 414 } 415 416 fclose(fp); 417 418 return 0; 419} 420 421static int list_available_scripts(const struct option *opt __used, 422 const char *s __used, int unset __used) 423{ 424 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 425 char scripts_path[MAXPATHLEN]; 426 DIR *scripts_dir, *lang_dir; 427 char script_path[MAXPATHLEN]; 428 char lang_path[MAXPATHLEN]; 429 struct script_desc *desc; 430 char first_half[BUFSIZ]; 431 char *script_root; 432 char *str; 433 434 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 435 436 scripts_dir = opendir(scripts_path); 437 if (!scripts_dir) 438 return -1; 439 440 for_each_lang(scripts_dir, lang_dirent, lang_next) { 441 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 442 lang_dirent.d_name); 443 lang_dir = opendir(lang_path); 444 if (!lang_dir) 445 continue; 446 447 for_each_script(lang_dir, script_dirent, script_next) { 448 script_root = strdup(script_dirent.d_name); 449 str = ends_with(script_root, REPORT_SUFFIX); 450 if (str) { 451 *str = '\0'; 452 desc = script_desc__findnew(script_root); 453 snprintf(script_path, MAXPATHLEN, "%s/%s", 454 lang_path, script_dirent.d_name); 455 read_script_info(desc, script_path); 456 } 457 free(script_root); 458 } 459 } 460 461 fprintf(stdout, "List of available trace scripts:\n"); 462 list_for_each_entry(desc, &script_descs, node) { 463 sprintf(first_half, "%s %s", desc->name, 464 desc->args ? desc->args : ""); 465 fprintf(stdout, " %-36s %s\n", first_half, 466 desc->half_liner ? desc->half_liner : ""); 467 } 468 469 exit(0); 470} 471 |
|
277static const char * const annotate_usage[] = { 278 "perf trace [<options>] <command>", 279 NULL 280}; 281 282static const struct option options[] = { 283 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 284 "dump raw trace in ASCII"), 285 OPT_BOOLEAN('v', "verbose", &verbose, 286 "be more verbose (show symbol address, etc)"), | 472static const char * const annotate_usage[] = { 473 "perf trace [<options>] <command>", 474 NULL 475}; 476 477static const struct option options[] = { 478 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 479 "dump raw trace in ASCII"), 480 OPT_BOOLEAN('v', "verbose", &verbose, 481 "be more verbose (show symbol address, etc)"), |
287 OPT_BOOLEAN('l', "latency", &latency_format, | 482 OPT_BOOLEAN('L', "Latency", &latency_format, |
288 "show latency attributes (irqs/preemption disabled, etc)"), | 483 "show latency attributes (irqs/preemption disabled, etc)"), |
484 OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts", 485 list_available_scripts), |
|
289 OPT_CALLBACK('s', "script", NULL, "name", 290 "script file name (lang:script name, script name, or *)", 291 parse_scriptname), 292 OPT_STRING('g', "gen-script", &generate_script_lang, "lang", 293 "generate perf-trace.xx script in specified language"), 294 295 OPT_END() 296}; --- 63 unchanged lines hidden --- | 486 OPT_CALLBACK('s', "script", NULL, "name", 487 "script file name (lang:script name, script name, or *)", 488 parse_scriptname), 489 OPT_STRING('g', "gen-script", &generate_script_lang, "lang", 490 "generate perf-trace.xx script in specified language"), 491 492 OPT_END() 493}; --- 63 unchanged lines hidden --- |