15ffd83dbSDimitry Andric //===-- source/Host/common/OptionParser.cpp -------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "lldb/Host/OptionParser.h"
100b57cec5SDimitry Andric #include "lldb/Host/HostGetOpt.h"
11*e8d8bef9SDimitry Andric #include "lldb/Utility/OptionDefinition.h"
120b57cec5SDimitry Andric #include "lldb/lldb-private-types.h"
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include <vector>
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric using namespace lldb_private;
170b57cec5SDimitry Andric
Prepare(std::unique_lock<std::mutex> & lock)180b57cec5SDimitry Andric void OptionParser::Prepare(std::unique_lock<std::mutex> &lock) {
190b57cec5SDimitry Andric static std::mutex g_mutex;
200b57cec5SDimitry Andric lock = std::unique_lock<std::mutex>(g_mutex);
210b57cec5SDimitry Andric #ifdef __GLIBC__
220b57cec5SDimitry Andric optind = 0;
230b57cec5SDimitry Andric #else
240b57cec5SDimitry Andric optreset = 1;
250b57cec5SDimitry Andric optind = 1;
260b57cec5SDimitry Andric #endif
270b57cec5SDimitry Andric }
280b57cec5SDimitry Andric
EnableError(bool error)290b57cec5SDimitry Andric void OptionParser::EnableError(bool error) { opterr = error ? 1 : 0; }
300b57cec5SDimitry Andric
Parse(llvm::MutableArrayRef<char * > argv,llvm::StringRef optstring,const Option * longopts,int * longindex)310b57cec5SDimitry Andric int OptionParser::Parse(llvm::MutableArrayRef<char *> argv,
320b57cec5SDimitry Andric llvm::StringRef optstring, const Option *longopts,
330b57cec5SDimitry Andric int *longindex) {
340b57cec5SDimitry Andric std::vector<option> opts;
350b57cec5SDimitry Andric while (longopts->definition != nullptr) {
360b57cec5SDimitry Andric option opt;
370b57cec5SDimitry Andric opt.flag = longopts->flag;
380b57cec5SDimitry Andric opt.val = longopts->val;
390b57cec5SDimitry Andric opt.name = longopts->definition->long_option;
400b57cec5SDimitry Andric opt.has_arg = longopts->definition->option_has_arg;
410b57cec5SDimitry Andric opts.push_back(opt);
420b57cec5SDimitry Andric ++longopts;
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric opts.push_back(option());
455ffd83dbSDimitry Andric std::string opt_cstr = std::string(optstring);
460b57cec5SDimitry Andric return getopt_long_only(argv.size() - 1, argv.data(), opt_cstr.c_str(),
470b57cec5SDimitry Andric &opts[0], longindex);
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric
GetOptionArgument()500b57cec5SDimitry Andric char *OptionParser::GetOptionArgument() { return optarg; }
510b57cec5SDimitry Andric
GetOptionIndex()520b57cec5SDimitry Andric int OptionParser::GetOptionIndex() { return optind; }
530b57cec5SDimitry Andric
GetOptionErrorCause()540b57cec5SDimitry Andric int OptionParser::GetOptionErrorCause() { return optopt; }
550b57cec5SDimitry Andric
GetShortOptionString(struct option * long_options)560b57cec5SDimitry Andric std::string OptionParser::GetShortOptionString(struct option *long_options) {
570b57cec5SDimitry Andric std::string s;
580b57cec5SDimitry Andric int i = 0;
590b57cec5SDimitry Andric bool done = false;
600b57cec5SDimitry Andric while (!done) {
610b57cec5SDimitry Andric if (long_options[i].name == nullptr && long_options[i].has_arg == 0 &&
620b57cec5SDimitry Andric long_options[i].flag == nullptr && long_options[i].val == 0) {
630b57cec5SDimitry Andric done = true;
640b57cec5SDimitry Andric } else {
650b57cec5SDimitry Andric if (long_options[i].flag == nullptr && isalpha(long_options[i].val)) {
660b57cec5SDimitry Andric s.append(1, (char)long_options[i].val);
670b57cec5SDimitry Andric switch (long_options[i].has_arg) {
680b57cec5SDimitry Andric default:
690b57cec5SDimitry Andric case no_argument:
700b57cec5SDimitry Andric break;
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric case optional_argument:
730b57cec5SDimitry Andric s.append(2, ':');
740b57cec5SDimitry Andric break;
750b57cec5SDimitry Andric case required_argument:
760b57cec5SDimitry Andric s.append(1, ':');
770b57cec5SDimitry Andric break;
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric ++i;
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric return s;
840b57cec5SDimitry Andric }
85