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