summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-data.c
blob: 15ca23675ef028104ff031f6e3f79cb2c47dea51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// SPDX-License-Identifier: GPL-2.0
#include <linux/compiler.h>
#include <stdio.h>
#include <string.h>
#include "builtin.h"
#include "perf.h"
#include "debug.h"
#include <subcmd/parse-options.h>
#include "data-convert.h"

typedef int (*data_cmd_fn_t)(int argc, const char **argv);

struct data_cmd {
	const char	*name;
	const char	*summary;
	data_cmd_fn_t	fn;
};

static struct data_cmd data_cmds[];

#define for_each_cmd(cmd) \
	for (cmd = data_cmds; cmd && cmd->name; cmd++)

static const struct option data_options[] = {
	OPT_END()
};

static const char * const data_subcommands[] = { "convert", NULL };

static const char *data_usage[] = {
	"perf data [<common options>] <command> [<options>]",
	NULL
};

static void print_usage(void)
{
	struct data_cmd *cmd;

	printf("Usage:\n");
	printf("\t%s\n\n", data_usage[0]);
	printf("\tAvailable commands:\n");

	for_each_cmd(cmd) {
		printf("\t %s\t- %s\n", cmd->name, cmd->summary);
	}

	printf("\n");
}

static const char * const data_convert_usage[] = {
	"perf data convert [<options>]",
	NULL
};

static int cmd_data_convert(int argc, const char **argv)
{
	const char *to_json = NULL;
	const char *to_ctf = NULL;
	struct perf_data_convert_opts opts = {
		.force = false,
		.all = false,
	};
	const struct option options[] = {
		OPT_INCR('v', "verbose", &verbose, "be more verbose"),
		OPT_STRING('i', "input", &input_name, "file", "input file name"),
		OPT_STRING(0, "to-json", &to_json, NULL, "Convert to JSON format"),
#ifdef HAVE_LIBBABELTRACE_SUPPORT
		OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
		OPT_BOOLEAN(0, "tod", &opts.tod, "Convert time to wall clock time"),
#endif
		OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"),
		OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"),
		OPT_END()
	};

	argc = parse_options(argc, argv, options,
			     data_convert_usage, 0);
	if (argc) {
		usage_with_options(data_convert_usage, options);
		return -1;
	}

	if (to_json && to_ctf) {
		pr_err("You cannot specify both --to-ctf and --to-json.\n");
		return -1;
	}
	if (!to_json && !to_ctf) {
		pr_err("You must specify one of --to-ctf or --to-json.\n");
		return -1;
	}

	if (to_json)
		return bt_convert__perf2json(input_name, to_json, &opts);

	if (to_ctf) {
#ifdef HAVE_LIBBABELTRACE_SUPPORT
		return bt_convert__perf2ctf(input_name, to_ctf, &opts);
#else
		pr_err("The libbabeltrace support is not compiled in. perf should be "
		       "compiled with environment variables LIBBABELTRACE=1 and "
		       "LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n");
		return -1;
#endif
	}

	return 0;
}

static struct data_cmd data_cmds[] = {
	{ "convert", "converts data file between formats", cmd_data_convert },
	{ .name = NULL, },
};

int cmd_data(int argc, const char **argv)
{
	struct data_cmd *cmd;
	const char *cmdstr;

	/* No command specified. */
	if (argc < 2)
		goto usage;

	argc = parse_options_subcommand(argc, argv, data_options, data_subcommands, data_usage,
			     PARSE_OPT_STOP_AT_NON_OPTION);
	if (argc < 1)
		goto usage;

	cmdstr = argv[0];

	for_each_cmd(cmd) {
		if (strcmp(cmd->name, cmdstr))
			continue;

		return cmd->fn(argc, argv);
	}

	pr_err("Unknown command: %s\n", cmdstr);
usage:
	print_usage();
	return -1;
}