/* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "test/headless/get_options.h" #include #include #include #include #include #include namespace { constexpr struct option long_options[] = { {"device", required_argument, 0, 0}, {"loop", required_argument, 0, 0}, {"uuid", required_argument, 0, 0}, {"msleep", required_argument, 0, 0}, {"stderr", no_argument, 0, 0}, {0, 0, 0, 0}}; enum OptionType { kOptionDevice = 0, kOptionLoop = 1, kOptionUuid = 2, kOptionMsleep = 3, kOptionStdErr = 4, }; } // namespace void bluetooth::test::headless::GetOpt::Usage() const { fprintf(stdout, "%s: Usage:\n", name_); fprintf(stdout, "%s --device= Comma separated list of remote devices\n", name_); fprintf(stdout, "%s --uuid= Comma separated list of uuids\n", name_); fprintf(stdout, "%s --loop= Number of loops\n", name_); fprintf(stdout, "%s --msleep= Sleep msec between loops\n", name_); fprintf(stdout, "%s --stderr Dump stderr to stdout\n", name_); fflush(nullptr); } void bluetooth::test::headless::GetOpt::ParseValue( char* optarg, std::list& string_list) { CHECK(optarg != nullptr); char* p = optarg; char* pp = optarg; while (*p != '\0') { if (*p == ',') { *p = 0; string_list.push_back(std::string(pp)); pp = p + 1; } p++; } if (pp != p) string_list.push_back(std::string(pp)); } void bluetooth::test::headless::GetOpt::ProcessOption(int option_index, char* optarg) { std::list string_list; OptionType option_type = static_cast(option_index); switch (option_type) { case kOptionDevice: if (!optarg) return; ParseValue(optarg, string_list); for (auto& entry : string_list) { if (RawAddress::IsValidAddress(entry)) { RawAddress address; RawAddress::FromString(entry, address); device_.push_back(address); } } break; case kOptionLoop: loop_ = std::stoul(optarg, nullptr, 0); break; case kOptionUuid: if (!optarg) return; ParseValue(optarg, string_list); for (auto& entry : string_list) { uuid_.push_back( bluetooth::Uuid::From16Bit(std::stoul(entry.c_str(), nullptr, 0))); } break; case kOptionMsleep: if (!optarg) return; msec_ = std::stoul(optarg, nullptr, 0); break; case kOptionStdErr: close_stderr_ = false; break; default: fflush(nullptr); valid_ = false; return; break; } } bluetooth::test::headless::GetOpt::GetOpt(int argc, char** argv) : name_(argv[0]) { while (1) { int option_index = 0; int c = getopt_long_only(argc, argv, "d:l:u:", long_options, &option_index); if (c == -1) break; switch (c) { case 0: ProcessOption(static_cast(option_index), optarg); break; case '?': Usage(); valid_ = false; return; default: printf("?? getopt returned character code 0%o ??\n", c); } } while (optind < argc) { non_options_.push_back(argv[optind++]); } fflush(nullptr); }