Property.cpp revision 360784
1//===-- Property.cpp --------------------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "lldb/Interpreter/Property.h" 10 11#include "lldb/Core/UserSettingsController.h" 12#include "lldb/Host/StringConvert.h" 13#include "lldb/Interpreter/CommandInterpreter.h" 14#include "lldb/Interpreter/OptionArgParser.h" 15#include "lldb/Interpreter/OptionValues.h" 16#include "lldb/Target/Language.h" 17 18#include <memory> 19 20using namespace lldb; 21using namespace lldb_private; 22 23Property::Property(const PropertyDefinition &definition) 24 : m_name(definition.name), m_description(definition.description), 25 m_value_sp(), m_is_global(definition.global) { 26 switch (definition.type) { 27 case OptionValue::eTypeInvalid: 28 case OptionValue::eTypeProperties: 29 break; 30 case OptionValue::eTypeArch: 31 // "definition.default_uint_value" is not used 32 // "definition.default_cstr_value" as a string value that represents the 33 // default string value for the architecture/triple 34 m_value_sp = 35 std::make_shared<OptionValueArch>(definition.default_cstr_value); 36 break; 37 38 case OptionValue::eTypeArgs: 39 // "definition.default_uint_value" is always a OptionValue::Type 40 m_value_sp = std::make_shared<OptionValueArgs>(); 41 break; 42 43 case OptionValue::eTypeArray: 44 // "definition.default_uint_value" is always a OptionValue::Type 45 m_value_sp = 46 std::make_shared<OptionValueArray>(OptionValue::ConvertTypeToMask( 47 (OptionValue::Type)definition.default_uint_value)); 48 break; 49 50 case OptionValue::eTypeBoolean: 51 // "definition.default_uint_value" is the default boolean value if 52 // "definition.default_cstr_value" is NULL, otherwise interpret 53 // "definition.default_cstr_value" as a string value that represents the 54 // default value. 55 if (definition.default_cstr_value) 56 m_value_sp = 57 std::make_shared<OptionValueBoolean>(OptionArgParser::ToBoolean( 58 llvm::StringRef(definition.default_cstr_value), false, nullptr)); 59 else 60 m_value_sp = std::make_shared<OptionValueBoolean>( 61 definition.default_uint_value != 0); 62 break; 63 64 case OptionValue::eTypeChar: { 65 llvm::StringRef s(definition.default_cstr_value ? definition.default_cstr_value : ""); 66 m_value_sp = std::make_shared<OptionValueChar>( 67 OptionArgParser::ToChar(s, '\0', nullptr)); 68 break; 69 } 70 case OptionValue::eTypeDictionary: 71 // "definition.default_uint_value" is always a OptionValue::Type 72 m_value_sp = 73 std::make_shared<OptionValueDictionary>(OptionValue::ConvertTypeToMask( 74 (OptionValue::Type)definition.default_uint_value)); 75 break; 76 77 case OptionValue::eTypeEnum: 78 // "definition.default_uint_value" is the default enumeration value if 79 // "definition.default_cstr_value" is NULL, otherwise interpret 80 // "definition.default_cstr_value" as a string value that represents the 81 // default value. 82 { 83 OptionValueEnumeration *enum_value = new OptionValueEnumeration( 84 definition.enum_values, definition.default_uint_value); 85 m_value_sp.reset(enum_value); 86 if (definition.default_cstr_value) { 87 if (enum_value 88 ->SetValueFromString( 89 llvm::StringRef(definition.default_cstr_value)) 90 .Success()) { 91 enum_value->SetDefaultValue(enum_value->GetCurrentValue()); 92 // Call Clear() since we don't want the value to appear as having 93 // been set since we called SetValueFromString() above. Clear will 94 // set the current value to the default and clear the boolean that 95 // says that the value has been set. 96 enum_value->Clear(); 97 } 98 } 99 } 100 break; 101 102 case OptionValue::eTypeFileSpec: { 103 // "definition.default_uint_value" represents if the 104 // "definition.default_cstr_value" should be resolved or not 105 const bool resolve = definition.default_uint_value != 0; 106 FileSpec file_spec = FileSpec(definition.default_cstr_value); 107 if (resolve) 108 FileSystem::Instance().Resolve(file_spec); 109 m_value_sp = std::make_shared<OptionValueFileSpec>(file_spec, resolve); 110 break; 111 } 112 113 case OptionValue::eTypeFileSpecList: 114 // "definition.default_uint_value" is not used for a 115 // OptionValue::eTypeFileSpecList 116 m_value_sp = std::make_shared<OptionValueFileSpecList>(); 117 break; 118 119 case OptionValue::eTypeFormat: 120 // "definition.default_uint_value" is the default format enumeration value 121 // if "definition.default_cstr_value" is NULL, otherwise interpret 122 // "definition.default_cstr_value" as a string value that represents the 123 // default value. 124 { 125 Format new_format = eFormatInvalid; 126 if (definition.default_cstr_value) 127 OptionArgParser::ToFormat(definition.default_cstr_value, new_format, 128 nullptr); 129 else 130 new_format = (Format)definition.default_uint_value; 131 m_value_sp = std::make_shared<OptionValueFormat>(new_format); 132 } 133 break; 134 135 case OptionValue::eTypeLanguage: 136 // "definition.default_uint_value" is the default language enumeration 137 // value if "definition.default_cstr_value" is NULL, otherwise interpret 138 // "definition.default_cstr_value" as a string value that represents the 139 // default value. 140 { 141 LanguageType new_lang = eLanguageTypeUnknown; 142 if (definition.default_cstr_value) 143 Language::GetLanguageTypeFromString( 144 llvm::StringRef(definition.default_cstr_value)); 145 else 146 new_lang = (LanguageType)definition.default_uint_value; 147 m_value_sp = std::make_shared<OptionValueLanguage>(new_lang); 148 } 149 break; 150 151 case OptionValue::eTypeFormatEntity: 152 // "definition.default_cstr_value" as a string value that represents the 153 // default 154 m_value_sp = std::make_shared<OptionValueFormatEntity>( 155 definition.default_cstr_value); 156 break; 157 158 case OptionValue::eTypePathMap: 159 // "definition.default_uint_value" tells us if notifications should occur 160 // for path mappings 161 m_value_sp = std::make_shared<OptionValuePathMappings>( 162 definition.default_uint_value != 0); 163 break; 164 165 case OptionValue::eTypeRegex: 166 // "definition.default_uint_value" is used to the regular expression flags 167 // "definition.default_cstr_value" the default regular expression value 168 // value. 169 m_value_sp = 170 std::make_shared<OptionValueRegex>(definition.default_cstr_value); 171 break; 172 173 case OptionValue::eTypeSInt64: 174 // "definition.default_uint_value" is the default integer value if 175 // "definition.default_cstr_value" is NULL, otherwise interpret 176 // "definition.default_cstr_value" as a string value that represents the 177 // default value. 178 m_value_sp = std::make_shared<OptionValueSInt64>( 179 definition.default_cstr_value 180 ? StringConvert::ToSInt64(definition.default_cstr_value) 181 : definition.default_uint_value); 182 break; 183 184 case OptionValue::eTypeUInt64: 185 // "definition.default_uint_value" is the default unsigned integer value if 186 // "definition.default_cstr_value" is NULL, otherwise interpret 187 // "definition.default_cstr_value" as a string value that represents the 188 // default value. 189 m_value_sp = std::make_shared<OptionValueUInt64>( 190 definition.default_cstr_value 191 ? StringConvert::ToUInt64(definition.default_cstr_value) 192 : definition.default_uint_value); 193 break; 194 195 case OptionValue::eTypeUUID: 196 // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID 197 // "definition.default_cstr_value" can contain a default UUID value 198 { 199 UUID uuid; 200 if (definition.default_cstr_value) 201 uuid.SetFromStringRef(definition.default_cstr_value); 202 m_value_sp = std::make_shared<OptionValueUUID>(uuid); 203 } 204 break; 205 206 case OptionValue::eTypeString: 207 // "definition.default_uint_value" can contain the string option flags 208 // OR'ed together "definition.default_cstr_value" can contain a default 209 // string value 210 { 211 OptionValueString *string_value = 212 new OptionValueString(definition.default_cstr_value); 213 if (definition.default_uint_value != 0) 214 string_value->GetOptions().Reset(definition.default_uint_value); 215 m_value_sp.reset(string_value); 216 } 217 break; 218 } 219} 220 221Property::Property(ConstString name, ConstString desc, 222 bool is_global, const lldb::OptionValueSP &value_sp) 223 : m_name(name), m_description(desc), m_value_sp(value_sp), 224 m_is_global(is_global) {} 225 226bool Property::DumpQualifiedName(Stream &strm) const { 227 if (m_name) { 228 if (m_value_sp->DumpQualifiedName(strm)) 229 strm.PutChar('.'); 230 strm << m_name; 231 return true; 232 } 233 return false; 234} 235 236void Property::Dump(const ExecutionContext *exe_ctx, Stream &strm, 237 uint32_t dump_mask) const { 238 if (m_value_sp) { 239 const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription; 240 const bool dump_cmd = dump_mask & OptionValue::eDumpOptionCommand; 241 const bool transparent = m_value_sp->ValueIsTransparent(); 242 if (dump_cmd && !transparent) 243 strm << "settings set -f "; 244 if (dump_desc || !transparent) { 245 if ((dump_mask & OptionValue::eDumpOptionName) && m_name) { 246 DumpQualifiedName(strm); 247 if (dump_mask & ~OptionValue::eDumpOptionName) 248 strm.PutChar(' '); 249 } 250 } 251 if (dump_desc) { 252 llvm::StringRef desc = GetDescription(); 253 if (!desc.empty()) 254 strm << "-- " << desc; 255 256 if (transparent && (dump_mask == (OptionValue::eDumpOptionName | 257 OptionValue::eDumpOptionDescription))) 258 strm.EOL(); 259 } 260 m_value_sp->DumpValue(exe_ctx, strm, dump_mask); 261 } 262} 263 264void Property::DumpDescription(CommandInterpreter &interpreter, Stream &strm, 265 uint32_t output_width, 266 bool display_qualified_name) const { 267 if (!m_value_sp) 268 return; 269 llvm::StringRef desc = GetDescription(); 270 271 if (desc.empty()) 272 return; 273 274 StreamString qualified_name; 275 const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties(); 276 if (sub_properties) { 277 strm.EOL(); 278 279 if (m_value_sp->DumpQualifiedName(qualified_name)) 280 strm.Printf("'%s' variables:\n\n", qualified_name.GetData()); 281 sub_properties->DumpAllDescriptions(interpreter, strm); 282 } else { 283 if (display_qualified_name) { 284 StreamString qualified_name; 285 DumpQualifiedName(qualified_name); 286 interpreter.OutputFormattedHelpText(strm, qualified_name.GetString(), 287 "--", desc, output_width); 288 } else { 289 interpreter.OutputFormattedHelpText(strm, m_name.GetStringRef(), "--", 290 desc, output_width); 291 } 292 } 293} 294 295void Property::SetValueChangedCallback(std::function<void()> callback) { 296 if (m_value_sp) 297 m_value_sp->SetValueChangedCallback(std::move(callback)); 298} 299