diff options
Diffstat (limited to 'source/Interpreter/Options.cpp')
-rw-r--r-- | source/Interpreter/Options.cpp | 129 |
1 files changed, 54 insertions, 75 deletions
diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp index c6357399a7e26..ba15c020f2daa 100644 --- a/source/Interpreter/Options.cpp +++ b/source/Interpreter/Options.cpp @@ -1,9 +1,8 @@ //===-- Options.cpp ---------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -25,9 +24,7 @@ using namespace lldb; using namespace lldb_private; -//------------------------------------------------------------------------- // Options -//------------------------------------------------------------------------- Options::Options() : m_getopt_table() { BuildValidOptionSets(); } Options::~Options() {} @@ -761,7 +758,7 @@ bool Options::HandleOptionArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector, int opt_element_index, CommandInterpreter &interpreter) { auto opt_defs = GetDefinitions(); - std::unique_ptr<SearchFilter> filter_ap; + std::unique_ptr<SearchFilter> filter_up; int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; @@ -832,7 +829,7 @@ bool Options::HandleOptionArgumentCompletion( interpreter.GetDebugger().GetSelectedTarget(); // Search filters require a target... if (target_sp) - filter_ap.reset(new SearchFilterByModule(target_sp, module_spec)); + filter_up.reset(new SearchFilterByModule(target_sp, module_spec)); } break; } @@ -840,7 +837,7 @@ bool Options::HandleOptionArgumentCompletion( } return CommandCompletions::InvokeCommonCompletionCallbacks( - interpreter, completion_mask, request, filter_ap.get()); + interpreter, completion_mask, request, filter_up.get()); } void OptionGroupOptions::Append(OptionGroup *group) { @@ -933,6 +930,7 @@ static std::vector<char *> GetArgvForParsing(const Args &args) { result.push_back(const_cast<char *>("<FAKE-ARG0>")); for (const Args::ArgEntry &entry : args) result.push_back(const_cast<char *>(entry.c_str())); + result.push_back(nullptr); return result; } @@ -975,19 +973,15 @@ static size_t FindArgumentIndexForOption(const Args &args, return size_t(-1); } -llvm::Expected<Args> Options::ParseAlias(const Args &args, - OptionArgVector *option_arg_vector, - std::string &input_line) { - StreamString sstr; - int i; - Option *long_options = GetLongOptions(); +static std::string BuildShortOptions(const Option *long_options) { + std::string storage; + llvm::raw_string_ostream sstr(storage); - if (long_options == nullptr) { - return llvm::make_error<llvm::StringError>("Invalid long options", - llvm::inconvertibleErrorCode()); - } + // Leading : tells getopt to return a : for a missing option argument AND to + // suppress error messages. + sstr << ":"; - for (i = 0; long_options[i].definition != nullptr; ++i) { + for (size_t i = 0; long_options[i].definition != nullptr; ++i) { if (long_options[i].flag == nullptr) { sstr << (char)long_options[i].val; switch (long_options[i].definition->option_has_arg) { @@ -1003,6 +997,20 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args, } } } + return std::move(sstr.str()); +} + +llvm::Expected<Args> Options::ParseAlias(const Args &args, + OptionArgVector *option_arg_vector, + std::string &input_line) { + Option *long_options = GetLongOptions(); + + if (long_options == nullptr) { + return llvm::make_error<llvm::StringError>("Invalid long options", + llvm::inconvertibleErrorCode()); + } + + std::string short_options = BuildShortOptions(long_options); Args args_copy = args; std::vector<char *> argv = GetArgvForParsing(args); @@ -1010,10 +1018,15 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args, std::unique_lock<std::mutex> lock; OptionParser::Prepare(lock); int val; - while (1) { + while (true) { int long_options_index = -1; - val = OptionParser::Parse(argv.size(), &*argv.begin(), sstr.GetString(), - long_options, &long_options_index); + val = OptionParser::Parse(argv, short_options, long_options, + &long_options_index); + + if (val == ':') { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "last option requires an argument"); + } if (val == -1) break; @@ -1119,33 +1132,13 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args, OptionElementVector Options::ParseForCompletion(const Args &args, uint32_t cursor_index) { OptionElementVector option_element_vector; - StreamString sstr; Option *long_options = GetLongOptions(); option_element_vector.clear(); if (long_options == nullptr) return option_element_vector; - // Leading : tells getopt to return a : for a missing option argument AND to - // suppress error messages. - - sstr << ":"; - for (int i = 0; long_options[i].definition != nullptr; ++i) { - if (long_options[i].flag == nullptr) { - sstr << (char)long_options[i].val; - switch (long_options[i].definition->option_has_arg) { - default: - case OptionParser::eNoArgument: - break; - case OptionParser::eRequiredArgument: - sstr << ":"; - break; - case OptionParser::eOptionalArgument: - sstr << "::"; - break; - } - } - } + std::string short_options = BuildShortOptions(long_options); std::unique_lock<std::mutex> lock; OptionParser::Prepare(lock); @@ -1156,19 +1149,15 @@ OptionElementVector Options::ParseForCompletion(const Args &args, std::vector<char *> dummy_vec = GetArgvForParsing(args); - // I stick an element on the end of the input, because if the last element - // is option that requires an argument, getopt_long_only will freak out. - dummy_vec.push_back(const_cast<char *>("<FAKE-VALUE>")); - bool failed_once = false; uint32_t dash_dash_pos = -1; - while (1) { + while (true) { bool missing_argument = false; int long_options_index = -1; - val = OptionParser::Parse(dummy_vec.size(), &dummy_vec[0], sstr.GetString(), - long_options, &long_options_index); + val = OptionParser::Parse(dummy_vec, short_options, long_options, + &long_options_index); if (val == -1) { // When we're completing a "--" which is the last option on line, @@ -1331,7 +1320,6 @@ llvm::Expected<Args> Options::Parse(const Args &args, ExecutionContext *execution_context, lldb::PlatformSP platform_sp, bool require_validation) { - StreamString sstr; Status error; Option *long_options = GetLongOptions(); if (long_options == nullptr) { @@ -1339,32 +1327,21 @@ llvm::Expected<Args> Options::Parse(const Args &args, llvm::inconvertibleErrorCode()); } - for (int i = 0; long_options[i].definition != nullptr; ++i) { - if (long_options[i].flag == nullptr) { - if (isprint8(long_options[i].val)) { - sstr << (char)long_options[i].val; - switch (long_options[i].definition->option_has_arg) { - default: - case OptionParser::eNoArgument: - break; - case OptionParser::eRequiredArgument: - sstr << ':'; - break; - case OptionParser::eOptionalArgument: - sstr << "::"; - break; - } - } - } - } + std::string short_options = BuildShortOptions(long_options); std::vector<char *> argv = GetArgvForParsing(args); std::unique_lock<std::mutex> lock; OptionParser::Prepare(lock); int val; - while (1) { + while (true) { int long_options_index = -1; - val = OptionParser::Parse(argv.size(), &*argv.begin(), sstr.GetString(), - long_options, &long_options_index); + val = OptionParser::Parse(argv, short_options, long_options, + &long_options_index); + + if (val == ':') { + error.SetErrorStringWithFormat("last option requires an argument"); + break; + } + if (val == -1) break; @@ -1437,10 +1414,12 @@ llvm::Expected<Args> Options::Parse(const Args &args, } else { error.SetErrorStringWithFormat("invalid option with value '%i'", val); } - if (error.Fail()) - return error.ToError(); } + if (error.Fail()) + return error.ToError(); + + argv.pop_back(); argv.erase(argv.begin(), argv.begin() + OptionParser::GetOptionIndex()); return ReconstituteArgsAfterParsing(argv, args); } |