1254721Semaste//===-- Property.cpp --------------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "lldb/Interpreter/Property.h" 10254721Semaste 11254721Semaste#include "lldb/Core/UserSettingsController.h" 12288943Sdim#include "lldb/Host/StringConvert.h" 13254721Semaste#include "lldb/Interpreter/CommandInterpreter.h" 14341825Sdim#include "lldb/Interpreter/OptionArgParser.h" 15254721Semaste#include "lldb/Interpreter/OptionValues.h" 16296417Sdim#include "lldb/Target/Language.h" 17254721Semaste 18353358Sdim#include <memory> 19353358Sdim 20254721Semasteusing namespace lldb; 21254721Semasteusing namespace lldb_private; 22254721Semaste 23314564SdimProperty::Property(const PropertyDefinition &definition) 24314564Sdim : m_name(definition.name), m_description(definition.description), 25314564Sdim m_value_sp(), m_is_global(definition.global) { 26314564Sdim switch (definition.type) { 27314564Sdim case OptionValue::eTypeInvalid: 28314564Sdim case OptionValue::eTypeProperties: 29314564Sdim break; 30314564Sdim case OptionValue::eTypeArch: 31314564Sdim // "definition.default_uint_value" is not used 32314564Sdim // "definition.default_cstr_value" as a string value that represents the 33314564Sdim // default string value for the architecture/triple 34353358Sdim m_value_sp = 35353358Sdim std::make_shared<OptionValueArch>(definition.default_cstr_value); 36314564Sdim break; 37280031Sdim 38314564Sdim case OptionValue::eTypeArgs: 39314564Sdim // "definition.default_uint_value" is always a OptionValue::Type 40353358Sdim m_value_sp = std::make_shared<OptionValueArgs>(); 41314564Sdim break; 42280031Sdim 43314564Sdim case OptionValue::eTypeArray: 44314564Sdim // "definition.default_uint_value" is always a OptionValue::Type 45353358Sdim m_value_sp = 46353358Sdim std::make_shared<OptionValueArray>(OptionValue::ConvertTypeToMask( 47353358Sdim (OptionValue::Type)definition.default_uint_value)); 48314564Sdim break; 49314564Sdim 50314564Sdim case OptionValue::eTypeBoolean: 51314564Sdim // "definition.default_uint_value" is the default boolean value if 52314564Sdim // "definition.default_cstr_value" is NULL, otherwise interpret 53314564Sdim // "definition.default_cstr_value" as a string value that represents the 54314564Sdim // default value. 55314564Sdim if (definition.default_cstr_value) 56353358Sdim m_value_sp = 57353358Sdim std::make_shared<OptionValueBoolean>(OptionArgParser::ToBoolean( 58353358Sdim llvm::StringRef(definition.default_cstr_value), false, nullptr)); 59314564Sdim else 60353358Sdim m_value_sp = std::make_shared<OptionValueBoolean>( 61353358Sdim definition.default_uint_value != 0); 62314564Sdim break; 63314564Sdim 64314564Sdim case OptionValue::eTypeChar: { 65314564Sdim llvm::StringRef s(definition.default_cstr_value ? definition.default_cstr_value : ""); 66341825Sdim m_value_sp = std::make_shared<OptionValueChar>( 67341825Sdim OptionArgParser::ToChar(s, '\0', nullptr)); 68314564Sdim break; 69314564Sdim } 70314564Sdim case OptionValue::eTypeDictionary: 71314564Sdim // "definition.default_uint_value" is always a OptionValue::Type 72353358Sdim m_value_sp = 73353358Sdim std::make_shared<OptionValueDictionary>(OptionValue::ConvertTypeToMask( 74353358Sdim (OptionValue::Type)definition.default_uint_value)); 75314564Sdim break; 76314564Sdim 77314564Sdim case OptionValue::eTypeEnum: 78314564Sdim // "definition.default_uint_value" is the default enumeration value if 79314564Sdim // "definition.default_cstr_value" is NULL, otherwise interpret 80314564Sdim // "definition.default_cstr_value" as a string value that represents the 81341825Sdim // default value. 82314564Sdim { 83314564Sdim OptionValueEnumeration *enum_value = new OptionValueEnumeration( 84314564Sdim definition.enum_values, definition.default_uint_value); 85314564Sdim m_value_sp.reset(enum_value); 86314564Sdim if (definition.default_cstr_value) { 87314564Sdim if (enum_value 88314564Sdim ->SetValueFromString( 89314564Sdim llvm::StringRef(definition.default_cstr_value)) 90314564Sdim .Success()) { 91314564Sdim enum_value->SetDefaultValue(enum_value->GetCurrentValue()); 92341825Sdim // Call Clear() since we don't want the value to appear as having 93341825Sdim // been set since we called SetValueFromString() above. Clear will 94341825Sdim // set the current value to the default and clear the boolean that 95341825Sdim // says that the value has been set. 96314564Sdim enum_value->Clear(); 97254721Semaste } 98314564Sdim } 99254721Semaste } 100314564Sdim break; 101254721Semaste 102314564Sdim case OptionValue::eTypeFileSpec: { 103314564Sdim // "definition.default_uint_value" represents if the 104341825Sdim // "definition.default_cstr_value" should be resolved or not 105314564Sdim const bool resolve = definition.default_uint_value != 0; 106344779Sdim FileSpec file_spec = FileSpec(definition.default_cstr_value); 107344779Sdim if (resolve) 108344779Sdim FileSystem::Instance().Resolve(file_spec); 109353358Sdim m_value_sp = std::make_shared<OptionValueFileSpec>(file_spec, resolve); 110314564Sdim break; 111314564Sdim } 112254721Semaste 113314564Sdim case OptionValue::eTypeFileSpecList: 114314564Sdim // "definition.default_uint_value" is not used for a 115314564Sdim // OptionValue::eTypeFileSpecList 116353358Sdim m_value_sp = std::make_shared<OptionValueFileSpecList>(); 117314564Sdim break; 118314564Sdim 119314564Sdim case OptionValue::eTypeFormat: 120314564Sdim // "definition.default_uint_value" is the default format enumeration value 121341825Sdim // if "definition.default_cstr_value" is NULL, otherwise interpret 122314564Sdim // "definition.default_cstr_value" as a string value that represents the 123341825Sdim // default value. 124254721Semaste { 125314564Sdim Format new_format = eFormatInvalid; 126314564Sdim if (definition.default_cstr_value) 127341825Sdim OptionArgParser::ToFormat(definition.default_cstr_value, new_format, 128341825Sdim nullptr); 129314564Sdim else 130314564Sdim new_format = (Format)definition.default_uint_value; 131353358Sdim m_value_sp = std::make_shared<OptionValueFormat>(new_format); 132254721Semaste } 133314564Sdim break; 134254721Semaste 135314564Sdim case OptionValue::eTypeLanguage: 136341825Sdim // "definition.default_uint_value" is the default language enumeration 137341825Sdim // value if "definition.default_cstr_value" is NULL, otherwise interpret 138314564Sdim // "definition.default_cstr_value" as a string value that represents the 139341825Sdim // default value. 140314564Sdim { 141314564Sdim LanguageType new_lang = eLanguageTypeUnknown; 142314564Sdim if (definition.default_cstr_value) 143314564Sdim Language::GetLanguageTypeFromString( 144314564Sdim llvm::StringRef(definition.default_cstr_value)); 145314564Sdim else 146314564Sdim new_lang = (LanguageType)definition.default_uint_value; 147353358Sdim m_value_sp = std::make_shared<OptionValueLanguage>(new_lang); 148314564Sdim } 149314564Sdim break; 150254721Semaste 151314564Sdim case OptionValue::eTypeFormatEntity: 152314564Sdim // "definition.default_cstr_value" as a string value that represents the 153314564Sdim // default 154353358Sdim m_value_sp = std::make_shared<OptionValueFormatEntity>( 155353358Sdim definition.default_cstr_value); 156314564Sdim break; 157314564Sdim 158314564Sdim case OptionValue::eTypePathMap: 159314564Sdim // "definition.default_uint_value" tells us if notifications should occur 160341825Sdim // for path mappings 161353358Sdim m_value_sp = std::make_shared<OptionValuePathMappings>( 162353358Sdim definition.default_uint_value != 0); 163314564Sdim break; 164314564Sdim 165314564Sdim case OptionValue::eTypeRegex: 166314564Sdim // "definition.default_uint_value" is used to the regular expression flags 167314564Sdim // "definition.default_cstr_value" the default regular expression value 168314564Sdim // value. 169353358Sdim m_value_sp = 170353358Sdim std::make_shared<OptionValueRegex>(definition.default_cstr_value); 171314564Sdim break; 172314564Sdim 173314564Sdim case OptionValue::eTypeSInt64: 174314564Sdim // "definition.default_uint_value" is the default integer value if 175314564Sdim // "definition.default_cstr_value" is NULL, otherwise interpret 176314564Sdim // "definition.default_cstr_value" as a string value that represents the 177341825Sdim // default value. 178353358Sdim m_value_sp = std::make_shared<OptionValueSInt64>( 179314564Sdim definition.default_cstr_value 180314564Sdim ? StringConvert::ToSInt64(definition.default_cstr_value) 181353358Sdim : definition.default_uint_value); 182314564Sdim break; 183314564Sdim 184314564Sdim case OptionValue::eTypeUInt64: 185314564Sdim // "definition.default_uint_value" is the default unsigned integer value if 186314564Sdim // "definition.default_cstr_value" is NULL, otherwise interpret 187314564Sdim // "definition.default_cstr_value" as a string value that represents the 188341825Sdim // default value. 189353358Sdim m_value_sp = std::make_shared<OptionValueUInt64>( 190314564Sdim definition.default_cstr_value 191314564Sdim ? StringConvert::ToUInt64(definition.default_cstr_value) 192353358Sdim : definition.default_uint_value); 193314564Sdim break; 194314564Sdim 195314564Sdim case OptionValue::eTypeUUID: 196314564Sdim // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID 197314564Sdim // "definition.default_cstr_value" can contain a default UUID value 198254721Semaste { 199314564Sdim UUID uuid; 200314564Sdim if (definition.default_cstr_value) 201341825Sdim uuid.SetFromStringRef(definition.default_cstr_value); 202353358Sdim m_value_sp = std::make_shared<OptionValueUUID>(uuid); 203254721Semaste } 204314564Sdim break; 205314564Sdim 206314564Sdim case OptionValue::eTypeString: 207341825Sdim // "definition.default_uint_value" can contain the string option flags 208341825Sdim // OR'ed together "definition.default_cstr_value" can contain a default 209341825Sdim // string value 210314564Sdim { 211314564Sdim OptionValueString *string_value = 212314564Sdim new OptionValueString(definition.default_cstr_value); 213314564Sdim if (definition.default_uint_value != 0) 214314564Sdim string_value->GetOptions().Reset(definition.default_uint_value); 215314564Sdim m_value_sp.reset(string_value); 216314564Sdim } 217314564Sdim break; 218314564Sdim } 219254721Semaste} 220254721Semaste 221353358SdimProperty::Property(ConstString name, ConstString desc, 222314564Sdim bool is_global, const lldb::OptionValueSP &value_sp) 223314564Sdim : m_name(name), m_description(desc), m_value_sp(value_sp), 224314564Sdim m_is_global(is_global) {} 225254721Semaste 226314564Sdimbool Property::DumpQualifiedName(Stream &strm) const { 227314564Sdim if (m_name) { 228314564Sdim if (m_value_sp->DumpQualifiedName(strm)) 229314564Sdim strm.PutChar('.'); 230314564Sdim strm << m_name; 231314564Sdim return true; 232314564Sdim } 233314564Sdim return false; 234314564Sdim} 235254721Semaste 236314564Sdimvoid Property::Dump(const ExecutionContext *exe_ctx, Stream &strm, 237314564Sdim uint32_t dump_mask) const { 238314564Sdim if (m_value_sp) { 239314564Sdim const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription; 240344779Sdim const bool dump_cmd = dump_mask & OptionValue::eDumpOptionCommand; 241314564Sdim const bool transparent = m_value_sp->ValueIsTransparent(); 242344779Sdim if (dump_cmd && !transparent) 243344779Sdim strm << "settings set -f "; 244314564Sdim if (dump_desc || !transparent) { 245314564Sdim if ((dump_mask & OptionValue::eDumpOptionName) && m_name) { 246314564Sdim DumpQualifiedName(strm); 247314564Sdim if (dump_mask & ~OptionValue::eDumpOptionName) 248314564Sdim strm.PutChar(' '); 249314564Sdim } 250254721Semaste } 251314564Sdim if (dump_desc) { 252314564Sdim llvm::StringRef desc = GetDescription(); 253314564Sdim if (!desc.empty()) 254314564Sdim strm << "-- " << desc; 255314564Sdim 256314564Sdim if (transparent && (dump_mask == (OptionValue::eDumpOptionName | 257314564Sdim OptionValue::eDumpOptionDescription))) 258314564Sdim strm.EOL(); 259314564Sdim } 260314564Sdim m_value_sp->DumpValue(exe_ctx, strm, dump_mask); 261314564Sdim } 262254721Semaste} 263254721Semaste 264314564Sdimvoid Property::DumpDescription(CommandInterpreter &interpreter, Stream &strm, 265314564Sdim uint32_t output_width, 266314564Sdim bool display_qualified_name) const { 267314564Sdim if (!m_value_sp) 268314564Sdim return; 269314564Sdim llvm::StringRef desc = GetDescription(); 270280031Sdim 271314564Sdim if (desc.empty()) 272314564Sdim return; 273314564Sdim 274314564Sdim StreamString qualified_name; 275314564Sdim const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties(); 276314564Sdim if (sub_properties) { 277314564Sdim strm.EOL(); 278314564Sdim 279314564Sdim if (m_value_sp->DumpQualifiedName(qualified_name)) 280314564Sdim strm.Printf("'%s' variables:\n\n", qualified_name.GetData()); 281314564Sdim sub_properties->DumpAllDescriptions(interpreter, strm); 282314564Sdim } else { 283314564Sdim if (display_qualified_name) { 284314564Sdim StreamString qualified_name; 285314564Sdim DumpQualifiedName(qualified_name); 286314564Sdim interpreter.OutputFormattedHelpText(strm, qualified_name.GetString(), 287314564Sdim "--", desc, output_width); 288314564Sdim } else { 289314564Sdim interpreter.OutputFormattedHelpText(strm, m_name.GetStringRef(), "--", 290314564Sdim desc, output_width); 291314564Sdim } 292314564Sdim } 293280031Sdim} 294280031Sdim 295360784Sdimvoid Property::SetValueChangedCallback(std::function<void()> callback) { 296314564Sdim if (m_value_sp) 297360784Sdim m_value_sp->SetValueChangedCallback(std::move(callback)); 298314564Sdim} 299