1 // Copyright (C) 2021 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <ditto/arg_parser.h>
16
17 namespace dittosuite {
18
ArgToResultsOutput(const std::string_view optarg)19 ResultsOutput ArgToResultsOutput(const std::string_view optarg) {
20 if (optarg == "csv" || optarg == "1") {
21 return ResultsOutput::kCsv;
22 }
23 if (optarg == "null" || optarg == "-1") {
24 return ResultsOutput::kCsv;
25 }
26 return ResultsOutput::kReport; // by default, the results output is the report (= 0)
27 }
28
ArgToLogStream(const std::string_view optarg)29 LogStream ArgToLogStream(const std::string_view optarg) {
30 if (optarg == "logcat" || optarg == "1") {
31 #ifdef __ANDROID__
32 return LogStream::kLogcat;
33 #else
34 PLOGF("Cannot set log stream as logcat outside of Android");
35 #endif
36 }
37 return LogStream::kStdout; // by default, the log stream is stdout
38 }
39
ArgToLogLevel(const std::string_view optarg)40 LogLevel ArgToLogLevel(const std::string_view optarg) {
41 if (optarg == "VERBOSE" || optarg == "0") {
42 return LogLevel::kVerbose;
43 }
44 if (optarg == "DEBUG" || optarg == "1") {
45 return LogLevel::kDebug;
46 }
47 if (optarg == "INFO" || optarg == "2") {
48 return LogLevel::kInfo;
49 }
50 if (optarg == "WARNING" || optarg == "3") {
51 return LogLevel::kWarning;
52 }
53 if (optarg == "ERROR" || optarg == "4") {
54 return LogLevel::kError;
55 }
56 if (optarg == "FATAL" || optarg == "5") {
57 return LogLevel::kFatal;
58 }
59 return LogLevel::kInfo; // by default, the log level is info
60 }
61
PrintHelpAndExit(std::string_view program_name)62 void PrintHelpAndExit(std::string_view program_name) {
63 std::cerr << "Usage: " << program_name << " [OPTION]... [FILE]\n"
64 << "Benchmarking tool for generic workloads.\n\n"
65
66 << " -f, --format[=FMT]"
67 << "\tresults output format, where FMT can be one of:\n"
68 << "\t\t\t - report (or 0, default): human readable summary;\n"
69 << "\t\t\t - csv (or 1): for comma-separated detailed stats;\n"
70 << "\t\t\t - null (-1): do not print.\n"
71
72 << " -p, --param[=PAR]..."
73 << "\tif the benchmark is parametric, all the parameters can be passed\n"
74 << "\t\t\tthrough PAR (comma separated)\n"
75
76 << " -l, --log[=LOG]"
77 << "\toutput stream for the log messages.\n"
78 << "\t\t\tLOG can be one of: stdout (or 0, default), logcat (or 1)\n"
79
80 << " -v, --verbosity[=VER]"
81 << "\toutput messages verbosity.\n"
82 << "\t\t\tVER can be one of: VERBOSE (or 5), DEBUG (or 4), INFO (or 3, default),\n"
83 << "\t\t\tWARNING (or 2), ERROR (or 1), FATAL (or 0)\n"
84
85 << " -h, --help"
86 << "\t\tdisplay this help and exit\n";
87
88 exit(EXIT_SUCCESS);
89 }
90
ParseArguments(int argc,char ** argv)91 CmdArguments ParseArguments(int argc, char** argv) {
92 CmdArguments arguments;
93
94 while (true) {
95 int option_index = 0;
96 static struct option long_options[] = {{"format", required_argument, 0, 'f'},
97 {"param", required_argument, 0, 'p'},
98 {"log", required_argument, 0, 'l'},
99 {"verbosity", required_argument, 0, 'v'},
100 {"help", no_argument, 0, 'h'},
101 {0, 0, 0, 0}};
102
103 int c = getopt_long(argc, argv, "f:l:v:p:h", long_options, &option_index);
104 if (c == -1) break;
105
106 switch (c) {
107 case 'f':
108 arguments.results_output = ArgToResultsOutput(optarg);
109 break;
110 case 'l':
111 dittosuite::Logger::GetInstance().SetLogStream(ArgToLogStream(optarg));
112 break;
113 case 'v':
114 dittosuite::Logger::GetInstance().SetLogLevel(ArgToLogLevel(optarg));
115 break;
116 case 'p': {
117 char* token = strtok(optarg, ",");
118 while (token != nullptr) {
119 arguments.parameters.push_back(token);
120 token = strtok(nullptr, ",");
121 }
122 break;
123 }
124 case 'h':
125 [[fallthrough]];
126 default: {
127 PrintHelpAndExit(argv[0]);
128 break;
129 }
130 }
131 }
132
133 if (optind >= argc) {
134 LOGE("Expected .ditto file");
135 PrintHelpAndExit(argv[0]);
136 }
137
138 arguments.file_path = argv[optind];
139
140 return arguments;
141 }
142
143 } // namespace dittosuite
144