summaryrefslogtreecommitdiff
path: root/source/Interpreter/Options.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Interpreter/Options.cpp')
-rw-r--r--source/Interpreter/Options.cpp129
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);
}