diff --git a/lldb/bindings/interface/SBDebugger.i b/lldb/bindings/interface/SBDebugger.i --- a/lldb/bindings/interface/SBDebugger.i +++ b/lldb/bindings/interface/SBDebugger.i @@ -225,6 +225,8 @@ } } + lldb::SBStructuredData GetSetting(const char *setting = nullptr); + SBError SetInputString (const char* data); diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -115,6 +115,21 @@ void Clear(); + /// Getting a specific setting value into SBStructuredData format. + /// Client can specify empty string or null to get all settings. + /// + /// Example usages: + /// lldb::SBStructuredData settings = debugger.GetSetting(); + /// lldb::SBStructuredData settings = debugger.GetSetting(nullptr); + /// lldb::SBStructuredData settings = debugger.GetSetting(""); + /// lldb::SBStructuredData settings = debugger.GetSetting("target.arg0"); + /// lldb::SBStructuredData settings = debugger.GetSetting("target"); + /// + /// \param[out] setting + /// Property setting path to retrieve values. e.g "target.source-map" + /// + lldb::SBStructuredData GetSetting(const char *setting = nullptr); + void SetAsync(bool b); bool GetAsync(); diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h --- a/lldb/include/lldb/Core/UserSettingsController.h +++ b/lldb/include/lldb/Core/UserSettingsController.h @@ -57,10 +57,11 @@ virtual Status DumpPropertyValue(const ExecutionContext *exe_ctx, Stream &strm, llvm::StringRef property_path, - uint32_t dump_mask); + uint32_t dump_mask, bool is_json = false); virtual void DumpAllPropertyValues(const ExecutionContext *exe_ctx, - Stream &strm, uint32_t dump_mask); + Stream &strm, uint32_t dump_mask, + bool is_json = false); virtual void DumpAllDescriptions(CommandInterpreter &interpreter, Stream &strm) const; diff --git a/lldb/include/lldb/Interpreter/OptionValue.h b/lldb/include/lldb/Interpreter/OptionValue.h --- a/lldb/include/lldb/Interpreter/OptionValue.h +++ b/lldb/include/lldb/Interpreter/OptionValue.h @@ -17,6 +17,7 @@ #include "lldb/lldb-defines.h" #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-private-interfaces.h" +#include "llvm/Support/JSON.h" namespace lldb_private { @@ -82,6 +83,16 @@ virtual void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) = 0; + // TODO: make this function pure virtual after implementing it in all + // child classes. + virtual llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) { + // Return nullptr which will create a llvm::json::Value() that is a NULL + // value. No setting should ever really have a NULL value in JSON. This + // indicates an error occurred and if/when we add a FromJSON() it will know + // to fail if someone tries to set it with a NULL JSON value. + return nullptr; + } + virtual Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign); diff --git a/lldb/include/lldb/Interpreter/OptionValueArray.h b/lldb/include/lldb/Interpreter/OptionValueArray.h --- a/lldb/include/lldb/Interpreter/OptionValueArray.h +++ b/lldb/include/lldb/Interpreter/OptionValueArray.h @@ -29,6 +29,8 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override; + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/lldb/include/lldb/Interpreter/OptionValueBoolean.h --- a/lldb/include/lldb/Interpreter/OptionValueBoolean.h +++ b/lldb/include/lldb/Interpreter/OptionValueBoolean.h @@ -29,6 +29,10 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override { + return m_current_value; + } + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueChar.h b/lldb/include/lldb/Interpreter/OptionValueChar.h --- a/lldb/include/lldb/Interpreter/OptionValueChar.h +++ b/lldb/include/lldb/Interpreter/OptionValueChar.h @@ -30,6 +30,10 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override { + return m_current_value; + } + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/lldb/include/lldb/Interpreter/OptionValueDictionary.h --- a/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -34,6 +34,8 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override; + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h --- a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h @@ -35,6 +35,10 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override { + return m_current_value.GetPath(); + } + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueFormat.h b/lldb/include/lldb/Interpreter/OptionValueFormat.h --- a/lldb/include/lldb/Interpreter/OptionValueFormat.h +++ b/lldb/include/lldb/Interpreter/OptionValueFormat.h @@ -31,6 +31,8 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override; + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h --- a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -28,6 +28,8 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override; + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/lldb/include/lldb/Interpreter/OptionValueLanguage.h --- a/lldb/include/lldb/Interpreter/OptionValueLanguage.h +++ b/lldb/include/lldb/Interpreter/OptionValueLanguage.h @@ -33,6 +33,8 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override; + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h --- a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h +++ b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h @@ -29,6 +29,8 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override; + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueProperties.h b/lldb/include/lldb/Interpreter/OptionValueProperties.h --- a/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -47,11 +47,13 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override; + ConstString GetName() const override { return m_name; } virtual Status DumpPropertyValue(const ExecutionContext *exe_ctx, Stream &strm, llvm::StringRef property_path, - uint32_t dump_mask); + uint32_t dump_mask, bool is_json = false); virtual void DumpAllDescriptions(CommandInterpreter &interpreter, Stream &strm) const; diff --git a/lldb/include/lldb/Interpreter/OptionValueRegex.h b/lldb/include/lldb/Interpreter/OptionValueRegex.h --- a/lldb/include/lldb/Interpreter/OptionValueRegex.h +++ b/lldb/include/lldb/Interpreter/OptionValueRegex.h @@ -28,6 +28,10 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override { + return m_regex.GetText(); + } + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/lldb/include/lldb/Interpreter/OptionValueSInt64.h --- a/lldb/include/lldb/Interpreter/OptionValueSInt64.h +++ b/lldb/include/lldb/Interpreter/OptionValueSInt64.h @@ -35,6 +35,10 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override { + return m_current_value; + } + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueString.h b/lldb/include/lldb/Interpreter/OptionValueString.h --- a/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/lldb/include/lldb/Interpreter/OptionValueString.h @@ -69,6 +69,10 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override { + return m_current_value; + } + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; @@ -109,7 +113,7 @@ bool IsCurrentValueEmpty() const { return m_current_value.empty(); } bool IsDefaultValueEmpty() const { return m_default_value.empty(); } - + void SetValidator(ValidatorCallback validator, void *baton = nullptr) { m_validator = validator; m_validator_baton = baton; diff --git a/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/lldb/include/lldb/Interpreter/OptionValueUInt64.h --- a/lldb/include/lldb/Interpreter/OptionValueUInt64.h +++ b/lldb/include/lldb/Interpreter/OptionValueUInt64.h @@ -38,6 +38,10 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override { + return m_current_value; + } + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Interpreter/OptionValueUUID.h b/lldb/include/lldb/Interpreter/OptionValueUUID.h --- a/lldb/include/lldb/Interpreter/OptionValueUUID.h +++ b/lldb/include/lldb/Interpreter/OptionValueUUID.h @@ -29,6 +29,10 @@ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override; + llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) override { + return m_uuid.GetAsString(); + } + Status SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; diff --git a/lldb/include/lldb/Target/PathMappingList.h b/lldb/include/lldb/Target/PathMappingList.h --- a/lldb/include/lldb/Target/PathMappingList.h +++ b/lldb/include/lldb/Target/PathMappingList.h @@ -9,10 +9,11 @@ #ifndef LLDB_TARGET_PATHMAPPINGLIST_H #define LLDB_TARGET_PATHMAPPINGLIST_H -#include -#include #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" +#include "llvm/Support/JSON.h" +#include +#include namespace lldb_private { @@ -41,6 +42,8 @@ // By default, dump all pairs. void Dump(Stream *s, int pair_index = -1); + llvm::json::Value ToJSON(); + bool IsEmpty() const { return m_pairs.empty(); } size_t GetSize() const { return m_pairs.size(); } diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -436,6 +436,29 @@ return error; } +lldb::SBStructuredData SBDebugger::GetSetting(const char *setting) { + LLDB_INSTRUMENT_VA(this, setting); + + SBStructuredData data; + if (!m_opaque_sp) + return data; + + StreamString json_strm; + ExecutionContext exe_ctx( + m_opaque_sp->GetCommandInterpreter().GetExecutionContext()); + if (setting && strlen(setting) > 0) + m_opaque_sp->DumpPropertyValue(&exe_ctx, json_strm, setting, + /*dump_mask*/ 0, + /*is_json*/ true); + else + m_opaque_sp->DumpAllPropertyValues(&exe_ctx, json_strm, /*dump_mask*/ 0, + /*is_json*/ true); + + data.m_impl_up->SetObjectSP( + StructuredData::ParseJSON(json_strm.GetString().str())); + return data; +} + FILE *SBDebugger::GetInputFileHandle() { LLDB_INSTRUMENT_VA(this); if (m_opaque_sp) { diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp --- a/lldb/source/Core/UserSettingsController.cpp +++ b/lldb/source/Core/UserSettingsController.cpp @@ -53,10 +53,17 @@ } void Properties::DumpAllPropertyValues(const ExecutionContext *exe_ctx, - Stream &strm, uint32_t dump_mask) { + Stream &strm, uint32_t dump_mask, + bool is_json) { OptionValuePropertiesSP properties_sp(GetValueProperties()); - if (properties_sp) - return properties_sp->DumpValue(exe_ctx, strm, dump_mask); + if (!properties_sp) + return; + + if (is_json) { + llvm::json::Value json = properties_sp->ToJSON(exe_ctx); + strm.Printf("%s", llvm::formatv("{0:2}", json).str().c_str()); + } else + properties_sp->DumpValue(exe_ctx, strm, dump_mask); } void Properties::DumpAllDescriptions(CommandInterpreter &interpreter, @@ -71,11 +78,11 @@ Status Properties::DumpPropertyValue(const ExecutionContext *exe_ctx, Stream &strm, llvm::StringRef property_path, - uint32_t dump_mask) { + uint32_t dump_mask, bool is_json) { OptionValuePropertiesSP properties_sp(GetValueProperties()); if (properties_sp) { return properties_sp->DumpPropertyValue(exe_ctx, strm, property_path, - dump_mask); + dump_mask, is_json); } Status error; error.SetErrorString("empty property list"); diff --git a/lldb/source/Interpreter/OptionValueArray.cpp b/lldb/source/Interpreter/OptionValueArray.cpp --- a/lldb/source/Interpreter/OptionValueArray.cpp +++ b/lldb/source/Interpreter/OptionValueArray.cpp @@ -75,6 +75,14 @@ } } +llvm::json::Value OptionValueArray::ToJSON(const ExecutionContext *exe_ctx) { + llvm::json::Array json_array; + const uint32_t size = m_values.size(); + for (uint32_t i = 0; i < size; ++i) + json_array.emplace_back(m_values[i]->ToJSON(exe_ctx)); + return json_array; +} + Status OptionValueArray::SetValueFromString(llvm::StringRef value, VarSetOperationType op) { Args args(value.str()); diff --git a/lldb/source/Interpreter/OptionValueDictionary.cpp b/lldb/source/Interpreter/OptionValueDictionary.cpp --- a/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -83,6 +83,15 @@ } } +llvm::json::Value +OptionValueDictionary::ToJSON(const ExecutionContext *exe_ctx) { + llvm::json::Object dict; + for (const auto &value : m_values) { + dict.try_emplace(value.first.GetCString(), value.second->ToJSON(exe_ctx)); + } + return dict; +} + size_t OptionValueDictionary::GetArgs(Args &args) const { args.Clear(); collection::const_iterator pos, end = m_values.end(); diff --git a/lldb/source/Interpreter/OptionValueFormat.cpp b/lldb/source/Interpreter/OptionValueFormat.cpp --- a/lldb/source/Interpreter/OptionValueFormat.cpp +++ b/lldb/source/Interpreter/OptionValueFormat.cpp @@ -26,6 +26,10 @@ } } +llvm::json::Value OptionValueFormat::ToJSON(const ExecutionContext *exe_ctx) { + return FormatManager::GetFormatAsCString(m_current_value); +} + Status OptionValueFormat::SetValueFromString(llvm::StringRef value, VarSetOperationType op) { Status error; diff --git a/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/lldb/source/Interpreter/OptionValueFormatEntity.cpp --- a/lldb/source/Interpreter/OptionValueFormatEntity.cpp +++ b/lldb/source/Interpreter/OptionValueFormatEntity.cpp @@ -60,6 +60,13 @@ } } +llvm::json::Value +OptionValueFormatEntity::ToJSON(const ExecutionContext *exe_ctx) { + std::string escaped; + EscapeBackticks(m_current_format, escaped); + return escaped; +} + Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str, VarSetOperationType op) { Status error; diff --git a/lldb/source/Interpreter/OptionValueLanguage.cpp b/lldb/source/Interpreter/OptionValueLanguage.cpp --- a/lldb/source/Interpreter/OptionValueLanguage.cpp +++ b/lldb/source/Interpreter/OptionValueLanguage.cpp @@ -29,6 +29,10 @@ } } +llvm::json::Value OptionValueLanguage::ToJSON(const ExecutionContext *exe_ctx) { + return Language::GetNameForLanguageType(m_current_value); +} + Status OptionValueLanguage::SetValueFromString(llvm::StringRef value, VarSetOperationType op) { Status error; diff --git a/lldb/source/Interpreter/OptionValuePathMappings.cpp b/lldb/source/Interpreter/OptionValuePathMappings.cpp --- a/lldb/source/Interpreter/OptionValuePathMappings.cpp +++ b/lldb/source/Interpreter/OptionValuePathMappings.cpp @@ -34,6 +34,11 @@ } } +llvm::json::Value +OptionValuePathMappings::ToJSON(const ExecutionContext *exe_ctx) { + return m_path_mappings.ToJSON(); +} + Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, VarSetOperationType op) { Status error; diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp --- a/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/lldb/source/Interpreter/OptionValueProperties.cpp @@ -545,10 +545,26 @@ } } +llvm::json::Value +OptionValueProperties::ToJSON(const ExecutionContext *exe_ctx) { + llvm::json::Object json_properties; + 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); + json_properties.try_emplace(property->GetName(), + option_value->ToJSON(exe_ctx)); + } + } + return json_properties; +} + Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx, Stream &strm, llvm::StringRef property_path, - uint32_t dump_mask) { + uint32_t dump_mask, bool is_json) { Status error; const bool will_modify = false; lldb::OptionValueSP value_sp( @@ -560,7 +576,10 @@ if (dump_mask & ~eDumpOptionName) strm.PutChar(' '); } - value_sp->DumpValue(exe_ctx, strm, dump_mask); + if (is_json) { + strm.Printf("%s", llvm::formatv("{0:2}", value_sp->ToJSON(exe_ctx)).str().c_str()); + } else + value_sp->DumpValue(exe_ctx, strm, dump_mask); } return error; } diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -131,6 +131,16 @@ } } +llvm::json::Value PathMappingList::ToJSON() { + llvm::json::Array entries; + for (const auto &pair : m_pairs) { + llvm::json::Array entry{pair.first.GetStringRef().str(), + pair.second.GetStringRef().str()}; + entries.emplace_back(std::move(entry)); + } + return entries; +} + void PathMappingList::Clear(bool notify) { if (!m_pairs.empty()) ++m_mod_id; diff --git a/lldb/test/API/commands/settings/TestSettings.py b/lldb/test/API/commands/settings/TestSettings.py --- a/lldb/test/API/commands/settings/TestSettings.py +++ b/lldb/test/API/commands/settings/TestSettings.py @@ -3,7 +3,7 @@ """ - +import json import os import re import lldb @@ -274,7 +274,7 @@ self.assertEqual(launch_info.GetArgumentAtIndex(0), "A") self.assertEqual(launch_info.GetArgumentAtIndex(1), "B") self.assertEqual(launch_info.GetArgumentAtIndex(2), "C") - + self.expect( 'target show-launch-environment', substrs=["MY_ENV_VAR=YES"]) @@ -787,3 +787,59 @@ # A known option should fail if its argument is invalid. self.expect("settings set auto-confirm bogus", error=True) + + def get_setting_json(self, setting_path = None): + settings_data = self.dbg.GetSetting(setting_path) + stream = lldb.SBStream() + settings_data.GetAsJSON(stream) + return json.loads(stream.GetData()) + + def verify_setting_value_json(self, setting_path, setting_value): + self.runCmd("settings set %s %s" % (setting_path, setting_value)) + settings_json = self.get_setting_json(setting_path) + self.assertEqual(settings_json, setting_value) + + def test_settings_api(self): + """ + Test that ensures SBDebugger::GetSetting() APIs + can correctly fetch settings. + """ + + # Test basic values and embedding special JSON escaping characters. + self.runCmd("settings set auto-confirm true") + self.runCmd("settings set tab-size 2") + arg_value = "hello \"world\"" + self.runCmd('settings set target.arg0 %s' % arg_value) + + settings_json = self.get_setting_json() + self.assertEqual(settings_json["auto-confirm"], True) + self.assertEqual(settings_json["tab-size"], 2) + self.assertEqual(settings_json["target"]["arg0"], arg_value) + + settings_data = self.get_setting_json("target.arg0") + self.assertEqual(settings_data, arg_value) + + # Test OptionValueFileSpec + self.verify_setting_value_json("platform.module-cache-directory", self.get_process_working_directory()) + + # Test OptionValueArray + setting_path = "target.run-args" + setting_value = ["value1", "value2", "value3"] + self.runCmd("settings set %s %s" % (setting_path, " ".join(setting_value))) + settings_json = self.get_setting_json(setting_path) + self.assertEqual(settings_json, setting_value) + + # Test OptionValueFormatEntity + setting_value = """thread #${thread.index}{, name = \\'${thread.name}\\ + '}{, queue = ${ansi.fg.green}\\'${thread.queue}\\'${ansi.normal}}{, + activity = ${ansi.fg.green}\\'${thread.info.activity.name}\\'${ansi.normal}} + {, ${thread.info.trace_messages} messages}{, stop reason = ${ansi.fg.red}$ + {thread.stop-reason}${ansi.normal}}{\\\\nReturn value: ${thread.return-value}} + {\\\\nCompleted expression: ${thread.completed-expression}}\\\\n""" + self.verify_setting_value_json("thread-stop-format", setting_value) + + # Test OptionValueRegex + self.verify_setting_value_json("target.process.thread.step-avoid-regexp", "^std::") + + # Test OptionValueLanguage + self.verify_setting_value_json("repl-lang", "c++") diff --git a/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py b/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py --- a/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py +++ b/lldb/test/API/functionalities/source-map/TestTargetSourceMap.py @@ -1,11 +1,45 @@ import lldb from lldbsuite.test.lldbtest import * from lldbsuite.test.decorators import * +import json import os class TestTargetSourceMap(TestBase): + @no_debug_info_test + def test_source_map_via_setting_api(self): + """ + Test that ensures SBDebugger::GetSetting("target.source-map") API + can correctly fetch source mapping entries. + """ + # Set the target soure map to map "./" to the current test directory + src_dir = self.getSourceDir() + + source_map_setting_path = "target.source-map" + initial_source_map = self.dbg.GetSetting(source_map_setting_path) + self.assertEquals(initial_source_map.GetSize(), 0, + "Initial source map should be empty") + + src_dir = self.getSourceDir() + self.runCmd('settings set %s . "%s"' % (source_map_setting_path, src_dir)) + + source_map = self.dbg.GetSetting(source_map_setting_path) + self.assertEquals(source_map.GetSize(), 1, + "source map should be have one appended entry") + + stream = lldb.SBStream() + source_map.GetAsJSON(stream) + serialized_source_map = json.loads(stream.GetData()) + + self.assertEquals(len(serialized_source_map[0]), 2, + "source map entry should have two parts") + self.assertEquals(serialized_source_map[0][0], ".", + "source map entry's first part does not match") + self.assertEquals(serialized_source_map[0][1], src_dir, + "source map entry's second part does not match") + + @no_debug_info_test def test_source_map(self): """Test target.source-map' functionality."""