From 31d97a5c8ab78c619deada0cdb1fcf64021d25dd Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 17 Nov 2016 18:08:12 +0000 Subject: [PATCH] Rewrite all Property related functions in terms of StringRef. This was a bit tricky, especially for things like OptionValueArray and OptionValueDictionary since they do some funky string parsing. Rather than try to re-write line-by-line I tried to make the StringRef usage idiomatic, even though it meant often re-writing from scratch large blocks of code in a different way while keeping true to the original intent. The finished code is a big improvement though, and often much shorter than the original code. All tests and unit tests pass on Windows and Linux. llvm-svn: 287242 --- lldb/include/lldb/Core/DataBufferHeap.h | 1 + lldb/include/lldb/Core/Debugger.h | 4 +- lldb/include/lldb/Core/Disassembler.h | 4 +- lldb/include/lldb/Core/UserSettingsController.h | 8 +- lldb/include/lldb/Interpreter/OptionValue.h | 14 +- lldb/include/lldb/Interpreter/OptionValueArray.h | 2 +- .../lldb/Interpreter/OptionValueDictionary.h | 7 +- .../lldb/Interpreter/OptionValueProperties.h | 20 +- lldb/include/lldb/Target/ProcessInfo.h | 4 +- lldb/include/lldb/Target/Target.h | 4 +- lldb/source/Commands/CommandObjectMemory.cpp | 3 +- lldb/source/Commands/CommandObjectProcess.cpp | 6 +- lldb/source/Commands/CommandObjectSettings.cpp | 2 +- lldb/source/Core/Debugger.cpp | 13 +- lldb/source/Core/Disassembler.cpp | 5 +- lldb/source/Core/UserSettingsController.cpp | 23 +-- lldb/source/Interpreter/OptionValue.cpp | 8 +- lldb/source/Interpreter/OptionValueArgs.cpp | 15 +- lldb/source/Interpreter/OptionValueArray.cpp | 109 ++++++----- lldb/source/Interpreter/OptionValueDictionary.cpp | 131 +++++-------- lldb/source/Interpreter/OptionValueProperties.cpp | 208 ++++++++++----------- .../DarwinLog/StructuredDataDarwinLog.cpp | 4 +- lldb/source/Target/ProcessInfo.cpp | 11 +- lldb/source/Target/Target.cpp | 8 +- 24 files changed, 269 insertions(+), 345 deletions(-) diff --git a/lldb/include/lldb/Core/DataBufferHeap.h b/lldb/include/lldb/Core/DataBufferHeap.h index 5ccec1d..5528ebd 100644 --- a/lldb/include/lldb/Core/DataBufferHeap.h +++ b/lldb/include/lldb/Core/DataBufferHeap.h @@ -112,6 +112,7 @@ public: /// The number of bytes in \a src to copy. //------------------------------------------------------------------ void CopyData(const void *src, lldb::offset_t src_len); + void CopyData(llvm::StringRef src) { CopyData(src.data(), src.size()); } void AppendData(const void *src, uint64_t src_len); diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index b1f8a73..ccc07b3 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -207,8 +207,8 @@ public: }; Error SetPropertyValue(const ExecutionContext *exe_ctx, - VarSetOperationType op, const char *property_path, - const char *value) override; + VarSetOperationType op, llvm::StringRef property_path, + llvm::StringRef value) override; bool GetAutoConfirm() const; diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h index 73dbc42..c420747 100644 --- a/lldb/include/lldb/Core/Disassembler.h +++ b/lldb/include/lldb/Core/Disassembler.h @@ -131,7 +131,7 @@ public: const DataExtractor &data, lldb::offset_t data_offset) = 0; - virtual void SetDescription(const char *) { + virtual void SetDescription(llvm::StringRef) { } // May be overridden in sub-classes that have descriptions. lldb::OptionValueSP ReadArray(FILE *in_file, Stream *out_stream, @@ -290,7 +290,7 @@ public: void SetOpcode(size_t opcode_size, void *opcode_data); - void SetDescription(const char *description) override; + void SetDescription(llvm::StringRef description) override; protected: std::string m_description; diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h index 30fe0d5..a30dfd4 100644 --- a/lldb/include/lldb/Core/UserSettingsController.h +++ b/lldb/include/lldb/Core/UserSettingsController.h @@ -44,16 +44,16 @@ public: } virtual lldb::OptionValueSP GetPropertyValue(const ExecutionContext *exe_ctx, - const char *property_path, + llvm::StringRef property_path, bool will_modify, Error &error) const; virtual Error SetPropertyValue(const ExecutionContext *exe_ctx, VarSetOperationType op, - const char *property_path, const char *value); + llvm::StringRef property_path, llvm::StringRef value); virtual Error DumpPropertyValue(const ExecutionContext *exe_ctx, Stream &strm, - const char *property_path, + llvm::StringRef property_path, uint32_t dump_mask); virtual void DumpAllPropertyValues(const ExecutionContext *exe_ctx, @@ -82,7 +82,7 @@ public: // real one. static const char *GetExperimentalSettingsName(); - static bool IsSettingExperimental(const char *setting); + static bool IsSettingExperimental(llvm::StringRef setting); protected: lldb::OptionValuePropertiesSP m_collection_sp; diff --git a/lldb/include/lldb/Interpreter/OptionValue.h b/lldb/include/lldb/Interpreter/OptionValue.h index 177da602..2c1d5df 100644 --- a/lldb/include/lldb/Interpreter/OptionValue.h +++ b/lldb/include/lldb/Interpreter/OptionValue.h @@ -92,9 +92,6 @@ public: virtual Error SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign); - Error - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; virtual bool Clear() = 0; @@ -109,15 +106,15 @@ public: // Subclasses can override these functions //----------------------------------------------------------------- virtual lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx, - const char *name, bool will_modify, + llvm::StringRef name, bool will_modify, Error &error) const { - error.SetErrorStringWithFormat("'%s' is not a value subvalue", name); + error.SetErrorStringWithFormat("'%s' is not a value subvalue", name.str().c_str()); return lldb::OptionValueSP(); } virtual Error SetSubValue(const ExecutionContext *exe_ctx, - VarSetOperationType op, const char *name, - const char *value); + VarSetOperationType op, llvm::StringRef name, + llvm::StringRef value); virtual bool IsAggregateValue() const { return false; } @@ -300,7 +297,8 @@ public: bool SetSInt64Value(int64_t new_value); - const char *GetStringValue(const char *fail_value = nullptr) const; + llvm::StringRef GetStringValue(llvm::StringRef fail_value) const; + llvm::StringRef GetStringValue() const { return GetStringValue(llvm::StringRef()); } bool SetStringValue(llvm::StringRef new_value); diff --git a/lldb/include/lldb/Interpreter/OptionValueArray.h b/lldb/include/lldb/Interpreter/OptionValueArray.h index 5deb983..1e568ca 100644 --- a/lldb/include/lldb/Interpreter/OptionValueArray.h +++ b/lldb/include/lldb/Interpreter/OptionValueArray.h @@ -54,7 +54,7 @@ public: bool IsAggregateValue() const override { return true; } lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx, - const char *name, bool will_modify, + llvm::StringRef name, bool will_modify, Error &error) const override; //--------------------------------------------------------------------- diff --git a/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/lldb/include/lldb/Interpreter/OptionValueDictionary.h index a720d74..5d015a5 100644 --- a/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -41,9 +41,6 @@ public: Error SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Error - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; bool Clear() override { m_values.clear(); @@ -68,11 +65,11 @@ public: lldb::OptionValueSP GetValueForKey(const ConstString &key) const; lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx, - const char *name, bool will_modify, + llvm::StringRef name, bool will_modify, Error &error) const override; Error SetSubValue(const ExecutionContext *exe_ctx, VarSetOperationType op, - const char *name, const char *value) override; + llvm::StringRef name, llvm::StringRef value) override; bool SetValueForKey(const ConstString &key, const lldb::OptionValueSP &value_sp, diff --git a/lldb/include/lldb/Interpreter/OptionValueProperties.h b/lldb/include/lldb/Interpreter/OptionValueProperties.h index d683348..bb4202a 100644 --- a/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -46,9 +46,6 @@ public: Error SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - Error - SetValueFromString(const char *, - VarSetOperationType = eVarSetOperationAssign) = delete; void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; @@ -56,7 +53,7 @@ public: ConstString GetName() const override { return m_name; } virtual Error DumpPropertyValue(const ExecutionContext *exe_ctx, Stream &strm, - const char *property_path, + llvm::StringRef property_path, uint32_t dump_mask); virtual void DumpAllDescriptions(CommandInterpreter &interpreter, @@ -102,7 +99,7 @@ public: //--------------------------------------------------------------------- virtual const Property *GetPropertyAtPath(const ExecutionContext *exe_ctx, bool will_modify, - const char *property_path) const; + llvm::StringRef property_path) const; virtual lldb::OptionValueSP GetPropertyValueAtIndex(const ExecutionContext *exe_ctx, bool will_modify, @@ -113,14 +110,14 @@ public: bool value_will_be_modified) const; lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx, - const char *name, bool value_will_be_modified, + llvm::StringRef name, bool value_will_be_modified, Error &error) const override; Error SetSubValue(const ExecutionContext *exe_ctx, VarSetOperationType op, - const char *path, const char *value) override; + llvm::StringRef path, llvm::StringRef value) override; virtual bool PredicateMatches(const ExecutionContext *exe_ctx, - const char *predicate) const { + llvm::StringRef predicate) const { return false; } @@ -179,12 +176,9 @@ public: bool SetPropertyAtIndexAsUInt64(const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value); - const char *GetPropertyAtIndexAsString(const ExecutionContext *exe_ctx, + llvm::StringRef GetPropertyAtIndexAsString(const ExecutionContext *exe_ctx, uint32_t idx, - const char *fail_value) const; - - bool SetPropertyAtIndexAsString(const ExecutionContext *, uint32_t, - const char *) = delete; + llvm::StringRef fail_value) const; bool SetPropertyAtIndexAsString(const ExecutionContext *exe_ctx, uint32_t idx, llvm::StringRef new_value); diff --git a/lldb/include/lldb/Target/ProcessInfo.h b/lldb/include/lldb/Target/ProcessInfo.h index 72a6067..f8d37fa 100644 --- a/lldb/include/lldb/Target/ProcessInfo.h +++ b/lldb/include/lldb/Target/ProcessInfo.h @@ -73,9 +73,9 @@ public: const Args &GetArguments() const { return m_arguments; } - const char *GetArg0() const; + llvm::StringRef GetArg0() const; - void SetArg0(const char *arg); + void SetArg0(llvm::StringRef arg); void SetArguments(const Args &args, bool first_arg_is_executable); diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index b81da48..d1a67ed 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -100,9 +100,9 @@ public: InlineStrategy GetInlineStrategy() const; - const char *GetArg0() const; + llvm::StringRef GetArg0() const; - void SetArg0(const char *arg); + void SetArg0(llvm::StringRef arg); bool GetRunArguments(Args &args) const; diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index e49f49f..727a7fa 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -1062,8 +1062,7 @@ protected: DataBufferHeap buffer; if (m_memory_options.m_string.OptionWasSet()) - buffer.CopyData(m_memory_options.m_string.GetStringValue(), - strlen(m_memory_options.m_string.GetStringValue())); + buffer.CopyData(m_memory_options.m_string.GetStringValue()); else if (m_memory_options.m_expr.OptionWasSet()) { StackFrame *frame = m_exe_ctx.GetFramePtr(); ValueObjectSP result_sp; diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index dea996c..144ba3f 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -175,7 +175,7 @@ protected: if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result)) return false; - const char *target_settings_argv0 = target->GetArg0(); + llvm::StringRef target_settings_argv0 = target->GetArg0(); // Determine whether we will disable ASLR or leave it in the default state // (i.e. enabled if the platform supports it). @@ -210,9 +210,9 @@ protected: m_options.launch_info.GetEnvironmentEntries().AppendArguments( environment); - if (target_settings_argv0) { + if (!target_settings_argv0.empty()) { m_options.launch_info.GetArguments().AppendArgument( - llvm::StringRef(target_settings_argv0)); + target_settings_argv0); m_options.launch_info.SetExecutableFile( exe_module_sp->GetPlatformFileSpec(), false); } else { diff --git a/lldb/source/Commands/CommandObjectSettings.cpp b/lldb/source/Commands/CommandObjectSettings.cpp index 54efead..0a97804 100644 --- a/lldb/source/Commands/CommandObjectSettings.cpp +++ b/lldb/source/Commands/CommandObjectSettings.cpp @@ -1011,7 +1011,7 @@ protected: } Error error(m_interpreter.GetDebugger().SetPropertyValue( - &m_exe_ctx, eVarSetOperationClear, var_name, nullptr)); + &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef())); if (error.Fail()) { result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 24715ec..e66fb23 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -276,11 +276,9 @@ LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr; Error Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, VarSetOperationType op, - const char *property_path, const char *value) { - bool is_load_script = - strcmp(property_path, "target.load-script-from-symbol-file") == 0; - bool is_escape_non_printables = - strcmp(property_path, "escape-non-printables") == 0; + llvm::StringRef property_path, llvm::StringRef value) { + bool is_load_script = (property_path == "target.load-script-from-symbol-file"); + bool is_escape_non_printables = (property_path == "escape-non-printables"); TargetSP target_sp; LoadScriptFromSymFile load_script_old_value; if (is_load_script && exe_ctx->GetTargetSP()) { @@ -291,7 +289,7 @@ Error Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, Error error(Properties::SetPropertyValue(exe_ctx, op, property_path, value)); if (error.Success()) { // FIXME it would be nice to have "on-change" callbacks for properties - if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0) { + if (property_path == g_properties[ePropertyPrompt].name) { llvm::StringRef new_prompt = GetPrompt(); std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes( new_prompt, GetUseColor()); @@ -302,8 +300,7 @@ Error Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes(new_prompt))); GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp); - } else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == - 0) { + } else if (property_path == g_properties[ePropertyUseColor].name) { // use-color changed. Ping the prompt so it can reset the ansi terminal // codes. SetPrompt(GetPrompt()); diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index c55ad1c..7cac294 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -1321,9 +1321,8 @@ void PseudoInstruction::SetOpcode(size_t opcode_size, void *opcode_data) { } } -void PseudoInstruction::SetDescription(const char *description) { - if (description && strlen(description) > 0) - m_description = description; +void PseudoInstruction::SetDescription(llvm::StringRef description) { + m_description = description; } Instruction::Operand Instruction::Operand::BuildRegister(ConstString &r) { diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp index 00fbc4b..92c3c84 100644 --- a/lldb/source/Core/UserSettingsController.cpp +++ b/lldb/source/Core/UserSettingsController.cpp @@ -24,7 +24,7 @@ using namespace lldb; using namespace lldb_private; lldb::OptionValueSP -Properties::GetPropertyValue(const ExecutionContext *exe_ctx, const char *path, +Properties::GetPropertyValue(const ExecutionContext *exe_ctx, llvm::StringRef path, bool will_modify, Error &error) const { OptionValuePropertiesSP properties_sp(GetValueProperties()); if (properties_sp) @@ -33,8 +33,8 @@ Properties::GetPropertyValue(const ExecutionContext *exe_ctx, const char *path, } Error Properties::SetPropertyValue(const ExecutionContext *exe_ctx, - VarSetOperationType op, const char *path, - const char *value) { + VarSetOperationType op, llvm::StringRef path, + llvm::StringRef value) { OptionValuePropertiesSP properties_sp(GetValueProperties()); if (properties_sp) return properties_sp->SetSubValue(exe_ctx, op, path, value); @@ -60,7 +60,7 @@ void Properties::DumpAllDescriptions(CommandInterpreter &interpreter, } Error Properties::DumpPropertyValue(const ExecutionContext *exe_ctx, - Stream &strm, const char *property_path, + Stream &strm, llvm::StringRef property_path, uint32_t dump_mask) { OptionValuePropertiesSP properties_sp(GetValueProperties()); if (properties_sp) { @@ -93,16 +93,11 @@ Properties::GetSubProperty(const ExecutionContext *exe_ctx, const char *Properties::GetExperimentalSettingsName() { return "experimental"; } -bool Properties::IsSettingExperimental(const char *setting) { - if (setting == nullptr) +bool Properties::IsSettingExperimental(llvm::StringRef setting) { + if (setting.empty()) return false; - const char *experimental = GetExperimentalSettingsName(); - const char *dot_pos = strchr(setting, '.'); - if (dot_pos == nullptr) - return strcmp(experimental, setting) == 0; - else { - size_t first_elem_len = dot_pos - setting; - return strncmp(experimental, setting, first_elem_len) == 0; - } + llvm::StringRef experimental = GetExperimentalSettingsName(); + size_t dot_pos = setting.find_first_of('.'); + return setting.take_front(dot_pos) == experimental; } diff --git a/lldb/source/Interpreter/OptionValue.cpp b/lldb/source/Interpreter/OptionValue.cpp index 446fb8e..58de32c 100644 --- a/lldb/source/Interpreter/OptionValue.cpp +++ b/lldb/source/Interpreter/OptionValue.cpp @@ -43,8 +43,8 @@ uint64_t OptionValue::GetUInt64Value(uint64_t fail_value, bool *success_ptr) { } Error OptionValue::SetSubValue(const ExecutionContext *exe_ctx, - VarSetOperationType op, const char *name, - const char *value) { + VarSetOperationType op, llvm::StringRef name, + llvm::StringRef value) { Error error; error.SetErrorStringWithFormat("SetSubValue is not supported"); return error; @@ -412,10 +412,10 @@ bool OptionValue::SetSInt64Value(int64_t new_value) { return false; } -const char *OptionValue::GetStringValue(const char *fail_value) const { +llvm::StringRef OptionValue::GetStringValue(llvm::StringRef fail_value) const { const OptionValueString *option_value = GetAsString(); if (option_value) - return option_value->GetCurrentValue(); + return option_value->GetCurrentValueAsRef(); return fail_value; } diff --git a/lldb/source/Interpreter/OptionValueArgs.cpp b/lldb/source/Interpreter/OptionValueArgs.cpp index 2cc93ab..8edec77 100644 --- a/lldb/source/Interpreter/OptionValueArgs.cpp +++ b/lldb/source/Interpreter/OptionValueArgs.cpp @@ -19,17 +19,12 @@ using namespace lldb; using namespace lldb_private; size_t OptionValueArgs::GetArgs(Args &args) { - const uint32_t size = m_values.size(); - std::vector 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); + 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(); } diff --git a/lldb/source/Interpreter/OptionValueArray.cpp b/lldb/source/Interpreter/OptionValueArray.cpp index ae0e01c..9dc4633 100644 --- a/lldb/source/Interpreter/OptionValueArray.cpp +++ b/lldb/source/Interpreter/OptionValueArray.cpp @@ -80,75 +80,72 @@ Error OptionValueArray::SetValueFromString(llvm::StringRef value, } lldb::OptionValueSP -OptionValueArray::GetSubValue(const ExecutionContext *exe_ctx, const char *name, +OptionValueArray::GetSubValue(const ExecutionContext *exe_ctx, llvm::StringRef 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; - } + if (name.empty() || name.front() != '[') { + error.SetErrorStringWithFormat( + "invalid value path '%s', %s values only support '[]' subvalues " + "where 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 { - error.SetErrorStringWithFormat( - "invalid value path '%s', %s values only support '[]' subvalues " - "where is a positive or negative array index", - name, GetTypeAsCString()); + 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); } return OptionValueSP(); } size_t OptionValueArray::GetArgs(Args &args) const { + args.Clear(); const uint32_t size = m_values.size(); - std::vector 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); + llvm::StringRef string_value = m_values[i]->GetStringValue(); + if (!string_value.empty()) + args.AppendArgument(string_value); } - if (argv.empty()) - args.Clear(); - else - args.SetArguments(argv.size(), &argv[0]); return args.GetArgumentCount(); } diff --git a/lldb/source/Interpreter/OptionValueDictionary.cpp b/lldb/source/Interpreter/OptionValueDictionary.cpp index edf5beb..ea18b94 100644 --- a/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -207,112 +207,67 @@ Error OptionValueDictionary::SetValueFromString(llvm::StringRef value, lldb::OptionValueSP OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx, - const char *name, bool will_modify, + llvm::StringRef name, bool will_modify, Error &error) const { lldb::OptionValueSP value_sp; + if (name.empty()) + return nullptr; - if (name && name[0]) { - const char *sub_name = nullptr; - ConstString key; - const char *open_bracket = ::strchr(name, '['); + 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 '[]' subvalues where " + "a string value optionally delimited by " + "single or double quotes", + name.str().c_str(), GetTypeAsCString()); + return nullptr; + } + assert(!temp.empty()); - 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 [''] where 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 [\"\"] where 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; + llvm::StringRef quote_char; - 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 (temp[0] == '\"' || temp[0] == '\'') { + quote_char = temp.take_front(); + temp = temp.drop_front(); + } - if (key_start && key_end) { - key.SetCStringWithLength(key_start, key_end - key_start); + llvm::StringRef sub_name; + std::tie(key, sub_name) = temp.split(']'); - 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 '[]' subvalues where " - "a string value optionally delimited by " - "single or double quotes", - name, GetTypeAsCString()); - } + if (!key.consume_back(quote_char) || key.empty()) { + error.SetErrorStringWithFormat("invalid value path '%s', " + "key names must be formatted as [''] where " + "is a string that doesn't contain quotes and the quote" + " char is optional", name.str().c_str()); + return nullptr; } - return value_sp; + + 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); } Error OptionValueDictionary::SetSubValue(const ExecutionContext *exe_ctx, VarSetOperationType op, - const char *name, const char *value) { + 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( - llvm::StringRef::withNullAsEmpty(value), op); + error = value_sp->SetValueFromString(value, op); else { if (error.AsCString() == nullptr) - error.SetErrorStringWithFormat("invalid value path '%s'", name); + error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str()); } return error; } diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp index f6a96f5..9a621be 100644 --- a/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/lldb/source/Interpreter/OptionValueProperties.cpp @@ -115,102 +115,102 @@ OptionValueProperties::GetValueForKey(const ExecutionContext *exe_ctx, lldb::OptionValueSP OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx, - const char *name, bool will_modify, + llvm::StringRef 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; + 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; + + 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(); } - case '{': - // Predicate matching for predicates like - // "{}" - // 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; - } - } + } + return return_val_sp; + } + case '{': + // Predicate matching for predicates like + // "{}" + // 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; } } + // 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, - const char *name, const char *value) { + 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 ? llvm::StringRef(value) : llvm::StringRef(), op); + error = value_sp->SetValueFromString(value, op); else { if (error.AsCString() == nullptr) - error.SetErrorStringWithFormat("invalid value path '%s'", name); + error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str()); } return error; } @@ -462,9 +462,9 @@ bool OptionValueProperties::SetPropertyAtIndexAsSInt64( return false; } -const char *OptionValueProperties::GetPropertyAtIndexAsString( +llvm::StringRef OptionValueProperties::GetPropertyAtIndexAsString( const ExecutionContext *exe_ctx, uint32_t idx, - const char *fail_value) const { + llvm::StringRef fail_value) const { const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); if (property) { OptionValue *value = property->GetValue().get(); @@ -565,7 +565,7 @@ void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx, Error OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx, Stream &strm, - const char *property_path, + llvm::StringRef property_path, uint32_t dump_mask) { Error error; const bool will_modify = false; @@ -589,32 +589,32 @@ lldb::OptionValueSP OptionValueProperties::DeepCopy() const { } const Property *OptionValueProperties::GetPropertyAtPath( - const ExecutionContext *exe_ctx, bool will_modify, const char *name) const { + const ExecutionContext *exe_ctx, bool will_modify, llvm::StringRef 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; - } + 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; + + 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 property; + return nullptr; } void OptionValueProperties::DumpAllDescriptions(CommandInterpreter &interpreter, diff --git a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp index 2d2705c..5e1dd27 100644 --- a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp +++ b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp @@ -157,7 +157,7 @@ public: nullptr, idx, g_properties[idx].default_uint_value != 0); } - const char *GetAutoEnableOptions() const { + llvm::StringRef GetAutoEnableOptions() const { const uint32_t idx = ePropertyAutoEnableOptions; return m_collection_sp->GetPropertyAtIndexAsString( nullptr, idx, g_properties[idx].default_cstr_value); @@ -1100,7 +1100,7 @@ bool RunEnableCommand(CommandInterpreter &interpreter) { command_stream << "plugin structured-data darwin-log enable"; auto enable_options = GetGlobalProperties()->GetAutoEnableOptions(); - if (enable_options && (strlen(enable_options) > 0)) { + if (!enable_options.empty()) { command_stream << ' '; command_stream << enable_options; } diff --git a/lldb/source/Target/ProcessInfo.cpp b/lldb/source/Target/ProcessInfo.cpp index 4b02332..5c4b2f0 100644 --- a/lldb/source/Target/ProcessInfo.cpp +++ b/lldb/source/Target/ProcessInfo.cpp @@ -78,15 +78,12 @@ void ProcessInfo::SetExecutableFile(const FileSpec &exe_file, } } -const char *ProcessInfo::GetArg0() const { - return (m_arg0.empty() ? nullptr : m_arg0.c_str()); +llvm::StringRef ProcessInfo::GetArg0() const { + return m_arg0; } -void ProcessInfo::SetArg0(const char *arg) { - if (arg && arg[0]) - m_arg0 = arg; - else - m_arg0.clear(); +void ProcessInfo::SetArg0(llvm::StringRef arg) { + m_arg0 = arg; } void ProcessInfo::SetArguments(char const **argv, diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 4344d4c..fb43c40 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -3694,15 +3694,15 @@ InlineStrategy TargetProperties::GetInlineStrategy() const { nullptr, idx, g_properties[idx].default_uint_value); } -const char *TargetProperties::GetArg0() const { +llvm::StringRef TargetProperties::GetArg0() const { const uint32_t idx = ePropertyArg0; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, nullptr); + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, llvm::StringRef()); } -void TargetProperties::SetArg0(const char *arg) { +void TargetProperties::SetArg0(llvm::StringRef arg) { const uint32_t idx = ePropertyArg0; m_collection_sp->SetPropertyAtIndexAsString( - nullptr, idx, llvm::StringRef::withNullAsEmpty(arg)); + nullptr, idx, arg); m_launch_info.SetArg0(arg); } -- 2.7.4