This revision was automatically updated to reflect the committed changes. Closed by commit rL365665: Options: Reduce code duplication (authored by labath, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits.
Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63770/new/ https://reviews.llvm.org/D63770 Files: lldb/trunk/include/lldb/Host/OptionParser.h lldb/trunk/source/Host/common/OptionParser.cpp lldb/trunk/source/Interpreter/CommandAlias.cpp lldb/trunk/source/Interpreter/Options.cpp
Index: lldb/trunk/source/Interpreter/CommandAlias.cpp =================================================================== --- lldb/trunk/source/Interpreter/CommandAlias.cpp +++ lldb/trunk/source/Interpreter/CommandAlias.cpp @@ -30,6 +30,8 @@ Args args(options_args); std::string options_string(options_args); + // TODO: Find a way to propagate errors in this CommandReturnObject up the + // stack. CommandReturnObject result; // Check to see if the command being aliased can take any command options. Options *options = cmd_obj_sp->GetOptions(); Index: lldb/trunk/source/Interpreter/Options.cpp =================================================================== --- lldb/trunk/source/Interpreter/Options.cpp +++ lldb/trunk/source/Interpreter/Options.cpp @@ -930,6 +930,7 @@ 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 @@ 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 @@ } } } + 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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::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"); Index: lldb/trunk/source/Host/common/OptionParser.cpp =================================================================== --- lldb/trunk/source/Host/common/OptionParser.cpp +++ lldb/trunk/source/Host/common/OptionParser.cpp @@ -27,8 +27,9 @@ void OptionParser::EnableError(bool error) { opterr = error ? 1 : 0; } -int OptionParser::Parse(int argc, char *const argv[], llvm::StringRef optstring, - const Option *longopts, int *longindex) { +int OptionParser::Parse(llvm::MutableArrayRef<char *> argv, + llvm::StringRef optstring, const Option *longopts, + int *longindex) { std::vector<option> opts; while (longopts->definition != nullptr) { option opt; @@ -41,7 +42,8 @@ } opts.push_back(option()); std::string opt_cstr = optstring; - return getopt_long_only(argc, argv, opt_cstr.c_str(), &opts[0], longindex); + return getopt_long_only(argv.size() - 1, argv.data(), opt_cstr.c_str(), + &opts[0], longindex); } char *OptionParser::GetOptionArgument() { return optarg; } Index: lldb/trunk/include/lldb/Host/OptionParser.h =================================================================== --- lldb/trunk/include/lldb/Host/OptionParser.h +++ lldb/trunk/include/lldb/Host/OptionParser.h @@ -13,6 +13,7 @@ #include <string> #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/ArrayRef.h" struct option; @@ -37,8 +38,11 @@ static void EnableError(bool error); - static int Parse(int argc, char *const argv[], llvm::StringRef optstring, - const Option *longopts, int *longindex); + /// Argv must be an argument vector "as passed to main", i.e. terminated with + /// a nullptr. + static int Parse(llvm::MutableArrayRef<char *> argv, + llvm::StringRef optstring, const Option *longopts, + int *longindex); static char *GetOptionArgument(); static int GetOptionIndex();
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits