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 "debug.h" |
7 | #include <subcmd/parse-options.h> |
8 | #include "data-convert.h" |
9 | #include "util/util.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 char * const data_subcommands[] = { "convert" , NULL }; |
25 | |
26 | static const char *data_usage[] = { |
27 | "perf data convert [<options>]" , |
28 | NULL |
29 | }; |
30 | |
31 | const char *to_json; |
32 | const char *to_ctf; |
33 | struct perf_data_convert_opts opts = { |
34 | .force = false, |
35 | .all = false, |
36 | }; |
37 | |
38 | const struct option data_options[] = { |
39 | OPT_INCR('v', "verbose" , &verbose, "be more verbose" ), |
40 | OPT_STRING('i', "input" , &input_name, "file" , "input file name" ), |
41 | OPT_STRING(0, "to-json" , &to_json, NULL, "Convert to JSON format" ), |
42 | #ifdef HAVE_LIBBABELTRACE_SUPPORT |
43 | OPT_STRING(0, "to-ctf" , &to_ctf, NULL, "Convert to CTF format" ), |
44 | OPT_BOOLEAN(0, "tod" , &opts.tod, "Convert time to wall clock time" ), |
45 | #endif |
46 | OPT_BOOLEAN('f', "force" , &opts.force, "don't complain, do it" ), |
47 | OPT_BOOLEAN(0, "all" , &opts.all, "Convert all events" ), |
48 | OPT_END() |
49 | }; |
50 | |
51 | static int cmd_data_convert(int argc, const char **argv) |
52 | { |
53 | |
54 | argc = parse_options(argc, argv, data_options, |
55 | data_usage, 0); |
56 | if (argc) { |
57 | usage_with_options(data_usage, data_options); |
58 | return -1; |
59 | } |
60 | |
61 | if (to_json && to_ctf) { |
62 | pr_err("You cannot specify both --to-ctf and --to-json.\n" ); |
63 | return -1; |
64 | } |
65 | #ifdef HAVE_LIBBABELTRACE_SUPPORT |
66 | if (!to_json && !to_ctf) { |
67 | pr_err("You must specify one of --to-ctf or --to-json.\n" ); |
68 | return -1; |
69 | } |
70 | #else |
71 | if (!to_json) { |
72 | pr_err("You must specify --to-json.\n" ); |
73 | return -1; |
74 | } |
75 | #endif |
76 | |
77 | if (to_json) |
78 | return bt_convert__perf2json(input_name, to_json, &opts); |
79 | |
80 | if (to_ctf) { |
81 | #if defined(HAVE_LIBBABELTRACE_SUPPORT) && defined(HAVE_LIBTRACEEVENT) |
82 | return bt_convert__perf2ctf(input_name, to_ctf, &opts); |
83 | #else |
84 | pr_err("The libbabeltrace support is not compiled in. perf should be " |
85 | "compiled with environment variables LIBBABELTRACE=1 and " |
86 | "LIBBABELTRACE_DIR=/path/to/libbabeltrace/.\n" |
87 | "Check also if libbtraceevent devel files are available.\n" ); |
88 | return -1; |
89 | #endif |
90 | } |
91 | |
92 | return 0; |
93 | } |
94 | |
95 | static struct data_cmd data_cmds[] = { |
96 | { "convert" , "converts data file between formats" , cmd_data_convert }, |
97 | { .name = NULL, }, |
98 | }; |
99 | |
100 | int cmd_data(int argc, const char **argv) |
101 | { |
102 | struct data_cmd *cmd; |
103 | const char *cmdstr; |
104 | |
105 | argc = parse_options_subcommand(argc, argv, data_options, data_subcommands, data_usage, |
106 | PARSE_OPT_STOP_AT_NON_OPTION); |
107 | |
108 | if (!argc) { |
109 | usage_with_options(data_usage, data_options); |
110 | return -1; |
111 | } |
112 | |
113 | cmdstr = argv[0]; |
114 | |
115 | for_each_cmd(cmd) { |
116 | if (strcmp(cmd->name, cmdstr)) |
117 | continue; |
118 | |
119 | return cmd->fn(argc, argv); |
120 | } |
121 | |
122 | pr_err("Unknown command: %s\n" , cmdstr); |
123 | usage_with_options(data_usage, data_options); |
124 | return -1; |
125 | } |
126 | |