diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Interpreter')
46 files changed, 10507 insertions, 12302 deletions
diff --git a/contrib/llvm/tools/lldb/source/Interpreter/Args.cpp b/contrib/llvm/tools/lldb/source/Interpreter/Args.cpp index d90ef1d..6984328 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/Args.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/Args.cpp @@ -12,1764 +12,1489 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Interpreter/Args.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Host/StringConvert.h" -#include "lldb/Interpreter/Options.h" +#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/Options.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSwitch.h" + using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- -// Args constructor -//---------------------------------------------------------------------- -Args::Args (llvm::StringRef command) : - m_args(), - m_argv(), - m_args_quote_char() -{ - SetCommandString (command); -} - -//---------------------------------------------------------------------- -// We have to be very careful on the copy constructor of this class -// to make sure we copy all of the string values, but we can't copy the -// rhs.m_argv into m_argv since it will point to the "const char *" c -// strings in rhs.m_args. We need to copy the string list and update our -// own m_argv appropriately. -//---------------------------------------------------------------------- -Args::Args (const Args &rhs) : - m_args (rhs.m_args), - m_argv (), - m_args_quote_char(rhs.m_args_quote_char) -{ - UpdateArgvFromArgs(); -} - -//---------------------------------------------------------------------- -// We have to be very careful on the copy constructor of this class -// to make sure we copy all of the string values, but we can't copy the -// rhs.m_argv into m_argv since it will point to the "const char *" c -// strings in rhs.m_args. We need to copy the string list and update our -// own m_argv appropriately. -//---------------------------------------------------------------------- -const Args & -Args::operator= (const Args &rhs) -{ - // Make sure we aren't assigning to self - if (this != &rhs) - { - m_args = rhs.m_args; - m_args_quote_char = rhs.m_args_quote_char; - UpdateArgvFromArgs(); +// A helper function for argument parsing. +// Parses the initial part of the first argument using normal double quote +// rules: +// backslash escapes the double quote and itself. The parsed string is appended +// to the second +// argument. The function returns the unparsed portion of the string, starting +// at the closing +// quote. +static llvm::StringRef ParseDoubleQuotes(llvm::StringRef quoted, + std::string &result) { + // Inside double quotes, '\' and '"' are special. + static const char *k_escapable_characters = "\"\\"; + while (true) { + // Skip over over regular characters and append them. + size_t regular = quoted.find_first_of(k_escapable_characters); + result += quoted.substr(0, regular); + quoted = quoted.substr(regular); + + // If we have reached the end of string or the closing quote, we're done. + if (quoted.empty() || quoted.front() == '"') + break; + + // We have found a backslash. + quoted = quoted.drop_front(); + + if (quoted.empty()) { + // A lone backslash at the end of string, let's just append it. + result += '\\'; + break; } - return *this; -} -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -Args::~Args () -{ -} + // If the character after the backslash is not a whitelisted escapable + // character, we + // leave the character sequence untouched. + if (strchr(k_escapable_characters, quoted.front()) == nullptr) + result += '\\'; -void -Args::Dump (Stream &s, const char *label_name) const -{ - if (!label_name) - return; - - const size_t argc = m_argv.size(); - for (size_t i=0; i<argc; ++i) - { - s.Indent(); - const char *arg_cstr = m_argv[i]; - if (arg_cstr) - s.Printf("%s[%zi]=\"%s\"\n", label_name, i, arg_cstr); - else - s.Printf("%s[%zi]=NULL\n", label_name, i); - } - s.EOL(); -} + result += quoted.front(); + quoted = quoted.drop_front(); + } -bool -Args::GetCommandString (std::string &command) const -{ - command.clear(); - const size_t argc = GetArgumentCount(); - for (size_t i=0; i<argc; ++i) - { - if (i > 0) - command += ' '; - command += m_argv[i]; - } - return argc > 0; + return quoted; } -bool -Args::GetQuotedCommandString (std::string &command) const -{ - command.clear (); - const size_t argc = GetArgumentCount(); - for (size_t i = 0; i < argc; ++i) - { - if (i > 0) - command.append (1, ' '); - char quote_char = GetArgumentQuoteCharAtIndex(i); - if (quote_char) - { - command.append (1, quote_char); - command.append (m_argv[i]); - command.append (1, quote_char); - } - else - command.append (m_argv[i]); - } - return argc > 0; +static size_t ArgvToArgc(const char **argv) { + if (!argv) + return 0; + size_t count = 0; + while (*argv++) + ++count; + return count; } -// A helper function for argument parsing. -// Parses the initial part of the first argument using normal double quote rules: -// backslash escapes the double quote and itself. The parsed string is appended to the second -// argument. The function returns the unparsed portion of the string, starting at the closing -// quote. -static llvm::StringRef -ParseDoubleQuotes(llvm::StringRef quoted, std::string &result) -{ - // Inside double quotes, '\' and '"' are special. - static const char *k_escapable_characters = "\"\\"; - while (true) - { - // Skip over over regular characters and append them. - size_t regular = quoted.find_first_of(k_escapable_characters); - result += quoted.substr(0, regular); - quoted = quoted.substr(regular); - - // If we have reached the end of string or the closing quote, we're done. - if (quoted.empty() || quoted.front() == '"') - break; - - // We have found a backslash. - quoted = quoted.drop_front(); - - if (quoted.empty()) - { - // A lone backslash at the end of string, let's just append it. - result += '\\'; - break; - } - - // If the character after the backslash is not a whitelisted escapable character, we - // leave the character sequence untouched. - if (strchr(k_escapable_characters, quoted.front()) == nullptr) - result += '\\'; +// A helper function for SetCommandString. Parses a single argument from the +// command string, processing quotes and backslashes in a shell-like manner. +// The function returns a tuple consisting of the parsed argument, the quote +// char used, and the unparsed portion of the string starting at the first +// unqouted, unescaped whitespace character. +static std::tuple<std::string, char, llvm::StringRef> +ParseSingleArgument(llvm::StringRef command) { + // Argument can be split into multiple discontiguous pieces, for example: + // "Hello ""World" + // this would result in a single argument "Hello World" (without the quotes) + // since the quotes would be removed and there is not space between the + // strings. + std::string arg; + + // Since we can have multiple quotes that form a single command + // in a command like: "Hello "world'!' (which will make a single + // argument "Hello world!") we remember the first quote character + // we encounter and use that for the quote character. + char first_quote_char = '\0'; + + bool arg_complete = false; + do { + // Skip over over regular characters and append them. + size_t regular = command.find_first_of(" \t\"'`\\"); + arg += command.substr(0, regular); + command = command.substr(regular); + + if (command.empty()) + break; + + char special = command.front(); + command = command.drop_front(); + switch (special) { + case '\\': + if (command.empty()) { + arg += '\\'; + break; + } + + // If the character after the backslash is not a whitelisted escapable + // character, we + // leave the character sequence untouched. + if (strchr(" \t\\'\"`", command.front()) == nullptr) + arg += '\\'; + + arg += command.front(); + command = command.drop_front(); + + break; + + case ' ': + case '\t': + // We are not inside any quotes, we just found a space after an + // argument. We are done. + arg_complete = true; + break; + + case '"': + case '\'': + case '`': + // We found the start of a quote scope. + if (first_quote_char == '\0') + first_quote_char = special; + + if (special == '"') + command = ParseDoubleQuotes(command, arg); + else { + // For single quotes, we simply skip ahead to the matching quote + // character + // (or the end of the string). + size_t quoted = command.find(special); + arg += command.substr(0, quoted); + command = command.substr(quoted); + } + + // If we found a closing quote, skip it. + if (!command.empty()) + command = command.drop_front(); - result += quoted.front(); - quoted = quoted.drop_front(); + break; } + } while (!arg_complete); - return quoted; + return std::make_tuple(arg, first_quote_char, command); } -// A helper function for SetCommandString. -// Parses a single argument from the command string, processing quotes and backslashes in a -// shell-like manner. The parsed argument is appended to the m_args array. The function returns -// the unparsed portion of the string, starting at the first unqouted, unescaped whitespace -// character. -llvm::StringRef -Args::ParseSingleArgument(llvm::StringRef command) -{ - // Argument can be split into multiple discontiguous pieces, - // for example: - // "Hello ""World" - // this would result in a single argument "Hello World" (without/ - // the quotes) since the quotes would be removed and there is - // not space between the strings. - - std::string arg; - - // Since we can have multiple quotes that form a single command - // in a command like: "Hello "world'!' (which will make a single - // argument "Hello world!") we remember the first quote character - // we encounter and use that for the quote character. - char first_quote_char = '\0'; - - bool arg_complete = false; - do - { - // Skip over over regular characters and append them. - size_t regular = command.find_first_of(" \t\"'`\\"); - arg += command.substr(0, regular); - command = command.substr(regular); - - if (command.empty()) - break; - - char special = command.front(); - command = command.drop_front(); - switch (special) - { - case '\\': - if (command.empty()) - { - arg += '\\'; - break; - } +Args::ArgEntry::ArgEntry(llvm::StringRef str, char quote) : quote(quote) { + size_t size = str.size(); + ptr.reset(new char[size + 1]); - // If the character after the backslash is not a whitelisted escapable character, we - // leave the character sequence untouched. - if (strchr(" \t\\'\"`", command.front()) == nullptr) - arg += '\\'; + ::memcpy(data(), str.data() ? str.data() : "", size); + ptr[size] = 0; + ref = llvm::StringRef(c_str(), size); +} - arg += command.front(); - command = command.drop_front(); +//---------------------------------------------------------------------- +// Args constructor +//---------------------------------------------------------------------- +Args::Args(llvm::StringRef command) { SetCommandString(command); } - break; +Args::Args(const Args &rhs) { *this = rhs; } - case ' ': - case '\t': - // We are not inside any quotes, we just found a space after an - // argument. We are done. - arg_complete = true; - break; +Args &Args::operator=(const Args &rhs) { + Clear(); - case '"': - case '\'': - case '`': - // We found the start of a quote scope. - if (first_quote_char == '\0') - first_quote_char = special; - - if (special == '"') - command = ParseDoubleQuotes(command, arg); - else - { - // For single quotes, we simply skip ahead to the matching quote character - // (or the end of the string). - size_t quoted = command.find(special); - arg += command.substr(0, quoted); - command = command.substr(quoted); - } - - // If we found a closing quote, skip it. - if (! command.empty()) - command = command.drop_front(); - - break; - } - } while (!arg_complete); + m_argv.clear(); + m_entries.clear(); + for (auto &entry : rhs.m_entries) { + m_entries.emplace_back(entry.ref, entry.quote); + m_argv.push_back(m_entries.back().data()); + } + m_argv.push_back(nullptr); + return *this; +} - m_args.push_back(arg); - m_args_quote_char.push_back (first_quote_char); - return command; +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +Args::~Args() {} + +void Args::Dump(Stream &s, const char *label_name) const { + if (!label_name) + return; + + int i = 0; + for (auto &entry : m_entries) { + s.Indent(); + s.Format("{0}[{1}]=\"{2}\"\n", label_name, i++, entry.ref); + } + s.Format("{0}[{1}]=NULL\n", label_name, i); + s.EOL(); } -void -Args::SetCommandString (llvm::StringRef command) -{ - m_args.clear(); - m_argv.clear(); - m_args_quote_char.clear(); +bool Args::GetCommandString(std::string &command) const { + command.clear(); - static const char *k_space_separators = " \t"; - command = command.ltrim(k_space_separators); - while (!command.empty()) - { - command = ParseSingleArgument(command); - command = command.ltrim(k_space_separators); - } + for (size_t i = 0; i < m_entries.size(); ++i) { + if (i > 0) + command += ' '; + command += m_entries[i].ref; + } - UpdateArgvFromArgs(); + return !m_entries.empty(); } -void -Args::UpdateArgsAfterOptionParsing() -{ - // Now m_argv might be out of date with m_args, so we need to fix that - arg_cstr_collection::const_iterator argv_pos, argv_end = m_argv.end(); - arg_sstr_collection::iterator args_pos; - arg_quote_char_collection::iterator quotes_pos; - - for (argv_pos = m_argv.begin(), args_pos = m_args.begin(), quotes_pos = m_args_quote_char.begin(); - argv_pos != argv_end && args_pos != m_args.end(); - ++argv_pos) - { - const char *argv_cstr = *argv_pos; - if (argv_cstr == nullptr) - break; - - while (args_pos != m_args.end()) - { - const char *args_cstr = args_pos->c_str(); - if (args_cstr == argv_cstr) - { - // We found the argument that matches the C string in the - // vector, so we can now look for the next one - ++args_pos; - ++quotes_pos; - break; - } - else - { - quotes_pos = m_args_quote_char.erase (quotes_pos); - args_pos = m_args.erase (args_pos); - } - } - } +bool Args::GetQuotedCommandString(std::string &command) const { + command.clear(); - if (args_pos != m_args.end()) - m_args.erase (args_pos, m_args.end()); + for (size_t i = 0; i < m_entries.size(); ++i) { + if (i > 0) + command += ' '; - if (quotes_pos != m_args_quote_char.end()) - m_args_quote_char.erase (quotes_pos, m_args_quote_char.end()); -} + if (m_entries[i].quote) { + command += m_entries[i].quote; + command += m_entries[i].ref; + command += m_entries[i].quote; + } else { + command += m_entries[i].ref; + } + } -void -Args::UpdateArgvFromArgs() -{ - m_argv.clear(); - arg_sstr_collection::const_iterator pos, end = m_args.end(); - for (pos = m_args.begin(); pos != end; ++pos) - m_argv.push_back(pos->c_str()); - m_argv.push_back(nullptr); - // Make sure we have enough arg quote chars in the array - if (m_args_quote_char.size() < m_args.size()) - m_args_quote_char.resize (m_argv.size()); + return !m_entries.empty(); } -size_t -Args::GetArgumentCount() const -{ - if (m_argv.empty()) - return 0; - return m_argv.size() - 1; +void Args::SetCommandString(llvm::StringRef command) { + Clear(); + m_argv.clear(); + + static const char *k_space_separators = " \t"; + command = command.ltrim(k_space_separators); + std::string arg; + char quote; + while (!command.empty()) { + std::tie(arg, quote, command) = ParseSingleArgument(command); + m_entries.emplace_back(arg, quote); + m_argv.push_back(m_entries.back().data()); + command = command.ltrim(k_space_separators); + } + m_argv.push_back(nullptr); } -const char * -Args::GetArgumentAtIndex (size_t idx) const -{ - if (idx < m_argv.size()) - return m_argv[idx]; - return nullptr; +void Args::UpdateArgsAfterOptionParsing() { + assert(!m_argv.empty()); + assert(m_argv.back() == nullptr); + + // Now m_argv might be out of date with m_entries, so we need to fix that. + // This happens because getopt_long_only may permute the order of the + // arguments in argv, so we need to re-order the quotes and the refs array + // to match. + for (size_t i = 0; i < m_argv.size() - 1; ++i) { + const char *argv = m_argv[i]; + auto pos = + std::find_if(m_entries.begin() + i, m_entries.end(), + [argv](const ArgEntry &D) { return D.c_str() == argv; }); + assert(pos != m_entries.end()); + size_t distance = std::distance(m_entries.begin(), pos); + if (i == distance) + continue; + + assert(distance > i); + + std::swap(m_entries[i], m_entries[distance]); + assert(m_entries[i].ref.data() == m_argv[i]); + } + m_entries.resize(m_argv.size() - 1); } -char -Args::GetArgumentQuoteCharAtIndex (size_t idx) const -{ - if (idx < m_args_quote_char.size()) - return m_args_quote_char[idx]; - return '\0'; +size_t Args::GetArgumentCount() const { return m_entries.size(); } + +const char *Args::GetArgumentAtIndex(size_t idx) const { + if (idx < m_argv.size()) + return m_argv[idx]; + return nullptr; } -char ** -Args::GetArgumentVector() -{ - if (!m_argv.empty()) - return const_cast<char **>(&m_argv[0]); - return nullptr; +char Args::GetArgumentQuoteCharAtIndex(size_t idx) const { + if (idx < m_entries.size()) + return m_entries[idx].quote; + return '\0'; } -const char ** -Args::GetConstArgumentVector() const -{ - if (!m_argv.empty()) - return const_cast<const char **>(&m_argv[0]); - return nullptr; +char **Args::GetArgumentVector() { + assert(!m_argv.empty()); + // TODO: functions like execve and posix_spawnp exhibit undefined behavior + // when argv or envp is null. So the code below is actually wrong. However, + // other code in LLDB depends on it being null. The code has been acting this + // way for some time, so it makes sense to leave it this way until someone + // has the time to come along and fix it. + return (m_argv.size() > 1) ? m_argv.data() : nullptr; } -void -Args::Shift () -{ - // Don't pop the last NULL terminator from the argv array - if (m_argv.size() > 1) - { - m_argv.erase(m_argv.begin()); - m_args.pop_front(); - if (!m_args_quote_char.empty()) - m_args_quote_char.erase(m_args_quote_char.begin()); - } +const char **Args::GetConstArgumentVector() const { + assert(!m_argv.empty()); + return (m_argv.size() > 1) ? const_cast<const char **>(m_argv.data()) + : nullptr; } -const char * -Args::Unshift (const char *arg_cstr, char quote_char) -{ - m_args.push_front(arg_cstr); - m_argv.insert(m_argv.begin(), m_args.front().c_str()); - m_args_quote_char.insert(m_args_quote_char.begin(), quote_char); - return GetArgumentAtIndex (0); +void Args::Shift() { + // Don't pop the last NULL terminator from the argv array + if (m_entries.empty()) + return; + m_argv.erase(m_argv.begin()); + m_entries.erase(m_entries.begin()); } -void -Args::AppendArguments (const Args &rhs) -{ - const size_t rhs_argc = rhs.GetArgumentCount(); - for (size_t i=0; i<rhs_argc; ++i) - AppendArgument(rhs.GetArgumentAtIndex(i), - rhs.GetArgumentQuoteCharAtIndex(i)); +void Args::Unshift(llvm::StringRef arg_str, char quote_char) { + InsertArgumentAtIndex(0, arg_str, quote_char); } -void -Args::AppendArguments (const char **argv) -{ - if (argv) - { - for (uint32_t i=0; argv[i]; ++i) - AppendArgument(argv[i]); - } +void Args::AppendArguments(const Args &rhs) { + assert(m_argv.size() == m_entries.size() + 1); + assert(m_argv.back() == nullptr); + m_argv.pop_back(); + for (auto &entry : rhs.m_entries) { + m_entries.emplace_back(entry.ref, entry.quote); + m_argv.push_back(m_entries.back().data()); + } + m_argv.push_back(nullptr); } -const char * -Args::AppendArgument (const char *arg_cstr, char quote_char) -{ - return InsertArgumentAtIndex (GetArgumentCount(), arg_cstr, quote_char); +void Args::AppendArguments(const char **argv) { + size_t argc = ArgvToArgc(argv); + + assert(m_argv.size() == m_entries.size() + 1); + assert(m_argv.back() == nullptr); + m_argv.pop_back(); + for (auto arg : llvm::makeArrayRef(argv, argc)) { + m_entries.emplace_back(arg, '\0'); + m_argv.push_back(m_entries.back().data()); + } + + m_argv.push_back(nullptr); } -const char * -Args::InsertArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char) -{ - // Since we are using a std::list to hold onto the copied C string and - // we don't have direct access to the elements, we have to iterate to - // find the value. - arg_sstr_collection::iterator pos, end = m_args.end(); - size_t i = idx; - for (pos = m_args.begin(); i > 0 && pos != end; ++pos) - --i; - - pos = m_args.insert(pos, arg_cstr); - - if (idx >= m_args_quote_char.size()) - { - m_args_quote_char.resize(idx + 1); - m_args_quote_char[idx] = quote_char; - } - else - m_args_quote_char.insert(m_args_quote_char.begin() + idx, quote_char); - - UpdateArgvFromArgs(); - return GetArgumentAtIndex(idx); +void Args::AppendArgument(llvm::StringRef arg_str, char quote_char) { + InsertArgumentAtIndex(GetArgumentCount(), arg_str, quote_char); } -const char * -Args::ReplaceArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char) -{ - // Since we are using a std::list to hold onto the copied C string and - // we don't have direct access to the elements, we have to iterate to - // find the value. - arg_sstr_collection::iterator pos, end = m_args.end(); - size_t i = idx; - for (pos = m_args.begin(); i > 0 && pos != end; ++pos) - --i; - - if (pos != end) - { - pos->assign(arg_cstr); - assert(idx < m_argv.size() - 1); - m_argv[idx] = pos->c_str(); - if (idx >= m_args_quote_char.size()) - m_args_quote_char.resize(idx + 1); - m_args_quote_char[idx] = quote_char; - return GetArgumentAtIndex(idx); - } - return nullptr; +void Args::InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, + char quote_char) { + assert(m_argv.size() == m_entries.size() + 1); + assert(m_argv.back() == nullptr); + + if (idx > m_entries.size()) + return; + m_entries.emplace(m_entries.begin() + idx, arg_str, quote_char); + m_argv.insert(m_argv.begin() + idx, m_entries[idx].data()); } -void -Args::DeleteArgumentAtIndex (size_t idx) -{ - // Since we are using a std::list to hold onto the copied C string and - // we don't have direct access to the elements, we have to iterate to - // find the value. - arg_sstr_collection::iterator pos, end = m_args.end(); - size_t i = idx; - for (pos = m_args.begin(); i > 0 && pos != end; ++pos) - --i; - - if (pos != end) - { - m_args.erase (pos); - assert(idx < m_argv.size() - 1); - m_argv.erase(m_argv.begin() + idx); - if (idx < m_args_quote_char.size()) - m_args_quote_char.erase(m_args_quote_char.begin() + idx); - } +void Args::ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, + char quote_char) { + assert(m_argv.size() == m_entries.size() + 1); + assert(m_argv.back() == nullptr); + + if (idx >= m_entries.size()) + return; + + if (arg_str.size() > m_entries[idx].ref.size()) { + m_entries[idx] = ArgEntry(arg_str, quote_char); + m_argv[idx] = m_entries[idx].data(); + } else { + const char *src_data = arg_str.data() ? arg_str.data() : ""; + ::memcpy(m_entries[idx].data(), src_data, arg_str.size()); + m_entries[idx].ptr[arg_str.size()] = 0; + m_entries[idx].ref = m_entries[idx].ref.take_front(arg_str.size()); + } } -void -Args::SetArguments (size_t argc, const char **argv) -{ - // m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is - // no need to clear it here. - m_args.clear(); - m_args_quote_char.clear(); - - // First copy each string - for (size_t i=0; i<argc; ++i) - { - m_args.push_back (argv[i]); - if ((argv[i][0] == '\'') || (argv[i][0] == '"') || (argv[i][0] == '`')) - m_args_quote_char.push_back (argv[i][0]); - else - m_args_quote_char.push_back ('\0'); - } +void Args::DeleteArgumentAtIndex(size_t idx) { + if (idx >= m_entries.size()) + return; - UpdateArgvFromArgs(); + m_argv.erase(m_argv.begin() + idx); + m_entries.erase(m_entries.begin() + idx); } -void -Args::SetArguments (const char **argv) -{ - // m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is - // no need to clear it here. - m_args.clear(); - m_args_quote_char.clear(); - - if (argv) - { - // First copy each string - for (size_t i=0; argv[i]; ++i) - { - m_args.push_back (argv[i]); - if ((argv[i][0] == '\'') || (argv[i][0] == '"') || (argv[i][0] == '`')) - m_args_quote_char.push_back (argv[i][0]); - else - m_args_quote_char.push_back ('\0'); - } - } - - UpdateArgvFromArgs(); +void Args::SetArguments(size_t argc, const char **argv) { + Clear(); + + auto args = llvm::makeArrayRef(argv, argc); + m_entries.resize(argc); + m_argv.resize(argc + 1); + for (size_t i = 0; i < args.size(); ++i) { + char quote = + ((args[i][0] == '\'') || (args[i][0] == '"') || (args[i][0] == '`')) + ? args[i][0] + : '\0'; + + m_entries[i] = ArgEntry(args[i], quote); + m_argv[i] = m_entries[i].data(); + } } +void Args::SetArguments(const char **argv) { + SetArguments(ArgvToArgc(argv), argv); +} -Error -Args::ParseOptions (Options &options) -{ - StreamString sstr; - Error error; - Option *long_options = options.GetLongOptions(); - if (long_options == nullptr) - { - error.SetErrorStringWithFormat("invalid long options"); - return error; - } +Error Args::ParseOptions(Options &options, ExecutionContext *execution_context, + PlatformSP platform_sp, bool require_validation) { + StreamString sstr; + Error error; + Option *long_options = options.GetLongOptions(); + if (long_options == nullptr) { + error.SetErrorStringWithFormat("invalid long options"); + return error; + } - 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; - } - } + 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::unique_lock<std::mutex> lock; - OptionParser::Prepare(lock); - int val; - while (1) - { - int long_options_index = -1; - val = OptionParser::Parse(GetArgumentCount(), - GetArgumentVector(), - sstr.GetData(), - long_options, - &long_options_index); - if (val == -1) - break; - - // Did we get an error? - if (val == '?') - { - error.SetErrorStringWithFormat("unknown or ambiguous option"); - break; - } - // The option auto-set itself - if (val == 0) - continue; - - ((Options *) &options)->OptionSeen (val); - - // Lookup the long option index - if (long_options_index == -1) - { - for (int i=0; - long_options[i].definition || long_options[i].flag || long_options[i].val; - ++i) - { - if (long_options[i].val == val) - { - long_options_index = i; - break; - } - } - } - // Call the callback with the option - if (long_options_index >= 0 && long_options[long_options_index].definition) - { - const OptionDefinition *def = long_options[long_options_index].definition; - CommandInterpreter &interpreter = options.GetInterpreter(); - OptionValidator *validator = def->validator; - if (validator && !validator->IsValid(*interpreter.GetPlatform(true), interpreter.GetExecutionContext())) - { - error.SetErrorStringWithFormat("Option \"%s\" invalid. %s", def->long_option, def->validator->LongConditionString()); - } - else - { - error = options.SetOptionValue(long_options_index, - (def->option_has_arg == OptionParser::eNoArgument) ? nullptr : OptionParser::GetOptionArgument()); - } + } + std::unique_lock<std::mutex> lock; + OptionParser::Prepare(lock); + int val; + while (1) { + int long_options_index = -1; + val = OptionParser::Parse(GetArgumentCount(), GetArgumentVector(), + sstr.GetString(), long_options, + &long_options_index); + if (val == -1) + break; + + // Did we get an error? + if (val == '?') { + error.SetErrorStringWithFormat("unknown or ambiguous option"); + break; + } + // The option auto-set itself + if (val == 0) + continue; + + ((Options *)&options)->OptionSeen(val); + + // Lookup the long option index + if (long_options_index == -1) { + for (int i = 0; long_options[i].definition || long_options[i].flag || + long_options[i].val; + ++i) { + if (long_options[i].val == val) { + long_options_index = i; + break; } - else - { - error.SetErrorStringWithFormat("invalid option with value '%i'", val); + } + } + // Call the callback with the option + if (long_options_index >= 0 && + long_options[long_options_index].definition) { + const OptionDefinition *def = long_options[long_options_index].definition; + + if (!platform_sp) { + // User did not pass in an explicit platform. Try to grab + // from the execution context. + TargetSP target_sp = + execution_context ? execution_context->GetTargetSP() : TargetSP(); + platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP(); + } + OptionValidator *validator = def->validator; + + if (!platform_sp && require_validation) { + // Caller requires validation but we cannot validate as we + // don't have the mandatory platform against which to + // validate. + error.SetErrorString("cannot validate options: " + "no platform available"); + return error; + } + + bool validation_failed = false; + if (platform_sp) { + // Ensure we have an execution context, empty or not. + ExecutionContext dummy_context; + ExecutionContext *exe_ctx_p = + execution_context ? execution_context : &dummy_context; + if (validator && !validator->IsValid(*platform_sp, *exe_ctx_p)) { + validation_failed = true; + error.SetErrorStringWithFormat("Option \"%s\" invalid. %s", + def->long_option, + def->validator->LongConditionString()); } - if (error.Fail()) - break; + } + + // As long as validation didn't fail, we set the option value. + if (!validation_failed) + error = options.SetOptionValue( + long_options_index, + (def->option_has_arg == OptionParser::eNoArgument) + ? nullptr + : OptionParser::GetOptionArgument(), + execution_context); + } else { + error.SetErrorStringWithFormat("invalid option with value '%i'", val); } - - // Update our ARGV now that get options has consumed all the options - m_argv.erase(m_argv.begin(), m_argv.begin() + OptionParser::GetOptionIndex()); - UpdateArgsAfterOptionParsing (); - return error; + if (error.Fail()) + break; + } + + // Update our ARGV now that get options has consumed all the options + m_argv.erase(m_argv.begin(), m_argv.begin() + OptionParser::GetOptionIndex()); + UpdateArgsAfterOptionParsing(); + return error; } -void -Args::Clear () -{ - m_args.clear (); - m_argv.clear (); - m_args_quote_char.clear(); +void Args::Clear() { + m_entries.clear(); + m_argv.clear(); + m_argv.push_back(nullptr); } -lldb::addr_t -Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::addr_t fail_value, Error *error_ptr) -{ - bool error_set = false; - if (s && s[0]) - { - char *end = nullptr; - lldb::addr_t addr = ::strtoull (s, &end, 0); - if (*end == '\0') - { - if (error_ptr) - error_ptr->Clear(); - return addr; // All characters were used, return the result - } - // Try base 16 with no prefix... - addr = ::strtoull (s, &end, 16); - if (*end == '\0') - { - if (error_ptr) - error_ptr->Clear(); - return addr; // All characters were used, return the result - } - - if (exe_ctx) - { - Target *target = exe_ctx->GetTargetPtr(); - if (target) - { - lldb::ValueObjectSP valobj_sp; - EvaluateExpressionOptions options; - options.SetCoerceToId(false); - options.SetUnwindOnError(true); - options.SetKeepInMemory(false); - options.SetTryAllThreads(true); - - ExpressionResults expr_result = target->EvaluateExpression(s, - exe_ctx->GetFramePtr(), - valobj_sp, - options); - - bool success = false; - if (expr_result == eExpressionCompleted) - { - if (valobj_sp) - valobj_sp = valobj_sp->GetQualifiedRepresentationIfAvailable(valobj_sp->GetDynamicValueType(), true); - // Get the address to watch. - if (valobj_sp) - addr = valobj_sp->GetValueAsUnsigned(fail_value, &success); - if (success) - { - if (error_ptr) - error_ptr->Clear(); - return addr; - } - else - { - if (error_ptr) - { - error_set = true; - error_ptr->SetErrorStringWithFormat("address expression \"%s\" resulted in a value whose type can't be converted to an address: %s", s, valobj_sp->GetTypeName().GetCString()); - } - } - - } - else - { - // Since the compiler can't handle things like "main + 12" we should - // try to do this for now. The compiler doesn't like adding offsets - // to function pointer types. - static RegularExpression g_symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$"); - RegularExpression::Match regex_match(3); - if (g_symbol_plus_offset_regex.Execute(s, ®ex_match)) - { - uint64_t offset = 0; - bool add = true; - std::string name; - std::string str; - if (regex_match.GetMatchAtIndex(s, 1, name)) - { - if (regex_match.GetMatchAtIndex(s, 2, str)) - { - add = str[0] == '+'; - - if (regex_match.GetMatchAtIndex(s, 3, str)) - { - offset = StringConvert::ToUInt64(str.c_str(), 0, 0, &success); - - if (success) - { - Error error; - addr = StringToAddress (exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS, &error); - if (addr != LLDB_INVALID_ADDRESS) - { - if (add) - return addr + offset; - else - return addr - offset; - } - } - } - } - } - } - - if (error_ptr) - { - error_set = true; - error_ptr->SetErrorStringWithFormat("address expression \"%s\" evaluation failed", s); - } - } - } - } - } +lldb::addr_t Args::StringToAddress(const ExecutionContext *exe_ctx, + llvm::StringRef s, lldb::addr_t fail_value, + Error *error_ptr) { + bool error_set = false; + if (s.empty()) { if (error_ptr) - { - if (!error_set) - error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", s); - } + error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", + s.str().c_str()); return fail_value; -} + } -const char * -Args::StripSpaces (std::string &s, bool leading, bool trailing, bool return_null_if_empty) -{ - static const char *k_white_space = " \t\v"; - if (!s.empty()) - { - if (leading) - { - size_t pos = s.find_first_not_of (k_white_space); - if (pos == std::string::npos) - s.clear(); - else if (pos > 0) - s.erase(0, pos); - } - - if (trailing) - { - size_t rpos = s.find_last_not_of(k_white_space); - if (rpos != std::string::npos && rpos + 1 < s.size()) - s.erase(rpos + 1); - } - } - if (return_null_if_empty && s.empty()) - return nullptr; - return s.c_str(); -} + llvm::StringRef sref = s; -bool -Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr) -{ - llvm::StringRef ref = llvm::StringRef(s).trim(); - if (ref.equals_lower("false") || - ref.equals_lower("off") || - ref.equals_lower("no") || - ref.equals_lower("0")) - { - if (success_ptr) - *success_ptr = true; - return false; - } - else - if (ref.equals_lower("true") || - ref.equals_lower("on") || - ref.equals_lower("yes") || - ref.equals_lower("1")) - { - if (success_ptr) *success_ptr = true; - return true; - } - if (success_ptr) *success_ptr = false; - return fail_value; -} + lldb::addr_t addr = LLDB_INVALID_ADDRESS; + if (!s.getAsInteger(0, addr)) { + if (error_ptr) + error_ptr->Clear(); + return addr; + } -char -Args::StringToChar(const char *s, char fail_value, bool *success_ptr) -{ - bool success = false; - char result = fail_value; - - if (s) - { - size_t length = strlen(s); - if (length == 1) - { - success = true; - result = s[0]; - } + // Try base 16 with no prefix... + if (!s.getAsInteger(16, addr)) { + if (error_ptr) + error_ptr->Clear(); + return addr; + } + + Target *target = nullptr; + if (!exe_ctx || !(target = exe_ctx->GetTargetPtr())) { + if (error_ptr) + error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", + s.str().c_str()); + return fail_value; + } + + lldb::ValueObjectSP valobj_sp; + EvaluateExpressionOptions options; + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetKeepInMemory(false); + options.SetTryAllThreads(true); + + ExpressionResults expr_result = + target->EvaluateExpression(s, exe_ctx->GetFramePtr(), valobj_sp, options); + + bool success = false; + if (expr_result == eExpressionCompleted) { + if (valobj_sp) + valobj_sp = valobj_sp->GetQualifiedRepresentationIfAvailable( + valobj_sp->GetDynamicValueType(), true); + // Get the address to watch. + if (valobj_sp) + addr = valobj_sp->GetValueAsUnsigned(fail_value, &success); + if (success) { + if (error_ptr) + error_ptr->Clear(); + return addr; + } else { + if (error_ptr) { + error_set = true; + error_ptr->SetErrorStringWithFormat( + "address expression \"%s\" resulted in a value whose type " + "can't be converted to an address: %s", + s.str().c_str(), valobj_sp->GetTypeName().GetCString()); + } } - if (success_ptr) - *success_ptr = success; - return result; -} -const char * -Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update) -{ - major = UINT32_MAX; - minor = UINT32_MAX; - update = UINT32_MAX; - - if (s && s[0]) - { - char *pos = nullptr; - unsigned long uval32 = ::strtoul (s, &pos, 0); - if (pos == s) - return s; - major = uval32; - if (*pos == '\0') - { - return pos; // Decoded major and got end of string - } - else if (*pos == '.') - { - const char *minor_cstr = pos + 1; - uval32 = ::strtoul (minor_cstr, &pos, 0); - if (pos == minor_cstr) - return pos; // Didn't get any digits for the minor version... - minor = uval32; - if (*pos == '.') - { - const char *update_cstr = pos + 1; - uval32 = ::strtoul (update_cstr, &pos, 0); - if (pos == update_cstr) - return pos; - update = uval32; + } else { + // Since the compiler can't handle things like "main + 12" we should + // try to do this for now. The compiler doesn't like adding offsets + // to function pointer types. + static RegularExpression g_symbol_plus_offset_regex( + "^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$"); + RegularExpression::Match regex_match(3); + if (g_symbol_plus_offset_regex.Execute(sref, ®ex_match)) { + uint64_t offset = 0; + bool add = true; + std::string name; + std::string str; + if (regex_match.GetMatchAtIndex(s, 1, name)) { + if (regex_match.GetMatchAtIndex(s, 2, str)) { + add = str[0] == '+'; + + if (regex_match.GetMatchAtIndex(s, 3, str)) { + offset = StringConvert::ToUInt64(str.c_str(), 0, 0, &success); + + if (success) { + Error error; + addr = StringToAddress(exe_ctx, name.c_str(), + LLDB_INVALID_ADDRESS, &error); + if (addr != LLDB_INVALID_ADDRESS) { + if (add) + return addr + offset; + else + return addr - offset; + } } - return pos; + } } + } } - return nullptr; + + if (error_ptr) { + error_set = true; + error_ptr->SetErrorStringWithFormat( + "address expression \"%s\" evaluation failed", s.str().c_str()); + } + } + + if (error_ptr) { + if (!error_set) + error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", + s.str().c_str()); + } + return fail_value; } -const char * -Args::GetShellSafeArgument (const FileSpec& shell, - const char *unsafe_arg, - std::string &safe_arg) -{ - struct ShellDescriptor - { - ConstString m_basename; - const char* m_escapables; - }; - - static ShellDescriptor g_Shells[] = { - {ConstString("bash")," '\"<>()&"}, - {ConstString("tcsh")," '\"<>()&$"}, - {ConstString("sh")," '\"<>()&"} - }; - - // safe minimal set - const char* escapables = " '\""; - - if (auto basename = shell.GetFilename()) - { - for (const auto& Shell : g_Shells) - { - if (Shell.m_basename == basename) - { - escapables = Shell.m_escapables; - break; - } - } +const char *Args::StripSpaces(std::string &s, bool leading, bool trailing, + bool return_null_if_empty) { + static const char *k_white_space = " \t\v"; + if (!s.empty()) { + if (leading) { + size_t pos = s.find_first_not_of(k_white_space); + if (pos == std::string::npos) + s.clear(); + else if (pos > 0) + s.erase(0, pos); } - safe_arg.assign (unsafe_arg); - size_t prev_pos = 0; - while (prev_pos < safe_arg.size()) - { - // Escape spaces and quotes - size_t pos = safe_arg.find_first_of(escapables, prev_pos); - if (pos != std::string::npos) - { - safe_arg.insert (pos, 1, '\\'); - prev_pos = pos + 2; - } - else - break; + if (trailing) { + size_t rpos = s.find_last_not_of(k_white_space); + if (rpos != std::string::npos && rpos + 1 < s.size()) + s.erase(rpos + 1); } - return safe_arg.c_str(); + } + if (return_null_if_empty && s.empty()) + return nullptr; + return s.c_str(); } -int64_t -Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error) -{ - if (enum_values) - { - if (s && s[0]) - { - for (int i = 0; enum_values[i].string_value != nullptr ; i++) - { - if (strstr(enum_values[i].string_value, s) == enum_values[i].string_value) - { - error.Clear(); - return enum_values[i].value; - } - } - } +bool Args::StringToBoolean(llvm::StringRef ref, bool fail_value, + bool *success_ptr) { + if (success_ptr) + *success_ptr = true; + ref = ref.trim(); + if (ref.equals_lower("false") || ref.equals_lower("off") || + ref.equals_lower("no") || ref.equals_lower("0")) { + return false; + } else if (ref.equals_lower("true") || ref.equals_lower("on") || + ref.equals_lower("yes") || ref.equals_lower("1")) { + return true; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} - StreamString strm; - strm.PutCString ("invalid enumeration value, valid values are: "); - for (int i = 0; enum_values[i].string_value != nullptr; i++) - { - strm.Printf ("%s\"%s\"", - i > 0 ? ", " : "", - enum_values[i].string_value); - } - error.SetErrorString(strm.GetData()); - } - else - { - error.SetErrorString ("invalid enumeration argument"); - } +char Args::StringToChar(llvm::StringRef s, char fail_value, bool *success_ptr) { + if (success_ptr) + *success_ptr = false; + if (s.size() != 1) return fail_value; + + if (success_ptr) + *success_ptr = true; + return s[0]; } -ScriptLanguage -Args::StringToScriptLanguage (const char *s, ScriptLanguage fail_value, bool *success_ptr) -{ - if (s && s[0]) - { - if ((::strcasecmp (s, "python") == 0) || - (::strcasecmp (s, "default") == 0 && eScriptLanguagePython == eScriptLanguageDefault)) - { - if (success_ptr) *success_ptr = true; - return eScriptLanguagePython; - } - if (::strcasecmp (s, "none")) - { - if (success_ptr) *success_ptr = true; - return eScriptLanguageNone; - } +bool Args::StringToVersion(llvm::StringRef string, uint32_t &major, + uint32_t &minor, uint32_t &update) { + major = UINT32_MAX; + minor = UINT32_MAX; + update = UINT32_MAX; + + if (string.empty()) + return false; + + llvm::StringRef major_str, minor_str, update_str; + + std::tie(major_str, minor_str) = string.split('.'); + std::tie(minor_str, update_str) = minor_str.split('.'); + if (major_str.getAsInteger(10, major)) + return false; + if (!minor_str.empty() && minor_str.getAsInteger(10, minor)) + return false; + if (!update_str.empty() && update_str.getAsInteger(10, update)) + return false; + + return true; +} + +const char *Args::GetShellSafeArgument(const FileSpec &shell, + const char *unsafe_arg, + std::string &safe_arg) { + struct ShellDescriptor { + ConstString m_basename; + const char *m_escapables; + }; + + static ShellDescriptor g_Shells[] = {{ConstString("bash"), " '\"<>()&"}, + {ConstString("tcsh"), " '\"<>()&$"}, + {ConstString("sh"), " '\"<>()&"}}; + + // safe minimal set + const char *escapables = " '\""; + + if (auto basename = shell.GetFilename()) { + for (const auto &Shell : g_Shells) { + if (Shell.m_basename == basename) { + escapables = Shell.m_escapables; + break; + } } - if (success_ptr) *success_ptr = false; - return fail_value; + } + + safe_arg.assign(unsafe_arg); + size_t prev_pos = 0; + while (prev_pos < safe_arg.size()) { + // Escape spaces and quotes + size_t pos = safe_arg.find_first_of(escapables, prev_pos); + if (pos != std::string::npos) { + safe_arg.insert(pos, 1, '\\'); + prev_pos = pos + 2; + } else + break; + } + return safe_arg.c_str(); } -Error -Args::StringToFormat -( - const char *s, - lldb::Format &format, - size_t *byte_size_ptr -) -{ - format = eFormatInvalid; - Error error; - - if (s && s[0]) - { - if (byte_size_ptr) - { - if (isdigit (s[0])) - { - char *format_char = nullptr; - unsigned long byte_size = ::strtoul (s, &format_char, 0); - if (byte_size != ULONG_MAX) - *byte_size_ptr = byte_size; - s = format_char; - } - else - *byte_size_ptr = 0; - } +int64_t Args::StringToOptionEnum(llvm::StringRef s, + OptionEnumValueElement *enum_values, + int32_t fail_value, Error &error) { + error.Clear(); + if (!enum_values) { + error.SetErrorString("invalid enumeration argument"); + return fail_value; + } - const bool partial_match_ok = true; - if (!FormatManager::GetFormatFromCString (s, partial_match_ok, format)) - { - StreamString error_strm; - error_strm.Printf ("Invalid format character or name '%s'. Valid values are:\n", s); - for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1)) - { - char format_char = FormatManager::GetFormatAsFormatChar(f); - if (format_char) - error_strm.Printf ("'%c' or ", format_char); - - error_strm.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f)); - error_strm.EOL(); - } - - if (byte_size_ptr) - error_strm.PutCString ("An optional byte size can precede the format character.\n"); - error.SetErrorString(error_strm.GetString().c_str()); - } + if (s.empty()) { + error.SetErrorString("empty enumeration string"); + return fail_value; + } + + for (int i = 0; enum_values[i].string_value != nullptr; i++) { + llvm::StringRef this_enum(enum_values[i].string_value); + if (this_enum.startswith(s)) + return enum_values[i].value; + } + + StreamString strm; + strm.PutCString("invalid enumeration value, valid values are: "); + for (int i = 0; enum_values[i].string_value != nullptr; i++) { + strm.Printf("%s\"%s\"", i > 0 ? ", " : "", enum_values[i].string_value); + } + error.SetErrorString(strm.GetString()); + return fail_value; +} - if (error.Fail()) - return error; +lldb::ScriptLanguage +Args::StringToScriptLanguage(llvm::StringRef s, lldb::ScriptLanguage fail_value, + bool *success_ptr) { + if (success_ptr) + *success_ptr = true; + + if (s.equals_lower("python")) + return eScriptLanguagePython; + if (s.equals_lower("default")) + return eScriptLanguageDefault; + if (s.equals_lower("none")) + return eScriptLanguageNone; + + if (success_ptr) + *success_ptr = false; + return fail_value; +} + +Error Args::StringToFormat(const char *s, lldb::Format &format, + size_t *byte_size_ptr) { + format = eFormatInvalid; + Error error; + + if (s && s[0]) { + if (byte_size_ptr) { + if (isdigit(s[0])) { + char *format_char = nullptr; + unsigned long byte_size = ::strtoul(s, &format_char, 0); + if (byte_size != ULONG_MAX) + *byte_size_ptr = byte_size; + s = format_char; + } else + *byte_size_ptr = 0; } - else - { - error.SetErrorStringWithFormat("%s option string", s ? "empty" : "invalid"); + + const bool partial_match_ok = true; + if (!FormatManager::GetFormatFromCString(s, partial_match_ok, format)) { + StreamString error_strm; + error_strm.Printf( + "Invalid format character or name '%s'. Valid values are:\n", s); + for (Format f = eFormatDefault; f < kNumFormats; f = Format(f + 1)) { + char format_char = FormatManager::GetFormatAsFormatChar(f); + if (format_char) + error_strm.Printf("'%c' or ", format_char); + + error_strm.Printf("\"%s\"", FormatManager::GetFormatAsCString(f)); + error_strm.EOL(); + } + + if (byte_size_ptr) + error_strm.PutCString( + "An optional byte size can precede the format character.\n"); + error.SetErrorString(error_strm.GetString()); } - return error; + + if (error.Fail()) + return error; + } else { + error.SetErrorStringWithFormat("%s option string", s ? "empty" : "invalid"); + } + return error; } -lldb::Encoding -Args::StringToEncoding (const char *s, lldb::Encoding fail_value) -{ - if (s && s[0]) - { - if (strcmp(s, "uint") == 0) - return eEncodingUint; - else if (strcmp(s, "sint") == 0) - return eEncodingSint; - else if (strcmp(s, "ieee754") == 0) - return eEncodingIEEE754; - else if (strcmp(s, "vector") == 0) - return eEncodingVector; - } - return fail_value; +lldb::Encoding Args::StringToEncoding(llvm::StringRef s, + lldb::Encoding fail_value) { + return llvm::StringSwitch<lldb::Encoding>(s) + .Case("uint", eEncodingUint) + .Case("sint", eEncodingSint) + .Case("ieee754", eEncodingIEEE754) + .Case("vector", eEncodingVector) + .Default(fail_value); } -uint32_t -Args::StringToGenericRegister (const char *s) -{ - if (s && s[0]) - { - if (strcmp(s, "pc") == 0) - return LLDB_REGNUM_GENERIC_PC; - else if (strcmp(s, "sp") == 0) - return LLDB_REGNUM_GENERIC_SP; - else if (strcmp(s, "fp") == 0) - return LLDB_REGNUM_GENERIC_FP; - else if (strcmp(s, "ra") == 0 || strcmp(s, "lr") == 0) - return LLDB_REGNUM_GENERIC_RA; - else if (strcmp(s, "flags") == 0) - return LLDB_REGNUM_GENERIC_FLAGS; - else if (strncmp(s, "arg", 3) == 0) - { - if (s[3] && s[4] == '\0') - { - switch (s[3]) - { - case '1': return LLDB_REGNUM_GENERIC_ARG1; - case '2': return LLDB_REGNUM_GENERIC_ARG2; - case '3': return LLDB_REGNUM_GENERIC_ARG3; - case '4': return LLDB_REGNUM_GENERIC_ARG4; - case '5': return LLDB_REGNUM_GENERIC_ARG5; - case '6': return LLDB_REGNUM_GENERIC_ARG6; - case '7': return LLDB_REGNUM_GENERIC_ARG7; - case '8': return LLDB_REGNUM_GENERIC_ARG8; - } - } - } - } +uint32_t Args::StringToGenericRegister(llvm::StringRef s) { + if (s.empty()) return LLDB_INVALID_REGNUM; + uint32_t result = llvm::StringSwitch<uint32_t>(s) + .Case("pc", LLDB_REGNUM_GENERIC_PC) + .Case("sp", LLDB_REGNUM_GENERIC_SP) + .Case("fp", LLDB_REGNUM_GENERIC_FP) + .Cases("ra", "lr", LLDB_REGNUM_GENERIC_RA) + .Case("flags", LLDB_REGNUM_GENERIC_FLAGS) + .Case("arg1", LLDB_REGNUM_GENERIC_ARG1) + .Case("arg2", LLDB_REGNUM_GENERIC_ARG2) + .Case("arg3", LLDB_REGNUM_GENERIC_ARG3) + .Case("arg4", LLDB_REGNUM_GENERIC_ARG4) + .Case("arg5", LLDB_REGNUM_GENERIC_ARG5) + .Case("arg6", LLDB_REGNUM_GENERIC_ARG6) + .Case("arg7", LLDB_REGNUM_GENERIC_ARG7) + .Case("arg8", LLDB_REGNUM_GENERIC_ARG8) + .Default(LLDB_INVALID_REGNUM); + return result; } +void Args::AddOrReplaceEnvironmentVariable(llvm::StringRef env_var_name, + llvm::StringRef new_value) { + if (env_var_name.empty()) + return; + + // Build the new entry. + std::string var_string(env_var_name); + if (!new_value.empty()) { + var_string += "="; + var_string += new_value; + } + + size_t index = 0; + if (ContainsEnvironmentVariable(env_var_name, &index)) { + ReplaceArgumentAtIndex(index, var_string); + return; + } + + // We didn't find it. Append it instead. + AppendArgument(var_string); +} -void -Args::LongestCommonPrefix (std::string &common_prefix) -{ - arg_sstr_collection::iterator pos, end = m_args.end(); - pos = m_args.begin(); - if (pos == end) - common_prefix.clear(); - else - common_prefix = (*pos); - - for (++pos; pos != end; ++pos) - { - size_t new_size = (*pos).size(); - - // First trim common_prefix if it is longer than the current element: - if (common_prefix.size() > new_size) - common_prefix.erase (new_size); - - // Then trim it at the first disparity: - - for (size_t i = 0; i < common_prefix.size(); i++) - { - if ((*pos)[i] != common_prefix[i]) - { - common_prefix.erase(i); - break; - } - } +bool Args::ContainsEnvironmentVariable(llvm::StringRef env_var_name, + size_t *argument_index) const { + // Validate args. + if (env_var_name.empty()) + return false; - // If we've emptied the common prefix, we're done. - if (common_prefix.empty()) - break; - } -} + // Check each arg to see if it matches the env var name. + for (auto arg : llvm::enumerate(m_entries)) { + llvm::StringRef name, value; + std::tie(name, value) = arg.Value.ref.split('='); + if (name != env_var_name) + continue; -bool -Args::ContainsEnvironmentVariable(const char *env_var_name) const -{ - // Validate args. - if (!env_var_name) - return false; - - // Check each arg to see if it matches the env var name. - for (size_t i = 0; i < GetArgumentCount(); ++i) - { - // Get the arg value. - const char *argument_value = GetArgumentAtIndex(i); - if (!argument_value) - continue; - - // Check if we are the "{env_var_name}={env_var_value}" style. - const char *equal_p = strchr(argument_value, '='); - if (equal_p) - { - if (strncmp(env_var_name, argument_value, - equal_p - argument_value) == 0) - { - // We matched. - return true; - } - } - else - { - // We're a simple {env_var_name}-style entry. - if (strcmp(argument_value, env_var_name) == 0) - { - // We matched. - return true; - } - } - } + if (argument_index) + *argument_index = arg.Index; + return true; + } - // We didn't find a match. - return false; + // We didn't find a match. + return false; } -size_t -Args::FindArgumentIndexForOption (Option *long_options, int long_options_index) -{ - char short_buffer[3]; - char long_buffer[255]; - ::snprintf (short_buffer, sizeof (short_buffer), "-%c", long_options[long_options_index].val); - ::snprintf (long_buffer, sizeof (long_buffer), "--%s", long_options[long_options_index].definition->long_option); - size_t end = GetArgumentCount (); - size_t idx = 0; - while (idx < end) - { - if ((::strncmp (GetArgumentAtIndex (idx), short_buffer, strlen (short_buffer)) == 0) - || (::strncmp (GetArgumentAtIndex (idx), long_buffer, strlen (long_buffer)) == 0)) - { - return idx; - } - ++idx; - } - - return end; +size_t Args::FindArgumentIndexForOption(Option *long_options, + int long_options_index) const { + char short_buffer[3]; + char long_buffer[255]; + ::snprintf(short_buffer, sizeof(short_buffer), "-%c", + long_options[long_options_index].val); + ::snprintf(long_buffer, sizeof(long_buffer), "--%s", + long_options[long_options_index].definition->long_option); + + for (auto entry : llvm::enumerate(m_entries)) { + if (entry.Value.ref.startswith(short_buffer) || + entry.Value.ref.startswith(long_buffer)) + return entry.Index; + } + + return size_t(-1); } -bool -Args::IsPositionalArgument (const char *arg) -{ - if (arg == nullptr) - return false; - - bool is_positional = true; - const char *cptr = arg; - - if (cptr[0] == '%') - { - ++cptr; - while (isdigit (cptr[0])) - ++cptr; - if (cptr[0] != '\0') - is_positional = false; - } - else - is_positional = false; +bool Args::IsPositionalArgument(const char *arg) { + if (arg == nullptr) + return false; + + bool is_positional = true; + const char *cptr = arg; + + if (cptr[0] == '%') { + ++cptr; + while (isdigit(cptr[0])) + ++cptr; + if (cptr[0] != '\0') + is_positional = false; + } else + is_positional = false; - return is_positional; + return is_positional; } -void -Args::ParseAliasOptions (Options &options, - CommandReturnObject &result, - OptionArgVector *option_arg_vector, - std::string &raw_input_string) -{ - StreamString sstr; - int i; - Option *long_options = options.GetLongOptions(); - - if (long_options == nullptr) - { - result.AppendError ("invalid long options"); - result.SetStatus (eReturnStatusFailed); - return; +std::string Args::ParseAliasOptions(Options &options, + CommandReturnObject &result, + OptionArgVector *option_arg_vector, + llvm::StringRef raw_input_string) { + std::string result_string(raw_input_string); + StreamString sstr; + int i; + Option *long_options = options.GetLongOptions(); + + if (long_options == nullptr) { + result.AppendError("invalid long options"); + result.SetStatus(eReturnStatusFailed); + return result_string; + } + + for (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; + } } - - for (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::unique_lock<std::mutex> lock; + OptionParser::Prepare(lock); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + int val; + while (1) { + int long_options_index = -1; + val = OptionParser::Parse(GetArgumentCount(), GetArgumentVector(), + sstr.GetString(), long_options, + &long_options_index); + + if (val == -1) + break; + + if (val == '?') { + result.AppendError("unknown or ambiguous option"); + result.SetStatus(eReturnStatusFailed); + break; } - std::unique_lock<std::mutex> lock; - OptionParser::Prepare(lock); - int val; - while (1) - { - int long_options_index = -1; - val = OptionParser::Parse (GetArgumentCount(), - GetArgumentVector(), - sstr.GetData(), - long_options, - &long_options_index); - - if (val == -1) - break; - - if (val == '?') - { - result.AppendError ("unknown or ambiguous option"); - result.SetStatus (eReturnStatusFailed); - break; - } + if (val == 0) + continue; - if (val == 0) - continue; - - options.OptionSeen (val); - - // Look up the long option index - if (long_options_index == -1) - { - for (int j = 0; - long_options[j].definition || long_options[j].flag || long_options[j].val; - ++j) - { - if (long_options[j].val == val) - { - long_options_index = j; - break; - } - } - } + options.OptionSeen(val); - // See if the option takes an argument, and see if one was supplied. - if (long_options_index >= 0) - { - StreamString option_str; - option_str.Printf ("-%c", val); - const OptionDefinition *def = long_options[long_options_index].definition; - int has_arg = (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg; - - switch (has_arg) - { - case OptionParser::eNoArgument: - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - OptionArgValue (OptionParser::eNoArgument, "<no-argument>"))); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - break; - case OptionParser::eRequiredArgument: - if (OptionParser::GetOptionArgument() != nullptr) - { - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - OptionArgValue (OptionParser::eRequiredArgument, - std::string (OptionParser::GetOptionArgument())))); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendErrorWithFormat ("Option '%s' is missing argument specifier.\n", - option_str.GetData()); - result.SetStatus (eReturnStatusFailed); - } - break; - case OptionParser::eOptionalArgument: - if (OptionParser::GetOptionArgument() != nullptr) - { - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - OptionArgValue (OptionParser::eOptionalArgument, - std::string (OptionParser::GetOptionArgument())))); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - OptionArgValue (OptionParser::eOptionalArgument, "<no-argument>"))); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - break; - default: - result.AppendErrorWithFormat ("error with options table; invalid value in has_arg field for option '%c'.\n", val); - result.SetStatus (eReturnStatusFailed); - break; - } - } - else - { - result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", val); - result.SetStatus (eReturnStatusFailed); + // Look up the long option index + if (long_options_index == -1) { + for (int j = 0; long_options[j].definition || long_options[j].flag || + long_options[j].val; + ++j) { + if (long_options[j].val == val) { + long_options_index = j; + break; } + } + } - if (long_options_index >= 0) - { - // Find option in the argument list; also see if it was supposed to take an argument and if one was - // supplied. Remove option (and argument, if given) from the argument list. Also remove them from - // the raw_input_string, if one was passed in. - size_t idx = FindArgumentIndexForOption (long_options, long_options_index); - if (idx < GetArgumentCount()) - { - if (raw_input_string.size() > 0) - { - const char *tmp_arg = GetArgumentAtIndex (idx); - size_t pos = raw_input_string.find (tmp_arg); - if (pos != std::string::npos) - raw_input_string.erase (pos, strlen (tmp_arg)); - } - ReplaceArgumentAtIndex (idx, ""); - if ((long_options[long_options_index].definition->option_has_arg != OptionParser::eNoArgument) - && (OptionParser::GetOptionArgument() != nullptr) - && (idx+1 < GetArgumentCount()) - && (strcmp (OptionParser::GetOptionArgument(), GetArgumentAtIndex(idx+1)) == 0)) - { - if (raw_input_string.size() > 0) - { - const char *tmp_arg = GetArgumentAtIndex (idx+1); - size_t pos = raw_input_string.find (tmp_arg); - if (pos != std::string::npos) - raw_input_string.erase (pos, strlen (tmp_arg)); - } - ReplaceArgumentAtIndex (idx+1, ""); - } - } - } + // See if the option takes an argument, and see if one was supplied. + if (long_options_index == -1) { + result.AppendErrorWithFormat("Invalid option with value '%c'.\n", val); + result.SetStatus(eReturnStatusFailed); + return result_string; + } - if (!result.Succeeded()) - break; + StreamString option_str; + option_str.Printf("-%c", val); + const OptionDefinition *def = long_options[long_options_index].definition; + int has_arg = + (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg; + + const char *option_arg = nullptr; + switch (has_arg) { + case OptionParser::eRequiredArgument: + if (OptionParser::GetOptionArgument() == nullptr) { + result.AppendErrorWithFormat( + "Option '%s' is missing argument specifier.\n", + option_str.GetData()); + result.SetStatus(eReturnStatusFailed); + return result_string; + } + LLVM_FALLTHROUGH; + case OptionParser::eOptionalArgument: + option_arg = OptionParser::GetOptionArgument(); + LLVM_FALLTHROUGH; + case OptionParser::eNoArgument: + break; + default: + result.AppendErrorWithFormat("error with options table; invalid value " + "in has_arg field for option '%c'.\n", + val); + result.SetStatus(eReturnStatusFailed); + return result_string; } + if (!option_arg) + option_arg = "<no-argument>"; + option_arg_vector->emplace_back(option_str.GetString(), has_arg, + option_arg); + + // Find option in the argument list; also see if it was supposed to take + // an argument and if one was supplied. Remove option (and argument, if + // given) from the argument list. Also remove them from the + // raw_input_string, if one was passed in. + size_t idx = FindArgumentIndexForOption(long_options, long_options_index); + if (idx == size_t(-1)) + continue; + + if (!result_string.empty()) { + auto tmp_arg = m_entries[idx].ref; + size_t pos = result_string.find(tmp_arg); + if (pos != std::string::npos) + result_string.erase(pos, tmp_arg.size()); + } + ReplaceArgumentAtIndex(idx, llvm::StringRef()); + if ((long_options[long_options_index].definition->option_has_arg != + OptionParser::eNoArgument) && + (OptionParser::GetOptionArgument() != nullptr) && + (idx + 1 < GetArgumentCount()) && + (m_entries[idx + 1].ref == OptionParser::GetOptionArgument())) { + if (result_string.size() > 0) { + auto tmp_arg = m_entries[idx + 1].ref; + size_t pos = result_string.find(tmp_arg); + if (pos != std::string::npos) + result_string.erase(pos, tmp_arg.size()); + } + ReplaceArgumentAtIndex(idx + 1, llvm::StringRef()); + } + } + return result_string; } -void -Args::ParseArgsForCompletion -( - Options &options, - OptionElementVector &option_element_vector, - uint32_t cursor_index -) -{ - StreamString sstr; - Option *long_options = options.GetLongOptions(); - option_element_vector.clear(); - - if (long_options == nullptr) - { - return; +void Args::ParseArgsForCompletion(Options &options, + OptionElementVector &option_element_vector, + uint32_t cursor_index) { + StreamString sstr; + Option *long_options = options.GetLongOptions(); + option_element_vector.clear(); + + if (long_options == nullptr) { + return; + } + + // 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; + } } - - // 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::unique_lock<std::mutex> lock; + OptionParser::Prepare(lock); + OptionParser::EnableError(false); + + int val; + auto opt_defs = options.GetDefinitions(); + + // Fooey... OptionParser::Parse permutes the GetArgumentVector to move the + // options to the front. So we have to build another Arg and pass that to + // OptionParser::Parse so it doesn't change the one we have. + + std::vector<char *> dummy_vec = m_argv; + + bool failed_once = false; + uint32_t dash_dash_pos = -1; + + while (1) { + bool missing_argument = false; + int long_options_index = -1; + + val = OptionParser::Parse(dummy_vec.size() - 1, &dummy_vec[0], + sstr.GetString(), long_options, + &long_options_index); + + if (val == -1) { + // When we're completing a "--" which is the last option on line, + if (failed_once) + break; + + failed_once = true; + + // If this is a bare "--" we mark it as such so we can complete it + // successfully later. + // Handling the "--" is a little tricky, since that may mean end of + // options or arguments, or the + // user might want to complete options by long name. I make this work by + // checking whether the + // cursor is in the "--" argument, and if so I assume we're completing the + // long option, otherwise + // I let it pass to OptionParser::Parse which will terminate the option + // parsing. + // Note, in either case we continue parsing the line so we can figure out + // what other options + // were passed. This will be useful when we come to restricting + // completions based on what other + // options we've seen on the line. + + if (static_cast<size_t>(OptionParser::GetOptionIndex()) < + dummy_vec.size() - 1 && + (strcmp(dummy_vec[OptionParser::GetOptionIndex() - 1], "--") == 0)) { + dash_dash_pos = OptionParser::GetOptionIndex() - 1; + if (static_cast<size_t>(OptionParser::GetOptionIndex() - 1) == + cursor_index) { + option_element_vector.push_back( + OptionArgElement(OptionArgElement::eBareDoubleDash, + OptionParser::GetOptionIndex() - 1, + OptionArgElement::eBareDoubleDash)); + continue; + } else + break; + } else + break; + } else if (val == '?') { + option_element_vector.push_back( + OptionArgElement(OptionArgElement::eUnrecognizedArg, + OptionParser::GetOptionIndex() - 1, + OptionArgElement::eUnrecognizedArg)); + continue; + } else if (val == 0) { + continue; + } else if (val == ':') { + // This is a missing argument. + val = OptionParser::GetOptionErrorCause(); + missing_argument = true; } - std::unique_lock<std::mutex> lock; - OptionParser::Prepare(lock); - OptionParser::EnableError(false); - - int val; - const OptionDefinition *opt_defs = options.GetDefinitions(); - - // Fooey... OptionParser::Parse permutes the GetArgumentVector to move the options to the front. - // So we have to build another Arg and pass that to OptionParser::Parse so it doesn't - // change the one we have. - - std::vector<const char *> dummy_vec (GetArgumentVector(), GetArgumentVector() + GetArgumentCount() + 1); - - bool failed_once = false; - uint32_t dash_dash_pos = -1; - - while (1) - { - bool missing_argument = false; - int long_options_index = -1; - - val = OptionParser::Parse (dummy_vec.size() - 1, - const_cast<char *const *>(&dummy_vec.front()), - sstr.GetData(), - long_options, - &long_options_index); - - if (val == -1) - { - // When we're completing a "--" which is the last option on line, - if (failed_once) - break; - - failed_once = true; - - // If this is a bare "--" we mark it as such so we can complete it successfully later. - // Handling the "--" is a little tricky, since that may mean end of options or arguments, or the - // user might want to complete options by long name. I make this work by checking whether the - // cursor is in the "--" argument, and if so I assume we're completing the long option, otherwise - // I let it pass to OptionParser::Parse which will terminate the option parsing. - // Note, in either case we continue parsing the line so we can figure out what other options - // were passed. This will be useful when we come to restricting completions based on what other - // options we've seen on the line. - - if (static_cast<size_t>(OptionParser::GetOptionIndex()) < dummy_vec.size() - 1 - && (strcmp (dummy_vec[OptionParser::GetOptionIndex()-1], "--") == 0)) - { - dash_dash_pos = OptionParser::GetOptionIndex() - 1; - if (static_cast<size_t>(OptionParser::GetOptionIndex() - 1) == cursor_index) - { - option_element_vector.push_back (OptionArgElement (OptionArgElement::eBareDoubleDash, OptionParser::GetOptionIndex() - 1, - OptionArgElement::eBareDoubleDash)); - continue; - } - else - break; - } - else - break; - } - else if (val == '?') - { - option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, OptionParser::GetOptionIndex() - 1, - OptionArgElement::eUnrecognizedArg)); - continue; - } - else if (val == 0) - { - continue; - } - else if (val == ':') - { - // This is a missing argument. - val = OptionParser::GetOptionErrorCause(); - missing_argument = true; - } + ((Options *)&options)->OptionSeen(val); - ((Options *) &options)->OptionSeen (val); - - // Look up the long option index - if (long_options_index == -1) - { - for (int j = 0; - long_options[j].definition || long_options[j].flag || long_options[j].val; - ++j) - { - if (long_options[j].val == val) - { - long_options_index = j; - break; - } - } + // Look up the long option index + if (long_options_index == -1) { + for (int j = 0; long_options[j].definition || long_options[j].flag || + long_options[j].val; + ++j) { + if (long_options[j].val == val) { + long_options_index = j; + break; } + } + } - // See if the option takes an argument, and see if one was supplied. - if (long_options_index >= 0) - { - int opt_defs_index = -1; - for (int i = 0; ; i++) - { - if (opt_defs[i].short_option == 0) - break; - else if (opt_defs[i].short_option == val) - { - opt_defs_index = i; - break; - } - } - - const OptionDefinition *def = long_options[long_options_index].definition; - int has_arg = (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg; - switch (has_arg) - { - case OptionParser::eNoArgument: - option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 1, 0)); - break; - case OptionParser::eRequiredArgument: - if (OptionParser::GetOptionArgument() != nullptr) - { - int arg_index; - if (missing_argument) - arg_index = -1; - else - arg_index = OptionParser::GetOptionIndex() - 1; - - option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 2, arg_index)); - } - else - { - option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 1, -1)); - } - break; - case OptionParser::eOptionalArgument: - if (OptionParser::GetOptionArgument() != nullptr) - { - option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 2, OptionParser::GetOptionIndex() - 1)); - } - else - { - option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 2, OptionParser::GetOptionIndex() - 1)); - } - break; - default: - // The options table is messed up. Here we'll just continue - option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, OptionParser::GetOptionIndex() - 1, - OptionArgElement::eUnrecognizedArg)); - break; - } + // See if the option takes an argument, and see if one was supplied. + if (long_options_index >= 0) { + int opt_defs_index = -1; + for (size_t i = 0; i < opt_defs.size(); i++) { + if (opt_defs[i].short_option != val) + continue; + opt_defs_index = i; + break; + } + + const OptionDefinition *def = long_options[long_options_index].definition; + int has_arg = + (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg; + switch (has_arg) { + case OptionParser::eNoArgument: + option_element_vector.push_back(OptionArgElement( + opt_defs_index, OptionParser::GetOptionIndex() - 1, 0)); + break; + case OptionParser::eRequiredArgument: + if (OptionParser::GetOptionArgument() != nullptr) { + int arg_index; + if (missing_argument) + arg_index = -1; + else + arg_index = OptionParser::GetOptionIndex() - 1; + + option_element_vector.push_back(OptionArgElement( + opt_defs_index, OptionParser::GetOptionIndex() - 2, arg_index)); + } else { + option_element_vector.push_back(OptionArgElement( + opt_defs_index, OptionParser::GetOptionIndex() - 1, -1)); } - else - { - option_element_vector.push_back (OptionArgElement (OptionArgElement::eUnrecognizedArg, OptionParser::GetOptionIndex() - 1, - OptionArgElement::eUnrecognizedArg)); + break; + case OptionParser::eOptionalArgument: + if (OptionParser::GetOptionArgument() != nullptr) { + option_element_vector.push_back(OptionArgElement( + opt_defs_index, OptionParser::GetOptionIndex() - 2, + OptionParser::GetOptionIndex() - 1)); + } else { + option_element_vector.push_back(OptionArgElement( + opt_defs_index, OptionParser::GetOptionIndex() - 2, + OptionParser::GetOptionIndex() - 1)); } + break; + default: + // The options table is messed up. Here we'll just continue + option_element_vector.push_back( + OptionArgElement(OptionArgElement::eUnrecognizedArg, + OptionParser::GetOptionIndex() - 1, + OptionArgElement::eUnrecognizedArg)); + break; + } + } else { + option_element_vector.push_back( + OptionArgElement(OptionArgElement::eUnrecognizedArg, + OptionParser::GetOptionIndex() - 1, + OptionArgElement::eUnrecognizedArg)); } - - // Finally we have to handle the case where the cursor index points at a single "-". We want to mark that in - // the option_element_vector, but only if it is not after the "--". But it turns out that OptionParser::Parse just ignores - // an isolated "-". So we have to look it up by hand here. We only care if it is AT the cursor position. - // Note, a single quoted dash is not the same as a single dash... - - if ((static_cast<int32_t>(dash_dash_pos) == -1 || cursor_index < dash_dash_pos) - && m_args_quote_char[cursor_index] == '\0' - && strcmp (GetArgumentAtIndex(cursor_index), "-") == 0) - { - option_element_vector.push_back (OptionArgElement (OptionArgElement::eBareDash, cursor_index, - OptionArgElement::eBareDash)); - - } + } + + // Finally we have to handle the case where the cursor index points at a + // single "-". We want to mark that in + // the option_element_vector, but only if it is not after the "--". But it + // turns out that OptionParser::Parse just ignores + // an isolated "-". So we have to look it up by hand here. We only care if + // it is AT the cursor position. + // Note, a single quoted dash is not the same as a single dash... + + const ArgEntry &cursor = m_entries[cursor_index]; + if ((static_cast<int32_t>(dash_dash_pos) == -1 || + cursor_index < dash_dash_pos) && + cursor.quote == '\0' && cursor.ref == "-") { + option_element_vector.push_back( + OptionArgElement(OptionArgElement::eBareDash, cursor_index, + OptionArgElement::eBareDash)); + } } -void -Args::EncodeEscapeSequences (const char *src, std::string &dst) -{ - dst.clear(); - if (src) - { - for (const char *p = src; *p != '\0'; ++p) - { - size_t non_special_chars = ::strcspn (p, "\\"); - if (non_special_chars > 0) - { - dst.append(p, non_special_chars); - p += non_special_chars; - if (*p == '\0') - break; +void Args::EncodeEscapeSequences(const char *src, std::string &dst) { + dst.clear(); + if (src) { + for (const char *p = src; *p != '\0'; ++p) { + size_t non_special_chars = ::strcspn(p, "\\"); + if (non_special_chars > 0) { + dst.append(p, non_special_chars); + p += non_special_chars; + if (*p == '\0') + break; + } + + if (*p == '\\') { + ++p; // skip the slash + switch (*p) { + case 'a': + dst.append(1, '\a'); + break; + case 'b': + dst.append(1, '\b'); + break; + case 'f': + dst.append(1, '\f'); + break; + case 'n': + dst.append(1, '\n'); + break; + case 'r': + dst.append(1, '\r'); + break; + case 't': + dst.append(1, '\t'); + break; + case 'v': + dst.append(1, '\v'); + break; + case '\\': + dst.append(1, '\\'); + break; + case '\'': + dst.append(1, '\''); + break; + case '"': + dst.append(1, '"'); + break; + case '0': + // 1 to 3 octal chars + { + // Make a string that can hold onto the initial zero char, + // up to 3 octal digits, and a terminating NULL. + char oct_str[5] = {'\0', '\0', '\0', '\0', '\0'}; + + int i; + for (i = 0; (p[i] >= '0' && p[i] <= '7') && i < 4; ++i) + oct_str[i] = p[i]; + + // We don't want to consume the last octal character since + // the main for loop will do this for us, so we advance p by + // one less than i (even if i is zero) + p += i - 1; + unsigned long octal_value = ::strtoul(oct_str, nullptr, 8); + if (octal_value <= UINT8_MAX) { + dst.append(1, (char)octal_value); } - - if (*p == '\\') - { - ++p; // skip the slash - switch (*p) - { - case 'a' : dst.append(1, '\a'); break; - case 'b' : dst.append(1, '\b'); break; - case 'f' : dst.append(1, '\f'); break; - case 'n' : dst.append(1, '\n'); break; - case 'r' : dst.append(1, '\r'); break; - case 't' : dst.append(1, '\t'); break; - case 'v' : dst.append(1, '\v'); break; - case '\\': dst.append(1, '\\'); break; - case '\'': dst.append(1, '\''); break; - case '"' : dst.append(1, '"'); break; - case '0' : - // 1 to 3 octal chars - { - // Make a string that can hold onto the initial zero char, - // up to 3 octal digits, and a terminating NULL. - char oct_str[5] = { '\0', '\0', '\0', '\0', '\0' }; - - int i; - for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i) - oct_str[i] = p[i]; - - // We don't want to consume the last octal character since - // the main for loop will do this for us, so we advance p by - // one less than i (even if i is zero) - p += i - 1; - unsigned long octal_value = ::strtoul (oct_str, nullptr, 8); - if (octal_value <= UINT8_MAX) - { - dst.append(1, (char)octal_value); - } - } - break; - - case 'x': - // hex number in the format - if (isxdigit(p[1])) - { - ++p; // Skip the 'x' - - // Make a string that can hold onto two hex chars plus a - // NULL terminator - char hex_str[3] = { *p, '\0', '\0' }; - if (isxdigit(p[1])) - { - ++p; // Skip the first of the two hex chars - hex_str[1] = *p; - } - - unsigned long hex_value = strtoul (hex_str, nullptr, 16); - if (hex_value <= UINT8_MAX) - dst.append (1, (char)hex_value); - } - else - { - dst.append(1, 'x'); - } - break; - - default: - // Just desensitize any other character by just printing what - // came after the '\' - dst.append(1, *p); - break; - - } + } + break; + + case 'x': + // hex number in the format + if (isxdigit(p[1])) { + ++p; // Skip the 'x' + + // Make a string that can hold onto two hex chars plus a + // NULL terminator + char hex_str[3] = {*p, '\0', '\0'}; + if (isxdigit(p[1])) { + ++p; // Skip the first of the two hex chars + hex_str[1] = *p; } - } - } -} + unsigned long hex_value = strtoul(hex_str, nullptr, 16); + if (hex_value <= UINT8_MAX) + dst.append(1, (char)hex_value); + } else { + dst.append(1, 'x'); + } + break; -void -Args::ExpandEscapedCharacters (const char *src, std::string &dst) -{ - dst.clear(); - if (src) - { - for (const char *p = src; *p != '\0'; ++p) - { - if (isprint8(*p)) - dst.append(1, *p); - else - { - switch (*p) - { - case '\a': dst.append("\\a"); break; - case '\b': dst.append("\\b"); break; - case '\f': dst.append("\\f"); break; - case '\n': dst.append("\\n"); break; - case '\r': dst.append("\\r"); break; - case '\t': dst.append("\\t"); break; - case '\v': dst.append("\\v"); break; - case '\'': dst.append("\\'"); break; - case '"': dst.append("\\\""); break; - case '\\': dst.append("\\\\"); break; - default: - { - // Just encode as octal - dst.append("\\0"); - char octal_str[32]; - snprintf(octal_str, sizeof(octal_str), "%o", *p); - dst.append(octal_str); - } - break; - } - } + default: + // Just desensitize any other character by just printing what + // came after the '\' + dst.append(1, *p); + break; } + } } + } } -std::string -Args::EscapeLLDBCommandArgument (const std::string& arg, char quote_char) -{ - const char* chars_to_escape = nullptr; - switch (quote_char) - { - case '\0': - chars_to_escape = " \t\\'\"`"; - break; +void Args::ExpandEscapedCharacters(const char *src, std::string &dst) { + dst.clear(); + if (src) { + for (const char *p = src; *p != '\0'; ++p) { + if (isprint8(*p)) + dst.append(1, *p); + else { + switch (*p) { + case '\a': + dst.append("\\a"); + break; + case '\b': + dst.append("\\b"); + break; + case '\f': + dst.append("\\f"); + break; + case '\n': + dst.append("\\n"); + break; + case '\r': + dst.append("\\r"); + break; + case '\t': + dst.append("\\t"); + break; + case '\v': + dst.append("\\v"); + break; case '\'': - chars_to_escape = ""; - break; + dst.append("\\'"); + break; case '"': - chars_to_escape = "$\"`\\"; - break; - default: - assert(false && "Unhandled quote character"); - } - - std::string res; - res.reserve(arg.size()); - for (char c : arg) - { - if (::strchr(chars_to_escape, c)) - res.push_back('\\'); - res.push_back(c); + dst.append("\\\""); + break; + case '\\': + dst.append("\\\\"); + break; + default: { + // Just encode as octal + dst.append("\\0"); + char octal_str[32]; + snprintf(octal_str, sizeof(octal_str), "%o", *p); + dst.append(octal_str); + } break; + } + } } - return res; + } } +std::string Args::EscapeLLDBCommandArgument(const std::string &arg, + char quote_char) { + const char *chars_to_escape = nullptr; + switch (quote_char) { + case '\0': + chars_to_escape = " \t\\'\"`"; + break; + case '\'': + chars_to_escape = ""; + break; + case '"': + chars_to_escape = "$\"`\\"; + break; + default: + assert(false && "Unhandled quote character"); + } + + std::string res; + res.reserve(arg.size()); + for (char c : arg) { + if (::strchr(chars_to_escape, c)) + res.push_back('\\'); + res.push_back(c); + } + return res; +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandAlias.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandAlias.cpp index a915d63..a8f5343 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandAlias.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandAlias.cpp @@ -1,4 +1,4 @@ -//===-- CommandAlias.cpp ------------------------------------------*- C++ -*-===// +//===-- CommandAlias.cpp -----------------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -12,6 +12,7 @@ #include "llvm/Support/ErrorHandling.h" #include "lldb/Core/StreamString.h" +#include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/Options.h" @@ -19,289 +20,233 @@ using namespace lldb; using namespace lldb_private; -static bool -ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp, - const char *options_args, - OptionArgVectorSP &option_arg_vector_sp) -{ - bool success = true; - OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); - - if (!options_args || (strlen (options_args) < 1)) - return true; - - std::string options_string (options_args); - Args args (options_args); - CommandReturnObject result; - // Check to see if the command being aliased can take any command options. - Options *options = cmd_obj_sp->GetOptions (); - if (options) - { - // See if any options were specified as part of the alias; if so, handle them appropriately. - options->NotifyOptionParsingStarting (); - args.Unshift ("dummy_arg"); - args.ParseAliasOptions (*options, result, option_arg_vector, options_string); - args.Shift (); - if (result.Succeeded()) - options->VerifyPartialOptions (result); - if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted) - { - result.AppendError ("Unable to create requested alias.\n"); - return false; - } +static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp, + llvm::StringRef options_args, + OptionArgVectorSP &option_arg_vector_sp) { + bool success = true; + OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); + + if (options_args.size() < 1) + return true; + + Args args(options_args); + std::string options_string(options_args); + CommandReturnObject result; + // Check to see if the command being aliased can take any command options. + Options *options = cmd_obj_sp->GetOptions(); + if (options) { + // See if any options were specified as part of the alias; if so, handle + // them appropriately. + ExecutionContext exe_ctx = + cmd_obj_sp->GetCommandInterpreter().GetExecutionContext(); + options->NotifyOptionParsingStarting(&exe_ctx); + args.Unshift(llvm::StringRef("dummy_arg")); + options_string = args.ParseAliasOptions(*options, result, option_arg_vector, + options_args); + args.Shift(); + if (result.Succeeded()) + options->VerifyPartialOptions(result); + if (!result.Succeeded() && + result.GetStatus() != lldb::eReturnStatusStarted) { + result.AppendError("Unable to create requested alias.\n"); + return false; } - - if (!options_string.empty()) - { - if (cmd_obj_sp->WantsRawCommandString ()) - option_arg_vector->push_back (OptionArgPair ("<argument>", - OptionArgValue (-1, - options_string))); - else - { - const size_t argc = args.GetArgumentCount(); - for (size_t i = 0; i < argc; ++i) - if (strcmp (args.GetArgumentAtIndex (i), "") != 0) - option_arg_vector->push_back - (OptionArgPair ("<argument>", - OptionArgValue (-1, - std::string (args.GetArgumentAtIndex (i))))); - } + } + + if (!options_string.empty()) { + if (cmd_obj_sp->WantsRawCommandString()) + option_arg_vector->emplace_back("<argument>", -1, options_string); + else { + for (auto &entry : args.entries()) { + if (!entry.ref.empty()) + option_arg_vector->emplace_back("<argument>", -1, entry.ref); + } } - - return success; -} - -CommandAlias::CommandAlias (CommandInterpreter &interpreter, - lldb::CommandObjectSP cmd_sp, - const char *options_args, - const char *name, - const char *help, - const char *syntax, - uint32_t flags) : - CommandObject(interpreter, - name, - help, - syntax, - flags), -m_underlying_command_sp(), -m_option_string(options_args ? options_args : ""), -m_option_args_sp(new OptionArgVector), -m_is_dashdash_alias(eLazyBoolCalculate), -m_did_set_help(false), -m_did_set_help_long(false) -{ - if (ProcessAliasOptionsArgs(cmd_sp, options_args, m_option_args_sp)) - { - m_underlying_command_sp = cmd_sp; - for (int i = 0; - auto cmd_entry = m_underlying_command_sp->GetArgumentEntryAtIndex(i); - i++) - { - m_arguments.push_back(*cmd_entry); - } - if (!help || !help[0]) - { - StreamString sstr; - StreamString translation_and_help; - GetAliasExpansion(sstr); - - translation_and_help.Printf ("(%s) %s", sstr.GetData(), GetUnderlyingCommand()->GetHelp()); - SetHelp(translation_and_help.GetData()); - } + } + + return success; +} + +CommandAlias::CommandAlias(CommandInterpreter &interpreter, + lldb::CommandObjectSP cmd_sp, + llvm::StringRef options_args, llvm::StringRef name, + llvm::StringRef help, llvm::StringRef syntax, + uint32_t flags) + : CommandObject(interpreter, name, help, syntax, flags), + m_underlying_command_sp(), m_option_string(options_args), + m_option_args_sp(new OptionArgVector), + m_is_dashdash_alias(eLazyBoolCalculate), m_did_set_help(false), + m_did_set_help_long(false) { + if (ProcessAliasOptionsArgs(cmd_sp, options_args, m_option_args_sp)) { + m_underlying_command_sp = cmd_sp; + for (int i = 0; + auto cmd_entry = m_underlying_command_sp->GetArgumentEntryAtIndex(i); + i++) { + m_arguments.push_back(*cmd_entry); } -} + if (!help.empty()) { + StreamString sstr; + StreamString translation_and_help; + GetAliasExpansion(sstr); + + translation_and_help.Printf( + "(%s) %s", sstr.GetData(), + GetUnderlyingCommand()->GetHelp().str().c_str()); + SetHelp(translation_and_help.GetString()); + } + } +} + +bool CommandAlias::WantsRawCommandString() { + if (IsValid()) + return m_underlying_command_sp->WantsRawCommandString(); + return false; +} + +bool CommandAlias::WantsCompletion() { + if (IsValid()) + return m_underlying_command_sp->WantsCompletion(); + return false; +} + +int CommandAlias::HandleCompletion(Args &input, int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, bool &word_complete, + StringList &matches) { + if (IsValid()) + return m_underlying_command_sp->HandleCompletion( + input, cursor_index, cursor_char_position, match_start_point, + max_return_elements, word_complete, matches); + return -1; +} + +int CommandAlias::HandleArgumentCompletion( + Args &input, int &cursor_index, int &cursor_char_position, + OptionElementVector &opt_element_vector, int match_start_point, + int max_return_elements, bool &word_complete, StringList &matches) { + if (IsValid()) + return m_underlying_command_sp->HandleArgumentCompletion( + input, cursor_index, cursor_char_position, opt_element_vector, + match_start_point, max_return_elements, word_complete, matches); + return -1; +} + +Options *CommandAlias::GetOptions() { + if (IsValid()) + return m_underlying_command_sp->GetOptions(); + return nullptr; +} + +bool CommandAlias::Execute(const char *args_string, + CommandReturnObject &result) { + llvm_unreachable("CommandAlias::Execute is not to be called"); +} + +void CommandAlias::GetAliasExpansion(StreamString &help_string) const { + llvm::StringRef command_name = m_underlying_command_sp->GetCommandName(); + help_string.Printf("'%*s", (int)command_name.size(), command_name.data()); + + if (!m_option_args_sp) { + help_string.Printf("'"); + return; + } + + OptionArgVector *options = m_option_args_sp.get(); + std::string opt; + std::string value; + + for (const auto &opt_entry : *options) { + std::tie(opt, std::ignore, value) = opt_entry; + if (opt == "<argument>") { + help_string.Printf(" %s", value.c_str()); + } else { + help_string.Printf(" %s", opt.c_str()); + if ((value.compare("<no-argument>") != 0) && + (value.compare("<need-argument") != 0)) { + help_string.Printf(" %s", value.c_str()); + } + } + } -bool -CommandAlias::WantsRawCommandString() -{ - if (IsValid()) - return m_underlying_command_sp->WantsRawCommandString(); - return false; + help_string.Printf("'"); } -bool -CommandAlias::WantsCompletion() -{ - if (IsValid()) - return m_underlying_command_sp->WantsCompletion(); +bool CommandAlias::IsDashDashCommand() { + if (m_is_dashdash_alias != eLazyBoolCalculate) + return (m_is_dashdash_alias == eLazyBoolYes); + m_is_dashdash_alias = eLazyBoolNo; + if (!IsValid()) return false; -} -int -CommandAlias::HandleCompletion (Args &input, - int &cursor_index, - int &cursor_char_position, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - if (IsValid()) - return m_underlying_command_sp->HandleCompletion(input, - cursor_index, - cursor_char_position, - match_start_point, - max_return_elements, - word_complete, - matches); - return -1; -} - -int -CommandAlias::HandleArgumentCompletion (Args &input, - int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - if (IsValid()) - return m_underlying_command_sp->HandleArgumentCompletion(input, - cursor_index, - cursor_char_position, - opt_element_vector, - match_start_point, - max_return_elements, - word_complete, - matches); - return -1; -} + std::string opt; + std::string value; -Options* -CommandAlias::GetOptions() -{ - if (IsValid()) - return m_underlying_command_sp->GetOptions(); - return nullptr; -} - -bool -CommandAlias::Execute(const char *args_string, CommandReturnObject &result) -{ - llvm_unreachable("CommandAlias::Execute is not to be called"); -} - -void -CommandAlias::GetAliasExpansion (StreamString &help_string) -{ - const char* command_name = m_underlying_command_sp->GetCommandName(); - help_string.Printf ("'%s", command_name); - - if (m_option_args_sp) - { - OptionArgVector *options = m_option_args_sp.get(); - for (size_t i = 0; i < options->size(); ++i) - { - OptionArgPair cur_option = (*options)[i]; - std::string opt = cur_option.first; - OptionArgValue value_pair = cur_option.second; - std::string value = value_pair.second; - if (opt.compare("<argument>") == 0) - { - help_string.Printf (" %s", value.c_str()); - } - else - { - help_string.Printf (" %s", opt.c_str()); - if ((value.compare ("<no-argument>") != 0) - && (value.compare ("<need-argument") != 0)) - { - help_string.Printf (" %s", value.c_str()); - } - } - } + for (const auto &opt_entry : *GetOptionArguments()) { + std::tie(opt, std::ignore, value) = opt_entry; + if (opt == "<argument>" && !value.empty() && + llvm::StringRef(value).endswith("--")) { + m_is_dashdash_alias = eLazyBoolYes; + break; } - - help_string.Printf ("'"); -} + } -bool -CommandAlias::IsDashDashCommand () -{ - if (m_is_dashdash_alias == eLazyBoolCalculate) - { - m_is_dashdash_alias = eLazyBoolNo; - if (IsValid()) - { - for (const OptionArgPair& opt_arg : *GetOptionArguments()) - { - if (opt_arg.first == "<argument>" && - !opt_arg.second.second.empty() && - llvm::StringRef(opt_arg.second.second).endswith("--")) - { - m_is_dashdash_alias = eLazyBoolYes; - break; - } - } - // if this is a nested alias, it may be adding arguments on top of an already dash-dash alias - if ((m_is_dashdash_alias == eLazyBoolNo) && IsNestedAlias()) - m_is_dashdash_alias = (GetUnderlyingCommand()->IsDashDashCommand() ? eLazyBoolYes : eLazyBoolNo); - } - } - return (m_is_dashdash_alias == eLazyBoolYes); + // if this is a nested alias, it may be adding arguments on top of an + // already dash-dash alias + if ((m_is_dashdash_alias == eLazyBoolNo) && IsNestedAlias()) + m_is_dashdash_alias = + (GetUnderlyingCommand()->IsDashDashCommand() ? eLazyBoolYes + : eLazyBoolNo); + return (m_is_dashdash_alias == eLazyBoolYes); } -bool -CommandAlias::IsNestedAlias () -{ - if (GetUnderlyingCommand()) - return GetUnderlyingCommand()->IsAlias(); - return false; +bool CommandAlias::IsNestedAlias() { + if (GetUnderlyingCommand()) + return GetUnderlyingCommand()->IsAlias(); + return false; } -std::pair<lldb::CommandObjectSP, OptionArgVectorSP> -CommandAlias::Desugar () -{ - auto underlying = GetUnderlyingCommand(); - if (!underlying) - return {nullptr,nullptr}; - - if (underlying->IsAlias()) - { - auto desugared = ((CommandAlias*)underlying.get())->Desugar(); - auto options = GetOptionArguments(); - options->insert(options->begin(), desugared.second->begin(), desugared.second->end()); - return {desugared.first,options}; - } +std::pair<lldb::CommandObjectSP, OptionArgVectorSP> CommandAlias::Desugar() { + auto underlying = GetUnderlyingCommand(); + if (!underlying) + return {nullptr, nullptr}; + + if (underlying->IsAlias()) { + auto desugared = ((CommandAlias *)underlying.get())->Desugar(); + auto options = GetOptionArguments(); + options->insert(options->begin(), desugared.second->begin(), + desugared.second->end()); + return {desugared.first, options}; + } - return {underlying,GetOptionArguments()}; + return {underlying, GetOptionArguments()}; } -// allow CommandAlias objects to provide their own help, but fallback to the info +// allow CommandAlias objects to provide their own help, but fallback to the +// info // for the underlying command if no customization has been provided -void -CommandAlias::SetHelp (const char * str) -{ - this->CommandObject::SetHelp(str); - m_did_set_help = true; +void CommandAlias::SetHelp(llvm::StringRef str) { + this->CommandObject::SetHelp(str); + m_did_set_help = true; } -void -CommandAlias::SetHelpLong (const char * str) -{ - this->CommandObject::SetHelpLong(str); - m_did_set_help_long = true; +void CommandAlias::SetHelpLong(llvm::StringRef str) { + this->CommandObject::SetHelpLong(str); + m_did_set_help_long = true; } -const char* -CommandAlias::GetHelp () -{ - if (!m_cmd_help_short.empty() || m_did_set_help) - return m_cmd_help_short.c_str(); - if (IsValid()) - return m_underlying_command_sp->GetHelp(); - return nullptr; +llvm::StringRef CommandAlias::GetHelp() { + if (!m_cmd_help_short.empty() || m_did_set_help) + return m_cmd_help_short; + if (IsValid()) + return m_underlying_command_sp->GetHelp(); + return llvm::StringRef(); } -const char* -CommandAlias::GetHelpLong () -{ - if (!m_cmd_help_long.empty() || m_did_set_help_long) - return m_cmd_help_long.c_str(); - if (IsValid()) - return m_underlying_command_sp->GetHelpLong(); - return nullptr; +llvm::StringRef CommandAlias::GetHelpLong() { + if (!m_cmd_help_long.empty() || m_did_set_help_long) + return m_cmd_help_long; + if (IsValid()) + return m_underlying_command_sp->GetHelpLong(); + return llvm::StringRef(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandHistory.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandHistory.cpp index ff87e52..c16f713 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandHistory.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandHistory.cpp @@ -9,134 +9,103 @@ #include <inttypes.h> -#include "lldb/Interpreter/CommandHistory.h" #include "lldb/Host/StringConvert.h" +#include "lldb/Interpreter/CommandHistory.h" using namespace lldb; using namespace lldb_private; -CommandHistory::CommandHistory() : m_mutex(), m_history() -{} +CommandHistory::CommandHistory() : m_mutex(), m_history() {} -CommandHistory::~CommandHistory () -{} +CommandHistory::~CommandHistory() {} -size_t -CommandHistory::GetSize () const -{ - std::lock_guard<std::recursive_mutex> guard(m_mutex); - return m_history.size(); +size_t CommandHistory::GetSize() const { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return m_history.size(); } -bool -CommandHistory::IsEmpty () const -{ - std::lock_guard<std::recursive_mutex> guard(m_mutex); - return m_history.empty(); +bool CommandHistory::IsEmpty() const { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return m_history.empty(); } -const char* -CommandHistory::FindString (const char* input_str) const -{ - std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (!input_str) - return nullptr; - if (input_str[0] != g_repeat_char) - return nullptr; - if (input_str[1] == '-') - { - bool success; - size_t idx = StringConvert::ToUInt32 (input_str+2, 0, 0, &success); - if (!success) - return nullptr; - if (idx > m_history.size()) - return nullptr; - idx = m_history.size() - idx; - return m_history[idx].c_str(); - - } - else if (input_str[1] == g_repeat_char) - { - if (m_history.empty()) - return nullptr; - else - return m_history.back().c_str(); - } - else - { - bool success; - uint32_t idx = StringConvert::ToUInt32 (input_str+1, 0, 0, &success); - if (!success) - return nullptr; - if (idx >= m_history.size()) - return nullptr; - return m_history[idx].c_str(); - } +llvm::Optional<llvm::StringRef> +CommandHistory::FindString(llvm::StringRef input_str) const { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (input_str.size() < 2) + return llvm::None; + + if (input_str[0] != g_repeat_char) + return llvm::None; + + if (input_str[1] == g_repeat_char) { + if (m_history.empty()) + return llvm::None; + return llvm::StringRef(m_history.back()); + } + + input_str = input_str.drop_front(); + + size_t idx = 0; + if (input_str.front() == '-') { + if (input_str.drop_front(2).getAsInteger(0, idx)) + return llvm::None; + if (idx >= m_history.size()) + return llvm::None; + idx = m_history.size() - idx; + } else { + if (input_str.drop_front().getAsInteger(0, idx)) + return llvm::None; + if (idx >= m_history.size()) + return llvm::None; + } + + return llvm::StringRef(m_history[idx]); } -const char* -CommandHistory::GetStringAtIndex (size_t idx) const -{ - std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (idx < m_history.size()) - return m_history[idx].c_str(); - return nullptr; +llvm::StringRef CommandHistory::GetStringAtIndex(size_t idx) const { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (idx < m_history.size()) + return m_history[idx]; + return ""; } -const char* -CommandHistory::operator [] (size_t idx) const -{ - return GetStringAtIndex(idx); +llvm::StringRef CommandHistory::operator[](size_t idx) const { + return GetStringAtIndex(idx); } -const char* -CommandHistory::GetRecentmostString () const -{ - std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (m_history.empty()) - return nullptr; - return m_history.back().c_str(); +llvm::StringRef CommandHistory::GetRecentmostString() const { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (m_history.empty()) + return ""; + return m_history.back(); } -void -CommandHistory::AppendString (const std::string& str, - bool reject_if_dupe) -{ - std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (reject_if_dupe) - { - if (!m_history.empty()) - { - if (str == m_history.back()) - return; - } +void CommandHistory::AppendString(llvm::StringRef str, bool reject_if_dupe) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (reject_if_dupe) { + if (!m_history.empty()) { + if (str == m_history.back()) + return; } - m_history.push_back(std::string(str)); + } + m_history.push_back(str); } -void -CommandHistory::Clear () -{ - std::lock_guard<std::recursive_mutex> guard(m_mutex); - m_history.clear(); +void CommandHistory::Clear() { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + m_history.clear(); } -void -CommandHistory::Dump (Stream& stream, - size_t start_idx, - size_t stop_idx) const -{ - std::lock_guard<std::recursive_mutex> guard(m_mutex); - stop_idx = std::min(stop_idx + 1, m_history.size()); - for (size_t counter = start_idx; - counter < stop_idx; - counter++) - { - const std::string hist_item = m_history[counter]; - if (!hist_item.empty()) - { - stream.Indent(); - stream.Printf("%4" PRIu64 ": %s\n", (uint64_t)counter, hist_item.c_str()); - } +void CommandHistory::Dump(Stream &stream, size_t start_idx, + size_t stop_idx) const { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + stop_idx = std::min(stop_idx + 1, m_history.size()); + for (size_t counter = start_idx; counter < stop_idx; counter++) { + const std::string hist_item = m_history[counter]; + if (!hist_item.empty()) { + stream.Indent(); + stream.Printf("%4" PRIu64 ": %s\n", (uint64_t)counter, hist_item.c_str()); } + } } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp index 5d5669f..d44eb25 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// +#include <stdlib.h> #include <string> #include <vector> -#include <stdlib.h> #include "CommandObjectScript.h" #include "lldb/Interpreter/CommandObjectRegexCommand.h" @@ -18,11 +18,13 @@ #include "../Commands/CommandObjectArgs.h" #include "../Commands/CommandObjectBreakpoint.h" #include "../Commands/CommandObjectBugreport.h" +#include "../Commands/CommandObjectCommands.h" #include "../Commands/CommandObjectDisassemble.h" #include "../Commands/CommandObjectExpression.h" #include "../Commands/CommandObjectFrame.h" #include "../Commands/CommandObjectGUI.h" #include "../Commands/CommandObjectHelp.h" +#include "../Commands/CommandObjectLanguage.h" #include "../Commands/CommandObjectLog.h" #include "../Commands/CommandObjectMemory.h" #include "../Commands/CommandObjectPlatform.h" @@ -32,14 +34,12 @@ #include "../Commands/CommandObjectRegister.h" #include "../Commands/CommandObjectSettings.h" #include "../Commands/CommandObjectSource.h" -#include "../Commands/CommandObjectCommands.h" #include "../Commands/CommandObjectSyntax.h" #include "../Commands/CommandObjectTarget.h" #include "../Commands/CommandObjectThread.h" #include "../Commands/CommandObjectType.h" #include "../Commands/CommandObjectVersion.h" #include "../Commands/CommandObjectWatchpoint.h" -#include "../Commands/CommandObjectLanguage.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Log.h" @@ -59,3255 +59,3021 @@ #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/OptionValueProperties.h" +#include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/Property.h" - #include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" #include "lldb/Target/TargetList.h" +#include "lldb/Target/Thread.h" #include "lldb/Utility/CleanUp.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/Path.h" +#include "llvm/Support/PrettyStackTrace.h" using namespace lldb; using namespace lldb_private; static const char *k_white_space = " \t\v"; -static PropertyDefinition -g_properties[] = -{ - { "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." }, - { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." }, - { "stop-command-source-on-error", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, LLDB will stop running a 'command source' script upon encountering an error." }, - { "space-repl-prompts", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, blank lines will be printed between between REPL submissions." }, - { nullptr , OptionValue::eTypeInvalid, true, 0 , nullptr, nullptr, nullptr } -}; +static PropertyDefinition g_properties[] = { + {"expand-regex-aliases", OptionValue::eTypeBoolean, true, false, nullptr, + nullptr, "If true, regular expression alias commands will show the " + "expanded command that will be executed. This can be used to " + "debug new regular expression alias commands."}, + {"prompt-on-quit", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, + "If true, LLDB will prompt you before quitting if there are any live " + "processes being debugged. If false, LLDB will quit without asking in any " + "case."}, + {"stop-command-source-on-error", OptionValue::eTypeBoolean, true, true, + nullptr, nullptr, "If true, LLDB will stop running a 'command source' " + "script upon encountering an error."}, + {"space-repl-prompts", OptionValue::eTypeBoolean, true, false, nullptr, + nullptr, + "If true, blank lines will be printed between between REPL submissions."}, + {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}}; -enum -{ - ePropertyExpandRegexAliases = 0, - ePropertyPromptOnQuit = 1, - ePropertyStopCmdSourceOnError = 2, - eSpaceReplPrompts = 3 +enum { + ePropertyExpandRegexAliases = 0, + ePropertyPromptOnQuit = 1, + ePropertyStopCmdSourceOnError = 2, + eSpaceReplPrompts = 3 }; -ConstString & -CommandInterpreter::GetStaticBroadcasterClass () -{ - static ConstString class_name ("lldb.commandInterpreter"); - return class_name; +ConstString &CommandInterpreter::GetStaticBroadcasterClass() { + static ConstString class_name("lldb.commandInterpreter"); + return class_name; } -CommandInterpreter::CommandInterpreter(Debugger &debugger, ScriptLanguage script_language, bool synchronous_execution) - : Broadcaster(debugger.GetBroadcasterManager(), CommandInterpreter::GetStaticBroadcasterClass().AsCString()), - Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))), +CommandInterpreter::CommandInterpreter(Debugger &debugger, + ScriptLanguage script_language, + bool synchronous_execution) + : Broadcaster(debugger.GetBroadcasterManager(), + CommandInterpreter::GetStaticBroadcasterClass().AsCString()), + Properties(OptionValuePropertiesSP( + new OptionValueProperties(ConstString("interpreter")))), IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand), - m_debugger(debugger), - m_synchronous_execution(synchronous_execution), - m_skip_lldbinit_files(false), - m_skip_app_init_files(false), - m_script_interpreter_sp(), - m_command_io_handler_sp(), - m_comment_char('#'), - m_batch_command_mode(false), - m_truncation_warning(eNoTruncation), - m_command_source_depth(0), - m_num_errors(0), - m_quit_requested(false), - m_stopped_for_crash(false) -{ - debugger.SetScriptLanguage (script_language); - SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit"); - SetEventName (eBroadcastBitResetPrompt, "reset-prompt"); - SetEventName (eBroadcastBitQuitCommandReceived, "quit"); - CheckInWithManager (); - m_collection_sp->Initialize (g_properties); -} - -bool -CommandInterpreter::GetExpandRegexAliases () const -{ - const uint32_t idx = ePropertyExpandRegexAliases; - return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); -} - -bool -CommandInterpreter::GetPromptOnQuit () const -{ - const uint32_t idx = ePropertyPromptOnQuit; - return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); -} - -void -CommandInterpreter::SetPromptOnQuit (bool b) -{ - const uint32_t idx = ePropertyPromptOnQuit; - m_collection_sp->SetPropertyAtIndexAsBoolean (nullptr, idx, b); -} - -void -CommandInterpreter::ResolveCommand(const char *command_line, CommandReturnObject &result) -{ - std::string command = command_line; - if (ResolveCommandImpl(command, result) != nullptr) { - result.AppendMessageWithFormat("%s", command.c_str()); - result.SetStatus(eReturnStatusSuccessFinishResult); - } -} - - -bool -CommandInterpreter::GetStopCmdSourceOnError () const -{ - const uint32_t idx = ePropertyStopCmdSourceOnError; - return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); -} - -bool -CommandInterpreter::GetSpaceReplPrompts () const -{ - const uint32_t idx = eSpaceReplPrompts; - return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0); -} - -void -CommandInterpreter::Initialize () -{ - Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); - - CommandReturnObject result; - - LoadCommandDictionary (); - - // An alias arguments vector to reuse - reset it before use... - OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector); - - // Set up some initial aliases. - CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false); - if (cmd_obj_sp) - { - AddAlias ("q", cmd_obj_sp); - AddAlias ("exit", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("_regexp-attach",false); - if (cmd_obj_sp) - AddAlias ("attach", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("process detach",false); - if (cmd_obj_sp) - { - AddAlias ("detach", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("process continue", false); - if (cmd_obj_sp) - { - AddAlias ("c", cmd_obj_sp); - AddAlias ("continue", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("_regexp-break",false); - if (cmd_obj_sp) - AddAlias ("b", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false); - if (cmd_obj_sp) - AddAlias ("tbreak", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("thread step-inst", false); - if (cmd_obj_sp) - { - AddAlias ("stepi", cmd_obj_sp); - AddAlias ("si", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("thread step-inst-over", false); - if (cmd_obj_sp) - { - AddAlias ("nexti", cmd_obj_sp); - AddAlias ("ni", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("thread step-in", false); - if (cmd_obj_sp) - { - AddAlias ("s", cmd_obj_sp); - AddAlias ("step", cmd_obj_sp); - CommandAlias *sif_alias = AddAlias ("sif", cmd_obj_sp, "--end-linenumber block --step-in-target %1"); - if (sif_alias) - { - sif_alias->SetHelp("Step through the current block, stopping if you step " - "directly into a function whose name matches the TargetFunctionName."); - sif_alias->SetSyntax("sif <TargetFunctionName>"); - } - } - - cmd_obj_sp = GetCommandSPExact ("thread step-over", false); - if (cmd_obj_sp) - { - AddAlias ("n", cmd_obj_sp); - AddAlias ("next", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("thread step-out", false); - if (cmd_obj_sp) - { - AddAlias ("finish", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("frame select", false); - if (cmd_obj_sp) - { - AddAlias ("f", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("thread select", false); - if (cmd_obj_sp) - { - AddAlias ("t", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("_regexp-jump",false); - if (cmd_obj_sp) - { - AddAlias ("j", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - AddAlias ("jump", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - } - - cmd_obj_sp = GetCommandSPExact ("_regexp-list", false); - if (cmd_obj_sp) - { - AddAlias ("l", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - AddAlias ("list", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - } - - cmd_obj_sp = GetCommandSPExact ("_regexp-env", false); - if (cmd_obj_sp) - AddAlias ("env", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("memory read", false); - if (cmd_obj_sp) - AddAlias ("x", cmd_obj_sp); - - cmd_obj_sp = GetCommandSPExact ("_regexp-up", false); - if (cmd_obj_sp) - AddAlias ("up", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("_regexp-down", false); - if (cmd_obj_sp) - AddAlias ("down", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("_regexp-display", false); - if (cmd_obj_sp) - AddAlias ("display", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("disassemble", false); - if (cmd_obj_sp) - AddAlias ("dis", cmd_obj_sp); - - cmd_obj_sp = GetCommandSPExact ("disassemble", false); - if (cmd_obj_sp) - AddAlias ("di", cmd_obj_sp); - - - - cmd_obj_sp = GetCommandSPExact ("_regexp-undisplay", false); - if (cmd_obj_sp) - AddAlias ("undisplay", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("_regexp-bt", false); - if (cmd_obj_sp) - AddAlias ("bt", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); - - cmd_obj_sp = GetCommandSPExact ("target create", false); - if (cmd_obj_sp) - AddAlias ("file", cmd_obj_sp); - - cmd_obj_sp = GetCommandSPExact ("target modules", false); - if (cmd_obj_sp) - AddAlias ("image", cmd_obj_sp); - - + m_debugger(debugger), m_synchronous_execution(synchronous_execution), + m_skip_lldbinit_files(false), m_skip_app_init_files(false), + m_script_interpreter_sp(), m_command_io_handler_sp(), m_comment_char('#'), + m_batch_command_mode(false), m_truncation_warning(eNoTruncation), + m_command_source_depth(0), m_num_errors(0), m_quit_requested(false), + m_stopped_for_crash(false) { + debugger.SetScriptLanguage(script_language); + SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit"); + SetEventName(eBroadcastBitResetPrompt, "reset-prompt"); + SetEventName(eBroadcastBitQuitCommandReceived, "quit"); + CheckInWithManager(); + m_collection_sp->Initialize(g_properties); +} + +bool CommandInterpreter::GetExpandRegexAliases() const { + const uint32_t idx = ePropertyExpandRegexAliases; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +bool CommandInterpreter::GetPromptOnQuit() const { + const uint32_t idx = ePropertyPromptOnQuit; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +void CommandInterpreter::SetPromptOnQuit(bool b) { + const uint32_t idx = ePropertyPromptOnQuit; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); +} + +void CommandInterpreter::ResolveCommand(const char *command_line, + CommandReturnObject &result) { + std::string command = command_line; + if (ResolveCommandImpl(command, result) != nullptr) { + result.AppendMessageWithFormat("%s", command.c_str()); + result.SetStatus(eReturnStatusSuccessFinishResult); + } +} + +bool CommandInterpreter::GetStopCmdSourceOnError() const { + const uint32_t idx = ePropertyStopCmdSourceOnError; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +bool CommandInterpreter::GetSpaceReplPrompts() const { + const uint32_t idx = eSpaceReplPrompts; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +void CommandInterpreter::Initialize() { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION); + + CommandReturnObject result; + + LoadCommandDictionary(); + + // An alias arguments vector to reuse - reset it before use... + OptionArgVectorSP alias_arguments_vector_sp(new OptionArgVector); + + // Set up some initial aliases. + CommandObjectSP cmd_obj_sp = GetCommandSPExact("quit", false); + if (cmd_obj_sp) { + AddAlias("q", cmd_obj_sp); + AddAlias("exit", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("_regexp-attach", false); + if (cmd_obj_sp) + AddAlias("attach", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("process detach", false); + if (cmd_obj_sp) { + AddAlias("detach", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("process continue", false); + if (cmd_obj_sp) { + AddAlias("c", cmd_obj_sp); + AddAlias("continue", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("_regexp-break", false); + if (cmd_obj_sp) + AddAlias("b", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("_regexp-tbreak", false); + if (cmd_obj_sp) + AddAlias("tbreak", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("thread step-inst", false); + if (cmd_obj_sp) { + AddAlias("stepi", cmd_obj_sp); + AddAlias("si", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("thread step-inst-over", false); + if (cmd_obj_sp) { + AddAlias("nexti", cmd_obj_sp); + AddAlias("ni", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("thread step-in", false); + if (cmd_obj_sp) { + AddAlias("s", cmd_obj_sp); + AddAlias("step", cmd_obj_sp); + CommandAlias *sif_alias = AddAlias( + "sif", cmd_obj_sp, "--end-linenumber block --step-in-target %1"); + if (sif_alias) { + sif_alias->SetHelp("Step through the current block, stopping if you step " + "directly into a function whose name matches the " + "TargetFunctionName."); + sif_alias->SetSyntax("sif <TargetFunctionName>"); + } + } + + cmd_obj_sp = GetCommandSPExact("thread step-over", false); + if (cmd_obj_sp) { + AddAlias("n", cmd_obj_sp); + AddAlias("next", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("thread step-out", false); + if (cmd_obj_sp) { + AddAlias("finish", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("frame select", false); + if (cmd_obj_sp) { + AddAlias("f", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("thread select", false); + if (cmd_obj_sp) { + AddAlias("t", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("_regexp-jump", false); + if (cmd_obj_sp) { + AddAlias("j", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + AddAlias("jump", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + } + + cmd_obj_sp = GetCommandSPExact("_regexp-list", false); + if (cmd_obj_sp) { + AddAlias("l", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + AddAlias("list", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + } + + cmd_obj_sp = GetCommandSPExact("_regexp-env", false); + if (cmd_obj_sp) + AddAlias("env", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("memory read", false); + if (cmd_obj_sp) + AddAlias("x", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact("_regexp-up", false); + if (cmd_obj_sp) + AddAlias("up", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("_regexp-down", false); + if (cmd_obj_sp) + AddAlias("down", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("_regexp-display", false); + if (cmd_obj_sp) + AddAlias("display", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("disassemble", false); + if (cmd_obj_sp) + AddAlias("dis", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact("disassemble", false); + if (cmd_obj_sp) + AddAlias("di", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact("_regexp-undisplay", false); + if (cmd_obj_sp) + AddAlias("undisplay", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("_regexp-bt", false); + if (cmd_obj_sp) + AddAlias("bt", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax()); + + cmd_obj_sp = GetCommandSPExact("target create", false); + if (cmd_obj_sp) + AddAlias("file", cmd_obj_sp); + + cmd_obj_sp = GetCommandSPExact("target modules", false); + if (cmd_obj_sp) + AddAlias("image", cmd_obj_sp); + + alias_arguments_vector_sp.reset(new OptionArgVector); + + cmd_obj_sp = GetCommandSPExact("expression", false); + if (cmd_obj_sp) { + AddAlias("p", cmd_obj_sp, "--")->SetHelpLong(""); + AddAlias("print", cmd_obj_sp, "--")->SetHelpLong(""); + AddAlias("call", cmd_obj_sp, "--")->SetHelpLong(""); + if (auto po = AddAlias("po", cmd_obj_sp, "-O --")) { + po->SetHelp("Evaluate an expression on the current thread. Displays any " + "returned value with formatting " + "controlled by the type's author."); + po->SetHelpLong(""); + } + AddAlias("parray", cmd_obj_sp, "--element-count %1 --")->SetHelpLong(""); + AddAlias("poarray", cmd_obj_sp, + "--object-description --element-count %1 --") + ->SetHelpLong(""); + } + + cmd_obj_sp = GetCommandSPExact("process kill", false); + if (cmd_obj_sp) { + AddAlias("kill", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("process launch", false); + if (cmd_obj_sp) { alias_arguments_vector_sp.reset(new OptionArgVector); - - cmd_obj_sp = GetCommandSPExact ("expression", false); - if (cmd_obj_sp) - { - AddAlias ("p", cmd_obj_sp, "--")->SetHelpLong(""); - AddAlias ("print", cmd_obj_sp, "--")->SetHelpLong(""); - AddAlias ("call", cmd_obj_sp, "--")->SetHelpLong(""); - if (auto po = AddAlias ("po", cmd_obj_sp, "-O --")) - { - po->SetHelp("Evaluate an expression on the current thread. Displays any returned value with formatting " - "controlled by the type's author."); - po->SetHelpLong(""); - } - AddAlias("parray", cmd_obj_sp, "--element-count %1 --")->SetHelpLong(""); - AddAlias("poarray", cmd_obj_sp, "--object-description --element-count %1 --")->SetHelpLong(""); - } - - cmd_obj_sp = GetCommandSPExact ("process kill", false); - if (cmd_obj_sp) - { - AddAlias ("kill", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("process launch", false); - if (cmd_obj_sp) - { - alias_arguments_vector_sp.reset (new OptionArgVector); -#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__) - AddAlias ("r", cmd_obj_sp, "--"); - AddAlias ("run", cmd_obj_sp, "--"); +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) + AddAlias("r", cmd_obj_sp, "--"); + AddAlias("run", cmd_obj_sp, "--"); +#else +#if defined(__APPLE__) + std::string shell_option; + shell_option.append("--shell-expand-args"); + shell_option.append(" true"); + shell_option.append(" --"); + AddAlias("r", cmd_obj_sp, "--shell-expand-args true --"); + AddAlias("run", cmd_obj_sp, "--shell-expand-args true --"); #else - #if defined(__APPLE__) - std::string shell_option; - shell_option.append("--shell-expand-args"); - shell_option.append(" true"); - shell_option.append(" --"); - AddAlias ("r", cmd_obj_sp, "--shell-expand-args true --"); - AddAlias ("run", cmd_obj_sp, "--shell-expand-args true --"); - #else - StreamString defaultshell; - defaultshell.Printf("--shell=%s --", HostInfo::GetDefaultShell().GetPath().c_str()); - AddAlias ("r", cmd_obj_sp, defaultshell.GetData()); - AddAlias ("run", cmd_obj_sp, defaultshell.GetData()); - #endif + StreamString defaultshell; + defaultshell.Printf("--shell=%s --", + HostInfo::GetDefaultShell().GetPath().c_str()); + AddAlias("r", cmd_obj_sp, defaultshell.GetString()); + AddAlias("run", cmd_obj_sp, defaultshell.GetString()); #endif - } - - cmd_obj_sp = GetCommandSPExact ("target symbols add", false); - if (cmd_obj_sp) - { - AddAlias ("add-dsym", cmd_obj_sp); - } - - cmd_obj_sp = GetCommandSPExact ("breakpoint set", false); - if (cmd_obj_sp) - { - AddAlias ("rbreak", cmd_obj_sp, "--func-regex %1"); - } -} - -void -CommandInterpreter::Clear() -{ - m_command_io_handler_sp.reset(); - - if (m_script_interpreter_sp) - m_script_interpreter_sp->Clear(); -} +#endif + } + + cmd_obj_sp = GetCommandSPExact("target symbols add", false); + if (cmd_obj_sp) { + AddAlias("add-dsym", cmd_obj_sp); + } + + cmd_obj_sp = GetCommandSPExact("breakpoint set", false); + if (cmd_obj_sp) { + AddAlias("rbreak", cmd_obj_sp, "--func-regex %1"); + } +} + +void CommandInterpreter::Clear() { + m_command_io_handler_sp.reset(); + + if (m_script_interpreter_sp) + m_script_interpreter_sp->Clear(); +} + +const char *CommandInterpreter::ProcessEmbeddedScriptCommands(const char *arg) { + // This function has not yet been implemented. + + // Look for any embedded script command + // If found, + // get interpreter object from the command dictionary, + // call execute_one_command on it, + // get the results as a string, + // substitute that string for current stuff. + + return arg; +} + +void CommandInterpreter::LoadCommandDictionary() { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION); + + lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage(); + + m_command_dict["apropos"] = CommandObjectSP(new CommandObjectApropos(*this)); + m_command_dict["breakpoint"] = + CommandObjectSP(new CommandObjectMultiwordBreakpoint(*this)); + m_command_dict["bugreport"] = + CommandObjectSP(new CommandObjectMultiwordBugreport(*this)); + m_command_dict["command"] = + CommandObjectSP(new CommandObjectMultiwordCommands(*this)); + m_command_dict["disassemble"] = + CommandObjectSP(new CommandObjectDisassemble(*this)); + m_command_dict["expression"] = + CommandObjectSP(new CommandObjectExpression(*this)); + m_command_dict["frame"] = + CommandObjectSP(new CommandObjectMultiwordFrame(*this)); + m_command_dict["gui"] = CommandObjectSP(new CommandObjectGUI(*this)); + m_command_dict["help"] = CommandObjectSP(new CommandObjectHelp(*this)); + m_command_dict["log"] = CommandObjectSP(new CommandObjectLog(*this)); + m_command_dict["memory"] = CommandObjectSP(new CommandObjectMemory(*this)); + m_command_dict["platform"] = + CommandObjectSP(new CommandObjectPlatform(*this)); + m_command_dict["plugin"] = CommandObjectSP(new CommandObjectPlugin(*this)); + m_command_dict["process"] = + CommandObjectSP(new CommandObjectMultiwordProcess(*this)); + m_command_dict["quit"] = CommandObjectSP(new CommandObjectQuit(*this)); + m_command_dict["register"] = + CommandObjectSP(new CommandObjectRegister(*this)); + m_command_dict["script"] = + CommandObjectSP(new CommandObjectScript(*this, script_language)); + m_command_dict["settings"] = + CommandObjectSP(new CommandObjectMultiwordSettings(*this)); + m_command_dict["source"] = + CommandObjectSP(new CommandObjectMultiwordSource(*this)); + m_command_dict["target"] = + CommandObjectSP(new CommandObjectMultiwordTarget(*this)); + m_command_dict["thread"] = + CommandObjectSP(new CommandObjectMultiwordThread(*this)); + m_command_dict["type"] = CommandObjectSP(new CommandObjectType(*this)); + m_command_dict["version"] = CommandObjectSP(new CommandObjectVersion(*this)); + m_command_dict["watchpoint"] = + CommandObjectSP(new CommandObjectMultiwordWatchpoint(*this)); + m_command_dict["language"] = + CommandObjectSP(new CommandObjectLanguage(*this)); + + const char *break_regexes[][2] = { + {"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", + "breakpoint set --file '%1' --line %2"}, + {"^/([^/]+)/$", "breakpoint set --source-pattern-regexp '%1'"}, + {"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"}, + {"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"}, + {"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", + "breakpoint set --name '%1'"}, + {"^(-.*)$", "breakpoint set %1"}, + {"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", + "breakpoint set --name '%2' --shlib '%1'"}, + {"^\\&(.*[^[:space:]])[[:space:]]*$", + "breakpoint set --name '%1' --skip-prologue=0"}, + {"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$", + "breakpoint set --name '%1'"}}; + + size_t num_regexes = llvm::array_lengthof(break_regexes); + + std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-break", + "Set a breakpoint using one of several shorthand formats.\n", + "\n" + "_regexp-break <filename>:<linenum>\n" + " main.c:12 // Break at line 12 of " + "main.c\n\n" + "_regexp-break <linenum>\n" + " 12 // Break at line 12 of current " + "file\n\n" + "_regexp-break 0x<address>\n" + " 0x1234000 // Break at address " + "0x1234000\n\n" + "_regexp-break <name>\n" + " main // Break in 'main' after the " + "prologue\n\n" + "_regexp-break &<name>\n" + " &main // Break at first instruction " + "in 'main'\n\n" + "_regexp-break <module>`<name>\n" + " libc.so`malloc // Break in 'malloc' from " + "'libc.so'\n\n" + "_regexp-break /<source-regex>/\n" + " /break here/ // Break on source lines in " + "current file\n" + " // containing text 'break " + "here'.\n", + 2, CommandCompletions::eSymbolCompletion | + CommandCompletions::eSourceFileCompletion, + false)); + + if (break_regex_cmd_ap.get()) { + bool success = true; + for (size_t i = 0; i < num_regexes; i++) { + success = break_regex_cmd_ap->AddRegexCommand(break_regexes[i][0], + break_regexes[i][1]); + if (!success) + break; + } + success = + break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full"); + + if (success) { + CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release()); + m_command_dict[break_regex_cmd_sp->GetCommandName()] = break_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> tbreak_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-tbreak", + "Set a one-shot breakpoint using one of several shorthand formats.\n", + "\n" + "_regexp-break <filename>:<linenum>\n" + " main.c:12 // Break at line 12 of " + "main.c\n\n" + "_regexp-break <linenum>\n" + " 12 // Break at line 12 of current " + "file\n\n" + "_regexp-break 0x<address>\n" + " 0x1234000 // Break at address " + "0x1234000\n\n" + "_regexp-break <name>\n" + " main // Break in 'main' after the " + "prologue\n\n" + "_regexp-break &<name>\n" + " &main // Break at first instruction " + "in 'main'\n\n" + "_regexp-break <module>`<name>\n" + " libc.so`malloc // Break in 'malloc' from " + "'libc.so'\n\n" + "_regexp-break /<source-regex>/\n" + " /break here/ // Break on source lines in " + "current file\n" + " // containing text 'break " + "here'.\n", + 2, CommandCompletions::eSymbolCompletion | + CommandCompletions::eSourceFileCompletion, + false)); + + if (tbreak_regex_cmd_ap.get()) { + bool success = true; + for (size_t i = 0; i < num_regexes; i++) { + // If you add a resultant command string longer than 1024 characters be + // sure to increase the size of this buffer. + char buffer[1024]; + int num_printed = + snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o"); + assert(num_printed < 1024); + UNUSED_IF_ASSERT_DISABLED(num_printed); + success = + tbreak_regex_cmd_ap->AddRegexCommand(break_regexes[i][0], buffer); + if (!success) + break; + } + success = + tbreak_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full"); + + if (success) { + CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_ap.release()); + m_command_dict[tbreak_regex_cmd_sp->GetCommandName()] = + tbreak_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-attach", "Attach to process by ID or name.", + "_regexp-attach <pid> | <process-name>", 2, 0, false)); + if (attach_regex_cmd_ap.get()) { + if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", + "process attach --pid %1") && + attach_regex_cmd_ap->AddRegexCommand( + "^(-.*|.* -.*)$", "process attach %1") && // Any options that are + // specified get passed to + // 'process attach' + attach_regex_cmd_ap->AddRegexCommand("^(.+)$", + "process attach --name '%1'") && + attach_regex_cmd_ap->AddRegexCommand("^$", "process attach")) { + CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_ap.release()); + m_command_dict[attach_regex_cmd_sp->GetCommandName()] = + attach_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> down_regex_cmd_ap( + new CommandObjectRegexCommand(*this, "_regexp-down", + "Select a newer stack frame. Defaults to " + "moving one frame, a numeric argument can " + "specify an arbitrary number.", + "_regexp-down [<count>]", 2, 0, false)); + if (down_regex_cmd_ap.get()) { + if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") && + down_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", + "frame select -r -%1")) { + CommandObjectSP down_regex_cmd_sp(down_regex_cmd_ap.release()); + m_command_dict[down_regex_cmd_sp->GetCommandName()] = down_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> up_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-up", + "Select an older stack frame. Defaults to moving one " + "frame, a numeric argument can specify an arbitrary number.", + "_regexp-up [<count>]", 2, 0, false)); + if (up_regex_cmd_ap.get()) { + if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") && + up_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r %1")) { + CommandObjectSP up_regex_cmd_sp(up_regex_cmd_ap.release()); + m_command_dict[up_regex_cmd_sp->GetCommandName()] = up_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> display_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-display", + "Evaluate an expression at every stop (see 'help target stop-hook'.)", + "_regexp-display expression", 2, 0, false)); + if (display_regex_cmd_ap.get()) { + if (display_regex_cmd_ap->AddRegexCommand( + "^(.+)$", "target stop-hook add -o \"expr -- %1\"")) { + CommandObjectSP display_regex_cmd_sp(display_regex_cmd_ap.release()); + m_command_dict[display_regex_cmd_sp->GetCommandName()] = + display_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> undisplay_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-undisplay", "Stop displaying expression at every " + "stop (specified by stop-hook index.)", + "_regexp-undisplay stop-hook-number", 2, 0, false)); + if (undisplay_regex_cmd_ap.get()) { + if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", + "target stop-hook delete %1")) { + CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_ap.release()); + m_command_dict[undisplay_regex_cmd_sp->GetCommandName()] = + undisplay_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_ap( + new CommandObjectRegexCommand( + *this, "gdb-remote", "Connect to a process via remote GDB server. " + "If no host is specifed, localhost is assumed.", + "gdb-remote [<hostname>:]<portnum>", 2, 0, false)); + if (connect_gdb_remote_cmd_ap.get()) { + if (connect_gdb_remote_cmd_ap->AddRegexCommand( + "^([^:]+:[[:digit:]]+)$", + "process connect --plugin gdb-remote connect://%1") && + connect_gdb_remote_cmd_ap->AddRegexCommand( + "^([[:digit:]]+)$", + "process connect --plugin gdb-remote connect://localhost:%1")) { + CommandObjectSP command_sp(connect_gdb_remote_cmd_ap.release()); + m_command_dict[command_sp->GetCommandName()] = command_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_ap( + new CommandObjectRegexCommand( + *this, "kdp-remote", "Connect to a process via remote KDP server. " + "If no UDP port is specified, port 41139 is " + "assumed.", + "kdp-remote <hostname>[:<portnum>]", 2, 0, false)); + if (connect_kdp_remote_cmd_ap.get()) { + if (connect_kdp_remote_cmd_ap->AddRegexCommand( + "^([^:]+:[[:digit:]]+)$", + "process connect --plugin kdp-remote udp://%1") && + connect_kdp_remote_cmd_ap->AddRegexCommand( + "^(.+)$", "process connect --plugin kdp-remote udp://%1:41139")) { + CommandObjectSP command_sp(connect_kdp_remote_cmd_ap.release()); + m_command_dict[command_sp->GetCommandName()] = command_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> bt_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-bt", + "Show the current thread's call stack. Any numeric argument " + "displays at most that many " + "frames. The argument 'all' displays all threads.", + "bt [<digit> | all]", 2, 0, false)); + if (bt_regex_cmd_ap.get()) { + // accept but don't document "bt -c <number>" -- before bt was a regex + // command if you wanted to backtrace + // three frames you would do "bt -c 3" but the intention is to have this + // emulate the gdb "bt" command and + // so now "bt 3" is the preferred form, in line with gdb. + if (bt_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", + "thread backtrace -c %1") && + bt_regex_cmd_ap->AddRegexCommand("^-c ([[:digit:]]+)$", + "thread backtrace -c %1") && + bt_regex_cmd_ap->AddRegexCommand("^all$", "thread backtrace all") && + bt_regex_cmd_ap->AddRegexCommand("^$", "thread backtrace")) { + CommandObjectSP command_sp(bt_regex_cmd_ap.release()); + m_command_dict[command_sp->GetCommandName()] = command_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> list_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-list", + "List relevant source code using one of several shorthand formats.", + "\n" + "_regexp-list <file>:<line> // List around specific file/line\n" + "_regexp-list <line> // List current file around specified " + "line\n" + "_regexp-list <function-name> // List specified function\n" + "_regexp-list 0x<address> // List around specified address\n" + "_regexp-list -[<count>] // List previous <count> lines\n" + "_regexp-list // List subsequent lines", + 2, CommandCompletions::eSourceFileCompletion, false)); + if (list_regex_cmd_ap.get()) { + if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", + "source list --line %1") && + list_regex_cmd_ap->AddRegexCommand( + "^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]" + "]*$", + "source list --file '%1' --line %2") && + list_regex_cmd_ap->AddRegexCommand( + "^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", + "source list --address %1") && + list_regex_cmd_ap->AddRegexCommand("^-[[:space:]]*$", + "source list --reverse") && + list_regex_cmd_ap->AddRegexCommand( + "^-([[:digit:]]+)[[:space:]]*$", + "source list --reverse --count %1") && + list_regex_cmd_ap->AddRegexCommand("^(.+)$", + "source list --name \"%1\"") && + list_regex_cmd_ap->AddRegexCommand("^$", "source list")) { + CommandObjectSP list_regex_cmd_sp(list_regex_cmd_ap.release()); + m_command_dict[list_regex_cmd_sp->GetCommandName()] = list_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> env_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-env", + "Shorthand for viewing and setting environment variables.", + "\n" + "_regexp-env // Show enrivonment\n" + "_regexp-env <name>=<value> // Set an environment variable", + 2, 0, false)); + if (env_regex_cmd_ap.get()) { + if (env_regex_cmd_ap->AddRegexCommand("^$", + "settings show target.env-vars") && + env_regex_cmd_ap->AddRegexCommand("^([A-Za-z_][A-Za-z_0-9]*=.*)$", + "settings set target.env-vars %1")) { + CommandObjectSP env_regex_cmd_sp(env_regex_cmd_ap.release()); + m_command_dict[env_regex_cmd_sp->GetCommandName()] = env_regex_cmd_sp; + } + } + + std::unique_ptr<CommandObjectRegexCommand> jump_regex_cmd_ap( + new CommandObjectRegexCommand( + *this, "_regexp-jump", "Set the program counter to a new address.", + "\n" + "_regexp-jump <line>\n" + "_regexp-jump +<line-offset> | -<line-offset>\n" + "_regexp-jump <file>:<line>\n" + "_regexp-jump *<addr>\n", + 2, 0, false)); + if (jump_regex_cmd_ap.get()) { + if (jump_regex_cmd_ap->AddRegexCommand("^\\*(.*)$", + "thread jump --addr %1") && + jump_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", + "thread jump --line %1") && + jump_regex_cmd_ap->AddRegexCommand("^([^:]+):([0-9]+)$", + "thread jump --file %1 --line %2") && + jump_regex_cmd_ap->AddRegexCommand("^([+\\-][0-9]+)$", + "thread jump --by %1")) { + CommandObjectSP jump_regex_cmd_sp(jump_regex_cmd_ap.release()); + m_command_dict[jump_regex_cmd_sp->GetCommandName()] = jump_regex_cmd_sp; + } + } +} + +int CommandInterpreter::GetCommandNamesMatchingPartialString( + const char *cmd_str, bool include_aliases, StringList &matches) { + AddNamesMatchingPartialString(m_command_dict, cmd_str, matches); + + if (include_aliases) { + AddNamesMatchingPartialString(m_alias_dict, cmd_str, matches); + } + + return matches.GetSize(); +} + +CommandObjectSP CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, + bool include_aliases, + bool exact, + StringList *matches) const { + CommandObjectSP command_sp; + + std::string cmd = cmd_str; + + if (HasCommands()) { + auto pos = m_command_dict.find(cmd); + if (pos != m_command_dict.end()) + command_sp = pos->second; + } -const char * -CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg) -{ - // This function has not yet been implemented. + if (include_aliases && HasAliases()) { + auto alias_pos = m_alias_dict.find(cmd); + if (alias_pos != m_alias_dict.end()) + command_sp = alias_pos->second; + } - // Look for any embedded script command - // If found, - // get interpreter object from the command dictionary, - // call execute_one_command on it, - // get the results as a string, - // substitute that string for current stuff. + if (HasUserCommands()) { + auto pos = m_user_dict.find(cmd); + if (pos != m_user_dict.end()) + command_sp = pos->second; + } - return arg; -} + if (!exact && !command_sp) { + // We will only get into here if we didn't find any exact matches. + CommandObjectSP user_match_sp, alias_match_sp, real_match_sp; -void -CommandInterpreter::LoadCommandDictionary () -{ - Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); - - lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage(); - - m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this)); - m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this)); - m_command_dict["bugreport"] = CommandObjectSP (new CommandObjectMultiwordBugreport (*this)); - m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this)); - m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this)); - m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this)); - m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this)); - m_command_dict["gui"] = CommandObjectSP (new CommandObjectGUI (*this)); - m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this)); - m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this)); - m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this)); - m_command_dict["platform"] = CommandObjectSP (new CommandObjectPlatform (*this)); - m_command_dict["plugin"] = CommandObjectSP (new CommandObjectPlugin (*this)); - m_command_dict["process"] = CommandObjectSP (new CommandObjectMultiwordProcess (*this)); - m_command_dict["quit"] = CommandObjectSP (new CommandObjectQuit (*this)); - m_command_dict["register"] = CommandObjectSP (new CommandObjectRegister (*this)); - m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (*this, script_language)); - m_command_dict["settings"] = CommandObjectSP (new CommandObjectMultiwordSettings (*this)); - m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this)); - m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); - m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); - m_command_dict["type"] = CommandObjectSP (new CommandObjectType (*this)); - m_command_dict["version"] = CommandObjectSP (new CommandObjectVersion (*this)); - m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this)); - m_command_dict["language"] = CommandObjectSP (new CommandObjectLanguage(*this)); - - const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"}, - {"^/([^/]+)/$", "breakpoint set --source-pattern-regexp '%1'"}, - {"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"}, - {"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"}, - {"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"}, - {"^(-.*)$", "breakpoint set %1"}, - {"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"}, - {"^\\&(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1' --skip-prologue=0"}, - {"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"}}; - - size_t num_regexes = llvm::array_lengthof(break_regexes); - - std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_ap(new CommandObjectRegexCommand( - *this, "_regexp-break", "Set a breakpoint using one of several shorthand formats.\n", - "\n" - "_regexp-break <filename>:<linenum>\n" - " main.c:12 // Break at line 12 of main.c\n\n" - "_regexp-break <linenum>\n" - " 12 // Break at line 12 of current file\n\n" - "_regexp-break 0x<address>\n" - " 0x1234000 // Break at address 0x1234000\n\n" - "_regexp-break <name>\n" - " main // Break in 'main' after the prologue\n\n" - "_regexp-break &<name>\n" - " &main // Break at first instruction in 'main'\n\n" - "_regexp-break <module>`<name>\n" - " libc.so`malloc // Break in 'malloc' from 'libc.so'\n\n" - "_regexp-break /<source-regex>/\n" - " /break here/ // Break on source lines in current file\n" - " // containing text 'break here'.\n", - 2, CommandCompletions::eSymbolCompletion | CommandCompletions::eSourceFileCompletion, false)); - - if (break_regex_cmd_ap.get()) - { - bool success = true; - for (size_t i = 0; i < num_regexes; i++) - { - success = break_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], break_regexes[i][1]); - if (!success) - break; - } - success = break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full"); + StringList local_matches; + if (matches == nullptr) + matches = &local_matches; - if (success) - { - CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release()); - m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp; - } - } + unsigned int num_cmd_matches = 0; + unsigned int num_alias_matches = 0; + unsigned int num_user_matches = 0; - std::unique_ptr<CommandObjectRegexCommand> tbreak_regex_cmd_ap(new CommandObjectRegexCommand( - *this, "_regexp-tbreak", "Set a one-shot breakpoint using one of several shorthand formats.\n", - "\n" - "_regexp-break <filename>:<linenum>\n" - " main.c:12 // Break at line 12 of main.c\n\n" - "_regexp-break <linenum>\n" - " 12 // Break at line 12 of current file\n\n" - "_regexp-break 0x<address>\n" - " 0x1234000 // Break at address 0x1234000\n\n" - "_regexp-break <name>\n" - " main // Break in 'main' after the prologue\n\n" - "_regexp-break &<name>\n" - " &main // Break at first instruction in 'main'\n\n" - "_regexp-break <module>`<name>\n" - " libc.so`malloc // Break in 'malloc' from 'libc.so'\n\n" - "_regexp-break /<source-regex>/\n" - " /break here/ // Break on source lines in current file\n" - " // containing text 'break here'.\n", - 2, CommandCompletions::eSymbolCompletion | CommandCompletions::eSourceFileCompletion, false)); - - if (tbreak_regex_cmd_ap.get()) - { - bool success = true; - for (size_t i = 0; i < num_regexes; i++) - { - // If you add a resultant command string longer than 1024 characters be sure to increase the size of this buffer. - char buffer[1024]; - int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o"); - assert (num_printed < 1024); - UNUSED_IF_ASSERT_DISABLED(num_printed); - success = tbreak_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], buffer); - if (!success) - break; - } - success = tbreak_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full"); + // Look through the command dictionaries one by one, and if we get only one + // match from any of + // them in toto, then return that, otherwise return an empty CommandObjectSP + // and the list of matches. - if (success) - { - CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_ap.release()); - m_command_dict[tbreak_regex_cmd_sp->GetCommandName ()] = tbreak_regex_cmd_sp; - } + if (HasCommands()) { + num_cmd_matches = + AddNamesMatchingPartialString(m_command_dict, cmd_str, *matches); } - std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_ap( - new CommandObjectRegexCommand(*this, "_regexp-attach", "Attach to process by ID or name.", - "_regexp-attach <pid> | <process-name>", 2, 0, false)); - if (attach_regex_cmd_ap.get()) - { - if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") && - attach_regex_cmd_ap->AddRegexCommand("^(-.*|.* -.*)$", "process attach %1") && // Any options that are specified get passed to 'process attach' - attach_regex_cmd_ap->AddRegexCommand("^(.+)$", "process attach --name '%1'") && - attach_regex_cmd_ap->AddRegexCommand("^$", "process attach")) - { - CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_ap.release()); - m_command_dict[attach_regex_cmd_sp->GetCommandName ()] = attach_regex_cmd_sp; - } + if (num_cmd_matches == 1) { + cmd.assign(matches->GetStringAtIndex(0)); + auto pos = m_command_dict.find(cmd); + if (pos != m_command_dict.end()) + real_match_sp = pos->second; } - std::unique_ptr<CommandObjectRegexCommand> down_regex_cmd_ap(new CommandObjectRegexCommand( - *this, "_regexp-down", "Select a newer stack frame. Defaults to moving one frame, a numeric argument can " - "specify an arbitrary number.", - "_regexp-down [<count>]", 2, 0, false)); - if (down_regex_cmd_ap.get()) - { - if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") && - down_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r -%1")) - { - CommandObjectSP down_regex_cmd_sp(down_regex_cmd_ap.release()); - m_command_dict[down_regex_cmd_sp->GetCommandName ()] = down_regex_cmd_sp; - } + if (include_aliases && HasAliases()) { + num_alias_matches = + AddNamesMatchingPartialString(m_alias_dict, cmd_str, *matches); } - std::unique_ptr<CommandObjectRegexCommand> up_regex_cmd_ap( - new CommandObjectRegexCommand(*this, "_regexp-up", "Select an older stack frame. Defaults to moving one " - "frame, a numeric argument can specify an arbitrary number.", - "_regexp-up [<count>]", 2, 0, false)); - if (up_regex_cmd_ap.get()) - { - if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") && - up_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r %1")) - { - CommandObjectSP up_regex_cmd_sp(up_regex_cmd_ap.release()); - m_command_dict[up_regex_cmd_sp->GetCommandName ()] = up_regex_cmd_sp; - } + if (num_alias_matches == 1) { + cmd.assign(matches->GetStringAtIndex(num_cmd_matches)); + auto alias_pos = m_alias_dict.find(cmd); + if (alias_pos != m_alias_dict.end()) + alias_match_sp = alias_pos->second; } - std::unique_ptr<CommandObjectRegexCommand> display_regex_cmd_ap(new CommandObjectRegexCommand( - *this, "_regexp-display", "Evaluate an expression at every stop (see 'help target stop-hook'.)", - "_regexp-display expression", 2, 0, false)); - if (display_regex_cmd_ap.get()) - { - if (display_regex_cmd_ap->AddRegexCommand("^(.+)$", "target stop-hook add -o \"expr -- %1\"")) - { - CommandObjectSP display_regex_cmd_sp(display_regex_cmd_ap.release()); - m_command_dict[display_regex_cmd_sp->GetCommandName ()] = display_regex_cmd_sp; - } + if (HasUserCommands()) { + num_user_matches = + AddNamesMatchingPartialString(m_user_dict, cmd_str, *matches); } - std::unique_ptr<CommandObjectRegexCommand> undisplay_regex_cmd_ap(new CommandObjectRegexCommand( - *this, "_regexp-undisplay", "Stop displaying expression at every stop (specified by stop-hook index.)", - "_regexp-undisplay stop-hook-number", 2, 0, false)); - if (undisplay_regex_cmd_ap.get()) - { - if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1")) - { - CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_ap.release()); - m_command_dict[undisplay_regex_cmd_sp->GetCommandName ()] = undisplay_regex_cmd_sp; - } - } + if (num_user_matches == 1) { + cmd.assign( + matches->GetStringAtIndex(num_cmd_matches + num_alias_matches)); - std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand( - *this, "gdb-remote", - "Connect to a process via remote GDB server. If no host is specifed, localhost is assumed.", - "gdb-remote [<hostname>:]<portnum>", 2, 0, false)); - if (connect_gdb_remote_cmd_ap.get()) - { - if (connect_gdb_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin gdb-remote connect://%1") && - connect_gdb_remote_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "process connect --plugin gdb-remote connect://localhost:%1")) - { - CommandObjectSP command_sp(connect_gdb_remote_cmd_ap.release()); - m_command_dict[command_sp->GetCommandName ()] = command_sp; - } + auto pos = m_user_dict.find(cmd); + if (pos != m_user_dict.end()) + user_match_sp = pos->second; } - std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand( - *this, "kdp-remote", - "Connect to a process via remote KDP server. If no UDP port is specified, port 41139 is assumed.", - "kdp-remote <hostname>[:<portnum>]", 2, 0, false)); - if (connect_kdp_remote_cmd_ap.get()) - { - if (connect_kdp_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin kdp-remote udp://%1") && - connect_kdp_remote_cmd_ap->AddRegexCommand("^(.+)$", "process connect --plugin kdp-remote udp://%1:41139")) - { - CommandObjectSP command_sp(connect_kdp_remote_cmd_ap.release()); - m_command_dict[command_sp->GetCommandName ()] = command_sp; - } - } + // If we got exactly one match, return that, otherwise return the match + // list. - std::unique_ptr<CommandObjectRegexCommand> bt_regex_cmd_ap(new CommandObjectRegexCommand( - *this, "_regexp-bt", "Show the current thread's call stack. Any numeric argument displays at most that many " - "frames. The argument 'all' displays all threads.", - "bt [<digit> | all]", 2, 0, false)); - if (bt_regex_cmd_ap.get()) - { - // accept but don't document "bt -c <number>" -- before bt was a regex command if you wanted to backtrace - // three frames you would do "bt -c 3" but the intention is to have this emulate the gdb "bt" command and - // so now "bt 3" is the preferred form, in line with gdb. - if (bt_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "thread backtrace -c %1") && - bt_regex_cmd_ap->AddRegexCommand("^-c ([[:digit:]]+)$", "thread backtrace -c %1") && - bt_regex_cmd_ap->AddRegexCommand("^all$", "thread backtrace all") && - bt_regex_cmd_ap->AddRegexCommand("^$", "thread backtrace")) - { - CommandObjectSP command_sp(bt_regex_cmd_ap.release()); - m_command_dict[command_sp->GetCommandName ()] = command_sp; - } + if (num_user_matches + num_cmd_matches + num_alias_matches == 1) { + if (num_cmd_matches) + return real_match_sp; + else if (num_alias_matches) + return alias_match_sp; + else + return user_match_sp; } + } else if (matches && command_sp) { + matches->AppendString(cmd_str); + } - std::unique_ptr<CommandObjectRegexCommand> list_regex_cmd_ap(new CommandObjectRegexCommand( - *this, "_regexp-list", "List relevant source code using one of several shorthand formats.", - "\n" - "_regexp-list <file>:<line> // List around specific file/line\n" - "_regexp-list <line> // List current file around specified line\n" - "_regexp-list <function-name> // List specified function\n" - "_regexp-list 0x<address> // List around specified address\n" - "_regexp-list -[<count>] // List previous <count> lines\n" - "_regexp-list // List subsequent lines", - 2, CommandCompletions::eSourceFileCompletion, false)); - if (list_regex_cmd_ap.get()) - { - if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") && - list_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "source list --file '%1' --line %2") && - list_regex_cmd_ap->AddRegexCommand("^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "source list --address %1") && - list_regex_cmd_ap->AddRegexCommand("^-[[:space:]]*$", "source list --reverse") && - list_regex_cmd_ap->AddRegexCommand("^-([[:digit:]]+)[[:space:]]*$", "source list --reverse --count %1") && - list_regex_cmd_ap->AddRegexCommand("^(.+)$", "source list --name \"%1\"") && - list_regex_cmd_ap->AddRegexCommand("^$", "source list")) - { - CommandObjectSP list_regex_cmd_sp(list_regex_cmd_ap.release()); - m_command_dict[list_regex_cmd_sp->GetCommandName ()] = list_regex_cmd_sp; - } - } - - std::unique_ptr<CommandObjectRegexCommand> env_regex_cmd_ap( - new CommandObjectRegexCommand(*this, "_regexp-env", "Shorthand for viewing and setting environment variables.", - "\n" - "_regexp-env // Show enrivonment\n" - "_regexp-env <name>=<value> // Set an environment variable", - 2, 0, false)); - if (env_regex_cmd_ap.get()) - { - if (env_regex_cmd_ap->AddRegexCommand("^$", "settings show target.env-vars") && - env_regex_cmd_ap->AddRegexCommand("^([A-Za-z_][A-Za-z_0-9]*=.*)$", "settings set target.env-vars %1")) - { - CommandObjectSP env_regex_cmd_sp(env_regex_cmd_ap.release()); - m_command_dict[env_regex_cmd_sp->GetCommandName ()] = env_regex_cmd_sp; - } - } - - std::unique_ptr<CommandObjectRegexCommand> jump_regex_cmd_ap( - new CommandObjectRegexCommand(*this, "_regexp-jump", "Set the program counter to a new address.", - "\n" - "_regexp-jump <line>\n" - "_regexp-jump +<line-offset> | -<line-offset>\n" - "_regexp-jump <file>:<line>\n" - "_regexp-jump *<addr>\n", - 2, 0, false)); - if (jump_regex_cmd_ap.get()) - { - if (jump_regex_cmd_ap->AddRegexCommand("^\\*(.*)$", "thread jump --addr %1") && - jump_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "thread jump --line %1") && - jump_regex_cmd_ap->AddRegexCommand("^([^:]+):([0-9]+)$", "thread jump --file %1 --line %2") && - jump_regex_cmd_ap->AddRegexCommand("^([+\\-][0-9]+)$", "thread jump --by %1")) - { - CommandObjectSP jump_regex_cmd_sp(jump_regex_cmd_ap.release()); - m_command_dict[jump_regex_cmd_sp->GetCommandName ()] = jump_regex_cmd_sp; - } - } - -} - -int -CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases, - StringList &matches) -{ - AddNamesMatchingPartialString (m_command_dict, cmd_str, matches); - - if (include_aliases) - { - AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches); - } - - return matches.GetSize(); -} - -CommandObjectSP -CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches) -{ - CommandObject::CommandMap::iterator pos; - CommandObjectSP command_sp; - - std::string cmd(cmd_cstr); - - if (HasCommands()) - { - pos = m_command_dict.find(cmd); - if (pos != m_command_dict.end()) - command_sp = pos->second; - } - - if (include_aliases && HasAliases()) - { - auto alias_pos = m_alias_dict.find(cmd); - if (alias_pos != m_alias_dict.end()) - command_sp = alias_pos->second; - } - - if (HasUserCommands()) - { - pos = m_user_dict.find(cmd); - if (pos != m_user_dict.end()) - command_sp = pos->second; - } - - if (!exact && !command_sp) - { - // We will only get into here if we didn't find any exact matches. - - CommandObjectSP user_match_sp, alias_match_sp, real_match_sp; - - StringList local_matches; - if (matches == nullptr) - matches = &local_matches; - - unsigned int num_cmd_matches = 0; - unsigned int num_alias_matches = 0; - unsigned int num_user_matches = 0; - - // Look through the command dictionaries one by one, and if we get only one match from any of - // them in toto, then return that, otherwise return an empty CommandObjectSP and the list of matches. - - if (HasCommands()) - { - num_cmd_matches = AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches); - } - - if (num_cmd_matches == 1) - { - cmd.assign(matches->GetStringAtIndex(0)); - pos = m_command_dict.find(cmd); - if (pos != m_command_dict.end()) - real_match_sp = pos->second; - } - - if (include_aliases && HasAliases()) - { - num_alias_matches = AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches); - - } - - if (num_alias_matches == 1) - { - cmd.assign(matches->GetStringAtIndex (num_cmd_matches)); - auto alias_pos = m_alias_dict.find(cmd); - if (alias_pos != m_alias_dict.end()) - alias_match_sp = alias_pos->second; - } - - if (HasUserCommands()) - { - num_user_matches = AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches); - } - - if (num_user_matches == 1) - { - cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches)); - - pos = m_user_dict.find (cmd); - if (pos != m_user_dict.end()) - user_match_sp = pos->second; - } - - // If we got exactly one match, return that, otherwise return the match list. - - if (num_user_matches + num_cmd_matches + num_alias_matches == 1) - { - if (num_cmd_matches) - return real_match_sp; - else if (num_alias_matches) - return alias_match_sp; - else - return user_match_sp; - } - } - else if (matches && command_sp) - { - matches->AppendString (cmd_cstr); - } - - - return command_sp; -} - -bool -CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &cmd_sp, bool can_replace) -{ - if (cmd_sp.get()) - assert((this == &cmd_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter"); - - if (name && name[0]) - { - std::string name_sstr(name); - bool found = (m_command_dict.find (name_sstr) != m_command_dict.end()); - if (found && !can_replace) - return false; - if (found && m_command_dict[name_sstr]->IsRemovable() == false) - return false; - m_command_dict[name_sstr] = cmd_sp; - return true; - } - return false; + return command_sp; } -bool -CommandInterpreter::AddUserCommand (std::string name, +bool CommandInterpreter::AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, - bool can_replace) -{ - if (cmd_sp.get()) - assert((this == &cmd_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter"); - - if (!name.empty()) - { - const char* name_cstr = name.c_str(); - - // do not allow replacement of internal commands - if (CommandExists(name_cstr)) - { - if (can_replace == false) - return false; - if (m_command_dict[name]->IsRemovable() == false) - return false; - } - - if (UserCommandExists(name_cstr)) - { - if (can_replace == false) - return false; - if (m_user_dict[name]->IsRemovable() == false) - return false; - } - - m_user_dict[name] = cmd_sp; - return true; - } - return false; -} - -CommandObjectSP -CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases) -{ - Args cmd_words (cmd_cstr); // Break up the command string into words, in case it's a multi-word command. - CommandObjectSP ret_val; // Possibly empty return value. - - if (cmd_cstr == nullptr) - return ret_val; - - if (cmd_words.GetArgumentCount() == 1) - return GetCommandSP(cmd_cstr, include_aliases, true, nullptr); - else - { - // We have a multi-word command (seemingly), so we need to do more work. - // First, get the cmd_obj_sp for the first word in the command. - CommandObjectSP cmd_obj_sp = GetCommandSP (cmd_words.GetArgumentAtIndex (0), include_aliases, true, nullptr); - if (cmd_obj_sp.get() != nullptr) - { - // Loop through the rest of the words in the command (everything passed in was supposed to be part of a - // command name), and find the appropriate sub-command SP for each command word.... - size_t end = cmd_words.GetArgumentCount(); - for (size_t j= 1; j < end; ++j) - { - if (cmd_obj_sp->IsMultiwordObject()) - { - cmd_obj_sp = cmd_obj_sp->GetSubcommandSP (cmd_words.GetArgumentAtIndex (j)); - if (cmd_obj_sp.get() == nullptr) - // The sub-command name was invalid. Fail and return the empty 'ret_val'. - return ret_val; - } - else - // We have more words in the command name, but we don't have a multiword object. Fail and return - // empty 'ret_val'. - return ret_val; - } - // We successfully looped through all the command words and got valid command objects for them. Assign the - // last object retrieved to 'ret_val'. - ret_val = cmd_obj_sp; - } - } - return ret_val; -} - -CommandObject * -CommandInterpreter::GetCommandObjectExact (const char *cmd_cstr, bool include_aliases) -{ - return GetCommandSPExact (cmd_cstr, include_aliases).get(); -} - -CommandObject * -CommandInterpreter::GetCommandObject (const char *cmd_cstr, StringList *matches) -{ - CommandObject *command_obj = GetCommandSP (cmd_cstr, false, true, matches).get(); + bool can_replace) { + if (cmd_sp.get()) + assert((this == &cmd_sp->GetCommandInterpreter()) && + "tried to add a CommandObject from a different interpreter"); - // If we didn't find an exact match to the command string in the commands, look in - // the aliases. - - if (command_obj) - return command_obj; - - command_obj = GetCommandSP (cmd_cstr, true, true, matches).get(); - - if (command_obj) - return command_obj; - - // If there wasn't an exact match then look for an inexact one in just the commands - command_obj = GetCommandSP(cmd_cstr, false, false, nullptr).get(); + if (name.empty()) + return false; - // Finally, if there wasn't an inexact match among the commands, look for an inexact - // match in both the commands and aliases. - - if (command_obj) - { - if (matches) - matches->AppendString(command_obj->GetCommandName()); - return command_obj; + std::string name_sstr(name); + auto name_iter = m_command_dict.find(name_sstr); + if (name_iter != m_command_dict.end()) { + if (!can_replace || !name_iter->second->IsRemovable()) + return false; + name_iter->second = cmd_sp; + } else { + m_command_dict[name_sstr] = cmd_sp; + } + return true; +} + +bool CommandInterpreter::AddUserCommand(llvm::StringRef name, + const lldb::CommandObjectSP &cmd_sp, + bool can_replace) { + if (cmd_sp.get()) + assert((this == &cmd_sp->GetCommandInterpreter()) && + "tried to add a CommandObject from a different interpreter"); + + if (!name.empty()) { + // do not allow replacement of internal commands + if (CommandExists(name)) { + if (can_replace == false) + return false; + if (m_command_dict[name]->IsRemovable() == false) + return false; } - - return GetCommandSP(cmd_cstr, true, false, matches).get(); -} - -bool -CommandInterpreter::CommandExists (const char *cmd) -{ - return m_command_dict.find(cmd) != m_command_dict.end(); -} -bool -CommandInterpreter::GetAliasFullName (const char *cmd, std::string &full_name) -{ - bool exact_match = (m_alias_dict.find(cmd) != m_alias_dict.end()); - if (exact_match) - { - full_name.assign(cmd); - return exact_match; - } - else - { - StringList matches; - size_t num_alias_matches; - num_alias_matches = AddNamesMatchingPartialString (m_alias_dict, cmd, matches); - if (num_alias_matches == 1) - { - // Make sure this isn't shadowing a command in the regular command space: - StringList regular_matches; - const bool include_aliases = false; - const bool exact = false; - CommandObjectSP cmd_obj_sp(GetCommandSP (cmd, include_aliases, exact, ®ular_matches)); - if (cmd_obj_sp || regular_matches.GetSize() > 0) - return false; - else - { - full_name.assign (matches.GetStringAtIndex(0)); - return true; - } - } - else - return false; + if (UserCommandExists(name)) { + if (can_replace == false) + return false; + if (m_user_dict[name]->IsRemovable() == false) + return false; } -} -bool -CommandInterpreter::AliasExists (const char *cmd) -{ - return m_alias_dict.find(cmd) != m_alias_dict.end(); + m_user_dict[name] = cmd_sp; + return true; + } + return false; } -bool -CommandInterpreter::UserCommandExists (const char *cmd) -{ - return m_user_dict.find(cmd) != m_user_dict.end(); -} +CommandObjectSP CommandInterpreter::GetCommandSPExact(llvm::StringRef cmd_str, + bool include_aliases) const { + Args cmd_words(cmd_str); // Break up the command string into words, in case + // it's a multi-word command. + CommandObjectSP ret_val; // Possibly empty return value. -CommandAlias* -CommandInterpreter::AddAlias (const char *alias_name, - lldb::CommandObjectSP& command_obj_sp, - const char *args_string) -{ - if (command_obj_sp.get()) - assert((this == &command_obj_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter"); - - std::unique_ptr<CommandAlias> command_alias_up(new CommandAlias(*this, - command_obj_sp, - args_string, - alias_name)); - - if (command_alias_up && command_alias_up->IsValid()) - { - m_alias_dict[alias_name] = CommandObjectSP(command_alias_up.get()); - return command_alias_up.release(); - } - - return nullptr; -} - -bool -CommandInterpreter::RemoveAlias (const char *alias_name) -{ - auto pos = m_alias_dict.find(alias_name); - if (pos != m_alias_dict.end()) - { - m_alias_dict.erase(pos); - return true; - } - return false; -} + if (cmd_str.empty()) + return ret_val; -bool -CommandInterpreter::RemoveCommand (const char *cmd) -{ - auto pos = m_command_dict.find(cmd); - if (pos != m_command_dict.end()) - { - if (pos->second->IsRemovable()) - { - // Only regular expression objects or python commands are removable - m_command_dict.erase(pos); - return true; - } - } - return false; -} -bool -CommandInterpreter::RemoveUser (const char *alias_name) -{ - CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name); - if (pos != m_user_dict.end()) - { - m_user_dict.erase(pos); + if (cmd_words.GetArgumentCount() == 1) + return GetCommandSP(cmd_str, include_aliases, true, nullptr); + else { + // We have a multi-word command (seemingly), so we need to do more work. + // First, get the cmd_obj_sp for the first word in the command. + CommandObjectSP cmd_obj_sp = GetCommandSP(llvm::StringRef(cmd_words.GetArgumentAtIndex(0)), + include_aliases, true, nullptr); + if (cmd_obj_sp.get() != nullptr) { + // Loop through the rest of the words in the command (everything passed in + // was supposed to be part of a + // command name), and find the appropriate sub-command SP for each command + // word.... + size_t end = cmd_words.GetArgumentCount(); + for (size_t j = 1; j < end; ++j) { + if (cmd_obj_sp->IsMultiwordObject()) { + cmd_obj_sp = + cmd_obj_sp->GetSubcommandSP(cmd_words.GetArgumentAtIndex(j)); + if (cmd_obj_sp.get() == nullptr) + // The sub-command name was invalid. Fail and return the empty + // 'ret_val'. + return ret_val; + } else + // We have more words in the command name, but we don't have a + // multiword object. Fail and return empty 'ret_val'. + return ret_val; + } + // We successfully looped through all the command words and got valid + // command objects for them. Assign the last object retrieved to + // 'ret_val'. + ret_val = cmd_obj_sp; + } + } + return ret_val; +} + +CommandObject *CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str, + StringList *matches) const { + CommandObject *command_obj = + GetCommandSP(cmd_str, false, true, matches).get(); + + // If we didn't find an exact match to the command string in the commands, + // look in + // the aliases. + + if (command_obj) + return command_obj; + + command_obj = GetCommandSP(cmd_str, true, true, matches).get(); + + if (command_obj) + return command_obj; + + // If there wasn't an exact match then look for an inexact one in just the + // commands + command_obj = GetCommandSP(cmd_str, false, false, nullptr).get(); + + // Finally, if there wasn't an inexact match among the commands, look for an + // inexact + // match in both the commands and aliases. + + if (command_obj) { + if (matches) + matches->AppendString(command_obj->GetCommandName()); + return command_obj; + } + + return GetCommandSP(cmd_str, true, false, matches).get(); +} + +bool CommandInterpreter::CommandExists(llvm::StringRef cmd) const { + return m_command_dict.find(cmd) != m_command_dict.end(); +} + +bool CommandInterpreter::GetAliasFullName(llvm::StringRef cmd, + std::string &full_name) const { + bool exact_match = (m_alias_dict.find(cmd) != m_alias_dict.end()); + if (exact_match) { + full_name.assign(cmd); + return exact_match; + } else { + StringList matches; + size_t num_alias_matches; + num_alias_matches = + AddNamesMatchingPartialString(m_alias_dict, cmd, matches); + if (num_alias_matches == 1) { + // Make sure this isn't shadowing a command in the regular command space: + StringList regular_matches; + const bool include_aliases = false; + const bool exact = false; + CommandObjectSP cmd_obj_sp( + GetCommandSP(cmd, include_aliases, exact, ®ular_matches)); + if (cmd_obj_sp || regular_matches.GetSize() > 0) + return false; + else { + full_name.assign(matches.GetStringAtIndex(0)); return true; - } - return false; -} - -void -CommandInterpreter::GetHelp (CommandReturnObject &result, - uint32_t cmd_types) -{ - const char * help_prologue = GetDebugger().GetIOHandlerHelpPrologue(); - if (help_prologue != NULL) - { - OutputFormattedHelpText(result.GetOutputStream(), NULL, help_prologue); - } - - CommandObject::CommandMap::const_iterator pos; - size_t max_len = FindLongestCommandWord (m_command_dict); - - if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin ) - { - result.AppendMessage("Debugger commands:"); - result.AppendMessage(""); - - for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) - { - if (!(cmd_types & eCommandTypesHidden) && (pos->first.compare(0, 1, "_") == 0)) - continue; - - OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), - max_len); - } - result.AppendMessage(""); - - } - - if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases )) - { - result.AppendMessageWithFormat("Current command abbreviations " - "(type '%shelp command alias' for more info):\n", - GetCommandPrefix()); - result.AppendMessage(""); - max_len = FindLongestCommandWord (m_alias_dict); - - for (auto alias_pos = m_alias_dict.begin(); alias_pos != m_alias_dict.end(); ++alias_pos) - { - OutputFormattedHelpText (result.GetOutputStream(), alias_pos->first.c_str(), "--", alias_pos->second->GetHelp(), - max_len); - } - result.AppendMessage(""); - } - - if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef )) - { - result.AppendMessage ("Current user-defined commands:"); - result.AppendMessage(""); - max_len = FindLongestCommandWord (m_user_dict); - for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) - { - OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), - max_len); - } - result.AppendMessage(""); - } - - result.AppendMessageWithFormat("For more information on any command, type '%shelp <command-name>'.\n", - GetCommandPrefix()); -} - -CommandObject * -CommandInterpreter::GetCommandObjectForCommand (std::string &command_string) -{ - // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will - // eventually be invoked by the given command line. - - CommandObject *cmd_obj = nullptr; - size_t start = command_string.find_first_not_of (k_white_space); - size_t end = 0; - bool done = false; - while (!done) - { - if (start != std::string::npos) - { - // Get the next word from command_string. - end = command_string.find_first_of (k_white_space, start); - if (end == std::string::npos) - end = command_string.size(); - std::string cmd_word = command_string.substr (start, end - start); - - if (cmd_obj == nullptr) - // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid - // command or alias. - cmd_obj = GetCommandObject (cmd_word.c_str()); - else if (cmd_obj->IsMultiwordObject ()) - { - // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object. - CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str()); - if (sub_cmd_obj) - cmd_obj = sub_cmd_obj; - else // cmd_word was not a valid sub-command word, so we are done - done = true; - } - else - // We have a cmd_obj and it is not a multi-word object, so we are done. - done = true; - - // If we didn't find a valid command object, or our command object is not a multi-word object, or - // we are at the end of the command_string, then we are done. Otherwise, find the start of the - // next word. - - if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size()) - done = true; - else - start = command_string.find_first_not_of (k_white_space, end); - } - else - // Unable to find any more words. - done = true; - } - - if (end == command_string.size()) - command_string.clear(); - else - command_string = command_string.substr(end); - - return cmd_obj; + } + } else + return false; + } } -static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; -static void -StripLeadingSpaces (std::string &s) -{ - if (!s.empty()) - { - size_t pos = s.find_first_not_of (k_white_space); - if (pos == std::string::npos) - s.clear(); - else if (pos == 0) - return; - s.erase (0, pos); - } -} - -static size_t -FindArgumentTerminator (const std::string &s) -{ - const size_t s_len = s.size(); - size_t offset = 0; - while (offset < s_len) - { - size_t pos = s.find ("--", offset); - if (pos == std::string::npos) - break; - if (pos > 0) - { - if (isspace(s[pos-1])) - { - // Check if the string ends "\s--" (where \s is a space character) - // or if we have "\s--\s". - if ((pos + 2 >= s_len) || isspace(s[pos+2])) - { - return pos; - } - } - } - offset = pos + 2; - } - return std::string::npos; -} +bool CommandInterpreter::AliasExists(llvm::StringRef cmd) const { + return m_alias_dict.find(cmd) != m_alias_dict.end(); +} + +bool CommandInterpreter::UserCommandExists(llvm::StringRef cmd) const { + return m_user_dict.find(cmd) != m_user_dict.end(); +} + +CommandAlias * +CommandInterpreter::AddAlias(llvm::StringRef alias_name, + lldb::CommandObjectSP &command_obj_sp, + llvm::StringRef args_string) { + if (command_obj_sp.get()) + assert((this == &command_obj_sp->GetCommandInterpreter()) && + "tried to add a CommandObject from a different interpreter"); -static bool -ExtractCommand (std::string &command_string, std::string &command, std::string &suffix, char "e_char) -{ - command.clear(); - suffix.clear(); - StripLeadingSpaces (command_string); - - bool result = false; - quote_char = '\0'; - - if (!command_string.empty()) - { - const char first_char = command_string[0]; - if (first_char == '\'' || first_char == '"') - { - quote_char = first_char; - const size_t end_quote_pos = command_string.find (quote_char, 1); - if (end_quote_pos == std::string::npos) - { - command.swap (command_string); - command_string.erase (); - } - else - { - command.assign (command_string, 1, end_quote_pos - 1); - if (end_quote_pos + 1 < command_string.size()) - command_string.erase (0, command_string.find_first_not_of (k_white_space, end_quote_pos + 1)); - else - command_string.erase (); - } - } + std::unique_ptr<CommandAlias> command_alias_up( + new CommandAlias(*this, command_obj_sp, args_string, alias_name)); + + if (command_alias_up && command_alias_up->IsValid()) { + m_alias_dict[alias_name] = CommandObjectSP(command_alias_up.get()); + return command_alias_up.release(); + } + + return nullptr; +} + +bool CommandInterpreter::RemoveAlias(llvm::StringRef alias_name) { + auto pos = m_alias_dict.find(alias_name); + if (pos != m_alias_dict.end()) { + m_alias_dict.erase(pos); + return true; + } + return false; +} + +bool CommandInterpreter::RemoveCommand(llvm::StringRef cmd) { + auto pos = m_command_dict.find(cmd); + if (pos != m_command_dict.end()) { + if (pos->second->IsRemovable()) { + // Only regular expression objects or python commands are removable + m_command_dict.erase(pos); + return true; + } + } + return false; +} +bool CommandInterpreter::RemoveUser(llvm::StringRef alias_name) { + CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name); + if (pos != m_user_dict.end()) { + m_user_dict.erase(pos); + return true; + } + return false; +} + +void CommandInterpreter::GetHelp(CommandReturnObject &result, + uint32_t cmd_types) { + llvm::StringRef help_prologue(GetDebugger().GetIOHandlerHelpPrologue()); + if (!help_prologue.empty()) { + OutputFormattedHelpText(result.GetOutputStream(), llvm::StringRef(), + help_prologue); + } + + CommandObject::CommandMap::const_iterator pos; + size_t max_len = FindLongestCommandWord(m_command_dict); + + if ((cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin) { + result.AppendMessage("Debugger commands:"); + result.AppendMessage(""); + + for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) { + if (!(cmd_types & eCommandTypesHidden) && + (pos->first.compare(0, 1, "_") == 0)) + continue; + + OutputFormattedHelpText(result.GetOutputStream(), pos->first, "--", + pos->second->GetHelp(), max_len); + } + result.AppendMessage(""); + } + + if (!m_alias_dict.empty() && + ((cmd_types & eCommandTypesAliases) == eCommandTypesAliases)) { + result.AppendMessageWithFormat( + "Current command abbreviations " + "(type '%shelp command alias' for more info):\n", + GetCommandPrefix()); + result.AppendMessage(""); + max_len = FindLongestCommandWord(m_alias_dict); + + for (auto alias_pos = m_alias_dict.begin(); alias_pos != m_alias_dict.end(); + ++alias_pos) { + OutputFormattedHelpText(result.GetOutputStream(), alias_pos->first, "--", + alias_pos->second->GetHelp(), max_len); + } + result.AppendMessage(""); + } + + if (!m_user_dict.empty() && + ((cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef)) { + result.AppendMessage("Current user-defined commands:"); + result.AppendMessage(""); + max_len = FindLongestCommandWord(m_user_dict); + for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) { + OutputFormattedHelpText(result.GetOutputStream(), pos->first, "--", + pos->second->GetHelp(), max_len); + } + result.AppendMessage(""); + } + + result.AppendMessageWithFormat( + "For more information on any command, type '%shelp <command-name>'.\n", + GetCommandPrefix()); +} + +CommandObject *CommandInterpreter::GetCommandObjectForCommand( + llvm::StringRef &command_string) { + // This function finds the final, lowest-level, alias-resolved command object + // whose 'Execute' function will + // eventually be invoked by the given command line. + + CommandObject *cmd_obj = nullptr; + size_t start = command_string.find_first_not_of(k_white_space); + size_t end = 0; + bool done = false; + while (!done) { + if (start != std::string::npos) { + // Get the next word from command_string. + end = command_string.find_first_of(k_white_space, start); + if (end == std::string::npos) + end = command_string.size(); + std::string cmd_word = command_string.substr(start, end - start); + + if (cmd_obj == nullptr) + // Since cmd_obj is NULL we are on our first time through this loop. + // Check to see if cmd_word is a valid command or alias. + cmd_obj = GetCommandObject(cmd_word); + else if (cmd_obj->IsMultiwordObject()) { + // Our current object is a multi-word object; see if the cmd_word is a + // valid sub-command for our object. + CommandObject *sub_cmd_obj = + cmd_obj->GetSubcommandObject(cmd_word.c_str()); + if (sub_cmd_obj) + cmd_obj = sub_cmd_obj; + else // cmd_word was not a valid sub-command word, so we are done + done = true; + } else + // We have a cmd_obj and it is not a multi-word object, so we are done. + done = true; + + // If we didn't find a valid command object, or our command object is not + // a multi-word object, or we are at the end of the command_string, then + // we are done. Otherwise, find the start of the next word. + + if (!cmd_obj || !cmd_obj->IsMultiwordObject() || + end >= command_string.size()) + done = true; + else + start = command_string.find_first_not_of(k_white_space, end); + } else + // Unable to find any more words. + done = true; + } + + command_string = command_string.substr(end); + return cmd_obj; +} + +static const char *k_valid_command_chars = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; +static void StripLeadingSpaces(std::string &s) { + if (!s.empty()) { + size_t pos = s.find_first_not_of(k_white_space); + if (pos == std::string::npos) + s.clear(); + else if (pos == 0) + return; + s.erase(0, pos); + } +} + +static size_t FindArgumentTerminator(const std::string &s) { + const size_t s_len = s.size(); + size_t offset = 0; + while (offset < s_len) { + size_t pos = s.find("--", offset); + if (pos == std::string::npos) + break; + if (pos > 0) { + if (isspace(s[pos - 1])) { + // Check if the string ends "\s--" (where \s is a space character) + // or if we have "\s--\s". + if ((pos + 2 >= s_len) || isspace(s[pos + 2])) { + return pos; + } + } + } + offset = pos + 2; + } + return std::string::npos; +} + +static bool ExtractCommand(std::string &command_string, std::string &command, + std::string &suffix, char "e_char) { + command.clear(); + suffix.clear(); + StripLeadingSpaces(command_string); + + bool result = false; + quote_char = '\0'; + + if (!command_string.empty()) { + const char first_char = command_string[0]; + if (first_char == '\'' || first_char == '"') { + quote_char = first_char; + const size_t end_quote_pos = command_string.find(quote_char, 1); + if (end_quote_pos == std::string::npos) { + command.swap(command_string); + command_string.erase(); + } else { + command.assign(command_string, 1, end_quote_pos - 1); + if (end_quote_pos + 1 < command_string.size()) + command_string.erase(0, command_string.find_first_not_of( + k_white_space, end_quote_pos + 1)); else - { - const size_t first_space_pos = command_string.find_first_of (k_white_space); - if (first_space_pos == std::string::npos) - { - command.swap (command_string); - command_string.erase(); - } - else - { - command.assign (command_string, 0, first_space_pos); - command_string.erase(0, command_string.find_first_not_of (k_white_space, first_space_pos)); - } - } - result = true; - } - - - if (!command.empty()) - { - // actual commands can't start with '-' or '_' - if (command[0] != '-' && command[0] != '_') - { - size_t pos = command.find_first_not_of(k_valid_command_chars); - if (pos > 0 && pos != std::string::npos) - { - suffix.assign (command.begin() + pos, command.end()); - command.erase (pos); - } - } - } - - return result; -} - -CommandObject * -CommandInterpreter::BuildAliasResult (const char *alias_name, - std::string &raw_input_string, - std::string &alias_result, - CommandReturnObject &result) -{ - CommandObject *alias_cmd_obj = nullptr; - Args cmd_args (raw_input_string); - alias_cmd_obj = GetCommandObject (alias_name); - StreamString result_str; - - if (alias_cmd_obj && alias_cmd_obj->IsAlias()) - { - std::pair<CommandObjectSP, OptionArgVectorSP> desugared = ((CommandAlias*)alias_cmd_obj)->Desugar(); - OptionArgVectorSP option_arg_vector_sp = desugared.second; - alias_cmd_obj = desugared.first.get(); - std::string alias_name_str = alias_name; - if ((cmd_args.GetArgumentCount() == 0) - || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)) - cmd_args.Unshift (alias_name); - - result_str.Printf ("%s", alias_cmd_obj->GetCommandName ()); - - if (option_arg_vector_sp.get()) - { - OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); - - for (size_t i = 0; i < option_arg_vector->size(); ++i) - { - OptionArgPair option_pair = (*option_arg_vector)[i]; - OptionArgValue value_pair = option_pair.second; - int value_type = value_pair.first; - std::string option = option_pair.first; - std::string value = value_pair.second; - if (option.compare ("<argument>") == 0) - result_str.Printf (" %s", value.c_str()); - else - { - result_str.Printf (" %s", option.c_str()); - if (value_type != OptionParser::eNoArgument) - { - if (value_type != OptionParser::eOptionalArgument) - result_str.Printf (" "); - int index = GetOptionArgumentPosition (value.c_str()); - if (index == 0) - result_str.Printf ("%s", value.c_str()); - else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) - { - - result.AppendErrorWithFormat - ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", - index); - result.SetStatus (eReturnStatusFailed); - return nullptr; - } - else - { - size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); - if (strpos != std::string::npos) - raw_input_string = raw_input_string.erase (strpos, - strlen (cmd_args.GetArgumentAtIndex (index))); - result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index)); - } - } - } - } - } - - alias_result = result_str.GetData(); - } + command_string.erase(); + } + } else { + const size_t first_space_pos = + command_string.find_first_of(k_white_space); + if (first_space_pos == std::string::npos) { + command.swap(command_string); + command_string.erase(); + } else { + command.assign(command_string, 0, first_space_pos); + command_string.erase(0, command_string.find_first_not_of( + k_white_space, first_space_pos)); + } + } + result = true; + } + + if (!command.empty()) { + // actual commands can't start with '-' or '_' + if (command[0] != '-' && command[0] != '_') { + size_t pos = command.find_first_not_of(k_valid_command_chars); + if (pos > 0 && pos != std::string::npos) { + suffix.assign(command.begin() + pos, command.end()); + command.erase(pos); + } + } + } + + return result; +} + +CommandObject *CommandInterpreter::BuildAliasResult( + llvm::StringRef alias_name, std::string &raw_input_string, + std::string &alias_result, CommandReturnObject &result) { + CommandObject *alias_cmd_obj = nullptr; + Args cmd_args(raw_input_string); + alias_cmd_obj = GetCommandObject(alias_name); + StreamString result_str; + + if (!alias_cmd_obj || !alias_cmd_obj->IsAlias()) { + alias_result.clear(); return alias_cmd_obj; -} + } + std::pair<CommandObjectSP, OptionArgVectorSP> desugared = + ((CommandAlias *)alias_cmd_obj)->Desugar(); + OptionArgVectorSP option_arg_vector_sp = desugared.second; + alias_cmd_obj = desugared.first.get(); + std::string alias_name_str = alias_name; + if ((cmd_args.GetArgumentCount() == 0) || + (alias_name_str.compare(cmd_args.GetArgumentAtIndex(0)) != 0)) + cmd_args.Unshift(alias_name_str); + + result_str.Printf("%s", alias_cmd_obj->GetCommandName().str().c_str()); + + if (!option_arg_vector_sp.get()) { + alias_result = result_str.GetString(); + return alias_cmd_obj; + } + OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); + + int value_type; + std::string option; + std::string value; + for (const auto &entry : *option_arg_vector) { + std::tie(option, value_type, value) = entry; + if (option == "<argument>") { + result_str.Printf(" %s", value.c_str()); + continue; + } + + result_str.Printf(" %s", option.c_str()); + if (value_type == OptionParser::eNoArgument) + continue; + + if (value_type != OptionParser::eOptionalArgument) + result_str.Printf(" "); + int index = GetOptionArgumentPosition(value.c_str()); + if (index == 0) + result_str.Printf("%s", value.c_str()); + else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) { + + result.AppendErrorWithFormat("Not enough arguments provided; you " + "need at least %d arguments to use " + "this alias.\n", + index); + result.SetStatus(eReturnStatusFailed); + return nullptr; + } else { + size_t strpos = raw_input_string.find(cmd_args.GetArgumentAtIndex(index)); + if (strpos != std::string::npos) + raw_input_string = raw_input_string.erase( + strpos, strlen(cmd_args.GetArgumentAtIndex(index))); + result_str.Printf("%s", cmd_args.GetArgumentAtIndex(index)); + } + } + + alias_result = result_str.GetString(); + return alias_cmd_obj; +} + +Error CommandInterpreter::PreprocessCommand(std::string &command) { + // The command preprocessor needs to do things to the command + // line before any parsing of arguments or anything else is done. + // The only current stuff that gets preprocessed is anything enclosed + // in backtick ('`') characters is evaluated as an expression and + // the result of the expression must be a scalar that can be substituted + // into the command. An example would be: + // (lldb) memory read `$rsp + 20` + Error error; // Error for any expressions that might not evaluate + size_t start_backtick; + size_t pos = 0; + while ((start_backtick = command.find('`', pos)) != std::string::npos) { + if (start_backtick > 0 && command[start_backtick - 1] == '\\') { + // The backtick was preceded by a '\' character, remove the slash + // and don't treat the backtick as the start of an expression + command.erase(start_backtick - 1, 1); + // No need to add one to start_backtick since we just deleted a char + pos = start_backtick; + } else { + const size_t expr_content_start = start_backtick + 1; + const size_t end_backtick = command.find('`', expr_content_start); + if (end_backtick == std::string::npos) + return error; + else if (end_backtick == expr_content_start) { + // Empty expression (two backticks in a row) + command.erase(start_backtick, 2); + } else { + std::string expr_str(command, expr_content_start, + end_backtick - expr_content_start); -Error -CommandInterpreter::PreprocessCommand (std::string &command) -{ - // The command preprocessor needs to do things to the command - // line before any parsing of arguments or anything else is done. - // The only current stuff that gets preprocessed is anything enclosed - // in backtick ('`') characters is evaluated as an expression and - // the result of the expression must be a scalar that can be substituted - // into the command. An example would be: - // (lldb) memory read `$rsp + 20` - Error error; // Error for any expressions that might not evaluate - size_t start_backtick; - size_t pos = 0; - while ((start_backtick = command.find ('`', pos)) != std::string::npos) - { - if (start_backtick > 0 && command[start_backtick-1] == '\\') - { - // The backtick was preceded by a '\' character, remove the slash - // and don't treat the backtick as the start of an expression - command.erase(start_backtick-1, 1); - // No need to add one to start_backtick since we just deleted a char - pos = start_backtick; - } - else - { - const size_t expr_content_start = start_backtick + 1; - const size_t end_backtick = command.find ('`', expr_content_start); - if (end_backtick == std::string::npos) - return error; - else if (end_backtick == expr_content_start) - { - // Empty expression (two backticks in a row) - command.erase (start_backtick, 2); - } - else - { - std::string expr_str (command, expr_content_start, end_backtick - expr_content_start); - - ExecutionContext exe_ctx(GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - // Get a dummy target to allow for calculator mode while processing backticks. - // This also helps break the infinite loop caused when target is null. - if (!target) - target = m_debugger.GetDummyTarget(); - if (target) - { - ValueObjectSP expr_result_valobj_sp; - - EvaluateExpressionOptions options; - options.SetCoerceToId(false); - options.SetUnwindOnError(true); - options.SetIgnoreBreakpoints(true); - options.SetKeepInMemory(false); - options.SetTryAllThreads(true); - options.SetTimeoutUsec(0); - - ExpressionResults expr_result = target->EvaluateExpression (expr_str.c_str(), - exe_ctx.GetFramePtr(), - expr_result_valobj_sp, - options); - - if (expr_result == eExpressionCompleted) - { - Scalar scalar; - if (expr_result_valobj_sp) - expr_result_valobj_sp = expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(expr_result_valobj_sp->GetDynamicValueType(), true); - if (expr_result_valobj_sp->ResolveValue (scalar)) - { - command.erase (start_backtick, end_backtick - start_backtick + 1); - StreamString value_strm; - const bool show_type = false; - scalar.GetValue (&value_strm, show_type); - size_t value_string_size = value_strm.GetSize(); - if (value_string_size) - { - command.insert (start_backtick, value_strm.GetData(), value_string_size); - pos = start_backtick + value_string_size; - continue; - } - else - { - error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); - } - } - else - { - error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str()); - } - } - else - { - if (expr_result_valobj_sp) - error = expr_result_valobj_sp->GetError(); - if (error.Success()) - { - - switch (expr_result) - { - case eExpressionSetupError: - error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str()); - break; - case eExpressionParseError: - error.SetErrorStringWithFormat ("expression parse error for the expression '%s'", expr_str.c_str()); - break; - case eExpressionResultUnavailable: - error.SetErrorStringWithFormat ("expression error fetching result for the expression '%s'", expr_str.c_str()); - break; - case eExpressionCompleted: - break; - case eExpressionDiscarded: - error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str()); - break; - case eExpressionInterrupted: - error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str()); - break; - case eExpressionHitBreakpoint: - error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str()); - break; - case eExpressionTimedOut: - error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str()); - break; - case eExpressionStoppedForDebug: - error.SetErrorStringWithFormat("expression stop at entry point for debugging for the expression '%s'", expr_str.c_str()); - break; - } - } - } - } + ExecutionContext exe_ctx(GetExecutionContext()); + Target *target = exe_ctx.GetTargetPtr(); + // Get a dummy target to allow for calculator mode while processing + // backticks. + // This also helps break the infinite loop caused when target is null. + if (!target) + target = m_debugger.GetDummyTarget(); + if (target) { + ValueObjectSP expr_result_valobj_sp; + + EvaluateExpressionOptions options; + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetKeepInMemory(false); + options.SetTryAllThreads(true); + options.SetTimeout(llvm::None); + + ExpressionResults expr_result = target->EvaluateExpression( + expr_str.c_str(), exe_ctx.GetFramePtr(), expr_result_valobj_sp, + options); + + if (expr_result == eExpressionCompleted) { + Scalar scalar; + if (expr_result_valobj_sp) + expr_result_valobj_sp = + expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable( + expr_result_valobj_sp->GetDynamicValueType(), true); + if (expr_result_valobj_sp->ResolveValue(scalar)) { + command.erase(start_backtick, end_backtick - start_backtick + 1); + StreamString value_strm; + const bool show_type = false; + scalar.GetValue(&value_strm, show_type); + size_t value_string_size = value_strm.GetSize(); + if (value_string_size) { + command.insert(start_backtick, value_strm.GetString()); + pos = start_backtick + value_string_size; + continue; + } else { + error.SetErrorStringWithFormat("expression value didn't result " + "in a scalar value for the " + "expression '%s'", + expr_str.c_str()); + } + } else { + error.SetErrorStringWithFormat("expression value didn't result " + "in a scalar value for the " + "expression '%s'", + expr_str.c_str()); } - if (error.Fail()) + } else { + if (expr_result_valobj_sp) + error = expr_result_valobj_sp->GetError(); + if (error.Success()) { + + switch (expr_result) { + case eExpressionSetupError: + error.SetErrorStringWithFormat( + "expression setup error for the expression '%s'", + expr_str.c_str()); break; - } - } - return error; -} - - -bool -CommandInterpreter::HandleCommand (const char *command_line, - LazyBool lazy_add_to_history, - CommandReturnObject &result, - ExecutionContext *override_context, - bool repeat_on_empty_command, - bool no_context_switching) - -{ - - std::string command_string (command_line); - std::string original_command_string (command_line); - - Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS)); - Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line); - - // Make a scoped cleanup object that will clear the crash description string - // on exit of this function. - lldb_utility::CleanUp <const char *> crash_description_cleanup(nullptr, Host::SetCrashDescription); - - if (log) - log->Printf ("Processing command: %s", command_line); - - Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line); - - if (!no_context_switching) - UpdateExecutionContext (override_context); - - bool add_to_history; - if (lazy_add_to_history == eLazyBoolCalculate) - add_to_history = (m_command_source_depth == 0); - else - add_to_history = (lazy_add_to_history == eLazyBoolYes); - - bool empty_command = false; - bool comment_command = false; - if (command_string.empty()) - empty_command = true; - else - { - const char *k_space_characters = "\t\n\v\f\r "; - - size_t non_space = command_string.find_first_not_of (k_space_characters); - // Check for empty line or comment line (lines whose first - // non-space character is the comment character for this interpreter) - if (non_space == std::string::npos) - empty_command = true; - else if (command_string[non_space] == m_comment_char) - comment_command = true; - else if (command_string[non_space] == CommandHistory::g_repeat_char) - { - const char *history_string = m_command_history.FindString(command_string.c_str() + non_space); - if (history_string == nullptr) - { - result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - add_to_history = false; - command_string = history_string; - original_command_string = history_string; - } - } - - if (empty_command) - { - if (repeat_on_empty_command) - { - if (m_command_history.IsEmpty()) - { - result.AppendError ("empty command"); - result.SetStatus(eReturnStatusFailed); - return false; - } - else - { - command_line = m_repeat_command.c_str(); - command_string = command_line; - original_command_string = command_line; - if (m_repeat_command.empty()) - { - result.AppendErrorWithFormat("No auto repeat.\n"); - result.SetStatus (eReturnStatusFailed); - return false; - } + case eExpressionParseError: + error.SetErrorStringWithFormat( + "expression parse error for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionResultUnavailable: + error.SetErrorStringWithFormat( + "expression error fetching result for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionCompleted: + break; + case eExpressionDiscarded: + error.SetErrorStringWithFormat( + "expression discarded for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionInterrupted: + error.SetErrorStringWithFormat( + "expression interrupted for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionHitBreakpoint: + error.SetErrorStringWithFormat( + "expression hit breakpoint for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionTimedOut: + error.SetErrorStringWithFormat( + "expression timed out for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionStoppedForDebug: + error.SetErrorStringWithFormat("expression stop at entry point " + "for debugging for the " + "expression '%s'", + expr_str.c_str()); + break; + } } - add_to_history = false; - } - else - { - result.SetStatus (eReturnStatusSuccessFinishNoResult); - return true; - } - } - else if (comment_command) - { - result.SetStatus (eReturnStatusSuccessFinishNoResult); - return true; - } - - - Error error (PreprocessCommand (command_string)); - - if (error.Fail()) - { - result.AppendError (error.AsCString()); + } + } + } + if (error.Fail()) + break; + } + } + return error; +} + +bool CommandInterpreter::HandleCommand(const char *command_line, + LazyBool lazy_add_to_history, + CommandReturnObject &result, + ExecutionContext *override_context, + bool repeat_on_empty_command, + bool no_context_switching) + +{ + + std::string command_string(command_line); + std::string original_command_string(command_line); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMANDS)); + llvm::PrettyStackTraceFormat stack_trace("HandleCommand(command = \"%s\")", + command_line); + + if (log) + log->Printf("Processing command: %s", command_line); + + Timer scoped_timer(LLVM_PRETTY_FUNCTION, "Handling command: %s.", + command_line); + + if (!no_context_switching) + UpdateExecutionContext(override_context); + + bool add_to_history; + if (lazy_add_to_history == eLazyBoolCalculate) + add_to_history = (m_command_source_depth == 0); + else + add_to_history = (lazy_add_to_history == eLazyBoolYes); + + bool empty_command = false; + bool comment_command = false; + if (command_string.empty()) + empty_command = true; + else { + const char *k_space_characters = "\t\n\v\f\r "; + + size_t non_space = command_string.find_first_not_of(k_space_characters); + // Check for empty line or comment line (lines whose first + // non-space character is the comment character for this interpreter) + if (non_space == std::string::npos) + empty_command = true; + else if (command_string[non_space] == m_comment_char) + comment_command = true; + else if (command_string[non_space] == CommandHistory::g_repeat_char) { + llvm::StringRef search_str(command_string); + search_str = search_str.drop_front(non_space); + if (auto hist_str = m_command_history.FindString(search_str)) { + add_to_history = false; + command_string = *hist_str; + original_command_string = *hist_str; + } else { + result.AppendErrorWithFormat("Could not find entry: %s in history", + command_string.c_str()); result.SetStatus(eReturnStatusFailed); return false; + } } + } - // Phase 1. - - // Before we do ANY kind of argument processing, we need to figure out what - // the real/final command object is for the specified command. This gets - // complicated by the fact that the user could have specified an alias, and, - // in translating the alias, there may also be command options and/or even - // data (including raw text strings) that need to be found and inserted into - // the command line as part of the translation. So this first step is plain - // look-up and replacement, resulting in: - // 1. the command object whose Execute method will actually be called - // 2. a revised command string, with all substitutions and replacements - // taken care of - // From 1 above, we can determine whether the Execute function wants raw - // input or not. - - CommandObject *cmd_obj = ResolveCommandImpl(command_string, result); - - // Although the user may have abbreviated the command, the command_string now - // has the command expanded to the full name. For example, if the input - // was "br s -n main", command_string is now "breakpoint set -n main". + if (empty_command) { + if (repeat_on_empty_command) { + if (m_command_history.IsEmpty()) { + result.AppendError("empty command"); + result.SetStatus(eReturnStatusFailed); + return false; + } else { + command_line = m_repeat_command.c_str(); + command_string = command_line; + original_command_string = command_line; + if (m_repeat_command.empty()) { + result.AppendErrorWithFormat("No auto repeat.\n"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + add_to_history = false; + } else { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + } else if (comment_command) { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + + Error error(PreprocessCommand(command_string)); + + if (error.Fail()) { + result.AppendError(error.AsCString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + // Phase 1. + + // Before we do ANY kind of argument processing, we need to figure out what + // the real/final command object is for the specified command. This gets + // complicated by the fact that the user could have specified an alias, and, + // in translating the alias, there may also be command options and/or even + // data (including raw text strings) that need to be found and inserted into + // the command line as part of the translation. So this first step is plain + // look-up and replacement, resulting in: + // 1. the command object whose Execute method will actually be called + // 2. a revised command string, with all substitutions and replacements + // taken care of + // From 1 above, we can determine whether the Execute function wants raw + // input or not. + + CommandObject *cmd_obj = ResolveCommandImpl(command_string, result); + + // Although the user may have abbreviated the command, the command_string now + // has the command expanded to the full name. For example, if the input + // was "br s -n main", command_string is now "breakpoint set -n main". + if (log) { + llvm::StringRef command_name = cmd_obj ? cmd_obj->GetCommandName() : "<not found>"; + log->Printf("HandleCommand, cmd_obj : '%s'", command_name.str().c_str()); + log->Printf("HandleCommand, (revised) command_string: '%s'", + command_string.c_str()); + const bool wants_raw_input = + (cmd_obj != NULL) ? cmd_obj->WantsRawCommandString() : false; + log->Printf("HandleCommand, wants_raw_input:'%s'", + wants_raw_input ? "True" : "False"); + } + + // Phase 2. + // Take care of things like setting up the history command & calling the + // appropriate Execute method on the + // CommandObject, with the appropriate arguments. + + if (cmd_obj != nullptr) { + if (add_to_history) { + Args command_args(command_string); + const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); + if (repeat_command != nullptr) + m_repeat_command.assign(repeat_command); + else + m_repeat_command.assign(original_command_string); + + m_command_history.AppendString(original_command_string); + } + + std::string remainder; + const std::size_t actual_cmd_name_len = cmd_obj->GetCommandName().size(); + if (actual_cmd_name_len < command_string.length()) + remainder = command_string.substr(actual_cmd_name_len); + + // Remove any initial spaces + size_t pos = remainder.find_first_not_of(k_white_space); + if (pos != 0 && pos != std::string::npos) + remainder.erase(0, pos); if (log) - { - log->Printf("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>"); - log->Printf("HandleCommand, (revised) command_string: '%s'", command_string.c_str()); - const bool wants_raw_input = (cmd_obj != NULL) ? cmd_obj->WantsRawCommandString() : false; - log->Printf("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False"); - } - - // Phase 2. - // Take care of things like setting up the history command & calling the appropriate Execute method on the - // CommandObject, with the appropriate arguments. - - if (cmd_obj != nullptr) - { - if (add_to_history) - { - Args command_args (command_string); - const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); - if (repeat_command != nullptr) - m_repeat_command.assign(repeat_command); - else - m_repeat_command.assign(original_command_string.c_str()); - - m_command_history.AppendString (original_command_string); - } - - std::string remainder; - const std::size_t actual_cmd_name_len = strlen (cmd_obj->GetCommandName()); - if (actual_cmd_name_len < command_string.length()) - remainder = command_string.substr (actual_cmd_name_len); - - // Remove any initial spaces - size_t pos = remainder.find_first_not_of (k_white_space); - if (pos != 0 && pos != std::string::npos) - remainder.erase(0, pos); - - if (log) - log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str()); - - cmd_obj->Execute (remainder.c_str(), result); - } - else - { - // We didn't find the first command object, so complete the first argument. - Args command_args (command_string); - StringList matches; - int num_matches; - int cursor_index = 0; - int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0)); - bool word_complete; - num_matches = HandleCompletionMatches (command_args, - cursor_index, - cursor_char_position, - 0, - -1, - word_complete, - matches); - - if (num_matches > 0) - { - std::string error_msg; - error_msg.assign ("ambiguous command '"); - error_msg.append(command_args.GetArgumentAtIndex(0)); - error_msg.append ("'."); - - error_msg.append (" Possible completions:"); - for (int i = 0; i < num_matches; i++) - { - error_msg.append ("\n\t"); - error_msg.append (matches.GetStringAtIndex (i)); - } - error_msg.append ("\n"); - result.AppendRawError (error_msg.c_str()); - } - else - result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0)); - - result.SetStatus (eReturnStatusFailed); - } - - if (log) - log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed")); - - return result.Succeeded(); -} - -int -CommandInterpreter::HandleCompletionMatches (Args &parsed_line, - int &cursor_index, - int &cursor_char_position, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - int num_command_matches = 0; - bool look_for_subcommand = false; - - // For any of the command completions a unique match will be a complete word. - word_complete = true; - - if (cursor_index == -1) - { - // We got nothing on the command line, so return the list of commands - bool include_aliases = true; - num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches); - } - else if (cursor_index == 0) - { - // The cursor is in the first argument, so just do a lookup in the dictionary. - CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches); - num_command_matches = matches.GetSize(); - - if (num_command_matches == 1 - && cmd_obj && cmd_obj->IsMultiwordObject() - && matches.GetStringAtIndex(0) != nullptr - && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0) - { - if (parsed_line.GetArgumentCount() == 1) - { - word_complete = true; - } - else - { - look_for_subcommand = true; - num_command_matches = 0; - matches.DeleteStringAtIndex(0); - parsed_line.AppendArgument (""); - cursor_index++; - cursor_char_position = 0; - } - } - } - - if (cursor_index > 0 || look_for_subcommand) - { - // We are completing further on into a commands arguments, so find the command and tell it - // to complete the command. - // First see if there is a matching initial command: - CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0)); - if (command_object == nullptr) - { - return 0; - } - else - { - parsed_line.Shift(); - cursor_index--; - num_command_matches = command_object->HandleCompletion (parsed_line, - cursor_index, - cursor_char_position, - match_start_point, - max_return_elements, - word_complete, - matches); - } - } - - return num_command_matches; - -} - -int -CommandInterpreter::HandleCompletion (const char *current_line, - const char *cursor, - const char *last_char, - int match_start_point, - int max_return_elements, - StringList &matches) -{ - // We parse the argument up to the cursor, so the last argument in parsed_line is - // the one containing the cursor, and the cursor is after the last character. - - Args parsed_line(llvm::StringRef(current_line, last_char - current_line)); - Args partial_parsed_line(llvm::StringRef(current_line, cursor - current_line)); - - // Don't complete comments, and if the line we are completing is just the history repeat character, - // substitute the appropriate history line. - const char *first_arg = parsed_line.GetArgumentAtIndex(0); - if (first_arg) - { - if (first_arg[0] == m_comment_char) - return 0; - else if (first_arg[0] == CommandHistory::g_repeat_char) - { - const char *history_string = m_command_history.FindString (first_arg); - if (history_string != nullptr) - { - matches.Clear(); - matches.InsertStringAtIndex(0, history_string); - return -2; - } - else - return 0; - - } - } - - - int num_args = partial_parsed_line.GetArgumentCount(); - int cursor_index = partial_parsed_line.GetArgumentCount() - 1; - int cursor_char_position; - - if (cursor_index == -1) - cursor_char_position = 0; - else - cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index)); - - if (cursor > current_line && cursor[-1] == ' ') - { - // We are just after a space. If we are in an argument, then we will continue - // parsing, but if we are between arguments, then we have to complete whatever the next - // element would be. - // We can distinguish the two cases because if we are in an argument (e.g. because the space is - // protected by a quote) then the space will also be in the parsed argument... - - const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index); - if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ') - { - parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '\0'); - cursor_index++; - cursor_char_position = 0; - } - } - - int num_command_matches; - - matches.Clear(); - - // Only max_return_elements == -1 is supported at present: - assert (max_return_elements == -1); + log->Printf( + "HandleCommand, command line after removing command name(s): '%s'", + remainder.c_str()); + + cmd_obj->Execute(remainder.c_str(), result); + } else { + // We didn't find the first command object, so complete the first argument. + Args command_args(command_string); + StringList matches; + int num_matches; + int cursor_index = 0; + int cursor_char_position = strlen(command_args.GetArgumentAtIndex(0)); bool word_complete; - num_command_matches = HandleCompletionMatches (parsed_line, - cursor_index, - cursor_char_position, - match_start_point, - max_return_elements, - word_complete, - matches); - - if (num_command_matches <= 0) - return num_command_matches; - - if (num_args == 0) - { - // If we got an empty string, insert nothing. - matches.InsertStringAtIndex(0, ""); - } - else - { - // Now figure out if there is a common substring, and if so put that in element 0, otherwise - // put an empty string in element 0. - std::string command_partial_str; - if (cursor_index >= 0) - command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index), - parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position); - - std::string common_prefix; - matches.LongestCommonPrefix (common_prefix); - const size_t partial_name_len = command_partial_str.size(); - common_prefix.erase (0, partial_name_len); - - // If we matched a unique single command, add a space... - // Only do this if the completer told us this was a complete word, however... - if (num_command_matches == 1 && word_complete) - { - char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index); - common_prefix = Args::EscapeLLDBCommandArgument(common_prefix, quote_char); - if (quote_char != '\0') - common_prefix.push_back(quote_char); - common_prefix.push_back(' '); - } - matches.InsertStringAtIndex(0, common_prefix.c_str()); - } + num_matches = HandleCompletionMatches(command_args, cursor_index, + cursor_char_position, 0, -1, + word_complete, matches); + + if (num_matches > 0) { + std::string error_msg; + error_msg.assign("ambiguous command '"); + error_msg.append(command_args.GetArgumentAtIndex(0)); + error_msg.append("'."); + + error_msg.append(" Possible completions:"); + for (int i = 0; i < num_matches; i++) { + error_msg.append("\n\t"); + error_msg.append(matches.GetStringAtIndex(i)); + } + error_msg.append("\n"); + result.AppendRawError(error_msg.c_str()); + } else + result.AppendErrorWithFormat("Unrecognized command '%s'.\n", + command_args.GetArgumentAtIndex(0)); + + result.SetStatus(eReturnStatusFailed); + } + + if (log) + log->Printf("HandleCommand, command %s", + (result.Succeeded() ? "succeeded" : "did not succeed")); + + return result.Succeeded(); +} + +int CommandInterpreter::HandleCompletionMatches( + Args &parsed_line, int &cursor_index, int &cursor_char_position, + int match_start_point, int max_return_elements, bool &word_complete, + StringList &matches) { + int num_command_matches = 0; + bool look_for_subcommand = false; + + // For any of the command completions a unique match will be a complete word. + word_complete = true; + + if (cursor_index == -1) { + // We got nothing on the command line, so return the list of commands + bool include_aliases = true; + num_command_matches = + GetCommandNamesMatchingPartialString("", include_aliases, matches); + } else if (cursor_index == 0) { + // The cursor is in the first argument, so just do a lookup in the + // dictionary. + CommandObject *cmd_obj = + GetCommandObject(parsed_line.GetArgumentAtIndex(0), &matches); + num_command_matches = matches.GetSize(); + + if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() && + matches.GetStringAtIndex(0) != nullptr && + strcmp(parsed_line.GetArgumentAtIndex(0), + matches.GetStringAtIndex(0)) == 0) { + if (parsed_line.GetArgumentCount() == 1) { + word_complete = true; + } else { + look_for_subcommand = true; + num_command_matches = 0; + matches.DeleteStringAtIndex(0); + parsed_line.AppendArgument(llvm::StringRef()); + cursor_index++; + cursor_char_position = 0; + } + } + } + + if (cursor_index > 0 || look_for_subcommand) { + // We are completing further on into a commands arguments, so find the + // command and tell it + // to complete the command. + // First see if there is a matching initial command: + CommandObject *command_object = + GetCommandObject(parsed_line.GetArgumentAtIndex(0)); + if (command_object == nullptr) { + return 0; + } else { + parsed_line.Shift(); + cursor_index--; + num_command_matches = command_object->HandleCompletion( + parsed_line, cursor_index, cursor_char_position, match_start_point, + max_return_elements, word_complete, matches); + } + } + + return num_command_matches; +} + +int CommandInterpreter::HandleCompletion( + const char *current_line, const char *cursor, const char *last_char, + int match_start_point, int max_return_elements, StringList &matches) { + // We parse the argument up to the cursor, so the last argument in parsed_line + // is + // the one containing the cursor, and the cursor is after the last character. + + Args parsed_line(llvm::StringRef(current_line, last_char - current_line)); + Args partial_parsed_line( + llvm::StringRef(current_line, cursor - current_line)); + + // Don't complete comments, and if the line we are completing is just the + // history repeat character, + // substitute the appropriate history line. + const char *first_arg = parsed_line.GetArgumentAtIndex(0); + if (first_arg) { + if (first_arg[0] == m_comment_char) + return 0; + else if (first_arg[0] == CommandHistory::g_repeat_char) { + if (auto hist_str = m_command_history.FindString(first_arg)) { + matches.Clear(); + matches.InsertStringAtIndex(0, *hist_str); + return -2; + } else + return 0; + } + } + + int num_args = partial_parsed_line.GetArgumentCount(); + int cursor_index = partial_parsed_line.GetArgumentCount() - 1; + int cursor_char_position; + + if (cursor_index == -1) + cursor_char_position = 0; + else + cursor_char_position = + strlen(partial_parsed_line.GetArgumentAtIndex(cursor_index)); + + if (cursor > current_line && cursor[-1] == ' ') { + // We are just after a space. If we are in an argument, then we will + // continue + // parsing, but if we are between arguments, then we have to complete + // whatever the next + // element would be. + // We can distinguish the two cases because if we are in an argument (e.g. + // because the space is + // protected by a quote) then the space will also be in the parsed + // argument... + + const char *current_elem = + partial_parsed_line.GetArgumentAtIndex(cursor_index); + if (cursor_char_position == 0 || + current_elem[cursor_char_position - 1] != ' ') { + parsed_line.InsertArgumentAtIndex(cursor_index + 1, llvm::StringRef(), + '\0'); + cursor_index++; + cursor_char_position = 0; + } + } + + int num_command_matches; + + matches.Clear(); + + // Only max_return_elements == -1 is supported at present: + assert(max_return_elements == -1); + bool word_complete; + num_command_matches = HandleCompletionMatches( + parsed_line, cursor_index, cursor_char_position, match_start_point, + max_return_elements, word_complete, matches); + + if (num_command_matches <= 0) return num_command_matches; -} - - -CommandInterpreter::~CommandInterpreter () -{ -} - -void -CommandInterpreter::UpdatePrompt (const char *new_prompt) -{ - EventSP prompt_change_event_sp (new Event(eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));; - BroadcastEvent (prompt_change_event_sp); - if (m_command_io_handler_sp) - m_command_io_handler_sp->SetPrompt(new_prompt); -} - - -bool -CommandInterpreter::Confirm (const char *message, bool default_answer) -{ - // Check AutoConfirm first: - if (m_debugger.GetAutoConfirm()) - return default_answer; - - IOHandlerConfirm *confirm = new IOHandlerConfirm(m_debugger, - message, - default_answer); - IOHandlerSP io_handler_sp (confirm); - m_debugger.RunIOHandler (io_handler_sp); - return confirm->GetResponse(); -} - -CommandAlias* -CommandInterpreter::GetAlias (const char *alias_name) -{ - OptionArgVectorSP ret_val; - - std::string alias (alias_name); - auto pos = m_alias_dict.find(alias); - if (pos != m_alias_dict.end()) - return (CommandAlias*)pos->second.get(); - - return nullptr; -} + if (num_args == 0) { + // If we got an empty string, insert nothing. + matches.InsertStringAtIndex(0, ""); + } else { + // Now figure out if there is a common substring, and if so put that in + // element 0, otherwise + // put an empty string in element 0. + std::string command_partial_str; + if (cursor_index >= 0) + command_partial_str = + parsed_line[cursor_index].ref.take_front(cursor_char_position); -bool -CommandInterpreter::HasCommands () -{ - return (!m_command_dict.empty()); -} - -bool -CommandInterpreter::HasAliases () -{ - return (!m_alias_dict.empty()); -} + std::string common_prefix; + matches.LongestCommonPrefix(common_prefix); + const size_t partial_name_len = command_partial_str.size(); + common_prefix.erase(0, partial_name_len); + + // If we matched a unique single command, add a space... + // Only do this if the completer told us this was a complete word, + // however... + if (num_command_matches == 1 && word_complete) { + char quote_char = parsed_line[cursor_index].quote; + common_prefix = + Args::EscapeLLDBCommandArgument(common_prefix, quote_char); + if (quote_char != '\0') + common_prefix.push_back(quote_char); + common_prefix.push_back(' '); + } + matches.InsertStringAtIndex(0, common_prefix.c_str()); + } + return num_command_matches; +} + +CommandInterpreter::~CommandInterpreter() {} + +void CommandInterpreter::UpdatePrompt(llvm::StringRef new_prompt) { + EventSP prompt_change_event_sp( + new Event(eBroadcastBitResetPrompt, new EventDataBytes(new_prompt))); + ; + BroadcastEvent(prompt_change_event_sp); + if (m_command_io_handler_sp) + m_command_io_handler_sp->SetPrompt(new_prompt); +} + +bool CommandInterpreter::Confirm(llvm::StringRef message, bool default_answer) { + // Check AutoConfirm first: + if (m_debugger.GetAutoConfirm()) + return default_answer; + + IOHandlerConfirm *confirm = + new IOHandlerConfirm(m_debugger, message, default_answer); + IOHandlerSP io_handler_sp(confirm); + m_debugger.RunIOHandler(io_handler_sp); + return confirm->GetResponse(); +} + +const CommandAlias * +CommandInterpreter::GetAlias(llvm::StringRef alias_name) const { + OptionArgVectorSP ret_val; + + auto pos = m_alias_dict.find(alias_name); + if (pos != m_alias_dict.end()) + return (CommandAlias *)pos->second.get(); + + return nullptr; +} + +bool CommandInterpreter::HasCommands() const { return (!m_command_dict.empty()); } + +bool CommandInterpreter::HasAliases() const { return (!m_alias_dict.empty()); } + +bool CommandInterpreter::HasUserCommands() const { return (!m_user_dict.empty()); } + +bool CommandInterpreter::HasAliasOptions() const { return HasAliases(); } + +void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, + const char *alias_name, + Args &cmd_args, + std::string &raw_input_string, + CommandReturnObject &result) { + OptionArgVectorSP option_arg_vector_sp = + GetAlias(alias_name)->GetOptionArguments(); + + bool wants_raw_input = alias_cmd_obj->WantsRawCommandString(); + + // Make sure that the alias name is the 0th element in cmd_args + std::string alias_name_str = alias_name; + if (alias_name_str.compare(cmd_args.GetArgumentAtIndex(0)) != 0) + cmd_args.Unshift(alias_name_str); + + Args new_args(alias_cmd_obj->GetCommandName()); + if (new_args.GetArgumentCount() == 2) + new_args.Shift(); + + if (option_arg_vector_sp.get()) { + if (wants_raw_input) { + // We have a command that both has command options and takes raw input. + // Make *sure* it has a + // " -- " in the right place in the raw_input_string. + size_t pos = raw_input_string.find(" -- "); + if (pos == std::string::npos) { + // None found; assume it goes at the beginning of the raw input string + raw_input_string.insert(0, " -- "); + } + } + + OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); + const size_t old_size = cmd_args.GetArgumentCount(); + std::vector<bool> used(old_size + 1, false); + + used[0] = true; + + int value_type; + std::string option; + std::string value; + for (const auto &option_entry : *option_arg_vector) { + std::tie(option, value_type, value) = option_entry; + if (option == "<argument>") { + if (!wants_raw_input || (value != "--")) { + // Since we inserted this above, make sure we don't insert it twice + new_args.AppendArgument(value); + } + continue; + } -bool -CommandInterpreter::HasUserCommands () -{ - return (!m_user_dict.empty()); -} + if (value_type != OptionParser::eOptionalArgument) + new_args.AppendArgument(option); -bool -CommandInterpreter::HasAliasOptions () -{ - return HasAliases(); -} + if (value == "<no-argument>") + continue; -void -CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj, - const char *alias_name, - Args &cmd_args, - std::string &raw_input_string, - CommandReturnObject &result) -{ - OptionArgVectorSP option_arg_vector_sp = GetAlias(alias_name)->GetOptionArguments(); - - bool wants_raw_input = alias_cmd_obj->WantsRawCommandString(); - - // Make sure that the alias name is the 0th element in cmd_args - std::string alias_name_str = alias_name; - if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0) - cmd_args.Unshift (alias_name); - - Args new_args (alias_cmd_obj->GetCommandName()); - if (new_args.GetArgumentCount() == 2) - new_args.Shift(); - - if (option_arg_vector_sp.get()) - { - if (wants_raw_input) - { - // We have a command that both has command options and takes raw input. Make *sure* it has a - // " -- " in the right place in the raw_input_string. - size_t pos = raw_input_string.find(" -- "); - if (pos == std::string::npos) - { - // None found; assume it goes at the beginning of the raw input string - raw_input_string.insert (0, " -- "); - } + int index = GetOptionArgumentPosition(value.c_str()); + if (index == 0) { + // value was NOT a positional argument; must be a real value + if (value_type != OptionParser::eOptionalArgument) + new_args.AppendArgument(value); + else { + char buffer[255]; + ::snprintf(buffer, sizeof(buffer), "%s%s", option.c_str(), + value.c_str()); + new_args.AppendArgument(llvm::StringRef(buffer)); } - OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); - const size_t old_size = cmd_args.GetArgumentCount(); - std::vector<bool> used (old_size + 1, false); - - used[0] = true; - - for (size_t i = 0; i < option_arg_vector->size(); ++i) - { - OptionArgPair option_pair = (*option_arg_vector)[i]; - OptionArgValue value_pair = option_pair.second; - int value_type = value_pair.first; - std::string option = option_pair.first; - std::string value = value_pair.second; - if (option.compare ("<argument>") == 0) - { - if (!wants_raw_input - || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice - new_args.AppendArgument (value.c_str()); - } - else - { - if (value_type != OptionParser::eOptionalArgument) - new_args.AppendArgument (option.c_str()); - if (value.compare ("<no-argument>") != 0) - { - int index = GetOptionArgumentPosition (value.c_str()); - if (index == 0) - { - // value was NOT a positional argument; must be a real value - if (value_type != OptionParser::eOptionalArgument) - new_args.AppendArgument (value.c_str()); - else - { - char buffer[255]; - ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str()); - new_args.AppendArgument (buffer); - } - - } - else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) - { - result.AppendErrorWithFormat - ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", + } else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) { + result.AppendErrorWithFormat("Not enough arguments provided; you " + "need at least %d arguments to use " + "this alias.\n", index); - result.SetStatus (eReturnStatusFailed); - return; - } - else - { - // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string - size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); - if (strpos != std::string::npos) - { - raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index))); - } - - if (value_type != OptionParser::eOptionalArgument) - new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index)); - else - { - char buffer[255]; - ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(), - cmd_args.GetArgumentAtIndex (index)); - new_args.AppendArgument (buffer); - } - used[index] = true; - } - } - } - } - - for (size_t j = 0; j < cmd_args.GetArgumentCount(); ++j) - { - if (!used[j] && !wants_raw_input) - new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j)); - } - - cmd_args.Clear(); - cmd_args.SetArguments (new_args.GetArgumentCount(), new_args.GetConstArgumentVector()); - } - else - { - result.SetStatus (eReturnStatusSuccessFinishNoResult); - // This alias was not created with any options; nothing further needs to be done, unless it is a command that - // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw - // input string. - if (wants_raw_input) - { - cmd_args.Clear(); - cmd_args.SetArguments (new_args.GetArgumentCount(), new_args.GetConstArgumentVector()); - } + result.SetStatus(eReturnStatusFailed); return; + } else { + // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string + size_t strpos = + raw_input_string.find(cmd_args.GetArgumentAtIndex(index)); + if (strpos != std::string::npos) { + raw_input_string = raw_input_string.erase( + strpos, strlen(cmd_args.GetArgumentAtIndex(index))); + } + + if (value_type != OptionParser::eOptionalArgument) + new_args.AppendArgument(cmd_args.GetArgumentAtIndex(index)); + else { + char buffer[255]; + ::snprintf(buffer, sizeof(buffer), "%s%s", option.c_str(), + cmd_args.GetArgumentAtIndex(index)); + new_args.AppendArgument(buffer); + } + used[index] = true; + } + } + + for (auto entry : llvm::enumerate(cmd_args.entries())) { + if (!used[entry.Index] && !wants_raw_input) + new_args.AppendArgument(entry.Value.ref); + } + + cmd_args.Clear(); + cmd_args.SetArguments(new_args.GetArgumentCount(), + new_args.GetConstArgumentVector()); + } else { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + // This alias was not created with any options; nothing further needs to be + // done, unless it is a command that + // wants raw input, in which case we need to clear the rest of the data from + // cmd_args, since its in the raw + // input string. + if (wants_raw_input) { + cmd_args.Clear(); + cmd_args.SetArguments(new_args.GetArgumentCount(), + new_args.GetConstArgumentVector()); } - - result.SetStatus (eReturnStatusSuccessFinishNoResult); return; + } + + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return; } +int CommandInterpreter::GetOptionArgumentPosition(const char *in_string) { + int position = 0; // Any string that isn't an argument position, i.e. '%' + // followed by an integer, gets a position + // of zero. -int -CommandInterpreter::GetOptionArgumentPosition (const char *in_string) -{ - int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position - // of zero. + const char *cptr = in_string; - const char *cptr = in_string; + // Does it start with '%' + if (cptr[0] == '%') { + ++cptr; - // Does it start with '%' - if (cptr[0] == '%') - { + // Is the rest of it entirely digits? + if (isdigit(cptr[0])) { + const char *start = cptr; + while (isdigit(cptr[0])) ++cptr; - // Is the rest of it entirely digits? - if (isdigit (cptr[0])) - { - const char *start = cptr; - while (isdigit (cptr[0])) - ++cptr; - - // We've gotten to the end of the digits; are we at the end of the string? - if (cptr[0] == '\0') - position = atoi (start); - } + // We've gotten to the end of the digits; are we at the end of the string? + if (cptr[0] == '\0') + position = atoi(start); } + } - return position; + return position; } -void -CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result) -{ - FileSpec init_file; - if (in_cwd) - { - ExecutionContext exe_ctx(GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) - { - // In the current working directory we don't load any program specific - // .lldbinit files, we only look for a ".lldbinit" file. - if (m_skip_lldbinit_files) - return; - - LoadCWDlldbinitFile should_load = target->TargetProperties::GetLoadCWDlldbinitFile (); - if (should_load == eLoadCWDlldbinitWarn) - { - FileSpec dot_lldb (".lldbinit", true); - llvm::SmallString<64> home_dir_path; - llvm::sys::path::home_directory (home_dir_path); - FileSpec homedir_dot_lldb (home_dir_path.c_str(), false); - homedir_dot_lldb.AppendPathComponent (".lldbinit"); - homedir_dot_lldb.ResolvePath (); - if (dot_lldb.Exists () - && dot_lldb.GetDirectory() != homedir_dot_lldb.GetDirectory()) - { - result.AppendErrorWithFormat ( - "There is a .lldbinit file in the current directory which is not being read.\n" - "To silence this warning without sourcing in the local .lldbinit,\n" - "add the following to the lldbinit file in your home directory:\n" - " settings set target.load-cwd-lldbinit false\n" - "To allow lldb to source .lldbinit files in the current working directory,\n" - "set the value of this variable to true. Only do so if you understand and\n" - "accept the security risk."); - result.SetStatus (eReturnStatusFailed); - return; - } - } - else if (should_load == eLoadCWDlldbinitTrue) - { - init_file.SetFile ("./.lldbinit", true); - } - } - } - else - { - // If we aren't looking in the current working directory we are looking - // in the home directory. We will first see if there is an application - // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a - // "-" and the name of the program. If this file doesn't exist, we fall - // back to just the "~/.lldbinit" file. We also obey any requests to not - // load the init files. +void CommandInterpreter::SourceInitFile(bool in_cwd, + CommandReturnObject &result) { + FileSpec init_file; + if (in_cwd) { + ExecutionContext exe_ctx(GetExecutionContext()); + Target *target = exe_ctx.GetTargetPtr(); + if (target) { + // In the current working directory we don't load any program specific + // .lldbinit files, we only look for a ".lldbinit" file. + if (m_skip_lldbinit_files) + return; + + LoadCWDlldbinitFile should_load = + target->TargetProperties::GetLoadCWDlldbinitFile(); + if (should_load == eLoadCWDlldbinitWarn) { + FileSpec dot_lldb(".lldbinit", true); llvm::SmallString<64> home_dir_path; llvm::sys::path::home_directory(home_dir_path); - FileSpec profilePath(home_dir_path.c_str(), false); - profilePath.AppendPathComponent(".lldbinit"); - std::string init_file_path = profilePath.GetPath(); - - if (m_skip_app_init_files == false) - { - FileSpec program_file_spec(HostInfo::GetProgramFileSpec()); - const char *program_name = program_file_spec.GetFilename().AsCString(); - - if (program_name) - { - char program_init_file_name[PATH_MAX]; - ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path.c_str(), program_name); - init_file.SetFile (program_init_file_name, true); - if (!init_file.Exists()) - init_file.Clear(); - } - } - - if (!init_file && !m_skip_lldbinit_files) - init_file.SetFile (init_file_path.c_str(), false); - } - - // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting - // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details). + FileSpec homedir_dot_lldb(home_dir_path.c_str(), false); + homedir_dot_lldb.AppendPathComponent(".lldbinit"); + homedir_dot_lldb.ResolvePath(); + if (dot_lldb.Exists() && + dot_lldb.GetDirectory() != homedir_dot_lldb.GetDirectory()) { + result.AppendErrorWithFormat( + "There is a .lldbinit file in the current directory which is not " + "being read.\n" + "To silence this warning without sourcing in the local " + ".lldbinit,\n" + "add the following to the lldbinit file in your home directory:\n" + " settings set target.load-cwd-lldbinit false\n" + "To allow lldb to source .lldbinit files in the current working " + "directory,\n" + "set the value of this variable to true. Only do so if you " + "understand and\n" + "accept the security risk."); + result.SetStatus(eReturnStatusFailed); + return; + } + } else if (should_load == eLoadCWDlldbinitTrue) { + init_file.SetFile("./.lldbinit", true); + } + } + } else { + // If we aren't looking in the current working directory we are looking + // in the home directory. We will first see if there is an application + // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a + // "-" and the name of the program. If this file doesn't exist, we fall + // back to just the "~/.lldbinit" file. We also obey any requests to not + // load the init files. + llvm::SmallString<64> home_dir_path; + llvm::sys::path::home_directory(home_dir_path); + FileSpec profilePath(home_dir_path.c_str(), false); + profilePath.AppendPathComponent(".lldbinit"); + std::string init_file_path = profilePath.GetPath(); + + if (m_skip_app_init_files == false) { + FileSpec program_file_spec(HostInfo::GetProgramFileSpec()); + const char *program_name = program_file_spec.GetFilename().AsCString(); + + if (program_name) { + char program_init_file_name[PATH_MAX]; + ::snprintf(program_init_file_name, sizeof(program_init_file_name), + "%s-%s", init_file_path.c_str(), program_name); + init_file.SetFile(program_init_file_name, true); + if (!init_file.Exists()) + init_file.Clear(); + } + } + + if (!init_file && !m_skip_lldbinit_files) + init_file.SetFile(init_file_path, false); + } + + // If the file exists, tell HandleCommand to 'source' it; this will do the + // actual broadcasting + // of the commands back to any appropriate listener (see + // CommandObjectSource::Execute for more details). + + if (init_file.Exists()) { + const bool saved_batch = SetBatchCommandMode(true); + CommandInterpreterRunOptions options; + options.SetSilent(true); + options.SetStopOnError(false); + options.SetStopOnContinue(true); + + HandleCommandsFromFile(init_file, + nullptr, // Execution context + options, result); + SetBatchCommandMode(saved_batch); + } else { + // nothing to be done if the file doesn't exist + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } +} + +const char *CommandInterpreter::GetCommandPrefix() { + const char *prefix = GetDebugger().GetIOHandlerCommandPrefix(); + return prefix == NULL ? "" : prefix; +} + +PlatformSP CommandInterpreter::GetPlatform(bool prefer_target_platform) { + PlatformSP platform_sp; + if (prefer_target_platform) { + ExecutionContext exe_ctx(GetExecutionContext()); + Target *target = exe_ctx.GetTargetPtr(); + if (target) + platform_sp = target->GetPlatform(); + } + + if (!platform_sp) + platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform(); + return platform_sp; +} + +void CommandInterpreter::HandleCommands(const StringList &commands, + ExecutionContext *override_context, + CommandInterpreterRunOptions &options, + CommandReturnObject &result) { + size_t num_lines = commands.GetSize(); + + // If we are going to continue past a "continue" then we need to run the + // commands synchronously. + // Make sure you reset this value anywhere you return from the function. + + bool old_async_execution = m_debugger.GetAsyncExecution(); + + // If we've been given an execution context, set it at the start, but don't + // keep resetting it or we will + // cause series of commands that change the context, then do an operation that + // relies on that context to fail. + + if (override_context != nullptr) + UpdateExecutionContext(override_context); + + if (!options.GetStopOnContinue()) { + m_debugger.SetAsyncExecution(false); + } + + for (size_t idx = 0; idx < num_lines; idx++) { + const char *cmd = commands.GetStringAtIndex(idx); + if (cmd[0] == '\0') + continue; + + if (options.GetEchoCommands()) { + // TODO: Add Stream support. + result.AppendMessageWithFormat("%s %s\n", + m_debugger.GetPrompt().str().c_str(), cmd); + } + + CommandReturnObject tmp_result; + // If override_context is not NULL, pass no_context_switching = true for + // HandleCommand() since we updated our context already. + + // We might call into a regex or alias command, in which case the + // add_to_history will get lost. This + // m_command_source_depth dingus is the way we turn off adding to the + // history in that case, so set it up here. + if (!options.GetAddToHistory()) + m_command_source_depth++; + bool success = + HandleCommand(cmd, options.m_add_to_history, tmp_result, + nullptr, /* override_context */ + true, /* repeat_on_empty_command */ + override_context != nullptr /* no_context_switching */); + if (!options.GetAddToHistory()) + m_command_source_depth--; + + if (options.GetPrintResults()) { + if (tmp_result.Succeeded()) + result.AppendMessage(tmp_result.GetOutputData()); + } + + if (!success || !tmp_result.Succeeded()) { + llvm::StringRef error_msg = tmp_result.GetErrorData(); + if (error_msg.empty()) + error_msg = "<unknown error>.\n"; + if (options.GetStopOnError()) { + result.AppendErrorWithFormat( + "Aborting reading of commands after command #%" PRIu64 + ": '%s' failed with %s", + (uint64_t)idx, cmd, error_msg.str().c_str()); + result.SetStatus(eReturnStatusFailed); + m_debugger.SetAsyncExecution(old_async_execution); + return; + } else if (options.GetPrintResults()) { + result.AppendMessageWithFormat( + "Command #%" PRIu64 " '%s' failed with %s", (uint64_t)idx + 1, cmd, + error_msg.str().c_str()); + } + } + + if (result.GetImmediateOutputStream()) + result.GetImmediateOutputStream()->Flush(); + + if (result.GetImmediateErrorStream()) + result.GetImmediateErrorStream()->Flush(); + + // N.B. Can't depend on DidChangeProcessState, because the state coming into + // the command execution + // could be running (for instance in Breakpoint Commands. + // So we check the return value to see if it is has running in it. + if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult) || + (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult)) { + if (options.GetStopOnContinue()) { + // If we caused the target to proceed, and we're going to stop in that + // case, set the + // status in our real result before returning. This is an error if the + // continue was not the + // last command in the set of commands to be run. + if (idx != num_lines - 1) + result.AppendErrorWithFormat( + "Aborting reading of commands after command #%" PRIu64 + ": '%s' continued the target.\n", + (uint64_t)idx + 1, cmd); + else + result.AppendMessageWithFormat("Command #%" PRIu64 + " '%s' continued the target.\n", + (uint64_t)idx + 1, cmd); - if (init_file.Exists()) - { - const bool saved_batch = SetBatchCommandMode (true); - CommandInterpreterRunOptions options; - options.SetSilent (true); - options.SetStopOnError (false); - options.SetStopOnContinue (true); + result.SetStatus(tmp_result.GetStatus()); + m_debugger.SetAsyncExecution(old_async_execution); - HandleCommandsFromFile (init_file, - nullptr, // Execution context - options, - result); - SetBatchCommandMode (saved_batch); - } - else - { - // nothing to be done if the file doesn't exist - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } -} + return; + } + } + + // Also check for "stop on crash here: + bool should_stop = false; + if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash()) { + TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget()); + if (target_sp) { + ProcessSP process_sp(target_sp->GetProcessSP()); + if (process_sp) { + for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) { + StopReason reason = thread_sp->GetStopReason(); + if (reason == eStopReasonSignal || reason == eStopReasonException || + reason == eStopReasonInstrumentation) { + should_stop = true; + break; + } + } + } + } + if (should_stop) { + if (idx != num_lines - 1) + result.AppendErrorWithFormat( + "Aborting reading of commands after command #%" PRIu64 + ": '%s' stopped with a signal or exception.\n", + (uint64_t)idx + 1, cmd); + else + result.AppendMessageWithFormat( + "Command #%" PRIu64 " '%s' stopped with a signal or exception.\n", + (uint64_t)idx + 1, cmd); -const char * -CommandInterpreter::GetCommandPrefix() -{ - const char * prefix = GetDebugger().GetIOHandlerCommandPrefix(); - return prefix == NULL ? "" : prefix; -} + result.SetStatus(tmp_result.GetStatus()); + m_debugger.SetAsyncExecution(old_async_execution); -PlatformSP -CommandInterpreter::GetPlatform (bool prefer_target_platform) -{ - PlatformSP platform_sp; - if (prefer_target_platform) - { - ExecutionContext exe_ctx(GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) - platform_sp = target->GetPlatform(); + return; + } } + } - if (!platform_sp) - platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform(); - return platform_sp; -} - -void -CommandInterpreter::HandleCommands (const StringList &commands, - ExecutionContext *override_context, - CommandInterpreterRunOptions &options, - CommandReturnObject &result) -{ - size_t num_lines = commands.GetSize(); - - // If we are going to continue past a "continue" then we need to run the commands synchronously. - // Make sure you reset this value anywhere you return from the function. - - bool old_async_execution = m_debugger.GetAsyncExecution(); - - // If we've been given an execution context, set it at the start, but don't keep resetting it or we will - // cause series of commands that change the context, then do an operation that relies on that context to fail. - - if (override_context != nullptr) - UpdateExecutionContext (override_context); - - if (!options.GetStopOnContinue()) - { - m_debugger.SetAsyncExecution (false); - } - - for (size_t idx = 0; idx < num_lines; idx++) - { - const char *cmd = commands.GetStringAtIndex(idx); - if (cmd[0] == '\0') - continue; - - if (options.GetEchoCommands()) - { - result.AppendMessageWithFormat ("%s %s\n", - m_debugger.GetPrompt(), - cmd); - } + result.SetStatus(eReturnStatusSuccessFinishResult); + m_debugger.SetAsyncExecution(old_async_execution); - CommandReturnObject tmp_result; - // If override_context is not NULL, pass no_context_switching = true for - // HandleCommand() since we updated our context already. - - // We might call into a regex or alias command, in which case the add_to_history will get lost. This - // m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here. - if (!options.GetAddToHistory()) - m_command_source_depth++; - bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result, - nullptr, /* override_context */ - true, /* repeat_on_empty_command */ - override_context != nullptr /* no_context_switching */); - if (!options.GetAddToHistory()) - m_command_source_depth--; - - if (options.GetPrintResults()) - { - if (tmp_result.Succeeded()) - result.AppendMessageWithFormat("%s", tmp_result.GetOutputData()); - } - - if (!success || !tmp_result.Succeeded()) - { - const char *error_msg = tmp_result.GetErrorData(); - if (error_msg == nullptr || error_msg[0] == '\0') - error_msg = "<unknown error>.\n"; - if (options.GetStopOnError()) - { - result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s", - (uint64_t)idx, cmd, error_msg); - result.SetStatus (eReturnStatusFailed); - m_debugger.SetAsyncExecution (old_async_execution); - return; - } - else if (options.GetPrintResults()) - { - result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s", - (uint64_t)idx + 1, - cmd, - error_msg); - } - } - - if (result.GetImmediateOutputStream()) - result.GetImmediateOutputStream()->Flush(); - - if (result.GetImmediateErrorStream()) - result.GetImmediateErrorStream()->Flush(); - - // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution - // could be running (for instance in Breakpoint Commands. - // So we check the return value to see if it is has running in it. - if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult) - || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult)) - { - if (options.GetStopOnContinue()) - { - // If we caused the target to proceed, and we're going to stop in that case, set the - // status in our real result before returning. This is an error if the continue was not the - // last command in the set of commands to be run. - if (idx != num_lines - 1) - result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' continued the target.\n", - (uint64_t)idx + 1, cmd); - else - result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' continued the target.\n", (uint64_t)idx + 1, cmd); - - result.SetStatus(tmp_result.GetStatus()); - m_debugger.SetAsyncExecution (old_async_execution); - - return; - } - } - - // Also check for "stop on crash here: - bool should_stop = false; - if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash()) - { - TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); - if (target_sp) - { - ProcessSP process_sp (target_sp->GetProcessSP()); - if (process_sp) - { - for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) - { - StopReason reason = thread_sp->GetStopReason(); - if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation) - { - should_stop = true; - break; - } - } - } - } - if (should_stop) - { - if (idx != num_lines - 1) - result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' stopped with a signal or exception.\n", - (uint64_t)idx + 1, cmd); - else - result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' stopped with a signal or exception.\n", (uint64_t)idx + 1, cmd); - - result.SetStatus(tmp_result.GetStatus()); - m_debugger.SetAsyncExecution (old_async_execution); - - return; - } - } - - } - - result.SetStatus (eReturnStatusSuccessFinishResult); - m_debugger.SetAsyncExecution (old_async_execution); - - return; + return; } -// Make flags that we can pass into the IOHandler so our delegates can do the right thing +// Make flags that we can pass into the IOHandler so our delegates can do the +// right thing enum { - eHandleCommandFlagStopOnContinue = (1u << 0), - eHandleCommandFlagStopOnError = (1u << 1), - eHandleCommandFlagEchoCommand = (1u << 2), - eHandleCommandFlagPrintResult = (1u << 3), - eHandleCommandFlagStopOnCrash = (1u << 4) + eHandleCommandFlagStopOnContinue = (1u << 0), + eHandleCommandFlagStopOnError = (1u << 1), + eHandleCommandFlagEchoCommand = (1u << 2), + eHandleCommandFlagPrintResult = (1u << 3), + eHandleCommandFlagStopOnCrash = (1u << 4) }; -void -CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file, - ExecutionContext *context, - CommandInterpreterRunOptions &options, - CommandReturnObject &result) -{ - if (cmd_file.Exists()) - { - StreamFileSP input_file_sp (new StreamFile()); - - std::string cmd_file_path = cmd_file.GetPath(); - Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), File::eOpenOptionRead); - - if (error.Success()) - { - Debugger &debugger = GetDebugger(); - - uint32_t flags = 0; - - if (options.m_stop_on_continue == eLazyBoolCalculate) - { - if (m_command_source_flags.empty()) - { - // Stop on continue by default - flags |= eHandleCommandFlagStopOnContinue; - } - else if (m_command_source_flags.back() & eHandleCommandFlagStopOnContinue) - { - flags |= eHandleCommandFlagStopOnContinue; - } - } - else if (options.m_stop_on_continue == eLazyBoolYes) - { - flags |= eHandleCommandFlagStopOnContinue; - } - - if (options.m_stop_on_error == eLazyBoolCalculate) - { - if (m_command_source_flags.empty()) - { - if (GetStopCmdSourceOnError()) - flags |= eHandleCommandFlagStopOnError; - } - else if (m_command_source_flags.back() & eHandleCommandFlagStopOnError) - { - flags |= eHandleCommandFlagStopOnError; - } - } - else if (options.m_stop_on_error == eLazyBoolYes) - { - flags |= eHandleCommandFlagStopOnError; - } - - if (options.GetStopOnCrash()) - { - if (m_command_source_flags.empty()) - { - // Echo command by default - flags |= eHandleCommandFlagStopOnCrash; - } - else if (m_command_source_flags.back() & eHandleCommandFlagStopOnCrash) - { - flags |= eHandleCommandFlagStopOnCrash; - } - } - - if (options.m_echo_commands == eLazyBoolCalculate) - { - if (m_command_source_flags.empty()) - { - // Echo command by default - flags |= eHandleCommandFlagEchoCommand; - } - else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand) - { - flags |= eHandleCommandFlagEchoCommand; - } - } - else if (options.m_echo_commands == eLazyBoolYes) - { - flags |= eHandleCommandFlagEchoCommand; - } - - if (options.m_print_results == eLazyBoolCalculate) - { - if (m_command_source_flags.empty()) - { - // Print output by default - flags |= eHandleCommandFlagPrintResult; - } - else if (m_command_source_flags.back() & eHandleCommandFlagPrintResult) - { - flags |= eHandleCommandFlagPrintResult; - } - } - else if (options.m_print_results == eLazyBoolYes) - { - flags |= eHandleCommandFlagPrintResult; - } - - if (flags & eHandleCommandFlagPrintResult) - { - debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", cmd_file_path.c_str()); - } - - // Used for inheriting the right settings when "command source" might have - // nested "command source" commands - lldb::StreamFileSP empty_stream_sp; - m_command_source_flags.push_back(flags); - IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, - IOHandler::Type::CommandInterpreter, - input_file_sp, - empty_stream_sp, // Pass in an empty stream so we inherit the top input reader output stream - empty_stream_sp, // Pass in an empty stream so we inherit the top input reader error stream - flags, - nullptr, // Pass in NULL for "editline_name" so no history is saved, or written - debugger.GetPrompt(), - NULL, - false, // Not multi-line - debugger.GetUseColor(), - 0, - *this)); - const bool old_async_execution = debugger.GetAsyncExecution(); - - // Set synchronous execution if we are not stopping on continue - if ((flags & eHandleCommandFlagStopOnContinue) == 0) - debugger.SetAsyncExecution (false); - - m_command_source_depth++; - - debugger.RunIOHandler(io_handler_sp); - if (!m_command_source_flags.empty()) - m_command_source_flags.pop_back(); - m_command_source_depth--; - result.SetStatus (eReturnStatusSuccessFinishNoResult); - debugger.SetAsyncExecution (old_async_execution); - } - else - { - result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString()); - result.SetStatus (eReturnStatusFailed); - } - - - } - else - { - result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n", - cmd_file.GetFilename().AsCString("<Unknown>")); - result.SetStatus (eReturnStatusFailed); - return; - } +void CommandInterpreter::HandleCommandsFromFile( + FileSpec &cmd_file, ExecutionContext *context, + CommandInterpreterRunOptions &options, CommandReturnObject &result) { + if (cmd_file.Exists()) { + StreamFileSP input_file_sp(new StreamFile()); + + std::string cmd_file_path = cmd_file.GetPath(); + Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), + File::eOpenOptionRead); + + if (error.Success()) { + Debugger &debugger = GetDebugger(); + + uint32_t flags = 0; + + if (options.m_stop_on_continue == eLazyBoolCalculate) { + if (m_command_source_flags.empty()) { + // Stop on continue by default + flags |= eHandleCommandFlagStopOnContinue; + } else if (m_command_source_flags.back() & + eHandleCommandFlagStopOnContinue) { + flags |= eHandleCommandFlagStopOnContinue; + } + } else if (options.m_stop_on_continue == eLazyBoolYes) { + flags |= eHandleCommandFlagStopOnContinue; + } + + if (options.m_stop_on_error == eLazyBoolCalculate) { + if (m_command_source_flags.empty()) { + if (GetStopCmdSourceOnError()) + flags |= eHandleCommandFlagStopOnError; + } else if (m_command_source_flags.back() & + eHandleCommandFlagStopOnError) { + flags |= eHandleCommandFlagStopOnError; + } + } else if (options.m_stop_on_error == eLazyBoolYes) { + flags |= eHandleCommandFlagStopOnError; + } + + if (options.GetStopOnCrash()) { + if (m_command_source_flags.empty()) { + // Echo command by default + flags |= eHandleCommandFlagStopOnCrash; + } else if (m_command_source_flags.back() & + eHandleCommandFlagStopOnCrash) { + flags |= eHandleCommandFlagStopOnCrash; + } + } + + if (options.m_echo_commands == eLazyBoolCalculate) { + if (m_command_source_flags.empty()) { + // Echo command by default + flags |= eHandleCommandFlagEchoCommand; + } else if (m_command_source_flags.back() & + eHandleCommandFlagEchoCommand) { + flags |= eHandleCommandFlagEchoCommand; + } + } else if (options.m_echo_commands == eLazyBoolYes) { + flags |= eHandleCommandFlagEchoCommand; + } + + if (options.m_print_results == eLazyBoolCalculate) { + if (m_command_source_flags.empty()) { + // Print output by default + flags |= eHandleCommandFlagPrintResult; + } else if (m_command_source_flags.back() & + eHandleCommandFlagPrintResult) { + flags |= eHandleCommandFlagPrintResult; + } + } else if (options.m_print_results == eLazyBoolYes) { + flags |= eHandleCommandFlagPrintResult; + } + + if (flags & eHandleCommandFlagPrintResult) { + debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", + cmd_file_path.c_str()); + } + + // Used for inheriting the right settings when "command source" might have + // nested "command source" commands + lldb::StreamFileSP empty_stream_sp; + m_command_source_flags.push_back(flags); + IOHandlerSP io_handler_sp(new IOHandlerEditline( + debugger, IOHandler::Type::CommandInterpreter, input_file_sp, + empty_stream_sp, // Pass in an empty stream so we inherit the top + // input reader output stream + empty_stream_sp, // Pass in an empty stream so we inherit the top + // input reader error stream + flags, + nullptr, // Pass in NULL for "editline_name" so no history is saved, + // or written + debugger.GetPrompt(), llvm::StringRef(), + false, // Not multi-line + debugger.GetUseColor(), 0, *this)); + const bool old_async_execution = debugger.GetAsyncExecution(); + + // Set synchronous execution if we are not stopping on continue + if ((flags & eHandleCommandFlagStopOnContinue) == 0) + debugger.SetAsyncExecution(false); + + m_command_source_depth++; + + debugger.RunIOHandler(io_handler_sp); + if (!m_command_source_flags.empty()) + m_command_source_flags.pop_back(); + m_command_source_depth--; + result.SetStatus(eReturnStatusSuccessFinishNoResult); + debugger.SetAsyncExecution(old_async_execution); + } else { + result.AppendErrorWithFormat( + "error: an error occurred read file '%s': %s\n", + cmd_file_path.c_str(), error.AsCString()); + result.SetStatus(eReturnStatusFailed); + } + + } else { + result.AppendErrorWithFormat( + "Error reading commands from file %s - file not found.\n", + cmd_file.GetFilename().AsCString("<Unknown>")); + result.SetStatus(eReturnStatusFailed); + return; + } } -ScriptInterpreter * -CommandInterpreter::GetScriptInterpreter(bool can_create) -{ - if (m_script_interpreter_sp) - return m_script_interpreter_sp.get(); - +ScriptInterpreter *CommandInterpreter::GetScriptInterpreter(bool can_create) { + std::lock_guard<std::mutex> locker(m_script_interpreter_mutex); + if (!m_script_interpreter_sp) { if (!can_create) - return nullptr; - + return nullptr; lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage(); - m_script_interpreter_sp = PluginManager::GetScriptInterpreterForLanguage(script_lang, *this); - return m_script_interpreter_sp.get(); + m_script_interpreter_sp = + PluginManager::GetScriptInterpreterForLanguage(script_lang, *this); + } + return m_script_interpreter_sp.get(); } -bool -CommandInterpreter::GetSynchronous () -{ - return m_synchronous_execution; -} +bool CommandInterpreter::GetSynchronous() { return m_synchronous_execution; } -void -CommandInterpreter::SetSynchronous (bool value) -{ - m_synchronous_execution = value; +void CommandInterpreter::SetSynchronous(bool value) { + m_synchronous_execution = value; } -void -CommandInterpreter::OutputFormattedHelpText (Stream &strm, - const char *prefix, - const char *help_text) -{ - const uint32_t max_columns = m_debugger.GetTerminalWidth(); - if (prefix == NULL) - prefix = ""; - - size_t prefix_width = strlen(prefix); - size_t line_width_max = max_columns - prefix_width; - const char *help_text_end = help_text + strlen(help_text); - const char *line_start = help_text; - if (line_width_max < 16) - line_width_max = help_text_end - help_text + prefix_width; - - strm.IndentMore (prefix_width); - while (line_start < help_text_end) - { - // Break each line at the first newline or last space/tab before - // the maximum number of characters that fit on a line. Lines with no - // natural break are left unbroken to wrap. - const char *line_end = help_text_end; - const char *line_scan = line_start; - const char *line_scan_end = help_text_end; - while (line_scan < line_scan_end) - { - char next = *line_scan; - if (next == '\t' || next == ' ') - { - line_end = line_scan; - line_scan_end = line_start + line_width_max; - } - else if (next == '\n' || next == '\0') - { - line_end = line_scan; - break; - } - ++line_scan; - } - - // Prefix the first line, indent subsequent lines to line up - if (line_start == help_text) - strm.Write (prefix, prefix_width); - else - strm.Indent(); - strm.Write (line_start, line_end - line_start); - strm.EOL(); - - // When a line breaks at whitespace consume it before continuing - line_start = line_end; - char next = *line_start; - if (next == '\n') - ++line_start; - else while (next == ' ' || next == '\t') - next = *(++line_start); - } - strm.IndentLess (prefix_width); -} - -void -CommandInterpreter::OutputFormattedHelpText (Stream &strm, - const char *word_text, - const char *separator, - const char *help_text, - size_t max_word_len) -{ - StreamString prefix_stream; - prefix_stream.Printf (" %-*s %s ", (int)max_word_len, word_text, separator); - OutputFormattedHelpText (strm, prefix_stream.GetData(), help_text); -} +void CommandInterpreter::OutputFormattedHelpText(Stream &strm, + llvm::StringRef prefix, + llvm::StringRef help_text) { + const uint32_t max_columns = m_debugger.GetTerminalWidth(); -void -CommandInterpreter::OutputHelpText (Stream &strm, - const char *word_text, - const char *separator, - const char *help_text, - uint32_t max_word_len) -{ - int indent_size = max_word_len + strlen (separator) + 2; - - strm.IndentMore (indent_size); - - StreamString text_strm; - text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text); - - const uint32_t max_columns = m_debugger.GetTerminalWidth(); - - size_t len = text_strm.GetSize(); - const char *text = text_strm.GetData(); - - uint32_t chars_left = max_columns; - - for (uint32_t i = 0; i < len; i++) - { - if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n') - { - chars_left = max_columns - indent_size; - strm.EOL(); - strm.Indent(); - } - else - { - strm.PutChar(text[i]); - chars_left--; - } - - } - - strm.EOL(); - strm.IndentLess(indent_size); -} + size_t line_width_max = max_columns - prefix.size(); + if (line_width_max < 16) + line_width_max = help_text.size() + prefix.size(); -void -CommandInterpreter::FindCommandsForApropos (const char *search_word, - StringList &commands_found, - StringList &commands_help, - CommandObject::CommandMap &command_map) -{ - CommandObject::CommandMap::const_iterator pos; - - for (pos = command_map.begin(); pos != command_map.end(); ++pos) - { - const char *command_name = pos->first.c_str(); - CommandObject *cmd_obj = pos->second.get(); - - const bool search_short_help = true; - const bool search_long_help = false; - const bool search_syntax = false; - const bool search_options = false; - if (strcasestr(command_name, search_word) || - cmd_obj->HelpTextContainsWord (search_word, - search_short_help, - search_long_help, - search_syntax, - search_options)) - { - commands_found.AppendString (cmd_obj->GetCommandName()); - commands_help.AppendString (cmd_obj->GetHelp()); - } - - if (cmd_obj->IsMultiwordObject()) - { - CommandObjectMultiword *cmd_multiword = cmd_obj->GetAsMultiwordCommand(); - FindCommandsForApropos(search_word, - commands_found, - commands_help, - cmd_multiword->GetSubcommandDictionary()); - } - } -} + strm.IndentMore(prefix.size()); + bool prefixed_yet = false; + while (!help_text.empty()) { + // Prefix the first line, indent subsequent lines to line up + if (!prefixed_yet) { + strm << prefix; + prefixed_yet = true; + } else + strm.Indent(); + // Never print more than the maximum on one line. + llvm::StringRef this_line = help_text.substr(0, line_width_max); -void -CommandInterpreter::FindCommandsForApropos (const char *search_word, - StringList &commands_found, - StringList &commands_help, - bool search_builtin_commands, - bool search_user_commands, - bool search_alias_commands) -{ - CommandObject::CommandMap::const_iterator pos; + // Always break on an explicit newline. + std::size_t first_newline = this_line.find_first_of("\n"); - if (search_builtin_commands) - FindCommandsForApropos(search_word, commands_found, commands_help, m_command_dict); - - if (search_user_commands) - FindCommandsForApropos(search_word, commands_found, commands_help, m_user_dict); + // Don't break on space/tab unless the text is too long to fit on one line. + std::size_t last_space = llvm::StringRef::npos; + if (this_line.size() != help_text.size()) + last_space = this_line.find_last_of(" \t"); - if (search_alias_commands) - FindCommandsForApropos(search_word, commands_found, commands_help, m_alias_dict); -} + // Break at whichever condition triggered first. + this_line = this_line.substr(0, std::min(first_newline, last_space)); + strm.PutCString(this_line); + strm.EOL(); -void -CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context) -{ - if (override_context != nullptr) - { - m_exe_ctx_ref = *override_context; - } - else - { - const bool adopt_selected = true; - m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected); - } + // Remove whitespace / newlines after breaking. + help_text = help_text.drop_front(this_line.size()).ltrim(); + } + strm.IndentLess(prefix.size()); } - -size_t -CommandInterpreter::GetProcessOutput () -{ - // The process has stuff waiting for stderr; get it and write it out to the appropriate place. - char stdio_buffer[1024]; - size_t len; - size_t total_bytes = 0; - Error error; - TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); - if (target_sp) - { - ProcessSP process_sp (target_sp->GetProcessSP()); - if (process_sp) - { - while ((len = process_sp->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0) - { - size_t bytes_written = len; - m_debugger.GetOutputFile()->Write (stdio_buffer, bytes_written); - total_bytes += len; - } - while ((len = process_sp->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0) - { - size_t bytes_written = len; - m_debugger.GetErrorFile()->Write (stdio_buffer, bytes_written); - total_bytes += len; - } - } - } - return total_bytes; +void CommandInterpreter::OutputFormattedHelpText(Stream &strm, + llvm::StringRef word_text, + llvm::StringRef separator, + llvm::StringRef help_text, + size_t max_word_len) { + StreamString prefix_stream; + prefix_stream.Printf(" %-*s %*s ", (int)max_word_len, word_text.data(), + (int)separator.size(), separator.data()); + OutputFormattedHelpText(strm, prefix_stream.GetString(), help_text); } -void -CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line) -{ - const bool is_interactive = io_handler.GetIsInteractive(); - if (is_interactive == false) - { - // When we are not interactive, don't execute blank lines. This will happen - // sourcing a commands file. We don't want blank lines to repeat the previous - // command and cause any errors to occur (like redefining an alias, get an error - // and stop parsing the commands file). - if (line.empty()) - return; - - // When using a non-interactive file handle (like when sourcing commands from a file) - // we need to echo the command out so we don't just see the command output and no - // command... - if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand)) - io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str()); - } - - lldb_private::CommandReturnObject result; - HandleCommand(line.c_str(), eLazyBoolCalculate, result); - - // Now emit the command output text from the command we just executed - if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult)) - { - // Display any STDOUT/STDERR _prior_ to emitting the command result text - GetProcessOutput (); - - if (!result.GetImmediateOutputStream()) - { - const char *output = result.GetOutputData(); - if (output && output[0]) - io_handler.GetOutputStreamFile()->PutCString(output); - } - - // Now emit the command error text from the command we just executed - if (!result.GetImmediateErrorStream()) - { - const char *error = result.GetErrorData(); - if (error && error[0]) - io_handler.GetErrorStreamFile()->PutCString(error); - } - } - - switch (result.GetStatus()) - { - case eReturnStatusInvalid: - case eReturnStatusSuccessFinishNoResult: - case eReturnStatusSuccessFinishResult: - case eReturnStatusStarted: - break; - - case eReturnStatusSuccessContinuingNoResult: - case eReturnStatusSuccessContinuingResult: - if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue)) - io_handler.SetIsDone(true); - break; +LLVM_ATTRIBUTE_ALWAYS_INLINE +static size_t nextWordLength(llvm::StringRef S) { + size_t pos = S.find_first_of(' '); + if (pos == llvm::StringRef::npos) + return S.size(); + return pos; +} - case eReturnStatusFailed: - m_num_errors++; - if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError)) - io_handler.SetIsDone(true); - break; - - case eReturnStatusQuit: - m_quit_requested = true; - io_handler.SetIsDone(true); +void CommandInterpreter::OutputHelpText(Stream &strm, llvm::StringRef word_text, + llvm::StringRef separator, + llvm::StringRef help_text, + uint32_t max_word_len) { + int indent_size = max_word_len + separator.size() + 2; + + strm.IndentMore(indent_size); + + StreamString text_strm; + text_strm.Printf("%-*s ", (int)max_word_len, word_text.data()); + text_strm << separator << " " << help_text; + + const uint32_t max_columns = m_debugger.GetTerminalWidth(); + + llvm::StringRef text = text_strm.GetString(); + + uint32_t chars_left = max_columns; + + while (!text.empty()) { + if (text.front() == '\n' || + (text.front() == ' ' && nextWordLength(text.ltrim(' ')) < chars_left)) { + strm.EOL(); + strm.Indent(); + chars_left = max_columns - indent_size; + if (text.front() == '\n') + text = text.drop_front(); + else + text = text.ltrim(' '); + } else { + strm.PutChar(text.front()); + --chars_left; + text = text.drop_front(); + } + } + + strm.EOL(); + strm.IndentLess(indent_size); +} + +void CommandInterpreter::FindCommandsForApropos( + llvm::StringRef search_word, StringList &commands_found, + StringList &commands_help, CommandObject::CommandMap &command_map) { + CommandObject::CommandMap::const_iterator pos; + + for (pos = command_map.begin(); pos != command_map.end(); ++pos) { + llvm::StringRef command_name = pos->first; + CommandObject *cmd_obj = pos->second.get(); + + const bool search_short_help = true; + const bool search_long_help = false; + const bool search_syntax = false; + const bool search_options = false; + if (command_name.contains_lower(search_word) || + cmd_obj->HelpTextContainsWord(search_word, search_short_help, + search_long_help, search_syntax, + search_options)) { + commands_found.AppendString(cmd_obj->GetCommandName()); + commands_help.AppendString(cmd_obj->GetHelp()); + } + + if (cmd_obj->IsMultiwordObject()) { + CommandObjectMultiword *cmd_multiword = cmd_obj->GetAsMultiwordCommand(); + FindCommandsForApropos(search_word, commands_found, commands_help, + cmd_multiword->GetSubcommandDictionary()); + } + } +} + +void CommandInterpreter::FindCommandsForApropos(llvm::StringRef search_word, + StringList &commands_found, + StringList &commands_help, + bool search_builtin_commands, + bool search_user_commands, + bool search_alias_commands) { + CommandObject::CommandMap::const_iterator pos; + + if (search_builtin_commands) + FindCommandsForApropos(search_word, commands_found, commands_help, + m_command_dict); + + if (search_user_commands) + FindCommandsForApropos(search_word, commands_found, commands_help, + m_user_dict); + + if (search_alias_commands) + FindCommandsForApropos(search_word, commands_found, commands_help, + m_alias_dict); +} + +void CommandInterpreter::UpdateExecutionContext( + ExecutionContext *override_context) { + if (override_context != nullptr) { + m_exe_ctx_ref = *override_context; + } else { + const bool adopt_selected = true; + m_exe_ctx_ref.SetTargetPtr(m_debugger.GetSelectedTarget().get(), + adopt_selected); + } +} + +size_t CommandInterpreter::GetProcessOutput() { + // The process has stuff waiting for stderr; get it and write it out to the + // appropriate place. + char stdio_buffer[1024]; + size_t len; + size_t total_bytes = 0; + Error error; + TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget()); + if (target_sp) { + ProcessSP process_sp(target_sp->GetProcessSP()); + if (process_sp) { + while ((len = process_sp->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer), + error)) > 0) { + size_t bytes_written = len; + m_debugger.GetOutputFile()->Write(stdio_buffer, bytes_written); + total_bytes += len; + } + while ((len = process_sp->GetSTDERR(stdio_buffer, sizeof(stdio_buffer), + error)) > 0) { + size_t bytes_written = len; + m_debugger.GetErrorFile()->Write(stdio_buffer, bytes_written); + total_bytes += len; + } + } + } + return total_bytes; +} + +void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, + std::string &line) { + const bool is_interactive = io_handler.GetIsInteractive(); + if (is_interactive == false) { + // When we are not interactive, don't execute blank lines. This will happen + // sourcing a commands file. We don't want blank lines to repeat the + // previous + // command and cause any errors to occur (like redefining an alias, get an + // error + // and stop parsing the commands file). + if (line.empty()) + return; + + // When using a non-interactive file handle (like when sourcing commands + // from a file) + // we need to echo the command out so we don't just see the command output + // and no + // command... + if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand)) + io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), + line.c_str()); + } + + lldb_private::CommandReturnObject result; + HandleCommand(line.c_str(), eLazyBoolCalculate, result); + + // Now emit the command output text from the command we just executed + if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult)) { + // Display any STDOUT/STDERR _prior_ to emitting the command result text + GetProcessOutput(); + + if (!result.GetImmediateOutputStream()) { + llvm::StringRef output = result.GetOutputData(); + if (!output.empty()) + io_handler.GetOutputStreamFile()->PutCString(output); + } + + // Now emit the command error text from the command we just executed + if (!result.GetImmediateErrorStream()) { + llvm::StringRef error = result.GetErrorData(); + if (!error.empty()) + io_handler.GetErrorStreamFile()->PutCString(error); + } + } + + switch (result.GetStatus()) { + case eReturnStatusInvalid: + case eReturnStatusSuccessFinishNoResult: + case eReturnStatusSuccessFinishResult: + case eReturnStatusStarted: + break; + + case eReturnStatusSuccessContinuingNoResult: + case eReturnStatusSuccessContinuingResult: + if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue)) + io_handler.SetIsDone(true); + break; + + case eReturnStatusFailed: + m_num_errors++; + if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError)) + io_handler.SetIsDone(true); + break; + + case eReturnStatusQuit: + m_quit_requested = true; + io_handler.SetIsDone(true); + break; + } + + // Finally, if we're going to stop on crash, check that here: + if (!m_quit_requested && result.GetDidChangeProcessState() && + io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash)) { + bool should_stop = false; + TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget()); + if (target_sp) { + ProcessSP process_sp(target_sp->GetProcessSP()); + if (process_sp) { + for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) { + StopReason reason = thread_sp->GetStopReason(); + if ((reason == eStopReasonSignal || reason == eStopReasonException || + reason == eStopReasonInstrumentation) && + !result.GetAbnormalStopWasExpected()) { + should_stop = true; break; - } - - // Finally, if we're going to stop on crash, check that here: - if (!m_quit_requested - && result.GetDidChangeProcessState() - && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash)) - { - bool should_stop = false; - TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget()); - if (target_sp) - { - ProcessSP process_sp (target_sp->GetProcessSP()); - if (process_sp) - { - for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) - { - StopReason reason = thread_sp->GetStopReason(); - if ((reason == eStopReasonSignal - || reason == eStopReasonException - || reason == eStopReasonInstrumentation) - && !result.GetAbnormalStopWasExpected()) - { - should_stop = true; - break; - } - } - } - } - if (should_stop) - { - io_handler.SetIsDone(true); - m_stopped_for_crash = true; - } - } -} - -bool -CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler) -{ - ExecutionContext exe_ctx (GetExecutionContext()); - Process *process = exe_ctx.GetProcessPtr(); - - if (process) - { - StateType state = process->GetState(); - if (StateIsRunningState(state)) - { - process->Halt(); - return true; // Don't do any updating when we are running - } - } - - ScriptInterpreter *script_interpreter = GetScriptInterpreter (false); - if (script_interpreter) - { - if (script_interpreter->Interrupt()) - return true; - } - return false; -} - -void -CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt, - IOHandlerDelegate &delegate, - bool asynchronously, - void *baton) -{ - Debugger &debugger = GetDebugger(); - IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, - IOHandler::Type::CommandList, - "lldb", // Name of input reader for history - prompt, // Prompt - NULL, // Continuation prompt - true, // Get multiple lines - debugger.GetUseColor(), - 0, // Don't show line numbers - delegate)); // IOHandlerDelegate - - if (io_handler_sp) - { - io_handler_sp->SetUserData (baton); - if (asynchronously) - debugger.PushIOHandler(io_handler_sp); - else - debugger.RunIOHandler(io_handler_sp); - } - -} - - -void -CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt, - IOHandlerDelegate &delegate, - bool asynchronously, - void *baton) -{ - Debugger &debugger = GetDebugger(); - IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, - IOHandler::Type::PythonCode, - "lldb-python", // Name of input reader for history - prompt, // Prompt - NULL, // Continuation prompt - true, // Get multiple lines - debugger.GetUseColor(), - 0, // Don't show line numbers - delegate)); // IOHandlerDelegate - - if (io_handler_sp) - { - io_handler_sp->SetUserData (baton); - if (asynchronously) - debugger.PushIOHandler(io_handler_sp); - else - debugger.RunIOHandler(io_handler_sp); - } - + } + } + } + } + if (should_stop) { + io_handler.SetIsDone(true); + m_stopped_for_crash = true; + } + } +} + +bool CommandInterpreter::IOHandlerInterrupt(IOHandler &io_handler) { + ExecutionContext exe_ctx(GetExecutionContext()); + Process *process = exe_ctx.GetProcessPtr(); + + if (process) { + StateType state = process->GetState(); + if (StateIsRunningState(state)) { + process->Halt(); + return true; // Don't do any updating when we are running + } + } + + ScriptInterpreter *script_interpreter = GetScriptInterpreter(false); + if (script_interpreter) { + if (script_interpreter->Interrupt()) + return true; + } + return false; +} + +void CommandInterpreter::GetLLDBCommandsFromIOHandler( + const char *prompt, IOHandlerDelegate &delegate, bool asynchronously, + void *baton) { + Debugger &debugger = GetDebugger(); + IOHandlerSP io_handler_sp( + new IOHandlerEditline(debugger, IOHandler::Type::CommandList, + "lldb", // Name of input reader for history + llvm::StringRef::withNullAsEmpty(prompt), // Prompt + llvm::StringRef(), // Continuation prompt + true, // Get multiple lines + debugger.GetUseColor(), + 0, // Don't show line numbers + delegate)); // IOHandlerDelegate + + if (io_handler_sp) { + io_handler_sp->SetUserData(baton); + if (asynchronously) + debugger.PushIOHandler(io_handler_sp); + else + debugger.RunIOHandler(io_handler_sp); + } +} + +void CommandInterpreter::GetPythonCommandsFromIOHandler( + const char *prompt, IOHandlerDelegate &delegate, bool asynchronously, + void *baton) { + Debugger &debugger = GetDebugger(); + IOHandlerSP io_handler_sp( + new IOHandlerEditline(debugger, IOHandler::Type::PythonCode, + "lldb-python", // Name of input reader for history + llvm::StringRef::withNullAsEmpty(prompt), // Prompt + llvm::StringRef(), // Continuation prompt + true, // Get multiple lines + debugger.GetUseColor(), + 0, // Don't show line numbers + delegate)); // IOHandlerDelegate + + if (io_handler_sp) { + io_handler_sp->SetUserData(baton); + if (asynchronously) + debugger.PushIOHandler(io_handler_sp); + else + debugger.RunIOHandler(io_handler_sp); + } } -bool -CommandInterpreter::IsActive () -{ - return m_debugger.IsTopIOHandler (m_command_io_handler_sp); +bool CommandInterpreter::IsActive() { + return m_debugger.IsTopIOHandler(m_command_io_handler_sp); } lldb::IOHandlerSP -CommandInterpreter::GetIOHandler(bool force_create, CommandInterpreterRunOptions *options) -{ +CommandInterpreter::GetIOHandler(bool force_create, + CommandInterpreterRunOptions *options) { + // Always re-create the IOHandlerEditline in case the input + // changed. The old instance might have had a non-interactive + // input and now it does or vice versa. + if (force_create || !m_command_io_handler_sp) { // Always re-create the IOHandlerEditline in case the input // changed. The old instance might have had a non-interactive // input and now it does or vice versa. - if (force_create || !m_command_io_handler_sp) - { - // Always re-create the IOHandlerEditline in case the input - // changed. The old instance might have had a non-interactive - // input and now it does or vice versa. - uint32_t flags = 0; - - if (options) - { - if (options->m_stop_on_continue == eLazyBoolYes) - flags |= eHandleCommandFlagStopOnContinue; - if (options->m_stop_on_error == eLazyBoolYes) - flags |= eHandleCommandFlagStopOnError; - if (options->m_stop_on_crash == eLazyBoolYes) - flags |= eHandleCommandFlagStopOnCrash; - if (options->m_echo_commands != eLazyBoolNo) - flags |= eHandleCommandFlagEchoCommand; - if (options->m_print_results != eLazyBoolNo) - flags |= eHandleCommandFlagPrintResult; - } - else - { - flags = eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult; - } - - m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger, - IOHandler::Type::CommandInterpreter, - m_debugger.GetInputFile(), - m_debugger.GetOutputFile(), - m_debugger.GetErrorFile(), - flags, - "lldb", - m_debugger.GetPrompt(), - NULL, // Continuation prompt - false, // Don't enable multiple line input, just single line commands - m_debugger.GetUseColor(), - 0, // Don't show line numbers - *this)); - } - return m_command_io_handler_sp; -} - -void -CommandInterpreter::RunCommandInterpreter(bool auto_handle_events, - bool spawn_thread, - CommandInterpreterRunOptions &options) -{ - // Always re-create the command interpreter when we run it in case - // any file handles have changed. - bool force_create = true; - m_debugger.PushIOHandler(GetIOHandler(force_create, &options)); - m_stopped_for_crash = false; - + uint32_t flags = 0; + + if (options) { + if (options->m_stop_on_continue == eLazyBoolYes) + flags |= eHandleCommandFlagStopOnContinue; + if (options->m_stop_on_error == eLazyBoolYes) + flags |= eHandleCommandFlagStopOnError; + if (options->m_stop_on_crash == eLazyBoolYes) + flags |= eHandleCommandFlagStopOnCrash; + if (options->m_echo_commands != eLazyBoolNo) + flags |= eHandleCommandFlagEchoCommand; + if (options->m_print_results != eLazyBoolNo) + flags |= eHandleCommandFlagPrintResult; + } else { + flags = eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult; + } + + m_command_io_handler_sp.reset(new IOHandlerEditline( + m_debugger, IOHandler::Type::CommandInterpreter, + m_debugger.GetInputFile(), m_debugger.GetOutputFile(), + m_debugger.GetErrorFile(), flags, "lldb", m_debugger.GetPrompt(), + llvm::StringRef(), // Continuation prompt + false, // Don't enable multiple line input, just single line commands + m_debugger.GetUseColor(), + 0, // Don't show line numbers + *this)); + } + return m_command_io_handler_sp; +} + +void CommandInterpreter::RunCommandInterpreter( + bool auto_handle_events, bool spawn_thread, + CommandInterpreterRunOptions &options) { + // Always re-create the command interpreter when we run it in case + // any file handles have changed. + bool force_create = true; + m_debugger.PushIOHandler(GetIOHandler(force_create, &options)); + m_stopped_for_crash = false; + + if (auto_handle_events) + m_debugger.StartEventHandlerThread(); + + if (spawn_thread) { + m_debugger.StartIOHandlerThread(); + } else { + m_debugger.ExecuteIOHandlers(); + if (auto_handle_events) - m_debugger.StartEventHandlerThread(); - - if (spawn_thread) - { - m_debugger.StartIOHandlerThread(); - } - else - { - m_debugger.ExecuteIOHandlers(); - - if (auto_handle_events) - m_debugger.StopEventHandlerThread(); - } - + m_debugger.StopEventHandlerThread(); + } } CommandObject * -CommandInterpreter::ResolveCommandImpl(std::string &command_line, CommandReturnObject &result) -{ - std::string scratch_command(command_line); // working copy so we don't modify command_line unless we succeed - CommandObject *cmd_obj = nullptr; - StreamString revised_command_line; - bool wants_raw_input = false; - size_t actual_cmd_name_len = 0; - std::string next_word; - StringList matches; - bool done = false; - while (!done) - { - char quote_char = '\0'; - std::string suffix; - ExtractCommand(scratch_command, next_word, suffix, quote_char); - if (cmd_obj == nullptr) - { - std::string full_name; - bool is_alias = GetAliasFullName(next_word.c_str(), full_name); - cmd_obj = GetCommandObject(next_word.c_str(), &matches); - bool is_real_command = (is_alias == false) || (cmd_obj != nullptr && cmd_obj->IsAlias() == false); - if (!is_real_command) - { - matches.Clear(); - std::string alias_result; - cmd_obj = BuildAliasResult(full_name.c_str(), scratch_command, alias_result, result); - revised_command_line.Printf("%s", alias_result.c_str()); - if (cmd_obj) - { - wants_raw_input = cmd_obj->WantsRawCommandString(); - actual_cmd_name_len = strlen(cmd_obj->GetCommandName()); - } - } - else - { - if (!cmd_obj) - cmd_obj = GetCommandObject(next_word.c_str(), &matches); - if (cmd_obj) - { - actual_cmd_name_len += strlen(cmd_obj->GetCommandName()); - revised_command_line.Printf("%s", cmd_obj->GetCommandName()); - wants_raw_input = cmd_obj->WantsRawCommandString(); - } - else - { - revised_command_line.Printf ("%s", next_word.c_str()); - } - } - } +CommandInterpreter::ResolveCommandImpl(std::string &command_line, + CommandReturnObject &result) { + std::string scratch_command(command_line); // working copy so we don't modify + // command_line unless we succeed + CommandObject *cmd_obj = nullptr; + StreamString revised_command_line; + bool wants_raw_input = false; + size_t actual_cmd_name_len = 0; + std::string next_word; + StringList matches; + bool done = false; + while (!done) { + char quote_char = '\0'; + std::string suffix; + ExtractCommand(scratch_command, next_word, suffix, quote_char); + if (cmd_obj == nullptr) { + std::string full_name; + bool is_alias = GetAliasFullName(next_word, full_name); + cmd_obj = GetCommandObject(next_word, &matches); + bool is_real_command = + (is_alias == false) || + (cmd_obj != nullptr && cmd_obj->IsAlias() == false); + if (!is_real_command) { + matches.Clear(); + std::string alias_result; + cmd_obj = + BuildAliasResult(full_name, scratch_command, alias_result, result); + revised_command_line.Printf("%s", alias_result.c_str()); + if (cmd_obj) { + wants_raw_input = cmd_obj->WantsRawCommandString(); + actual_cmd_name_len = cmd_obj->GetCommandName().size(); + } + } else { + if (!cmd_obj) + cmd_obj = GetCommandObject(next_word, &matches); + if (cmd_obj) { + llvm::StringRef cmd_name = cmd_obj->GetCommandName(); + actual_cmd_name_len += cmd_name.size(); + revised_command_line.Printf("%s", cmd_name.str().c_str()); + wants_raw_input = cmd_obj->WantsRawCommandString(); + } else { + revised_command_line.Printf("%s", next_word.c_str()); + } + } + } else { + if (cmd_obj->IsMultiwordObject()) { + CommandObject *sub_cmd_obj = + cmd_obj->GetSubcommandObject(next_word.c_str()); + if (sub_cmd_obj) { + // The subcommand's name includes the parent command's name, + // so restart rather than append to the revised_command_line. + llvm::StringRef sub_cmd_name = sub_cmd_obj->GetCommandName(); + actual_cmd_name_len = sub_cmd_name.size() + 1; + revised_command_line.Clear(); + revised_command_line.Printf("%s", sub_cmd_name.str().c_str()); + cmd_obj = sub_cmd_obj; + wants_raw_input = cmd_obj->WantsRawCommandString(); + } else { + if (quote_char) + revised_command_line.Printf(" %c%s%s%c", quote_char, + next_word.c_str(), suffix.c_str(), + quote_char); + else + revised_command_line.Printf(" %s%s", next_word.c_str(), + suffix.c_str()); + done = true; + } + } else { + if (quote_char) + revised_command_line.Printf(" %c%s%s%c", quote_char, + next_word.c_str(), suffix.c_str(), + quote_char); else - { - if (cmd_obj->IsMultiwordObject ()) - { - CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject(next_word.c_str()); - if (sub_cmd_obj) - { - // The subcommand's name includes the parent command's name, - // so restart rather than append to the revised_command_line. - actual_cmd_name_len = strlen(sub_cmd_obj->GetCommandName()) + 1; - revised_command_line.Clear(); - revised_command_line.Printf("%s", sub_cmd_obj->GetCommandName()); - cmd_obj = sub_cmd_obj; - wants_raw_input = cmd_obj->WantsRawCommandString(); - } - else - { - if (quote_char) - revised_command_line.Printf(" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char); - else - revised_command_line.Printf(" %s%s", next_word.c_str(), suffix.c_str()); - done = true; - } - } - else - { - if (quote_char) - revised_command_line.Printf(" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char); - else - revised_command_line.Printf(" %s%s", next_word.c_str(), suffix.c_str()); - done = true; - } - } - - if (cmd_obj == nullptr) - { - const size_t num_matches = matches.GetSize(); - if (matches.GetSize() > 1) { - StreamString error_msg; - error_msg.Printf("Ambiguous command '%s'. Possible matches:\n", next_word.c_str()); - - for (uint32_t i = 0; i < num_matches; ++i) { - error_msg.Printf("\t%s\n", matches.GetStringAtIndex(i)); - } - result.AppendRawError(error_msg.GetString().c_str()); + revised_command_line.Printf(" %s%s", next_word.c_str(), + suffix.c_str()); + done = true; + } + } + + if (cmd_obj == nullptr) { + const size_t num_matches = matches.GetSize(); + if (matches.GetSize() > 1) { + StreamString error_msg; + error_msg.Printf("Ambiguous command '%s'. Possible matches:\n", + next_word.c_str()); + + for (uint32_t i = 0; i < num_matches; ++i) { + error_msg.Printf("\t%s\n", matches.GetStringAtIndex(i)); + } + result.AppendRawError(error_msg.GetString()); + } else { + // We didn't have only one match, otherwise we wouldn't get here. + assert(num_matches == 0); + result.AppendErrorWithFormat("'%s' is not a valid command.\n", + next_word.c_str()); + } + result.SetStatus(eReturnStatusFailed); + return nullptr; + } + + if (cmd_obj->IsMultiwordObject()) { + if (!suffix.empty()) { + result.AppendErrorWithFormat( + "command '%s' did not recognize '%s%s%s' as valid (subcommand " + "might be invalid).\n", + cmd_obj->GetCommandName().str().c_str(), + next_word.empty() ? "" : next_word.c_str(), + next_word.empty() ? " -- " : " ", suffix.c_str()); + result.SetStatus(eReturnStatusFailed); + return nullptr; + } + } else { + // If we found a normal command, we are done + done = true; + if (!suffix.empty()) { + switch (suffix[0]) { + case '/': + // GDB format suffixes + { + Options *command_options = cmd_obj->GetOptions(); + if (command_options && + command_options->SupportsLongOption("gdb-format")) { + std::string gdb_format_option("--gdb-format="); + gdb_format_option += (suffix.c_str() + 1); + + std::string cmd = revised_command_line.GetString(); + size_t arg_terminator_idx = FindArgumentTerminator(cmd); + if (arg_terminator_idx != std::string::npos) { + // Insert the gdb format option before the "--" that terminates + // options + gdb_format_option.append(1, ' '); + cmd.insert(arg_terminator_idx, gdb_format_option); + revised_command_line.Clear(); + revised_command_line.PutCString(cmd); + } else + revised_command_line.Printf(" %s", gdb_format_option.c_str()); + + if (wants_raw_input && + FindArgumentTerminator(cmd) == std::string::npos) + revised_command_line.PutCString(" --"); } else { - // We didn't have only one match, otherwise we wouldn't get here. - assert(num_matches == 0); - result.AppendErrorWithFormat("'%s' is not a valid command.\n", next_word.c_str()); + result.AppendErrorWithFormat( + "the '%s' command doesn't support the --gdb-format option\n", + cmd_obj->GetCommandName().str().c_str()); + result.SetStatus(eReturnStatusFailed); + return nullptr; } - result.SetStatus(eReturnStatusFailed); - return nullptr; - } + } + break; - if (cmd_obj->IsMultiwordObject()) - { - if (!suffix.empty()) - { - result.AppendErrorWithFormat("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n", - cmd_obj->GetCommandName(), - next_word.empty() ? "" : next_word.c_str(), - next_word.empty() ? " -- " : " ", - suffix.c_str()); - result.SetStatus(eReturnStatusFailed); - return nullptr; - } - } - else - { - // If we found a normal command, we are done - done = true; - if (!suffix.empty()) - { - switch (suffix[0]) - { - case '/': - // GDB format suffixes - { - Options *command_options = cmd_obj->GetOptions(); - if (command_options && command_options->SupportsLongOption("gdb-format")) - { - std::string gdb_format_option("--gdb-format="); - gdb_format_option += (suffix.c_str() + 1); - - bool inserted = false; - std::string &cmd = revised_command_line.GetString(); - size_t arg_terminator_idx = FindArgumentTerminator(cmd); - if (arg_terminator_idx != std::string::npos) - { - // Insert the gdb format option before the "--" that terminates options - gdb_format_option.append(1,' '); - cmd.insert(arg_terminator_idx, gdb_format_option); - inserted = true; - } - - if (!inserted) - revised_command_line.Printf(" %s", gdb_format_option.c_str()); - - if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos) - revised_command_line.PutCString(" --"); - } - else - { - result.AppendErrorWithFormat("the '%s' command doesn't support the --gdb-format option\n", - cmd_obj->GetCommandName()); - result.SetStatus(eReturnStatusFailed); - return nullptr; - } - } - break; - - default: - result.AppendErrorWithFormat("unknown command shorthand suffix: '%s'\n", - suffix.c_str()); - result.SetStatus(eReturnStatusFailed); - return nullptr; - } - } + default: + result.AppendErrorWithFormat( + "unknown command shorthand suffix: '%s'\n", suffix.c_str()); + result.SetStatus(eReturnStatusFailed); + return nullptr; } - if (scratch_command.empty()) - done = true; + } } + if (scratch_command.empty()) + done = true; + } - if (!scratch_command.empty()) - revised_command_line.Printf(" %s", scratch_command.c_str()); + if (!scratch_command.empty()) + revised_command_line.Printf(" %s", scratch_command.c_str()); - if (cmd_obj != NULL) - command_line = revised_command_line.GetData(); + if (cmd_obj != NULL) + command_line = revised_command_line.GetString(); - return cmd_obj; + return cmd_obj; } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp index 75e4292..944d408 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp @@ -9,12 +9,12 @@ #include "lldb/Interpreter/CommandObject.h" -#include <string> -#include <sstream> #include <map> +#include <sstream> +#include <string> -#include <stdlib.h> #include <ctype.h> +#include <stdlib.h> #include "lldb/Core/Address.h" #include "lldb/Core/ArchSpec.h" @@ -22,9 +22,9 @@ // These are for the Sourcename completers. // FIXME: Make a separate file for the completers. -#include "lldb/Host/FileSpec.h" #include "lldb/Core/FileSpecList.h" #include "lldb/DataFormatters/FormatManager.h" +#include "lldb/Host/FileSpec.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -40,1066 +40,992 @@ using namespace lldb_private; // CommandObject //------------------------------------------------------------------------- -CommandObject::CommandObject -( - CommandInterpreter &interpreter, - const char *name, - const char *help, - const char *syntax, - uint32_t flags -) : - m_interpreter (interpreter), - m_cmd_name (name ? name : ""), - m_cmd_help_short (), - m_cmd_help_long (), - m_cmd_syntax (), - m_flags (flags), - m_arguments(), - m_deprecated_command_override_callback (nullptr), - m_command_override_callback (nullptr), - m_command_override_baton (nullptr) -{ - if (help && help[0]) - m_cmd_help_short = help; - if (syntax && syntax[0]) - m_cmd_syntax = syntax; +CommandObject::CommandObject(CommandInterpreter &interpreter, llvm::StringRef name, + llvm::StringRef help, llvm::StringRef syntax, uint32_t flags) + : m_interpreter(interpreter), m_cmd_name(name), + m_cmd_help_short(), m_cmd_help_long(), m_cmd_syntax(), m_flags(flags), + m_arguments(), m_deprecated_command_override_callback(nullptr), + m_command_override_callback(nullptr), m_command_override_baton(nullptr) { + m_cmd_help_short = help; + m_cmd_syntax = syntax; } -CommandObject::~CommandObject () -{ -} +CommandObject::~CommandObject() {} -const char * -CommandObject::GetHelp () -{ - return m_cmd_help_short.c_str(); -} +llvm::StringRef CommandObject::GetHelp() { return m_cmd_help_short; } -const char * -CommandObject::GetHelpLong () -{ - return m_cmd_help_long.c_str(); -} +llvm::StringRef CommandObject::GetHelpLong() { return m_cmd_help_long; } -const char * -CommandObject::GetSyntax () -{ - if (m_cmd_syntax.length() == 0) - { - StreamString syntax_str; - syntax_str.Printf ("%s", GetCommandName()); - if (!IsDashDashCommand() && GetOptions() != nullptr) - syntax_str.Printf (" <cmd-options>"); - if (m_arguments.size() > 0) - { - syntax_str.Printf (" "); - if (!IsDashDashCommand() && WantsRawCommandString() && GetOptions() && GetOptions()->NumCommandOptions()) - syntax_str.Printf("-- "); - GetFormattedCommandArguments (syntax_str); - } - m_cmd_syntax = syntax_str.GetData (); - } +llvm::StringRef CommandObject::GetSyntax() { + if (m_cmd_syntax.empty()) + return m_cmd_syntax; - return m_cmd_syntax.c_str(); -} + StreamString syntax_str; + syntax_str.PutCString(GetCommandName()); -const char * -CommandObject::GetCommandName () -{ - return m_cmd_name.c_str(); -} + if (!IsDashDashCommand() && GetOptions() != nullptr) + syntax_str.PutCString(" <cmd-options>"); -void -CommandObject::SetCommandName (const char *name) -{ - m_cmd_name = name; -} + if (!m_arguments.empty()) { + syntax_str.PutCString(" "); -void -CommandObject::SetHelp (const char *cstr) -{ - if (cstr) - m_cmd_help_short = cstr; - else - m_cmd_help_short.assign(""); -} + if (!IsDashDashCommand() && WantsRawCommandString() && GetOptions() && + GetOptions()->NumCommandOptions()) + syntax_str.PutCString("-- "); + GetFormattedCommandArguments(syntax_str); + } + m_cmd_syntax = syntax_str.GetString(); -void -CommandObject::SetHelpLong (const char *cstr) -{ - if (cstr) - m_cmd_help_long = cstr; - else - m_cmd_help_long.assign(""); + return m_cmd_syntax; } -void -CommandObject::SetSyntax (const char *cstr) -{ - m_cmd_syntax = cstr; -} +llvm::StringRef CommandObject::GetCommandName() const { return m_cmd_name; } -Options * -CommandObject::GetOptions () -{ - // By default commands don't have options unless this virtual function - // is overridden by base classes. - return nullptr; -} +void CommandObject::SetCommandName(llvm::StringRef name) { m_cmd_name = name; } -bool -CommandObject::ParseOptions -( - Args& args, - CommandReturnObject &result -) -{ - // See if the subclass has options? - Options *options = GetOptions(); - if (options != nullptr) - { - Error error; - options->NotifyOptionParsingStarting(); - - // ParseOptions calls getopt_long_only, which always skips the zero'th item in the array and starts at position 1, - // so we need to push a dummy value into position zero. - args.Unshift("dummy_string"); - error = args.ParseOptions (*options); - - // The "dummy_string" will have already been removed by ParseOptions, - // so no need to remove it. - - if (error.Success()) - error = options->NotifyOptionParsingFinished(); - - if (error.Success()) - { - if (options->VerifyOptions (result)) - return true; - } - else - { - const char *error_cstr = error.AsCString(); - if (error_cstr) - { - // We got an error string, lets use that - result.AppendError(error_cstr); - } - else - { - // No error string, output the usage information into result - options->GenerateOptionUsage (result.GetErrorStream(), this); - } - } - result.SetStatus (eReturnStatusFailed); - return false; - } - return true; +void CommandObject::SetHelp(llvm::StringRef str) { m_cmd_help_short = str; } + +void CommandObject::SetHelpLong(llvm::StringRef str) { m_cmd_help_long = str; } + +void CommandObject::SetSyntax(llvm::StringRef str) { m_cmd_syntax = str; } + +Options *CommandObject::GetOptions() { + // By default commands don't have options unless this virtual function + // is overridden by base classes. + return nullptr; } +bool CommandObject::ParseOptions(Args &args, CommandReturnObject &result) { + // See if the subclass has options? + Options *options = GetOptions(); + if (options != nullptr) { + Error error; + + auto exe_ctx = GetCommandInterpreter().GetExecutionContext(); + options->NotifyOptionParsingStarting(&exe_ctx); + // ParseOptions calls getopt_long_only, which always skips the zero'th item + // in the array and starts at position 1, + // so we need to push a dummy value into position zero. + args.Unshift(llvm::StringRef("dummy_string")); + const bool require_validation = true; + error = args.ParseOptions(*options, &exe_ctx, + GetCommandInterpreter().GetPlatform(true), + require_validation); -bool -CommandObject::CheckRequirements (CommandReturnObject &result) -{ + // The "dummy_string" will have already been removed by ParseOptions, + // so no need to remove it. + + if (error.Success()) + error = options->NotifyOptionParsingFinished(&exe_ctx); + + if (error.Success()) { + if (options->VerifyOptions(result)) + return true; + } else { + const char *error_cstr = error.AsCString(); + if (error_cstr) { + // We got an error string, lets use that + result.AppendError(error_cstr); + } else { + // No error string, output the usage information into result + options->GenerateOptionUsage( + result.GetErrorStream(), this, + GetCommandInterpreter().GetDebugger().GetTerminalWidth()); + } + } + result.SetStatus(eReturnStatusFailed); + return false; + } + return true; +} + +bool CommandObject::CheckRequirements(CommandReturnObject &result) { #ifdef LLDB_CONFIGURATION_DEBUG - // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx - // has shared pointers to the target, process, thread and frame and we don't - // want any CommandObject instances to keep any of these objects around - // longer than for a single command. Every command should call - // CommandObject::Cleanup() after it has completed - assert (m_exe_ctx.GetTargetPtr() == NULL); - assert (m_exe_ctx.GetProcessPtr() == NULL); - assert (m_exe_ctx.GetThreadPtr() == NULL); - assert (m_exe_ctx.GetFramePtr() == NULL); + // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx + // has shared pointers to the target, process, thread and frame and we don't + // want any CommandObject instances to keep any of these objects around + // longer than for a single command. Every command should call + // CommandObject::Cleanup() after it has completed + assert(m_exe_ctx.GetTargetPtr() == NULL); + assert(m_exe_ctx.GetProcessPtr() == NULL); + assert(m_exe_ctx.GetThreadPtr() == NULL); + assert(m_exe_ctx.GetFramePtr() == NULL); #endif - // Lock down the interpreter's execution context prior to running the - // command so we guarantee the selected target, process, thread and frame - // can't go away during the execution - m_exe_ctx = m_interpreter.GetExecutionContext(); - - const uint32_t flags = GetFlags().Get(); - if (flags & (eCommandRequiresTarget | - eCommandRequiresProcess | - eCommandRequiresThread | - eCommandRequiresFrame | - eCommandTryTargetAPILock )) - { - - if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope()) - { - result.AppendError (GetInvalidTargetDescription()); - return false; - } + // Lock down the interpreter's execution context prior to running the + // command so we guarantee the selected target, process, thread and frame + // can't go away during the execution + m_exe_ctx = m_interpreter.GetExecutionContext(); - if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope()) - { - if (!m_exe_ctx.HasTargetScope()) - result.AppendError (GetInvalidTargetDescription()); - else - result.AppendError (GetInvalidProcessDescription()); - return false; - } - - if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope()) - { - if (!m_exe_ctx.HasTargetScope()) - result.AppendError (GetInvalidTargetDescription()); - else if (!m_exe_ctx.HasProcessScope()) - result.AppendError (GetInvalidProcessDescription()); - else - result.AppendError (GetInvalidThreadDescription()); - return false; - } - - if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope()) - { - if (!m_exe_ctx.HasTargetScope()) - result.AppendError (GetInvalidTargetDescription()); - else if (!m_exe_ctx.HasProcessScope()) - result.AppendError (GetInvalidProcessDescription()); - else if (!m_exe_ctx.HasThreadScope()) - result.AppendError (GetInvalidThreadDescription()); - else - result.AppendError (GetInvalidFrameDescription()); - return false; - } - - if ((flags & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr)) - { - result.AppendError (GetInvalidRegContextDescription()); - return false; - } + const uint32_t flags = GetFlags().Get(); + if (flags & (eCommandRequiresTarget | eCommandRequiresProcess | + eCommandRequiresThread | eCommandRequiresFrame | + eCommandTryTargetAPILock)) { - if (flags & eCommandTryTargetAPILock) - { - Target *target = m_exe_ctx.GetTargetPtr(); - if (target) - m_api_locker = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex()); - } + if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope()) { + result.AppendError(GetInvalidTargetDescription()); + return false; + } + + if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope()) { + if (!m_exe_ctx.HasTargetScope()) + result.AppendError(GetInvalidTargetDescription()); + else + result.AppendError(GetInvalidProcessDescription()); + return false; + } + + if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope()) { + if (!m_exe_ctx.HasTargetScope()) + result.AppendError(GetInvalidTargetDescription()); + else if (!m_exe_ctx.HasProcessScope()) + result.AppendError(GetInvalidProcessDescription()); + else + result.AppendError(GetInvalidThreadDescription()); + return false; + } + + if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope()) { + if (!m_exe_ctx.HasTargetScope()) + result.AppendError(GetInvalidTargetDescription()); + else if (!m_exe_ctx.HasProcessScope()) + result.AppendError(GetInvalidProcessDescription()); + else if (!m_exe_ctx.HasThreadScope()) + result.AppendError(GetInvalidThreadDescription()); + else + result.AppendError(GetInvalidFrameDescription()); + return false; + } + + if ((flags & eCommandRequiresRegContext) && + (m_exe_ctx.GetRegisterContext() == nullptr)) { + result.AppendError(GetInvalidRegContextDescription()); + return false; } - if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)) - { - Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); - if (process == nullptr) - { - // A process that is not running is considered paused. - if (GetFlags().Test(eCommandProcessMustBeLaunched)) - { - result.AppendError ("Process must exist."); - result.SetStatus (eReturnStatusFailed); - return false; - } + if (flags & eCommandTryTargetAPILock) { + Target *target = m_exe_ctx.GetTargetPtr(); + if (target) + m_api_locker = + std::unique_lock<std::recursive_mutex>(target->GetAPIMutex()); + } + } + + if (GetFlags().AnySet(eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused)) { + Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); + if (process == nullptr) { + // A process that is not running is considered paused. + if (GetFlags().Test(eCommandProcessMustBeLaunched)) { + result.AppendError("Process must exist."); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + StateType state = process->GetState(); + switch (state) { + case eStateInvalid: + case eStateSuspended: + case eStateCrashed: + case eStateStopped: + break; + + case eStateConnected: + case eStateAttaching: + case eStateLaunching: + case eStateDetached: + case eStateExited: + case eStateUnloaded: + if (GetFlags().Test(eCommandProcessMustBeLaunched)) { + result.AppendError("Process must be launched."); + result.SetStatus(eReturnStatusFailed); + return false; } - else - { - StateType state = process->GetState(); - switch (state) - { - case eStateInvalid: - case eStateSuspended: - case eStateCrashed: - case eStateStopped: - break; - - case eStateConnected: - case eStateAttaching: - case eStateLaunching: - case eStateDetached: - case eStateExited: - case eStateUnloaded: - if (GetFlags().Test(eCommandProcessMustBeLaunched)) - { - result.AppendError ("Process must be launched."); - result.SetStatus (eReturnStatusFailed); - return false; - } - break; - - case eStateRunning: - case eStateStepping: - if (GetFlags().Test(eCommandProcessMustBePaused)) - { - result.AppendError ("Process is running. Use 'process interrupt' to pause execution."); - result.SetStatus (eReturnStatusFailed); - return false; - } - } + break; + + case eStateRunning: + case eStateStepping: + if (GetFlags().Test(eCommandProcessMustBePaused)) { + result.AppendError("Process is running. Use 'process interrupt' to " + "pause execution."); + result.SetStatus(eReturnStatusFailed); + return false; } + } } - return true; + } + return true; } -void -CommandObject::Cleanup () -{ - m_exe_ctx.Clear(); - if (m_api_locker.owns_lock()) - m_api_locker.unlock(); +void CommandObject::Cleanup() { + m_exe_ctx.Clear(); + if (m_api_locker.owns_lock()) + m_api_locker.unlock(); } -int -CommandObject::HandleCompletion -( - Args &input, - int &cursor_index, - int &cursor_char_position, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches -) -{ - // Default implementation of WantsCompletion() is !WantsRawCommandString(). - // Subclasses who want raw command string but desire, for example, - // argument completion should override WantsCompletion() to return true, - // instead. - if (WantsRawCommandString() && !WantsCompletion()) - { - // FIXME: Abstract telling the completion to insert the completion character. - matches.Clear(); - return -1; +int CommandObject::HandleCompletion(Args &input, int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + bool &word_complete, StringList &matches) { + // Default implementation of WantsCompletion() is !WantsRawCommandString(). + // Subclasses who want raw command string but desire, for example, + // argument completion should override WantsCompletion() to return true, + // instead. + if (WantsRawCommandString() && !WantsCompletion()) { + // FIXME: Abstract telling the completion to insert the completion + // character. + matches.Clear(); + return -1; + } else { + // Can we do anything generic with the options? + Options *cur_options = GetOptions(); + CommandReturnObject result; + OptionElementVector opt_element_vector; + + if (cur_options != nullptr) { + // Re-insert the dummy command name string which will have been + // stripped off: + input.Unshift(llvm::StringRef("dummy-string")); + cursor_index++; + + // 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. + + input.AppendArgument(llvm::StringRef("<FAKE-VALUE>")); + + input.ParseArgsForCompletion(*cur_options, opt_element_vector, + cursor_index); + + input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1); + + bool handled_by_options; + handled_by_options = cur_options->HandleOptionCompletion( + input, opt_element_vector, cursor_index, cursor_char_position, + match_start_point, max_return_elements, GetCommandInterpreter(), + word_complete, matches); + if (handled_by_options) + return matches.GetSize(); } - else - { - // Can we do anything generic with the options? - Options *cur_options = GetOptions(); - CommandReturnObject result; - OptionElementVector opt_element_vector; - - if (cur_options != nullptr) - { - // Re-insert the dummy command name string which will have been - // stripped off: - input.Unshift ("dummy-string"); - cursor_index++; - - - // 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. - - input.AppendArgument ("<FAKE-VALUE>"); - - input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index); - - input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1); - - bool handled_by_options; - handled_by_options = cur_options->HandleOptionCompletion (input, - opt_element_vector, - cursor_index, - cursor_char_position, - match_start_point, - max_return_elements, - word_complete, - matches); - if (handled_by_options) - return matches.GetSize(); - } - // If we got here, the last word is not an option or an option argument. - return HandleArgumentCompletion (input, - cursor_index, - cursor_char_position, - opt_element_vector, - match_start_point, - max_return_elements, - word_complete, - matches); - } + // If we got here, the last word is not an option or an option argument. + return HandleArgumentCompletion( + input, cursor_index, cursor_char_position, opt_element_vector, + match_start_point, max_return_elements, word_complete, matches); + } } -bool -CommandObject::HelpTextContainsWord (const char *search_word, - bool search_short_help, - bool search_long_help, - bool search_syntax, - bool search_options) -{ - std::string options_usage_help; - - bool found_word = false; - - const char *short_help = GetHelp(); - const char *long_help = GetHelpLong(); - const char *syntax_help = GetSyntax(); - - if (search_short_help && short_help && strcasestr (short_help, search_word)) - found_word = true; - else if (search_long_help && long_help && strcasestr (long_help, search_word)) - found_word = true; - else if (search_syntax && syntax_help && strcasestr (syntax_help, search_word)) +bool CommandObject::HelpTextContainsWord(llvm::StringRef search_word, + bool search_short_help, + bool search_long_help, + bool search_syntax, + bool search_options) { + std::string options_usage_help; + + bool found_word = false; + + llvm::StringRef short_help = GetHelp(); + llvm::StringRef long_help = GetHelpLong(); + llvm::StringRef syntax_help = GetSyntax(); + + if (search_short_help && short_help.contains_lower(search_word)) + found_word = true; + else if (search_long_help && long_help.contains_lower(search_word)) + found_word = true; + else if (search_syntax && syntax_help.contains_lower(search_word)) + found_word = true; + + if (!found_word && search_options && GetOptions() != nullptr) { + StreamString usage_help; + GetOptions()->GenerateOptionUsage( + usage_help, this, + GetCommandInterpreter().GetDebugger().GetTerminalWidth()); + if (!usage_help.Empty()) { + llvm::StringRef usage_text = usage_help.GetString(); + if (usage_text.contains_lower(search_word)) found_word = true; - - if (!found_word - && search_options - && GetOptions() != nullptr) - { - StreamString usage_help; - GetOptions()->GenerateOptionUsage (usage_help, this); - if (usage_help.GetSize() > 0) - { - const char *usage_text = usage_help.GetData(); - if (strcasestr (usage_text, search_word)) - found_word = true; - } } + } - return found_word; + return found_word; } -int -CommandObject::GetNumArgumentEntries () -{ - return m_arguments.size(); -} +int CommandObject::GetNumArgumentEntries() { return m_arguments.size(); } CommandObject::CommandArgumentEntry * -CommandObject::GetArgumentEntryAtIndex (int idx) -{ - if (static_cast<size_t>(idx) < m_arguments.size()) - return &(m_arguments[idx]); +CommandObject::GetArgumentEntryAtIndex(int idx) { + if (static_cast<size_t>(idx) < m_arguments.size()) + return &(m_arguments[idx]); - return nullptr; + return nullptr; } const CommandObject::ArgumentTableEntry * -CommandObject::FindArgumentDataByType (CommandArgumentType arg_type) -{ - const ArgumentTableEntry *table = CommandObject::GetArgumentTable(); +CommandObject::FindArgumentDataByType(CommandArgumentType arg_type) { + const ArgumentTableEntry *table = CommandObject::GetArgumentTable(); - for (int i = 0; i < eArgTypeLastArg; ++i) - if (table[i].arg_type == arg_type) - return &(table[i]); + for (int i = 0; i < eArgTypeLastArg; ++i) + if (table[i].arg_type == arg_type) + return &(table[i]); - return nullptr; + return nullptr; } -void -CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter) -{ - const ArgumentTableEntry* table = CommandObject::GetArgumentTable(); - const ArgumentTableEntry *entry = &(table[arg_type]); - - // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up... - - if (entry->arg_type != arg_type) - entry = CommandObject::FindArgumentDataByType (arg_type); - - if (!entry) - return; - - StreamString name_str; - name_str.Printf ("<%s>", entry->arg_name); - - if (entry->help_function) - { - const char* help_text = entry->help_function(); - if (!entry->help_function.self_formatting) - { - interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text, - name_str.GetSize()); - } - else - { - interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text, - name_str.GetSize()); - } +void CommandObject::GetArgumentHelp(Stream &str, CommandArgumentType arg_type, + CommandInterpreter &interpreter) { + const ArgumentTableEntry *table = CommandObject::GetArgumentTable(); + const ArgumentTableEntry *entry = &(table[arg_type]); + + // The table is *supposed* to be kept in arg_type order, but someone *could* + // have messed it up... + + if (entry->arg_type != arg_type) + entry = CommandObject::FindArgumentDataByType(arg_type); + + if (!entry) + return; + + StreamString name_str; + name_str.Printf("<%s>", entry->arg_name); + + if (entry->help_function) { + llvm::StringRef help_text = entry->help_function(); + if (!entry->help_function.self_formatting) { + interpreter.OutputFormattedHelpText(str, name_str.GetString(), "--", + help_text, name_str.GetSize()); + } else { + interpreter.OutputHelpText(str, name_str.GetString(), "--", help_text, + name_str.GetSize()); } - else - interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize()); + } else + interpreter.OutputFormattedHelpText(str, name_str.GetString(), "--", + entry->help_text, name_str.GetSize()); } -const char * -CommandObject::GetArgumentName (CommandArgumentType arg_type) -{ - const ArgumentTableEntry *entry = &(CommandObject::GetArgumentTable()[arg_type]); +const char *CommandObject::GetArgumentName(CommandArgumentType arg_type) { + const ArgumentTableEntry *entry = + &(CommandObject::GetArgumentTable()[arg_type]); - // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up... + // The table is *supposed* to be kept in arg_type order, but someone *could* + // have messed it up... - if (entry->arg_type != arg_type) - entry = CommandObject::FindArgumentDataByType (arg_type); + if (entry->arg_type != arg_type) + entry = CommandObject::FindArgumentDataByType(arg_type); - if (entry) - return entry->arg_name; + if (entry) + return entry->arg_name; - StreamString str; - str << "Arg name for type (" << arg_type << ") not in arg table!"; - return str.GetData(); + return nullptr; } -bool -CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type) -{ - if ((arg_repeat_type == eArgRepeatPairPlain) - || (arg_repeat_type == eArgRepeatPairOptional) - || (arg_repeat_type == eArgRepeatPairPlus) - || (arg_repeat_type == eArgRepeatPairStar) - || (arg_repeat_type == eArgRepeatPairRange) - || (arg_repeat_type == eArgRepeatPairRangeOptional)) - return true; +bool CommandObject::IsPairType(ArgumentRepetitionType arg_repeat_type) { + if ((arg_repeat_type == eArgRepeatPairPlain) || + (arg_repeat_type == eArgRepeatPairOptional) || + (arg_repeat_type == eArgRepeatPairPlus) || + (arg_repeat_type == eArgRepeatPairStar) || + (arg_repeat_type == eArgRepeatPairRange) || + (arg_repeat_type == eArgRepeatPairRangeOptional)) + return true; - return false; + return false; } static CommandObject::CommandArgumentEntry -OptSetFiltered(uint32_t opt_set_mask, CommandObject::CommandArgumentEntry &cmd_arg_entry) -{ - CommandObject::CommandArgumentEntry ret_val; - for (unsigned i = 0; i < cmd_arg_entry.size(); ++i) - if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association) - ret_val.push_back(cmd_arg_entry[i]); - return ret_val; +OptSetFiltered(uint32_t opt_set_mask, + CommandObject::CommandArgumentEntry &cmd_arg_entry) { + CommandObject::CommandArgumentEntry ret_val; + for (unsigned i = 0; i < cmd_arg_entry.size(); ++i) + if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association) + ret_val.push_back(cmd_arg_entry[i]); + return ret_val; } // Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take // all the argument data into account. On rare cases where some argument sticks // with certain option sets, this function returns the option set filtered args. -void -CommandObject::GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask) -{ - int num_args = m_arguments.size(); - for (int i = 0; i < num_args; ++i) - { - if (i > 0) - str.Printf (" "); - CommandArgumentEntry arg_entry = - opt_set_mask == LLDB_OPT_SET_ALL ? m_arguments[i] - : OptSetFiltered(opt_set_mask, m_arguments[i]); - int num_alternatives = arg_entry.size(); - - if ((num_alternatives == 2) - && IsPairType (arg_entry[0].arg_repetition)) - { - const char *first_name = GetArgumentName (arg_entry[0].arg_type); - const char *second_name = GetArgumentName (arg_entry[1].arg_type); - switch (arg_entry[0].arg_repetition) - { - case eArgRepeatPairPlain: - str.Printf ("<%s> <%s>", first_name, second_name); - break; - case eArgRepeatPairOptional: - str.Printf ("[<%s> <%s>]", first_name, second_name); - break; - case eArgRepeatPairPlus: - str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name); - break; - case eArgRepeatPairStar: - str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name); - break; - case eArgRepeatPairRange: - str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name); - break; - case eArgRepeatPairRangeOptional: - str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name); - break; - // Explicitly test for all the rest of the cases, so if new types get added we will notice the - // missing case statement(s). - case eArgRepeatPlain: - case eArgRepeatOptional: - case eArgRepeatPlus: - case eArgRepeatStar: - case eArgRepeatRange: - // These should not be reached, as they should fail the IsPairType test above. - break; - } - } - else - { - StreamString names; - for (int j = 0; j < num_alternatives; ++j) - { - if (j > 0) - names.Printf (" | "); - names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type)); - } - switch (arg_entry[0].arg_repetition) - { - case eArgRepeatPlain: - str.Printf ("<%s>", names.GetData()); - break; - case eArgRepeatPlus: - str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData()); - break; - case eArgRepeatStar: - str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData()); - break; - case eArgRepeatOptional: - str.Printf ("[<%s>]", names.GetData()); - break; - case eArgRepeatRange: - str.Printf ("<%s_1> .. <%s_n>", names.GetData(), names.GetData()); - break; - // Explicitly test for all the rest of the cases, so if new types get added we will notice the - // missing case statement(s). - case eArgRepeatPairPlain: - case eArgRepeatPairOptional: - case eArgRepeatPairPlus: - case eArgRepeatPairStar: - case eArgRepeatPairRange: - case eArgRepeatPairRangeOptional: - // These should not be hit, as they should pass the IsPairType test above, and control should - // have gone into the other branch of the if statement. - break; - } - } +void CommandObject::GetFormattedCommandArguments(Stream &str, + uint32_t opt_set_mask) { + int num_args = m_arguments.size(); + for (int i = 0; i < num_args; ++i) { + if (i > 0) + str.Printf(" "); + CommandArgumentEntry arg_entry = + opt_set_mask == LLDB_OPT_SET_ALL + ? m_arguments[i] + : OptSetFiltered(opt_set_mask, m_arguments[i]); + int num_alternatives = arg_entry.size(); + + if ((num_alternatives == 2) && IsPairType(arg_entry[0].arg_repetition)) { + const char *first_name = GetArgumentName(arg_entry[0].arg_type); + const char *second_name = GetArgumentName(arg_entry[1].arg_type); + switch (arg_entry[0].arg_repetition) { + case eArgRepeatPairPlain: + str.Printf("<%s> <%s>", first_name, second_name); + break; + case eArgRepeatPairOptional: + str.Printf("[<%s> <%s>]", first_name, second_name); + break; + case eArgRepeatPairPlus: + str.Printf("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, + first_name, second_name); + break; + case eArgRepeatPairStar: + str.Printf("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, + first_name, second_name); + break; + case eArgRepeatPairRange: + str.Printf("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, + first_name, second_name); + break; + case eArgRepeatPairRangeOptional: + str.Printf("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, + first_name, second_name); + break; + // Explicitly test for all the rest of the cases, so if new types get + // added we will notice the + // missing case statement(s). + case eArgRepeatPlain: + case eArgRepeatOptional: + case eArgRepeatPlus: + case eArgRepeatStar: + case eArgRepeatRange: + // These should not be reached, as they should fail the IsPairType test + // above. + break; + } + } else { + StreamString names; + for (int j = 0; j < num_alternatives; ++j) { + if (j > 0) + names.Printf(" | "); + names.Printf("%s", GetArgumentName(arg_entry[j].arg_type)); + } + + std::string name_str = names.GetString(); + switch (arg_entry[0].arg_repetition) { + case eArgRepeatPlain: + str.Printf("<%s>", name_str.c_str()); + break; + case eArgRepeatPlus: + str.Printf("<%s> [<%s> [...]]", name_str.c_str(), name_str.c_str()); + break; + case eArgRepeatStar: + str.Printf("[<%s> [<%s> [...]]]", name_str.c_str(), name_str.c_str()); + break; + case eArgRepeatOptional: + str.Printf("[<%s>]", name_str.c_str()); + break; + case eArgRepeatRange: + str.Printf("<%s_1> .. <%s_n>", name_str.c_str(), name_str.c_str()); + break; + // Explicitly test for all the rest of the cases, so if new types get + // added we will notice the + // missing case statement(s). + case eArgRepeatPairPlain: + case eArgRepeatPairOptional: + case eArgRepeatPairPlus: + case eArgRepeatPairStar: + case eArgRepeatPairRange: + case eArgRepeatPairRangeOptional: + // These should not be hit, as they should pass the IsPairType test + // above, and control should + // have gone into the other branch of the if statement. + break; + } } + } } CommandArgumentType -CommandObject::LookupArgumentName (const char *arg_name) -{ - CommandArgumentType return_type = eArgTypeLastArg; - - std::string arg_name_str (arg_name); - size_t len = arg_name_str.length(); - if (arg_name[0] == '<' - && arg_name[len-1] == '>') - arg_name_str = arg_name_str.substr (1, len-2); - - const ArgumentTableEntry *table = GetArgumentTable(); - for (int i = 0; i < eArgTypeLastArg; ++i) - if (arg_name_str.compare (table[i].arg_name) == 0) - return_type = g_arguments_data[i].arg_type; - - return return_type; -} +CommandObject::LookupArgumentName(llvm::StringRef arg_name) { + CommandArgumentType return_type = eArgTypeLastArg; -static const char * -RegisterNameHelpTextCallback () -{ - return "Register names can be specified using the architecture specific names. " - "They can also be specified using generic names. Not all generic entities have " - "registers backing them on all architectures. When they don't the generic name " - "will return an error.\n" - "The generic names defined in lldb are:\n" - "\n" - "pc - program counter register\n" - "ra - return address register\n" - "fp - frame pointer register\n" - "sp - stack pointer register\n" - "flags - the flags register\n" - "arg{1-6} - integer argument passing registers.\n"; + arg_name = arg_name.ltrim('<').rtrim('>'); + + const ArgumentTableEntry *table = GetArgumentTable(); + for (int i = 0; i < eArgTypeLastArg; ++i) + if (arg_name == table[i].arg_name) + return_type = g_arguments_data[i].arg_type; + + return return_type; } -static const char * -BreakpointIDHelpTextCallback () -{ - return "Breakpoints are identified using major and minor numbers; the major " - "number corresponds to the single entity that was created with a 'breakpoint " - "set' command; the minor numbers correspond to all the locations that were " - "actually found/set based on the major breakpoint. A full breakpoint ID might " - "look like 3.14, meaning the 14th location set for the 3rd breakpoint. You " - "can specify all the locations of a breakpoint by just indicating the major " - "breakpoint number. A valid breakpoint ID consists either of just the major " - "number, or the major number followed by a dot and the location number (e.g. " - "3 or 3.2 could both be valid breakpoint IDs.)"; +static llvm::StringRef RegisterNameHelpTextCallback() { + return "Register names can be specified using the architecture specific " + "names. " + "They can also be specified using generic names. Not all generic " + "entities have " + "registers backing them on all architectures. When they don't the " + "generic name " + "will return an error.\n" + "The generic names defined in lldb are:\n" + "\n" + "pc - program counter register\n" + "ra - return address register\n" + "fp - frame pointer register\n" + "sp - stack pointer register\n" + "flags - the flags register\n" + "arg{1-6} - integer argument passing registers.\n"; } -static const char * -BreakpointIDRangeHelpTextCallback () -{ - return "A 'breakpoint ID list' is a manner of specifying multiple breakpoints. " - "This can be done through several mechanisms. The easiest way is to just " - "enter a space-separated list of breakpoint IDs. To specify all the " - "breakpoint locations under a major breakpoint, you can use the major " - "breakpoint number followed by '.*', eg. '5.*' means all the locations under " - "breakpoint 5. You can also indicate a range of breakpoints by using " - "<start-bp-id> - <end-bp-id>. The start-bp-id and end-bp-id for a range can " - "be any valid breakpoint IDs. It is not legal, however, to specify a range " - "using specific locations that cross major breakpoint numbers. I.e. 3.2 - 3.7" - " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal."; +static llvm::StringRef BreakpointIDHelpTextCallback() { + return "Breakpoints are identified using major and minor numbers; the major " + "number corresponds to the single entity that was created with a " + "'breakpoint " + "set' command; the minor numbers correspond to all the locations that " + "were " + "actually found/set based on the major breakpoint. A full breakpoint " + "ID might " + "look like 3.14, meaning the 14th location set for the 3rd " + "breakpoint. You " + "can specify all the locations of a breakpoint by just indicating the " + "major " + "breakpoint number. A valid breakpoint ID consists either of just the " + "major " + "number, or the major number followed by a dot and the location " + "number (e.g. " + "3 or 3.2 could both be valid breakpoint IDs.)"; } -static const char * -BreakpointNameHelpTextCallback () -{ - return "A name that can be added to a breakpoint when it is created, or later " - "on with the \"breakpoint name add\" command. " - "Breakpoint names can be used to specify breakpoints in all the places breakpoint IDs " - "and breakpoint ID ranges can be used. As such they provide a convenient way to group breakpoints, " - "and to operate on breakpoints you create without having to track the breakpoint number. " - "Note, the attributes you set when using a breakpoint name in a breakpoint command don't " - "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that " - "name. Future breakpoints " - "tagged with that name will not pick up the attributes previously given using that name. " - "In order to distinguish breakpoint names from breakpoint IDs and ranges, " - "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\". " - "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations."; +static llvm::StringRef BreakpointIDRangeHelpTextCallback() { + return "A 'breakpoint ID list' is a manner of specifying multiple " + "breakpoints. " + "This can be done through several mechanisms. The easiest way is to " + "just " + "enter a space-separated list of breakpoint IDs. To specify all the " + "breakpoint locations under a major breakpoint, you can use the major " + "breakpoint number followed by '.*', eg. '5.*' means all the " + "locations under " + "breakpoint 5. You can also indicate a range of breakpoints by using " + "<start-bp-id> - <end-bp-id>. The start-bp-id and end-bp-id for a " + "range can " + "be any valid breakpoint IDs. It is not legal, however, to specify a " + "range " + "using specific locations that cross major breakpoint numbers. I.e. " + "3.2 - 3.7" + " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal."; } -static const char * -GDBFormatHelpTextCallback () -{ - return "A GDB format consists of a repeat count, a format letter and a size letter. " - "The repeat count is optional and defaults to 1. The format letter is optional " - "and defaults to the previous format that was used. The size letter is optional " - "and defaults to the previous size that was used.\n" - "\n" - "Format letters include:\n" - "o - octal\n" - "x - hexadecimal\n" - "d - decimal\n" - "u - unsigned decimal\n" - "t - binary\n" - "f - float\n" - "a - address\n" - "i - instruction\n" - "c - char\n" - "s - string\n" - "T - OSType\n" - "A - float as hex\n" - "\n" - "Size letters include:\n" - "b - 1 byte (byte)\n" - "h - 2 bytes (halfword)\n" - "w - 4 bytes (word)\n" - "g - 8 bytes (giant)\n" - "\n" - "Example formats:\n" - "32xb - show 32 1 byte hexadecimal integer values\n" - "16xh - show 16 2 byte hexadecimal integer values\n" - "64 - show 64 2 byte hexadecimal integer values (format and size from the last format)\n" - "dw - show 1 4 byte decimal integer value\n" - ; -} - -static const char * -FormatHelpTextCallback () -{ - - static char* help_text_ptr = nullptr; - - if (help_text_ptr) - return help_text_ptr; - - StreamString sstr; - sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n"; - for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1)) - { - if (f != eFormatDefault) - sstr.PutChar('\n'); - - char format_char = FormatManager::GetFormatAsFormatChar(f); - if (format_char) - sstr.Printf("'%c' or ", format_char); - - sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f)); - } - - sstr.Flush(); - - std::string data = sstr.GetString(); - - help_text_ptr = new char[data.length()+1]; - - data.copy(help_text_ptr, data.length()); - - return help_text_ptr; +static llvm::StringRef BreakpointNameHelpTextCallback() { + return "A name that can be added to a breakpoint when it is created, or " + "later " + "on with the \"breakpoint name add\" command. " + "Breakpoint names can be used to specify breakpoints in all the " + "places breakpoint IDs " + "and breakpoint ID ranges can be used. As such they provide a " + "convenient way to group breakpoints, " + "and to operate on breakpoints you create without having to track the " + "breakpoint number. " + "Note, the attributes you set when using a breakpoint name in a " + "breakpoint command don't " + "adhere to the name, but instead are set individually on all the " + "breakpoints currently tagged with that " + "name. Future breakpoints " + "tagged with that name will not pick up the attributes previously " + "given using that name. " + "In order to distinguish breakpoint names from breakpoint IDs and " + "ranges, " + "names must start with a letter from a-z or A-Z and cannot contain " + "spaces, \".\" or \"-\". " + "Also, breakpoint names can only be applied to breakpoints, not to " + "breakpoint locations."; } -static const char * -LanguageTypeHelpTextCallback () -{ - static char* help_text_ptr = nullptr; - - if (help_text_ptr) - return help_text_ptr; - - StreamString sstr; - sstr << "One of the following languages:\n"; - - Language::PrintAllLanguages(sstr, " ", "\n"); - - sstr.Flush(); - - std::string data = sstr.GetString(); - - help_text_ptr = new char[data.length()+1]; - - data.copy(help_text_ptr, data.length()); - - return help_text_ptr; +static llvm::StringRef GDBFormatHelpTextCallback() { + return "A GDB format consists of a repeat count, a format letter and a size " + "letter. " + "The repeat count is optional and defaults to 1. The format letter is " + "optional " + "and defaults to the previous format that was used. The size letter " + "is optional " + "and defaults to the previous size that was used.\n" + "\n" + "Format letters include:\n" + "o - octal\n" + "x - hexadecimal\n" + "d - decimal\n" + "u - unsigned decimal\n" + "t - binary\n" + "f - float\n" + "a - address\n" + "i - instruction\n" + "c - char\n" + "s - string\n" + "T - OSType\n" + "A - float as hex\n" + "\n" + "Size letters include:\n" + "b - 1 byte (byte)\n" + "h - 2 bytes (halfword)\n" + "w - 4 bytes (word)\n" + "g - 8 bytes (giant)\n" + "\n" + "Example formats:\n" + "32xb - show 32 1 byte hexadecimal integer values\n" + "16xh - show 16 2 byte hexadecimal integer values\n" + "64 - show 64 2 byte hexadecimal integer values (format and size " + "from the last format)\n" + "dw - show 1 4 byte decimal integer value\n"; } -static const char * -SummaryStringHelpTextCallback() -{ - return - "A summary string is a way to extract information from variables in order to present them using a summary.\n" - "Summary strings contain static text, variables, scopes and control sequences:\n" - " - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n" - " - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n" - " - Scopes are any sequence of text between { and }. Anything included in a scope will only appear in the output summary if there were no errors.\n" - " - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n" - "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n" - "A variable is expanded by giving it a value other than its textual representation, and the way this is done depends on what comes after the ${ marker.\n" - "The most common sequence if ${var followed by an expression path, which is the text one would type to access a member of an aggregate types, given a variable of that type" - " (e.g. if type T has a member named x, which has a member named y, and if t is of type T, the expression path would be .x.y and the way to fit that into a summary string would be" - " ${var.x.y}). You can also use ${*var followed by an expression path and in that case the object referred by the path will be dereferenced before being displayed." - " If the object is not a pointer, doing so will cause an error. For additional details on expression paths, you can type 'help expr-path'. \n" - "By default, summary strings attempt to display the summary for any variable they reference, and if that fails the value. If neither can be shown, nothing is displayed." - "In a summary string, you can also use an array index [n], or a slice-like range [n-m]. This can have two different meanings depending on what kind of object the expression" - " path refers to:\n" - " - if it is a scalar type (any basic type like int, float, ...) the expression is a bitfield, i.e. the bits indicated by the indexing operator are extracted out of the number" - " and displayed as an individual variable\n" - " - if it is an array or pointer the array items indicated by the indexing operator are shown as the result of the variable. if the expression is an array, real array items are" - " printed; if it is a pointer, the pointer-as-array syntax is used to obtain the values (this means, the latter case can have no range checking)\n" - "If you are trying to display an array for which the size is known, you can also use [] instead of giving an exact range. This has the effect of showing items 0 thru size - 1.\n" - "Additionally, a variable can contain an (optional) format code, as in ${var.x.y%code}, where code can be any of the valid formats described in 'help format', or one of the" - " special symbols only allowed as part of a variable:\n" - " %V: show the value of the object by default\n" - " %S: show the summary of the object by default\n" - " %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n" - " %L: show the location of the object (memory address or a register name)\n" - " %#: show the number of children of the object\n" - " %T: show the type of the object\n" - "Another variable that you can use in summary strings is ${svar . This sequence works exactly like ${var, including the fact that ${*svar is an allowed sequence, but uses" - " the object's synthetic children provider instead of the actual objects. For instance, if you are using STL synthetic children providers, the following summary string would" - " count the number of actual elements stored in an std::list:\n" - "type summary add -s \"${svar%#}\" -x \"std::list<\""; +static llvm::StringRef FormatHelpTextCallback() { + static std::string help_text; + + if (!help_text.empty()) + return help_text; + + StreamString sstr; + sstr << "One of the format names (or one-character names) that can be used " + "to show a variable's value:\n"; + for (Format f = eFormatDefault; f < kNumFormats; f = Format(f + 1)) { + if (f != eFormatDefault) + sstr.PutChar('\n'); + + char format_char = FormatManager::GetFormatAsFormatChar(f); + if (format_char) + sstr.Printf("'%c' or ", format_char); + + sstr.Printf("\"%s\"", FormatManager::GetFormatAsCString(f)); + } + + sstr.Flush(); + + help_text = sstr.GetString(); + + return help_text; } -static const char * -ExprPathHelpTextCallback() -{ - return - "An expression path is the sequence of symbols that is used in C/C++ to access a member variable of an aggregate object (class).\n" - "For instance, given a class:\n" - " class foo {\n" - " int a;\n" - " int b; .\n" - " foo* next;\n" - " };\n" - "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n" - "Given that aFoo could just be any object of type foo, the string '.next->b' is the expression path, because it can be attached to any foo instance to achieve the effect.\n" - "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n" - "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n" - "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n" - "for objects of native types (int, float, char, ...) saying '[n-m]' as an expression path (where n and m are any positive integers, e.g. [3-5]) causes LLDB to extract" - " bits n thru m from the value of the variable. If n == m, [n] is also allowed as a shortcut syntax. For arrays and pointers, expression paths can only contain one index" - " and the meaning of the operation is the same as the one defined by C/C++ (item extraction). Some commands extend bitfield-like syntax for arrays and pointers with the" - " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory)."; +static llvm::StringRef LanguageTypeHelpTextCallback() { + static std::string help_text; + + if (!help_text.empty()) + return help_text; + + StreamString sstr; + sstr << "One of the following languages:\n"; + + Language::PrintAllLanguages(sstr, " ", "\n"); + + sstr.Flush(); + + help_text = sstr.GetString(); + + return help_text; } -void -CommandObject::FormatLongHelpText (Stream &output_strm, const char *long_help) -{ - CommandInterpreter& interpreter = GetCommandInterpreter(); - std::stringstream lineStream (long_help); - std::string line; - while (std::getline (lineStream, line)) { - if (line.empty()) { - output_strm << "\n"; - continue; - } - size_t result = line.find_first_not_of (" \t"); - if (result == std::string::npos) { - result = 0; - } - std::string whitespace_prefix = line.substr (0, result); - std::string remainder = line.substr (result); - interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), remainder.c_str()); - } +static llvm::StringRef SummaryStringHelpTextCallback() { + return "A summary string is a way to extract information from variables in " + "order to present them using a summary.\n" + "Summary strings contain static text, variables, scopes and control " + "sequences:\n" + " - Static text can be any sequence of non-special characters, i.e. " + "anything but '{', '}', '$', or '\\'.\n" + " - Variables are sequences of characters beginning with ${, ending " + "with } and that contain symbols in the format described below.\n" + " - Scopes are any sequence of text between { and }. Anything " + "included in a scope will only appear in the output summary if there " + "were no errors.\n" + " - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus " + "'\\$', '\\{' and '\\}'.\n" + "A summary string works by copying static text verbatim, turning " + "control sequences into their character counterpart, expanding " + "variables and trying to expand scopes.\n" + "A variable is expanded by giving it a value other than its textual " + "representation, and the way this is done depends on what comes after " + "the ${ marker.\n" + "The most common sequence if ${var followed by an expression path, " + "which is the text one would type to access a member of an aggregate " + "types, given a variable of that type" + " (e.g. if type T has a member named x, which has a member named y, " + "and if t is of type T, the expression path would be .x.y and the way " + "to fit that into a summary string would be" + " ${var.x.y}). You can also use ${*var followed by an expression path " + "and in that case the object referred by the path will be " + "dereferenced before being displayed." + " If the object is not a pointer, doing so will cause an error. For " + "additional details on expression paths, you can type 'help " + "expr-path'. \n" + "By default, summary strings attempt to display the summary for any " + "variable they reference, and if that fails the value. If neither can " + "be shown, nothing is displayed." + "In a summary string, you can also use an array index [n], or a " + "slice-like range [n-m]. This can have two different meanings " + "depending on what kind of object the expression" + " path refers to:\n" + " - if it is a scalar type (any basic type like int, float, ...) the " + "expression is a bitfield, i.e. the bits indicated by the indexing " + "operator are extracted out of the number" + " and displayed as an individual variable\n" + " - if it is an array or pointer the array items indicated by the " + "indexing operator are shown as the result of the variable. if the " + "expression is an array, real array items are" + " printed; if it is a pointer, the pointer-as-array syntax is used to " + "obtain the values (this means, the latter case can have no range " + "checking)\n" + "If you are trying to display an array for which the size is known, " + "you can also use [] instead of giving an exact range. This has the " + "effect of showing items 0 thru size - 1.\n" + "Additionally, a variable can contain an (optional) format code, as " + "in ${var.x.y%code}, where code can be any of the valid formats " + "described in 'help format', or one of the" + " special symbols only allowed as part of a variable:\n" + " %V: show the value of the object by default\n" + " %S: show the summary of the object by default\n" + " %@: show the runtime-provided object description (for " + "Objective-C, it calls NSPrintForDebugger; for C/C++ it does " + "nothing)\n" + " %L: show the location of the object (memory address or a " + "register name)\n" + " %#: show the number of children of the object\n" + " %T: show the type of the object\n" + "Another variable that you can use in summary strings is ${svar . " + "This sequence works exactly like ${var, including the fact that " + "${*svar is an allowed sequence, but uses" + " the object's synthetic children provider instead of the actual " + "objects. For instance, if you are using STL synthetic children " + "providers, the following summary string would" + " count the number of actual elements stored in an std::list:\n" + "type summary add -s \"${svar%#}\" -x \"std::list<\""; } -void -CommandObject::GenerateHelpText (CommandReturnObject &result) -{ - GenerateHelpText(result.GetOutputStream()); - - result.SetStatus (eReturnStatusSuccessFinishNoResult); +static llvm::StringRef ExprPathHelpTextCallback() { + return "An expression path is the sequence of symbols that is used in C/C++ " + "to access a member variable of an aggregate object (class).\n" + "For instance, given a class:\n" + " class foo {\n" + " int a;\n" + " int b; .\n" + " foo* next;\n" + " };\n" + "the expression to read item b in the item pointed to by next for foo " + "aFoo would be aFoo.next->b.\n" + "Given that aFoo could just be any object of type foo, the string " + "'.next->b' is the expression path, because it can be attached to any " + "foo instance to achieve the effect.\n" + "Expression paths in LLDB include dot (.) and arrow (->) operators, " + "and most commands using expression paths have ways to also accept " + "the star (*) operator.\n" + "The meaning of these operators is the same as the usual one given to " + "them by the C/C++ standards.\n" + "LLDB also has support for indexing ([ ]) in expression paths, and " + "extends the traditional meaning of the square brackets operator to " + "allow bitfield extraction:\n" + "for objects of native types (int, float, char, ...) saying '[n-m]' " + "as an expression path (where n and m are any positive integers, e.g. " + "[3-5]) causes LLDB to extract" + " bits n thru m from the value of the variable. If n == m, [n] is " + "also allowed as a shortcut syntax. For arrays and pointers, " + "expression paths can only contain one index" + " and the meaning of the operation is the same as the one defined by " + "C/C++ (item extraction). Some commands extend bitfield-like syntax " + "for arrays and pointers with the" + " meaning of array slicing (taking elements n thru m inside the array " + "or pointed-to memory)."; } -void -CommandObject::GenerateHelpText (Stream &output_strm) -{ - CommandInterpreter& interpreter = GetCommandInterpreter(); - if (WantsRawCommandString()) - { - std::string help_text(GetHelp()); - help_text.append(" Expects 'raw' input (see 'help raw-input'.)"); - interpreter.OutputFormattedHelpText(output_strm, "", "", help_text.c_str(), 1); +void CommandObject::FormatLongHelpText(Stream &output_strm, + llvm::StringRef long_help) { + CommandInterpreter &interpreter = GetCommandInterpreter(); + std::stringstream lineStream(long_help); + std::string line; + while (std::getline(lineStream, line)) { + if (line.empty()) { + output_strm << "\n"; + continue; } - else - interpreter.OutputFormattedHelpText(output_strm, "", "", GetHelp(), 1); - output_strm.Printf("\nSyntax: %s\n", GetSyntax()); - Options *options = GetOptions(); - if (options != nullptr) - { - options->GenerateOptionUsage(output_strm, this); - } - const char *long_help = GetHelpLong(); - if ((long_help != nullptr) && (strlen(long_help) > 0)) - { - FormatLongHelpText(output_strm, long_help); - } - if (!IsDashDashCommand() && options && options->NumCommandOptions() > 0) - { - if (WantsRawCommandString() && !WantsCompletion()) - { - // Emit the message about using ' -- ' between the end of the command options and the raw input - // conditionally, i.e., only if the command object does not want completion. - interpreter.OutputFormattedHelpText( - output_strm, "", "", - "\nImportant Note: Because this command takes 'raw' input, if you use any command options" - " you must use ' -- ' between the end of the command options and the beginning of the raw input.", - 1); - } - else if (GetNumArgumentEntries() > 0) - { - // Also emit a warning about using "--" in case you are using a command that takes options and arguments. - interpreter.OutputFormattedHelpText( - output_strm, "", "", "\nThis command takes options and free-form arguments. If your arguments resemble" - " option specifiers (i.e., they start with a - or --), you must use ' -- ' between" - " the end of the command options and the beginning of the arguments.", - 1); - } + size_t result = line.find_first_not_of(" \t"); + if (result == std::string::npos) { + result = 0; } + std::string whitespace_prefix = line.substr(0, result); + std::string remainder = line.substr(result); + interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), + remainder.c_str()); + } } -void -CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType ID, CommandArgumentType IDRange) -{ - CommandArgumentData id_arg; - CommandArgumentData id_range_arg; +void CommandObject::GenerateHelpText(CommandReturnObject &result) { + GenerateHelpText(result.GetOutputStream()); - // Create the first variant for the first (and only) argument for this command. - id_arg.arg_type = ID; - id_arg.arg_repetition = eArgRepeatOptional; + result.SetStatus(eReturnStatusSuccessFinishNoResult); +} - // Create the second variant for the first (and only) argument for this command. - id_range_arg.arg_type = IDRange; - id_range_arg.arg_repetition = eArgRepeatOptional; +void CommandObject::GenerateHelpText(Stream &output_strm) { + CommandInterpreter &interpreter = GetCommandInterpreter(); + if (WantsRawCommandString()) { + std::string help_text(GetHelp()); + help_text.append(" Expects 'raw' input (see 'help raw-input'.)"); + interpreter.OutputFormattedHelpText(output_strm, "", "", help_text.c_str(), + 1); + } else + interpreter.OutputFormattedHelpText(output_strm, "", "", GetHelp(), 1); + output_strm << "\nSyntax: " << GetSyntax() << "\n"; + Options *options = GetOptions(); + if (options != nullptr) { + options->GenerateOptionUsage( + output_strm, this, + GetCommandInterpreter().GetDebugger().GetTerminalWidth()); + } + llvm::StringRef long_help = GetHelpLong(); + if (!long_help.empty()) { + FormatLongHelpText(output_strm, long_help); + } + if (!IsDashDashCommand() && options && options->NumCommandOptions() > 0) { + if (WantsRawCommandString() && !WantsCompletion()) { + // Emit the message about using ' -- ' between the end of the command + // options and the raw input + // conditionally, i.e., only if the command object does not want + // completion. + interpreter.OutputFormattedHelpText( + output_strm, "", "", + "\nImportant Note: Because this command takes 'raw' input, if you " + "use any command options" + " you must use ' -- ' between the end of the command options and the " + "beginning of the raw input.", + 1); + } else if (GetNumArgumentEntries() > 0) { + // Also emit a warning about using "--" in case you are using a command + // that takes options and arguments. + interpreter.OutputFormattedHelpText( + output_strm, "", "", + "\nThis command takes options and free-form arguments. If your " + "arguments resemble" + " option specifiers (i.e., they start with a - or --), you must use " + "' -- ' between" + " the end of the command options and the beginning of the arguments.", + 1); + } + } +} - // The first (and only) argument for this command could be either an id or an id_range. - // Push both variants into the entry for the first argument for this command. - arg.push_back(id_arg); - arg.push_back(id_range_arg); +void CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, + CommandArgumentType ID, + CommandArgumentType IDRange) { + CommandArgumentData id_arg; + CommandArgumentData id_range_arg; + + // Create the first variant for the first (and only) argument for this + // command. + id_arg.arg_type = ID; + id_arg.arg_repetition = eArgRepeatOptional; + + // Create the second variant for the first (and only) argument for this + // command. + id_range_arg.arg_type = IDRange; + id_range_arg.arg_repetition = eArgRepeatOptional; + + // The first (and only) argument for this command could be either an id or an + // id_range. + // Push both variants into the entry for the first argument for this command. + arg.push_back(id_arg); + arg.push_back(id_range_arg); } -const char * -CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) -{ - assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentTypeAsCString"); - return g_arguments_data[arg_type].arg_name; +const char *CommandObject::GetArgumentTypeAsCString( + const lldb::CommandArgumentType arg_type) { + assert(arg_type < eArgTypeLastArg && + "Invalid argument type passed to GetArgumentTypeAsCString"); + return g_arguments_data[arg_type].arg_name; } -const char * -CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type) -{ - assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentDescriptionAsCString"); - return g_arguments_data[arg_type].help_text; +const char *CommandObject::GetArgumentDescriptionAsCString( + const lldb::CommandArgumentType arg_type) { + assert(arg_type < eArgTypeLastArg && + "Invalid argument type passed to GetArgumentDescriptionAsCString"); + return g_arguments_data[arg_type].help_text; } -Target * -CommandObject::GetDummyTarget() -{ - return m_interpreter.GetDebugger().GetDummyTarget(); +Target *CommandObject::GetDummyTarget() { + return m_interpreter.GetDebugger().GetDummyTarget(); } -Target * -CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) -{ - return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy); +Target *CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) { + return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy); } -Thread * -CommandObject::GetDefaultThread() -{ - Thread *thread_to_use = m_exe_ctx.GetThreadPtr(); - if (thread_to_use) - return thread_to_use; - - Process *process = m_exe_ctx.GetProcessPtr(); - if (!process) - { - Target *target = m_exe_ctx.GetTargetPtr(); - if (!target) - { - target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - } - if (target) - process = target->GetProcessSP().get(); +Thread *CommandObject::GetDefaultThread() { + Thread *thread_to_use = m_exe_ctx.GetThreadPtr(); + if (thread_to_use) + return thread_to_use; + + Process *process = m_exe_ctx.GetProcessPtr(); + if (!process) { + Target *target = m_exe_ctx.GetTargetPtr(); + if (!target) { + target = m_interpreter.GetDebugger().GetSelectedTarget().get(); } + if (target) + process = target->GetProcessSP().get(); + } - if (process) - return process->GetThreadList().GetSelectedThread().get(); - else - return nullptr; + if (process) + return process->GetThreadList().GetSelectedThread().get(); + else + return nullptr; } -bool -CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result) -{ - bool handled = false; - Args cmd_args (args_string); - if (HasOverrideCallback()) - { - Args full_args (GetCommandName ()); - full_args.AppendArguments(cmd_args); - handled = InvokeOverrideCallback (full_args.GetConstArgumentVector(), result); +bool CommandObjectParsed::Execute(const char *args_string, + CommandReturnObject &result) { + bool handled = false; + Args cmd_args(args_string); + if (HasOverrideCallback()) { + Args full_args(GetCommandName()); + full_args.AppendArguments(cmd_args); + handled = + InvokeOverrideCallback(full_args.GetConstArgumentVector(), result); + } + if (!handled) { + for (auto entry : llvm::enumerate(cmd_args.entries())) { + if (!entry.Value.ref.empty() && entry.Value.ref.front() == '`') { + cmd_args.ReplaceArgumentAtIndex( + entry.Index, + m_interpreter.ProcessEmbeddedScriptCommands(entry.Value.c_str())); + } } - if (!handled) - { - for (size_t i = 0; i < cmd_args.GetArgumentCount(); ++i) - { - const char *tmp_str = cmd_args.GetArgumentAtIndex (i); - if (tmp_str[0] == '`') // back-quote - cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str)); - } - - if (CheckRequirements(result)) - { - if (ParseOptions (cmd_args, result)) - { - // Call the command-specific version of 'Execute', passing it the already processed arguments. - handled = DoExecute (cmd_args, result); - } - } - Cleanup(); + if (CheckRequirements(result)) { + if (ParseOptions(cmd_args, result)) { + // Call the command-specific version of 'Execute', passing it the + // already processed arguments. + handled = DoExecute(cmd_args, result); + } } - return handled; + + Cleanup(); + } + return handled; } -bool -CommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result) -{ - bool handled = false; - if (HasOverrideCallback()) - { - std::string full_command (GetCommandName ()); - full_command += ' '; - full_command += args_string; - const char *argv[2] = { nullptr, nullptr }; - argv[0] = full_command.c_str(); - handled = InvokeOverrideCallback (argv, result); - } - if (!handled) - { - if (CheckRequirements(result)) - handled = DoExecute (args_string, result); - - Cleanup(); - } - return handled; +bool CommandObjectRaw::Execute(const char *args_string, + CommandReturnObject &result) { + bool handled = false; + if (HasOverrideCallback()) { + std::string full_command(GetCommandName()); + full_command += ' '; + full_command += args_string; + const char *argv[2] = {nullptr, nullptr}; + argv[0] = full_command.c_str(); + handled = InvokeOverrideCallback(argv, result); + } + if (!handled) { + if (CheckRequirements(result)) + handled = DoExecute(args_string, result); + + Cleanup(); + } + return handled; } -static -const char *arch_helper() -{ - static StreamString g_archs_help; - if (g_archs_help.Empty()) - { - StringList archs; - ArchSpec::AutoComplete(nullptr, archs); - g_archs_help.Printf("These are the supported architecture names:\n"); - archs.Join("\n", g_archs_help); - } - return g_archs_help.GetData(); +static llvm::StringRef arch_helper() { + static StreamString g_archs_help; + if (g_archs_help.Empty()) { + StringList archs; + ArchSpec::AutoComplete(llvm::StringRef(), archs); + g_archs_help.Printf("These are the supported architecture names:\n"); + archs.Join("\n", g_archs_help); + } + return g_archs_help.GetString(); } CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { @@ -1191,12 +1117,10 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { // clang-format on }; -const CommandObject::ArgumentTableEntry* -CommandObject::GetArgumentTable () -{ - // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration - assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg); - return CommandObject::g_arguments_data; +const CommandObject::ArgumentTableEntry *CommandObject::GetArgumentTable() { + // If this assertion fires, then the table above is out of date with the + // CommandArgumentType enumeration + assert((sizeof(CommandObject::g_arguments_data) / + sizeof(CommandObject::ArgumentTableEntry)) == eArgTypeLastArg); + return CommandObject::g_arguments_data; } - - diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp index 1c3c3cd..79d3bb1 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp @@ -22,129 +22,100 @@ using namespace lldb_private; //---------------------------------------------------------------------- // CommandObjectRegexCommand constructor //---------------------------------------------------------------------- -CommandObjectRegexCommand::CommandObjectRegexCommand -( - CommandInterpreter &interpreter, - const char *name, - const char *help, - const char *syntax, - uint32_t max_matches, - uint32_t completion_type_mask, - bool is_removable -) : - CommandObjectRaw (interpreter, name, help, syntax), - m_max_matches (max_matches), - m_completion_type_mask (completion_type_mask), - m_entries (), - m_is_removable (is_removable) -{ -} +CommandObjectRegexCommand::CommandObjectRegexCommand( + CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help, + llvm::StringRef syntax, uint32_t max_matches, uint32_t completion_type_mask, + bool is_removable) + : CommandObjectRaw(interpreter, name, help, syntax), + m_max_matches(max_matches), m_completion_type_mask(completion_type_mask), + m_entries(), m_is_removable(is_removable) {} //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -CommandObjectRegexCommand::~CommandObjectRegexCommand() -{ -} - +CommandObjectRegexCommand::~CommandObjectRegexCommand() {} -bool -CommandObjectRegexCommand::DoExecute -( - const char *command, - CommandReturnObject &result -) -{ - if (command) - { - EntryCollection::const_iterator pos, end = m_entries.end(); - for (pos = m_entries.begin(); pos != end; ++pos) - { - RegularExpression::Match regex_match(m_max_matches); +bool CommandObjectRegexCommand::DoExecute(const char *command, + CommandReturnObject &result) { + if (command) { + EntryCollection::const_iterator pos, end = m_entries.end(); + for (pos = m_entries.begin(); pos != end; ++pos) { + RegularExpression::Match regex_match(m_max_matches); - if (pos->regex.Execute (command, ®ex_match)) - { - std::string new_command(pos->command); - std::string match_str; - char percent_var[8]; - size_t idx, percent_var_idx; - for (uint32_t match_idx=1; match_idx <= m_max_matches; ++match_idx) - { - if (regex_match.GetMatchAtIndex (command, match_idx, match_str)) - { - const int percent_var_len = ::snprintf (percent_var, sizeof(percent_var), "%%%u", match_idx); - for (idx = 0; (percent_var_idx = new_command.find(percent_var, idx)) != std::string::npos; ) - { - new_command.erase(percent_var_idx, percent_var_len); - new_command.insert(percent_var_idx, match_str); - idx += percent_var_idx + match_str.size(); - } - } - } - // Interpret the new command and return this as the result! - if (m_interpreter.GetExpandRegexAliases()) - result.GetOutputStream().Printf("%s\n", new_command.c_str()); - // Pass in true for "no context switching". The command that called us should have set up the context - // appropriately, we shouldn't have to redo that. - return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result, nullptr, true, true); + if (pos->regex.Execute(command, ®ex_match)) { + std::string new_command(pos->command); + std::string match_str; + char percent_var[8]; + size_t idx, percent_var_idx; + for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) { + if (regex_match.GetMatchAtIndex(command, match_idx, match_str)) { + const int percent_var_len = + ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx); + for (idx = 0; (percent_var_idx = new_command.find( + percent_var, idx)) != std::string::npos;) { + new_command.erase(percent_var_idx, percent_var_len); + new_command.insert(percent_var_idx, match_str); + idx += percent_var_idx + match_str.size(); } + } } - result.SetStatus(eReturnStatusFailed); - if (GetSyntax() != nullptr) - result.AppendError (GetSyntax()); - else - result.AppendErrorWithFormat ("Command contents '%s' failed to match any regular expression in the '%s' regex command.\n", - command, - m_cmd_name.c_str()); - return false; + // Interpret the new command and return this as the result! + if (m_interpreter.GetExpandRegexAliases()) + result.GetOutputStream().Printf("%s\n", new_command.c_str()); + // Pass in true for "no context switching". The command that called us + // should have set up the context + // appropriately, we shouldn't have to redo that. + return m_interpreter.HandleCommand(new_command.c_str(), + eLazyBoolCalculate, result, nullptr, + true, true); + } } - result.AppendError("empty command passed to regular expression command"); result.SetStatus(eReturnStatusFailed); + if (!GetSyntax().empty()) + result.AppendError(GetSyntax()); + else + result.AppendErrorWithFormat("Command contents '%s' failed to match any " + "regular expression in the '%s' regex " + "command.\n", + command, m_cmd_name.c_str()); return false; + } + result.AppendError("empty command passed to regular expression command"); + result.SetStatus(eReturnStatusFailed); + return false; } - -bool -CommandObjectRegexCommand::AddRegexCommand (const char *re_cstr, const char *command_cstr) -{ - m_entries.resize(m_entries.size() + 1); - // Only add the regular expression if it compiles - if (m_entries.back().regex.Compile (re_cstr)) - { - m_entries.back().command.assign (command_cstr); - return true; - } - // The regex didn't compile... - m_entries.pop_back(); - return false; +bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr, + const char *command_cstr) { + m_entries.resize(m_entries.size() + 1); + // Only add the regular expression if it compiles + if (m_entries.back().regex.Compile( + llvm::StringRef::withNullAsEmpty(re_cstr))) { + m_entries.back().command.assign(command_cstr); + return true; + } + // The regex didn't compile... + m_entries.pop_back(); + return false; } -int -CommandObjectRegexCommand::HandleCompletion (Args &input, - int &cursor_index, - int &cursor_char_position, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - if (m_completion_type_mask) - { - std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position); - CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, - m_completion_type_mask, - completion_str.c_str(), - match_start_point, - max_return_elements, - nullptr, - word_complete, - matches); - return matches.GetSize(); - } - else - { - matches.Clear(); - word_complete = false; - } - return 0; +int CommandObjectRegexCommand::HandleCompletion(Args &input, int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) { + if (m_completion_type_mask) { + std::string completion_str(input.GetArgumentAtIndex(cursor_index), + cursor_char_position); + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), m_completion_type_mask, completion_str.c_str(), + match_start_point, max_return_elements, nullptr, word_complete, + matches); + return matches.GetSize(); + } else { + matches.Clear(); + word_complete = false; + } + return 0; } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.cpp index e7de490..0891298 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.cpp @@ -30,61 +30,57 @@ using namespace lldb_private; // CommandObjectScript //------------------------------------------------------------------------- -CommandObjectScript::CommandObjectScript(CommandInterpreter &interpreter, ScriptLanguage script_lang) - : CommandObjectRaw(interpreter, "script", "Invoke the script interpreter with provided code and display any " - "results. Start the interactive interpreter if no code is supplied.", - "script [<script-code>]") -{ -} +CommandObjectScript::CommandObjectScript(CommandInterpreter &interpreter, + ScriptLanguage script_lang) + : CommandObjectRaw( + interpreter, "script", + "Invoke the script interpreter with provided code and display any " + "results. Start the interactive interpreter if no code is supplied.", + "script [<script-code>]") {} -CommandObjectScript::~CommandObjectScript () -{ -} +CommandObjectScript::~CommandObjectScript() {} -bool -CommandObjectScript::DoExecute -( - const char *command, - CommandReturnObject &result -) -{ +bool CommandObjectScript::DoExecute(const char *command, + CommandReturnObject &result) { #ifdef LLDB_DISABLE_PYTHON - // if we ever support languages other than Python this simple #ifdef won't work - result.AppendError("your copy of LLDB does not support scripting."); - result.SetStatus (eReturnStatusFailed); - return false; + // if we ever support languages other than Python this simple #ifdef won't + // work + result.AppendError("your copy of LLDB does not support scripting."); + result.SetStatus(eReturnStatusFailed); + return false; #else - if (m_interpreter.GetDebugger().GetScriptLanguage() == lldb::eScriptLanguageNone) - { - result.AppendError("the script-lang setting is set to none - scripting not available"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - ScriptInterpreter *script_interpreter = m_interpreter.GetScriptInterpreter (); - - if (script_interpreter == nullptr) - { - result.AppendError("no script interpreter"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - DataVisualization::ForceUpdate(); // script might change Python code we use for formatting.. make sure we keep up to date with it - - if (command == nullptr || command[0] == '\0') - { - script_interpreter->ExecuteInterpreterLoop (); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } - - // We can do better when reporting the status of one-liner script execution. - if (script_interpreter->ExecuteOneLine (command, &result)) - result.SetStatus(eReturnStatusSuccessFinishNoResult); - else - result.SetStatus(eReturnStatusFailed); + if (m_interpreter.GetDebugger().GetScriptLanguage() == + lldb::eScriptLanguageNone) { + result.AppendError( + "the script-lang setting is set to none - scripting not available"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + ScriptInterpreter *script_interpreter = m_interpreter.GetScriptInterpreter(); + if (script_interpreter == nullptr) { + result.AppendError("no script interpreter"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + DataVisualization::ForceUpdate(); // script might change Python code we use + // for formatting.. make sure we keep up to + // date with it + + if (command == nullptr || command[0] == '\0') { + script_interpreter->ExecuteInterpreterLoop(); + result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); + } + + // We can do better when reporting the status of one-liner script execution. + if (script_interpreter->ExecuteOneLine(command, &result)) + result.SetStatus(eReturnStatusSuccessFinishNoResult); + else + result.SetStatus(eReturnStatusFailed); + + return result.Succeeded(); #endif } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.h b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.h index 5365aaa..2c05ca9 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.h +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.h @@ -22,17 +22,15 @@ namespace lldb_private { // CommandObjectScript //------------------------------------------------------------------------- -class CommandObjectScript : public CommandObjectRaw -{ +class CommandObjectScript : public CommandObjectRaw { public: - CommandObjectScript(CommandInterpreter &interpreter, - lldb::ScriptLanguage script_lang); + CommandObjectScript(CommandInterpreter &interpreter, + lldb::ScriptLanguage script_lang); - ~CommandObjectScript() override; + ~CommandObjectScript() override; protected: - bool - DoExecute(const char *command, CommandReturnObject &result) override; + bool DoExecute(const char *command, CommandReturnObject &result) override; }; } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandOptionValidators.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandOptionValidators.cpp index 7d66de5..1e614a9 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandOptionValidators.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandOptionValidators.cpp @@ -15,25 +15,23 @@ using namespace lldb; using namespace lldb_private; -bool PosixPlatformCommandOptionValidator::IsValid(Platform &platform, const ExecutionContext &target) const -{ - llvm::Triple::OSType os = platform.GetSystemArchitecture().GetTriple().getOS(); - switch (os) - { - // Are there any other platforms that are not POSIX-compatible? - case llvm::Triple::Win32: - return false; - default: - return true; - } +bool PosixPlatformCommandOptionValidator::IsValid( + Platform &platform, const ExecutionContext &target) const { + llvm::Triple::OSType os = + platform.GetSystemArchitecture().GetTriple().getOS(); + switch (os) { + // Are there any other platforms that are not POSIX-compatible? + case llvm::Triple::Win32: + return false; + default: + return true; + } } -const char* PosixPlatformCommandOptionValidator::ShortConditionString() const -{ - return "POSIX"; +const char *PosixPlatformCommandOptionValidator::ShortConditionString() const { + return "POSIX"; } -const char* PosixPlatformCommandOptionValidator::LongConditionString() const -{ - return "Option only valid for POSIX-compliant hosts."; +const char *PosixPlatformCommandOptionValidator::LongConditionString() const { + return "Option only valid for POSIX-compliant hosts."; } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandReturnObject.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandReturnObject.cpp index b083c7f..72e66aa 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandReturnObject.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandReturnObject.cpp @@ -19,218 +19,157 @@ using namespace lldb; using namespace lldb_private; -static void -DumpStringToStreamWithNewline (Stream &strm, const std::string &s, bool add_newline_if_empty) -{ - bool add_newline = false; - if (s.empty()) - { - add_newline = add_newline_if_empty; - } - else - { - // We already checked for empty above, now make sure there is a newline - // in the error, and if there isn't one, add one. - strm.Write(s.c_str(), s.size()); - - const char last_char = *s.rbegin(); - add_newline = last_char != '\n' && last_char != '\r'; - - } - if (add_newline) - strm.EOL(); -} - - -CommandReturnObject::CommandReturnObject () : - m_out_stream (), - m_err_stream (), - m_status (eReturnStatusStarted), - m_did_change_process_state (false), - m_interactive (true), - m_abnormal_stop_was_expected(false) -{ -} - -CommandReturnObject::~CommandReturnObject () -{ -} - -void -CommandReturnObject::AppendErrorWithFormat (const char *format, ...) -{ - if (!format) - return; - va_list args; - va_start (args, format); - StreamString sstrm; - sstrm.PrintfVarArg(format, args); - va_end (args); - - - const std::string &s = sstrm.GetString(); - if (!s.empty()) - { - Stream &error_strm = GetErrorStream(); - error_strm.PutCString ("error: "); - DumpStringToStreamWithNewline (error_strm, s, false); - } -} - -void -CommandReturnObject::AppendMessageWithFormat (const char *format, ...) -{ - if (!format) - return; - va_list args; - va_start (args, format); - StreamString sstrm; - sstrm.PrintfVarArg(format, args); - va_end (args); - - GetOutputStream().Printf("%s", sstrm.GetData()); -} - -void -CommandReturnObject::AppendWarningWithFormat (const char *format, ...) -{ - if (!format) - return; - va_list args; - va_start (args, format); - StreamString sstrm; - sstrm.PrintfVarArg(format, args); - va_end (args); - - GetErrorStream().Printf("warning: %s", sstrm.GetData()); -} - -void -CommandReturnObject::AppendMessage (const char *in_string) -{ - if (!in_string) - return; - GetOutputStream().Printf("%s\n", in_string); -} - -void -CommandReturnObject::AppendWarning (const char *in_string) -{ - if (!in_string || *in_string == '\0') - return; - GetErrorStream().Printf("warning: %s\n", in_string); +static void DumpStringToStreamWithNewline(Stream &strm, const std::string &s, + bool add_newline_if_empty) { + bool add_newline = false; + if (s.empty()) { + add_newline = add_newline_if_empty; + } else { + // We already checked for empty above, now make sure there is a newline + // in the error, and if there isn't one, add one. + strm.Write(s.c_str(), s.size()); + + const char last_char = *s.rbegin(); + add_newline = last_char != '\n' && last_char != '\r'; + } + if (add_newline) + strm.EOL(); +} + +CommandReturnObject::CommandReturnObject() + : m_out_stream(), m_err_stream(), m_status(eReturnStatusStarted), + m_did_change_process_state(false), m_interactive(true), + m_abnormal_stop_was_expected(false) {} + +CommandReturnObject::~CommandReturnObject() {} + +void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) { + if (!format) + return; + va_list args; + va_start(args, format); + StreamString sstrm; + sstrm.PrintfVarArg(format, args); + va_end(args); + + const std::string &s = sstrm.GetString(); + if (!s.empty()) { + Stream &error_strm = GetErrorStream(); + error_strm.PutCString("error: "); + DumpStringToStreamWithNewline(error_strm, s, false); + } +} + +void CommandReturnObject::AppendMessageWithFormat(const char *format, ...) { + if (!format) + return; + va_list args; + va_start(args, format); + StreamString sstrm; + sstrm.PrintfVarArg(format, args); + va_end(args); + + GetOutputStream() << sstrm.GetString(); +} + +void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) { + if (!format) + return; + va_list args; + va_start(args, format); + StreamString sstrm; + sstrm.PrintfVarArg(format, args); + va_end(args); + + GetErrorStream() << "warning: " << sstrm.GetString(); +} + +void CommandReturnObject::AppendMessage(llvm::StringRef in_string) { + if (in_string.empty()) + return; + GetOutputStream() << in_string << "\n"; +} + +void CommandReturnObject::AppendWarning(llvm::StringRef in_string) { + if (in_string.empty()) + return; + GetErrorStream() << "warning: " << in_string << "\n"; } // Similar to AppendWarning, but do not prepend 'warning: ' to message, and // don't append "\n" to the end of it. -void -CommandReturnObject::AppendRawWarning (const char *in_string) -{ - if (in_string && in_string[0]) - GetErrorStream().PutCString(in_string); +void CommandReturnObject::AppendRawWarning(llvm::StringRef in_string) { + if (in_string.empty()) + return; + GetErrorStream() << in_string; } -void -CommandReturnObject::AppendError (const char *in_string) -{ - if (!in_string || *in_string == '\0') - return; - GetErrorStream().Printf ("error: %s\n", in_string); +void CommandReturnObject::AppendError(llvm::StringRef in_string) { + if (in_string.empty()) + return; + GetErrorStream() << "error: " << in_string << "\n"; } -void -CommandReturnObject::SetError (const Error &error, const char *fallback_error_cstr) -{ - const char *error_cstr = error.AsCString(); - if (error_cstr == nullptr) - error_cstr = fallback_error_cstr; - SetError(error_cstr); +void CommandReturnObject::SetError(const Error &error, + const char *fallback_error_cstr) { + const char *error_cstr = error.AsCString(); + if (error_cstr == nullptr) + error_cstr = fallback_error_cstr; + SetError(error_cstr); } -void -CommandReturnObject::SetError (const char *error_cstr) -{ - if (error_cstr) - { - AppendError (error_cstr); - SetStatus (eReturnStatusFailed); - } +void CommandReturnObject::SetError(llvm::StringRef error_str) { + if (error_str.empty()) + return; + + AppendError(error_str); + SetStatus(eReturnStatusFailed); } // Similar to AppendError, but do not prepend 'Error: ' to message, and // don't append "\n" to the end of it. -void -CommandReturnObject::AppendRawError (const char *in_string) -{ - if (in_string && in_string[0]) - GetErrorStream().PutCString(in_string); -} - -void -CommandReturnObject::SetStatus (ReturnStatus status) -{ - m_status = status; -} - -ReturnStatus -CommandReturnObject::GetStatus () -{ - return m_status; +void CommandReturnObject::AppendRawError(llvm::StringRef in_string) { + if (in_string.empty()) + return; + GetErrorStream() << in_string; } -bool -CommandReturnObject::Succeeded () -{ - return m_status <= eReturnStatusSuccessContinuingResult; -} +void CommandReturnObject::SetStatus(ReturnStatus status) { m_status = status; } -bool -CommandReturnObject::HasResult () -{ - return (m_status == eReturnStatusSuccessFinishResult || - m_status == eReturnStatusSuccessContinuingResult); -} +ReturnStatus CommandReturnObject::GetStatus() { return m_status; } -void -CommandReturnObject::Clear() -{ - lldb::StreamSP stream_sp; - stream_sp = m_out_stream.GetStreamAtIndex (eStreamStringIndex); - if (stream_sp) - static_cast<StreamString *>(stream_sp.get())->Clear(); - stream_sp = m_err_stream.GetStreamAtIndex (eStreamStringIndex); - if (stream_sp) - static_cast<StreamString *>(stream_sp.get())->Clear(); - m_status = eReturnStatusStarted; - m_did_change_process_state = false; - m_interactive = true; +bool CommandReturnObject::Succeeded() { + return m_status <= eReturnStatusSuccessContinuingResult; } -bool -CommandReturnObject::GetDidChangeProcessState () -{ - return m_did_change_process_state; +bool CommandReturnObject::HasResult() { + return (m_status == eReturnStatusSuccessFinishResult || + m_status == eReturnStatusSuccessContinuingResult); } -void -CommandReturnObject::SetDidChangeProcessState (bool b) -{ - m_did_change_process_state = b; +void CommandReturnObject::Clear() { + lldb::StreamSP stream_sp; + stream_sp = m_out_stream.GetStreamAtIndex(eStreamStringIndex); + if (stream_sp) + static_cast<StreamString *>(stream_sp.get())->Clear(); + stream_sp = m_err_stream.GetStreamAtIndex(eStreamStringIndex); + if (stream_sp) + static_cast<StreamString *>(stream_sp.get())->Clear(); + m_status = eReturnStatusStarted; + m_did_change_process_state = false; + m_interactive = true; } - -bool -CommandReturnObject::GetInteractive () const -{ - return m_interactive; +bool CommandReturnObject::GetDidChangeProcessState() { + return m_did_change_process_state; } -void -CommandReturnObject::SetInteractive (bool b) -{ - m_interactive = b; +void CommandReturnObject::SetDidChangeProcessState(bool b) { + m_did_change_process_state = b; } +bool CommandReturnObject::GetInteractive() const { return m_interactive; } +void CommandReturnObject::SetInteractive(bool b) { m_interactive = b; } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupArchitecture.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupArchitecture.cpp index 3a45409..51245a8 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupArchitecture.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupArchitecture.cpp @@ -18,69 +18,49 @@ using namespace lldb; using namespace lldb_private; -OptionGroupArchitecture::OptionGroupArchitecture() : - m_arch_str () -{ -} +OptionGroupArchitecture::OptionGroupArchitecture() : m_arch_str() {} -OptionGroupArchitecture::~OptionGroupArchitecture () -{ -} +OptionGroupArchitecture::~OptionGroupArchitecture() {} -static OptionDefinition -g_option_table[] = -{ - { LLDB_OPT_SET_1 , false, "arch" , 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture , "Specify the architecture for the target."}, +static OptionDefinition g_option_table[] = { + {LLDB_OPT_SET_1, false, "arch", 'a', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeArchitecture, + "Specify the architecture for the target."}, }; -uint32_t -OptionGroupArchitecture::GetNumDefinitions () -{ - return llvm::array_lengthof(g_option_table); -} - -const OptionDefinition * -OptionGroupArchitecture::GetDefinitions () -{ - return g_option_table; +llvm::ArrayRef<OptionDefinition> OptionGroupArchitecture::GetDefinitions() { + return llvm::makeArrayRef(g_option_table); } -bool -OptionGroupArchitecture::GetArchitecture (Platform *platform, ArchSpec &arch) -{ - if (m_arch_str.empty()) - arch.Clear(); - else - arch.SetTriple(m_arch_str.c_str(), platform); - return arch.IsValid(); +bool OptionGroupArchitecture::GetArchitecture(Platform *platform, + ArchSpec &arch) { + if (m_arch_str.empty()) + arch.Clear(); + else + arch.SetTriple(m_arch_str.c_str(), platform); + return arch.IsValid(); } +Error OptionGroupArchitecture::SetOptionValue( + uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error; + const int short_option = g_option_table[option_idx].short_option; -Error -OptionGroupArchitecture::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - const int short_option = g_option_table[option_idx].short_option; - - switch (short_option) - { - case 'a': - m_arch_str.assign (option_arg); - break; + switch (short_option) { + case 'a': + m_arch_str.assign(option_arg); + break; - default: - error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); - break; - } + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); + break; + } - return error; + return error; } -void -OptionGroupArchitecture::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_arch_str.clear(); +void OptionGroupArchitecture::OptionParsingStarting( + ExecutionContext *execution_context) { + m_arch_str.clear(); } - diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupBoolean.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupBoolean.cpp index 6bd2743..10b9746 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupBoolean.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupBoolean.cpp @@ -17,52 +17,44 @@ using namespace lldb; using namespace lldb_private; -OptionGroupBoolean::OptionGroupBoolean (uint32_t usage_mask, - bool required, - const char *long_option, - int short_option, - const char *usage_text, - bool default_value, - bool no_argument_toggle_default) : - m_value (default_value, default_value) -{ - m_option_definition.usage_mask = usage_mask; - m_option_definition.required = required; - m_option_definition.long_option = long_option; - m_option_definition.short_option = short_option; - m_option_definition.validator = nullptr; - m_option_definition.option_has_arg = no_argument_toggle_default ? OptionParser::eNoArgument : OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; - m_option_definition.completion_type = 0; - m_option_definition.argument_type = eArgTypeBoolean; - m_option_definition.usage_text = usage_text; +OptionGroupBoolean::OptionGroupBoolean(uint32_t usage_mask, bool required, + const char *long_option, + int short_option, const char *usage_text, + bool default_value, + bool no_argument_toggle_default) + : m_value(default_value, default_value) { + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.validator = nullptr; + m_option_definition.option_has_arg = no_argument_toggle_default + ? OptionParser::eNoArgument + : OptionParser::eRequiredArgument; + m_option_definition.enum_values = nullptr; + m_option_definition.completion_type = 0; + m_option_definition.argument_type = eArgTypeBoolean; + m_option_definition.usage_text = usage_text; } -OptionGroupBoolean::~OptionGroupBoolean () -{ -} +OptionGroupBoolean::~OptionGroupBoolean() {} -Error -OptionGroupBoolean::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - if (m_option_definition.option_has_arg == OptionParser::eNoArgument) - { - // Not argument, toggle the default value and mark the option as having been set - m_value.SetCurrentValue (!m_value.GetDefaultValue()); - m_value.SetOptionWasSet (); - } - else - { - error = m_value.SetValueFromString (option_arg); - } - return error; +Error OptionGroupBoolean::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_value, + ExecutionContext *execution_context) { + Error error; + if (m_option_definition.option_has_arg == OptionParser::eNoArgument) { + // Not argument, toggle the default value and mark the option as having been + // set + m_value.SetCurrentValue(!m_value.GetDefaultValue()); + m_value.SetOptionWasSet(); + } else { + error = m_value.SetValueFromString(option_value); + } + return error; } -void -OptionGroupBoolean::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_value.Clear(); +void OptionGroupBoolean::OptionParsingStarting( + ExecutionContext *execution_context) { + m_value.Clear(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFile.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFile.cpp index a4b5640..0c0b068 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFile.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFile.cpp @@ -17,83 +17,65 @@ using namespace lldb; using namespace lldb_private; -OptionGroupFile::OptionGroupFile (uint32_t usage_mask, - bool required, - const char *long_option, - int short_option, - uint32_t completion_type, - lldb::CommandArgumentType argument_type, - const char *usage_text) : - m_file () -{ - m_option_definition.usage_mask = usage_mask; - m_option_definition.required = required; - m_option_definition.long_option = long_option; - m_option_definition.short_option = short_option; - m_option_definition.validator = nullptr; - m_option_definition.option_has_arg = OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; - m_option_definition.completion_type = completion_type; - m_option_definition.argument_type = argument_type; - m_option_definition.usage_text = usage_text; +OptionGroupFile::OptionGroupFile(uint32_t usage_mask, bool required, + const char *long_option, int short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text) + : m_file() { + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.validator = nullptr; + m_option_definition.option_has_arg = OptionParser::eRequiredArgument; + m_option_definition.enum_values = nullptr; + m_option_definition.completion_type = completion_type; + m_option_definition.argument_type = argument_type; + m_option_definition.usage_text = usage_text; } -OptionGroupFile::~OptionGroupFile () -{ -} +OptionGroupFile::~OptionGroupFile() {} -Error -OptionGroupFile::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error (m_file.SetValueFromString (option_arg)); - return error; +Error OptionGroupFile::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error(m_file.SetValueFromString(option_arg)); + return error; } -void -OptionGroupFile::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_file.Clear(); +void OptionGroupFile::OptionParsingStarting( + ExecutionContext *execution_context) { + m_file.Clear(); } - -OptionGroupFileList::OptionGroupFileList (uint32_t usage_mask, - bool required, - const char *long_option, - int short_option, - uint32_t completion_type, - lldb::CommandArgumentType argument_type, - const char *usage_text) : - m_file_list () -{ - m_option_definition.usage_mask = usage_mask; - m_option_definition.required = required; - m_option_definition.long_option = long_option; - m_option_definition.short_option = short_option; - m_option_definition.validator = nullptr; - m_option_definition.option_has_arg = OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; - m_option_definition.completion_type = completion_type; - m_option_definition.argument_type = argument_type; - m_option_definition.usage_text = usage_text; +OptionGroupFileList::OptionGroupFileList( + uint32_t usage_mask, bool required, const char *long_option, + int short_option, uint32_t completion_type, + lldb::CommandArgumentType argument_type, const char *usage_text) + : m_file_list() { + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.validator = nullptr; + m_option_definition.option_has_arg = OptionParser::eRequiredArgument; + m_option_definition.enum_values = nullptr; + m_option_definition.completion_type = completion_type; + m_option_definition.argument_type = argument_type; + m_option_definition.usage_text = usage_text; } -OptionGroupFileList::~OptionGroupFileList () -{ -} +OptionGroupFileList::~OptionGroupFileList() {} -Error -OptionGroupFileList::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error (m_file_list.SetValueFromString (option_arg)); - return error; +Error OptionGroupFileList::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_value, + ExecutionContext *execution_context) { + Error error(m_file_list.SetValueFromString(option_value)); + return error; } -void -OptionGroupFileList::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_file_list.Clear(); +void OptionGroupFileList::OptionParsingStarting( + ExecutionContext *execution_context) { + m_file_list.Clear(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFormat.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFormat.cpp index 08ff262..c97d16a 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFormat.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFormat.cpp @@ -22,228 +22,252 @@ using namespace lldb; using namespace lldb_private; -OptionGroupFormat::OptionGroupFormat (lldb::Format default_format, - uint64_t default_byte_size, - uint64_t default_count) : - m_format (default_format, default_format), - m_byte_size (default_byte_size, default_byte_size), - m_count (default_count, default_count), - m_prev_gdb_format('x'), - m_prev_gdb_size('w') -{ -} +OptionGroupFormat::OptionGroupFormat(lldb::Format default_format, + uint64_t default_byte_size, + uint64_t default_count) + : m_format(default_format, default_format), + m_byte_size(default_byte_size, default_byte_size), + m_count(default_count, default_count), m_prev_gdb_format('x'), + m_prev_gdb_size('w') {} -OptionGroupFormat::~OptionGroupFormat () -{ -} +OptionGroupFormat::~OptionGroupFormat() {} -static OptionDefinition -g_option_table[] = -{ -{ LLDB_OPT_SET_1, false, "format" ,'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFormat , "Specify a format to be used for display."}, -{ LLDB_OPT_SET_2, false, "gdb-format",'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeGDBFormat, "Specify a format using a GDB format specifier string."}, -{ LLDB_OPT_SET_3, false, "size" ,'s', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeByteSize , "The size in bytes to use when displaying with the selected format."}, -{ LLDB_OPT_SET_4, false, "count" ,'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount , "The number of total items to display."}, +static OptionDefinition g_option_table[] = { + {LLDB_OPT_SET_1, false, "format", 'f', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeFormat, + "Specify a format to be used for display."}, + {LLDB_OPT_SET_2, false, "gdb-format", 'G', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeGDBFormat, + "Specify a format using a GDB format specifier string."}, + {LLDB_OPT_SET_3, false, "size", 's', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeByteSize, + "The size in bytes to use when displaying with the selected format."}, + {LLDB_OPT_SET_4, false, "count", 'c', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeCount, + "The number of total items to display."}, }; -uint32_t -OptionGroupFormat::GetNumDefinitions () -{ - if (m_byte_size.GetDefaultValue() < UINT64_MAX) - { - if (m_count.GetDefaultValue() < UINT64_MAX) - return 4; - else - return 3; - } - return 2; +llvm::ArrayRef<OptionDefinition> OptionGroupFormat::GetDefinitions() { + auto result = llvm::makeArrayRef(g_option_table); + if (m_byte_size.GetDefaultValue() < UINT64_MAX) { + if (m_count.GetDefaultValue() < UINT64_MAX) + return result; + else + return result.take_front(3); + } + return result.take_front(2); } -const OptionDefinition * -OptionGroupFormat::GetDefinitions () -{ - return g_option_table; -} +Error OptionGroupFormat::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error; + const int short_option = g_option_table[option_idx].short_option; -Error -OptionGroupFormat::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - const int short_option = g_option_table[option_idx].short_option; + switch (short_option) { + case 'f': + error = m_format.SetValueFromString(option_arg); + break; - switch (short_option) - { - case 'f': - error = m_format.SetValueFromString (option_arg); - break; - - case 'c': - if (m_count.GetDefaultValue() == 0) - { - error.SetErrorString ("--count option is disabled"); - } - else - { - error = m_count.SetValueFromString (option_arg); - if (m_count.GetCurrentValue() == 0) - error.SetErrorStringWithFormat("invalid --count option value '%s'", option_arg); - } - break; - - case 's': - if (m_byte_size.GetDefaultValue() == 0) - { - error.SetErrorString ("--size option is disabled"); - } - else - { - error = m_byte_size.SetValueFromString (option_arg); - if (m_byte_size.GetCurrentValue() == 0) - error.SetErrorStringWithFormat("invalid --size option value '%s'", option_arg); - } - break; - - case 'G': - { - char *end = nullptr; - const char *gdb_format_cstr = option_arg; - uint64_t count = 0; - if (::isdigit (gdb_format_cstr[0])) - { - count = strtoull (gdb_format_cstr, &end, 0); - - if (option_arg != end) - gdb_format_cstr = end; // We have a valid count, advance the string position - else - count = 0; - } - - Format format = eFormatDefault; - uint32_t byte_size = 0; - - while (ParserGDBFormatLetter (interpreter, gdb_format_cstr[0], format, byte_size)) - { - ++gdb_format_cstr; - } - - // We the first character of the "gdb_format_cstr" is not the - // NULL terminator, we didn't consume the entire string and - // something is wrong. Also, if none of the format, size or count - // was specified correctly, then abort. - if (gdb_format_cstr[0] || (format == eFormatInvalid && byte_size == 0 && count == 0)) - { - // Nothing got set correctly - error.SetErrorStringWithFormat ("invalid gdb format string '%s'", option_arg); - return error; - } - - // At least one of the format, size or count was set correctly. - // Anything that wasn't set correctly should be set to the - // previous default - if (format == eFormatInvalid) - ParserGDBFormatLetter (interpreter, m_prev_gdb_format, format, byte_size); - - const bool byte_size_enabled = m_byte_size.GetDefaultValue() < UINT64_MAX; - const bool count_enabled = m_count.GetDefaultValue() < UINT64_MAX; - if (byte_size_enabled) - { - // Byte size is enabled - if (byte_size == 0) - ParserGDBFormatLetter (interpreter, m_prev_gdb_size, format, byte_size); - } - else - { - // Byte size is disabled, make sure it wasn't specified - // but if this is an address, it's actually necessary to - // specify one so don't error out - if (byte_size > 0 && format != lldb::eFormatAddressInfo) - { - error.SetErrorString ("this command doesn't support specifying a byte size"); - return error; - } - } - - if (count_enabled) - { - // Count is enabled and was not set, set it to the default for gdb format statements (which is 1). - if (count == 0) - count = 1; - } - else - { - // Count is disabled, make sure it wasn't specified - if (count > 0) - { - error.SetErrorString ("this command doesn't support specifying a count"); - return error; - } - } - - m_format.SetCurrentValue (format); - m_format.SetOptionWasSet (); - if (byte_size_enabled) - { - m_byte_size.SetCurrentValue (byte_size); - m_byte_size.SetOptionWasSet (); - } - if (count_enabled) - { - m_count.SetCurrentValue(count); - m_count.SetOptionWasSet (); - } - } - break; - - default: - error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); - break; + case 'c': + if (m_count.GetDefaultValue() == 0) { + error.SetErrorString("--count option is disabled"); + } else { + error = m_count.SetValueFromString(option_arg); + if (m_count.GetCurrentValue() == 0) + error.SetErrorStringWithFormat("invalid --count option value '%s'", + option_arg.str().c_str()); + } + break; + + case 's': + if (m_byte_size.GetDefaultValue() == 0) { + error.SetErrorString("--size option is disabled"); + } else { + error = m_byte_size.SetValueFromString(option_arg); + if (m_byte_size.GetCurrentValue() == 0) + error.SetErrorStringWithFormat("invalid --size option value '%s'", + option_arg.str().c_str()); + } + break; + + case 'G': { + uint64_t count = 0; + llvm::StringRef gdb_format_str = option_arg; + gdb_format_str.consumeInteger(0, count); + + Format format = eFormatDefault; + uint32_t byte_size = 0; + + while (!gdb_format_str.empty() && + ParserGDBFormatLetter(execution_context, gdb_format_str[0], format, + byte_size)) { + gdb_format_str = gdb_format_str.drop_front(); + } + + // We the first character of the "gdb_format_str" is not the + // NULL terminator, we didn't consume the entire string and + // something is wrong. Also, if none of the format, size or count + // was specified correctly, then abort. + if (!gdb_format_str.empty() || + (format == eFormatInvalid && byte_size == 0 && count == 0)) { + // Nothing got set correctly + error.SetErrorStringWithFormat("invalid gdb format string '%s'", + option_arg.str().c_str()); + return error; + } + + // At least one of the format, size or count was set correctly. + // Anything that wasn't set correctly should be set to the + // previous default + if (format == eFormatInvalid) + ParserGDBFormatLetter(execution_context, m_prev_gdb_format, format, + byte_size); + + const bool byte_size_enabled = m_byte_size.GetDefaultValue() < UINT64_MAX; + const bool count_enabled = m_count.GetDefaultValue() < UINT64_MAX; + if (byte_size_enabled) { + // Byte size is enabled + if (byte_size == 0) + ParserGDBFormatLetter(execution_context, m_prev_gdb_size, format, + byte_size); + } else { + // Byte size is disabled, make sure it wasn't specified + // but if this is an address, it's actually necessary to + // specify one so don't error out + if (byte_size > 0 && format != lldb::eFormatAddressInfo) { + error.SetErrorString( + "this command doesn't support specifying a byte size"); + return error; + } } - return error; + if (count_enabled) { + // Count is enabled and was not set, set it to the default for gdb format + // statements (which is 1). + if (count == 0) + count = 1; + } else { + // Count is disabled, make sure it wasn't specified + if (count > 0) { + error.SetErrorString("this command doesn't support specifying a count"); + return error; + } + } + + m_format.SetCurrentValue(format); + m_format.SetOptionWasSet(); + if (byte_size_enabled) { + m_byte_size.SetCurrentValue(byte_size); + m_byte_size.SetOptionWasSet(); + } + if (count_enabled) { + m_count.SetCurrentValue(count); + m_count.SetOptionWasSet(); + } + } break; + + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); + break; + } + + return error; } -bool -OptionGroupFormat::ParserGDBFormatLetter (CommandInterpreter &interpreter, char format_letter, Format &format, uint32_t &byte_size) -{ - m_has_gdb_format = true; - switch (format_letter) +bool OptionGroupFormat::ParserGDBFormatLetter( + ExecutionContext *execution_context, char format_letter, Format &format, + uint32_t &byte_size) { + m_has_gdb_format = true; + switch (format_letter) { + case 'o': + format = eFormatOctal; + m_prev_gdb_format = format_letter; + return true; + case 'x': + format = eFormatHex; + m_prev_gdb_format = format_letter; + return true; + case 'd': + format = eFormatDecimal; + m_prev_gdb_format = format_letter; + return true; + case 'u': + format = eFormatUnsigned; + m_prev_gdb_format = format_letter; + return true; + case 't': + format = eFormatBinary; + m_prev_gdb_format = format_letter; + return true; + case 'f': + format = eFormatFloat; + m_prev_gdb_format = format_letter; + return true; + case 'a': + format = eFormatAddressInfo; { - case 'o': format = eFormatOctal; m_prev_gdb_format = format_letter; return true; - case 'x': format = eFormatHex; m_prev_gdb_format = format_letter; return true; - case 'd': format = eFormatDecimal; m_prev_gdb_format = format_letter; return true; - case 'u': format = eFormatUnsigned; m_prev_gdb_format = format_letter; return true; - case 't': format = eFormatBinary; m_prev_gdb_format = format_letter; return true; - case 'f': format = eFormatFloat; m_prev_gdb_format = format_letter; return true; - case 'a': format = eFormatAddressInfo; - { - ExecutionContext exe_ctx(interpreter.GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) - byte_size = target->GetArchitecture().GetAddressByteSize(); - m_prev_gdb_format = format_letter; - return true; - } - case 'i': format = eFormatInstruction; m_prev_gdb_format = format_letter; return true; - case 'c': format = eFormatChar; m_prev_gdb_format = format_letter; return true; - case 's': format = eFormatCString; m_prev_gdb_format = format_letter; return true; - case 'T': format = eFormatOSType; m_prev_gdb_format = format_letter; return true; - case 'A': format = eFormatHexFloat; m_prev_gdb_format = format_letter; return true; - case 'b': byte_size = 1; m_prev_gdb_size = format_letter; return true; - case 'h': byte_size = 2; m_prev_gdb_size = format_letter; return true; - case 'w': byte_size = 4; m_prev_gdb_size = format_letter; return true; - case 'g': byte_size = 8; m_prev_gdb_size = format_letter; return true; - default: break; + TargetSP target_sp = + execution_context ? execution_context->GetTargetSP() : TargetSP(); + if (target_sp) + byte_size = target_sp->GetArchitecture().GetAddressByteSize(); + m_prev_gdb_format = format_letter; + return true; } - return false; + case 'i': + format = eFormatInstruction; + m_prev_gdb_format = format_letter; + return true; + case 'c': + format = eFormatChar; + m_prev_gdb_format = format_letter; + return true; + case 's': + format = eFormatCString; + m_prev_gdb_format = format_letter; + return true; + case 'T': + format = eFormatOSType; + m_prev_gdb_format = format_letter; + return true; + case 'A': + format = eFormatHexFloat; + m_prev_gdb_format = format_letter; + return true; + + // Size isn't used for printing instructions, so if a size is specified, and + // the previous format was + // 'i', then we should reset it to the default ('x'). Otherwise we'll + // continue to print as instructions, + // which isn't expected. + case 'b': + byte_size = 1; + LLVM_FALLTHROUGH; + case 'h': + byte_size = 2; + LLVM_FALLTHROUGH; + case 'w': + byte_size = 4; + LLVM_FALLTHROUGH; + case 'g': + byte_size = 8; + + m_prev_gdb_size = format_letter; + if (m_prev_gdb_format == 'i') + m_prev_gdb_format = 'x'; + return true; + + break; + default: + break; + } + return false; } -void -OptionGroupFormat::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_format.Clear(); - m_byte_size.Clear(); - m_count.Clear(); - m_has_gdb_format = false; +void OptionGroupFormat::OptionParsingStarting( + ExecutionContext *execution_context) { + m_format.Clear(); + m_byte_size.Clear(); + m_count.Clear(); + m_has_gdb_format = false; } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupOutputFile.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupOutputFile.cpp index e95cd35..b9538fb 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupOutputFile.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupOutputFile.cpp @@ -18,68 +18,51 @@ using namespace lldb; using namespace lldb_private; -OptionGroupOutputFile::OptionGroupOutputFile() : - m_file (), - m_append (false, false) -{ -} +OptionGroupOutputFile::OptionGroupOutputFile() + : m_file(), m_append(false, false) {} -OptionGroupOutputFile::~OptionGroupOutputFile () -{ -} +OptionGroupOutputFile::~OptionGroupOutputFile() {} -static const uint32_t SHORT_OPTION_APND = 0x61706e64; // 'apnd' +static const uint32_t SHORT_OPTION_APND = 0x61706e64; // 'apnd' -static OptionDefinition -g_option_table[] = -{ - { LLDB_OPT_SET_1 , false, "outfile", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename , "Specify a path for capturing command output."}, - { LLDB_OPT_SET_1 , false, "append-outfile" , SHORT_OPTION_APND, - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , - "Append to the file specified with '--outfile <path>'."}, +static OptionDefinition g_option_table[] = { + {LLDB_OPT_SET_1, false, "outfile", 'o', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeFilename, + "Specify a path for capturing command output."}, + {LLDB_OPT_SET_1, false, "append-outfile", SHORT_OPTION_APND, + OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + "Append to the file specified with '--outfile <path>'."}, }; -uint32_t -OptionGroupOutputFile::GetNumDefinitions () -{ - return llvm::array_lengthof(g_option_table); -} - -const OptionDefinition * -OptionGroupOutputFile::GetDefinitions () -{ - return g_option_table; +llvm::ArrayRef<OptionDefinition> OptionGroupOutputFile::GetDefinitions() { + return llvm::makeArrayRef(g_option_table); } -Error -OptionGroupOutputFile::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - const int short_option = g_option_table[option_idx].short_option; +Error OptionGroupOutputFile::SetOptionValue( + uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error; + const int short_option = g_option_table[option_idx].short_option; - switch (short_option) - { - case 'o': - error = m_file.SetValueFromString (option_arg); - break; + switch (short_option) { + case 'o': + error = m_file.SetValueFromString(option_arg); + break; - case SHORT_OPTION_APND: - m_append.SetCurrentValue(true); - break; + case SHORT_OPTION_APND: + m_append.SetCurrentValue(true); + break; - default: - error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); - break; - } + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); + break; + } - return error; + return error; } -void -OptionGroupOutputFile::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_file.Clear(); - m_append.Clear(); +void OptionGroupOutputFile::OptionParsingStarting( + ExecutionContext *execution_context) { + m_file.Clear(); + m_append.Clear(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp index 6fa06d1..6231162 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -20,163 +20,140 @@ using namespace lldb; using namespace lldb_private; -PlatformSP -OptionGroupPlatform::CreatePlatformWithOptions (CommandInterpreter &interpreter, - const ArchSpec &arch, - bool make_selected, - Error& error, - ArchSpec &platform_arch) const -{ - PlatformSP platform_sp; - - if (!m_platform_name.empty()) - { - platform_sp = Platform::Create (ConstString(m_platform_name.c_str()), error); - if (platform_sp) - { - if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) - { - error.SetErrorStringWithFormat ("platform '%s' doesn't support '%s'", - platform_sp->GetName().GetCString(), - arch.GetTriple().getTriple().c_str()); - platform_sp.reset(); - return platform_sp; - } - } +PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( + CommandInterpreter &interpreter, const ArchSpec &arch, bool make_selected, + Error &error, ArchSpec &platform_arch) const { + PlatformSP platform_sp; + + if (!m_platform_name.empty()) { + platform_sp = Platform::Create(ConstString(m_platform_name.c_str()), error); + if (platform_sp) { + if (platform_arch.IsValid() && + !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) { + error.SetErrorStringWithFormat("platform '%s' doesn't support '%s'", + platform_sp->GetName().GetCString(), + arch.GetTriple().getTriple().c_str()); + platform_sp.reset(); + return platform_sp; + } } - else if (arch.IsValid()) - { - platform_sp = Platform::Create (arch, &platform_arch, error); - } - - if (platform_sp) - { - interpreter.GetDebugger().GetPlatformList().Append (platform_sp, make_selected); - if (m_os_version_major != UINT32_MAX) - { - platform_sp->SetOSVersion (m_os_version_major, - m_os_version_minor, - m_os_version_update); - } - - if (m_sdk_sysroot) - platform_sp->SetSDKRootDirectory (m_sdk_sysroot); - - if (m_sdk_build) - platform_sp->SetSDKBuild (m_sdk_build); + } else if (arch.IsValid()) { + platform_sp = Platform::Create(arch, &platform_arch, error); + } + + if (platform_sp) { + interpreter.GetDebugger().GetPlatformList().Append(platform_sp, + make_selected); + if (m_os_version_major != UINT32_MAX) { + platform_sp->SetOSVersion(m_os_version_major, m_os_version_minor, + m_os_version_update); } - return platform_sp; -} + if (m_sdk_sysroot) + platform_sp->SetSDKRootDirectory(m_sdk_sysroot); + + if (m_sdk_build) + platform_sp->SetSDKBuild(m_sdk_build); + } -void -OptionGroupPlatform::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_platform_name.clear(); - m_sdk_sysroot.Clear(); - m_sdk_build.Clear(); - m_os_version_major = UINT32_MAX; - m_os_version_minor = UINT32_MAX; - m_os_version_update = UINT32_MAX; + return platform_sp; } -static OptionDefinition -g_option_table[] = -{ - { LLDB_OPT_SET_ALL, false, "platform", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlatform, "Specify name of the platform to use for this target, creating the platform if necessary."}, - { LLDB_OPT_SET_ALL, false, "version" , 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "Specify the initial SDK version to use prior to connecting." }, - { LLDB_OPT_SET_ALL, false, "build" , 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "Specify the initial SDK build number." }, - { LLDB_OPT_SET_ALL, false, "sysroot" , 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Specify the SDK root directory that contains a root of all remote system files." } -}; - -const OptionDefinition* -OptionGroupPlatform::GetDefinitions () -{ - if (m_include_platform_option) - return g_option_table; - return g_option_table + 1; +void OptionGroupPlatform::OptionParsingStarting( + ExecutionContext *execution_context) { + m_platform_name.clear(); + m_sdk_sysroot.Clear(); + m_sdk_build.Clear(); + m_os_version_major = UINT32_MAX; + m_os_version_minor = UINT32_MAX; + m_os_version_update = UINT32_MAX; } -uint32_t -OptionGroupPlatform::GetNumDefinitions () -{ - if (m_include_platform_option) - return llvm::array_lengthof(g_option_table); - return llvm::array_lengthof(g_option_table) - 1; +static OptionDefinition g_option_table[] = { + {LLDB_OPT_SET_ALL, false, "platform", 'p', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypePlatform, "Specify name of the platform to " + "use for this target, creating the " + "platform if necessary."}, + {LLDB_OPT_SET_ALL, false, "version", 'v', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeNone, + "Specify the initial SDK version to use prior to connecting."}, + {LLDB_OPT_SET_ALL, false, "build", 'b', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeNone, + "Specify the initial SDK build number."}, + {LLDB_OPT_SET_ALL, false, "sysroot", 'S', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeFilename, "Specify the SDK root directory " + "that contains a root of all " + "remote system files."}}; + +llvm::ArrayRef<OptionDefinition> OptionGroupPlatform::GetDefinitions() { + llvm::ArrayRef<OptionDefinition> result(g_option_table); + if (m_include_platform_option) + return result; + return result.drop_front(); } +Error OptionGroupPlatform::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error; + if (!m_include_platform_option) + ++option_idx; + + const int short_option = g_option_table[option_idx].short_option; + + switch (short_option) { + case 'p': + m_platform_name.assign(option_arg); + break; + + case 'v': + if (!Args::StringToVersion(option_arg, m_os_version_major, + m_os_version_minor, m_os_version_update)) + error.SetErrorStringWithFormat("invalid version string '%s'", + option_arg.str().c_str()); + break; + + case 'b': + m_sdk_build.SetString(option_arg); + break; + + case 'S': + m_sdk_sysroot.SetString(option_arg); + break; + + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); + break; + } + return error; +} -Error -OptionGroupPlatform::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - if (!m_include_platform_option) - ++option_idx; - - const int short_option = g_option_table[option_idx].short_option; - - switch (short_option) - { - case 'p': - m_platform_name.assign (option_arg); - break; - - case 'v': - if (Args::StringToVersion (option_arg, - m_os_version_major, - m_os_version_minor, - m_os_version_update) == option_arg) - error.SetErrorStringWithFormat ("invalid version string '%s'", option_arg); - break; - - case 'b': - m_sdk_build.SetCString (option_arg); - break; - - case 'S': - m_sdk_sysroot.SetCString (option_arg); - break; - - default: - error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); - break; +bool OptionGroupPlatform::PlatformMatches( + const lldb::PlatformSP &platform_sp) const { + if (platform_sp) { + if (!m_platform_name.empty()) { + if (platform_sp->GetName() != ConstString(m_platform_name.c_str())) + return false; } - return error; -} -bool -OptionGroupPlatform::PlatformMatches(const lldb::PlatformSP &platform_sp) const -{ - if (platform_sp) - { - if (!m_platform_name.empty()) - { - if (platform_sp->GetName() != ConstString(m_platform_name.c_str())) - return false; - } - - if (m_sdk_build && m_sdk_build != platform_sp->GetSDKBuild()) - return false; - - if (m_sdk_sysroot && m_sdk_sysroot != platform_sp->GetSDKRootDirectory()) - return false; - - if (m_os_version_major != UINT32_MAX) - { - uint32_t major, minor, update; - if (platform_sp->GetOSVersion (major, minor, update)) - { - if (m_os_version_major != major) - return false; - if (m_os_version_minor != minor) - return false; - if (m_os_version_update != update) - return false; - } - } - return true; + if (m_sdk_build && m_sdk_build != platform_sp->GetSDKBuild()) + return false; + + if (m_sdk_sysroot && m_sdk_sysroot != platform_sp->GetSDKRootDirectory()) + return false; + + if (m_os_version_major != UINT32_MAX) { + uint32_t major, minor, update; + if (platform_sp->GetOSVersion(major, minor, update)) { + if (m_os_version_major != major) + return false; + if (m_os_version_minor != minor) + return false; + if (m_os_version_update != update) + return false; + } } - return false; + return true; + } + return false; } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupString.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupString.cpp index e0291b1..48a9ff1 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupString.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupString.cpp @@ -17,43 +17,35 @@ using namespace lldb; using namespace lldb_private; -OptionGroupString::OptionGroupString (uint32_t usage_mask, - bool required, - const char *long_option, - int short_option, - uint32_t completion_type, - lldb::CommandArgumentType argument_type, - const char *usage_text, - const char *default_value) : - m_value (default_value, default_value) -{ - m_option_definition.usage_mask = usage_mask; - m_option_definition.required = required; - m_option_definition.long_option = long_option; - m_option_definition.short_option = short_option; - m_option_definition.validator = nullptr; - m_option_definition.option_has_arg = OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; - m_option_definition.completion_type = completion_type; - m_option_definition.argument_type = argument_type; - m_option_definition.usage_text = usage_text; +OptionGroupString::OptionGroupString(uint32_t usage_mask, bool required, + const char *long_option, int short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text, + const char *default_value) + : m_value(default_value, default_value) { + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.validator = nullptr; + m_option_definition.option_has_arg = OptionParser::eRequiredArgument; + m_option_definition.enum_values = nullptr; + m_option_definition.completion_type = completion_type; + m_option_definition.argument_type = argument_type; + m_option_definition.usage_text = usage_text; } -OptionGroupString::~OptionGroupString () -{ -} +OptionGroupString::~OptionGroupString() {} -Error -OptionGroupString::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error (m_value.SetValueFromString (option_arg)); - return error; +Error OptionGroupString::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error(m_value.SetValueFromString(option_arg)); + return error; } -void -OptionGroupString::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_value.Clear(); +void OptionGroupString::OptionParsingStarting( + ExecutionContext *execution_context) { + m_value.Clear(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUInt64.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUInt64.cpp index a922ab2..a8501fa 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUInt64.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUInt64.cpp @@ -17,43 +17,35 @@ using namespace lldb; using namespace lldb_private; -OptionGroupUInt64::OptionGroupUInt64 (uint32_t usage_mask, - bool required, - const char *long_option, - int short_option, - uint32_t completion_type, - lldb::CommandArgumentType argument_type, - const char *usage_text, - uint64_t default_value) : - m_value (default_value, default_value) -{ - m_option_definition.usage_mask = usage_mask; - m_option_definition.required = required; - m_option_definition.long_option = long_option; - m_option_definition.short_option = short_option; - m_option_definition.validator = nullptr; - m_option_definition.option_has_arg = OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; - m_option_definition.completion_type = completion_type; - m_option_definition.argument_type = argument_type; - m_option_definition.usage_text = usage_text; +OptionGroupUInt64::OptionGroupUInt64(uint32_t usage_mask, bool required, + const char *long_option, int short_option, + uint32_t completion_type, + lldb::CommandArgumentType argument_type, + const char *usage_text, + uint64_t default_value) + : m_value(default_value, default_value) { + m_option_definition.usage_mask = usage_mask; + m_option_definition.required = required; + m_option_definition.long_option = long_option; + m_option_definition.short_option = short_option; + m_option_definition.validator = nullptr; + m_option_definition.option_has_arg = OptionParser::eRequiredArgument; + m_option_definition.enum_values = nullptr; + m_option_definition.completion_type = completion_type; + m_option_definition.argument_type = argument_type; + m_option_definition.usage_text = usage_text; } -OptionGroupUInt64::~OptionGroupUInt64 () -{ -} +OptionGroupUInt64::~OptionGroupUInt64() {} -Error -OptionGroupUInt64::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error (m_value.SetValueFromString (option_arg)); - return error; +Error OptionGroupUInt64::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error(m_value.SetValueFromString(option_arg)); + return error; } -void -OptionGroupUInt64::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_value.Clear(); +void OptionGroupUInt64::OptionParsingStarting( + ExecutionContext *execution_context) { + m_value.Clear(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUUID.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUUID.cpp index 609967a..cd6c02a 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUUID.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUUID.cpp @@ -18,59 +18,41 @@ using namespace lldb; using namespace lldb_private; -OptionGroupUUID::OptionGroupUUID() : - m_uuid () -{ -} +OptionGroupUUID::OptionGroupUUID() : m_uuid() {} -OptionGroupUUID::~OptionGroupUUID () -{ -} +OptionGroupUUID::~OptionGroupUUID() {} -static OptionDefinition -g_option_table[] = -{ - { LLDB_OPT_SET_1 , false, "uuid", 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A module UUID value."}, +static OptionDefinition g_option_table[] = { + {LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeNone, "A module UUID value."}, }; -uint32_t -OptionGroupUUID::GetNumDefinitions () -{ - return llvm::array_lengthof(g_option_table); -} - -const OptionDefinition * -OptionGroupUUID::GetDefinitions () -{ - return g_option_table; +llvm::ArrayRef<OptionDefinition> OptionGroupUUID::GetDefinitions() { + return llvm::makeArrayRef(g_option_table); } -Error -OptionGroupUUID::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - const int short_option = g_option_table[option_idx].short_option; - - switch (short_option) - { - case 'u': - error = m_uuid.SetValueFromString (option_arg); - if (error.Success()) - m_uuid.SetOptionWasSet(); - break; - - default: - error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); - break; - } - - return error; +Error OptionGroupUUID::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error; + const int short_option = g_option_table[option_idx].short_option; + + switch (short_option) { + case 'u': + error = m_uuid.SetValueFromString(option_arg); + if (error.Success()) + m_uuid.SetOptionWasSet(); + break; + + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); + break; + } + + return error; } -void -OptionGroupUUID::OptionParsingStarting (CommandInterpreter &interpreter) -{ - m_uuid.Clear(); +void OptionGroupUUID::OptionParsingStarting( + ExecutionContext *execution_context) { + m_uuid.Clear(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp index c30a978..6d33132 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -15,188 +15,215 @@ // Project includes #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/StringConvert.h" -#include "lldb/Target/Target.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Target/Target.h" #include "lldb/Utility/Utils.h" +#include "llvm/ADT/ArrayRef.h" + using namespace lldb; using namespace lldb_private; -OptionGroupValueObjectDisplay::OptionGroupValueObjectDisplay() -{ -} - -OptionGroupValueObjectDisplay::~OptionGroupValueObjectDisplay () -{ -} - -static OptionDefinition -g_option_table[] = -{ - { LLDB_OPT_SET_1, false, "dynamic-type", 'd', OptionParser::eRequiredArgument, nullptr, g_dynamic_value_types, 0, eArgTypeNone, "Show the object as its full dynamic type, not its static type, if available."}, - { LLDB_OPT_SET_1, false, "synthetic-type", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the object obeying its synthetic provider, if available."}, - { LLDB_OPT_SET_1, false, "depth", 'D', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the max recurse depth when dumping aggregate types (default is infinity)."}, - { LLDB_OPT_SET_1, false, "flat", 'F', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display results in a flat format that uses expression paths for each variable or member."}, - { LLDB_OPT_SET_1, false, "location", 'L', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show variable location information."}, - { LLDB_OPT_SET_1, false, "object-description", 'O', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print as an Objective-C object."}, - { LLDB_OPT_SET_1, false, "ptr-depth", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "The number of pointers to be traversed when dumping values (default is zero)."}, - { LLDB_OPT_SET_1, false, "show-types", 'T', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show variable types when dumping values."}, - { LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the depth at which omitting summary information stops (default is 1)."}, - { LLDB_OPT_SET_1, false, "raw-output", 'R', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use formatting options."}, - { LLDB_OPT_SET_1, false, "show-all-children", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore the upper bound on the number of children to show."}, - { LLDB_OPT_SET_1, false, "validate", 'V', OptionParser::eRequiredArgument, nullptr, nullptr,0, eArgTypeBoolean, "Show results of type validators."}, - { LLDB_OPT_SET_1, false, "element-count", 'Z', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Treat the result of the expression as if its type is an array of this many values."}, - { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } -}; - -uint32_t -OptionGroupValueObjectDisplay::GetNumDefinitions () -{ - return llvm::array_lengthof(g_option_table); -} - -const OptionDefinition * -OptionGroupValueObjectDisplay::GetDefinitions () -{ - return g_option_table; +OptionGroupValueObjectDisplay::OptionGroupValueObjectDisplay() {} + +OptionGroupValueObjectDisplay::~OptionGroupValueObjectDisplay() {} + +static OptionDefinition g_option_table[] = { + {LLDB_OPT_SET_1, false, "dynamic-type", 'd', + OptionParser::eRequiredArgument, nullptr, g_dynamic_value_types, 0, + eArgTypeNone, "Show the object as its full dynamic type, not its static " + "type, if available."}, + {LLDB_OPT_SET_1, false, "synthetic-type", 'S', + OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, + "Show the object obeying its synthetic provider, if available."}, + {LLDB_OPT_SET_1, false, "depth", 'D', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeCount, "Set the max recurse depth when " + "dumping aggregate types (default is " + "infinity)."}, + {LLDB_OPT_SET_1, false, "flat", 'F', OptionParser::eNoArgument, nullptr, + nullptr, 0, eArgTypeNone, "Display results in a flat format that uses " + "expression paths for each variable or member."}, + {LLDB_OPT_SET_1, false, "location", 'L', OptionParser::eNoArgument, nullptr, + nullptr, 0, eArgTypeNone, "Show variable location information."}, + {LLDB_OPT_SET_1, false, "object-description", 'O', + OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + "Print as an Objective-C object."}, + {LLDB_OPT_SET_1, false, "ptr-depth", 'P', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeCount, "The number of pointers to be " + "traversed when dumping values " + "(default is zero)."}, + {LLDB_OPT_SET_1, false, "show-types", 'T', OptionParser::eNoArgument, + nullptr, nullptr, 0, eArgTypeNone, + "Show variable types when dumping values."}, + {LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', + OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeCount, + "Set the depth at which omitting summary information stops (default is " + "1)."}, + {LLDB_OPT_SET_1, false, "raw-output", 'R', OptionParser::eNoArgument, + nullptr, nullptr, 0, eArgTypeNone, "Don't use formatting options."}, + {LLDB_OPT_SET_1, false, "show-all-children", 'A', OptionParser::eNoArgument, + nullptr, nullptr, 0, eArgTypeNone, + "Ignore the upper bound on the number of children to show."}, + {LLDB_OPT_SET_1, false, "validate", 'V', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeBoolean, "Show results of type validators."}, + {LLDB_OPT_SET_1, false, "element-count", 'Z', + OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, + "Treat the result of the expression as if its type is an array of this " + "many values."}}; + +llvm::ArrayRef<OptionDefinition> +OptionGroupValueObjectDisplay::GetDefinitions() { + return llvm::makeArrayRef(g_option_table); } +Error OptionGroupValueObjectDisplay::SetOptionValue( + uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error; + const int short_option = g_option_table[option_idx].short_option; + bool success = false; + + switch (short_option) { + case 'd': { + int32_t result; + result = + Args::StringToOptionEnum(option_arg, g_dynamic_value_types, 2, error); + if (error.Success()) + use_dynamic = (lldb::DynamicValueType)result; + } break; + case 'T': + show_types = true; + break; + case 'L': + show_location = true; + break; + case 'F': + flat_output = true; + break; + case 'O': + use_objc = true; + break; + case 'R': + be_raw = true; + break; + case 'A': + ignore_cap = true; + break; + + case 'D': + if (option_arg.getAsInteger(0, max_depth)) { + max_depth = UINT32_MAX; + error.SetErrorStringWithFormat("invalid max depth '%s'", + option_arg.str().c_str()); + } + break; -Error -OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - const int short_option = g_option_table[option_idx].short_option; - bool success = false; - - switch (short_option) - { - case 'd': - { - int32_t result; - result = Args::StringToOptionEnum (option_arg, g_dynamic_value_types, 2, error); - if (error.Success()) - use_dynamic = (lldb::DynamicValueType) result; - } - break; - case 'T': show_types = true; break; - case 'L': show_location= true; break; - case 'F': flat_output = true; break; - case 'O': use_objc = true; break; - case 'R': be_raw = true; break; - case 'A': ignore_cap = true; break; - - case 'D': - max_depth = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success); - if (!success) - error.SetErrorStringWithFormat("invalid max depth '%s'", option_arg); - break; - - case 'Z': - elem_count = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success); - if (!success) - error.SetErrorStringWithFormat("invalid element count '%s'", option_arg); - break; - - case 'P': - ptr_depth = StringConvert::ToUInt32 (option_arg, 0, 0, &success); - if (!success) - error.SetErrorStringWithFormat("invalid pointer depth '%s'", option_arg); - break; - - case 'Y': - if (option_arg) - { - no_summary_depth = StringConvert::ToUInt32 (option_arg, 0, 0, &success); - if (!success) - error.SetErrorStringWithFormat("invalid pointer depth '%s'", option_arg); - } - else - no_summary_depth = 1; - break; - - case 'S': - use_synth = Args::StringToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat("invalid synthetic-type '%s'", option_arg); - break; - - case 'V': - run_validator = Args::StringToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat("invalid validate '%s'", option_arg); - break; - - default: - error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); - break; + case 'Z': + if (option_arg.getAsInteger(0, elem_count)) { + elem_count = UINT32_MAX; + error.SetErrorStringWithFormat("invalid element count '%s'", + option_arg.str().c_str()); } + break; - return error; + case 'P': + if (option_arg.getAsInteger(0, ptr_depth)) { + ptr_depth = 0; + error.SetErrorStringWithFormat("invalid pointer depth '%s'", + option_arg.str().c_str()); + } + break; + + case 'Y': + if (option_arg.empty()) + no_summary_depth = 1; + else if (option_arg.getAsInteger(0, no_summary_depth)) { + no_summary_depth = 0; + error.SetErrorStringWithFormat("invalid pointer depth '%s'", + option_arg.str().c_str()); + } + break; + + case 'S': + use_synth = Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("invalid synthetic-type '%s'", + option_arg.str().c_str()); + break; + + case 'V': + run_validator = Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("invalid validate '%s'", + option_arg.str().c_str()); + break; + + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); + break; + } + + return error; } -void -OptionGroupValueObjectDisplay::OptionParsingStarting (CommandInterpreter &interpreter) -{ - // If these defaults change, be sure to modify AnyOptionWasSet(). - show_types = false; - no_summary_depth = 0; - show_location = false; - flat_output = false; - use_objc = false; - max_depth = UINT32_MAX; - ptr_depth = 0; - elem_count = 0; - use_synth = true; - be_raw = false; - ignore_cap = false; - run_validator = false; - - Target *target = interpreter.GetExecutionContext().GetTargetPtr(); - if (target != nullptr) - use_dynamic = target->GetPreferDynamicValue(); - else - { - // If we don't have any targets, then dynamic values won't do us much good. - use_dynamic = lldb::eNoDynamicValues; - } +void OptionGroupValueObjectDisplay::OptionParsingStarting( + ExecutionContext *execution_context) { + // If these defaults change, be sure to modify AnyOptionWasSet(). + show_types = false; + no_summary_depth = 0; + show_location = false; + flat_output = false; + use_objc = false; + max_depth = UINT32_MAX; + ptr_depth = 0; + elem_count = 0; + use_synth = true; + be_raw = false; + ignore_cap = false; + run_validator = false; + + TargetSP target_sp = + execution_context ? execution_context->GetTargetSP() : TargetSP(); + if (target_sp) + use_dynamic = target_sp->GetPreferDynamicValue(); + else { + // If we don't have any targets, then dynamic values won't do us much good. + use_dynamic = lldb::eNoDynamicValues; + } } -DumpValueObjectOptions -OptionGroupValueObjectDisplay::GetAsDumpOptions (LanguageRuntimeDescriptionDisplayVerbosity lang_descr_verbosity, - lldb::Format format, - lldb::TypeSummaryImplSP summary_sp) -{ - DumpValueObjectOptions options; - options.SetMaximumPointerDepth( {DumpValueObjectOptions::PointerDepth::Mode::Always,ptr_depth} ); - if (use_objc) - options.SetShowSummary(false); - else - options.SetOmitSummaryDepth(no_summary_depth); - options.SetMaximumDepth(max_depth) - .SetShowTypes(show_types) - .SetShowLocation(show_location) - .SetUseObjectiveC(use_objc) - .SetUseDynamicType(use_dynamic) - .SetUseSyntheticValue(use_synth) - .SetFlatOutput(flat_output) - .SetIgnoreCap(ignore_cap) - .SetFormat(format) - .SetSummary(summary_sp); - - if (lang_descr_verbosity == eLanguageRuntimeDescriptionDisplayVerbosityCompact) - options.SetHideRootType(use_objc) - .SetHideName(use_objc) - .SetHideValue(use_objc); - - if (be_raw) - options.SetRawDisplay(); - - options.SetRunValidator(run_validator); - - options.SetElementCount(elem_count); - - return options; +DumpValueObjectOptions OptionGroupValueObjectDisplay::GetAsDumpOptions( + LanguageRuntimeDescriptionDisplayVerbosity lang_descr_verbosity, + lldb::Format format, lldb::TypeSummaryImplSP summary_sp) { + DumpValueObjectOptions options; + options.SetMaximumPointerDepth( + {DumpValueObjectOptions::PointerDepth::Mode::Always, ptr_depth}); + if (use_objc) + options.SetShowSummary(false); + else + options.SetOmitSummaryDepth(no_summary_depth); + options.SetMaximumDepth(max_depth) + .SetShowTypes(show_types) + .SetShowLocation(show_location) + .SetUseObjectiveC(use_objc) + .SetUseDynamicType(use_dynamic) + .SetUseSyntheticValue(use_synth) + .SetFlatOutput(flat_output) + .SetIgnoreCap(ignore_cap) + .SetFormat(format) + .SetSummary(summary_sp); + + if (lang_descr_verbosity == + eLanguageRuntimeDescriptionDisplayVerbosityCompact) + options.SetHideRootType(use_objc).SetHideName(use_objc).SetHideValue( + use_objc); + + if (be_raw) + options.SetRawDisplay(); + + options.SetRunValidator(run_validator); + + options.SetElementCount(elem_count); + + return options; } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupVariable.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupVariable.cpp index 092d60a..c257506 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupVariable.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupVariable.cpp @@ -22,121 +22,121 @@ using namespace lldb; using namespace lldb_private; -// if you add any options here, remember to update the counters in OptionGroupVariable::GetNumDefinitions() -static OptionDefinition -g_option_table[] = -{ - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Omit function arguments."}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals", 'l', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Omit local variables."}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show the current frame source file global and static variables."}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration",'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show variable declaration information (source file and line where the variable was declared)."}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "The <variable-name> argument for name lookups are regular expressions."}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."}, - { LLDB_OPT_SET_1, false, "summary", 'y', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Specify the summary that the variable output should use."}, - { LLDB_OPT_SET_2, false, "summary-string", 'z', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Specify a summary string to use to format the variable output."}, +// if you add any options here, remember to update the counters in +// OptionGroupVariable::GetNumDefinitions() +static OptionDefinition g_variable_options[] = { + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args", 'a', + OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + "Omit function arguments."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals", 'l', + OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + "Omit local variables."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals", 'g', + OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + "Show the current frame source file global and static variables."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration", 'c', + OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + "Show variable declaration information (source file and line where the " + "variable was declared)."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex", 'r', + OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, + "The <variable-name> argument for name lookups are regular expressions."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope", 's', + OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + "Show variable scope (argument, local, global, static)."}, + {LLDB_OPT_SET_1, false, "summary", 'y', OptionParser::eRequiredArgument, + nullptr, nullptr, 0, eArgTypeName, + "Specify the summary that the variable output should use."}, + {LLDB_OPT_SET_2, false, "summary-string", 'z', + OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, + "Specify a summary string to use to format the variable output."}, }; -static Error -ValidateNamedSummary (const char* str, void*) -{ - if (!str || !str[0]) - return Error("must specify a valid named summary"); - TypeSummaryImplSP summary_sp; - if (DataVisualization::NamedSummaryFormats::GetSummaryFormat(ConstString(str), summary_sp) == false) - return Error("must specify a valid named summary"); - return Error(); +static Error ValidateNamedSummary(const char *str, void *) { + if (!str || !str[0]) + return Error("must specify a valid named summary"); + TypeSummaryImplSP summary_sp; + if (DataVisualization::NamedSummaryFormats::GetSummaryFormat( + ConstString(str), summary_sp) == false) + return Error("must specify a valid named summary"); + return Error(); } -static Error -ValidateSummaryString (const char* str, void*) -{ - if (!str || !str[0]) - return Error("must specify a non-empty summary string"); - return Error(); +static Error ValidateSummaryString(const char *str, void *) { + if (!str || !str[0]) + return Error("must specify a non-empty summary string"); + return Error(); } -OptionGroupVariable::OptionGroupVariable (bool show_frame_options) : - OptionGroup(), - include_frame_options (show_frame_options), - summary(ValidateNamedSummary), - summary_string(ValidateSummaryString) -{ +OptionGroupVariable::OptionGroupVariable(bool show_frame_options) + : OptionGroup(), include_frame_options(show_frame_options), + summary(ValidateNamedSummary), summary_string(ValidateSummaryString) {} + +OptionGroupVariable::~OptionGroupVariable() {} + +Error OptionGroupVariable::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error; + if (!include_frame_options) + option_idx += 3; + const int short_option = g_variable_options[option_idx].short_option; + switch (short_option) { + case 'r': + use_regex = true; + break; + case 'a': + show_args = false; + break; + case 'l': + show_locals = false; + break; + case 'g': + show_globals = true; + break; + case 'c': + show_decl = true; + break; + case 's': + show_scope = true; + break; + case 'y': + error = summary.SetCurrentValue(option_arg); + break; + case 'z': + error = summary_string.SetCurrentValue(option_arg); + break; + default: + error.SetErrorStringWithFormat("unrecognized short option '%c'", + short_option); + break; + } + + return error; } -OptionGroupVariable::~OptionGroupVariable () -{ -} - -Error -OptionGroupVariable::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - if (!include_frame_options) - option_idx += 3; - const int short_option = g_option_table[option_idx].short_option; - switch (short_option) - { - case 'r': use_regex = true; break; - case 'a': show_args = false; break; - case 'l': show_locals = false; break; - case 'g': show_globals = true; break; - case 'c': show_decl = true; break; - case 's': - show_scope = true; - break; - case 'y': - error = summary.SetCurrentValue(option_arg); - break; - case 'z': - error = summary_string.SetCurrentValue(option_arg); - break; - default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); - break; - } - - return error; -} - -void -OptionGroupVariable::OptionParsingStarting (CommandInterpreter &interpreter) -{ - show_args = true; // Frame option only - show_locals = true; // Frame option only - show_globals = false; // Frame option only - show_decl = false; - use_regex = false; - show_scope = false; - summary.Clear(); - summary_string.Clear(); +void OptionGroupVariable::OptionParsingStarting( + ExecutionContext *execution_context) { + show_args = true; // Frame option only + show_locals = true; // Frame option only + show_globals = false; // Frame option only + show_decl = false; + use_regex = false; + show_scope = false; + summary.Clear(); + summary_string.Clear(); } #define NUM_FRAME_OPTS 3 -const OptionDefinition* -OptionGroupVariable::GetDefinitions () -{ - // Show the "--no-args", "--no-locals" and "--show-globals" - // options if we are showing frame specific options - if (include_frame_options) - return g_option_table; +llvm::ArrayRef<OptionDefinition> OptionGroupVariable::GetDefinitions() { + auto result = llvm::makeArrayRef(g_variable_options); + // Show the "--no-args", "--no-locals" and "--show-globals" + // options if we are showing frame specific options + if (include_frame_options) + return result; - // Skip the "--no-args", "--no-locals" and "--show-globals" - // options if we are not showing frame specific options (globals only) - return &g_option_table[NUM_FRAME_OPTS]; + // Skip the "--no-args", "--no-locals" and "--show-globals" + // options if we are not showing frame specific options (globals only) + return result.drop_front(NUM_FRAME_OPTS); } - -uint32_t -OptionGroupVariable::GetNumDefinitions () -{ - // Count the "--no-args", "--no-locals" and "--show-globals" - // options if we are showing frame specific options. - if (include_frame_options) - return llvm::array_lengthof(g_option_table); - else - return llvm::array_lengthof(g_option_table) - NUM_FRAME_OPTS; -} - - diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupWatchpoint.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupWatchpoint.cpp index c6f4b8f..cda934b 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupWatchpoint.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupWatchpoint.cpp @@ -13,109 +13,86 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/lldb-enumerations.h" #include "lldb/Interpreter/Args.h" #include "lldb/Utility/Utils.h" +#include "lldb/lldb-enumerations.h" using namespace lldb; using namespace lldb_private; -static OptionEnumValueElement g_watch_type[] = -{ - { OptionGroupWatchpoint::eWatchRead, "read", "Watch for read"}, - { OptionGroupWatchpoint::eWatchWrite, "write", "Watch for write"}, - { OptionGroupWatchpoint::eWatchReadWrite, "read_write", "Watch for read/write"}, - { 0, nullptr, nullptr } -}; - -static OptionEnumValueElement g_watch_size[] = -{ - { 1, "1", "Watch for byte size of 1"}, - { 2, "2", "Watch for byte size of 2"}, - { 4, "4", "Watch for byte size of 4"}, - { 8, "8", "Watch for byte size of 8"}, - { 0, nullptr, nullptr } -}; - -static OptionDefinition -g_option_table[] = -{ - { LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument, nullptr, g_watch_type, 0, eArgTypeWatchType, "Specify the type of watching to perform."}, - { LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument, nullptr, g_watch_size, 0, eArgTypeByteSize, "Number of bytes to use to watch a region."} -}; - - -bool -OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) -{ - for (uint32_t i = 0; i < llvm::array_lengthof(g_watch_size); ++i) - { - if (g_watch_size[i].value == 0) - break; - if (watch_size == g_watch_size[i].value) - return true; - } - return false; +static OptionEnumValueElement g_watch_type[] = { + {OptionGroupWatchpoint::eWatchRead, "read", "Watch for read"}, + {OptionGroupWatchpoint::eWatchWrite, "write", "Watch for write"}, + {OptionGroupWatchpoint::eWatchReadWrite, "read_write", + "Watch for read/write"}, + {0, nullptr, nullptr}}; + +static OptionEnumValueElement g_watch_size[] = { + {1, "1", "Watch for byte size of 1"}, + {2, "2", "Watch for byte size of 2"}, + {4, "4", "Watch for byte size of 4"}, + {8, "8", "Watch for byte size of 8"}, + {0, nullptr, nullptr}}; + +static OptionDefinition g_option_table[] = { + {LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument, + nullptr, g_watch_type, 0, eArgTypeWatchType, + "Specify the type of watching to perform."}, + {LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument, + nullptr, g_watch_size, 0, eArgTypeByteSize, + "Number of bytes to use to watch a region."}}; + +bool OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) { + for (uint32_t i = 0; i < llvm::array_lengthof(g_watch_size); ++i) { + if (g_watch_size[i].value == 0) + break; + if (watch_size == g_watch_size[i].value) + return true; + } + return false; } -OptionGroupWatchpoint::OptionGroupWatchpoint () : - OptionGroup() -{ -} - -OptionGroupWatchpoint::~OptionGroupWatchpoint () -{ -} - -Error -OptionGroupWatchpoint::SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) -{ - Error error; - const int short_option = g_option_table[option_idx].short_option; - switch (short_option) - { - case 'w': - { - WatchType tmp_watch_type; - tmp_watch_type = (WatchType) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); - if (error.Success()) - { - watch_type = tmp_watch_type; - watch_type_specified = true; - } - break; - } - case 's': - watch_size = (uint32_t) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); - break; - - default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); - break; +OptionGroupWatchpoint::OptionGroupWatchpoint() : OptionGroup() {} + +OptionGroupWatchpoint::~OptionGroupWatchpoint() {} + +Error OptionGroupWatchpoint::SetOptionValue( + uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Error error; + const int short_option = g_option_table[option_idx].short_option; + switch (short_option) { + case 'w': { + WatchType tmp_watch_type; + tmp_watch_type = (WatchType)Args::StringToOptionEnum( + option_arg, g_option_table[option_idx].enum_values, 0, error); + if (error.Success()) { + watch_type = tmp_watch_type; + watch_type_specified = true; } - - return error; + break; + } + case 's': + watch_size = (uint32_t)Args::StringToOptionEnum( + option_arg, g_option_table[option_idx].enum_values, 0, error); + break; + + default: + error.SetErrorStringWithFormat("unrecognized short option '%c'", + short_option); + break; + } + + return error; } -void -OptionGroupWatchpoint::OptionParsingStarting (CommandInterpreter &interpreter) -{ - watch_type_specified = false; - watch_type = eWatchInvalid; - watch_size = 0; -} - - -const OptionDefinition* -OptionGroupWatchpoint::GetDefinitions () -{ - return g_option_table; +void OptionGroupWatchpoint::OptionParsingStarting( + ExecutionContext *execution_context) { + watch_type_specified = false; + watch_type = eWatchInvalid; + watch_size = 0; } -uint32_t -OptionGroupWatchpoint::GetNumDefinitions () -{ - return llvm::array_lengthof(g_option_table); +llvm::ArrayRef<OptionDefinition> OptionGroupWatchpoint::GetDefinitions() { + return llvm::makeArrayRef(g_option_table); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp index 8f136a5..58de32c 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp @@ -19,720 +19,608 @@ using namespace lldb; using namespace lldb_private; - //------------------------------------------------------------------------- // Get this value as a uint64_t value if it is encoded as a boolean, -// uint64_t or int64_t. Other types will cause "fail_value" to be +// uint64_t or int64_t. Other types will cause "fail_value" to be // returned //------------------------------------------------------------------------- -uint64_t -OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr) -{ - if (success_ptr) - *success_ptr = true; - switch (GetType()) - { - case OptionValue::eTypeBoolean: return static_cast<OptionValueBoolean *>(this)->GetCurrentValue(); - case OptionValue::eTypeSInt64: return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue(); - case OptionValue::eTypeUInt64: return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue(); - default: - break; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -Error -OptionValue::SetSubValue (const ExecutionContext *exe_ctx, - VarSetOperationType op, - const char *name, - const char *value) -{ - Error error; - error.SetErrorStringWithFormat("SetSubValue is not supported"); - return error; -} - - -OptionValueBoolean * -OptionValue::GetAsBoolean () -{ - if (GetType () == OptionValue::eTypeBoolean) - return static_cast<OptionValueBoolean *>(this); - return nullptr; -} - -const OptionValueBoolean * -OptionValue::GetAsBoolean () const -{ - if (GetType () == OptionValue::eTypeBoolean) - return static_cast<const OptionValueBoolean *>(this); - return nullptr; -} - -const OptionValueChar * -OptionValue::GetAsChar () const -{ - if (GetType () == OptionValue::eTypeChar) - return static_cast<const OptionValueChar *>(this); - return nullptr; -} - -OptionValueChar * -OptionValue::GetAsChar () -{ - if (GetType () == OptionValue::eTypeChar) - return static_cast<OptionValueChar *>(this); - return nullptr; -} - -OptionValueFileSpec * -OptionValue::GetAsFileSpec () -{ - if (GetType () == OptionValue::eTypeFileSpec) - return static_cast<OptionValueFileSpec *>(this); - return nullptr; - -} - -const OptionValueFileSpec * -OptionValue::GetAsFileSpec () const -{ - if (GetType () == OptionValue::eTypeFileSpec) - return static_cast<const OptionValueFileSpec *>(this); - return nullptr; - -} - -OptionValueFileSpecList * -OptionValue::GetAsFileSpecList () -{ - if (GetType () == OptionValue::eTypeFileSpecList) - return static_cast<OptionValueFileSpecList *>(this); - return nullptr; - -} - -const OptionValueFileSpecList * -OptionValue::GetAsFileSpecList () const -{ - if (GetType () == OptionValue::eTypeFileSpecList) - return static_cast<const OptionValueFileSpecList *>(this); - return nullptr; - -} - -OptionValueArch * -OptionValue::GetAsArch () -{ - if (GetType () == OptionValue::eTypeArch) - return static_cast<OptionValueArch *>(this); - return nullptr; +uint64_t OptionValue::GetUInt64Value(uint64_t fail_value, bool *success_ptr) { + if (success_ptr) + *success_ptr = true; + switch (GetType()) { + case OptionValue::eTypeBoolean: + return static_cast<OptionValueBoolean *>(this)->GetCurrentValue(); + case OptionValue::eTypeSInt64: + return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue(); + case OptionValue::eTypeUInt64: + return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue(); + default: + break; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} + +Error OptionValue::SetSubValue(const ExecutionContext *exe_ctx, + VarSetOperationType op, llvm::StringRef name, + llvm::StringRef value) { + Error error; + error.SetErrorStringWithFormat("SetSubValue is not supported"); + return error; +} + +OptionValueBoolean *OptionValue::GetAsBoolean() { + if (GetType() == OptionValue::eTypeBoolean) + return static_cast<OptionValueBoolean *>(this); + return nullptr; +} + +const OptionValueBoolean *OptionValue::GetAsBoolean() const { + if (GetType() == OptionValue::eTypeBoolean) + return static_cast<const OptionValueBoolean *>(this); + return nullptr; +} + +const OptionValueChar *OptionValue::GetAsChar() const { + if (GetType() == OptionValue::eTypeChar) + return static_cast<const OptionValueChar *>(this); + return nullptr; +} + +OptionValueChar *OptionValue::GetAsChar() { + if (GetType() == OptionValue::eTypeChar) + return static_cast<OptionValueChar *>(this); + return nullptr; +} + +OptionValueFileSpec *OptionValue::GetAsFileSpec() { + if (GetType() == OptionValue::eTypeFileSpec) + return static_cast<OptionValueFileSpec *>(this); + return nullptr; } +const OptionValueFileSpec *OptionValue::GetAsFileSpec() const { + if (GetType() == OptionValue::eTypeFileSpec) + return static_cast<const OptionValueFileSpec *>(this); + return nullptr; +} -const OptionValueArch * -OptionValue::GetAsArch () const -{ - if (GetType () == OptionValue::eTypeArch) - return static_cast<const OptionValueArch *>(this); - return nullptr; +OptionValueFileSpecList *OptionValue::GetAsFileSpecList() { + if (GetType() == OptionValue::eTypeFileSpecList) + return static_cast<OptionValueFileSpecList *>(this); + return nullptr; } -OptionValueArray * -OptionValue::GetAsArray () -{ - if (GetType () == OptionValue::eTypeArray) - return static_cast<OptionValueArray *>(this); - return nullptr; +const OptionValueFileSpecList *OptionValue::GetAsFileSpecList() const { + if (GetType() == OptionValue::eTypeFileSpecList) + return static_cast<const OptionValueFileSpecList *>(this); + return nullptr; } +OptionValueArch *OptionValue::GetAsArch() { + if (GetType() == OptionValue::eTypeArch) + return static_cast<OptionValueArch *>(this); + return nullptr; +} -const OptionValueArray * -OptionValue::GetAsArray () const -{ - if (GetType () == OptionValue::eTypeArray) - return static_cast<const OptionValueArray *>(this); - return nullptr; +const OptionValueArch *OptionValue::GetAsArch() const { + if (GetType() == OptionValue::eTypeArch) + return static_cast<const OptionValueArch *>(this); + return nullptr; } -OptionValueArgs * -OptionValue::GetAsArgs () -{ - if (GetType () == OptionValue::eTypeArgs) - return static_cast<OptionValueArgs *>(this); - return nullptr; +OptionValueArray *OptionValue::GetAsArray() { + if (GetType() == OptionValue::eTypeArray) + return static_cast<OptionValueArray *>(this); + return nullptr; } +const OptionValueArray *OptionValue::GetAsArray() const { + if (GetType() == OptionValue::eTypeArray) + return static_cast<const OptionValueArray *>(this); + return nullptr; +} -const OptionValueArgs * -OptionValue::GetAsArgs () const -{ - if (GetType () == OptionValue::eTypeArgs) - return static_cast<const OptionValueArgs *>(this); - return nullptr; +OptionValueArgs *OptionValue::GetAsArgs() { + if (GetType() == OptionValue::eTypeArgs) + return static_cast<OptionValueArgs *>(this); + return nullptr; } -OptionValueDictionary * -OptionValue::GetAsDictionary () -{ - if (GetType () == OptionValue::eTypeDictionary) - return static_cast<OptionValueDictionary *>(this); - return nullptr; +const OptionValueArgs *OptionValue::GetAsArgs() const { + if (GetType() == OptionValue::eTypeArgs) + return static_cast<const OptionValueArgs *>(this); + return nullptr; } -const OptionValueDictionary * -OptionValue::GetAsDictionary () const -{ - if (GetType () == OptionValue::eTypeDictionary) - return static_cast<const OptionValueDictionary *>(this); - return nullptr; +OptionValueDictionary *OptionValue::GetAsDictionary() { + if (GetType() == OptionValue::eTypeDictionary) + return static_cast<OptionValueDictionary *>(this); + return nullptr; } -OptionValueEnumeration * -OptionValue::GetAsEnumeration () -{ - if (GetType () == OptionValue::eTypeEnum) - return static_cast<OptionValueEnumeration *>(this); - return nullptr; +const OptionValueDictionary *OptionValue::GetAsDictionary() const { + if (GetType() == OptionValue::eTypeDictionary) + return static_cast<const OptionValueDictionary *>(this); + return nullptr; } -const OptionValueEnumeration * -OptionValue::GetAsEnumeration () const -{ - if (GetType () == OptionValue::eTypeEnum) - return static_cast<const OptionValueEnumeration *>(this); - return nullptr; +OptionValueEnumeration *OptionValue::GetAsEnumeration() { + if (GetType() == OptionValue::eTypeEnum) + return static_cast<OptionValueEnumeration *>(this); + return nullptr; } -OptionValueFormat * -OptionValue::GetAsFormat () -{ - if (GetType () == OptionValue::eTypeFormat) - return static_cast<OptionValueFormat *>(this); - return nullptr; +const OptionValueEnumeration *OptionValue::GetAsEnumeration() const { + if (GetType() == OptionValue::eTypeEnum) + return static_cast<const OptionValueEnumeration *>(this); + return nullptr; } -const OptionValueFormat * -OptionValue::GetAsFormat () const -{ - if (GetType () == OptionValue::eTypeFormat) - return static_cast<const OptionValueFormat *>(this); - return nullptr; +OptionValueFormat *OptionValue::GetAsFormat() { + if (GetType() == OptionValue::eTypeFormat) + return static_cast<OptionValueFormat *>(this); + return nullptr; } -OptionValueLanguage * -OptionValue::GetAsLanguage () -{ - if (GetType () == OptionValue::eTypeLanguage) - return static_cast<OptionValueLanguage *>(this); - return NULL; +const OptionValueFormat *OptionValue::GetAsFormat() const { + if (GetType() == OptionValue::eTypeFormat) + return static_cast<const OptionValueFormat *>(this); + return nullptr; } -const OptionValueLanguage * -OptionValue::GetAsLanguage () const -{ - if (GetType () == OptionValue::eTypeLanguage) - return static_cast<const OptionValueLanguage *>(this); - return NULL; +OptionValueLanguage *OptionValue::GetAsLanguage() { + if (GetType() == OptionValue::eTypeLanguage) + return static_cast<OptionValueLanguage *>(this); + return NULL; } -OptionValueFormatEntity * -OptionValue::GetAsFormatEntity () -{ - if (GetType () == OptionValue::eTypeFormatEntity) - return static_cast<OptionValueFormatEntity *>(this); - return nullptr; +const OptionValueLanguage *OptionValue::GetAsLanguage() const { + if (GetType() == OptionValue::eTypeLanguage) + return static_cast<const OptionValueLanguage *>(this); + return NULL; } -const OptionValueFormatEntity * -OptionValue::GetAsFormatEntity () const -{ - if (GetType () == OptionValue::eTypeFormatEntity) - return static_cast<const OptionValueFormatEntity *>(this); - return nullptr; +OptionValueFormatEntity *OptionValue::GetAsFormatEntity() { + if (GetType() == OptionValue::eTypeFormatEntity) + return static_cast<OptionValueFormatEntity *>(this); + return nullptr; } -OptionValuePathMappings * -OptionValue::GetAsPathMappings () -{ - if (GetType () == OptionValue::eTypePathMap) - return static_cast<OptionValuePathMappings *>(this); - return nullptr; +const OptionValueFormatEntity *OptionValue::GetAsFormatEntity() const { + if (GetType() == OptionValue::eTypeFormatEntity) + return static_cast<const OptionValueFormatEntity *>(this); + return nullptr; } -const OptionValuePathMappings * -OptionValue::GetAsPathMappings () const -{ - if (GetType () == OptionValue::eTypePathMap) - return static_cast<const OptionValuePathMappings *>(this); - return nullptr; +OptionValuePathMappings *OptionValue::GetAsPathMappings() { + if (GetType() == OptionValue::eTypePathMap) + return static_cast<OptionValuePathMappings *>(this); + return nullptr; } -OptionValueProperties * -OptionValue::GetAsProperties () -{ - if (GetType () == OptionValue::eTypeProperties) - return static_cast<OptionValueProperties *>(this); - return nullptr; +const OptionValuePathMappings *OptionValue::GetAsPathMappings() const { + if (GetType() == OptionValue::eTypePathMap) + return static_cast<const OptionValuePathMappings *>(this); + return nullptr; } -const OptionValueProperties * -OptionValue::GetAsProperties () const -{ - if (GetType () == OptionValue::eTypeProperties) - return static_cast<const OptionValueProperties *>(this); - return nullptr; -} - -OptionValueRegex * -OptionValue::GetAsRegex () -{ - if (GetType () == OptionValue::eTypeRegex) - return static_cast<OptionValueRegex *>(this); - return nullptr; -} - -const OptionValueRegex * -OptionValue::GetAsRegex () const -{ - if (GetType () == OptionValue::eTypeRegex) - return static_cast<const OptionValueRegex *>(this); - return nullptr; -} - -OptionValueSInt64 * -OptionValue::GetAsSInt64 () -{ - if (GetType () == OptionValue::eTypeSInt64) - return static_cast<OptionValueSInt64 *>(this); - return nullptr; -} - -const OptionValueSInt64 * -OptionValue::GetAsSInt64 () const -{ - if (GetType () == OptionValue::eTypeSInt64) - return static_cast<const OptionValueSInt64 *>(this); - return nullptr; -} - -OptionValueString * -OptionValue::GetAsString () -{ - if (GetType () == OptionValue::eTypeString) - return static_cast<OptionValueString *>(this); - return nullptr; -} - -const OptionValueString * -OptionValue::GetAsString () const -{ - if (GetType () == OptionValue::eTypeString) - return static_cast<const OptionValueString *>(this); - return nullptr; -} - -OptionValueUInt64 * -OptionValue::GetAsUInt64 () -{ - if (GetType () == OptionValue::eTypeUInt64) - return static_cast<OptionValueUInt64 *>(this); - return nullptr; -} - -const OptionValueUInt64 * -OptionValue::GetAsUInt64 () const -{ - if (GetType () == OptionValue::eTypeUInt64) - return static_cast<const OptionValueUInt64 *>(this); - return nullptr; -} - -OptionValueUUID * -OptionValue::GetAsUUID () -{ - if (GetType () == OptionValue::eTypeUUID) - return static_cast<OptionValueUUID *>(this); - return nullptr; - -} - -const OptionValueUUID * -OptionValue::GetAsUUID () const -{ - if (GetType () == OptionValue::eTypeUUID) - return static_cast<const OptionValueUUID *>(this); - return nullptr; - -} - -bool -OptionValue::GetBooleanValue (bool fail_value) const -{ - const OptionValueBoolean *option_value = GetAsBoolean (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -bool -OptionValue::SetBooleanValue (bool new_value) -{ - OptionValueBoolean *option_value = GetAsBoolean (); - if (option_value) - { - option_value->SetCurrentValue(new_value); - return true; - } - return false; -} - -char -OptionValue::GetCharValue(char fail_value) const -{ - const OptionValueChar *option_value = GetAsChar(); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -char -OptionValue::SetCharValue(char new_value) -{ - OptionValueChar *option_value = GetAsChar(); - if (option_value) - { - option_value->SetCurrentValue(new_value); - return true; - } - return false; -} - -int64_t -OptionValue::GetEnumerationValue (int64_t fail_value) const -{ - const OptionValueEnumeration *option_value = GetAsEnumeration(); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -bool -OptionValue::SetEnumerationValue (int64_t value) -{ - OptionValueEnumeration *option_value = GetAsEnumeration(); - if (option_value) - { - option_value->SetCurrentValue(value); - return true; - } - return false; -} - -FileSpec -OptionValue::GetFileSpecValue () const -{ - const OptionValueFileSpec *option_value = GetAsFileSpec (); - if (option_value) - return option_value->GetCurrentValue(); - return FileSpec(); -} - - -bool -OptionValue::SetFileSpecValue (const FileSpec &file_spec) -{ - OptionValueFileSpec *option_value = GetAsFileSpec (); - if (option_value) - { - option_value->SetCurrentValue(file_spec, false); - return true; - } - return false; -} - -FileSpecList -OptionValue::GetFileSpecListValue () const -{ - const OptionValueFileSpecList *option_value = GetAsFileSpecList (); - if (option_value) - return option_value->GetCurrentValue(); - return FileSpecList(); -} - - -lldb::Format -OptionValue::GetFormatValue (lldb::Format fail_value) const -{ - const OptionValueFormat *option_value = GetAsFormat (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -bool -OptionValue::SetFormatValue (lldb::Format new_value) -{ - OptionValueFormat *option_value = GetAsFormat (); - if (option_value) - { - option_value->SetCurrentValue(new_value); - return true; - } - return false; +OptionValueProperties *OptionValue::GetAsProperties() { + if (GetType() == OptionValue::eTypeProperties) + return static_cast<OptionValueProperties *>(this); + return nullptr; +} + +const OptionValueProperties *OptionValue::GetAsProperties() const { + if (GetType() == OptionValue::eTypeProperties) + return static_cast<const OptionValueProperties *>(this); + return nullptr; +} + +OptionValueRegex *OptionValue::GetAsRegex() { + if (GetType() == OptionValue::eTypeRegex) + return static_cast<OptionValueRegex *>(this); + return nullptr; +} + +const OptionValueRegex *OptionValue::GetAsRegex() const { + if (GetType() == OptionValue::eTypeRegex) + return static_cast<const OptionValueRegex *>(this); + return nullptr; +} + +OptionValueSInt64 *OptionValue::GetAsSInt64() { + if (GetType() == OptionValue::eTypeSInt64) + return static_cast<OptionValueSInt64 *>(this); + return nullptr; +} + +const OptionValueSInt64 *OptionValue::GetAsSInt64() const { + if (GetType() == OptionValue::eTypeSInt64) + return static_cast<const OptionValueSInt64 *>(this); + return nullptr; +} + +OptionValueString *OptionValue::GetAsString() { + if (GetType() == OptionValue::eTypeString) + return static_cast<OptionValueString *>(this); + return nullptr; +} + +const OptionValueString *OptionValue::GetAsString() const { + if (GetType() == OptionValue::eTypeString) + return static_cast<const OptionValueString *>(this); + return nullptr; +} + +OptionValueUInt64 *OptionValue::GetAsUInt64() { + if (GetType() == OptionValue::eTypeUInt64) + return static_cast<OptionValueUInt64 *>(this); + return nullptr; +} + +const OptionValueUInt64 *OptionValue::GetAsUInt64() const { + if (GetType() == OptionValue::eTypeUInt64) + return static_cast<const OptionValueUInt64 *>(this); + return nullptr; +} + +OptionValueUUID *OptionValue::GetAsUUID() { + if (GetType() == OptionValue::eTypeUUID) + return static_cast<OptionValueUUID *>(this); + return nullptr; +} + +const OptionValueUUID *OptionValue::GetAsUUID() const { + if (GetType() == OptionValue::eTypeUUID) + return static_cast<const OptionValueUUID *>(this); + return nullptr; +} + +bool OptionValue::GetBooleanValue(bool fail_value) const { + const OptionValueBoolean *option_value = GetAsBoolean(); + if (option_value) + return option_value->GetCurrentValue(); + return fail_value; +} + +bool OptionValue::SetBooleanValue(bool new_value) { + OptionValueBoolean *option_value = GetAsBoolean(); + if (option_value) { + option_value->SetCurrentValue(new_value); + return true; + } + return false; +} + +char OptionValue::GetCharValue(char fail_value) const { + const OptionValueChar *option_value = GetAsChar(); + if (option_value) + return option_value->GetCurrentValue(); + return fail_value; +} + +char OptionValue::SetCharValue(char new_value) { + OptionValueChar *option_value = GetAsChar(); + if (option_value) { + option_value->SetCurrentValue(new_value); + return true; + } + return false; +} + +int64_t OptionValue::GetEnumerationValue(int64_t fail_value) const { + const OptionValueEnumeration *option_value = GetAsEnumeration(); + if (option_value) + return option_value->GetCurrentValue(); + return fail_value; +} + +bool OptionValue::SetEnumerationValue(int64_t value) { + OptionValueEnumeration *option_value = GetAsEnumeration(); + if (option_value) { + option_value->SetCurrentValue(value); + return true; + } + return false; +} + +FileSpec OptionValue::GetFileSpecValue() const { + const OptionValueFileSpec *option_value = GetAsFileSpec(); + if (option_value) + return option_value->GetCurrentValue(); + return FileSpec(); +} + +bool OptionValue::SetFileSpecValue(const FileSpec &file_spec) { + OptionValueFileSpec *option_value = GetAsFileSpec(); + if (option_value) { + option_value->SetCurrentValue(file_spec, false); + return true; + } + return false; +} + +FileSpecList OptionValue::GetFileSpecListValue() const { + const OptionValueFileSpecList *option_value = GetAsFileSpecList(); + if (option_value) + return option_value->GetCurrentValue(); + return FileSpecList(); +} + +lldb::Format OptionValue::GetFormatValue(lldb::Format fail_value) const { + const OptionValueFormat *option_value = GetAsFormat(); + if (option_value) + return option_value->GetCurrentValue(); + return fail_value; +} + +bool OptionValue::SetFormatValue(lldb::Format new_value) { + OptionValueFormat *option_value = GetAsFormat(); + if (option_value) { + option_value->SetCurrentValue(new_value); + return true; + } + return false; } lldb::LanguageType -OptionValue::GetLanguageValue (lldb::LanguageType fail_value) const -{ - const OptionValueLanguage *option_value = GetAsLanguage (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -bool -OptionValue::SetLanguageValue (lldb::LanguageType new_language) -{ - OptionValueLanguage *option_value = GetAsLanguage (); - if (option_value) - { - option_value->SetCurrentValue(new_language); - return true; - } - return false; -} - -const FormatEntity::Entry * -OptionValue::GetFormatEntity () const -{ - const OptionValueFormatEntity *option_value = GetAsFormatEntity(); - if (option_value) - return &option_value->GetCurrentValue(); - return nullptr; -} - -const RegularExpression * -OptionValue::GetRegexValue () const -{ - const OptionValueRegex *option_value = GetAsRegex (); - if (option_value) - return option_value->GetCurrentValue(); - return nullptr; -} - - -int64_t -OptionValue::GetSInt64Value (int64_t fail_value) const -{ - const OptionValueSInt64 *option_value = GetAsSInt64 (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -bool -OptionValue::SetSInt64Value (int64_t new_value) -{ - OptionValueSInt64 *option_value = GetAsSInt64 (); - if (option_value) - { - option_value->SetCurrentValue(new_value); - return true; - } - return false; -} - -const char * -OptionValue::GetStringValue (const char *fail_value) const -{ - const OptionValueString *option_value = GetAsString (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -bool -OptionValue::SetStringValue (const char *new_value) -{ - OptionValueString *option_value = GetAsString (); - if (option_value) - { - option_value->SetCurrentValue(new_value); - return true; - } - return false; -} - -uint64_t -OptionValue::GetUInt64Value (uint64_t fail_value) const -{ - const OptionValueUInt64 *option_value = GetAsUInt64 (); - if (option_value) - return option_value->GetCurrentValue(); - return fail_value; -} - -bool -OptionValue::SetUInt64Value (uint64_t new_value) -{ - OptionValueUInt64 *option_value = GetAsUInt64 (); - if (option_value) - { - option_value->SetCurrentValue(new_value); - return true; - } - return false; -} - -UUID -OptionValue::GetUUIDValue () const -{ - const OptionValueUUID *option_value = GetAsUUID(); - if (option_value) - return option_value->GetCurrentValue(); - return UUID(); -} - -bool -OptionValue::SetUUIDValue (const UUID &uuid) -{ - OptionValueUUID *option_value = GetAsUUID(); - if (option_value) - { - option_value->SetCurrentValue(uuid); - return true; - } - return false; -} - -const char * -OptionValue::GetBuiltinTypeAsCString (Type t) -{ - switch (t) - { - case eTypeInvalid: return "invalid"; - case eTypeArch: return "arch"; - case eTypeArgs: return "arguments"; - case eTypeArray: return "array"; - case eTypeBoolean: return "boolean"; - case eTypeChar: - return "char"; - case eTypeDictionary: return "dictionary"; - case eTypeEnum: return "enum"; - case eTypeFileSpec: return "file"; - case eTypeFileSpecList: return "file-list"; - case eTypeFormat: return "format"; - case eTypeFormatEntity: return "format-string"; - case eTypeLanguage: return "language"; - case eTypePathMap: return "path-map"; - case eTypeProperties: return "properties"; - case eTypeRegex: return "regex"; - case eTypeSInt64: return "int"; - case eTypeString: return "string"; - case eTypeUInt64: return "unsigned"; - case eTypeUUID: return "uuid"; - } - return nullptr; -} - - -lldb::OptionValueSP -OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t type_mask, Error &error) -{ - // If only 1 bit is set in the type mask for a dictionary or array - // then we know how to decode a value from a cstring - lldb::OptionValueSP value_sp; - switch (type_mask) - { - case 1u << eTypeArch: value_sp.reset(new OptionValueArch()); break; - case 1u << eTypeBoolean: value_sp.reset(new OptionValueBoolean(false)); break; - case 1u << eTypeChar: value_sp.reset(new OptionValueChar('\0')); break; - case 1u << eTypeFileSpec: value_sp.reset(new OptionValueFileSpec()); break; - case 1u << eTypeFormat: value_sp.reset(new OptionValueFormat(eFormatInvalid)); break; - case 1u << eTypeFormatEntity: value_sp.reset(new OptionValueFormatEntity(NULL)); break; - case 1u << eTypeLanguage: value_sp.reset(new OptionValueLanguage(eLanguageTypeUnknown)); break; - case 1u << eTypeSInt64: value_sp.reset(new OptionValueSInt64()); break; - case 1u << eTypeString: value_sp.reset(new OptionValueString()); break; - case 1u << eTypeUInt64: value_sp.reset(new OptionValueUInt64()); break; - case 1u << eTypeUUID: value_sp.reset(new OptionValueUUID()); break; - } - - if (value_sp) - error = value_sp->SetValueFromString (value_cstr, eVarSetOperationAssign); +OptionValue::GetLanguageValue(lldb::LanguageType fail_value) const { + const OptionValueLanguage *option_value = GetAsLanguage(); + if (option_value) + return option_value->GetCurrentValue(); + return fail_value; +} + +bool OptionValue::SetLanguageValue(lldb::LanguageType new_language) { + OptionValueLanguage *option_value = GetAsLanguage(); + if (option_value) { + option_value->SetCurrentValue(new_language); + return true; + } + return false; +} + +const FormatEntity::Entry *OptionValue::GetFormatEntity() const { + const OptionValueFormatEntity *option_value = GetAsFormatEntity(); + if (option_value) + return &option_value->GetCurrentValue(); + return nullptr; +} + +const RegularExpression *OptionValue::GetRegexValue() const { + const OptionValueRegex *option_value = GetAsRegex(); + if (option_value) + return option_value->GetCurrentValue(); + return nullptr; +} + +int64_t OptionValue::GetSInt64Value(int64_t fail_value) const { + const OptionValueSInt64 *option_value = GetAsSInt64(); + if (option_value) + return option_value->GetCurrentValue(); + return fail_value; +} + +bool OptionValue::SetSInt64Value(int64_t new_value) { + OptionValueSInt64 *option_value = GetAsSInt64(); + if (option_value) { + option_value->SetCurrentValue(new_value); + return true; + } + return false; +} + +llvm::StringRef OptionValue::GetStringValue(llvm::StringRef fail_value) const { + const OptionValueString *option_value = GetAsString(); + if (option_value) + return option_value->GetCurrentValueAsRef(); + return fail_value; +} + +bool OptionValue::SetStringValue(llvm::StringRef new_value) { + OptionValueString *option_value = GetAsString(); + if (option_value) { + option_value->SetCurrentValue(new_value); + return true; + } + return false; +} + +uint64_t OptionValue::GetUInt64Value(uint64_t fail_value) const { + const OptionValueUInt64 *option_value = GetAsUInt64(); + if (option_value) + return option_value->GetCurrentValue(); + return fail_value; +} + +bool OptionValue::SetUInt64Value(uint64_t new_value) { + OptionValueUInt64 *option_value = GetAsUInt64(); + if (option_value) { + option_value->SetCurrentValue(new_value); + return true; + } + return false; +} + +UUID OptionValue::GetUUIDValue() const { + const OptionValueUUID *option_value = GetAsUUID(); + if (option_value) + return option_value->GetCurrentValue(); + return UUID(); +} + +bool OptionValue::SetUUIDValue(const UUID &uuid) { + OptionValueUUID *option_value = GetAsUUID(); + if (option_value) { + option_value->SetCurrentValue(uuid); + return true; + } + return false; +} + +const char *OptionValue::GetBuiltinTypeAsCString(Type t) { + switch (t) { + case eTypeInvalid: + return "invalid"; + case eTypeArch: + return "arch"; + case eTypeArgs: + return "arguments"; + case eTypeArray: + return "array"; + case eTypeBoolean: + return "boolean"; + case eTypeChar: + return "char"; + case eTypeDictionary: + return "dictionary"; + case eTypeEnum: + return "enum"; + case eTypeFileSpec: + return "file"; + case eTypeFileSpecList: + return "file-list"; + case eTypeFormat: + return "format"; + case eTypeFormatEntity: + return "format-string"; + case eTypeLanguage: + return "language"; + case eTypePathMap: + return "path-map"; + case eTypeProperties: + return "properties"; + case eTypeRegex: + return "regex"; + case eTypeSInt64: + return "int"; + case eTypeString: + return "string"; + case eTypeUInt64: + return "unsigned"; + case eTypeUUID: + return "uuid"; + } + return nullptr; +} + +lldb::OptionValueSP OptionValue::CreateValueFromCStringForTypeMask( + const char *value_cstr, uint32_t type_mask, Error &error) { + // If only 1 bit is set in the type mask for a dictionary or array + // then we know how to decode a value from a cstring + lldb::OptionValueSP value_sp; + switch (type_mask) { + case 1u << eTypeArch: + value_sp.reset(new OptionValueArch()); + break; + case 1u << eTypeBoolean: + value_sp.reset(new OptionValueBoolean(false)); + break; + case 1u << eTypeChar: + value_sp.reset(new OptionValueChar('\0')); + break; + case 1u << eTypeFileSpec: + value_sp.reset(new OptionValueFileSpec()); + break; + case 1u << eTypeFormat: + value_sp.reset(new OptionValueFormat(eFormatInvalid)); + break; + case 1u << eTypeFormatEntity: + value_sp.reset(new OptionValueFormatEntity(NULL)); + break; + case 1u << eTypeLanguage: + value_sp.reset(new OptionValueLanguage(eLanguageTypeUnknown)); + break; + case 1u << eTypeSInt64: + value_sp.reset(new OptionValueSInt64()); + break; + case 1u << eTypeString: + value_sp.reset(new OptionValueString()); + break; + case 1u << eTypeUInt64: + value_sp.reset(new OptionValueUInt64()); + break; + case 1u << eTypeUUID: + value_sp.reset(new OptionValueUUID()); + break; + } + + if (value_sp) + error = value_sp->SetValueFromString( + llvm::StringRef::withNullAsEmpty(value_cstr), eVarSetOperationAssign); + else + error.SetErrorString("unsupported type mask"); + return value_sp; +} + +bool OptionValue::DumpQualifiedName(Stream &strm) const { + bool dumped_something = false; + lldb::OptionValueSP m_parent_sp(m_parent_wp.lock()); + if (m_parent_sp) { + if (m_parent_sp->DumpQualifiedName(strm)) + dumped_something = true; + } + ConstString name(GetName()); + if (name) { + if (dumped_something) + strm.PutChar('.'); else - error.SetErrorString("unsupported type mask"); - return value_sp; -} - -bool -OptionValue::DumpQualifiedName (Stream &strm) const -{ - bool dumped_something = false; - lldb::OptionValueSP m_parent_sp(m_parent_wp.lock()); - if (m_parent_sp) - { - if (m_parent_sp->DumpQualifiedName(strm)) - dumped_something = true; - } - ConstString name (GetName()); - if (name) - { - if (dumped_something) - strm.PutChar('.'); - else - dumped_something = true; - strm << name; - } - return dumped_something; -} - -size_t -OptionValue::AutoComplete (CommandInterpreter &interpreter, - const char *s, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - word_complete = false; - matches.Clear(); - return matches.GetSize(); -} - -Error -OptionValue::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationReplace: - error.SetErrorStringWithFormat ("%s objects do not support the 'replace' operation", GetTypeAsCString()); - break; - case eVarSetOperationInsertBefore: - error.SetErrorStringWithFormat ("%s objects do not support the 'insert-before' operation", GetTypeAsCString()); - break; - case eVarSetOperationInsertAfter: - error.SetErrorStringWithFormat ("%s objects do not support the 'insert-after' operation", GetTypeAsCString()); - break; - case eVarSetOperationRemove: - error.SetErrorStringWithFormat ("%s objects do not support the 'remove' operation", GetTypeAsCString()); - break; - case eVarSetOperationAppend: - error.SetErrorStringWithFormat ("%s objects do not support the 'append' operation", GetTypeAsCString()); - break; - case eVarSetOperationClear: - error.SetErrorStringWithFormat ("%s objects do not support the 'clear' operation", GetTypeAsCString()); - break; - case eVarSetOperationAssign: - error.SetErrorStringWithFormat ("%s objects do not support the 'assign' operation", GetTypeAsCString()); - break; - case eVarSetOperationInvalid: - error.SetErrorStringWithFormat ("invalid operation performed on a %s object", GetTypeAsCString()); - break; - } - return error; + dumped_something = true; + strm << name; + } + return dumped_something; +} + +size_t OptionValue::AutoComplete(CommandInterpreter &interpreter, + llvm::StringRef s, int match_start_point, + int max_return_elements, bool &word_complete, + StringList &matches) { + word_complete = false; + matches.Clear(); + return matches.GetSize(); +} + +Error OptionValue::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationReplace: + error.SetErrorStringWithFormat( + "%s objects do not support the 'replace' operation", + GetTypeAsCString()); + break; + case eVarSetOperationInsertBefore: + error.SetErrorStringWithFormat( + "%s objects do not support the 'insert-before' operation", + GetTypeAsCString()); + break; + case eVarSetOperationInsertAfter: + error.SetErrorStringWithFormat( + "%s objects do not support the 'insert-after' operation", + GetTypeAsCString()); + break; + case eVarSetOperationRemove: + error.SetErrorStringWithFormat( + "%s objects do not support the 'remove' operation", GetTypeAsCString()); + break; + case eVarSetOperationAppend: + error.SetErrorStringWithFormat( + "%s objects do not support the 'append' operation", GetTypeAsCString()); + break; + case eVarSetOperationClear: + error.SetErrorStringWithFormat( + "%s objects do not support the 'clear' operation", GetTypeAsCString()); + break; + case eVarSetOperationAssign: + error.SetErrorStringWithFormat( + "%s objects do not support the 'assign' operation", GetTypeAsCString()); + break; + case eVarSetOperationInvalid: + error.SetErrorStringWithFormat("invalid operation performed on a %s object", + GetTypeAsCString()); + break; + } + return error; } - diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp index 0e1ca07..3e41300 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp @@ -17,92 +17,70 @@ #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandCompletions.h" +#include "lldb/Interpreter/CommandInterpreter.h" using namespace lldb; using namespace lldb_private; -void -OptionValueArch::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueArch::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); + strm.PutCString(" = "); - if (m_current_value.IsValid()) - { - const char *arch_name = m_current_value.GetArchitectureName(); - if (arch_name) - strm.PutCString (arch_name); - } + if (m_current_value.IsValid()) { + const char *arch_name = m_current_value.GetArchitectureName(); + if (arch_name) + strm.PutCString(arch_name); } + } } -Error -OptionValueArch::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear(); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - std::string value_str = value.trim().str(); - if (m_current_value.SetTriple (value_str.c_str())) - { - m_value_was_set = true; - NotifyValueChanged(); - } - else - error.SetErrorStringWithFormat("unsupported architecture '%s'", value_str.c_str()); - break; - } - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value, op); - break; - } - return error; -} +Error OptionValueArch::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; -lldb::OptionValueSP -OptionValueArch::DeepCopy () const -{ - return OptionValueSP(new OptionValueArch(*this)); + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + std::string value_str = value.trim().str(); + if (m_current_value.SetTriple(value_str.c_str())) { + m_value_was_set = true; + NotifyValueChanged(); + } else + error.SetErrorStringWithFormat("unsupported architecture '%s'", + value_str.c_str()); + break; + } + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; } - -size_t -OptionValueArch::AutoComplete (CommandInterpreter &interpreter, - const char *s, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - word_complete = false; - matches.Clear(); - CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, - CommandCompletions::eArchitectureCompletion, - s, - match_start_point, - max_return_elements, - nullptr, - word_complete, - matches); - return matches.GetSize(); +lldb::OptionValueSP OptionValueArch::DeepCopy() const { + return OptionValueSP(new OptionValueArch(*this)); } - - - +size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter, + llvm::StringRef s, int match_start_point, + int max_return_elements, + bool &word_complete, StringList &matches) { + word_complete = false; + matches.Clear(); + CommandCompletions::InvokeCommonCompletionCallbacks( + interpreter, CommandCompletions::eArchitectureCompletion, s, + match_start_point, max_return_elements, nullptr, word_complete, matches); + return matches.GetSize(); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArgs.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArgs.cpp index e28d884..8edec77 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArgs.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArgs.cpp @@ -18,21 +18,13 @@ using namespace lldb; using namespace lldb_private; -size_t -OptionValueArgs::GetArgs (Args &args) -{ - const uint32_t size = m_values.size(); - std::vector<const char *> argv; - for (uint32_t i = 0; i<size; ++i) - { - const char *string_value = m_values[i]->GetStringValue (); - if (string_value) - argv.push_back(string_value); - } +size_t OptionValueArgs::GetArgs(Args &args) { + args.Clear(); + for (auto value : m_values) { + llvm::StringRef string_value = value->GetStringValue(); + if (!string_value.empty()) + args.AppendArgument(string_value); + } - if (argv.empty()) - args.Clear(); - else - args.SetArguments(argv.size(), &argv[0]); - return args.GetArgumentCount(); + return args.GetArgumentCount(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp index 348414f..9dc4633 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp @@ -20,340 +20,291 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueArray::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ - const Type array_element_type = ConvertTypeMaskToType (m_type_mask); +void OptionValueArray::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + const Type array_element_type = ConvertTypeMaskToType(m_type_mask); + if (dump_mask & eDumpOptionType) { + if ((GetType() == eTypeArray) && (m_type_mask != eTypeInvalid)) + strm.Printf("(%s of %ss)", GetTypeAsCString(), + GetBuiltinTypeAsCString(array_element_type)); + else + strm.Printf("(%s)", GetTypeAsCString()); + } + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - { - if ((GetType() == eTypeArray) && (m_type_mask != eTypeInvalid)) - strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(array_element_type)); - else - strm.Printf ("(%s)", GetTypeAsCString()); - } - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.Printf (" =%s", (m_values.size() > 0) ? "\n" : ""); - strm.IndentMore(); - const uint32_t size = m_values.size(); - for (uint32_t i = 0; i<size; ++i) - { - strm.Indent(); - strm.Printf("[%u]: ", i); - const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; - switch (array_element_type) - { - default: - case eTypeArray: - case eTypeDictionary: - case eTypeProperties: - case eTypeFileSpecList: - case eTypePathMap: - m_values[i]->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options); - break; - - case eTypeBoolean: - case eTypeChar: - case eTypeEnum: - case eTypeFileSpec: - case eTypeFormat: - case eTypeSInt64: - case eTypeString: - case eTypeUInt64: - case eTypeUUID: - // No need to show the type for dictionaries of simple items - m_values[i]->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options); - break; - } - if (i < (size - 1)) - strm.EOL(); - } - strm.IndentLess(); + strm.Printf(" =%s", (m_values.size() > 0) ? "\n" : ""); + strm.IndentMore(); + const uint32_t size = m_values.size(); + for (uint32_t i = 0; i < size; ++i) { + strm.Indent(); + strm.Printf("[%u]: ", i); + const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; + switch (array_element_type) { + default: + case eTypeArray: + case eTypeDictionary: + case eTypeProperties: + case eTypeFileSpecList: + case eTypePathMap: + m_values[i]->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options); + break; + + case eTypeBoolean: + case eTypeChar: + case eTypeEnum: + case eTypeFileSpec: + case eTypeFormat: + case eTypeSInt64: + case eTypeString: + case eTypeUInt64: + case eTypeUUID: + // No need to show the type for dictionaries of simple items + m_values[i]->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | + extra_dump_options); + break; + } + if (i < (size - 1)) + strm.EOL(); } + strm.IndentLess(); + } } -Error -OptionValueArray::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Args args(value.str().c_str()); - Error error = SetArgs (args, op); - if (error.Success()) - NotifyValueChanged(); - return error; +Error OptionValueArray::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Args args(value.str()); + Error error = SetArgs(args, op); + if (error.Success()) + NotifyValueChanged(); + return error; } - lldb::OptionValueSP -OptionValueArray::GetSubValue (const ExecutionContext *exe_ctx, - const char *name, - bool will_modify, - Error &error) const -{ - if (name && name[0] == '[') - { - const char *end_bracket = strchr (name+1, ']'); - if (end_bracket) - { - const char *sub_value = nullptr; - if (end_bracket[1]) - sub_value = end_bracket + 1; - std::string index_str (name+1, end_bracket); - const size_t array_count = m_values.size(); - int32_t idx = StringConvert::ToSInt32(index_str.c_str(), INT32_MAX, 0, nullptr); - if (idx != INT32_MAX) - { - ; - uint32_t new_idx = UINT32_MAX; - if (idx < 0) - { - // Access from the end of the array if the index is negative - new_idx = array_count - idx; - } - else - { - // Just a standard index - new_idx = idx; - } +OptionValueArray::GetSubValue(const ExecutionContext *exe_ctx, llvm::StringRef name, + bool will_modify, Error &error) const { + if (name.empty() || name.front() != '[') { + error.SetErrorStringWithFormat( + "invalid value path '%s', %s values only support '[<index>]' subvalues " + "where <index> is a positive or negative array index", + name.str().c_str(), GetTypeAsCString()); + return nullptr; + } - if (new_idx < array_count) - { - if (m_values[new_idx]) - { - if (sub_value) - return m_values[new_idx]->GetSubValue (exe_ctx, sub_value, will_modify, error); - else - return m_values[new_idx]; - } - } - else - { - if (array_count == 0) - error.SetErrorStringWithFormat("index %i is not valid for an empty array", idx); - else if (idx > 0) - error.SetErrorStringWithFormat("index %i out of range, valid values are 0 through %" PRIu64, idx, (uint64_t)(array_count - 1)); - else - error.SetErrorStringWithFormat("negative index %i out of range, valid values are -1 through -%" PRIu64, idx, (uint64_t)array_count); - } - } - } + name = name.drop_front(); + llvm::StringRef index, sub_value; + std::tie(index, sub_value) = name.split(']'); + if (index.size() == name.size()) { + // Couldn't find a closing bracket + return nullptr; + } + + const size_t array_count = m_values.size(); + int32_t idx = 0; + if (index.getAsInteger(0, idx)) + return nullptr; + + uint32_t new_idx = UINT32_MAX; + if (idx < 0) { + // Access from the end of the array if the index is negative + new_idx = array_count - idx; + } else { + // Just a standard index + new_idx = idx; + } + + if (new_idx < array_count) { + if (m_values[new_idx]) { + if (!sub_value.empty()) + return m_values[new_idx]->GetSubValue(exe_ctx, sub_value, + will_modify, error); + else + return m_values[new_idx]; } + } else { + if (array_count == 0) + error.SetErrorStringWithFormat( + "index %i is not valid for an empty array", idx); + else if (idx > 0) + error.SetErrorStringWithFormat( + "index %i out of range, valid values are 0 through %" PRIu64, + idx, (uint64_t)(array_count - 1)); else - { - error.SetErrorStringWithFormat("invalid value path '%s', %s values only support '[<index>]' subvalues where <index> is a positive or negative array index", name, GetTypeAsCString()); - } - return OptionValueSP(); + error.SetErrorStringWithFormat("negative index %i out of range, " + "valid values are -1 through " + "-%" PRIu64, + idx, (uint64_t)array_count); + } + return OptionValueSP(); } +size_t OptionValueArray::GetArgs(Args &args) const { + args.Clear(); + const uint32_t size = m_values.size(); + for (uint32_t i = 0; i < size; ++i) { + llvm::StringRef string_value = m_values[i]->GetStringValue(); + if (!string_value.empty()) + args.AppendArgument(string_value); + } -size_t -OptionValueArray::GetArgs (Args &args) const -{ - const uint32_t size = m_values.size(); - std::vector<const char *> argv; - for (uint32_t i = 0; i<size; ++i) - { - const char *string_value = m_values[i]->GetStringValue (); - if (string_value) - argv.push_back(string_value); - } - - if (argv.empty()) - args.Clear(); - else - args.SetArguments(argv.size(), &argv[0]); - return args.GetArgumentCount(); + return args.GetArgumentCount(); } -Error -OptionValueArray::SetArgs (const Args &args, VarSetOperationType op) -{ - Error error; - const size_t argc = args.GetArgumentCount(); - switch (op) - { - case eVarSetOperationInvalid: - error.SetErrorString("unsupported operation"); - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - if (argc > 1) - { - uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); - const uint32_t count = GetSize(); - if (idx > count) - { - error.SetErrorStringWithFormat("invalid insert array index %u, index must be 0 through %u", idx, count); - } - else - { - if (op == eVarSetOperationInsertAfter) - ++idx; - for (size_t i=1; i<argc; ++i, ++idx) - { - lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i), - m_type_mask, - error)); - if (value_sp) - { - if (error.Fail()) - return error; - if (idx >= m_values.size()) - m_values.push_back(value_sp); - else - m_values.insert(m_values.begin() + idx, value_sp); - } - else - { - error.SetErrorString("array of complex types must subclass OptionValueArray"); - return error; - } - } - } - } - else - { - error.SetErrorString("insert operation takes an array index followed by one or more values"); - } - break; - - case eVarSetOperationRemove: - if (argc > 0) - { - const uint32_t size = m_values.size(); - std::vector<int> remove_indexes; - bool all_indexes_valid = true; - size_t i; - for (i=0; i<argc; ++i) - { - const size_t idx = - StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); - if (idx >= size) - { - all_indexes_valid = false; - break; - } - else - remove_indexes.push_back(idx); - } - - if (all_indexes_valid) - { - size_t num_remove_indexes = remove_indexes.size(); - if (num_remove_indexes) - { - // Sort and then erase in reverse so indexes are always valid - if (num_remove_indexes > 1) - { - std::sort(remove_indexes.begin(), remove_indexes.end()); - for (std::vector<int>::const_reverse_iterator pos = remove_indexes.rbegin(), end = remove_indexes.rend(); pos != end; ++pos) - { - m_values.erase(m_values.begin() + *pos); - } - } - else - { - // Only one index - m_values.erase(m_values.begin() + remove_indexes.front()); - } - } - } +Error OptionValueArray::SetArgs(const Args &args, VarSetOperationType op) { + Error error; + const size_t argc = args.GetArgumentCount(); + switch (op) { + case eVarSetOperationInvalid: + error.SetErrorString("unsupported operation"); + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + if (argc > 1) { + uint32_t idx = + StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = GetSize(); + if (idx > count) { + error.SetErrorStringWithFormat( + "invalid insert array index %u, index must be 0 through %u", idx, + count); + } else { + if (op == eVarSetOperationInsertAfter) + ++idx; + for (size_t i = 1; i < argc; ++i, ++idx) { + lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask( + args.GetArgumentAtIndex(i), m_type_mask, error)); + if (value_sp) { + if (error.Fail()) + return error; + if (idx >= m_values.size()) + m_values.push_back(value_sp); else - { - error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); - } - } - else - { - error.SetErrorString("remove operation takes one or more array indices"); + m_values.insert(m_values.begin() + idx, value_sp); + } else { + error.SetErrorString( + "array of complex types must subclass OptionValueArray"); + return error; + } } - break; - - case eVarSetOperationClear: - Clear (); - break; - - case eVarSetOperationReplace: - if (argc > 1) - { - uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); - const uint32_t count = GetSize(); - if (idx > count) - { - error.SetErrorStringWithFormat("invalid replace array index %u, index must be 0 through %u", idx, count); - } - else - { - for (size_t i=1; i<argc; ++i, ++idx) - { - lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i), - m_type_mask, - error)); - if (value_sp) - { - if (error.Fail()) - return error; - if (idx < count) - m_values[idx] = value_sp; - else - m_values.push_back(value_sp); - } - else - { - error.SetErrorString("array of complex types must subclass OptionValueArray"); - return error; - } - } + } + } else { + error.SetErrorString("insert operation takes an array index followed by " + "one or more values"); + } + break; + + case eVarSetOperationRemove: + if (argc > 0) { + const uint32_t size = m_values.size(); + std::vector<int> remove_indexes; + bool all_indexes_valid = true; + size_t i; + for (i = 0; i < argc; ++i) { + const size_t idx = + StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + if (idx >= size) { + all_indexes_valid = false; + break; + } else + remove_indexes.push_back(idx); + } + + if (all_indexes_valid) { + size_t num_remove_indexes = remove_indexes.size(); + if (num_remove_indexes) { + // Sort and then erase in reverse so indexes are always valid + if (num_remove_indexes > 1) { + std::sort(remove_indexes.begin(), remove_indexes.end()); + for (std::vector<int>::const_reverse_iterator + pos = remove_indexes.rbegin(), + end = remove_indexes.rend(); + pos != end; ++pos) { + m_values.erase(m_values.begin() + *pos); } + } else { + // Only one index + m_values.erase(m_values.begin() + remove_indexes.front()); + } } - else - { - error.SetErrorString("replace operation takes an array index followed by one or more values"); - } - break; - - case eVarSetOperationAssign: - m_values.clear(); - // Fall through to append case - LLVM_FALLTHROUGH; - case eVarSetOperationAppend: - for (size_t i=0; i<argc; ++i) - { - lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i), - m_type_mask, - error)); - if (value_sp) - { - if (error.Fail()) - return error; - m_value_was_set = true; - AppendValue(value_sp); - } + } else { + error.SetErrorStringWithFormat( + "invalid array index '%s', aborting remove operation", + args.GetArgumentAtIndex(i)); + } + } else { + error.SetErrorString("remove operation takes one or more array indices"); + } + break; + + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationReplace: + if (argc > 1) { + uint32_t idx = + StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = GetSize(); + if (idx > count) { + error.SetErrorStringWithFormat( + "invalid replace array index %u, index must be 0 through %u", idx, + count); + } else { + for (size_t i = 1; i < argc; ++i, ++idx) { + lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask( + args.GetArgumentAtIndex(i), m_type_mask, error)); + if (value_sp) { + if (error.Fail()) + return error; + if (idx < count) + m_values[idx] = value_sp; else - { - error.SetErrorString("array of complex types must subclass OptionValueArray"); - } + m_values.push_back(value_sp); + } else { + error.SetErrorString( + "array of complex types must subclass OptionValueArray"); + return error; + } } - break; + } + } else { + error.SetErrorString("replace operation takes an array index followed by " + "one or more values"); } - return error; -} + break; -lldb::OptionValueSP -OptionValueArray::DeepCopy () const -{ - OptionValueArray *copied_array = new OptionValueArray (m_type_mask, m_raw_value_dump); - lldb::OptionValueSP copied_value_sp(copied_array); - *static_cast<OptionValue *>(copied_array) = *this; - copied_array->m_callback = m_callback; - const uint32_t size = m_values.size(); - for (uint32_t i = 0; i<size; ++i) - { - copied_array->AppendValue (m_values[i]->DeepCopy()); + case eVarSetOperationAssign: + m_values.clear(); + // Fall through to append case + LLVM_FALLTHROUGH; + case eVarSetOperationAppend: + for (size_t i = 0; i < argc; ++i) { + lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask( + args.GetArgumentAtIndex(i), m_type_mask, error)); + if (value_sp) { + if (error.Fail()) + return error; + m_value_was_set = true; + AppendValue(value_sp); + } else { + error.SetErrorString( + "array of complex types must subclass OptionValueArray"); + } } - return copied_value_sp; + break; + } + return error; } - - +lldb::OptionValueSP OptionValueArray::DeepCopy() const { + OptionValueArray *copied_array = + new OptionValueArray(m_type_mask, m_raw_value_dump); + lldb::OptionValueSP copied_value_sp(copied_array); + *static_cast<OptionValue *>(copied_array) = *this; + copied_array->m_callback = m_callback; + const uint32_t size = m_values.size(); + for (uint32_t i = 0; i < size; ++i) { + copied_array->AppendValue(m_values[i]->DeepCopy()); + } + return copied_value_sp; +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp index dae1f4b..85799fe 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueBoolean.cpp ------------------------------------*- C++ -*-===// +//===-- OptionValueBoolean.cpp ----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,123 +15,84 @@ // Project includes #include "lldb/Core/Stream.h" #include "lldb/Core/StringList.h" +#include "lldb/Host/PosixApi.h" #include "lldb/Interpreter/Args.h" #include "llvm/ADT/STLExtras.h" using namespace lldb; using namespace lldb_private; -void -OptionValueBoolean::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueBoolean::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + // if (dump_mask & eDumpOptionName) + // DumpQualifiedName (strm); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); -// if (dump_mask & eDumpOptionName) -// DumpQualifiedName (strm); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - strm.PutCString (m_current_value ? "true" : "false"); - } + strm.PutCString(" = "); + strm.PutCString(m_current_value ? "true" : "false"); + } } -Error -OptionValueBoolean::SetValueFromString (llvm::StringRef value_str, - VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear(); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - bool success = false; - bool value = Args::StringToBoolean(value_str.str().c_str(), false, &success); - if (success) - { - m_value_was_set = true; - m_current_value = value; - NotifyValueChanged(); - } - else - { - if (value_str.size() == 0) - error.SetErrorString ("invalid boolean string value <empty>"); - else - error.SetErrorStringWithFormat ("invalid boolean string value: '%s'", - value_str.str().c_str()); - } - } - break; +Error OptionValueBoolean::SetValueFromString(llvm::StringRef value_str, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value_str, op); - break; + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + bool success = false; + bool value = Args::StringToBoolean(value_str, false, &success); + if (success) { + m_value_was_set = true; + m_current_value = value; + NotifyValueChanged(); + } else { + if (value_str.size() == 0) + error.SetErrorString("invalid boolean string value <empty>"); + else + error.SetErrorStringWithFormat("invalid boolean string value: '%s'", + value_str.str().c_str()); } - return error; -} + } break; -lldb::OptionValueSP -OptionValueBoolean::DeepCopy () const -{ - return OptionValueSP(new OptionValueBoolean(*this)); + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value_str, op); + break; + } + return error; } -size_t -OptionValueBoolean::AutoComplete (CommandInterpreter &interpreter, - const char *s, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - word_complete = false; - matches.Clear(); - struct StringEntry { - const char *string; - const size_t length; - }; - static const StringEntry g_autocomplete_entries[] = - { - { "true" , 4 }, - { "false", 5 }, - { "on" , 2 }, - { "off" , 3 }, - { "yes" , 3 }, - { "no" , 2 }, - { "1" , 1 }, - { "0" , 1 }, - }; - const size_t k_num_autocomplete_entries = llvm::array_lengthof(g_autocomplete_entries); - - if (s && s[0]) - { - const size_t s_len = strlen(s); - for (size_t i=0; i<k_num_autocomplete_entries; ++i) - { - if (s_len <= g_autocomplete_entries[i].length) - if (::strncasecmp(s, g_autocomplete_entries[i].string, s_len) == 0) - matches.AppendString(g_autocomplete_entries[i].string); - } - } - else - { - // only suggest "true" or "false" by default - for (size_t i=0; i<2; ++i) - matches.AppendString(g_autocomplete_entries[i].string); - } - return matches.GetSize(); +lldb::OptionValueSP OptionValueBoolean::DeepCopy() const { + return OptionValueSP(new OptionValueBoolean(*this)); } +size_t OptionValueBoolean::AutoComplete( + CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point, + int max_return_elements, bool &word_complete, StringList &matches) { + word_complete = false; + matches.Clear(); + static const llvm::StringRef g_autocomplete_entries[] = { + "true", "false", "on", "off", "yes", "no", "1", "0"}; + + auto entries = llvm::makeArrayRef(g_autocomplete_entries); + // only suggest "true" or "false" by default + if (s.empty()) + entries = entries.take_front(2); + for (auto entry : entries) { + if (entry.startswith_lower(s)) + matches.AppendString(entry); + } + return matches.GetSize(); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp index b5ef1d3..6423185 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp @@ -21,60 +21,48 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueChar::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ - if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); +void OptionValueChar::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - if (m_current_value != '\0') - strm.PutChar(m_current_value); - else - strm.PutCString("(null)"); - } + if (dump_mask & eDumpOptionValue) { + if (dump_mask & eDumpOptionType) + strm.PutCString(" = "); + if (m_current_value != '\0') + strm.PutChar(m_current_value); + else + strm.PutCString("(null)"); + } } -Error -OptionValueChar::SetValueFromString (llvm::StringRef value, - VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear(); - break; +Error OptionValueChar::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + break; - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - bool success = false; - char char_value = Args::StringToChar(value.str().c_str(), '\0', &success); - if (success) - { - m_current_value = char_value; - m_value_was_set = true; - } - else - error.SetErrorStringWithFormat("'%s' cannot be longer than 1 character", value.str().c_str()); - } - break; + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + bool success = false; + char char_value = Args::StringToChar(value, '\0', &success); + if (success) { + m_current_value = char_value; + m_value_was_set = true; + } else + error.SetErrorStringWithFormat("'%s' cannot be longer than 1 character", + value.str().c_str()); + } break; - default: - error = OptionValue::SetValueFromString (value.str().c_str(), op); - break; - } - return error; + default: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; } -lldb::OptionValueSP -OptionValueChar::DeepCopy () const -{ - return OptionValueSP(new OptionValueChar(*this)); +lldb::OptionValueSP OptionValueChar::DeepCopy() const { + return OptionValueSP(new OptionValueChar(*this)); } - - diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp index 24eeec3..dfba435 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -22,423 +22,301 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueDictionary::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ - const Type dict_type = ConvertTypeMaskToType (m_type_mask); +void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + const Type dict_type = ConvertTypeMaskToType(m_type_mask); + if (dump_mask & eDumpOptionType) { + if (m_type_mask != eTypeInvalid) + strm.Printf("(%s of %ss)", GetTypeAsCString(), + GetBuiltinTypeAsCString(dict_type)); + else + strm.Printf("(%s)", GetTypeAsCString()); + } + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - { - if (m_type_mask != eTypeInvalid) - strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(dict_type)); - else - strm.Printf ("(%s)", GetTypeAsCString()); - } - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" ="); - - collection::iterator pos, end = m_values.end(); - - strm.IndentMore(); - - for (pos = m_values.begin(); pos != end; ++pos) - { - OptionValue *option_value = pos->second.get(); - strm.EOL(); - strm.Indent(pos->first.GetCString()); - - const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; - switch (dict_type) - { - default: - case eTypeArray: - case eTypeDictionary: - case eTypeProperties: - case eTypeFileSpecList: - case eTypePathMap: - strm.PutChar (' '); - option_value->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options); - break; + strm.PutCString(" ="); - case eTypeBoolean: - case eTypeChar: - case eTypeEnum: - case eTypeFileSpec: - case eTypeFormat: - case eTypeSInt64: - case eTypeString: - case eTypeUInt64: - case eTypeUUID: - // No need to show the type for dictionaries of simple items - strm.PutCString("="); - option_value->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options); - break; - } - } - strm.IndentLess(); - } + collection::iterator pos, end = m_values.end(); -} + strm.IndentMore(); -size_t -OptionValueDictionary::GetArgs (Args &args) const -{ - args.Clear(); - collection::const_iterator pos, end = m_values.end(); - for (pos = m_values.begin(); pos != end; ++pos) - { - StreamString strm; - strm.Printf("%s=", pos->first.GetCString()); - pos->second->DumpValue(nullptr, strm, eDumpOptionValue|eDumpOptionRaw); - args.AppendArgument(strm.GetString().c_str()); - } - return args.GetArgumentCount(); -} + for (pos = m_values.begin(); pos != end; ++pos) { + OptionValue *option_value = pos->second.get(); + strm.EOL(); + strm.Indent(pos->first.GetCString()); -Error -OptionValueDictionary::SetArgs (const Args &args, VarSetOperationType op) -{ - Error error; - const size_t argc = args.GetArgumentCount(); - switch (op) - { - case eVarSetOperationClear: - Clear(); + const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; + switch (dict_type) { + default: + case eTypeArray: + case eTypeDictionary: + case eTypeProperties: + case eTypeFileSpecList: + case eTypePathMap: + strm.PutChar(' '); + option_value->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options); break; - - case eVarSetOperationAppend: - case eVarSetOperationReplace: - case eVarSetOperationAssign: - if (argc > 0) - { - for (size_t i=0; i<argc; ++i) - { - llvm::StringRef key_and_value(args.GetArgumentAtIndex(i)); - if (!key_and_value.empty()) - { - if (key_and_value.find('=') == llvm::StringRef::npos) - { - error.SetErrorString("assign operation takes one or more key=value arguments"); - return error; - } - - std::pair<llvm::StringRef, llvm::StringRef> kvp(key_and_value.split('=')); - llvm::StringRef key = kvp.first; - bool key_valid = false; - if (!key.empty()) - { - if (key.front() == '[') - { - // Key name starts with '[', so the key value must be in single or double quotes like: - // ['<key>'] - // ["<key>"] - if ((key.size() > 2) && (key.back() == ']')) - { - // Strip leading '[' and trailing ']' - key = key.substr(1, key.size()-2); - const char quote_char = key.front(); - if ((quote_char == '\'') || (quote_char == '"')) - { - if ((key.size() > 2) && (key.back() == quote_char)) - { - // Strip the quotes - key = key.substr(1, key.size()-2); - key_valid = true; - } - } - else - { - // square brackets, no quotes - key_valid = true; - } - } - } - else - { - // No square brackets or quotes - key_valid = true; - } - } - if (!key_valid) - { - error.SetErrorStringWithFormat("invalid key \"%s\", the key must be a bare string or surrounded by brackets with optional quotes: [<key>] or ['<key>'] or [\"<key>\"]", kvp.first.str().c_str()); - return error; - } - lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (kvp.second.data(), - m_type_mask, - error)); - if (value_sp) - { - if (error.Fail()) - return error; - m_value_was_set = true; - SetValueForKey (ConstString(key), value_sp, true); - } - else - { - error.SetErrorString("dictionaries that can contain multiple types must subclass OptionValueArray"); - } - } - else - { - error.SetErrorString("empty argument"); - } - } - } - else - { - error.SetErrorString("assign operation takes one or more key=value arguments"); - } - break; - - case eVarSetOperationRemove: - if (argc > 0) - { - for (size_t i=0; i<argc; ++i) - { - ConstString key(args.GetArgumentAtIndex(i)); - if (!DeleteValueForKey(key)) - { - error.SetErrorStringWithFormat("no value found named '%s', aborting remove operation", key.GetCString()); - break; - } - } - } - else - { - error.SetErrorString("remove operation takes one or more key arguments"); - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (llvm::StringRef(), op); + case eTypeBoolean: + case eTypeChar: + case eTypeEnum: + case eTypeFileSpec: + case eTypeFormat: + case eTypeSInt64: + case eTypeString: + case eTypeUInt64: + case eTypeUUID: + // No need to show the type for dictionaries of simple items + strm.PutCString("="); + option_value->DumpValue(exe_ctx, strm, + (dump_mask & (~eDumpOptionType)) | + extra_dump_options); break; + } } - return error; + strm.IndentLess(); + } } -Error -OptionValueDictionary::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Args args(value.str().c_str()); - Error error = SetArgs (args, op); - if (error.Success()) - NotifyValueChanged(); - return error; +size_t OptionValueDictionary::GetArgs(Args &args) const { + args.Clear(); + collection::const_iterator pos, end = m_values.end(); + for (pos = m_values.begin(); pos != end; ++pos) { + StreamString strm; + strm.Printf("%s=", pos->first.GetCString()); + pos->second->DumpValue(nullptr, strm, eDumpOptionValue | eDumpOptionRaw); + args.AppendArgument(strm.GetString()); + } + return args.GetArgumentCount(); } -lldb::OptionValueSP -OptionValueDictionary::GetSubValue (const ExecutionContext *exe_ctx, const char *name, bool will_modify, Error &error) const -{ - lldb::OptionValueSP value_sp; +Error OptionValueDictionary::SetArgs(const Args &args, VarSetOperationType op) { + Error error; + const size_t argc = args.GetArgumentCount(); + switch (op) { + case eVarSetOperationClear: + Clear(); + break; - if (name && name[0]) - { - const char *sub_name = nullptr; - ConstString key; - const char *open_bracket = ::strchr (name, '['); + case eVarSetOperationAppend: + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (argc == 0) { + error.SetErrorString( + "assign operation takes one or more key=value arguments"); + return error; + } + for (const auto &entry : args) { + if (entry.ref.empty()) { + error.SetErrorString("empty argument"); + return error; + } + if (!entry.ref.contains('=')) { + error.SetErrorString( + "assign operation takes one or more key=value arguments"); + return error; + } - if (open_bracket) - { - const char *key_start = open_bracket + 1; - const char *key_end = nullptr; - switch (open_bracket[1]) - { - case '\'': - ++key_start; - key_end = strchr(key_start, '\''); - if (key_end) - { - if (key_end[1] == ']') - { - if (key_end[2]) - sub_name = key_end + 2; - } - else - { - error.SetErrorStringWithFormat ("invalid value path '%s', single quoted key names must be formatted as ['<key>'] where <key> is a string that doesn't contain quotes", name); - return value_sp; - } - } - else - { - error.SetErrorString ("missing '] key name terminator, key name started with ['"); - return value_sp; - } - break; - case '"': - ++key_start; - key_end = strchr(key_start, '"'); - if (key_end) - { - if (key_end[1] == ']') - { - if (key_end[2]) - sub_name = key_end + 2; - break; - } - error.SetErrorStringWithFormat ("invalid value path '%s', double quoted key names must be formatted as [\"<key>\"] where <key> is a string that doesn't contain quotes", name); - return value_sp; - } - else - { - error.SetErrorString ("missing \"] key name terminator, key name started with [\""); - return value_sp; - } - break; + llvm::StringRef key, value; + std::tie(key, value) = entry.ref.split('='); + bool key_valid = false; + if (key.empty()) { + error.SetErrorString("empty dictionary key"); + return error; + } - default: - key_end = strchr(key_start, ']'); - if (key_end) - { - if (key_end[1]) - sub_name = key_end + 1; - } - else - { - error.SetErrorString ("missing ] key name terminator, key name started with ["); - return value_sp; - } - break; + if (key.front() == '[') { + // Key name starts with '[', so the key value must be in single or + // double quotes like: + // ['<key>'] + // ["<key>"] + if ((key.size() > 2) && (key.back() == ']')) { + // Strip leading '[' and trailing ']' + key = key.substr(1, key.size() - 2); + const char quote_char = key.front(); + if ((quote_char == '\'') || (quote_char == '"')) { + if ((key.size() > 2) && (key.back() == quote_char)) { + // Strip the quotes + key = key.substr(1, key.size() - 2); + key_valid = true; } - - if (key_start && key_end) - { - key.SetCStringWithLength (key_start, key_end - key_start); - - value_sp = GetValueForKey (key); - if (value_sp) - { - if (sub_name) - return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error); - } - else - { - error.SetErrorStringWithFormat("dictionary does not contain a value for the key name '%s'", key.GetCString()); - } - } - } - if (!value_sp && error.AsCString() == nullptr) - { - error.SetErrorStringWithFormat ("invalid value path '%s', %s values only support '[<key>]' subvalues where <key> a string value optionally delimited by single or double quotes", - name, - GetTypeAsCString()); + } else { + // square brackets, no quotes + key_valid = true; + } } + } else { + // No square brackets or quotes + key_valid = true; + } + if (!key_valid) { + error.SetErrorStringWithFormat( + "invalid key \"%s\", the key must be a bare string or " + "surrounded by brackets with optional quotes: [<key>] or " + "['<key>'] or [\"<key>\"]", + key.str().c_str()); + return error; + } + + lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask( + value.str().c_str(), m_type_mask, error)); + if (value_sp) { + if (error.Fail()) + return error; + m_value_was_set = true; + SetValueForKey(ConstString(key), value_sp, true); + } else { + error.SetErrorString("dictionaries that can contain multiple types " + "must subclass OptionValueArray"); + } } - return value_sp; -} + break; -Error -OptionValueDictionary::SetSubValue (const ExecutionContext *exe_ctx, VarSetOperationType op, const char *name, const char *value) -{ - Error error; - const bool will_modify = true; - lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error)); - if (value_sp) - error = value_sp->SetValueFromString(value, op); - else - { - if (error.AsCString() == nullptr) - error.SetErrorStringWithFormat("invalid value path '%s'", name); + case eVarSetOperationRemove: + if (argc > 0) { + for (size_t i = 0; i < argc; ++i) { + ConstString key(args.GetArgumentAtIndex(i)); + if (!DeleteValueForKey(key)) { + error.SetErrorStringWithFormat( + "no value found named '%s', aborting remove operation", + key.GetCString()); + break; + } + } + } else { + error.SetErrorString("remove operation takes one or more key arguments"); } - return error; + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(llvm::StringRef(), op); + break; + } + return error; } +Error OptionValueDictionary::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Args args(value.str()); + Error error = SetArgs(args, op); + if (error.Success()) + NotifyValueChanged(); + return error; +} lldb::OptionValueSP -OptionValueDictionary::GetValueForKey (const ConstString &key) const -{ - lldb::OptionValueSP value_sp; - collection::const_iterator pos = m_values.find (key); - if (pos != m_values.end()) - value_sp = pos->second; - return value_sp; -} +OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx, + llvm::StringRef name, bool will_modify, + Error &error) const { + lldb::OptionValueSP value_sp; + if (name.empty()) + return nullptr; -const char * -OptionValueDictionary::GetStringValueForKey (const ConstString &key) -{ - collection::const_iterator pos = m_values.find (key); - if (pos != m_values.end()) - { - OptionValueString *string_value = pos->second->GetAsString(); - if (string_value) - return string_value->GetCurrentValue(); - } + llvm::StringRef left, temp; + std::tie(left, temp) = name.split('['); + if (left.size() == name.size()) { + error.SetErrorStringWithFormat("invalid value path '%s', %s values only " + "support '[<key>]' subvalues where <key> " + "a string value optionally delimited by " + "single or double quotes", + name.str().c_str(), GetTypeAsCString()); return nullptr; -} + } + assert(!temp.empty()); + llvm::StringRef key, value; + llvm::StringRef quote_char; -bool -OptionValueDictionary::SetStringValueForKey (const ConstString &key, - const char *value, - bool can_replace) -{ - collection::const_iterator pos = m_values.find (key); - if (pos != m_values.end()) - { - if (!can_replace) - return false; - if (pos->second->GetType() == OptionValue::eTypeString) - { - pos->second->SetValueFromString(value); - return true; - } - } - m_values[key] = OptionValueSP (new OptionValueString (value)); - return true; + if (temp[0] == '\"' || temp[0] == '\'') { + quote_char = temp.take_front(); + temp = temp.drop_front(); + } -} + llvm::StringRef sub_name; + std::tie(key, sub_name) = temp.split(']'); -bool -OptionValueDictionary::SetValueForKey (const ConstString &key, - const lldb::OptionValueSP &value_sp, - bool can_replace) -{ - // Make sure the value_sp object is allowed to contain - // values of the type passed in... - if (value_sp && (m_type_mask & value_sp->GetTypeAsMask())) - { - if (!can_replace) - { - collection::const_iterator pos = m_values.find (key); - if (pos != m_values.end()) - return false; - } - m_values[key] = value_sp; - return true; - } - return false; + if (!key.consume_back(quote_char) || key.empty()) { + error.SetErrorStringWithFormat("invalid value path '%s', " + "key names must be formatted as ['<key>'] where <key> " + "is a string that doesn't contain quotes and the quote" + " char is optional", name.str().c_str()); + return nullptr; + } + + value_sp = GetValueForKey(ConstString(key)); + if (!value_sp) { + error.SetErrorStringWithFormat( + "dictionary does not contain a value for the key name '%s'", + key.str().c_str()); + return nullptr; + } + + if (sub_name.empty()) + return value_sp; + return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error); } -bool -OptionValueDictionary::DeleteValueForKey (const ConstString &key) -{ - collection::iterator pos = m_values.find (key); - if (pos != m_values.end()) - { - m_values.erase(pos); - return true; - } - return false; +Error OptionValueDictionary::SetSubValue(const ExecutionContext *exe_ctx, + VarSetOperationType op, + llvm::StringRef name, llvm::StringRef value) { + Error error; + const bool will_modify = true; + lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error)); + if (value_sp) + error = value_sp->SetValueFromString(value, op); + else { + if (error.AsCString() == nullptr) + error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str()); + } + return error; } lldb::OptionValueSP -OptionValueDictionary::DeepCopy () const -{ - OptionValueDictionary *copied_dict = new OptionValueDictionary (m_type_mask, m_raw_value_dump); - lldb::OptionValueSP copied_value_sp(copied_dict); - collection::const_iterator pos, end = m_values.end(); - for (pos = m_values.begin(); pos != end; ++pos) - { - StreamString strm; - strm.Printf("%s=", pos->first.GetCString()); - copied_dict->SetValueForKey (pos->first, pos->second->DeepCopy(), true); +OptionValueDictionary::GetValueForKey(const ConstString &key) const { + lldb::OptionValueSP value_sp; + collection::const_iterator pos = m_values.find(key); + if (pos != m_values.end()) + value_sp = pos->second; + return value_sp; +} + +bool OptionValueDictionary::SetValueForKey(const ConstString &key, + const lldb::OptionValueSP &value_sp, + bool can_replace) { + // Make sure the value_sp object is allowed to contain + // values of the type passed in... + if (value_sp && (m_type_mask & value_sp->GetTypeAsMask())) { + if (!can_replace) { + collection::const_iterator pos = m_values.find(key); + if (pos != m_values.end()) + return false; } - return copied_value_sp; + m_values[key] = value_sp; + return true; + } + return false; +} + +bool OptionValueDictionary::DeleteValueForKey(const ConstString &key) { + collection::iterator pos = m_values.find(key); + if (pos != m_values.end()) { + m_values.erase(pos); + return true; + } + return false; } +lldb::OptionValueSP OptionValueDictionary::DeepCopy() const { + OptionValueDictionary *copied_dict = + new OptionValueDictionary(m_type_mask, m_raw_value_dump); + lldb::OptionValueSP copied_value_sp(copied_dict); + collection::const_iterator pos, end = m_values.end(); + for (pos = m_values.begin(); pos != end; ++pos) { + StreamString strm; + strm.Printf("%s=", pos->first.GetCString()); + copied_dict->SetValueForKey(pos->first, pos->second->DeepCopy(), true); + } + return copied_value_sp; +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp index 0f163d1..679b5cc 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp @@ -18,146 +18,115 @@ using namespace lldb; using namespace lldb_private; -OptionValueEnumeration::OptionValueEnumeration (const OptionEnumValueElement *enumerators, - enum_type value) : - OptionValue(), - m_current_value (value), - m_default_value (value), - m_enumerations () -{ - SetEnumerations(enumerators); +OptionValueEnumeration::OptionValueEnumeration( + const OptionEnumValueElement *enumerators, enum_type value) + : OptionValue(), m_current_value(value), m_default_value(value), + m_enumerations() { + SetEnumerations(enumerators); } -OptionValueEnumeration::~OptionValueEnumeration() -{ -} +OptionValueEnumeration::~OptionValueEnumeration() {} -void -OptionValueEnumeration::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueEnumeration::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - const size_t count = m_enumerations.GetSize (); - for (size_t i=0; i<count; ++i) - { - if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) - { - strm.PutCString(m_enumerations.GetCStringAtIndex(i)); - return; - } - } - strm.Printf("%" PRIu64, (uint64_t)m_current_value); + strm.PutCString(" = "); + const size_t count = m_enumerations.GetSize(); + for (size_t i = 0; i < count; ++i) { + if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) { + strm.PutCString(m_enumerations.GetCStringAtIndex(i)); + return; + } } + strm.Printf("%" PRIu64, (uint64_t)m_current_value); + } } -Error -OptionValueEnumeration::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear (); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - ConstString const_enumerator_name(value.trim()); - const EnumerationMapEntry *enumerator_entry = m_enumerations.FindFirstValueForName (const_enumerator_name.GetCString()); - if (enumerator_entry) - { - m_current_value = enumerator_entry->value.value; - NotifyValueChanged(); - } - else - { - StreamString error_strm; - error_strm.Printf("invalid enumeration value '%s'", value.str().c_str()); - const size_t count = m_enumerations.GetSize (); - if (count) - { - error_strm.Printf(", valid values are: %s", m_enumerations.GetCStringAtIndex(0)); - for (size_t i=1; i<count; ++i) - { - error_strm.Printf (", %s", m_enumerations.GetCStringAtIndex(i)); - } - } - error.SetErrorString(error_strm.GetData()); - } - break; - } - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value, op); - break; - } - return error; -} +Error OptionValueEnumeration::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; -void -OptionValueEnumeration::SetEnumerations (const OptionEnumValueElement *enumerators) -{ - m_enumerations.Clear(); - if (enumerators) - { - for (size_t i=0; enumerators[i].string_value != nullptr; ++i) - { - ConstString const_enumerator_name(enumerators[i].string_value); - EnumeratorInfo enumerator_info = { enumerators[i].value, enumerators[i].usage }; - m_enumerations.Append (const_enumerator_name.GetCString(), enumerator_info); + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + ConstString const_enumerator_name(value.trim()); + const EnumerationMapEntry *enumerator_entry = + m_enumerations.FindFirstValueForName( + const_enumerator_name.GetStringRef()); + if (enumerator_entry) { + m_current_value = enumerator_entry->value.value; + NotifyValueChanged(); + } else { + StreamString error_strm; + error_strm.Printf("invalid enumeration value '%s'", value.str().c_str()); + const size_t count = m_enumerations.GetSize(); + if (count) { + error_strm.Printf(", valid values are: %s", + m_enumerations.GetCStringAtIndex(0).str().c_str()); + for (size_t i = 1; i < count; ++i) { + error_strm.Printf(", %s", + m_enumerations.GetCStringAtIndex(i).str().c_str()); } - m_enumerations.Sort(); + } + error.SetErrorString(error_strm.GetString()); } -} - + break; + } -lldb::OptionValueSP -OptionValueEnumeration::DeepCopy () const -{ - return OptionValueSP(new OptionValueEnumeration(*this)); + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; } -size_t -OptionValueEnumeration::AutoComplete (CommandInterpreter &interpreter, - const char *s, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - word_complete = false; - matches.Clear(); - - const uint32_t num_enumerators = m_enumerations.GetSize(); - if (s && s[0]) - { - const size_t s_len = strlen(s); - for (size_t i=0; i<num_enumerators; ++i) - { - const char *name = m_enumerations.GetCStringAtIndex(i); - if (::strncmp(s, name, s_len) == 0) - matches.AppendString(name); - } - } - else - { - // only suggest "true" or "false" by default - for (size_t i=0; i<num_enumerators; ++i) - matches.AppendString(m_enumerations.GetCStringAtIndex(i)); +void OptionValueEnumeration::SetEnumerations( + const OptionEnumValueElement *enumerators) { + m_enumerations.Clear(); + if (enumerators) { + for (size_t i = 0; enumerators[i].string_value != nullptr; ++i) { + ConstString const_enumerator_name(enumerators[i].string_value); + EnumeratorInfo enumerator_info = {enumerators[i].value, + enumerators[i].usage}; + m_enumerations.Append(const_enumerator_name.GetStringRef(), + enumerator_info); } - return matches.GetSize(); + m_enumerations.Sort(); + } } +lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const { + return OptionValueSP(new OptionValueEnumeration(*this)); +} +size_t OptionValueEnumeration::AutoComplete( + CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point, + int max_return_elements, bool &word_complete, StringList &matches) { + word_complete = false; + matches.Clear(); - + const uint32_t num_enumerators = m_enumerations.GetSize(); + if (!s.empty()) { + for (size_t i = 0; i < num_enumerators; ++i) { + llvm::StringRef name = m_enumerations.GetCStringAtIndex(i); + if (name.startswith(s)) + matches.AppendString(name); + } + } else { + // only suggest "true" or "false" by default + for (size_t i = 0; i < num_enumerators; ++i) + matches.AppendString(m_enumerations.GetCStringAtIndex(i)); + } + return matches.GetSize(); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp index 3a282f1..a6eb537 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -9,162 +9,120 @@ #include "lldb/Interpreter/OptionValueFileSpec.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/State.h" #include "lldb/DataFormatters/FormatManager.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandCompletions.h" +#include "lldb/Interpreter/CommandInterpreter.h" using namespace lldb; using namespace lldb_private; - -OptionValueFileSpec::OptionValueFileSpec (bool resolve) : - OptionValue(), - m_current_value (), - m_default_value (), - m_data_sp(), - m_data_mod_time (), - m_completion_mask (CommandCompletions::eDiskFileCompletion), - m_resolve (resolve) -{ -} - -OptionValueFileSpec::OptionValueFileSpec (const FileSpec &value, - bool resolve) : - OptionValue(), - m_current_value (value), - m_default_value (value), - m_data_sp(), - m_data_mod_time (), - m_completion_mask (CommandCompletions::eDiskFileCompletion), - m_resolve (resolve) -{ -} - -OptionValueFileSpec::OptionValueFileSpec (const FileSpec ¤t_value, - const FileSpec &default_value, - bool resolve) : - OptionValue(), - m_current_value (current_value), - m_default_value (default_value), - m_data_sp(), - m_data_mod_time (), - m_completion_mask (CommandCompletions::eDiskFileCompletion), - m_resolve (resolve) -{ -} - -void -OptionValueFileSpec::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +OptionValueFileSpec::OptionValueFileSpec(bool resolve) + : OptionValue(), m_current_value(), m_default_value(), m_data_sp(), + m_data_mod_time(), + m_completion_mask(CommandCompletions::eDiskFileCompletion), + m_resolve(resolve) {} + +OptionValueFileSpec::OptionValueFileSpec(const FileSpec &value, bool resolve) + : OptionValue(), m_current_value(value), m_default_value(value), + m_data_sp(), m_data_mod_time(), + m_completion_mask(CommandCompletions::eDiskFileCompletion), + m_resolve(resolve) {} + +OptionValueFileSpec::OptionValueFileSpec(const FileSpec ¤t_value, + const FileSpec &default_value, + bool resolve) + : OptionValue(), m_current_value(current_value), + m_default_value(default_value), m_data_sp(), m_data_mod_time(), + m_completion_mask(CommandCompletions::eDiskFileCompletion), + m_resolve(resolve) {} + +void OptionValueFileSpec::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); + strm.PutCString(" = "); - if (m_current_value) - { - strm << '"' << m_current_value.GetPath().c_str() << '"'; - } + if (m_current_value) { + strm << '"' << m_current_value.GetPath().c_str() << '"'; } + } } -Error -OptionValueFileSpec::SetValueFromString (llvm::StringRef value, - VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear (); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - if (value.size() > 0) - { - // The setting value may have whitespace, double-quotes, or single-quotes around the file - // path to indicate that internal spaces are not word breaks. Strip off any ws & quotes - // from the start and end of the file path - we aren't doing any word // breaking here so - // the quoting is unnecessary. NB this will cause a problem if someone tries to specify - // a file path that legitimately begins or ends with a " or ' character, or whitespace. - value = value.trim("\"' \t"); - m_value_was_set = true; - m_current_value.SetFile(value.str().c_str(), m_resolve); - m_data_sp.reset(); - m_data_mod_time.Clear(); - NotifyValueChanged(); - } - else - { - error.SetErrorString("invalid value string"); - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value, op); - break; +Error OptionValueFileSpec::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (value.size() > 0) { + // The setting value may have whitespace, double-quotes, or single-quotes + // around the file + // path to indicate that internal spaces are not word breaks. Strip off + // any ws & quotes + // from the start and end of the file path - we aren't doing any word // + // breaking here so + // the quoting is unnecessary. NB this will cause a problem if someone + // tries to specify + // a file path that legitimately begins or ends with a " or ' character, + // or whitespace. + value = value.trim("\"' \t"); + m_value_was_set = true; + m_current_value.SetFile(value.str(), m_resolve); + m_data_sp.reset(); + m_data_mod_time = llvm::sys::TimePoint<>(); + NotifyValueChanged(); + } else { + error.SetErrorString("invalid value string"); } - return error; + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; } -lldb::OptionValueSP -OptionValueFileSpec::DeepCopy () const -{ - return OptionValueSP(new OptionValueFileSpec(*this)); +lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const { + return OptionValueSP(new OptionValueFileSpec(*this)); } - -size_t -OptionValueFileSpec::AutoComplete (CommandInterpreter &interpreter, - const char *s, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - word_complete = false; - matches.Clear(); - CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, - m_completion_mask, - s, - match_start_point, - max_return_elements, - nullptr, - word_complete, - matches); - return matches.GetSize(); +size_t OptionValueFileSpec::AutoComplete( + CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point, + int max_return_elements, bool &word_complete, StringList &matches) { + word_complete = false; + matches.Clear(); + CommandCompletions::InvokeCommonCompletionCallbacks( + interpreter, m_completion_mask, s, match_start_point, max_return_elements, + nullptr, word_complete, matches); + return matches.GetSize(); } - - const lldb::DataBufferSP & -OptionValueFileSpec::GetFileContents(bool null_terminate) -{ - if (m_current_value) - { - const TimeValue file_mod_time = m_current_value.GetModificationTime(); - if (m_data_sp && m_data_mod_time == file_mod_time) - return m_data_sp; - if (null_terminate) - m_data_sp = m_current_value.ReadFileContentsAsCString(); - else - m_data_sp = m_current_value.ReadFileContents(); - m_data_mod_time = file_mod_time; - } - return m_data_sp; +OptionValueFileSpec::GetFileContents(bool null_terminate) { + if (m_current_value) { + const auto file_mod_time = FileSystem::GetModificationTime(m_current_value); + if (m_data_sp && m_data_mod_time == file_mod_time) + return m_data_sp; + if (null_terminate) + m_data_sp = m_current_value.ReadFileContentsAsCString(); + else + m_data_sp = m_current_value.ReadFileContents(); + m_data_mod_time = file_mod_time; + } + return m_data_sp; } - - diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp index 6a0ba11..e4bd4ba 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueFileSpecList.cpp -----------------------------*- C++ -*-===// +//===-- OptionValueFileSpecLIst.cpp -----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -20,171 +20,145 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueFileSpecList::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueFileSpecList::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.Printf (" =%s", m_current_value.GetSize() > 0 ? "\n" : ""); - strm.IndentMore(); - const uint32_t size = m_current_value.GetSize(); - for (uint32_t i = 0; i<size; ++i) - { - strm.Indent(); - strm.Printf("[%u]: ", i); - m_current_value.GetFileSpecAtIndex(i).Dump(&strm); - } - strm.IndentLess(); + strm.Printf(" =%s", m_current_value.GetSize() > 0 ? "\n" : ""); + strm.IndentMore(); + const uint32_t size = m_current_value.GetSize(); + for (uint32_t i = 0; i < size; ++i) { + strm.Indent(); + strm.Printf("[%u]: ", i); + m_current_value.GetFileSpecAtIndex(i).Dump(&strm); } + strm.IndentLess(); + } } -Error -OptionValueFileSpecList::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Error error; - Args args(value.str().c_str()); - const size_t argc = args.GetArgumentCount(); +Error OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + Args args(value.str()); + const size_t argc = args.GetArgumentCount(); - switch (op) - { - case eVarSetOperationClear: - Clear (); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - if (argc > 1) - { - uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); - const uint32_t count = m_current_value.GetSize(); - if (idx > count) - { - error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); - } - else - { - for (size_t i=1; i<argc; ++i, ++idx) - { - FileSpec file (args.GetArgumentAtIndex(i), false); - if (idx < count) - m_current_value.Replace(idx, file); - else - m_current_value.Append(file); - } - NotifyValueChanged(); - } - } - else - { - error.SetErrorString("replace operation takes an array index followed by one or more values"); - } - break; - - - - case eVarSetOperationAssign: - m_current_value.Clear(); - // Fall through to append case - LLVM_FALLTHROUGH; - case eVarSetOperationAppend: - if (argc > 0) - { - m_value_was_set = true; - for (size_t i=0; i<argc; ++i) - { - FileSpec file (args.GetArgumentAtIndex(i), false); - m_current_value.Append(file); - } - NotifyValueChanged(); - } - else - { - error.SetErrorString("assign operation takes at least one file path argument"); - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - if (argc > 1) - { - uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); - const uint32_t count = m_current_value.GetSize(); - if (idx > count) - { - error.SetErrorStringWithFormat("invalid insert file list index %u, index must be 0 through %u", idx, count); - } - else - { - if (op == eVarSetOperationInsertAfter) - ++idx; - for (size_t i=1; i<argc; ++i, ++idx) - { - FileSpec file (args.GetArgumentAtIndex(i), false); - m_current_value.Insert (idx, file); - } - NotifyValueChanged(); - } - } - else - { - error.SetErrorString("insert operation takes an array index followed by one or more values"); - } - break; - - case eVarSetOperationRemove: - if (argc > 0) - { - std::vector<int> remove_indexes; - bool all_indexes_valid = true; - size_t i; - for (i=0; all_indexes_valid && i<argc; ++i) - { - const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); - if (idx == INT32_MAX) - all_indexes_valid = false; - else - remove_indexes.push_back(idx); - } - - if (all_indexes_valid) - { - size_t num_remove_indexes = remove_indexes.size(); - if (num_remove_indexes) - { - // Sort and then erase in reverse so indexes are always valid - std::sort(remove_indexes.begin(), remove_indexes.end()); - for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j) - { - m_current_value.Remove (j); - } - } - NotifyValueChanged(); - } - else - { - error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); - } - } - else - { - error.SetErrorString("remove operation takes one or more array index"); - } - break; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value, op); - break; + case eVarSetOperationReplace: + if (argc > 1) { + uint32_t idx = + StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = m_current_value.GetSize(); + if (idx > count) { + error.SetErrorStringWithFormat( + "invalid file list index %u, index must be 0 through %u", idx, + count); + } else { + for (size_t i = 1; i < argc; ++i, ++idx) { + FileSpec file(args.GetArgumentAtIndex(i), false); + if (idx < count) + m_current_value.Replace(idx, file); + else + m_current_value.Append(file); + } + NotifyValueChanged(); + } + } else { + error.SetErrorString("replace operation takes an array index followed by " + "one or more values"); } - return error; -} + break; -lldb::OptionValueSP -OptionValueFileSpecList::DeepCopy () const -{ - return OptionValueSP(new OptionValueFileSpecList(*this)); -} + case eVarSetOperationAssign: + m_current_value.Clear(); + // Fall through to append case + LLVM_FALLTHROUGH; + case eVarSetOperationAppend: + if (argc > 0) { + m_value_was_set = true; + for (size_t i = 0; i < argc; ++i) { + FileSpec file(args.GetArgumentAtIndex(i), false); + m_current_value.Append(file); + } + NotifyValueChanged(); + } else { + error.SetErrorString( + "assign operation takes at least one file path argument"); + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + if (argc > 1) { + uint32_t idx = + StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = m_current_value.GetSize(); + if (idx > count) { + error.SetErrorStringWithFormat( + "invalid insert file list index %u, index must be 0 through %u", + idx, count); + } else { + if (op == eVarSetOperationInsertAfter) + ++idx; + for (size_t i = 1; i < argc; ++i, ++idx) { + FileSpec file(args.GetArgumentAtIndex(i), false); + m_current_value.Insert(idx, file); + } + NotifyValueChanged(); + } + } else { + error.SetErrorString("insert operation takes an array index followed by " + "one or more values"); + } + break; + + case eVarSetOperationRemove: + if (argc > 0) { + std::vector<int> remove_indexes; + bool all_indexes_valid = true; + size_t i; + for (i = 0; all_indexes_valid && i < argc; ++i) { + const int idx = + StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + if (idx == INT32_MAX) + all_indexes_valid = false; + else + remove_indexes.push_back(idx); + } + if (all_indexes_valid) { + size_t num_remove_indexes = remove_indexes.size(); + if (num_remove_indexes) { + // Sort and then erase in reverse so indexes are always valid + std::sort(remove_indexes.begin(), remove_indexes.end()); + for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) { + m_current_value.Remove(j); + } + } + NotifyValueChanged(); + } else { + error.SetErrorStringWithFormat( + "invalid array index '%s', aborting remove operation", + args.GetArgumentAtIndex(i)); + } + } else { + error.SetErrorString("remove operation takes one or more array index"); + } + break; + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; +} + +lldb::OptionValueSP OptionValueFileSpecList::DeepCopy() const { + return OptionValueSP(new OptionValueFileSpecList(*this)); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp index 1d73d58..041d8a5 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp @@ -20,59 +20,48 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueFormat::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueFormat::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - strm.PutCString (FormatManager::GetFormatAsCString (m_current_value)); - } + strm.PutCString(" = "); + strm.PutCString(FormatManager::GetFormatAsCString(m_current_value)); + } } -Error -OptionValueFormat::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear(); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - Format new_format; - error = Args::StringToFormat (value.str().c_str(), new_format, nullptr); - if (error.Success()) - { - m_value_was_set = true; - m_current_value = new_format; - NotifyValueChanged(); - } - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value, op); - break; - } - return error; -} +Error OptionValueFormat::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + Format new_format; + error = Args::StringToFormat(value.str().c_str(), new_format, nullptr); + if (error.Success()) { + m_value_was_set = true; + m_current_value = new_format; + NotifyValueChanged(); + } + } break; -lldb::OptionValueSP -OptionValueFormat::DeepCopy () const -{ - return OptionValueSP(new OptionValueFormat(*this)); + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; } +lldb::OptionValueSP OptionValueFormat::DeepCopy() const { + return OptionValueSP(new OptionValueFormat(*this)); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormatEntity.cpp index 66d8d84..03f077c 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormatEntity.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormatEntity.cpp @@ -20,121 +20,96 @@ using namespace lldb; using namespace lldb_private; - -OptionValueFormatEntity::OptionValueFormatEntity (const char *default_format) : - OptionValue(), - m_current_format (), - m_default_format (), - m_current_entry (), - m_default_entry () -{ - if (default_format && default_format[0]) - { - llvm::StringRef default_format_str(default_format); - Error error = FormatEntity::Parse(default_format_str, m_default_entry); - if (error.Success()) - { - m_default_format = default_format; - m_current_format = default_format; - m_current_entry = m_default_entry; - } +OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format) + : OptionValue(), m_current_format(), m_default_format(), m_current_entry(), + m_default_entry() { + if (default_format && default_format[0]) { + llvm::StringRef default_format_str(default_format); + Error error = FormatEntity::Parse(default_format_str, m_default_entry); + if (error.Success()) { + m_default_format = default_format; + m_current_format = default_format; + m_current_entry = m_default_entry; } + } } -bool -OptionValueFormatEntity::Clear () -{ - m_current_entry = m_default_entry; - m_current_format = m_default_format; - m_value_was_set = false; - return true; +bool OptionValueFormatEntity::Clear() { + m_current_entry = m_default_entry; + m_current_format = m_default_format; + m_value_was_set = false; + return true; } - -void -OptionValueFormatEntity::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueFormatEntity::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = \""); - strm << m_current_format.c_str() << '"'; - } + strm.PutCString(" = \""); + strm << m_current_format.c_str() << '"'; + } } -Error -OptionValueFormatEntity::SetValueFromString (llvm::StringRef value_str, - VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear(); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - // Check if the string starts with a quote character after removing leading and trailing spaces. - // If it does start with a quote character, make sure it ends with the same quote character - // and remove the quotes before we parse the format string. If the string doesn't start with - // a quote, leave the string alone and parse as is. - llvm::StringRef trimmed_value_str = value_str.trim(); - if (!trimmed_value_str.empty()) - { - const char first_char = trimmed_value_str[0]; - if (first_char == '"' || first_char == '\'') - { - const size_t trimmed_len = trimmed_value_str.size(); - if (trimmed_len == 1 || value_str[trimmed_len-1] != first_char) - { - error.SetErrorStringWithFormat("mismatched quotes"); - return error; - } - value_str = trimmed_value_str.substr(1,trimmed_len-2); - } - } - FormatEntity::Entry entry; - error = FormatEntity::Parse(value_str, entry); - if (error.Success()) - { - m_current_entry = std::move(entry); - m_current_format = value_str; - m_value_was_set = true; - NotifyValueChanged(); - } - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value_str, op); - break; +Error OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + // Check if the string starts with a quote character after removing leading + // and trailing spaces. + // If it does start with a quote character, make sure it ends with the same + // quote character + // and remove the quotes before we parse the format string. If the string + // doesn't start with + // a quote, leave the string alone and parse as is. + llvm::StringRef trimmed_value_str = value_str.trim(); + if (!trimmed_value_str.empty()) { + const char first_char = trimmed_value_str[0]; + if (first_char == '"' || first_char == '\'') { + const size_t trimmed_len = trimmed_value_str.size(); + if (trimmed_len == 1 || value_str[trimmed_len - 1] != first_char) { + error.SetErrorStringWithFormat("mismatched quotes"); + return error; + } + value_str = trimmed_value_str.substr(1, trimmed_len - 2); + } } - return error; -} + FormatEntity::Entry entry; + error = FormatEntity::Parse(value_str, entry); + if (error.Success()) { + m_current_entry = std::move(entry); + m_current_format = value_str; + m_value_was_set = true; + NotifyValueChanged(); + } + } break; -lldb::OptionValueSP -OptionValueFormatEntity::DeepCopy () const -{ - return OptionValueSP(new OptionValueFormatEntity(*this)); + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value_str, op); + break; + } + return error; } -size_t -OptionValueFormatEntity::AutoComplete (CommandInterpreter &interpreter, - const char *s, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - return FormatEntity::AutoComplete (s, match_start_point, max_return_elements, word_complete, matches); +lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const { + return OptionValueSP(new OptionValueFormatEntity(*this)); } +size_t OptionValueFormatEntity::AutoComplete( + CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point, + int max_return_elements, bool &word_complete, StringList &matches) { + return FormatEntity::AutoComplete(s, match_start_point, max_return_elements, + word_complete, matches); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueLanguage.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueLanguage.cpp index dd7173c..b3da6d3 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueLanguage.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueLanguage.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueFormat.cpp -----------------------------------*- C++ -*-===// +//===-- OptionValueLanguage.cpp ---------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -21,72 +21,61 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueLanguage::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueLanguage::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - strm.PutCString (Language::GetNameForLanguageType(m_current_value)); - } + strm.PutCString(" = "); + strm.PutCString(Language::GetNameForLanguageType(m_current_value)); + } } -Error -OptionValueLanguage::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - ConstString lang_name(value.trim()); - std::set<lldb::LanguageType> languages_for_types; - std::set<lldb::LanguageType> languages_for_expressions; - Language::GetLanguagesSupportingTypeSystems(languages_for_types, languages_for_expressions); +Error OptionValueLanguage::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + break; - LanguageType new_type = Language::GetLanguageTypeFromString(lang_name.GetCString()); - if (new_type && languages_for_types.count(new_type)) - { - m_value_was_set = true; - m_current_value = new_type; - } - else - { - StreamString error_strm; - error_strm.Printf("invalid language type '%s', ", value.str().c_str()); - error_strm.Printf("valid values are:\n"); - for (lldb::LanguageType language : languages_for_types) - { - error_strm.Printf("%s%s%s", " ", Language::GetNameForLanguageType(language), "\n"); - } - error.SetErrorString(error_strm.GetData()); - } - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString(value, op); - break; - } - return error; -} + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + ConstString lang_name(value.trim()); + std::set<lldb::LanguageType> languages_for_types; + std::set<lldb::LanguageType> languages_for_expressions; + Language::GetLanguagesSupportingTypeSystems(languages_for_types, + languages_for_expressions); + LanguageType new_type = + Language::GetLanguageTypeFromString(lang_name.GetStringRef()); + if (new_type && languages_for_types.count(new_type)) { + m_value_was_set = true; + m_current_value = new_type; + } else { + StreamString error_strm; + error_strm.Printf("invalid language type '%s', ", value.str().c_str()); + error_strm.Printf("valid values are:\n"); + for (lldb::LanguageType language : languages_for_types) { + error_strm.Printf("%s%s%s", " ", + Language::GetNameForLanguageType(language), "\n"); + } + error.SetErrorString(error_strm.GetString()); + } + } break; -lldb::OptionValueSP -OptionValueLanguage::DeepCopy () const -{ - return OptionValueSP(new OptionValueLanguage(*this)); + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; } +lldb::OptionValueSP OptionValueLanguage::DeepCopy() const { + return OptionValueSP(new OptionValueLanguage(*this)); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp index f3f146f..5b9850d 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp @@ -20,222 +20,189 @@ using namespace lldb; using namespace lldb_private; -namespace -{ - static bool - VerifyPathExists(const char *path) - { - if (path && path[0]) - return FileSpec(path, false).Exists(); - else - return false; - } +namespace { +static bool VerifyPathExists(const char *path) { + if (path && path[0]) + return FileSpec(path, false).Exists(); + else + return false; +} } - -void -OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValuePathMappings::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.Printf (" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : ""); - m_path_mappings.Dump(&strm); - } + strm.Printf(" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : ""); + m_path_mappings.Dump(&strm); + } } -Error -OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Error error; - Args args(value.str().c_str()); - const size_t argc = args.GetArgumentCount(); +Error OptionValuePathMappings::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + Args args(value.str()); + const size_t argc = args.GetArgumentCount(); - switch (op) - { - case eVarSetOperationClear: - Clear (); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - // Must be at least one index + 1 pair of paths, and the pair count must be even - if (argc >= 3 && (((argc - 1) & 1) == 0)) - { - uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); - const uint32_t count = m_path_mappings.GetSize(); - if (idx > count) - { - error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); - } - else - { - bool changed = false; - for (size_t i=1; i<argc; i += 2, ++idx) - { - const char *orginal_path = args.GetArgumentAtIndex(i); - const char *replace_path = args.GetArgumentAtIndex(i+1); - if (VerifyPathExists(replace_path)) - { - ConstString a(orginal_path); - ConstString b(replace_path); - if (!m_path_mappings.Replace (a, b, idx, m_notify_changes)) - m_path_mappings.Append(a, b, m_notify_changes); - changed = true; - } - else - { - error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path); - break; - } - } - if (changed) - NotifyValueChanged(); - } - } - else - { - error.SetErrorString("replace operation takes an array index followed by one or more path pairs"); - } - break; - - - - case eVarSetOperationAssign: - if (argc < 2 || (argc & 1)) - { - error.SetErrorString("assign operation takes one or more path pairs"); - break; - } - m_path_mappings.Clear(m_notify_changes); - // Fall through to append case - LLVM_FALLTHROUGH; - case eVarSetOperationAppend: - if (argc < 2 || (argc & 1)) - { - error.SetErrorString("append operation takes one or more path pairs"); - break; - } - else - { - bool changed = false; - for (size_t i=0; i<argc; i += 2) - { - const char *orginal_path = args.GetArgumentAtIndex(i); - const char *replace_path = args.GetArgumentAtIndex(i+1); - if (VerifyPathExists(replace_path)) - { - ConstString a(orginal_path); - ConstString b(replace_path); - m_path_mappings.Append(a, b, m_notify_changes); - m_value_was_set = true; - changed = true; - } - else - { - error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path); - break; - } - } - if (changed) - NotifyValueChanged(); - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - // Must be at least one index + 1 pair of paths, and the pair count must be even - if (argc >= 3 && (((argc - 1) & 1) == 0)) - { - uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); - const uint32_t count = m_path_mappings.GetSize(); - if (idx > count) - { - error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); - } - else - { - bool changed = false; - if (op == eVarSetOperationInsertAfter) - ++idx; - for (size_t i=1; i<argc; i += 2, ++idx) - { - const char *orginal_path = args.GetArgumentAtIndex(i); - const char *replace_path = args.GetArgumentAtIndex(i+1); - if (VerifyPathExists(replace_path)) - { - ConstString a(orginal_path); - ConstString b(replace_path); - m_path_mappings.Insert (a, b, idx, m_notify_changes); - changed = true; - } - else - { - error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path); - break; - } - } - if (changed) - NotifyValueChanged(); - } - } - else - { - error.SetErrorString("insert operation takes an array index followed by one or more path pairs"); - } - break; - - case eVarSetOperationRemove: - if (argc > 0) - { - std::vector<int> remove_indexes; - bool all_indexes_valid = true; - size_t i; - for (i=0; all_indexes_valid && i<argc; ++i) - { - const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); - if (idx == INT32_MAX) - all_indexes_valid = false; - else - remove_indexes.push_back(idx); - } - - if (all_indexes_valid) - { - size_t num_remove_indexes = remove_indexes.size(); - if (num_remove_indexes) - { - // Sort and then erase in reverse so indexes are always valid - std::sort(remove_indexes.begin(), remove_indexes.end()); - for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j) - { - m_path_mappings.Remove (j, m_notify_changes); - } - } - NotifyValueChanged(); - } - else - { - error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); - } - } - else - { - error.SetErrorString("remove operation takes one or more array index"); - } + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + + case eVarSetOperationReplace: + // Must be at least one index + 1 pair of paths, and the pair count must be + // even + if (argc >= 3 && (((argc - 1) & 1) == 0)) { + uint32_t idx = + StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = m_path_mappings.GetSize(); + if (idx > count) { + error.SetErrorStringWithFormat( + "invalid file list index %u, index must be 0 through %u", idx, + count); + } else { + bool changed = false; + for (size_t i = 1; i < argc; i += 2, ++idx) { + const char *orginal_path = args.GetArgumentAtIndex(i); + const char *replace_path = args.GetArgumentAtIndex(i + 1); + if (VerifyPathExists(replace_path)) { + ConstString a(orginal_path); + ConstString b(replace_path); + if (!m_path_mappings.Replace(a, b, idx, m_notify_changes)) + m_path_mappings.Append(a, b, m_notify_changes); + changed = true; + } else { + error.SetErrorStringWithFormat( + "the replacement path doesn't exist: \"%s\"", replace_path); break; + } + } + if (changed) + NotifyValueChanged(); + } + } else { + error.SetErrorString("replace operation takes an array index followed by " + "one or more path pairs"); + } + break; - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value, op); + case eVarSetOperationAssign: + if (argc < 2 || (argc & 1)) { + error.SetErrorString("assign operation takes one or more path pairs"); + break; + } + m_path_mappings.Clear(m_notify_changes); + // Fall through to append case + LLVM_FALLTHROUGH; + case eVarSetOperationAppend: + if (argc < 2 || (argc & 1)) { + error.SetErrorString("append operation takes one or more path pairs"); + break; + } else { + bool changed = false; + for (size_t i = 0; i < argc; i += 2) { + const char *orginal_path = args.GetArgumentAtIndex(i); + const char *replace_path = args.GetArgumentAtIndex(i + 1); + if (VerifyPathExists(replace_path)) { + ConstString a(orginal_path); + ConstString b(replace_path); + m_path_mappings.Append(a, b, m_notify_changes); + m_value_was_set = true; + changed = true; + } else { + error.SetErrorStringWithFormat( + "the replacement path doesn't exist: \"%s\"", replace_path); + break; + } + } + if (changed) + NotifyValueChanged(); + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + // Must be at least one index + 1 pair of paths, and the pair count must be + // even + if (argc >= 3 && (((argc - 1) & 1) == 0)) { + uint32_t idx = + StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + const uint32_t count = m_path_mappings.GetSize(); + if (idx > count) { + error.SetErrorStringWithFormat( + "invalid file list index %u, index must be 0 through %u", idx, + count); + } else { + bool changed = false; + if (op == eVarSetOperationInsertAfter) + ++idx; + for (size_t i = 1; i < argc; i += 2, ++idx) { + const char *orginal_path = args.GetArgumentAtIndex(i); + const char *replace_path = args.GetArgumentAtIndex(i + 1); + if (VerifyPathExists(replace_path)) { + ConstString a(orginal_path); + ConstString b(replace_path); + m_path_mappings.Insert(a, b, idx, m_notify_changes); + changed = true; + } else { + error.SetErrorStringWithFormat( + "the replacement path doesn't exist: \"%s\"", replace_path); break; + } + } + if (changed) + NotifyValueChanged(); + } + } else { + error.SetErrorString("insert operation takes an array index followed by " + "one or more path pairs"); } - return error; + break; + + case eVarSetOperationRemove: + if (argc > 0) { + std::vector<int> remove_indexes; + bool all_indexes_valid = true; + size_t i; + for (i = 0; all_indexes_valid && i < argc; ++i) { + const int idx = + StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + if (idx == INT32_MAX) + all_indexes_valid = false; + else + remove_indexes.push_back(idx); + } + + if (all_indexes_valid) { + size_t num_remove_indexes = remove_indexes.size(); + if (num_remove_indexes) { + // Sort and then erase in reverse so indexes are always valid + std::sort(remove_indexes.begin(), remove_indexes.end()); + for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) { + m_path_mappings.Remove(j, m_notify_changes); + } + } + NotifyValueChanged(); + } else { + error.SetErrorStringWithFormat( + "invalid array index '%s', aborting remove operation", + args.GetArgumentAtIndex(i)); + } + } else { + error.SetErrorString("remove operation takes one or more array index"); + } + break; + + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; } -lldb::OptionValueSP -OptionValuePathMappings::DeepCopy () const -{ - return OptionValueSP(new OptionValuePathMappings(*this)); +lldb::OptionValueSP OptionValuePathMappings::DeepCopy() const { + return OptionValueSP(new OptionValuePathMappings(*this)); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp index 7024c36..7e4df3a 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp @@ -1,4 +1,4 @@ -//===-- OptionValueProperties.cpp ---------------------------------*- C++ -*-===// +//===-- OptionValueProperties.cpp --------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -24,89 +24,67 @@ using namespace lldb; using namespace lldb_private; - -OptionValueProperties::OptionValueProperties (const ConstString &name) : - OptionValue (), - m_name (name), - m_properties (), - m_name_to_index () -{ -} - -OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) : - OptionValue (global_properties), - std::enable_shared_from_this<OptionValueProperties> (), - m_name (global_properties.m_name), - m_properties (global_properties.m_properties), - m_name_to_index (global_properties.m_name_to_index) -{ - // We now have an exact copy of "global_properties". We need to now - // find all non-global settings and copy the property values so that - // all non-global settings get new OptionValue instances created for - // them. - const size_t num_properties = m_properties.size(); - for (size_t i=0; i<num_properties; ++i) - { - // Duplicate any values that are not global when constructing properties from - // a global copy - if (m_properties[i].IsGlobal() == false) - { - lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy()); - m_properties[i].SetOptionValue(new_value_sp); - } +OptionValueProperties::OptionValueProperties(const ConstString &name) + : OptionValue(), m_name(name), m_properties(), m_name_to_index() {} + +OptionValueProperties::OptionValueProperties( + const OptionValueProperties &global_properties) + : OptionValue(global_properties), + std::enable_shared_from_this<OptionValueProperties>(), + m_name(global_properties.m_name), + m_properties(global_properties.m_properties), + m_name_to_index(global_properties.m_name_to_index) { + // We now have an exact copy of "global_properties". We need to now + // find all non-global settings and copy the property values so that + // all non-global settings get new OptionValue instances created for + // them. + const size_t num_properties = m_properties.size(); + for (size_t i = 0; i < num_properties; ++i) { + // Duplicate any values that are not global when constructing properties + // from + // a global copy + if (m_properties[i].IsGlobal() == false) { + lldb::OptionValueSP new_value_sp(m_properties[i].GetValue()->DeepCopy()); + m_properties[i].SetOptionValue(new_value_sp); } + } } - - -size_t -OptionValueProperties::GetNumProperties() const -{ - return m_properties.size(); +size_t OptionValueProperties::GetNumProperties() const { + return m_properties.size(); } - -void -OptionValueProperties::Initialize (const PropertyDefinition *defs) -{ - for (size_t i=0; defs[i].name; ++i) - { - Property property(defs[i]); - assert(property.IsValid()); - m_name_to_index.Append(property.GetName().GetCString(),m_properties.size()); - property.GetValue()->SetParent(shared_from_this()); - m_properties.push_back(property); - } - m_name_to_index.Sort(); +void OptionValueProperties::Initialize(const PropertyDefinition *defs) { + for (size_t i = 0; defs[i].name; ++i) { + Property property(defs[i]); + assert(property.IsValid()); + m_name_to_index.Append(property.GetName(), m_properties.size()); + property.GetValue()->SetParent(shared_from_this()); + m_properties.push_back(property); + } + m_name_to_index.Sort(); } -void -OptionValueProperties::SetValueChangedCallback (uint32_t property_idx, - OptionValueChangedCallback callback, - void *baton) -{ - Property *property = ProtectedGetPropertyAtIndex (property_idx); - if (property) - property->SetValueChangedCallback (callback, baton); +void OptionValueProperties::SetValueChangedCallback( + uint32_t property_idx, OptionValueChangedCallback callback, void *baton) { + Property *property = ProtectedGetPropertyAtIndex(property_idx); + if (property) + property->SetValueChangedCallback(callback, baton); } -void -OptionValueProperties::AppendProperty(const ConstString &name, - const ConstString &desc, - bool is_global, - const OptionValueSP &value_sp) -{ - Property property(name, desc, is_global, value_sp); - m_name_to_index.Append(name.GetCString(),m_properties.size()); - m_properties.push_back(property); - value_sp->SetParent (shared_from_this()); - m_name_to_index.Sort(); +void OptionValueProperties::AppendProperty(const ConstString &name, + const ConstString &desc, + bool is_global, + const OptionValueSP &value_sp) { + Property property(name, desc, is_global, value_sp); + m_name_to_index.Append(name.GetStringRef(), m_properties.size()); + m_properties.push_back(property); + value_sp->SetParent(shared_from_this()); + m_name_to_index.Sort(); } - - -//bool -//OptionValueProperties::GetQualifiedName (Stream &strm) +// bool +// OptionValueProperties::GetQualifiedName (Stream &strm) //{ // bool dumped_something = false; //// lldb::OptionValuePropertiesSP parent_sp(GetParent ()); @@ -125,686 +103,573 @@ OptionValueProperties::AppendProperty(const ConstString &name, //} // lldb::OptionValueSP -OptionValueProperties::GetValueForKey (const ExecutionContext *exe_ctx, - const ConstString &key, - bool will_modify) const -{ - lldb::OptionValueSP value_sp; - size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX); - if (idx < m_properties.size()) - value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue(); - return value_sp; +OptionValueProperties::GetValueForKey(const ExecutionContext *exe_ctx, + const ConstString &key, + bool will_modify) const { + lldb::OptionValueSP value_sp; + size_t idx = m_name_to_index.Find(key.GetStringRef(), SIZE_MAX); + if (idx < m_properties.size()) + value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue(); + return value_sp; } lldb::OptionValueSP -OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx, - const char *name, - bool will_modify, - Error &error) const -{ - lldb::OptionValueSP value_sp; - - if (name && name[0]) - { - const char *sub_name = nullptr; - ConstString key; - size_t key_len = ::strcspn (name, ".[{"); - - if (name[key_len]) - { - key.SetCStringWithLength (name, key_len); - sub_name = name + key_len; - } - else - key.SetCString (name); - - value_sp = GetValueForKey (exe_ctx, key, will_modify); - if (sub_name && value_sp) - { - switch (sub_name[0]) - { - case '.': - { - lldb::OptionValueSP return_val_sp; - return_val_sp = value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error); - if (!return_val_sp) - { - if (Properties::IsSettingExperimental(sub_name + 1)) - { - size_t experimental_len = strlen(Properties::GetExperimentalSettingsName()); - if (*(sub_name + experimental_len + 1) == '.') - return_val_sp = value_sp->GetSubValue(exe_ctx, sub_name + experimental_len + 2, will_modify, error); - // It isn't an error if an experimental setting is not present. - if (!return_val_sp) - error.Clear(); - } - } - return return_val_sp; - } - case '{': - // Predicate matching for predicates like - // "<setting-name>{<predicate>}" - // strings are parsed by the current OptionValueProperties subclass - // to mean whatever they want to. For instance a subclass of - // OptionValueProperties for a lldb_private::Target might implement: - // "target.run-args{arch==i386}" -- only set run args if the arch is i386 - // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches - // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if executable basename is "test" and arch is "x86_64" - if (sub_name[1]) - { - const char *predicate_start = sub_name + 1; - const char *predicate_end = strchr(predicate_start, '}'); - if (predicate_end) - { - std::string predicate(predicate_start, predicate_end); - if (PredicateMatches(exe_ctx, predicate.c_str())) - { - if (predicate_end[1]) - { - // Still more subvalue string to evaluate - return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error); - } - else - { - // We have a match! - break; - } - } - } - } - // Predicate didn't match or wasn't correctly formed - value_sp.reset(); - break; - - case '[': - // Array or dictionary access for subvalues like: - // "[12]" -- access 12th array element - // "['hello']" -- dictionary access of key named hello - return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error); - - default: - value_sp.reset(); - break; - } - } - } +OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx, + llvm::StringRef name, bool will_modify, + Error &error) const { + lldb::OptionValueSP value_sp; + if (name.empty()) + return OptionValueSP(); + + llvm::StringRef sub_name; + ConstString key; + size_t key_len = name.find_first_of(".[{"); + if (key_len != llvm::StringRef::npos) { + key.SetString(name.take_front(key_len)); + sub_name = name.drop_front(key_len); + } else + key.SetString(name); + + value_sp = GetValueForKey(exe_ctx, key, will_modify); + if (sub_name.empty() || !value_sp) return value_sp; -} -Error -OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx, - VarSetOperationType op, - const char *name, - const char *value) -{ - Error error; - const bool will_modify = true; - lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error)); - if (value_sp) - error = value_sp->SetValueFromString(value ? llvm::StringRef(value) : llvm::StringRef(), op); - else - { - if (error.AsCString() == nullptr) - error.SetErrorStringWithFormat("invalid value path '%s'", name); + switch (sub_name[0]) { + case '.': { + lldb::OptionValueSP return_val_sp; + return_val_sp = + value_sp->GetSubValue(exe_ctx, sub_name.drop_front(), will_modify, error); + if (!return_val_sp) { + if (Properties::IsSettingExperimental(sub_name.drop_front())) { + size_t experimental_len = + strlen(Properties::GetExperimentalSettingsName()); + if (sub_name[experimental_len + 1] == '.') + return_val_sp = value_sp->GetSubValue( + exe_ctx, sub_name.drop_front(experimental_len + 2), will_modify, error); + // It isn't an error if an experimental setting is not present. + if (!return_val_sp) + error.Clear(); + } } - return error; -} - - -ConstString -OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex(nullptr, false, idx); - if (property) - return property->GetName(); - return ConstString(); - -} - -const char * -OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex(nullptr, false, idx); - if (property) - return property->GetDescription(); - return nullptr; + return return_val_sp; + } + case '{': + // Predicate matching for predicates like + // "<setting-name>{<predicate>}" + // strings are parsed by the current OptionValueProperties subclass + // to mean whatever they want to. For instance a subclass of + // OptionValueProperties for a lldb_private::Target might implement: + // "target.run-args{arch==i386}" -- only set run args if the arch is + // i386 + // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the + // path matches + // "target.run-args{basename==test&&arch==x86_64}" -- only set run args + // if executable basename is "test" and arch is "x86_64" + if (sub_name[1]) { + llvm::StringRef predicate_start = sub_name.drop_front(); + size_t pos = predicate_start.find_first_of('}'); + if (pos != llvm::StringRef::npos) { + auto predicate = predicate_start.take_front(pos); + auto rest = predicate_start.drop_front(pos); + if (PredicateMatches(exe_ctx, predicate)) { + if (!rest.empty()) { + // Still more subvalue string to evaluate + return value_sp->GetSubValue(exe_ctx, rest, + will_modify, error); + } else { + // We have a match! + break; + } + } + } + } + // Predicate didn't match or wasn't correctly formed + value_sp.reset(); + break; + + case '[': + // Array or dictionary access for subvalues like: + // "[12]" -- access 12th array element + // "['hello']" -- dictionary access of key named hello + return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error); + + default: + value_sp.reset(); + break; + } + return value_sp; +} + +Error OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx, + VarSetOperationType op, + llvm::StringRef name, llvm::StringRef value) { + Error error; + const bool will_modify = true; + lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error)); + if (value_sp) + error = value_sp->SetValueFromString(value, op); + else { + if (error.AsCString() == nullptr) + error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str()); + } + return error; } uint32_t -OptionValueProperties::GetPropertyIndex (const ConstString &name) const -{ - return m_name_to_index.Find (name.GetCString(), SIZE_MAX); +OptionValueProperties::GetPropertyIndex(const ConstString &name) const { + return m_name_to_index.Find(name.GetStringRef(), SIZE_MAX); } const Property * -OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const -{ - return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX)); +OptionValueProperties::GetProperty(const ExecutionContext *exe_ctx, + bool will_modify, + const ConstString &name) const { + return GetPropertyAtIndex( + exe_ctx, will_modify, + m_name_to_index.Find(name.GetStringRef(), SIZE_MAX)); } -const Property * -OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const -{ - return ProtectedGetPropertyAtIndex (idx); +const Property *OptionValueProperties::GetPropertyAtIndex( + const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { + return ProtectedGetPropertyAtIndex(idx); } -lldb::OptionValueSP -OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx, - bool will_modify, - uint32_t idx) const -{ - const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx); - if (setting) - return setting->GetValue(); - return OptionValueSP(); +lldb::OptionValueSP OptionValueProperties::GetPropertyValueAtIndex( + const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { + const Property *setting = GetPropertyAtIndex(exe_ctx, will_modify, idx); + if (setting) + return setting->GetValue(); + return OptionValueSP(); } OptionValuePathMappings * -OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const -{ - OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); - if (value_sp) - return value_sp->GetAsPathMappings(); - return nullptr; +OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings( + const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { + OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx)); + if (value_sp) + return value_sp->GetAsPathMappings(); + return nullptr; } OptionValueFileSpecList * -OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const -{ - OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); - if (value_sp) - return value_sp->GetAsFileSpecList(); - return nullptr; +OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList( + const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { + OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx)); + if (value_sp) + return value_sp->GetAsFileSpecList(); + return nullptr; } -OptionValueArch * -OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - return property->GetValue()->GetAsArch(); - return nullptr; +OptionValueArch *OptionValueProperties::GetPropertyAtIndexAsOptionValueArch( + const ExecutionContext *exe_ctx, uint32_t idx) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) + return property->GetValue()->GetAsArch(); + return nullptr; } OptionValueLanguage * -OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage (const ExecutionContext *exe_ctx, uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - return property->GetValue()->GetAsLanguage(); - return nullptr; -} - -bool -OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - { - const OptionValueArray *array = value->GetAsArray(); - if (array) - return array->GetArgs(args); - else - { - const OptionValueDictionary *dict = value->GetAsDictionary(); - if (dict) - return dict->GetArgs(args); - } - } +OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage( + const ExecutionContext *exe_ctx, uint32_t idx) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) + return property->GetValue()->GetAsLanguage(); + return nullptr; +} + +bool OptionValueProperties::GetPropertyAtIndexAsArgs( + const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) { + const OptionValueArray *array = value->GetAsArray(); + if (array) + return array->GetArgs(args); + else { + const OptionValueDictionary *dict = value->GetAsDictionary(); + if (dict) + return dict->GetArgs(args); + } } - return false; -} - -bool -OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) -{ - const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - { - OptionValueArray *array = value->GetAsArray(); - if (array) - return array->SetArgs(args, eVarSetOperationAssign).Success(); - else - { - OptionValueDictionary *dict = value->GetAsDictionary(); - if (dict) - return dict->SetArgs(args, eVarSetOperationAssign).Success(); - } - } - } - return false; -} - -bool -OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetBooleanValue(fail_value); + } + return false; +} + +bool OptionValueProperties::SetPropertyAtIndexFromArgs( + const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) { + const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) { + OptionValueArray *array = value->GetAsArray(); + if (array) + return array->SetArgs(args, eVarSetOperationAssign).Success(); + else { + OptionValueDictionary *dict = value->GetAsDictionary(); + if (dict) + return dict->SetArgs(args, eVarSetOperationAssign).Success(); + } } - return fail_value; -} - -bool -OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value) -{ - const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - { - value->SetBooleanValue(new_value); - return true; - } + } + return false; +} + +bool OptionValueProperties::GetPropertyAtIndexAsBoolean( + const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetBooleanValue(fail_value); + } + return fail_value; +} + +bool OptionValueProperties::SetPropertyAtIndexAsBoolean( + const ExecutionContext *exe_ctx, uint32_t idx, bool new_value) { + const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) { + value->SetBooleanValue(new_value); + return true; } - return false; + } + return false; } OptionValueDictionary * -OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - return property->GetValue()->GetAsDictionary(); - return nullptr; -} - -int64_t -OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetEnumerationValue(fail_value); - } - return fail_value; -} - -bool -OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) -{ - const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetEnumerationValue(new_value); - } - return false; +OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary( + const ExecutionContext *exe_ctx, uint32_t idx) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) + return property->GetValue()->GetAsDictionary(); + return nullptr; +} + +int64_t OptionValueProperties::GetPropertyAtIndexAsEnumeration( + const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetEnumerationValue(fail_value); + } + return fail_value; +} + +bool OptionValueProperties::SetPropertyAtIndexAsEnumeration( + const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) { + const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetEnumerationValue(new_value); + } + return false; } const FormatEntity::Entry * -OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx) -{ - const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetFormatEntity(); - } - return nullptr; +OptionValueProperties::GetPropertyAtIndexAsFormatEntity( + const ExecutionContext *exe_ctx, uint32_t idx) { + const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetFormatEntity(); + } + return nullptr; } OptionValueFileSpec * -OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetAsFileSpec(); - } - return nullptr; -} - - -FileSpec -OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetFileSpecValue(); - } - return FileSpec(); -} - - -bool -OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec) -{ - const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetFileSpecValue(new_file_spec); - } - return false; +OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec( + const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetAsFileSpec(); + } + return nullptr; +} + +FileSpec OptionValueProperties::GetPropertyAtIndexAsFileSpec( + const ExecutionContext *exe_ctx, uint32_t idx) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetFileSpecValue(); + } + return FileSpec(); +} + +bool OptionValueProperties::SetPropertyAtIndexAsFileSpec( + const ExecutionContext *exe_ctx, uint32_t idx, + const FileSpec &new_file_spec) { + const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetFileSpecValue(new_file_spec); + } + return false; } const RegularExpression * -OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetRegexValue(); - } - return nullptr; -} - -OptionValueSInt64 * -OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetAsSInt64(); +OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex( + const ExecutionContext *exe_ctx, uint32_t idx) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetRegexValue(); + } + return nullptr; +} + +OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64( + const ExecutionContext *exe_ctx, uint32_t idx) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetAsSInt64(); + } + return nullptr; +} + +int64_t OptionValueProperties::GetPropertyAtIndexAsSInt64( + const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetSInt64Value(fail_value); + } + return fail_value; +} + +bool OptionValueProperties::SetPropertyAtIndexAsSInt64( + const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) { + const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetSInt64Value(new_value); + } + return false; +} + +llvm::StringRef OptionValueProperties::GetPropertyAtIndexAsString( + const ExecutionContext *exe_ctx, uint32_t idx, + llvm::StringRef fail_value) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetStringValue(fail_value); + } + return fail_value; +} + +bool OptionValueProperties::SetPropertyAtIndexAsString( + const ExecutionContext *exe_ctx, uint32_t idx, llvm::StringRef new_value) { + const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetStringValue(new_value); + } + return false; +} + +OptionValueString *OptionValueProperties::GetPropertyAtIndexAsOptionValueString( + const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { + OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx)); + if (value_sp) + return value_sp->GetAsString(); + return nullptr; +} + +uint64_t OptionValueProperties::GetPropertyAtIndexAsUInt64( + const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const { + const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetUInt64Value(fail_value); + } + return fail_value; +} + +bool OptionValueProperties::SetPropertyAtIndexAsUInt64( + const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value) { + const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + if (property) { + OptionValue *value = property->GetValue().get(); + if (value) + return value->SetUInt64Value(new_value); + } + return false; +} + +bool OptionValueProperties::Clear() { + const size_t num_properties = m_properties.size(); + for (size_t i = 0; i < num_properties; ++i) + m_properties[i].GetValue()->Clear(); + return true; +} + +Error OptionValueProperties::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + + // Args args(value_cstr); + // const size_t argc = args.GetArgumentCount(); + switch (op) { + case eVarSetOperationClear: + Clear(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + case eVarSetOperationRemove: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + + return error; +} + +void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + const size_t num_properties = m_properties.size(); + for (size_t i = 0; i < num_properties; ++i) { + const Property *property = GetPropertyAtIndex(exe_ctx, false, i); + if (property) { + OptionValue *option_value = property->GetValue().get(); + assert(option_value); + const bool transparent_value = option_value->ValueIsTransparent(); + property->Dump(exe_ctx, strm, dump_mask); + if (!transparent_value) + strm.EOL(); } - return nullptr; -} - -int64_t -OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetSInt64Value(fail_value); + } +} + +Error OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx, + Stream &strm, + llvm::StringRef property_path, + uint32_t dump_mask) { + Error error; + const bool will_modify = false; + lldb::OptionValueSP value_sp( + GetSubValue(exe_ctx, property_path, will_modify, error)); + if (value_sp) { + if (!value_sp->ValueIsTransparent()) { + if (dump_mask & eDumpOptionName) + strm.PutCString(property_path); + if (dump_mask & ~eDumpOptionName) + strm.PutChar(' '); } - return fail_value; + value_sp->DumpValue(exe_ctx, strm, dump_mask); + } + return error; } -bool -OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) -{ - const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetSInt64Value(new_value); - } - return false; +lldb::OptionValueSP OptionValueProperties::DeepCopy() const { + llvm_unreachable("this shouldn't happen"); } -const char * -OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetStringValue(fail_value); - } - return fail_value; -} - -bool -OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value) -{ - const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); - if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetStringValue(new_value); - } - return false; -} - -OptionValueString * -OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const -{ - OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); - if (value_sp) - return value_sp->GetAsString(); +const Property *OptionValueProperties::GetPropertyAtPath( + const ExecutionContext *exe_ctx, bool will_modify, llvm::StringRef name) const { + const Property *property = nullptr; + if (name.empty()) return nullptr; -} - + llvm::StringRef sub_name; + ConstString key; + size_t key_len = name.find_first_of(".[{"); + + if (key_len != llvm::StringRef::npos) { + key.SetString(name.take_front(key_len)); + sub_name = name.drop_front(key_len); + } else + key.SetString(name); + + property = GetProperty(exe_ctx, will_modify, key); + if (sub_name.empty() || !property) + return property; -uint64_t -OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const -{ - const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); + if (sub_name[0] == '.') { + OptionValueProperties *sub_properties = + property->GetValue()->GetAsProperties(); + if (sub_properties) + return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, + sub_name.drop_front()); + } + return nullptr; +} + +void OptionValueProperties::DumpAllDescriptions(CommandInterpreter &interpreter, + Stream &strm) const { + size_t max_name_len = 0; + const size_t num_properties = m_properties.size(); + for (size_t i = 0; i < num_properties; ++i) { + const Property *property = ProtectedGetPropertyAtIndex(i); if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetUInt64Value(fail_value); - } - return fail_value; -} - -bool -OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value) -{ - const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + max_name_len = std::max<size_t>(property->GetName().size(), max_name_len); + } + for (size_t i = 0; i < num_properties; ++i) { + const Property *property = ProtectedGetPropertyAtIndex(i); if (property) - { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetUInt64Value(new_value); - } - return false; -} - -bool -OptionValueProperties::Clear () -{ - const size_t num_properties = m_properties.size(); - for (size_t i=0; i<num_properties; ++i) - m_properties[i].GetValue()->Clear(); - return true; -} - - -Error -OptionValueProperties::SetValueFromString (llvm::StringRef value, VarSetOperationType op) -{ - Error error; - -// Args args(value_cstr); -// const size_t argc = args.GetArgumentCount(); - switch (op) - { - case eVarSetOperationClear: - Clear (); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - case eVarSetOperationRemove: - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value, op); - break; - } - - return error; -} - -void -OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ - const size_t num_properties = m_properties.size(); - for (size_t i=0; i<num_properties; ++i) - { - const Property *property = GetPropertyAtIndex(exe_ctx, false, i); - if (property) - { - OptionValue *option_value = property->GetValue().get(); - assert (option_value); - const bool transparent_value = option_value->ValueIsTransparent (); - property->Dump (exe_ctx, - strm, - dump_mask); - if (!transparent_value) - strm.EOL(); + property->DumpDescription(interpreter, strm, max_name_len, false); + } +} + +void OptionValueProperties::Apropos( + llvm::StringRef keyword, + std::vector<const Property *> &matching_properties) const { + const size_t num_properties = m_properties.size(); + StreamString strm; + for (size_t i = 0; i < num_properties; ++i) { + const Property *property = ProtectedGetPropertyAtIndex(i); + if (property) { + const OptionValueProperties *properties = + property->GetValue()->GetAsProperties(); + if (properties) { + properties->Apropos(keyword, matching_properties); + } else { + bool match = false; + llvm::StringRef name = property->GetName(); + if (name.contains_lower(keyword)) + match = true; + else { + llvm::StringRef desc = property->GetDescription(); + if (desc.contains_lower(keyword)) + match = true; } - } -} - -Error -OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx, - Stream &strm, - const char *property_path, - uint32_t dump_mask) -{ - Error error; - const bool will_modify = false; - lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error)); - if (value_sp) - { - if (!value_sp->ValueIsTransparent ()) - { - if (dump_mask & eDumpOptionName) - strm.PutCString (property_path); - if (dump_mask & ~eDumpOptionName) - strm.PutChar (' '); - } - value_sp->DumpValue (exe_ctx, strm, dump_mask); - } - return error; -} - -lldb::OptionValueSP -OptionValueProperties::DeepCopy () const -{ - assert(!"this shouldn't happen"); - return lldb::OptionValueSP(); -} - -const Property * -OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx, - bool will_modify, - const char *name) const -{ - const Property *property = nullptr; - if (name && name[0]) - { - const char *sub_name = nullptr; - ConstString key; - size_t key_len = ::strcspn (name, ".[{"); - - if (name[key_len]) - { - key.SetCStringWithLength (name, key_len); - sub_name = name + key_len; - } - else - key.SetCString (name); - - property = GetProperty (exe_ctx, will_modify, key); - if (sub_name && property) - { - if (sub_name[0] == '.') - { - OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties(); - if (sub_properties) - return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1); - } - property = nullptr; - } - } - return property; -} - -void -OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter, - Stream &strm) const -{ - size_t max_name_len = 0; - const size_t num_properties = m_properties.size(); - for (size_t i=0; i<num_properties; ++i) - { - const Property *property = ProtectedGetPropertyAtIndex(i); - if (property) - max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len); - } - for (size_t i=0; i<num_properties; ++i) - { - const Property *property = ProtectedGetPropertyAtIndex(i); - if (property) - property->DumpDescription (interpreter, strm, max_name_len, false); - } -} - -void -OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const -{ - const size_t num_properties = m_properties.size(); - StreamString strm; - for (size_t i=0; i<num_properties; ++i) - { - const Property *property = ProtectedGetPropertyAtIndex(i); - if (property) - { - const OptionValueProperties *properties = property->GetValue()->GetAsProperties(); - if (properties) - { - properties->Apropos (keyword, matching_properties); - } - else - { - bool match = false; - const char *name = property->GetName().GetCString(); - if (name && ::strcasestr(name, keyword)) - match = true; - else - { - const char *desc = property->GetDescription(); - if (desc && ::strcasestr(desc, keyword)) - match = true; - } - if (match) - { - matching_properties.push_back (property); - } - } + if (match) { + matching_properties.push_back(property); } + } } + } } lldb::OptionValuePropertiesSP -OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx, - const ConstString &name) -{ - lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false)); - if (option_value_sp) - { - OptionValueProperties *ov_properties = option_value_sp->GetAsProperties (); - if (ov_properties) - return ov_properties->shared_from_this(); - } - return lldb::OptionValuePropertiesSP(); +OptionValueProperties::GetSubProperty(const ExecutionContext *exe_ctx, + const ConstString &name) { + lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false)); + if (option_value_sp) { + OptionValueProperties *ov_properties = option_value_sp->GetAsProperties(); + if (ov_properties) + return ov_properties->shared_from_this(); + } + return lldb::OptionValuePropertiesSP(); } - - - diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp index ebe7ae2..86ef102 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp @@ -18,71 +18,55 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueRegex::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueRegex::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - if (m_regex.IsValid()) - { - const char *regex_text = m_regex.GetText(); - if (regex_text && regex_text[0]) - strm.Printf ("%s", regex_text); - } - else - { - - } + strm.PutCString(" = "); + if (m_regex.IsValid()) { + llvm::StringRef regex_text = m_regex.GetText(); + strm.Printf("%s", regex_text.str().c_str()); } + } } -Error -OptionValueRegex::SetValueFromString (llvm::StringRef value, - VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationInvalid: - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - error = OptionValue::SetValueFromString (value, op); - break; +Error OptionValueRegex::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationInvalid: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + error = OptionValue::SetValueFromString(value, op); + break; - case eVarSetOperationClear: - Clear(); - NotifyValueChanged(); - break; + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; - case eVarSetOperationReplace: - case eVarSetOperationAssign: - if (m_regex.Compile (value.str().c_str())) - { - m_value_was_set = true; - NotifyValueChanged(); - } - else - { - char regex_error[1024]; - if (m_regex.GetErrorAsCString(regex_error, sizeof(regex_error))) - error.SetErrorString (regex_error); - else - error.SetErrorStringWithFormat ("regex error %u", m_regex.GetErrorCode()); - } - break; + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (m_regex.Compile(value)) { + m_value_was_set = true; + NotifyValueChanged(); + } else { + char regex_error[1024]; + if (m_regex.GetErrorAsCString(regex_error, sizeof(regex_error))) + error.SetErrorString(regex_error); + else + error.SetErrorStringWithFormat("regex error %u", + m_regex.GetErrorCode()); } - return error; + break; + } + return error; } - -lldb::OptionValueSP -OptionValueRegex::DeepCopy () const -{ - return OptionValueSP(new OptionValueRegex(m_regex.GetText())); +lldb::OptionValueSP OptionValueRegex::DeepCopy() const { + return OptionValueSP(new OptionValueRegex(m_regex.GetText().str().c_str())); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp index 97cdf10..3f3844a 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp @@ -19,74 +19,62 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueSInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ - //printf ("%p: DumpValue (exe_ctx=%p, strm, mask) m_current_value = %" PRIi64 "\n", this, exe_ctx, m_current_value); +void OptionValueSInt64::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + // printf ("%p: DumpValue (exe_ctx=%p, strm, mask) m_current_value = %" PRIi64 + // "\n", this, exe_ctx, m_current_value); + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + // if (dump_mask & eDumpOptionName) + // DumpQualifiedName (strm); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); -// if (dump_mask & eDumpOptionName) -// DumpQualifiedName (strm); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - strm.Printf ("%" PRIi64, m_current_value); - } + strm.PutCString(" = "); + strm.Printf("%" PRIi64, m_current_value); + } } -Error -OptionValueSInt64::SetValueFromString (llvm::StringRef value_ref, VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear(); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - bool success = false; - std::string value_str = value_ref.trim().str(); - int64_t value = StringConvert::ToSInt64 (value_str.c_str(), 0, 0, &success); - if (success) - { - if (value >= m_min_value && value <= m_max_value) - { - m_value_was_set = true; - m_current_value = value; - NotifyValueChanged(); - } - else - error.SetErrorStringWithFormat ("%" PRIi64 " is out of range, valid values must be between %" PRIi64 " and %" PRIi64 ".", - value, - m_min_value, - m_max_value); - } - else - { - error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'", - value_ref.str().c_str()); - } - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value_ref, op); - break; +Error OptionValueSInt64::SetValueFromString(llvm::StringRef value_ref, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + bool success = false; + std::string value_str = value_ref.trim().str(); + int64_t value = StringConvert::ToSInt64(value_str.c_str(), 0, 0, &success); + if (success) { + if (value >= m_min_value && value <= m_max_value) { + m_value_was_set = true; + m_current_value = value; + NotifyValueChanged(); + } else + error.SetErrorStringWithFormat( + "%" PRIi64 " is out of range, valid values must be between %" PRIi64 + " and %" PRIi64 ".", + value, m_min_value, m_max_value); + } else { + error.SetErrorStringWithFormat("invalid int64_t string value: '%s'", + value_ref.str().c_str()); } - return error; + } break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value_ref, op); + break; + } + return error; } -lldb::OptionValueSP -OptionValueSInt64::DeepCopy () const -{ - return OptionValueSP(new OptionValueSInt64(*this)); +lldb::OptionValueSP OptionValueSInt64::DeepCopy() const { + return OptionValueSP(new OptionValueSInt64(*this)); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp index 63f006e..e61ead0 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp @@ -1,4 +1,5 @@ -//===-- OptionValueString.cpp ------------------------------------*- C++ -*-===// +//===-- OptionValueString.cpp ------------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -19,171 +20,133 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueString::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueString::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - if (!m_current_value.empty() || m_value_was_set) - { - if (m_options.Test (eOptionEncodeCharacterEscapeSequences)) - { - std::string expanded_escape_value; - Args::ExpandEscapedCharacters(m_current_value.c_str(), expanded_escape_value); - if (dump_mask & eDumpOptionRaw) - strm.Printf ("%s", expanded_escape_value.c_str()); - else - strm.Printf ("\"%s\"", expanded_escape_value.c_str()); - } - else - { - if (dump_mask & eDumpOptionRaw) - strm.Printf ("%s", m_current_value.c_str()); - else - strm.Printf ("\"%s\"", m_current_value.c_str()); - } - } + strm.PutCString(" = "); + if (!m_current_value.empty() || m_value_was_set) { + if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) { + std::string expanded_escape_value; + Args::ExpandEscapedCharacters(m_current_value.c_str(), + expanded_escape_value); + if (dump_mask & eDumpOptionRaw) + strm.Printf("%s", expanded_escape_value.c_str()); + else + strm.Printf("\"%s\"", expanded_escape_value.c_str()); + } else { + if (dump_mask & eDumpOptionRaw) + strm.Printf("%s", m_current_value.c_str()); + else + strm.Printf("\"%s\"", m_current_value.c_str()); + } } + } } -Error -OptionValueString::SetValueFromString (llvm::StringRef value, - VarSetOperationType op) -{ - Error error; +Error OptionValueString::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; - std::string value_str = value.str(); - value = value.trim(); - if (value.size() > 0) - { - switch (value.front()) - { - case '"': - case '\'': - { - if (value.size() <= 1 || value.back() != value.front()) - { - error.SetErrorString("mismatched quotes"); - return error; - } - value = value.drop_front().drop_back(); - } - break; - } - value_str = value.str(); + std::string value_str = value.str(); + value = value.trim(); + if (value.size() > 0) { + switch (value.front()) { + case '"': + case '\'': { + if (value.size() <= 1 || value.back() != value.front()) { + error.SetErrorString("mismatched quotes"); + return error; + } + value = value.drop_front().drop_back(); + } break; } + value_str = value.str(); + } - switch (op) - { - case eVarSetOperationInvalid: - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - if (m_validator) - { - error = m_validator(value_str.c_str(),m_validator_baton); - if (error.Fail()) - return error; - } - error = OptionValue::SetValueFromString (value, op); - break; + switch (op) { + case eVarSetOperationInvalid: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + if (m_validator) { + error = m_validator(value_str.c_str(), m_validator_baton); + if (error.Fail()) + return error; + } + error = OptionValue::SetValueFromString(value, op); + break; - case eVarSetOperationAppend: - { - std::string new_value(m_current_value); - if (value.size() > 0) - { - if (m_options.Test (eOptionEncodeCharacterEscapeSequences)) - { - std::string str; - Args::EncodeEscapeSequences (value_str.c_str(), str); - new_value.append(str); - } - else - new_value.append(value); - } - if (m_validator) - { - error = m_validator(new_value.c_str(),m_validator_baton); - if (error.Fail()) - return error; - } - m_current_value.assign(new_value); - NotifyValueChanged(); - } - break; + case eVarSetOperationAppend: { + std::string new_value(m_current_value); + if (value.size() > 0) { + if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) { + std::string str; + Args::EncodeEscapeSequences(value_str.c_str(), str); + new_value.append(str); + } else + new_value.append(value); + } + if (m_validator) { + error = m_validator(new_value.c_str(), m_validator_baton); + if (error.Fail()) + return error; + } + m_current_value.assign(new_value); + NotifyValueChanged(); + } break; - case eVarSetOperationClear: - Clear (); - NotifyValueChanged(); - break; + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; - case eVarSetOperationReplace: - case eVarSetOperationAssign: - if (m_validator) - { - error = m_validator(value_str.c_str(), m_validator_baton); - if (error.Fail()) - return error; - } - m_value_was_set = true; - if (m_options.Test (eOptionEncodeCharacterEscapeSequences)) - { - Args::EncodeEscapeSequences (value_str.c_str(), m_current_value); - } - else - { - SetCurrentValue (value_str.c_str()); - } - NotifyValueChanged(); - break; + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (m_validator) { + error = m_validator(value_str.c_str(), m_validator_baton); + if (error.Fail()) + return error; } - return error; + m_value_was_set = true; + if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) { + Args::EncodeEscapeSequences(value_str.c_str(), m_current_value); + } else { + SetCurrentValue(value_str); + } + NotifyValueChanged(); + break; + } + return error; } - -lldb::OptionValueSP -OptionValueString::DeepCopy () const -{ - return OptionValueSP(new OptionValueString(*this)); +lldb::OptionValueSP OptionValueString::DeepCopy() const { + return OptionValueSP(new OptionValueString(*this)); } -Error -OptionValueString::SetCurrentValue (const char *value) -{ - if (m_validator) - { - Error error(m_validator(value,m_validator_baton)); - if (error.Fail()) - return error; - } - if (value && value[0]) - m_current_value.assign (value); - else - m_current_value.clear(); - return Error(); +Error OptionValueString::SetCurrentValue(llvm::StringRef value) { + if (m_validator) { + Error error(m_validator(value.str().c_str(), m_validator_baton)); + if (error.Fail()) + return error; + } + m_current_value.assign(value); + return Error(); } -Error -OptionValueString::AppendToCurrentValue (const char *value) -{ - if (value && value[0]) - { - if (m_validator) - { - std::string new_value(m_current_value); - new_value.append(value); - Error error(m_validator(value,m_validator_baton)); - if (error.Fail()) - return error; - m_current_value.assign(new_value); - } - else - m_current_value.append (value); - } - return Error(); +Error OptionValueString::AppendToCurrentValue(const char *value) { + if (value && value[0]) { + if (m_validator) { + std::string new_value(m_current_value); + new_value.append(value); + Error error(m_validator(value, m_validator_baton)); + if (error.Fail()) + return error; + m_current_value.assign(new_value); + } else + m_current_value.append(value); + } + return Error(); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp index b414802..8986080 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp @@ -1,4 +1,5 @@ -//===-- OptionValueUInt64.cpp ------------------------------------*- C++ -*-===// +//===-- OptionValueUInt64.cpp ------------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -19,74 +20,61 @@ using namespace lldb; using namespace lldb_private; -lldb::OptionValueSP -OptionValueUInt64::Create (const char *value_cstr, Error &error) -{ - lldb::OptionValueSP value_sp (new OptionValueUInt64()); - error = value_sp->SetValueFromString (value_cstr); - if (error.Fail()) - value_sp.reset(); - return value_sp; +lldb::OptionValueSP OptionValueUInt64::Create(llvm::StringRef value_str, + Error &error) { + lldb::OptionValueSP value_sp(new OptionValueUInt64()); + error = value_sp->SetValueFromString(value_str); + if (error.Fail()) + value_sp.reset(); + return value_sp; } - -void -OptionValueUInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueUInt64::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - strm.Printf ("%" PRIu64, m_current_value); - } + strm.PutCString(" = "); + strm.Printf("%" PRIu64, m_current_value); + } } -Error -OptionValueUInt64::SetValueFromString (llvm::StringRef value_ref, VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear (); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - bool success = false; - std::string value_str = value_ref.trim().str(); - uint64_t value = StringConvert::ToUInt64 (value_str.c_str(), 0, 0, &success); - if (success) - { - m_value_was_set = true; - m_current_value = value; - NotifyValueChanged(); - } - else - { - error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'", value_str.c_str()); - } - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value_ref, op); - break; +Error OptionValueUInt64::SetValueFromString(llvm::StringRef value_ref, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + bool success = false; + std::string value_str = value_ref.trim().str(); + uint64_t value = StringConvert::ToUInt64(value_str.c_str(), 0, 0, &success); + if (success) { + m_value_was_set = true; + m_current_value = value; + NotifyValueChanged(); + } else { + error.SetErrorStringWithFormat("invalid uint64_t string value: '%s'", + value_str.c_str()); } - return error; -} + } break; -lldb::OptionValueSP -OptionValueUInt64::DeepCopy () const -{ - return OptionValueSP(new OptionValueUInt64(*this)); + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value_ref, op); + break; + } + return error; } +lldb::OptionValueSP OptionValueUInt64::DeepCopy() const { + return OptionValueSP(new OptionValueUInt64(*this)); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp index b16a9eb..3519334 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp @@ -21,105 +21,87 @@ using namespace lldb; using namespace lldb_private; -void -OptionValueUUID::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) -{ +void OptionValueUUID::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.Printf ("(%s)", GetTypeAsCString ()); - if (dump_mask & eDumpOptionValue) - { - if (dump_mask & eDumpOptionType) - strm.PutCString (" = "); - m_uuid.Dump (&strm); - } + strm.PutCString(" = "); + m_uuid.Dump(&strm); + } } -Error -OptionValueUUID::SetValueFromString (llvm::StringRef value, - VarSetOperationType op) -{ - Error error; - switch (op) - { - case eVarSetOperationClear: - Clear(); - NotifyValueChanged(); - break; - - case eVarSetOperationReplace: - case eVarSetOperationAssign: - { - if (m_uuid.SetFromCString(value.str().c_str()) == 0) - error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value.str().c_str()); - else - { - m_value_was_set = true; - NotifyValueChanged(); - } - } - break; - - case eVarSetOperationInsertBefore: - case eVarSetOperationInsertAfter: - case eVarSetOperationRemove: - case eVarSetOperationAppend: - case eVarSetOperationInvalid: - error = OptionValue::SetValueFromString (value, op); - break; +Error OptionValueUUID::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Error error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: { + if (m_uuid.SetFromCString(value.str().c_str()) == 0) + error.SetErrorStringWithFormat("invalid uuid string value '%s'", + value.str().c_str()); + else { + m_value_was_set = true; + NotifyValueChanged(); } - return error; + } break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; } -lldb::OptionValueSP -OptionValueUUID::DeepCopy () const -{ - return OptionValueSP(new OptionValueUUID(*this)); +lldb::OptionValueSP OptionValueUUID::DeepCopy() const { + return OptionValueSP(new OptionValueUUID(*this)); } -size_t -OptionValueUUID::AutoComplete (CommandInterpreter &interpreter, - const char *s, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) -{ - word_complete = false; - matches.Clear(); - ExecutionContext exe_ctx(interpreter.GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) - { - const size_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) - { - UUID::ValueType uuid_bytes; - const size_t num_bytes_decoded = UUID::DecodeUUIDBytesFromCString(s, uuid_bytes, nullptr); - for (size_t i=0; i<num_modules; ++i) - { - ModuleSP module_sp (target->GetImages().GetModuleAtIndex(i)); - if (module_sp) - { - const UUID &module_uuid = module_sp->GetUUID(); - if (module_uuid.IsValid()) - { - bool add_uuid = false; - if (num_bytes_decoded == 0) - add_uuid = true; - else - add_uuid = ::memcmp(module_uuid.GetBytes(), uuid_bytes, num_bytes_decoded) == 0; - if (add_uuid) - { - std::string uuid_str; - uuid_str = module_uuid.GetAsString(); - if (!uuid_str.empty()) - matches.AppendString(uuid_str.c_str()); - } - } - } +size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter, + llvm::StringRef s, int match_start_point, + int max_return_elements, + bool &word_complete, StringList &matches) { + word_complete = false; + matches.Clear(); + ExecutionContext exe_ctx(interpreter.GetExecutionContext()); + Target *target = exe_ctx.GetTargetPtr(); + if (target) { + const size_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) { + UUID::ValueType uuid_bytes; + uint32_t num_bytes_decoded = 0; + UUID::DecodeUUIDBytesFromString(s, uuid_bytes, num_bytes_decoded); + for (size_t i = 0; i < num_modules; ++i) { + ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i)); + if (module_sp) { + const UUID &module_uuid = module_sp->GetUUID(); + if (module_uuid.IsValid()) { + bool add_uuid = false; + if (num_bytes_decoded == 0) + add_uuid = true; + else + add_uuid = ::memcmp(module_uuid.GetBytes(), uuid_bytes, + num_bytes_decoded) == 0; + if (add_uuid) { + std::string uuid_str; + uuid_str = module_uuid.GetAsString(); + if (!uuid_str.empty()) + matches.AppendString(uuid_str.c_str()); } + } } + } } - return matches.GetSize(); + } + return matches.GetSize(); } - diff --git a/contrib/llvm/tools/lldb/source/Interpreter/Options.cpp b/contrib/llvm/tools/lldb/source/Interpreter/Options.cpp index 70f532e..d26e53f 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/Options.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/Options.cpp @@ -18,11 +18,11 @@ // Other libraries and framework includes // Project includes -#include "lldb/Interpreter/CommandObject.h" -#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Core/StreamString.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Target.h" using namespace lldb; @@ -31,1083 +31,922 @@ using namespace lldb_private; //------------------------------------------------------------------------- // Options //------------------------------------------------------------------------- -Options::Options (CommandInterpreter &interpreter) : - m_interpreter (interpreter), - m_getopt_table () -{ - BuildValidOptionSets(); -} +Options::Options() : m_getopt_table() { BuildValidOptionSets(); } -Options::~Options () -{ -} +Options::~Options() {} -void -Options::NotifyOptionParsingStarting () -{ - m_seen_options.clear(); - // Let the subclass reset its option values - OptionParsingStarting (); +void Options::NotifyOptionParsingStarting(ExecutionContext *execution_context) { + m_seen_options.clear(); + // Let the subclass reset its option values + OptionParsingStarting(execution_context); } -Error -Options::NotifyOptionParsingFinished () -{ - return OptionParsingFinished (); +Error Options::NotifyOptionParsingFinished( + ExecutionContext *execution_context) { + return OptionParsingFinished(execution_context); } -void -Options::OptionSeen (int option_idx) -{ - m_seen_options.insert (option_idx); -} +void Options::OptionSeen(int option_idx) { m_seen_options.insert(option_idx); } // Returns true is set_a is a subset of set_b; Otherwise returns false. -bool -Options::IsASubset (const OptionSet& set_a, const OptionSet& set_b) -{ - bool is_a_subset = true; - OptionSet::const_iterator pos_a; - OptionSet::const_iterator pos_b; +bool Options::IsASubset(const OptionSet &set_a, const OptionSet &set_b) { + bool is_a_subset = true; + OptionSet::const_iterator pos_a; + OptionSet::const_iterator pos_b; - // set_a is a subset of set_b if every member of set_a is also a member of set_b + // set_a is a subset of set_b if every member of set_a is also a member of + // set_b - for (pos_a = set_a.begin(); pos_a != set_a.end() && is_a_subset; ++pos_a) - { - pos_b = set_b.find(*pos_a); - if (pos_b == set_b.end()) - is_a_subset = false; - } + for (pos_a = set_a.begin(); pos_a != set_a.end() && is_a_subset; ++pos_a) { + pos_b = set_b.find(*pos_a); + if (pos_b == set_b.end()) + is_a_subset = false; + } - return is_a_subset; + return is_a_subset; } -// Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) && !ElementOf (x, set_b) } - -size_t -Options::OptionsSetDiff (const OptionSet& set_a, const OptionSet& set_b, OptionSet& diffs) -{ - size_t num_diffs = 0; - OptionSet::const_iterator pos_a; - OptionSet::const_iterator pos_b; - - for (pos_a = set_a.begin(); pos_a != set_a.end(); ++pos_a) - { - pos_b = set_b.find(*pos_a); - if (pos_b == set_b.end()) - { - ++num_diffs; - diffs.insert(*pos_a); - } +// Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) && +// !ElementOf (x, set_b) } + +size_t Options::OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b, + OptionSet &diffs) { + size_t num_diffs = 0; + OptionSet::const_iterator pos_a; + OptionSet::const_iterator pos_b; + + for (pos_a = set_a.begin(); pos_a != set_a.end(); ++pos_a) { + pos_b = set_b.find(*pos_a); + if (pos_b == set_b.end()) { + ++num_diffs; + diffs.insert(*pos_a); } + } - return num_diffs; + return num_diffs; } -// Returns the union of set_a and set_b. Does not put duplicate members into the union. +// Returns the union of set_a and set_b. Does not put duplicate members into +// the union. -void -Options::OptionsSetUnion (const OptionSet &set_a, const OptionSet &set_b, OptionSet &union_set) -{ - OptionSet::const_iterator pos; - OptionSet::iterator pos_union; +void Options::OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b, + OptionSet &union_set) { + OptionSet::const_iterator pos; + OptionSet::iterator pos_union; - // Put all the elements of set_a into the union. + // Put all the elements of set_a into the union. - for (pos = set_a.begin(); pos != set_a.end(); ++pos) - union_set.insert(*pos); + for (pos = set_a.begin(); pos != set_a.end(); ++pos) + union_set.insert(*pos); - // Put all the elements of set_b that are not already there into the union. - for (pos = set_b.begin(); pos != set_b.end(); ++pos) - { - pos_union = union_set.find(*pos); - if (pos_union == union_set.end()) - union_set.insert(*pos); - } + // Put all the elements of set_b that are not already there into the union. + for (pos = set_b.begin(); pos != set_b.end(); ++pos) { + pos_union = union_set.find(*pos); + if (pos_union == union_set.end()) + union_set.insert(*pos); + } } -bool -Options::VerifyOptions (CommandReturnObject &result) -{ - bool options_are_valid = false; - - int num_levels = GetRequiredOptions().size(); - if (num_levels) - { - for (int i = 0; i < num_levels && !options_are_valid; ++i) - { - // This is the correct set of options if: 1). m_seen_options contains all of m_required_options[i] - // (i.e. all the required options at this level are a subset of m_seen_options); AND - // 2). { m_seen_options - m_required_options[i] is a subset of m_options_options[i] (i.e. all the rest of - // m_seen_options are in the set of optional options at this level. - - // Check to see if all of m_required_options[i] are a subset of m_seen_options - if (IsASubset (GetRequiredOptions()[i], m_seen_options)) - { - // Construct the set difference: remaining_options = {m_seen_options} - {m_required_options[i]} - OptionSet remaining_options; - OptionsSetDiff (m_seen_options, GetRequiredOptions()[i], remaining_options); - // Check to see if remaining_options is a subset of m_optional_options[i] - if (IsASubset (remaining_options, GetOptionalOptions()[i])) - options_are_valid = true; - } - } - } - else - { - options_are_valid = true; - } - - if (options_are_valid) - { - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendError ("invalid combination of options for the given command"); - result.SetStatus (eReturnStatusFailed); +bool Options::VerifyOptions(CommandReturnObject &result) { + bool options_are_valid = false; + + int num_levels = GetRequiredOptions().size(); + if (num_levels) { + for (int i = 0; i < num_levels && !options_are_valid; ++i) { + // This is the correct set of options if: 1). m_seen_options contains all + // of m_required_options[i] + // (i.e. all the required options at this level are a subset of + // m_seen_options); AND + // 2). { m_seen_options - m_required_options[i] is a subset of + // m_options_options[i] (i.e. all the rest of + // m_seen_options are in the set of optional options at this level. + + // Check to see if all of m_required_options[i] are a subset of + // m_seen_options + if (IsASubset(GetRequiredOptions()[i], m_seen_options)) { + // Construct the set difference: remaining_options = {m_seen_options} - + // {m_required_options[i]} + OptionSet remaining_options; + OptionsSetDiff(m_seen_options, GetRequiredOptions()[i], + remaining_options); + // Check to see if remaining_options is a subset of + // m_optional_options[i] + if (IsASubset(remaining_options, GetOptionalOptions()[i])) + options_are_valid = true; + } } - - return options_are_valid; + } else { + options_are_valid = true; + } + + if (options_are_valid) { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } else { + result.AppendError("invalid combination of options for the given command"); + result.SetStatus(eReturnStatusFailed); + } + + return options_are_valid; } -// This is called in the Options constructor, though we could call it lazily if that ends up being +// This is called in the Options constructor, though we could call it lazily if +// that ends up being // a performance problem. -void -Options::BuildValidOptionSets () -{ - // Check to see if we already did this. - if (m_required_options.size() != 0) - return; - - // Check to see if there are any options. - int num_options = NumCommandOptions (); - if (num_options == 0) - return; - - const OptionDefinition *opt_defs = GetDefinitions(); - m_required_options.resize(1); - m_optional_options.resize(1); - - // First count the number of option sets we've got. Ignore LLDB_ALL_OPTION_SETS... - - uint32_t num_option_sets = 0; - - for (int i = 0; i < num_options; i++) - { - uint32_t this_usage_mask = opt_defs[i].usage_mask; - if (this_usage_mask == LLDB_OPT_SET_ALL) - { - if (num_option_sets == 0) - num_option_sets = 1; - } - else - { - for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) - { - if (this_usage_mask & (1 << j)) - { - if (num_option_sets <= j) - num_option_sets = j + 1; - } - } +void Options::BuildValidOptionSets() { + // Check to see if we already did this. + if (m_required_options.size() != 0) + return; + + // Check to see if there are any options. + int num_options = NumCommandOptions(); + if (num_options == 0) + return; + + auto opt_defs = GetDefinitions(); + m_required_options.resize(1); + m_optional_options.resize(1); + + // First count the number of option sets we've got. Ignore + // LLDB_ALL_OPTION_SETS... + + uint32_t num_option_sets = 0; + + for (const auto &def : opt_defs) { + uint32_t this_usage_mask = def.usage_mask; + if (this_usage_mask == LLDB_OPT_SET_ALL) { + if (num_option_sets == 0) + num_option_sets = 1; + } else { + for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) { + if (this_usage_mask & (1 << j)) { + if (num_option_sets <= j) + num_option_sets = j + 1; } + } } - - if (num_option_sets > 0) - { - m_required_options.resize(num_option_sets); - m_optional_options.resize(num_option_sets); - - for (int i = 0; i < num_options; ++i) - { - for (uint32_t j = 0; j < num_option_sets; j++) - { - if (opt_defs[i].usage_mask & 1 << j) - { - if (opt_defs[i].required) - m_required_options[j].insert(opt_defs[i].short_option); - else - m_optional_options[j].insert(opt_defs[i].short_option); - } - } + } + + if (num_option_sets > 0) { + m_required_options.resize(num_option_sets); + m_optional_options.resize(num_option_sets); + + for (const auto &def : opt_defs) { + for (uint32_t j = 0; j < num_option_sets; j++) { + if (def.usage_mask & 1 << j) { + if (def.required) + m_required_options[j].insert(def.short_option); + else + m_optional_options[j].insert(def.short_option); } + } } + } } -uint32_t -Options::NumCommandOptions () -{ - const OptionDefinition *opt_defs = GetDefinitions (); - if (opt_defs == nullptr) - return 0; - - int i = 0; - - if (opt_defs != nullptr) - { - while (opt_defs[i].long_option != nullptr) - ++i; +uint32_t Options::NumCommandOptions() { return GetDefinitions().size(); } + +Option *Options::GetLongOptions() { + // Check to see if this has already been done. + if (m_getopt_table.empty()) { + auto defs = GetDefinitions(); + if (defs.empty()) + return nullptr; + + std::map<int, uint32_t> option_seen; + + m_getopt_table.resize(defs.size() + 1); + for (size_t i = 0; i < defs.size(); ++i) { + const int short_opt = defs[i].short_option; + + m_getopt_table[i].definition = &defs[i]; + m_getopt_table[i].flag = nullptr; + m_getopt_table[i].val = short_opt; + + if (option_seen.find(short_opt) == option_seen.end()) { + option_seen[short_opt] = i; + } else if (short_opt) { + m_getopt_table[i].val = 0; + std::map<int, uint32_t>::const_iterator pos = + option_seen.find(short_opt); + StreamString strm; + if (isprint8(short_opt)) + Host::SystemLog(Host::eSystemLogError, + "option[%u] --%s has a short option -%c that " + "conflicts with option[%u] --%s, short option won't " + "be used for --%s\n", + (int)i, defs[i].long_option, short_opt, pos->second, + m_getopt_table[pos->second].definition->long_option, + defs[i].long_option); + else + Host::SystemLog(Host::eSystemLogError, + "option[%u] --%s has a short option 0x%x that " + "conflicts with option[%u] --%s, short option won't " + "be used for --%s\n", + (int)i, defs[i].long_option, short_opt, pos->second, + m_getopt_table[pos->second].definition->long_option, + defs[i].long_option); + } } - return i; -} - -Option * -Options::GetLongOptions () -{ - // Check to see if this has already been done. - if (m_getopt_table.empty()) - { - // Check to see if there are any options. - const uint32_t num_options = NumCommandOptions(); - if (num_options == 0) - return nullptr; - - uint32_t i; - const OptionDefinition *opt_defs = GetDefinitions(); - - std::map<int, uint32_t> option_seen; - - m_getopt_table.resize(num_options + 1); - for (i = 0; i < num_options; ++i) - { - const int short_opt = opt_defs[i].short_option; - - m_getopt_table[i].definition = &opt_defs[i]; - m_getopt_table[i].flag = nullptr; - m_getopt_table[i].val = short_opt; - - if (option_seen.find(short_opt) == option_seen.end()) - { - option_seen[short_opt] = i; - } - else if (short_opt) - { - m_getopt_table[i].val = 0; - std::map<int, uint32_t>::const_iterator pos = option_seen.find(short_opt); - StreamString strm; - if (isprint8(short_opt)) - Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option -%c that conflicts with option[%u] --%s, short option won't be used for --%s\n", - i, - opt_defs[i].long_option, - short_opt, - pos->second, - m_getopt_table[pos->second].definition->long_option, - opt_defs[i].long_option); - else - Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option 0x%x that conflicts with option[%u] --%s, short option won't be used for --%s\n", - i, - opt_defs[i].long_option, - short_opt, - pos->second, - m_getopt_table[pos->second].definition->long_option, - opt_defs[i].long_option); - } - } + // getopt_long_only requires a NULL final entry in the table: - //getopt_long_only requires a NULL final entry in the table: + m_getopt_table.back().definition = nullptr; + m_getopt_table.back().flag = nullptr; + m_getopt_table.back().val = 0; + } - m_getopt_table[i].definition = nullptr; - m_getopt_table[i].flag = nullptr; - m_getopt_table[i].val = 0; - } - - if (m_getopt_table.empty()) - return nullptr; + if (m_getopt_table.empty()) + return nullptr; - return &m_getopt_table.front(); + return &m_getopt_table.front(); } - -// This function takes INDENT, which tells how many spaces to output at the front of each line; SPACES, which is -// a string containing 80 spaces; and TEXT, which is the text that is to be output. It outputs the text, on -// multiple lines if necessary, to RESULT, with INDENT spaces at the front of each line. It breaks lines on spaces, -// tabs or newlines, shortening the line if necessary to not break in the middle of a word. It assumes that each +// This function takes INDENT, which tells how many spaces to output at the +// front of each line; SPACES, which is +// a string containing 80 spaces; and TEXT, which is the text that is to be +// output. It outputs the text, on +// multiple lines if necessary, to RESULT, with INDENT spaces at the front of +// each line. It breaks lines on spaces, +// tabs or newlines, shortening the line if necessary to not break in the middle +// of a word. It assumes that each // output line should contain a maximum of OUTPUT_MAX_COLUMNS characters. - -void -Options::OutputFormattedUsageText -( - Stream &strm, - const OptionDefinition &option_def, - uint32_t output_max_columns -) -{ - std::string actual_text; - if (option_def.validator) - { - const char *condition = option_def.validator->ShortConditionString(); - if (condition) - { - actual_text = "["; - actual_text.append(condition); - actual_text.append("] "); - } - } - actual_text.append(option_def.usage_text); - - // Will it all fit on one line? - - if (static_cast<uint32_t>(actual_text.length() + strm.GetIndentLevel()) < output_max_columns) - { - // Output it as a single line. - strm.Indent (actual_text.c_str()); - strm.EOL(); +void Options::OutputFormattedUsageText(Stream &strm, + const OptionDefinition &option_def, + uint32_t output_max_columns) { + std::string actual_text; + if (option_def.validator) { + const char *condition = option_def.validator->ShortConditionString(); + if (condition) { + actual_text = "["; + actual_text.append(condition); + actual_text.append("] "); } - else - { - // We need to break it up into multiple lines. - - int text_width = output_max_columns - strm.GetIndentLevel() - 1; - int start = 0; - int end = start; - int final_end = actual_text.length(); - int sub_len; - - while (end < final_end) - { - // Don't start the 'text' on a space, since we're already outputting the indentation. - while ((start < final_end) && (actual_text[start] == ' ')) - start++; - - end = start + text_width; - if (end > final_end) - end = final_end; - else - { - // If we're not at the end of the text, make sure we break the line on white space. - while (end > start - && actual_text[end] != ' ' && actual_text[end] != '\t' && actual_text[end] != '\n') - end--; - } + } + actual_text.append(option_def.usage_text); + + // Will it all fit on one line? + + if (static_cast<uint32_t>(actual_text.length() + strm.GetIndentLevel()) < + output_max_columns) { + // Output it as a single line. + strm.Indent(actual_text.c_str()); + strm.EOL(); + } else { + // We need to break it up into multiple lines. + + int text_width = output_max_columns - strm.GetIndentLevel() - 1; + int start = 0; + int end = start; + int final_end = actual_text.length(); + int sub_len; + + while (end < final_end) { + // Don't start the 'text' on a space, since we're already outputting the + // indentation. + while ((start < final_end) && (actual_text[start] == ' ')) + start++; + + end = start + text_width; + if (end > final_end) + end = final_end; + else { + // If we're not at the end of the text, make sure we break the line on + // white space. + while (end > start && actual_text[end] != ' ' && + actual_text[end] != '\t' && actual_text[end] != '\n') + end--; + } - sub_len = end - start; - if (start != 0) - strm.EOL(); - strm.Indent(); - assert (start < final_end); - assert (start + sub_len <= final_end); - strm.Write(actual_text.c_str() + start, sub_len); - start = end + 1; - } + sub_len = end - start; + if (start != 0) strm.EOL(); + strm.Indent(); + assert(start < final_end); + assert(start + sub_len <= final_end); + strm.Write(actual_text.c_str() + start, sub_len); + start = end + 1; } + strm.EOL(); + } } -bool -Options::SupportsLongOption (const char *long_option) -{ - if (long_option && long_option[0]) - { - const OptionDefinition *opt_defs = GetDefinitions (); - if (opt_defs) - { - const char *long_option_name = long_option; - if (long_option[0] == '-' && long_option[1] == '-') - long_option_name += 2; - - for (uint32_t i = 0; opt_defs[i].long_option; ++i) - { - if (strcmp(opt_defs[i].long_option, long_option_name) == 0) - return true; - } - } - } +bool Options::SupportsLongOption(const char *long_option) { + if (!long_option || !long_option[0]) return false; + + auto opt_defs = GetDefinitions(); + if (opt_defs.empty()) + return false; + + const char *long_option_name = long_option; + if (long_option[0] == '-' && long_option[1] == '-') + long_option_name += 2; + + for (auto &def : opt_defs) { + if (!def.long_option) + continue; + + if (strcmp(def.long_option, long_option_name) == 0) + return true; + } + + return false; } -enum OptionDisplayType -{ - eDisplayBestOption, - eDisplayShortOption, - eDisplayLongOption +enum OptionDisplayType { + eDisplayBestOption, + eDisplayShortOption, + eDisplayLongOption }; -static bool -PrintOption (const OptionDefinition &opt_def, - OptionDisplayType display_type, - const char *header, - const char *footer, - bool show_optional, - Stream &strm) -{ - const bool has_short_option = isprint8(opt_def.short_option) != 0; - - if (display_type == eDisplayShortOption && !has_short_option) - return false; - - if (header && header[0]) - strm.PutCString(header); - - if (show_optional && !opt_def.required) +static bool PrintOption(const OptionDefinition &opt_def, + OptionDisplayType display_type, const char *header, + const char *footer, bool show_optional, Stream &strm) { + const bool has_short_option = isprint8(opt_def.short_option) != 0; + + if (display_type == eDisplayShortOption && !has_short_option) + return false; + + if (header && header[0]) + strm.PutCString(header); + + if (show_optional && !opt_def.required) strm.PutChar('['); - const bool show_short_option = has_short_option && display_type != eDisplayLongOption; - if (show_short_option) - strm.Printf ("-%c", opt_def.short_option); - else - strm.Printf ("--%s", opt_def.long_option); - switch (opt_def.option_has_arg) - { - case OptionParser::eNoArgument: - break; - case OptionParser::eRequiredArgument: - strm.Printf (" <%s>", CommandObject::GetArgumentName (opt_def.argument_type)); - break; - - case OptionParser::eOptionalArgument: - strm.Printf ("%s[<%s>]", - show_short_option ? "" : "=", - CommandObject::GetArgumentName (opt_def.argument_type)); - break; - } - if (show_optional && !opt_def.required) - strm.PutChar(']'); - if (footer && footer[0]) - strm.PutCString(footer); - return true; + const bool show_short_option = + has_short_option && display_type != eDisplayLongOption; + if (show_short_option) + strm.Printf("-%c", opt_def.short_option); + else + strm.Printf("--%s", opt_def.long_option); + switch (opt_def.option_has_arg) { + case OptionParser::eNoArgument: + break; + case OptionParser::eRequiredArgument: + strm.Printf(" <%s>", CommandObject::GetArgumentName(opt_def.argument_type)); + break; + + case OptionParser::eOptionalArgument: + strm.Printf("%s[<%s>]", show_short_option ? "" : "=", + CommandObject::GetArgumentName(opt_def.argument_type)); + break; + } + if (show_optional && !opt_def.required) + strm.PutChar(']'); + if (footer && footer[0]) + strm.PutCString(footer); + return true; } -void -Options::GenerateOptionUsage -( - Stream &strm, - CommandObject *cmd -) -{ - const bool only_print_args = cmd->IsDashDashCommand(); - const uint32_t screen_width = m_interpreter.GetDebugger().GetTerminalWidth(); - - const OptionDefinition *opt_defs = GetDefinitions(); - const uint32_t save_indent_level = strm.GetIndentLevel(); - const char *name; - - StreamString arguments_str; - - if (cmd) - { - name = cmd->GetCommandName(); - cmd->GetFormattedCommandArguments (arguments_str); - } - else - name = ""; +void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd, + uint32_t screen_width) { + const bool only_print_args = cmd->IsDashDashCommand(); - strm.PutCString ("\nCommand Options Usage:\n"); + auto opt_defs = GetDefinitions(); + const uint32_t save_indent_level = strm.GetIndentLevel(); + llvm::StringRef name; - strm.IndentMore(2); + StreamString arguments_str; - // First, show each usage level set of options, e.g. <cmd> [options-for-level-0] - // <cmd> [options-for-level-1] - // etc. + if (cmd) { + name = cmd->GetCommandName(); + cmd->GetFormattedCommandArguments(arguments_str); + } else + name = ""; - const uint32_t num_options = NumCommandOptions(); - if (num_options == 0) - return; - - uint32_t num_option_sets = GetRequiredOptions().size(); - - uint32_t i; - - if (!only_print_args) - { - for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set) - { - uint32_t opt_set_mask; - - opt_set_mask = 1 << opt_set; - if (opt_set > 0) - strm.Printf ("\n"); - strm.Indent (name); - - // Different option sets may require different args. - StreamString args_str; - if (cmd) - cmd->GetFormattedCommandArguments(args_str, opt_set_mask); - - // First go through and print all options that take no arguments as - // a single string. If a command has "-a" "-b" and "-c", this will show - // up as [-abc] - - std::set<int> options; - std::set<int>::const_iterator options_pos, options_end; - for (i = 0; i < num_options; ++i) - { - if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option)) - { - // Add current option to the end of out_stream. - - if (opt_defs[i].required == true && - opt_defs[i].option_has_arg == OptionParser::eNoArgument) - { - options.insert (opt_defs[i].short_option); - } - } - } + strm.PutCString("\nCommand Options Usage:\n"); - if (options.empty() == false) - { - // We have some required options with no arguments - strm.PutCString(" -"); - for (i=0; i<2; ++i) - for (options_pos = options.begin(), options_end = options.end(); - options_pos != options_end; - ++options_pos) - { - if (i==0 && ::islower (*options_pos)) - continue; - if (i==1 && ::isupper (*options_pos)) - continue; - strm << (char)*options_pos; - } - } + strm.IndentMore(2); - for (i = 0, options.clear(); i < num_options; ++i) - { - if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option)) - { - // Add current option to the end of out_stream. - - if (opt_defs[i].required == false && - opt_defs[i].option_has_arg == OptionParser::eNoArgument) - { - options.insert (opt_defs[i].short_option); - } - } - } + // First, show each usage level set of options, e.g. <cmd> + // [options-for-level-0] + // <cmd> + // [options-for-level-1] + // etc. - if (options.empty() == false) - { - // We have some required options with no arguments - strm.PutCString(" [-"); - for (i=0; i<2; ++i) - for (options_pos = options.begin(), options_end = options.end(); - options_pos != options_end; - ++options_pos) - { - if (i==0 && ::islower (*options_pos)) - continue; - if (i==1 && ::isupper (*options_pos)) - continue; - strm << (char)*options_pos; - } - strm.PutChar(']'); - } + const uint32_t num_options = NumCommandOptions(); + if (num_options == 0) + return; - // First go through and print the required options (list them up front). - - for (i = 0; i < num_options; ++i) - { - if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option)) - { - if (opt_defs[i].required && opt_defs[i].option_has_arg != OptionParser::eNoArgument) - PrintOption (opt_defs[i], eDisplayBestOption, " ", nullptr, true, strm); - } - } + uint32_t num_option_sets = GetRequiredOptions().size(); - // Now go through again, and this time only print the optional options. + uint32_t i; - for (i = 0; i < num_options; ++i) - { - if (opt_defs[i].usage_mask & opt_set_mask) - { - // Add current option to the end of out_stream. + if (!only_print_args) { + for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set) { + uint32_t opt_set_mask; - if (!opt_defs[i].required && opt_defs[i].option_has_arg != OptionParser::eNoArgument) - PrintOption (opt_defs[i], eDisplayBestOption, " ", nullptr, true, strm); - } - } - - if (args_str.GetSize() > 0) - { - if (cmd->WantsRawCommandString() && !only_print_args) - strm.Printf(" --"); - - strm.Printf (" %s", args_str.GetData()); - if (only_print_args) - break; - } + opt_set_mask = 1 << opt_set; + if (opt_set > 0) + strm.Printf("\n"); + strm.Indent(name); + + // Different option sets may require different args. + StreamString args_str; + if (cmd) + cmd->GetFormattedCommandArguments(args_str, opt_set_mask); + + // First go through and print all options that take no arguments as + // a single string. If a command has "-a" "-b" and "-c", this will show + // up as [-abc] + + std::set<int> options; + std::set<int>::const_iterator options_pos, options_end; + for (auto &def : opt_defs) { + if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) { + // Add current option to the end of out_stream. + + if (def.required && def.option_has_arg == OptionParser::eNoArgument) { + options.insert(def.short_option); + } } + } + + if (options.empty() == false) { + // We have some required options with no arguments + strm.PutCString(" -"); + for (i = 0; i < 2; ++i) + for (options_pos = options.begin(), options_end = options.end(); + options_pos != options_end; ++options_pos) { + if (i == 0 && ::islower(*options_pos)) + continue; + if (i == 1 && ::isupper(*options_pos)) + continue; + strm << (char)*options_pos; + } + } + + options.clear(); + for (auto &def : opt_defs) { + if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) { + // Add current option to the end of out_stream. + + if (def.required == false && + def.option_has_arg == OptionParser::eNoArgument) { + options.insert(def.short_option); + } + } + } + + if (options.empty() == false) { + // We have some required options with no arguments + strm.PutCString(" [-"); + for (i = 0; i < 2; ++i) + for (options_pos = options.begin(), options_end = options.end(); + options_pos != options_end; ++options_pos) { + if (i == 0 && ::islower(*options_pos)) + continue; + if (i == 1 && ::isupper(*options_pos)) + continue; + strm << (char)*options_pos; + } + strm.PutChar(']'); + } + + // First go through and print the required options (list them up front). + + for (auto &def : opt_defs) { + if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) { + if (def.required && def.option_has_arg != OptionParser::eNoArgument) + PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm); + } + } + + // Now go through again, and this time only print the optional options. + + for (auto &def : opt_defs) { + if (def.usage_mask & opt_set_mask) { + // Add current option to the end of out_stream. + + if (!def.required && def.option_has_arg != OptionParser::eNoArgument) + PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm); + } + } + + if (args_str.GetSize() > 0) { + if (cmd->WantsRawCommandString() && !only_print_args) + strm.Printf(" --"); + + strm << " " << args_str.GetString(); + if (only_print_args) + break; + } } - - if (cmd && - (only_print_args || cmd->WantsRawCommandString()) && - arguments_str.GetSize() > 0) - { - if (!only_print_args) strm.PutChar('\n'); - strm.Indent(name); - strm.Printf(" %s", arguments_str.GetData()); - } - - strm.Printf ("\n\n"); + } + if (cmd && (only_print_args || cmd->WantsRawCommandString()) && + arguments_str.GetSize() > 0) { if (!only_print_args) - { - // Now print out all the detailed information about the various options: long form, short form and help text: - // -short <argument> ( --long_name <argument> ) - // help text - - // This variable is used to keep track of which options' info we've printed out, because some options can be in - // more than one usage level, but we only want to print the long form of its information once. - - std::multimap<int, uint32_t> options_seen; - strm.IndentMore (5); - - // Put the unique command options in a vector & sort it, so we can output them alphabetically (by short_option) - // when writing out detailed help for each option. - - for (i = 0; i < num_options; ++i) - options_seen.insert(std::make_pair(opt_defs[i].short_option, i)); - - // Go through the unique'd and alphabetically sorted vector of options, find the table entry for each option - // and write out the detailed help information for that option. - - bool first_option_printed = false;; - - for (auto pos : options_seen) - { - i = pos.second; - //Print out the help information for this option. - - // Put a newline separation between arguments - if (first_option_printed) - strm.EOL(); - else - first_option_printed = true; - - CommandArgumentType arg_type = opt_defs[i].argument_type; - - StreamString arg_name_str; - arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type)); - - strm.Indent (); - if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option)) - { - PrintOption (opt_defs[i], eDisplayShortOption, nullptr, nullptr, false, strm); - PrintOption (opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm); - } - else - { - // Short option is not printable, just print long option - PrintOption (opt_defs[i], eDisplayLongOption, nullptr, nullptr, false, strm); - } - strm.EOL(); - - strm.IndentMore (5); - - if (opt_defs[i].usage_text) - OutputFormattedUsageText (strm, - opt_defs[i], - screen_width); - if (opt_defs[i].enum_values != nullptr) - { - strm.Indent (); - strm.Printf("Values: "); - for (int k = 0; opt_defs[i].enum_values[k].string_value != nullptr; k++) - { - if (k == 0) - strm.Printf("%s", opt_defs[i].enum_values[k].string_value); - else - strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value); - } - strm.EOL(); - } - strm.IndentLess (5); + strm.PutChar('\n'); + strm.Indent(name); + strm << " " << arguments_str.GetString(); + } + + strm.Printf("\n\n"); + + if (!only_print_args) { + // Now print out all the detailed information about the various options: + // long form, short form and help text: + // -short <argument> ( --long_name <argument> ) + // help text + + // This variable is used to keep track of which options' info we've printed + // out, because some options can be in + // more than one usage level, but we only want to print the long form of its + // information once. + + std::multimap<int, uint32_t> options_seen; + strm.IndentMore(5); + + // Put the unique command options in a vector & sort it, so we can output + // them alphabetically (by short_option) + // when writing out detailed help for each option. + + i = 0; + for (auto &def : opt_defs) + options_seen.insert(std::make_pair(def.short_option, i++)); + + // Go through the unique'd and alphabetically sorted vector of options, find + // the table entry for each option + // and write out the detailed help information for that option. + + bool first_option_printed = false; + + for (auto pos : options_seen) { + i = pos.second; + // Print out the help information for this option. + + // Put a newline separation between arguments + if (first_option_printed) + strm.EOL(); + else + first_option_printed = true; + + CommandArgumentType arg_type = opt_defs[i].argument_type; + + StreamString arg_name_str; + arg_name_str.Printf("<%s>", CommandObject::GetArgumentName(arg_type)); + + strm.Indent(); + if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option)) { + PrintOption(opt_defs[i], eDisplayShortOption, nullptr, nullptr, false, + strm); + PrintOption(opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm); + } else { + // Short option is not printable, just print long option + PrintOption(opt_defs[i], eDisplayLongOption, nullptr, nullptr, false, + strm); + } + strm.EOL(); + + strm.IndentMore(5); + + if (opt_defs[i].usage_text) + OutputFormattedUsageText(strm, opt_defs[i], screen_width); + if (opt_defs[i].enum_values != nullptr) { + strm.Indent(); + strm.Printf("Values: "); + for (int k = 0; opt_defs[i].enum_values[k].string_value != nullptr; + k++) { + if (k == 0) + strm.Printf("%s", opt_defs[i].enum_values[k].string_value); + else + strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value); } + strm.EOL(); + } + strm.IndentLess(5); } + } - // Restore the indent level - strm.SetIndentLevel (save_indent_level); + // Restore the indent level + strm.SetIndentLevel(save_indent_level); } -// This function is called when we have been given a potentially incomplete set of -// options, such as when an alias has been defined (more options might be added at -// at the time the alias is invoked). We need to verify that the options in the set -// m_seen_options are all part of a set that may be used together, but m_seen_options +// This function is called when we have been given a potentially incomplete set +// of +// options, such as when an alias has been defined (more options might be added +// at +// at the time the alias is invoked). We need to verify that the options in the +// set +// m_seen_options are all part of a set that may be used together, but +// m_seen_options // may be missing some of the "required" options. -bool -Options::VerifyPartialOptions (CommandReturnObject &result) -{ - bool options_are_valid = false; - - int num_levels = GetRequiredOptions().size(); - if (num_levels) - { - for (int i = 0; i < num_levels && !options_are_valid; ++i) - { - // In this case we are treating all options as optional rather than required. - // Therefore a set of options is correct if m_seen_options is a subset of the - // union of m_required_options and m_optional_options. - OptionSet union_set; - OptionsSetUnion (GetRequiredOptions()[i], GetOptionalOptions()[i], union_set); - if (IsASubset (m_seen_options, union_set)) - options_are_valid = true; - } - } +bool Options::VerifyPartialOptions(CommandReturnObject &result) { + bool options_are_valid = false; + + int num_levels = GetRequiredOptions().size(); + if (num_levels) { + for (int i = 0; i < num_levels && !options_are_valid; ++i) { + // In this case we are treating all options as optional rather than + // required. + // Therefore a set of options is correct if m_seen_options is a subset of + // the + // union of m_required_options and m_optional_options. + OptionSet union_set; + OptionsSetUnion(GetRequiredOptions()[i], GetOptionalOptions()[i], + union_set); + if (IsASubset(m_seen_options, union_set)) + options_are_valid = true; + } + } - return options_are_valid; + return options_are_valid; } -bool -Options::HandleOptionCompletion -( - Args &input, - OptionElementVector &opt_element_vector, - int cursor_index, - int char_pos, - int match_start_point, - int max_return_elements, - bool &word_complete, - lldb_private::StringList &matches -) -{ - word_complete = true; - - // For now we just scan the completions to see if the cursor position is in - // an option or its argument. Otherwise we'll call HandleArgumentCompletion. - // In the future we can use completion to validate options as well if we want. - - const OptionDefinition *opt_defs = GetDefinitions(); - - std::string cur_opt_std_str (input.GetArgumentAtIndex(cursor_index)); - cur_opt_std_str.erase(char_pos); - const char *cur_opt_str = cur_opt_std_str.c_str(); - - for (size_t i = 0; i < opt_element_vector.size(); i++) - { - int opt_pos = opt_element_vector[i].opt_pos; - int opt_arg_pos = opt_element_vector[i].opt_arg_pos; - int opt_defs_index = opt_element_vector[i].opt_defs_index; - if (opt_pos == cursor_index) - { - // We're completing the option itself. - - if (opt_defs_index == OptionArgElement::eBareDash) - { - // We're completing a bare dash. That means all options are open. - // FIXME: We should scan the other options provided and only complete options - // within the option group they belong to. - char opt_str[3] = {'-', 'a', '\0'}; - - for (int j = 0 ; opt_defs[j].short_option != 0 ; j++) - { - opt_str[1] = opt_defs[j].short_option; - matches.AppendString (opt_str); - } - return true; - } - else if (opt_defs_index == OptionArgElement::eBareDoubleDash) - { - std::string full_name ("--"); - for (int j = 0 ; opt_defs[j].short_option != 0 ; j++) - { - full_name.erase(full_name.begin() + 2, full_name.end()); - full_name.append (opt_defs[j].long_option); - matches.AppendString (full_name.c_str()); - } - return true; - } - else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) - { - // We recognized it, if it an incomplete long option, complete it anyway (getopt_long_only is - // happy with shortest unique string, but it's still a nice thing to do.) Otherwise return - // The string so the upper level code will know this is a full match and add the " ". - if (cur_opt_str && strlen (cur_opt_str) > 2 - && cur_opt_str[0] == '-' && cur_opt_str[1] == '-' - && strcmp (opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) - { - std::string full_name ("--"); - full_name.append (opt_defs[opt_defs_index].long_option); - matches.AppendString(full_name.c_str()); - return true; - } - else - { - matches.AppendString(input.GetArgumentAtIndex(cursor_index)); - return true; - } - } - else - { - // FIXME - not handling wrong options yet: - // Check to see if they are writing a long option & complete it. - // I think we will only get in here if the long option table has two elements - // that are not unique up to this point. getopt_long_only does shortest unique match - // for long options already. - - if (cur_opt_str && strlen (cur_opt_str) > 2 - && cur_opt_str[0] == '-' && cur_opt_str[1] == '-') - { - for (int j = 0 ; opt_defs[j].short_option != 0 ; j++) - { - if (strstr(opt_defs[j].long_option, cur_opt_str + 2) == opt_defs[j].long_option) - { - std::string full_name ("--"); - full_name.append (opt_defs[j].long_option); - // The options definitions table has duplicates because of the - // way the grouping information is stored, so only add once. - bool duplicate = false; - for (size_t k = 0; k < matches.GetSize(); k++) - { - if (matches.GetStringAtIndex(k) == full_name) - { - duplicate = true; - break; - } - } - if (!duplicate) - matches.AppendString(full_name.c_str()); - } - } - } - return true; - } +bool Options::HandleOptionCompletion( + Args &input, OptionElementVector &opt_element_vector, int cursor_index, + int char_pos, int match_start_point, int max_return_elements, + CommandInterpreter &interpreter, bool &word_complete, + lldb_private::StringList &matches) { + word_complete = true; + + // For now we just scan the completions to see if the cursor position is in + // an option or its argument. Otherwise we'll call HandleArgumentCompletion. + // In the future we can use completion to validate options as well if we want. + + auto opt_defs = GetDefinitions(); + + std::string cur_opt_std_str(input.GetArgumentAtIndex(cursor_index)); + cur_opt_std_str.erase(char_pos); + const char *cur_opt_str = cur_opt_std_str.c_str(); + + for (size_t i = 0; i < opt_element_vector.size(); i++) { + int opt_pos = opt_element_vector[i].opt_pos; + int opt_arg_pos = opt_element_vector[i].opt_arg_pos; + int opt_defs_index = opt_element_vector[i].opt_defs_index; + if (opt_pos == cursor_index) { + // We're completing the option itself. + + if (opt_defs_index == OptionArgElement::eBareDash) { + // We're completing a bare dash. That means all options are open. + // FIXME: We should scan the other options provided and only complete + // options + // within the option group they belong to. + char opt_str[3] = {'-', 'a', '\0'}; + + for (auto &def : opt_defs) { + if (!def.short_option) + continue; + opt_str[1] = def.short_option; + matches.AppendString(opt_str); + } + return true; + } else if (opt_defs_index == OptionArgElement::eBareDoubleDash) { + std::string full_name("--"); + for (auto &def : opt_defs) { + if (!def.short_option) + continue; + full_name.erase(full_name.begin() + 2, full_name.end()); + full_name.append(def.long_option); + matches.AppendString(full_name.c_str()); } - else if (opt_arg_pos == cursor_index) - { - // Okay the cursor is on the completion of an argument. - // See if it has a completion, otherwise return no matches. - - if (opt_defs_index != -1) - { - HandleOptionArgumentCompletion (input, - cursor_index, - strlen (input.GetArgumentAtIndex(cursor_index)), - opt_element_vector, - i, - match_start_point, - max_return_elements, - word_complete, - matches); - return true; - } - else - { - // No completion callback means no completions... - return true; - } - + return true; + } else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) { + // We recognized it, if it an incomplete long option, complete it anyway + // (getopt_long_only is + // happy with shortest unique string, but it's still a nice thing to + // do.) Otherwise return + // The string so the upper level code will know this is a full match and + // add the " ". + if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' && + cur_opt_str[1] == '-' && + strcmp(opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) { + std::string full_name("--"); + full_name.append(opt_defs[opt_defs_index].long_option); + matches.AppendString(full_name.c_str()); + return true; + } else { + matches.AppendString(input.GetArgumentAtIndex(cursor_index)); + return true; } - else - { - // Not the last element, keep going. - continue; + } else { + // FIXME - not handling wrong options yet: + // Check to see if they are writing a long option & complete it. + // I think we will only get in here if the long option table has two + // elements + // that are not unique up to this point. getopt_long_only does shortest + // unique match + // for long options already. + + if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' && + cur_opt_str[1] == '-') { + for (auto &def : opt_defs) { + if (!def.long_option) + continue; + + if (strstr(def.long_option, cur_opt_str + 2) == def.long_option) { + std::string full_name("--"); + full_name.append(def.long_option); + // The options definitions table has duplicates because of the + // way the grouping information is stored, so only add once. + bool duplicate = false; + for (size_t k = 0; k < matches.GetSize(); k++) { + if (matches.GetStringAtIndex(k) == full_name) { + duplicate = true; + break; + } + } + if (!duplicate) + matches.AppendString(full_name.c_str()); + } + } } + return true; + } + + } else if (opt_arg_pos == cursor_index) { + // Okay the cursor is on the completion of an argument. + // See if it has a completion, otherwise return no matches. + + if (opt_defs_index != -1) { + HandleOptionArgumentCompletion( + input, cursor_index, strlen(input.GetArgumentAtIndex(cursor_index)), + opt_element_vector, i, match_start_point, max_return_elements, + interpreter, word_complete, matches); + return true; + } else { + // No completion callback means no completions... + return true; + } + + } else { + // Not the last element, keep going. + continue; } - return false; + } + return false; } -bool -Options::HandleOptionArgumentCompletion -( - Args &input, - int cursor_index, - int char_pos, - OptionElementVector &opt_element_vector, - int opt_element_index, - int match_start_point, - int max_return_elements, - bool &word_complete, - lldb_private::StringList &matches -) -{ - const OptionDefinition *opt_defs = GetDefinitions(); - std::unique_ptr<SearchFilter> filter_ap; - - 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; - - // See if this is an enumeration type option, and if so complete it here: - - OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values; - if (enum_values != nullptr) - { - bool return_value = false; - std::string match_string(input.GetArgumentAtIndex (opt_arg_pos), input.GetArgumentAtIndex (opt_arg_pos) + char_pos); - for (int i = 0; enum_values[i].string_value != nullptr; i++) - { - if (strstr(enum_values[i].string_value, match_string.c_str()) == enum_values[i].string_value) - { - matches.AppendString (enum_values[i].string_value); - return_value = true; - } - } - return return_value; +bool Options::HandleOptionArgumentCompletion( + Args &input, int cursor_index, int char_pos, + OptionElementVector &opt_element_vector, int opt_element_index, + int match_start_point, int max_return_elements, + CommandInterpreter &interpreter, bool &word_complete, + lldb_private::StringList &matches) { + auto opt_defs = GetDefinitions(); + std::unique_ptr<SearchFilter> filter_ap; + + 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; + + // See if this is an enumeration type option, and if so complete it here: + + OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values; + if (enum_values != nullptr) { + bool return_value = false; + std::string match_string(input.GetArgumentAtIndex(opt_arg_pos), + input.GetArgumentAtIndex(opt_arg_pos) + char_pos); + for (int i = 0; enum_values[i].string_value != nullptr; i++) { + if (strstr(enum_values[i].string_value, match_string.c_str()) == + enum_values[i].string_value) { + matches.AppendString(enum_values[i].string_value); + return_value = true; + } } - - // If this is a source file or symbol type completion, and there is a - // -shlib option somewhere in the supplied arguments, then make a search filter - // for that shared library. - // FIXME: Do we want to also have an "OptionType" so we don't have to match string names? - - uint32_t completion_mask = opt_defs[opt_defs_index].completion_type; - - if (completion_mask == 0) - { - lldb::CommandArgumentType option_arg_type = opt_defs[opt_defs_index].argument_type; - if (option_arg_type != eArgTypeNone) - { - const CommandObject::ArgumentTableEntry *arg_entry = CommandObject::FindArgumentDataByType (opt_defs[opt_defs_index].argument_type); - if (arg_entry) - completion_mask = arg_entry->completion_type; - } + return return_value; + } + + // If this is a source file or symbol type completion, and there is a + // -shlib option somewhere in the supplied arguments, then make a search + // filter + // for that shared library. + // FIXME: Do we want to also have an "OptionType" so we don't have to match + // string names? + + uint32_t completion_mask = opt_defs[opt_defs_index].completion_type; + + if (completion_mask == 0) { + lldb::CommandArgumentType option_arg_type = + opt_defs[opt_defs_index].argument_type; + if (option_arg_type != eArgTypeNone) { + const CommandObject::ArgumentTableEntry *arg_entry = + CommandObject::FindArgumentDataByType( + opt_defs[opt_defs_index].argument_type); + if (arg_entry) + completion_mask = arg_entry->completion_type; } - - if (completion_mask & CommandCompletions::eSourceFileCompletion - || completion_mask & CommandCompletions::eSymbolCompletion) - { - for (size_t i = 0; i < opt_element_vector.size(); i++) - { - int cur_defs_index = opt_element_vector[i].opt_defs_index; - - // trying to use <0 indices will definitely cause problems - if (cur_defs_index == OptionArgElement::eUnrecognizedArg || - cur_defs_index == OptionArgElement::eBareDash || - cur_defs_index == OptionArgElement::eBareDoubleDash) - continue; - - int cur_arg_pos = opt_element_vector[i].opt_arg_pos; - const char *cur_opt_name = opt_defs[cur_defs_index].long_option; - - // If this is the "shlib" option and there was an argument provided, - // restrict it to that shared library. - if (cur_opt_name && strcmp(cur_opt_name, "shlib") == 0 && cur_arg_pos != -1) - { - const char *module_name = input.GetArgumentAtIndex(cur_arg_pos); - if (module_name) - { - FileSpec module_spec(module_name, false); - lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); - // Search filters require a target... - if (target_sp) - filter_ap.reset (new SearchFilterByModule (target_sp, module_spec)); - } - break; - } + } + + if (completion_mask & CommandCompletions::eSourceFileCompletion || + completion_mask & CommandCompletions::eSymbolCompletion) { + for (size_t i = 0; i < opt_element_vector.size(); i++) { + int cur_defs_index = opt_element_vector[i].opt_defs_index; + + // trying to use <0 indices will definitely cause problems + if (cur_defs_index == OptionArgElement::eUnrecognizedArg || + cur_defs_index == OptionArgElement::eBareDash || + cur_defs_index == OptionArgElement::eBareDoubleDash) + continue; + + int cur_arg_pos = opt_element_vector[i].opt_arg_pos; + const char *cur_opt_name = opt_defs[cur_defs_index].long_option; + + // If this is the "shlib" option and there was an argument provided, + // restrict it to that shared library. + if (cur_opt_name && strcmp(cur_opt_name, "shlib") == 0 && + cur_arg_pos != -1) { + const char *module_name = input.GetArgumentAtIndex(cur_arg_pos); + if (module_name) { + FileSpec module_spec(module_name, false); + lldb::TargetSP target_sp = + interpreter.GetDebugger().GetSelectedTarget(); + // Search filters require a target... + if (target_sp) + filter_ap.reset(new SearchFilterByModule(target_sp, module_spec)); } + break; + } } + } - return CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, - completion_mask, - input.GetArgumentAtIndex (opt_arg_pos), - match_start_point, - max_return_elements, - filter_ap.get(), - word_complete, - matches); - + return CommandCompletions::InvokeCommonCompletionCallbacks( + interpreter, completion_mask, input.GetArgumentAtIndex(opt_arg_pos), + match_start_point, max_return_elements, filter_ap.get(), word_complete, + matches); } - -void -OptionGroupOptions::Append (OptionGroup* group) -{ - const OptionDefinition* group_option_defs = group->GetDefinitions (); - const uint32_t group_option_count = group->GetNumDefinitions(); - for (uint32_t i=0; i<group_option_count; ++i) - { - m_option_infos.push_back (OptionInfo (group, i)); - m_option_defs.push_back (group_option_defs[i]); - } +void OptionGroupOptions::Append(OptionGroup *group) { + auto group_option_defs = group->GetDefinitions(); + for (uint32_t i = 0; i < group_option_defs.size(); ++i) { + m_option_infos.push_back(OptionInfo(group, i)); + m_option_defs.push_back(group_option_defs[i]); + } } -const OptionGroup* -OptionGroupOptions::GetGroupWithOption (char short_opt) -{ - for (uint32_t i = 0; i < m_option_defs.size(); i++) - { - OptionDefinition opt_def = m_option_defs[i]; - if (opt_def.short_option == short_opt) - return m_option_infos[i].option_group; - } - return nullptr; +const OptionGroup *OptionGroupOptions::GetGroupWithOption(char short_opt) { + for (uint32_t i = 0; i < m_option_defs.size(); i++) { + OptionDefinition opt_def = m_option_defs[i]; + if (opt_def.short_option == short_opt) + return m_option_infos[i].option_group; + } + return nullptr; } -void -OptionGroupOptions::Append (OptionGroup* group, - uint32_t src_mask, - uint32_t dst_mask) -{ - const OptionDefinition* group_option_defs = group->GetDefinitions (); - const uint32_t group_option_count = group->GetNumDefinitions(); - for (uint32_t i=0; i<group_option_count; ++i) - { - if (group_option_defs[i].usage_mask & src_mask) - { - m_option_infos.push_back (OptionInfo (group, i)); - m_option_defs.push_back (group_option_defs[i]); - m_option_defs.back().usage_mask = dst_mask; - } +void OptionGroupOptions::Append(OptionGroup *group, uint32_t src_mask, + uint32_t dst_mask) { + auto group_option_defs = group->GetDefinitions(); + for (uint32_t i = 0; i < group_option_defs.size(); ++i) { + if (group_option_defs[i].usage_mask & src_mask) { + m_option_infos.push_back(OptionInfo(group, i)); + m_option_defs.push_back(group_option_defs[i]); + m_option_defs.back().usage_mask = dst_mask; } + } } -void -OptionGroupOptions::Finalize () -{ - m_did_finalize = true; - OptionDefinition empty_option_def = { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }; - m_option_defs.push_back (empty_option_def); +void OptionGroupOptions::Finalize() { + m_did_finalize = true; } -Error -OptionGroupOptions::SetOptionValue (uint32_t option_idx, - const char *option_value) -{ - // After calling OptionGroupOptions::Append(...), you must finalize the groups - // by calling OptionGroupOptions::Finlize() - assert (m_did_finalize); - assert (m_option_infos.size() + 1 == m_option_defs.size()); - Error error; - if (option_idx < m_option_infos.size()) - { - error = m_option_infos[option_idx].option_group->SetOptionValue (m_interpreter, - m_option_infos[option_idx].option_index, - option_value); - - } - else - { - error.SetErrorString ("invalid option index"); // Shouldn't happen... - } - return error; +Error OptionGroupOptions::SetOptionValue(uint32_t option_idx, + llvm::StringRef option_value, + ExecutionContext *execution_context) { + // After calling OptionGroupOptions::Append(...), you must finalize the groups + // by calling OptionGroupOptions::Finlize() + assert(m_did_finalize); + Error error; + if (option_idx < m_option_infos.size()) { + error = m_option_infos[option_idx].option_group->SetOptionValue( + m_option_infos[option_idx].option_index, option_value, + execution_context); + + } else { + error.SetErrorString("invalid option index"); // Shouldn't happen... + } + return error; } -void -OptionGroupOptions::OptionParsingStarting () -{ - std::set<OptionGroup*> group_set; - OptionInfos::iterator pos, end = m_option_infos.end(); - for (pos = m_option_infos.begin(); pos != end; ++pos) - { - OptionGroup* group = pos->option_group; - if (group_set.find(group) == group_set.end()) - { - group->OptionParsingStarting (m_interpreter); - group_set.insert(group); - } +void OptionGroupOptions::OptionParsingStarting( + ExecutionContext *execution_context) { + std::set<OptionGroup *> group_set; + OptionInfos::iterator pos, end = m_option_infos.end(); + for (pos = m_option_infos.begin(); pos != end; ++pos) { + OptionGroup *group = pos->option_group; + if (group_set.find(group) == group_set.end()) { + group->OptionParsingStarting(execution_context); + group_set.insert(group); } + } } -Error -OptionGroupOptions::OptionParsingFinished () -{ - std::set<OptionGroup*> group_set; - Error error; - OptionInfos::iterator pos, end = m_option_infos.end(); - for (pos = m_option_infos.begin(); pos != end; ++pos) - { - OptionGroup* group = pos->option_group; - if (group_set.find(group) == group_set.end()) - { - error = group->OptionParsingFinished (m_interpreter); - group_set.insert(group); - if (error.Fail()) - return error; - } +Error OptionGroupOptions::OptionParsingFinished( + ExecutionContext *execution_context) { + std::set<OptionGroup *> group_set; + Error error; + OptionInfos::iterator pos, end = m_option_infos.end(); + for (pos = m_option_infos.begin(); pos != end; ++pos) { + OptionGroup *group = pos->option_group; + if (group_set.find(group) == group_set.end()) { + error = group->OptionParsingFinished(execution_context); + group_set.insert(group); + if (error.Fail()) + return error; } - return error; + } + return error; } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp b/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp index b9fe286..5bac5ea 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp @@ -22,289 +22,278 @@ using namespace lldb; using namespace lldb_private; -Property::Property (const PropertyDefinition &definition) : - m_name (definition.name), - m_description (definition.description), - m_value_sp (), - m_is_global (definition.global) -{ - switch (definition.type) - { - case OptionValue::eTypeInvalid: - case OptionValue::eTypeProperties: - break; - case OptionValue::eTypeArch: - // "definition.default_uint_value" is not used - // "definition.default_cstr_value" as a string value that represents the default string value for the architecture/triple - m_value_sp.reset (new OptionValueArch(definition.default_cstr_value)); - break; - - case OptionValue::eTypeArgs: - // "definition.default_uint_value" is always a OptionValue::Type - m_value_sp.reset (new OptionValueArgs()); - break; - - case OptionValue::eTypeArray: - // "definition.default_uint_value" is always a OptionValue::Type - m_value_sp.reset (new OptionValueArray(OptionValue::ConvertTypeToMask((OptionValue::Type)definition.default_uint_value))); - break; - - case OptionValue::eTypeBoolean: - // "definition.default_uint_value" is the default boolean value if - // "definition.default_cstr_value" is NULL, otherwise interpret - // "definition.default_cstr_value" as a string value that represents the default - // value. - if (definition.default_cstr_value) - m_value_sp.reset (new OptionValueBoolean(Args::StringToBoolean (definition.default_cstr_value, false, nullptr))); - else - m_value_sp.reset (new OptionValueBoolean(definition.default_uint_value != 0)); - break; +Property::Property(const PropertyDefinition &definition) + : m_name(definition.name), m_description(definition.description), + m_value_sp(), m_is_global(definition.global) { + switch (definition.type) { + case OptionValue::eTypeInvalid: + case OptionValue::eTypeProperties: + break; + case OptionValue::eTypeArch: + // "definition.default_uint_value" is not used + // "definition.default_cstr_value" as a string value that represents the + // default string value for the architecture/triple + m_value_sp.reset(new OptionValueArch(definition.default_cstr_value)); + break; - case OptionValue::eTypeChar: - m_value_sp.reset(new OptionValueChar(Args::StringToChar(definition.default_cstr_value, '\0', nullptr))); - break; + case OptionValue::eTypeArgs: + // "definition.default_uint_value" is always a OptionValue::Type + m_value_sp.reset(new OptionValueArgs()); + break; - case OptionValue::eTypeDictionary: - // "definition.default_uint_value" is always a OptionValue::Type - m_value_sp.reset (new OptionValueDictionary(OptionValue::ConvertTypeToMask((OptionValue::Type)definition.default_uint_value))); - break; - - case OptionValue::eTypeEnum: - // "definition.default_uint_value" is the default enumeration value if - // "definition.default_cstr_value" is NULL, otherwise interpret - // "definition.default_cstr_value" as a string value that represents the default - // value. - { - OptionValueEnumeration *enum_value = new OptionValueEnumeration(definition.enum_values, definition.default_uint_value); - m_value_sp.reset (enum_value); - if (definition.default_cstr_value) - { - if (enum_value->SetValueFromString(definition.default_cstr_value).Success()) - { - enum_value->SetDefaultValue(enum_value->GetCurrentValue()); - // Call Clear() since we don't want the value to appear as - // having been set since we called SetValueFromString() above. - // Clear will set the current value to the default and clear - // the boolean that says that the value has been set. - enum_value->Clear(); - } - } - } - break; - - case OptionValue::eTypeFileSpec: - { - // "definition.default_uint_value" represents if the "definition.default_cstr_value" should - // be resolved or not - const bool resolve = definition.default_uint_value != 0; - m_value_sp.reset (new OptionValueFileSpec(FileSpec(definition.default_cstr_value, resolve), resolve)); - break; - } - - case OptionValue::eTypeFileSpecList: - // "definition.default_uint_value" is not used for a OptionValue::eTypeFileSpecList - m_value_sp.reset (new OptionValueFileSpecList()); - break; - - case OptionValue::eTypeFormat: - // "definition.default_uint_value" is the default format enumeration value if - // "definition.default_cstr_value" is NULL, otherwise interpret - // "definition.default_cstr_value" as a string value that represents the default - // value. - { - Format new_format = eFormatInvalid; - if (definition.default_cstr_value) - Args::StringToFormat (definition.default_cstr_value, new_format, nullptr); - else - new_format = (Format)definition.default_uint_value; - m_value_sp.reset (new OptionValueFormat(new_format)); - } - break; - - case OptionValue::eTypeLanguage: - // "definition.default_uint_value" is the default language enumeration value if - // "definition.default_cstr_value" is NULL, otherwise interpret - // "definition.default_cstr_value" as a string value that represents the default - // value. - { - LanguageType new_lang = eLanguageTypeUnknown; - if (definition.default_cstr_value) - Language::GetLanguageTypeFromString(definition.default_cstr_value); - else - new_lang = (LanguageType)definition.default_uint_value; - m_value_sp.reset (new OptionValueLanguage(new_lang)); - } - break; - - case OptionValue::eTypeFormatEntity: - // "definition.default_cstr_value" as a string value that represents the default - m_value_sp.reset (new OptionValueFormatEntity(definition.default_cstr_value)); - break; + case OptionValue::eTypeArray: + // "definition.default_uint_value" is always a OptionValue::Type + m_value_sp.reset(new OptionValueArray(OptionValue::ConvertTypeToMask( + (OptionValue::Type)definition.default_uint_value))); + break; - case OptionValue::eTypePathMap: - // "definition.default_uint_value" tells us if notifications should occur for - // path mappings - m_value_sp.reset (new OptionValuePathMappings(definition.default_uint_value != 0)); - break; - - case OptionValue::eTypeRegex: - // "definition.default_uint_value" is used to the regular expression flags - // "definition.default_cstr_value" the default regular expression value - // value. - m_value_sp.reset (new OptionValueRegex(definition.default_cstr_value)); - break; - - case OptionValue::eTypeSInt64: - // "definition.default_uint_value" is the default integer value if - // "definition.default_cstr_value" is NULL, otherwise interpret - // "definition.default_cstr_value" as a string value that represents the default - // value. - m_value_sp.reset (new OptionValueSInt64(definition.default_cstr_value ? StringConvert::ToSInt64 (definition.default_cstr_value) : definition.default_uint_value)); - break; - - case OptionValue::eTypeUInt64: - // "definition.default_uint_value" is the default unsigned integer value if - // "definition.default_cstr_value" is NULL, otherwise interpret - // "definition.default_cstr_value" as a string value that represents the default - // value. - m_value_sp.reset (new OptionValueUInt64(definition.default_cstr_value ? StringConvert::ToUInt64 (definition.default_cstr_value) : definition.default_uint_value)); - break; - - case OptionValue::eTypeUUID: - // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID - // "definition.default_cstr_value" can contain a default UUID value - { - UUID uuid; - if (definition.default_cstr_value) - uuid.SetFromCString (definition.default_cstr_value); - m_value_sp.reset (new OptionValueUUID(uuid)); - } - break; - - case OptionValue::eTypeString: - // "definition.default_uint_value" can contain the string option flags OR'ed together - // "definition.default_cstr_value" can contain a default string value - { - OptionValueString *string_value = new OptionValueString(definition.default_cstr_value); - if (definition.default_uint_value != 0) - string_value->GetOptions().Reset(definition.default_uint_value); - m_value_sp.reset (string_value); - } - break; - } -} + case OptionValue::eTypeBoolean: + // "definition.default_uint_value" is the default boolean value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the + // default value. + if (definition.default_cstr_value) + m_value_sp.reset(new OptionValueBoolean(Args::StringToBoolean( + llvm::StringRef(definition.default_cstr_value), false, nullptr))); + else + m_value_sp.reset( + new OptionValueBoolean(definition.default_uint_value != 0)); + break; -Property::Property (const ConstString &name, - const ConstString &desc, - bool is_global, - const lldb::OptionValueSP &value_sp) : - m_name (name), - m_description (desc), - m_value_sp (value_sp), - m_is_global (is_global) -{ -} + case OptionValue::eTypeChar: { + llvm::StringRef s(definition.default_cstr_value ? definition.default_cstr_value : ""); + m_value_sp = std::make_shared<OptionValueChar>(Args::StringToChar(s, '\0', nullptr)); + break; + } + case OptionValue::eTypeDictionary: + // "definition.default_uint_value" is always a OptionValue::Type + m_value_sp.reset(new OptionValueDictionary(OptionValue::ConvertTypeToMask( + (OptionValue::Type)definition.default_uint_value))); + break; -bool -Property::DumpQualifiedName(Stream &strm) const -{ - if (m_name) + case OptionValue::eTypeEnum: + // "definition.default_uint_value" is the default enumeration value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the + // default + // value. { - if (m_value_sp->DumpQualifiedName(strm)) - strm.PutChar('.'); - strm << m_name; - return true; + OptionValueEnumeration *enum_value = new OptionValueEnumeration( + definition.enum_values, definition.default_uint_value); + m_value_sp.reset(enum_value); + if (definition.default_cstr_value) { + if (enum_value + ->SetValueFromString( + llvm::StringRef(definition.default_cstr_value)) + .Success()) { + enum_value->SetDefaultValue(enum_value->GetCurrentValue()); + // Call Clear() since we don't want the value to appear as + // having been set since we called SetValueFromString() above. + // Clear will set the current value to the default and clear + // the boolean that says that the value has been set. + enum_value->Clear(); + } + } } - return false; -} + break; + case OptionValue::eTypeFileSpec: { + // "definition.default_uint_value" represents if the + // "definition.default_cstr_value" should + // be resolved or not + const bool resolve = definition.default_uint_value != 0; + m_value_sp.reset(new OptionValueFileSpec( + FileSpec(definition.default_cstr_value, resolve), resolve)); + break; + } -void -Property::Dump (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) const -{ - if (m_value_sp) + case OptionValue::eTypeFileSpecList: + // "definition.default_uint_value" is not used for a + // OptionValue::eTypeFileSpecList + m_value_sp.reset(new OptionValueFileSpecList()); + break; + + case OptionValue::eTypeFormat: + // "definition.default_uint_value" is the default format enumeration value + // if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the + // default + // value. { - const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription; - const bool transparent = m_value_sp->ValueIsTransparent (); - if (dump_desc || !transparent) - { - if ((dump_mask & OptionValue::eDumpOptionName) && m_name) - { - DumpQualifiedName(strm); - if (dump_mask & ~OptionValue::eDumpOptionName) - strm.PutChar(' '); - } - } - if (dump_desc) - { - const char *desc = GetDescription(); - if (desc) - strm.Printf ("-- %s", desc); - - if (transparent && (dump_mask == (OptionValue::eDumpOptionName | OptionValue::eDumpOptionDescription))) - strm.EOL(); - } - m_value_sp->DumpValue(exe_ctx, strm, dump_mask); + Format new_format = eFormatInvalid; + if (definition.default_cstr_value) + Args::StringToFormat(definition.default_cstr_value, new_format, + nullptr); + else + new_format = (Format)definition.default_uint_value; + m_value_sp.reset(new OptionValueFormat(new_format)); } -} + break; + + case OptionValue::eTypeLanguage: + // "definition.default_uint_value" is the default language enumeration value + // if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the + // default + // value. + { + LanguageType new_lang = eLanguageTypeUnknown; + if (definition.default_cstr_value) + Language::GetLanguageTypeFromString( + llvm::StringRef(definition.default_cstr_value)); + else + new_lang = (LanguageType)definition.default_uint_value; + m_value_sp.reset(new OptionValueLanguage(new_lang)); + } + break; + + case OptionValue::eTypeFormatEntity: + // "definition.default_cstr_value" as a string value that represents the + // default + m_value_sp.reset( + new OptionValueFormatEntity(definition.default_cstr_value)); + break; + case OptionValue::eTypePathMap: + // "definition.default_uint_value" tells us if notifications should occur + // for + // path mappings + m_value_sp.reset( + new OptionValuePathMappings(definition.default_uint_value != 0)); + break; -void -Property::DumpDescription (CommandInterpreter &interpreter, - Stream &strm, - uint32_t output_width, - bool display_qualified_name) const -{ - if (m_value_sp) + case OptionValue::eTypeRegex: + // "definition.default_uint_value" is used to the regular expression flags + // "definition.default_cstr_value" the default regular expression value + // value. + m_value_sp.reset(new OptionValueRegex(definition.default_cstr_value)); + break; + + case OptionValue::eTypeSInt64: + // "definition.default_uint_value" is the default integer value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the + // default + // value. + m_value_sp.reset(new OptionValueSInt64( + definition.default_cstr_value + ? StringConvert::ToSInt64(definition.default_cstr_value) + : definition.default_uint_value)); + break; + + case OptionValue::eTypeUInt64: + // "definition.default_uint_value" is the default unsigned integer value if + // "definition.default_cstr_value" is NULL, otherwise interpret + // "definition.default_cstr_value" as a string value that represents the + // default + // value. + m_value_sp.reset(new OptionValueUInt64( + definition.default_cstr_value + ? StringConvert::ToUInt64(definition.default_cstr_value) + : definition.default_uint_value)); + break; + + case OptionValue::eTypeUUID: + // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID + // "definition.default_cstr_value" can contain a default UUID value { - const char *desc = GetDescription(); + UUID uuid; + if (definition.default_cstr_value) + uuid.SetFromCString(definition.default_cstr_value); + m_value_sp.reset(new OptionValueUUID(uuid)); + } + break; - if (desc) - { - StreamString qualified_name; - const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties(); - if (sub_properties) - { - strm.EOL(); - - if (m_value_sp->DumpQualifiedName(qualified_name)) - strm.Printf("'%s' variables:\n\n", qualified_name.GetString().c_str()); - sub_properties->DumpAllDescriptions(interpreter, strm); - } - else - { - if (desc) - { - if (display_qualified_name) - { - StreamString qualified_name; - DumpQualifiedName(qualified_name); - interpreter.OutputFormattedHelpText (strm, - qualified_name.GetString().c_str(), - "--", - desc, - output_width); - } - else - { - interpreter.OutputFormattedHelpText (strm, - m_name.GetCString(), - "--", - desc, - output_width); - } - } - } - } + case OptionValue::eTypeString: + // "definition.default_uint_value" can contain the string option flags OR'ed + // together + // "definition.default_cstr_value" can contain a default string value + { + OptionValueString *string_value = + new OptionValueString(definition.default_cstr_value); + if (definition.default_uint_value != 0) + string_value->GetOptions().Reset(definition.default_uint_value); + m_value_sp.reset(string_value); } + break; + } } +Property::Property(const ConstString &name, const ConstString &desc, + bool is_global, const lldb::OptionValueSP &value_sp) + : m_name(name), m_description(desc), m_value_sp(value_sp), + m_is_global(is_global) {} -void -Property::SetValueChangedCallback (OptionValueChangedCallback callback, void *baton) -{ - if (m_value_sp) - m_value_sp->SetValueChangedCallback (callback, baton); +bool Property::DumpQualifiedName(Stream &strm) const { + if (m_name) { + if (m_value_sp->DumpQualifiedName(strm)) + strm.PutChar('.'); + strm << m_name; + return true; + } + return false; } +void Property::Dump(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) const { + if (m_value_sp) { + const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription; + const bool transparent = m_value_sp->ValueIsTransparent(); + if (dump_desc || !transparent) { + if ((dump_mask & OptionValue::eDumpOptionName) && m_name) { + DumpQualifiedName(strm); + if (dump_mask & ~OptionValue::eDumpOptionName) + strm.PutChar(' '); + } + } + if (dump_desc) { + llvm::StringRef desc = GetDescription(); + if (!desc.empty()) + strm << "-- " << desc; + if (transparent && (dump_mask == (OptionValue::eDumpOptionName | + OptionValue::eDumpOptionDescription))) + strm.EOL(); + } + m_value_sp->DumpValue(exe_ctx, strm, dump_mask); + } +} + +void Property::DumpDescription(CommandInterpreter &interpreter, Stream &strm, + uint32_t output_width, + bool display_qualified_name) const { + if (!m_value_sp) + return; + llvm::StringRef desc = GetDescription(); + + if (desc.empty()) + return; + + StreamString qualified_name; + const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties(); + if (sub_properties) { + strm.EOL(); + + if (m_value_sp->DumpQualifiedName(qualified_name)) + strm.Printf("'%s' variables:\n\n", qualified_name.GetData()); + sub_properties->DumpAllDescriptions(interpreter, strm); + } else { + if (display_qualified_name) { + StreamString qualified_name; + DumpQualifiedName(qualified_name); + interpreter.OutputFormattedHelpText(strm, qualified_name.GetString(), + "--", desc, output_width); + } else { + interpreter.OutputFormattedHelpText(strm, m_name.GetStringRef(), "--", + desc, output_width); + } + } +} + +void Property::SetValueChangedCallback(OptionValueChangedCallback callback, + void *baton) { + if (m_value_sp) + m_value_sp->SetValueChangedCallback(callback, baton); +} diff --git a/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp b/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp index f1ec50e..d87d24e 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -9,9 +9,9 @@ #include "lldb/Interpreter/ScriptInterpreter.h" -#include <string> -#include <stdlib.h> #include <stdio.h> +#include <stdlib.h> +#include <string> #include "lldb/Core/Error.h" #include "lldb/Core/Stream.h" @@ -22,88 +22,81 @@ using namespace lldb; using namespace lldb_private; -ScriptInterpreter::ScriptInterpreter (CommandInterpreter &interpreter, lldb::ScriptLanguage script_lang) : - m_interpreter (interpreter), - m_script_lang (script_lang) -{ -} +ScriptInterpreter::ScriptInterpreter(CommandInterpreter &interpreter, + lldb::ScriptLanguage script_lang) + : m_interpreter(interpreter), m_script_lang(script_lang) {} -ScriptInterpreter::~ScriptInterpreter () -{ -} +ScriptInterpreter::~ScriptInterpreter() {} -CommandInterpreter & -ScriptInterpreter::GetCommandInterpreter () -{ - return m_interpreter; +CommandInterpreter &ScriptInterpreter::GetCommandInterpreter() { + return m_interpreter; } -void -ScriptInterpreter::CollectDataForBreakpointCommandCallback -( +void ScriptInterpreter::CollectDataForBreakpointCommandCallback( std::vector<BreakpointOptions *> &bp_options_vec, - CommandReturnObject &result -) -{ - result.SetStatus (eReturnStatusFailed); - result.AppendError ("ScriptInterpreter::GetScriptCommands(StringList &) is not implemented."); + CommandReturnObject &result) { + result.SetStatus(eReturnStatusFailed); + result.AppendError( + "ScriptInterpreter::GetScriptCommands(StringList &) is not implemented."); } -void -ScriptInterpreter::CollectDataForWatchpointCommandCallback -( - WatchpointOptions *bp_options, - CommandReturnObject &result -) -{ - result.SetStatus (eReturnStatusFailed); - result.AppendError ("ScriptInterpreter::GetScriptCommands(StringList &) is not implemented."); +void ScriptInterpreter::CollectDataForWatchpointCommandCallback( + WatchpointOptions *bp_options, CommandReturnObject &result) { + result.SetStatus(eReturnStatusFailed); + result.AppendError( + "ScriptInterpreter::GetScriptCommands(StringList &) is not implemented."); } -std::string -ScriptInterpreter::LanguageToString (lldb::ScriptLanguage language) -{ - std::string return_value; - - switch (language) - { - case eScriptLanguageNone: - return_value = "None"; - break; - case eScriptLanguagePython: - return_value = "Python"; - break; - } - - return return_value; +std::string ScriptInterpreter::LanguageToString(lldb::ScriptLanguage language) { + std::string return_value; + + switch (language) { + case eScriptLanguageNone: + return_value = "None"; + break; + case eScriptLanguagePython: + return_value = "Python"; + break; + case eScriptLanguageUnknown: + return_value = "Unknown"; + break; + } + + return return_value; +} + +lldb::ScriptLanguage +ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) { + if (language.equals_lower(LanguageToString(eScriptLanguageNone))) + return eScriptLanguageNone; + else if (language.equals_lower(LanguageToString(eScriptLanguagePython))) + return eScriptLanguagePython; + else + return eScriptLanguageUnknown; } -Error -ScriptInterpreter::SetBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, - const char *callback_text) -{ - Error return_error; - for (BreakpointOptions *bp_options : bp_options_vec) - { - return_error = SetBreakpointCommandCallback(bp_options, callback_text); - if (return_error.Success()) - break; - } - return return_error; +Error ScriptInterpreter::SetBreakpointCommandCallback( + std::vector<BreakpointOptions *> &bp_options_vec, + const char *callback_text) { + Error return_error; + for (BreakpointOptions *bp_options : bp_options_vec) { + return_error = SetBreakpointCommandCallback(bp_options, callback_text); + if (return_error.Success()) + break; + } + return return_error; } -void -ScriptInterpreter::SetBreakpointCommandCallbackFunction (std::vector<BreakpointOptions *> &bp_options_vec, - const char *function_name) -{ - for (BreakpointOptions *bp_options : bp_options_vec) - { - SetBreakpointCommandCallbackFunction(bp_options, function_name); - } +void ScriptInterpreter::SetBreakpointCommandCallbackFunction( + std::vector<BreakpointOptions *> &bp_options_vec, + const char *function_name) { + for (BreakpointOptions *bp_options : bp_options_vec) { + SetBreakpointCommandCallbackFunction(bp_options, function_name); + } } std::unique_ptr<ScriptInterpreterLocker> -ScriptInterpreter::AcquireInterpreterLock () -{ - return std::unique_ptr<ScriptInterpreterLocker>(new ScriptInterpreterLocker()); +ScriptInterpreter::AcquireInterpreterLock() { + return std::unique_ptr<ScriptInterpreterLocker>( + new ScriptInterpreterLocker()); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py b/contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py index 8ba539a..c103b7e 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py +++ b/contrib/llvm/tools/lldb/source/Interpreter/embedded_interpreter.py @@ -25,16 +25,21 @@ else: g_builtin_override_called = False + class LLDBQuitter(object): + def __init__(self, name): self.name = name + def __repr__(self): self() + def __call__(self, code=None): global g_builtin_override_called g_builtin_override_called = True raise SystemExit(-1) + def setquit(): '''Redefine builtin functions 'quit()' and 'exit()' to print a message and raise an EOFError exception.''' # This function will be called prior to each interactive @@ -56,21 +61,25 @@ g_run_one_line_str = None def get_terminal_size(fd): try: - import fcntl, termios, struct + import fcntl + import termios + import struct hw = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) except: - hw = (0,0) + hw = (0, 0) return hw + def readfunc_stdio(prompt): sys.stdout.write(prompt) return sys.stdin.readline().rstrip() -def run_python_interpreter (local_dict): + +def run_python_interpreter(local_dict): # Pass in the dictionary, for continuity from one session to the next. setquit() try: - fd = sys.stdin.fileno(); + fd = sys.stdin.fileno() interacted = False if get_terminal_size(fd)[1] == 0: try: @@ -83,33 +92,42 @@ def run_python_interpreter (local_dict): try: termios.tcsetattr(fd, termios.TCSADRAIN, new) interacted = True - code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.", readfunc=readfunc_stdio, local=local_dict) + code.interact( + banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.", + readfunc=readfunc_stdio, + local=local_dict) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old) except: pass # Don't need to turn off echoing if not interacted: - code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", readfunc=readfunc_stdio, local=local_dict) + code.interact( + banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", + readfunc=readfunc_stdio, + local=local_dict) else: # We have a real interactive terminal - code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", local=local_dict) + code.interact( + banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", + local=local_dict) except SystemExit as e: global g_builtin_override_called if not g_builtin_override_called: - print('Script exited with %s' %(e)) + print('Script exited with %s' % (e)) + -def run_one_line (local_dict, input_string): +def run_one_line(local_dict, input_string): global g_run_one_line_str setquit() try: - repl = code.InteractiveConsole(local_dict); + repl = code.InteractiveConsole(local_dict) if input_string: - repl.runsource (input_string) + repl.runsource(input_string) elif g_run_one_line_str: - repl.runsource (g_run_one_line_str) + repl.runsource(g_run_one_line_str) except SystemExit as e: global g_builtin_override_called if not g_builtin_override_called: - print('Script exited with %s' %(e)) + print('Script exited with %s' % (e)) |