1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <fstream>
18 #include <iostream>
19 
20 #include "perfetto/base/logging.h"
21 #include "tools/trace_to_text/trace_to_profile.h"
22 #include "tools/trace_to_text/trace_to_systrace.h"
23 #include "tools/trace_to_text/trace_to_text.h"
24 
25 #if PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
26 #include "perfetto_version.gen.h"
27 #else
28 #define PERFETTO_GET_GIT_REVISION() "unknown"
29 #endif
30 
31 namespace {
32 
Usage(const char * argv0)33 int Usage(const char* argv0) {
34   printf(
35       "Usage: %s systrace|json|text|profile [trace.pb] "
36       "[trace.txt]\n",
37       argv0);
38   return 1;
39 }
40 
41 }  // namespace
42 
main(int argc,char ** argv)43 int main(int argc, char** argv) {
44   for (int i = 1; i < argc; i++) {
45     if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
46       printf("%s\n", PERFETTO_GET_GIT_REVISION());
47       return 0;
48     }
49   }
50 
51   if (argc < 2)
52     return Usage(argv[0]);
53 
54   std::istream* input_stream;
55   std::ifstream file_istream;
56   if (argc > 2) {
57     const char* file_path = argv[2];
58     file_istream.open(file_path, std::ios_base::in | std::ios_base::binary);
59     if (!file_istream.is_open())
60       PERFETTO_FATAL("Could not open %s", file_path);
61     input_stream = &file_istream;
62   } else {
63     if (isatty(STDIN_FILENO)) {
64       PERFETTO_ELOG("Reading from stdin but it's connected to a TTY");
65       PERFETTO_LOG("It is unlikely that you want to type in some binary.");
66       PERFETTO_LOG("Either pass a file path to the cmdline or pipe stdin");
67       return Usage(argv[0]);
68     }
69     input_stream = &std::cin;
70   }
71 
72   std::ostream* output_stream;
73   std::ofstream file_ostream;
74   if (argc > 3) {
75     const char* file_path = argv[3];
76     file_ostream.open(file_path, std::ios_base::out | std::ios_base::trunc);
77     if (!file_ostream.is_open())
78       PERFETTO_FATAL("Could not open %s", file_path);
79     output_stream = &file_ostream;
80   } else {
81     output_stream = &std::cout;
82   }
83 
84   std::string format(argv[1]);
85 
86   if (format == "json")
87     return perfetto::trace_to_text::TraceToSystrace(input_stream, output_stream,
88                                                     /*wrap_in_json=*/true);
89   if (format == "systrace")
90     return perfetto::trace_to_text::TraceToSystrace(input_stream, output_stream,
91                                                     /*wrap_in_json=*/false);
92   if (format == "text")
93     return perfetto::trace_to_text::TraceToText(input_stream, output_stream);
94 
95   if (format == "profile")
96     return perfetto::trace_to_text::TraceToProfile(input_stream, output_stream);
97 
98   return Usage(argv[0]);
99 }
100