310 lines · cpp
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-exception6//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 19using namespace lldb;20using namespace lldb_private;21 22Property::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 used31 // "definition.default_cstr_value" as a string value that represents the32 // default string value for the architecture/triple33 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::Type39 m_value_sp = std::make_shared<OptionValueArgs>();40 break;41 42 case OptionValue::eTypeArray:43 // "definition.default_uint_value" is always a OptionValue::Type44 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 if51 // "definition.default_cstr_value" is NULL, otherwise interpret52 // "definition.default_cstr_value" as a string value that represents the53 // 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 else59 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::Type71 m_value_sp = std::make_shared<OptionValueDictionary>(72 OptionValue::ConvertTypeToMask(73 (OptionValue::Type)definition.default_uint_value),74 definition.enum_values);75 break;76 77 case OptionValue::eTypeEnum:78 // "definition.default_uint_value" is the default enumeration value if79 // "definition.default_cstr_value" is NULL, otherwise interpret80 // "definition.default_cstr_value" as a string value that represents the81 // 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_value88 ->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 having93 // been set since we called SetValueFromString() above. Clear will94 // set the current value to the default and clear the boolean that95 // 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 a104 // OptionValue::eTypeFileSpecList105 m_value_sp = std::make_shared<OptionValueFileColonLine>();106 break;107 108 case OptionValue::eTypeFileSpec: {109 // "definition.default_uint_value" represents if the110 // "definition.default_cstr_value" should be resolved or not111 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 a121 // OptionValue::eTypeFileSpecList122 m_value_sp = std::make_shared<OptionValueFileSpecList>();123 break;124 125 case OptionValue::eTypeFormat:126 // "definition.default_uint_value" is the default format enumeration value127 // if "definition.default_cstr_value" is NULL, otherwise interpret128 // "definition.default_cstr_value" as a string value that represents the129 // 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 else136 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 enumeration143 // value if "definition.default_cstr_value" is NULL, otherwise interpret144 // "definition.default_cstr_value" as a string value that represents the145 // 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 else152 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 the159 // default160 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 occur166 // for path mappings167 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 flags173 // "definition.default_cstr_value" the default regular expression value174 // 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 if181 // "definition.default_cstr_value" is NULL, otherwise interpret182 // "definition.default_cstr_value" as a string value that represents the183 // default value.184 int64_t value = 0;185 // FIXME: improve error handling for llvm::to_integer()186 if (definition.default_cstr_value)187 llvm::to_integer(definition.default_cstr_value, value);188 m_value_sp = std::make_shared<OptionValueSInt64>(189 definition.default_cstr_value ? value : definition.default_uint_value);190 break;191 }192 case OptionValue::eTypeUInt64: {193 uint64_t value = 0;194 // FIXME: improve error handling for llvm::to_integer()195 if (definition.default_cstr_value)196 llvm::to_integer(definition.default_cstr_value, value);197 // "definition.default_uint_value" is the default unsigned integer value if198 // "definition.default_cstr_value" is NULL, otherwise interpret199 // "definition.default_cstr_value" as a string value that represents the200 // default value.201 m_value_sp = std::make_shared<OptionValueUInt64>(202 definition.default_cstr_value ? value : definition.default_uint_value);203 break;204 }205 case OptionValue::eTypeUUID:206 // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID207 // "definition.default_cstr_value" can contain a default UUID value208 {209 UUID uuid;210 if (definition.default_cstr_value)211 uuid.SetFromStringRef(definition.default_cstr_value);212 m_value_sp = std::make_shared<OptionValueUUID>(uuid);213 }214 break;215 216 case OptionValue::eTypeString:217 // "definition.default_uint_value" can contain the string option flags218 // OR'ed together "definition.default_cstr_value" can contain a default219 // string value220 {221 OptionValueString *string_value =222 new OptionValueString(definition.default_cstr_value);223 if (definition.default_uint_value != 0)224 string_value->GetOptions().Reset(definition.default_uint_value);225 m_value_sp.reset(string_value);226 }227 break;228 }229 assert(m_value_sp && "invalid property definition");230}231 232Property::Property(llvm::StringRef name, llvm::StringRef desc, bool is_global,233 const lldb::OptionValueSP &value_sp)234 : m_name(name), m_description(desc), m_value_sp(value_sp),235 m_is_global(is_global) {}236 237bool Property::DumpQualifiedName(Stream &strm) const {238 if (!m_name.empty()) {239 if (m_value_sp->DumpQualifiedName(strm))240 strm.PutChar('.');241 strm << m_name;242 return true;243 }244 return false;245}246 247void Property::Dump(const ExecutionContext *exe_ctx, Stream &strm,248 uint32_t dump_mask) const {249 if (m_value_sp) {250 const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription;251 const bool dump_cmd = dump_mask & OptionValue::eDumpOptionCommand;252 const bool transparent = m_value_sp->ValueIsTransparent();253 if (dump_cmd && !transparent)254 strm << "settings set -f ";255 if (dump_desc || !transparent) {256 if ((dump_mask & OptionValue::eDumpOptionName) && !m_name.empty()) {257 DumpQualifiedName(strm);258 if (dump_mask & ~OptionValue::eDumpOptionName)259 strm.PutChar(' ');260 }261 }262 if (dump_desc) {263 llvm::StringRef desc = GetDescription();264 if (!desc.empty())265 strm << "-- " << desc;266 267 if (transparent && (dump_mask == (OptionValue::eDumpOptionName |268 OptionValue::eDumpOptionDescription)))269 strm.EOL();270 }271 m_value_sp->DumpValue(exe_ctx, strm, dump_mask);272 }273}274 275void Property::DumpDescription(CommandInterpreter &interpreter, Stream &strm,276 uint32_t output_width,277 bool display_qualified_name) const {278 if (!m_value_sp)279 return;280 llvm::StringRef desc = GetDescription();281 282 if (desc.empty())283 return;284 285 StreamString qualified_name;286 const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties();287 if (sub_properties) {288 strm.EOL();289 290 if (m_value_sp->DumpQualifiedName(qualified_name))291 strm.Printf("'%s' variables:\n\n", qualified_name.GetData());292 sub_properties->DumpAllDescriptions(interpreter, strm);293 } else {294 if (display_qualified_name) {295 StreamString qualified_name;296 DumpQualifiedName(qualified_name);297 interpreter.OutputFormattedHelpText(strm, qualified_name.GetString(),298 "--", desc, output_width);299 } else {300 interpreter.OutputFormattedHelpText(strm, m_name, "--", desc,301 output_width);302 }303 }304}305 306void Property::SetValueChangedCallback(std::function<void()> callback) {307 if (m_value_sp)308 m_value_sp->SetValueChangedCallback(std::move(callback));309}310