Linux Audio

Check our new training course

Loading...
v3.15
  1#include <elf.h>
  2#include <inttypes.h>
  3#include <sys/ttydefaults.h>
  4#include <string.h>
  5#include "../../util/sort.h"
  6#include "../../util/util.h"
  7#include "../../util/hist.h"
  8#include "../../util/debug.h"
  9#include "../../util/symbol.h"
 10#include "../browser.h"
 11#include "../helpline.h"
 12#include "../libslang.h"
 13
 14/* 2048 lines should be enough for a script output */
 15#define MAX_LINES		2048
 16
 17/* 160 bytes for one output line */
 18#define AVERAGE_LINE_LEN	160
 19
 20struct script_line {
 21	struct list_head node;
 22	char line[AVERAGE_LINE_LEN];
 23};
 24
 25struct perf_script_browser {
 26	struct ui_browser b;
 27	struct list_head entries;
 28	const char *script_name;
 29	int nr_lines;
 30};
 31
 32#define SCRIPT_NAMELEN	128
 33#define SCRIPT_MAX_NO	64
 34/*
 35 * Usually the full path for a script is:
 36 *	/home/username/libexec/perf-core/scripts/python/xxx.py
 37 *	/home/username/libexec/perf-core/scripts/perl/xxx.pl
 38 * So 256 should be long enough to contain the full path.
 39 */
 40#define SCRIPT_FULLPATH_LEN	256
 41
 42/*
 43 * When success, will copy the full path of the selected script
 44 * into  the buffer pointed by script_name, and return 0.
 45 * Return -1 on failure.
 46 */
 47static int list_scripts(char *script_name)
 48{
 49	char *buf, *names[SCRIPT_MAX_NO], *paths[SCRIPT_MAX_NO];
 50	int i, num, choice, ret = -1;
 51
 52	/* Preset the script name to SCRIPT_NAMELEN */
 53	buf = malloc(SCRIPT_MAX_NO * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN));
 54	if (!buf)
 55		return ret;
 56
 57	for (i = 0; i < SCRIPT_MAX_NO; i++) {
 58		names[i] = buf + i * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN);
 59		paths[i] = names[i] + SCRIPT_NAMELEN;
 60	}
 61
 62	num = find_scripts(names, paths);
 63	if (num > 0) {
 64		choice = ui__popup_menu(num, names);
 65		if (choice < num && choice >= 0) {
 66			strcpy(script_name, paths[choice]);
 67			ret = 0;
 68		}
 69	}
 70
 71	free(buf);
 72	return ret;
 73}
 74
 75static void script_browser__write(struct ui_browser *browser,
 76				   void *entry, int row)
 77{
 78	struct script_line *sline = list_entry(entry, struct script_line, node);
 79	bool current_entry = ui_browser__is_current_entry(browser, row);
 80
 81	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
 82						       HE_COLORSET_NORMAL);
 83
 84	slsmg_write_nstring(sline->line, browser->width);
 85}
 86
 87static int script_browser__run(struct perf_script_browser *browser)
 88{
 89	int key;
 90
 91	if (ui_browser__show(&browser->b, browser->script_name,
 92			     "Press <- or ESC to exit") < 0)
 93		return -1;
 94
 95	while (1) {
 96		key = ui_browser__run(&browser->b, 0);
 97
 98		/* We can add some special key handling here if needed */
 99		break;
100	}
101
102	ui_browser__hide(&browser->b);
103	return key;
104}
105
106
107int script_browse(const char *script_opt)
108{
109	char cmd[SCRIPT_FULLPATH_LEN*2], script_name[SCRIPT_FULLPATH_LEN];
110	char *line = NULL;
111	size_t len = 0;
112	ssize_t retlen;
113	int ret = -1, nr_entries = 0;
114	FILE *fp;
115	void *buf;
116	struct script_line *sline;
117
118	struct perf_script_browser script = {
119		.b = {
120			.refresh    = ui_browser__list_head_refresh,
121			.seek	    = ui_browser__list_head_seek,
122			.write	    = script_browser__write,
123		},
124		.script_name = script_name,
125	};
126
127	INIT_LIST_HEAD(&script.entries);
128
129	/* Save each line of the output in one struct script_line object. */
130	buf = zalloc((sizeof(*sline)) * MAX_LINES);
131	if (!buf)
132		return -1;
133	sline = buf;
134
135	memset(script_name, 0, SCRIPT_FULLPATH_LEN);
136	if (list_scripts(script_name))
137		goto exit;
138
139	sprintf(cmd, "perf script -s %s ", script_name);
140
141	if (script_opt)
142		strcat(cmd, script_opt);
143
144	if (input_name) {
145		strcat(cmd, " -i ");
146		strcat(cmd, input_name);
147	}
148
149	strcat(cmd, " 2>&1");
150
151	fp = popen(cmd, "r");
152	if (!fp)
153		goto exit;
154
155	while ((retlen = getline(&line, &len, fp)) != -1) {
156		strncpy(sline->line, line, AVERAGE_LINE_LEN);
157
158		/* If one output line is very large, just cut it short */
159		if (retlen >= AVERAGE_LINE_LEN) {
160			sline->line[AVERAGE_LINE_LEN - 1] = '\0';
161			sline->line[AVERAGE_LINE_LEN - 2] = '\n';
162		}
163		list_add_tail(&sline->node, &script.entries);
164
165		if (script.b.width < retlen)
166			script.b.width = retlen;
167
168		if (nr_entries++ >= MAX_LINES - 1)
169			break;
170		sline++;
171	}
172
173	if (script.b.width > AVERAGE_LINE_LEN)
174		script.b.width = AVERAGE_LINE_LEN;
175
176	free(line);
177	pclose(fp);
178
179	script.nr_lines = nr_entries;
180	script.b.nr_entries = nr_entries;
181	script.b.entries = &script.entries;
182
183	ret = script_browser__run(&script);
184exit:
185	free(buf);
186	return ret;
187}
v4.10.11
  1#include <elf.h>
  2#include <inttypes.h>
  3#include <sys/ttydefaults.h>
  4#include <string.h>
  5#include "../../util/sort.h"
  6#include "../../util/util.h"
  7#include "../../util/hist.h"
  8#include "../../util/debug.h"
  9#include "../../util/symbol.h"
 10#include "../browser.h"
 11#include "../helpline.h"
 12#include "../libslang.h"
 13
 14/* 2048 lines should be enough for a script output */
 15#define MAX_LINES		2048
 16
 17/* 160 bytes for one output line */
 18#define AVERAGE_LINE_LEN	160
 19
 20struct script_line {
 21	struct list_head node;
 22	char line[AVERAGE_LINE_LEN];
 23};
 24
 25struct perf_script_browser {
 26	struct ui_browser b;
 27	struct list_head entries;
 28	const char *script_name;
 29	int nr_lines;
 30};
 31
 32#define SCRIPT_NAMELEN	128
 33#define SCRIPT_MAX_NO	64
 34/*
 35 * Usually the full path for a script is:
 36 *	/home/username/libexec/perf-core/scripts/python/xxx.py
 37 *	/home/username/libexec/perf-core/scripts/perl/xxx.pl
 38 * So 256 should be long enough to contain the full path.
 39 */
 40#define SCRIPT_FULLPATH_LEN	256
 41
 42/*
 43 * When success, will copy the full path of the selected script
 44 * into  the buffer pointed by script_name, and return 0.
 45 * Return -1 on failure.
 46 */
 47static int list_scripts(char *script_name)
 48{
 49	char *buf, *names[SCRIPT_MAX_NO], *paths[SCRIPT_MAX_NO];
 50	int i, num, choice, ret = -1;
 51
 52	/* Preset the script name to SCRIPT_NAMELEN */
 53	buf = malloc(SCRIPT_MAX_NO * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN));
 54	if (!buf)
 55		return ret;
 56
 57	for (i = 0; i < SCRIPT_MAX_NO; i++) {
 58		names[i] = buf + i * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN);
 59		paths[i] = names[i] + SCRIPT_NAMELEN;
 60	}
 61
 62	num = find_scripts(names, paths);
 63	if (num > 0) {
 64		choice = ui__popup_menu(num, names);
 65		if (choice < num && choice >= 0) {
 66			strcpy(script_name, paths[choice]);
 67			ret = 0;
 68		}
 69	}
 70
 71	free(buf);
 72	return ret;
 73}
 74
 75static void script_browser__write(struct ui_browser *browser,
 76				   void *entry, int row)
 77{
 78	struct script_line *sline = list_entry(entry, struct script_line, node);
 79	bool current_entry = ui_browser__is_current_entry(browser, row);
 80
 81	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
 82						       HE_COLORSET_NORMAL);
 83
 84	ui_browser__write_nstring(browser, sline->line, browser->width);
 85}
 86
 87static int script_browser__run(struct perf_script_browser *browser)
 88{
 89	int key;
 90
 91	if (ui_browser__show(&browser->b, browser->script_name,
 92			     "Press ESC to exit") < 0)
 93		return -1;
 94
 95	while (1) {
 96		key = ui_browser__run(&browser->b, 0);
 97
 98		/* We can add some special key handling here if needed */
 99		break;
100	}
101
102	ui_browser__hide(&browser->b);
103	return key;
104}
105
106
107int script_browse(const char *script_opt)
108{
109	char cmd[SCRIPT_FULLPATH_LEN*2], script_name[SCRIPT_FULLPATH_LEN];
110	char *line = NULL;
111	size_t len = 0;
112	ssize_t retlen;
113	int ret = -1, nr_entries = 0;
114	FILE *fp;
115	void *buf;
116	struct script_line *sline;
117
118	struct perf_script_browser script = {
119		.b = {
120			.refresh    = ui_browser__list_head_refresh,
121			.seek	    = ui_browser__list_head_seek,
122			.write	    = script_browser__write,
123		},
124		.script_name = script_name,
125	};
126
127	INIT_LIST_HEAD(&script.entries);
128
129	/* Save each line of the output in one struct script_line object. */
130	buf = zalloc((sizeof(*sline)) * MAX_LINES);
131	if (!buf)
132		return -1;
133	sline = buf;
134
135	memset(script_name, 0, SCRIPT_FULLPATH_LEN);
136	if (list_scripts(script_name))
137		goto exit;
138
139	sprintf(cmd, "perf script -s %s ", script_name);
140
141	if (script_opt)
142		strcat(cmd, script_opt);
143
144	if (input_name) {
145		strcat(cmd, " -i ");
146		strcat(cmd, input_name);
147	}
148
149	strcat(cmd, " 2>&1");
150
151	fp = popen(cmd, "r");
152	if (!fp)
153		goto exit;
154
155	while ((retlen = getline(&line, &len, fp)) != -1) {
156		strncpy(sline->line, line, AVERAGE_LINE_LEN);
157
158		/* If one output line is very large, just cut it short */
159		if (retlen >= AVERAGE_LINE_LEN) {
160			sline->line[AVERAGE_LINE_LEN - 1] = '\0';
161			sline->line[AVERAGE_LINE_LEN - 2] = '\n';
162		}
163		list_add_tail(&sline->node, &script.entries);
164
165		if (script.b.width < retlen)
166			script.b.width = retlen;
167
168		if (nr_entries++ >= MAX_LINES - 1)
169			break;
170		sline++;
171	}
172
173	if (script.b.width > AVERAGE_LINE_LEN)
174		script.b.width = AVERAGE_LINE_LEN;
175
176	free(line);
177	pclose(fp);
178
179	script.nr_lines = nr_entries;
180	script.b.nr_entries = nr_entries;
181	script.b.entries = &script.entries;
182
183	ret = script_browser__run(&script);
184exit:
185	free(buf);
186	return ret;
187}