1 //===-- Property.cpp ------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Interpreter/Property.h"
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"
20 using namespace lldb_private
;
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
:
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
34 std::make_shared
<OptionValueArch
>(definition
.default_cstr_value
);
37 case OptionValue::eTypeArgs
:
38 // "definition.default_uint_value" is always a OptionValue::Type
39 m_value_sp
= std::make_shared
<OptionValueArgs
>();
42 case OptionValue::eTypeArray
:
43 // "definition.default_uint_value" is always a OptionValue::Type
45 std::make_shared
<OptionValueArray
>(OptionValue::ConvertTypeToMask(
46 (OptionValue::Type
)definition
.default_uint_value
));
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
54 if (definition
.default_cstr_value
)
56 std::make_shared
<OptionValueBoolean
>(OptionArgParser::ToBoolean(
57 llvm::StringRef(definition
.default_cstr_value
), false, nullptr));
59 m_value_sp
= std::make_shared
<OptionValueBoolean
>(
60 definition
.default_uint_value
!= 0);
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));
69 case OptionValue::eTypeDictionary
:
70 // "definition.default_uint_value" is always a OptionValue::Type
71 m_value_sp
= std::make_shared
<OptionValueDictionary
>(
72 OptionValue::ConvertTypeToMask(
73 (OptionValue::Type
)definition
.default_uint_value
),
74 definition
.enum_values
);
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
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
) {
89 llvm::StringRef(definition
.default_cstr_value
))
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.
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
>();
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
);
114 FileSystem::Instance().Resolve(file_spec
);
115 m_value_sp
= std::make_shared
<OptionValueFileSpec
>(file_spec
, resolve
);
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
>();
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
131 Format new_format
= eFormatInvalid
;
132 if (definition
.default_cstr_value
)
133 OptionArgParser::ToFormat(definition
.default_cstr_value
, new_format
,
136 new_format
= (Format
)definition
.default_uint_value
;
137 m_value_sp
= std::make_shared
<OptionValueFormat
>(new_format
);
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
147 LanguageType new_lang
= eLanguageTypeUnknown
;
148 if (definition
.default_cstr_value
)
149 Language::GetLanguageTypeFromString(
150 llvm::StringRef(definition
.default_cstr_value
));
152 new_lang
= (LanguageType
)definition
.default_uint_value
;
153 m_value_sp
= std::make_shared
<OptionValueLanguage
>(new_lang
);
157 case OptionValue::eTypeFormatEntity
:
158 // "definition.default_cstr_value" as a string value that represents the
160 m_value_sp
= std::make_shared
<OptionValueFormatEntity
>(
161 definition
.default_cstr_value
);
164 case OptionValue::eTypePathMap
:
165 // "definition.default_uint_value" tells us if notifications should occur
167 m_value_sp
= std::make_shared
<OptionValuePathMappings
>(
168 definition
.default_uint_value
!= 0);
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
176 std::make_shared
<OptionValueRegex
>(definition
.default_cstr_value
);
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
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
);
192 case OptionValue::eTypeUInt64
: {
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 if
198 // "definition.default_cstr_value" is NULL, otherwise interpret
199 // "definition.default_cstr_value" as a string value that represents the
201 m_value_sp
= std::make_shared
<OptionValueUInt64
>(
202 definition
.default_cstr_value
? value
: definition
.default_uint_value
);
205 case OptionValue::eTypeUUID
:
206 // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID
207 // "definition.default_cstr_value" can contain a default UUID value
210 if (definition
.default_cstr_value
)
211 uuid
.SetFromStringRef(definition
.default_cstr_value
);
212 m_value_sp
= std::make_shared
<OptionValueUUID
>(uuid
);
216 case OptionValue::eTypeString
:
217 // "definition.default_uint_value" can contain the string option flags
218 // OR'ed together "definition.default_cstr_value" can contain a default
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
);
229 assert(m_value_sp
&& "invalid property definition");
232 Property::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
) {}
237 bool Property::DumpQualifiedName(Stream
&strm
) const {
238 if (!m_name
.empty()) {
239 if (m_value_sp
->DumpQualifiedName(strm
))
247 void Property::Dump(const ExecutionContext
*exe_ctx
, Stream
&strm
,
248 uint32_t dump_mask
) const {
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
)
263 llvm::StringRef desc
= GetDescription();
265 strm
<< "-- " << desc
;
267 if (transparent
&& (dump_mask
== (OptionValue::eDumpOptionName
|
268 OptionValue::eDumpOptionDescription
)))
271 m_value_sp
->DumpValue(exe_ctx
, strm
, dump_mask
);
275 void Property::DumpDescription(CommandInterpreter
&interpreter
, Stream
&strm
,
276 uint32_t output_width
,
277 bool display_qualified_name
) const {
280 llvm::StringRef desc
= GetDescription();
285 StreamString qualified_name
;
286 const OptionValueProperties
*sub_properties
= m_value_sp
->GetAsProperties();
287 if (sub_properties
) {
290 if (m_value_sp
->DumpQualifiedName(qualified_name
))
291 strm
.Printf("'%s' variables:\n\n", qualified_name
.GetData());
292 sub_properties
->DumpAllDescriptions(interpreter
, strm
);
294 if (display_qualified_name
) {
295 StreamString qualified_name
;
296 DumpQualifiedName(qualified_name
);
297 interpreter
.OutputFormattedHelpText(strm
, qualified_name
.GetString(),
298 "--", desc
, output_width
);
300 interpreter
.OutputFormattedHelpText(strm
, m_name
, "--", desc
,
306 void Property::SetValueChangedCallback(std::function
<void()> callback
) {
308 m_value_sp
->SetValueChangedCallback(std::move(callback
));