blob: 4c5fd0c221ed30ef459f056d4b40b56abc755e13 [file] [log] [blame]
Robert Tarasovdf3962b2019-07-28 00:56:25 -07001
2/**************************************************************************
3 *
4 * Copyright 2011 Jose Fonseca
5 * Copyright 2010 VMware, Inc.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#include <string.h>
30#include <limits.h> // for CHAR_MAX
31#include <getopt.h>
32#ifndef _WIN32
33#include <unistd.h> // for isatty()
34#endif
35
36#include <memory>
37#include <fstream>
38#include <string>
39#include <regex>
40
41#include "cxx_compat.hpp" // for std::to_string, std::make_unique
42
43#include "cli.hpp"
44#include "cli_pager.hpp"
45
46#include "trace_parser.hpp"
47#include "trace_dump_internal.hpp"
48#include "trace_callset.hpp"
49#include "trace_option.hpp"
50
51static trace::CallSet calls(trace::FREQUENCY_ALL);
Robert Tarasovaaa95fc2020-01-30 14:26:37 +000052static const char *synopsis = "Print given trace file(s) information.";
Robert Tarasovdf3962b2019-07-28 00:56:25 -070053
54static void
55usage(void)
56{
57 std::cout
58 << "usage: apitrace info [OPTIONS] TRACE_FILE...\n"
59 << synopsis << "\n"
60 "\n"
Robert Tarasovaaa95fc2020-01-30 14:26:37 +000061 " -h, --help show this help message and exit\n"
62 " --json output trace file information in JSON format\n"
Robert Tarasovdf3962b2019-07-28 00:56:25 -070063 "\n"
64 ;
65}
66
67enum {
Robert Tarasovaaa95fc2020-01-30 14:26:37 +000068 JSON_OPT = CHAR_MAX + 1,
Robert Tarasovdf3962b2019-07-28 00:56:25 -070069};
70
71const static char *
Robert Tarasovaaa95fc2020-01-30 14:26:37 +000072shortOptions = "h";
Robert Tarasovdf3962b2019-07-28 00:56:25 -070073
74const static struct option
75longOptions[] = {
76 {"help", no_argument, 0, 'h'},
77 {"json", no_argument, 0, JSON_OPT},
78 {0, 0, 0, 0}
79};
80
Robert Tarasovaaa95fc2020-01-30 14:26:37 +000081static const char*
82getApiName(int api) {
83 if (api < trace::API_UNKNOWN || api >= trace::API_MAX)
84 api = trace::API_UNKNOWN;
85 return trace::API_NAMES[api];
Robert Tarasovdf3962b2019-07-28 00:56:25 -070086}
87
88static int
89command(int argc, char *argv[])
90{
Robert Tarasovdf3962b2019-07-28 00:56:25 -070091 bool json = false;
Robert Tarasovdf3962b2019-07-28 00:56:25 -070092 int opt;
93 while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
94 switch (opt) {
95 case 'h':
96 usage();
97 return 0;
98 case JSON_OPT:
99 json = true;
100 break;
101 default:
102 std::cerr << "error: unexpected option `" << (char)opt << "`\n";
103 usage();
104 return 1;
105 }
106 }
107
108 for (int i = optind; i < argc; ++i) {
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000109 unsigned long framesCount = 0;
110 trace::API api = trace::API_UNKNOWN;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700111 trace::Parser p;
112
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000113 if (!p.open(argv[i])) {
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700114 return 1;
115 }
116
117 trace::Call *call;
118 while ((call = p.parse_call())) {
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000119 if (api == trace::API_UNKNOWN && p.api != trace::API_UNKNOWN)
120 api = p.api;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700121 if (call->flags & trace::CALL_FLAG_END_FRAME)
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000122 ++framesCount;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700123 delete call;
124 }
125
126 if (json) {
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000127 std::cout <<
128 "{" <<
129 "\"FileName\":\"" << argv[i] << "\"," <<
130 "\"ContainerVersion\":" << p.getVersion() << "," <<
131 "\"API\":\"" << getApiName(api) << "\"," <<
132 "\"FramesCount\":" << framesCount << "" <<
133 "}" << std::endl;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700134 } else {
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000135 std::cout <<
136 std::endl <<
137 "FileName: " << argv[i] << std::endl <<
138 "ContainerVersion: " << p.getVersion() << std::endl <<
139 "API: " << getApiName(api) << std::endl <<
140 "FramesCount: " << framesCount << std::endl <<
141 std::endl;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700142 }
143 }
144
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000145 return 0;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700146}
147
148const Command info_command = {
149 "info",
150 synopsis,
151 usage,
152 command
153};