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