1 //===-- Property.cpp ------------------------------------------------------===// 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 20 using namespace lldb; 21 using namespace lldb_private; 22 23 Property::Property(const PropertyDefinition &definition) 24 : m_name(definition.name), m_description(definition.description), 25 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::eTypeFileLineColumn: 103 // "definition.default_uint_value" is not used for a 104 // OptionValue::eTypeFileSpecList 105 m_value_sp = std::make_shared<OptionValueFileColonLine>(); 106 break; 107 108 case OptionValue::eTypeFileSpec: { 109 // "definition.default_uint_value" represents if the 110 // "definition.default_cstr_value" should be resolved or not 111 const bool resolve = definition.default_uint_value != 0; 112 FileSpec file_spec = FileSpec(definition.default_cstr_value); 113 if (resolve) 114 FileSystem::Instance().Resolve(file_spec); 115 m_value_sp = std::make_shared<OptionValueFileSpec>(file_spec, resolve); 116 break; 117 } 118 119 case OptionValue::eTypeFileSpecList: 120 // "definition.default_uint_value" is not used for a 121 // OptionValue::eTypeFileSpecList 122 m_value_sp = std::make_shared<OptionValueFileSpecList>(); 123 break; 124 125 case OptionValue::eTypeFormat: 126 // "definition.default_uint_value" is the default format enumeration value 127 // if "definition.default_cstr_value" is NULL, otherwise interpret 128 // "definition.default_cstr_value" as a string value that represents the 129 // default value. 130 { 131 Format new_format = eFormatInvalid; 132 if (definition.default_cstr_value) 133 OptionArgParser::ToFormat(definition.default_cstr_value, new_format, 134 nullptr); 135 else 136 new_format = (Format)definition.default_uint_value; 137 m_value_sp = std::make_shared<OptionValueFormat>(new_format); 138 } 139 break; 140 141 case OptionValue::eTypeLanguage: 142 // "definition.default_uint_value" is the default language enumeration 143 // value if "definition.default_cstr_value" is NULL, otherwise interpret 144 // "definition.default_cstr_value" as a string value that represents the 145 // default value. 146 { 147 LanguageType new_lang = eLanguageTypeUnknown; 148 if (definition.default_cstr_value) 149 Language::GetLanguageTypeFromString( 150 llvm::StringRef(definition.default_cstr_value)); 151 else 152 new_lang = (LanguageType)definition.default_uint_value; 153 m_value_sp = std::make_shared<OptionValueLanguage>(new_lang); 154 } 155 break; 156 157 case OptionValue::eTypeFormatEntity: 158 // "definition.default_cstr_value" as a string value that represents the 159 // default 160 m_value_sp = std::make_shared<OptionValueFormatEntity>( 161 definition.default_cstr_value); 162 break; 163 164 case OptionValue::eTypePathMap: 165 // "definition.default_uint_value" tells us if notifications should occur 166 // for path mappings 167 m_value_sp = std::make_shared<OptionValuePathMappings>( 168 definition.default_uint_value != 0); 169 break; 170 171 case OptionValue::eTypeRegex: 172 // "definition.default_uint_value" is used to the regular expression flags 173 // "definition.default_cstr_value" the default regular expression value 174 // value. 175 m_value_sp = 176 std::make_shared<OptionValueRegex>(definition.default_cstr_value); 177 break; 178 179 case OptionValue::eTypeSInt64: 180 // "definition.default_uint_value" is the default integer value if 181 // "definition.default_cstr_value" is NULL, otherwise interpret 182 // "definition.default_cstr_value" as a string value that represents the 183 // default value. 184 m_value_sp = std::make_shared<OptionValueSInt64>( 185 definition.default_cstr_value 186 ? StringConvert::ToSInt64(definition.default_cstr_value) 187 : definition.default_uint_value); 188 break; 189 190 case OptionValue::eTypeUInt64: 191 // "definition.default_uint_value" is the default unsigned integer value if 192 // "definition.default_cstr_value" is NULL, otherwise interpret 193 // "definition.default_cstr_value" as a string value that represents the 194 // default value. 195 m_value_sp = std::make_shared<OptionValueUInt64>( 196 definition.default_cstr_value 197 ? StringConvert::ToUInt64(definition.default_cstr_value) 198 : definition.default_uint_value); 199 break; 200 201 case OptionValue::eTypeUUID: 202 // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID 203 // "definition.default_cstr_value" can contain a default UUID value 204 { 205 UUID uuid; 206 if (definition.default_cstr_value) 207 uuid.SetFromStringRef(definition.default_cstr_value); 208 m_value_sp = std::make_shared<OptionValueUUID>(uuid); 209 } 210 break; 211 212 case OptionValue::eTypeString: 213 // "definition.default_uint_value" can contain the string option flags 214 // OR'ed together "definition.default_cstr_value" can contain a default 215 // string value 216 { 217 OptionValueString *string_value = 218 new OptionValueString(definition.default_cstr_value); 219 if (definition.default_uint_value != 0) 220 string_value->GetOptions().Reset(definition.default_uint_value); 221 m_value_sp.reset(string_value); 222 } 223 break; 224 } 225 } 226 227 Property::Property(ConstString name, ConstString desc, 228 bool is_global, const lldb::OptionValueSP &value_sp) 229 : m_name(name), m_description(desc), m_value_sp(value_sp), 230 m_is_global(is_global) {} 231 232 bool Property::DumpQualifiedName(Stream &strm) const { 233 if (m_name) { 234 if (m_value_sp->DumpQualifiedName(strm)) 235 strm.PutChar('.'); 236 strm << m_name; 237 return true; 238 } 239 return false; 240 } 241 242 void Property::Dump(const ExecutionContext *exe_ctx, Stream &strm, 243 uint32_t dump_mask) const { 244 if (m_value_sp) { 245 const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription; 246 const bool dump_cmd = dump_mask & OptionValue::eDumpOptionCommand; 247 const bool transparent = m_value_sp->ValueIsTransparent(); 248 if (dump_cmd && !transparent) 249 strm << "settings set -f "; 250 if (dump_desc || !transparent) { 251 if ((dump_mask & OptionValue::eDumpOptionName) && m_name) { 252 DumpQualifiedName(strm); 253 if (dump_mask & ~OptionValue::eDumpOptionName) 254 strm.PutChar(' '); 255 } 256 } 257 if (dump_desc) { 258 llvm::StringRef desc = GetDescription(); 259 if (!desc.empty()) 260 strm << "-- " << desc; 261 262 if (transparent && (dump_mask == (OptionValue::eDumpOptionName | 263 OptionValue::eDumpOptionDescription))) 264 strm.EOL(); 265 } 266 m_value_sp->DumpValue(exe_ctx, strm, dump_mask); 267 } 268 } 269 270 void Property::DumpDescription(CommandInterpreter &interpreter, Stream &strm, 271 uint32_t output_width, 272 bool display_qualified_name) const { 273 if (!m_value_sp) 274 return; 275 llvm::StringRef desc = GetDescription(); 276 277 if (desc.empty()) 278 return; 279 280 StreamString qualified_name; 281 const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties(); 282 if (sub_properties) { 283 strm.EOL(); 284 285 if (m_value_sp->DumpQualifiedName(qualified_name)) 286 strm.Printf("'%s' variables:\n\n", qualified_name.GetData()); 287 sub_properties->DumpAllDescriptions(interpreter, strm); 288 } else { 289 if (display_qualified_name) { 290 StreamString qualified_name; 291 DumpQualifiedName(qualified_name); 292 interpreter.OutputFormattedHelpText(strm, qualified_name.GetString(), 293 "--", desc, output_width); 294 } else { 295 interpreter.OutputFormattedHelpText(strm, m_name.GetStringRef(), "--", 296 desc, output_width); 297 } 298 } 299 } 300 301 void Property::SetValueChangedCallback(std::function<void()> callback) { 302 if (m_value_sp) 303 m_value_sp->SetValueChangedCallback(std::move(callback)); 304 } 305