Index: include/lldb/Interpreter/Args.h =================================================================== --- include/lldb/Interpreter/Args.h +++ include/lldb/Interpreter/Args.h @@ -150,9 +150,14 @@ const char *GetArgumentAtIndex(size_t idx) const; llvm::ArrayRef entries() const { return m_entries; } - char GetArgumentQuoteCharAtIndex(size_t idx) const; + auto begin() const { return m_entries.begin(); } + auto end() const { return m_entries.end(); } + + size_t size() const { return GetArgumentCount(); } + const ArgEntry &operator[](size_t n) const { return m_entries[n]; } + //------------------------------------------------------------------ /// Gets the argument vector. /// Index: source/Breakpoint/BreakpointIDList.cpp =================================================================== --- source/Breakpoint/BreakpointIDList.cpp +++ source/Breakpoint/BreakpointIDList.cpp @@ -122,13 +122,12 @@ llvm::StringRef range_from; llvm::StringRef range_to; llvm::StringRef current_arg; - const size_t num_old_args = old_args.GetArgumentCount(); std::set names_found; - for (size_t i = 0; i < num_old_args; ++i) { + for (size_t i = 0; i < old_args.size(); ++i) { bool is_range = false; - current_arg = old_args.GetArgumentAtIndex(i); + current_arg = old_args[i].ref; if (!allow_locations && current_arg.contains('.')) { result.AppendErrorWithFormat( "Breakpoint locations not allowed, saw location: %s.", @@ -152,19 +151,17 @@ return; } else names_found.insert(current_arg); - } else if ((i + 2 < num_old_args) && - BreakpointID::IsRangeIdentifier( - old_args.GetArgumentAtIndex(i + 1)) && + } else if ((i + 2 < old_args.size()) && + BreakpointID::IsRangeIdentifier(old_args[i + 1].ref) && BreakpointID::IsValidIDExpression(current_arg) && - BreakpointID::IsValidIDExpression( - old_args.GetArgumentAtIndex(i + 2))) { + BreakpointID::IsValidIDExpression(old_args[i + 2].ref)) { range_from = current_arg; - range_to = old_args.GetArgumentAtIndex(i + 2); + range_to = old_args[i + 2].ref; is_range = true; i = i + 2; } else { // See if user has specified id.* - llvm::StringRef tmp_str = old_args.GetArgumentAtIndex(i); + llvm::StringRef tmp_str = old_args[i].ref; size_t pos = tmp_str.find('.'); if (pos != llvm::StringRef::npos) { llvm::StringRef bp_id_str = tmp_str.substr(0, pos); Index: source/Commands/CommandObjectCommands.cpp =================================================================== --- source/Commands/CommandObjectCommands.cpp +++ source/Commands/CommandObjectCommands.cpp @@ -1476,12 +1476,12 @@ int match_start_point, int max_return_elements, bool &word_complete, StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); + llvm::StringRef completion_str = input[cursor_index].ref; + completion_str = completion_str.take_front(cursor_char_position); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, + completion_str, match_start_point, max_return_elements, nullptr, word_complete, matches); return matches.GetSize(); } Index: source/Commands/CommandObjectFrame.cpp =================================================================== --- source/Commands/CommandObjectFrame.cpp +++ source/Commands/CommandObjectFrame.cpp @@ -473,12 +473,12 @@ bool &word_complete, StringList &matches) override { // Arguments are the standard source file completer. - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); + auto completion_str = input[cursor_index].ref; + completion_str = completion_str.take_front(cursor_char_position); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, + completion_str, match_start_point, max_return_elements, nullptr, word_complete, matches); return matches.GetSize(); } Index: source/Commands/CommandObjectProcess.cpp =================================================================== --- source/Commands/CommandObjectProcess.cpp +++ source/Commands/CommandObjectProcess.cpp @@ -1558,9 +1558,8 @@ int num_signals_set = 0; if (num_args > 0) { - for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals_sp->GetSignalNumberFromName( - signal_args.GetArgumentAtIndex(i)); + for (const auto &arg : signal_args) { + int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str()); if (signo != LLDB_INVALID_SIGNAL_NUMBER) { // Casting the actions as bools here should be okay, because // VerifyCommandOptionValue guarantees @@ -1576,7 +1575,7 @@ ++num_signals_set; } else { result.AppendErrorWithFormat("Invalid signal name '%s'\n", - signal_args.GetArgumentAtIndex(i)); + arg.c_str()); } } } else { Index: source/Commands/CommandObjectSettings.cpp =================================================================== --- source/Commands/CommandObjectSettings.cpp +++ source/Commands/CommandObjectSettings.cpp @@ -295,13 +295,9 @@ const size_t argc = args.GetArgumentCount(); if (!args.empty()) { - // TODO: Convert this to StringRef based enumeration. Requires converting - // DumpPropertyValue first. - for (size_t i = 0; i < argc; ++i) { - const char *property_path = args.GetArgumentAtIndex(i); - + for (const auto &arg : args) { Error error(m_interpreter.GetDebugger().DumpPropertyValue( - &m_exe_ctx, result.GetOutputStream(), property_path, + &m_exe_ctx, result.GetOutputStream(), arg.ref, OptionValue::eDumpGroupValue)); if (error.Success()) { result.GetOutputStream().EOL(); Index: source/Interpreter/CommandInterpreter.cpp =================================================================== --- source/Interpreter/CommandInterpreter.cpp +++ source/Interpreter/CommandInterpreter.cpp @@ -1859,9 +1859,8 @@ // 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); + command_partial_str = + parsed_line[cursor_index].ref.take_front(cursor_char_position); std::string common_prefix; matches.LongestCommonPrefix(common_prefix); @@ -1872,7 +1871,7 @@ // 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); + char quote_char = parsed_line[cursor_index].quote; common_prefix = Args::EscapeLLDBCommandArgument(common_prefix, quote_char); if (quote_char != '\0') Index: source/Interpreter/OptionValueDictionary.cpp =================================================================== --- source/Interpreter/OptionValueDictionary.cpp +++ source/Interpreter/OptionValueDictionary.cpp @@ -101,73 +101,74 @@ 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; - } + 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; + } + + 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; + } - std::pair 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: - // [''] - // [""] - 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 + if (key.front() == '[') { + // Key name starts with '[', so the key value must be in single or + // double quotes like: + // [''] + // [""] + 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_valid) { - error.SetErrorStringWithFormat( - "invalid key \"%s\", the key must be a bare string or " - "surrounded by brackets with optional quotes: [] or " - "[''] or [\"\"]", - 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"); + // square brackets, no quotes + key_valid = true; } - } else { - error.SetErrorString("empty argument"); } + } 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: [] or " + "[''] or [\"\"]", + 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"); } - } else { - error.SetErrorString( - "assign operation takes one or more key=value arguments"); } break;