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