diff options
Diffstat (limited to 'lldb/source/Interpreter/Options.cpp')
-rw-r--r-- | lldb/source/Interpreter/Options.cpp | 102 |
1 files changed, 35 insertions, 67 deletions
diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp index e015ee4c575..ba15c020f2d 100644 --- a/lldb/source/Interpreter/Options.cpp +++ b/lldb/source/Interpreter/Options.cpp @@ -930,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; } @@ -972,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) { @@ -1000,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); @@ -1009,8 +1020,13 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args, int val; 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; @@ -1116,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); @@ -1153,10 +1149,6 @@ 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; @@ -1164,8 +1156,8 @@ OptionElementVector Options::ParseForCompletion(const Args &args, 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, @@ -1328,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) { @@ -1336,38 +1327,15 @@ llvm::Expected<Args> Options::Parse(const Args &args, llvm::inconvertibleErrorCode()); } - // 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) { - 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); - // If the last option requires an argument but doesn't have one, - // some implementations of getopt_long will still try to read it. - argv.push_back(nullptr); std::unique_lock<std::mutex> lock; OptionParser::Prepare(lock); int val; while (true) { int long_options_index = -1; - val = OptionParser::Parse(argv.size() - 1, &*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"); |