10 #include "common-cmds.h"
15 static struct man_viewer_list {
16 struct man_viewer_list *
next;
20 static struct man_viewer_info_list {
21 struct man_viewer_info_list *
next;
24 } *man_viewer_info_list;
35 if (!
strcmp(format,
"man"))
37 if (!
strcmp(format,
"info"))
42 pr_err(
"unrecognized help format '%s'", format);
46 static const char *get_man_viewer_info(
const char *
name)
48 struct man_viewer_info_list *viewer;
50 for (viewer = man_viewer_info_list; viewer; viewer = viewer->next) {
57 static int check_emacsclient_version(
void)
61 const char *argv_ec[] = {
"emacsclient",
"--version",
NULL };
65 memset(&ec_process, 0,
sizeof(ec_process));
66 ec_process.argv = argv_ec;
68 ec_process.stdout_to_stderr = 1;
70 fprintf(stderr,
"Failed to start emacsclient.\n");
74 close(ec_process.err);
83 fprintf(stderr,
"Failed to parse emacsclient version.\n");
89 version = atoi(buffer.
buf);
93 "emacsclient version '%d' too old (< 22).\n",
103 static void exec_woman_emacs(
const char *
path,
const char *
page)
105 if (!check_emacsclient_version()) {
110 path =
"emacsclient";
112 execlp(path,
"emacsclient",
"-e", man_page.
buf,
NULL);
117 static void exec_man_konqueror(
const char *path,
const char *page)
119 const char *
display = getenv(
"DISPLAY");
120 if (display && *display) {
127 if (file && !
strcmp(file + 1,
"konqueror")) {
128 char *
new = strdup(path);
132 strcpy(dest + 1,
"kfmclient");
140 execlp(path, filename,
"newTab", man_page.
buf,
NULL);
145 static void exec_man_man(
const char *path,
const char *page)
149 execlp(path,
"man", page,
NULL);
153 static void exec_man_cmd(
const char *
cmd,
const char *page)
157 execl(
"/bin/sh",
"sh",
"-c", shell_cmd.
buf,
NULL);
161 static void add_man_viewer(
const char *name)
163 struct man_viewer_list **
p = &man_viewer_list;
168 *p =
zalloc(
sizeof(**p) + len + 1);
169 strncpy((*p)->name, name, len);
172 static int supported_man_viewer(
const char *name,
size_t len)
179 static void do_add_man_viewer_info(
const char *name,
183 struct man_viewer_info_list *
new =
zalloc(
sizeof(*
new) + len + 1);
186 new->info = strdup(value);
187 new->next = man_viewer_info_list;
188 man_viewer_info_list =
new;
191 static int add_man_viewer_path(
const char *name,
195 if (supported_man_viewer(name, len))
196 do_add_man_viewer_info(name, len, value);
198 warning(
"'%s': path for unsupported man viewer.\n"
199 "Please consider using 'man.<tool>.cmd' instead.",
205 static int add_man_viewer_cmd(
const char *name,
209 if (supported_man_viewer(name, len))
210 warning(
"'%s': cmd for supported man viewer.\n"
211 "Please consider using 'man.<tool>.path' instead.",
214 do_add_man_viewer_info(name, len, value);
219 static int add_man_viewer_info(
const char *var,
const char *value)
221 const char *name = var + 4;
222 const char *subkey =
strrchr(name,
'.');
225 return error(
"Config with no key for man viewer: %s", name);
227 if (!
strcmp(subkey,
".path")) {
230 return add_man_viewer_path(name, subkey - name, value);
232 if (!
strcmp(subkey,
".cmd")) {
235 return add_man_viewer_cmd(name, subkey - name, value);
238 warning(
"'%s': unsupported man viewer sub key.", subkey);
242 static int perf_help_config(
const char *var,
const char *value,
void *
cb)
246 if (!
strcmp(var,
"help.format")) {
249 *help_formatp = parse_help_format(value);
254 if (!
strcmp(var,
"man.viewer")) {
257 add_man_viewer(value);
261 return add_man_viewer_info(var, value);
266 static struct cmdnames main_cmds, other_cmds;
270 unsigned int i, longest = 0;
272 for (i = 0; i <
ARRAY_SIZE(common_cmds); i++) {
273 if (longest <
strlen(common_cmds[i].name))
274 longest =
strlen(common_cmds[i].name);
277 puts(
" The most commonly used perf commands are:");
278 for (i = 0; i <
ARRAY_SIZE(common_cmds); i++) {
279 printf(
" %-*s ", longest, common_cmds[i].name);
280 puts(common_cmds[i].help);
284 static int is_perf_command(
const char *
s)
290 static const char *prepend(
const char *
prefix,
const char *cmd)
292 size_t pre_len =
strlen(prefix);
294 char *p =
malloc(pre_len + cmd_len + 1);
295 memcpy(p, prefix, pre_len);
300 static const char *cmd_to_page(
const char *perf_cmd)
307 return prepend(
"perf-", perf_cmd);
310 static void setup_man_path(
void)
313 const char *old_path = getenv(
"MANPATH");
319 strbuf_addstr(&new_path,
system_path(PERF_MAN_PATH));
320 strbuf_addch(&new_path,
':');
322 strbuf_addstr(&new_path, old_path);
324 setenv(
"MANPATH", new_path.
buf, 1);
329 static void exec_viewer(
const char *name,
const char *page)
331 const char *
info = get_man_viewer_info(name);
334 exec_man_man(info, page);
336 exec_woman_emacs(info, page);
338 exec_man_konqueror(info, page);
340 exec_man_cmd(info, page);
342 warning(
"'%s': unknown man viewer.", name);
345 static int show_man_page(
const char *perf_cmd)
347 struct man_viewer_list *viewer;
348 const char *page = cmd_to_page(perf_cmd);
349 const char *fallback = getenv(
"PERF_MAN_VIEWER");
352 for (viewer = man_viewer_list; viewer; viewer = viewer->next)
353 exec_viewer(viewer->name, page);
356 exec_viewer(fallback, page);
357 exec_viewer(
"man", page);
359 pr_err(
"no man viewer handled the request");
363 static int show_info_page(
const char *perf_cmd)
365 const char *page = cmd_to_page(perf_cmd);
366 setenv(
"INFOPATH",
system_path(PERF_INFO_PATH), 1);
367 execlp(
"info",
"info",
"perfman", page,
NULL);
371 static int get_html_page_path(
struct strbuf *page_path,
const char *page)
374 const char *html_path =
system_path(PERF_HTML_PATH);
379 pr_err(
"'%s': not a documentation directory.", html_path);
384 strbuf_addf(page_path,
"%s/%s.html", html_path, page);
395 static void open_html(
const char *path)
401 static int show_html_page(
const char *perf_cmd)
403 const char *page = cmd_to_page(perf_cmd);
406 if (get_html_page_path(&page_path, page) != 0)
409 open_html(page_path.
buf);
418 struct option builtin_help_options[] = {
419 OPT_BOOLEAN(
'a',
"all", &show_all,
"print all available commands"),
421 OPT_SET_UINT(
'w',
"web", &help_format,
"show manual in web browser",
423 OPT_SET_UINT(
'i',
"info", &help_format,
"show info page",
427 const char *
const builtin_help_usage[] = {
428 "perf help [--all] [--man|--web|--info] [command]",
439 builtin_help_usage, 0);
456 if (alias && !is_perf_command(argv[0])) {
457 printf(
"`perf %s' is aliased to `%s'\n", argv[0], alias);
461 switch (help_format) {
463 rc = show_man_page(argv[0]);
466 rc = show_info_page(argv[0]);
469 rc = show_html_page(argv[0]);