xref: /openbmc/linux/tools/perf/builtin-data.c (revision 06c6fad9)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/compiler.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include "builtin.h"
6 #include "perf.h"
7 #include "debug.h"
8 #include <subcmd/parse-options.h>
9 #include "data-convert.h"
10 
11 typedef int (*data_cmd_fn_t)(int argc, const char **argv);
12 
13 struct data_cmd {
14 	const char	*name;
15 	const char	*summary;
16 	data_cmd_fn_t	fn;
17 };
18 
19 static struct data_cmd data_cmds[];
20 
21 #define for_each_cmd(cmd) \
22 	for (cmd = data_cmds; cmd && cmd->name; cmd++)
23 
24 static const struct option data_options[] = {
25 	OPT_END()
26 };
27 
28 static const char * const data_subcommands[] = { "convert", NULL };
29 
30 static const char *data_usage[] = {
31 	"perf data [<common options>] <command> [<options>]",
32 	NULL
33 };
34 
35 static void print_usage(void)
36 {
37 	struct data_cmd *cmd;
38 
39 	printf("Usage:\n");
40 	printf("\t%s\n\n", data_usage[0]);
41 	printf("\tAvailable commands:\n");
42 
43 	for_each_cmd(cmd) {
44 		printf("\t %s\t- %s\n", cmd->name, cmd->summary);
45 	}
46 
47 	printf("\n");
48 }
49 
50 static const char * const data_convert_usage[] = {
51 	"perf data convert [<options>]",
52 	NULL
53 };
54 
55 static int cmd_data_convert(int argc, const char **argv)
56 {
57 	const char *to_json = NULL;
58 	const char *to_ctf = NULL;
59 	struct perf_data_convert_opts opts = {
60 		.force = false,
61 		.all = false,
62 	};
63 	const struct option options[] = {
64 		OPT_INCR('v', "verbose", &verbose, "be more verbose"),
65 		OPT_STRING('i', "input", &input_name, "file", "input file name"),
66 		OPT_STRING(0, "to-json", &to_json, NULL, "Convert to JSON format"),
67 #ifdef HAVE_LIBBABELTRACE_SUPPORT
68 		OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
69 		OPT_BOOLEAN(0, "tod", &opts.tod, "Convert time to wall clock time"),
70 #endif
71 		OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"),
72 		OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"),
73 		OPT_END()
74 	};
75 
76 	argc = parse_options(argc, argv, options,
77 			     data_convert_usage, 0);
78 	if (argc) {
79 		usage_with_options(data_convert_usage, options);
80 		return -1;
81 	}
82 
83 	if (to_json && to_ctf) {
84 		pr_err("You cannot specify both --to-ctf and --to-json.\n");
85 		return -1;
86 	}
87 	if (!to_json && !to_ctf) {
88 		pr_err("You must specify one of --to-ctf or --to-json.\n");
89 		return -1;
90 	}
91 
92 	if (to_json)
93 		return bt_convert__perf2json(input_name, to_json, &opts);
94 
95 	if (to_ctf) {
96 #ifdef HAVE_LIBBABELTRACE_SUPPORT
97 		return bt_convert__perf2ctf(input_name, to_ctf, &opts);
98 #else
99 		pr_err("The libbabeltrace support is not compiled in. perf should be "
100 		       "compiled with environment variables LIBBABELTRACE=1 and "
101 		       "LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n");
102 		return -1;
103 #endif
104 	}
105 
106 	return 0;
107 }
108 
109 static struct data_cmd data_cmds[] = {
110 	{ "convert", "converts data file between formats", cmd_data_convert },
111 	{ .name = NULL, },
112 };
113 
114 int cmd_data(int argc, const char **argv)
115 {
116 	struct data_cmd *cmd;
117 	const char *cmdstr;
118 
119 	/* No command specified. */
120 	if (argc < 2)
121 		goto usage;
122 
123 	argc = parse_options_subcommand(argc, argv, data_options, data_subcommands, data_usage,
124 			     PARSE_OPT_STOP_AT_NON_OPTION);
125 	if (argc < 1)
126 		goto usage;
127 
128 	cmdstr = argv[0];
129 
130 	for_each_cmd(cmd) {
131 		if (strcmp(cmd->name, cmdstr))
132 			continue;
133 
134 		return cmd->fn(argc, argv);
135 	}
136 
137 	pr_err("Unknown command: %s\n", cmdstr);
138 usage:
139 	print_usage();
140 	return -1;
141 }
142