xref: /openbsd-src/gnu/llvm/lldb/source/Interpreter/Property.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- Property.cpp ------------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "lldb/Interpreter/Property.h"
10061da546Spatrick 
11061da546Spatrick #include "lldb/Core/UserSettingsController.h"
12061da546Spatrick #include "lldb/Interpreter/CommandInterpreter.h"
13061da546Spatrick #include "lldb/Interpreter/OptionArgParser.h"
14061da546Spatrick #include "lldb/Interpreter/OptionValues.h"
15061da546Spatrick #include "lldb/Target/Language.h"
16061da546Spatrick 
17061da546Spatrick #include <memory>
18061da546Spatrick 
19061da546Spatrick using namespace lldb;
20061da546Spatrick using namespace lldb_private;
21061da546Spatrick 
Property(const PropertyDefinition & definition)22061da546Spatrick Property::Property(const PropertyDefinition &definition)
23061da546Spatrick     : m_name(definition.name), m_description(definition.description),
24be691f3bSpatrick       m_is_global(definition.global) {
25061da546Spatrick   switch (definition.type) {
26061da546Spatrick   case OptionValue::eTypeInvalid:
27061da546Spatrick   case OptionValue::eTypeProperties:
28061da546Spatrick     break;
29061da546Spatrick   case OptionValue::eTypeArch:
30061da546Spatrick     // "definition.default_uint_value" is not used
31061da546Spatrick     // "definition.default_cstr_value" as a string value that represents the
32061da546Spatrick     // default string value for the architecture/triple
33061da546Spatrick     m_value_sp =
34061da546Spatrick         std::make_shared<OptionValueArch>(definition.default_cstr_value);
35061da546Spatrick     break;
36061da546Spatrick 
37061da546Spatrick   case OptionValue::eTypeArgs:
38061da546Spatrick     // "definition.default_uint_value" is always a OptionValue::Type
39061da546Spatrick     m_value_sp = std::make_shared<OptionValueArgs>();
40061da546Spatrick     break;
41061da546Spatrick 
42061da546Spatrick   case OptionValue::eTypeArray:
43061da546Spatrick     // "definition.default_uint_value" is always a OptionValue::Type
44061da546Spatrick     m_value_sp =
45061da546Spatrick         std::make_shared<OptionValueArray>(OptionValue::ConvertTypeToMask(
46061da546Spatrick             (OptionValue::Type)definition.default_uint_value));
47061da546Spatrick     break;
48061da546Spatrick 
49061da546Spatrick   case OptionValue::eTypeBoolean:
50061da546Spatrick     // "definition.default_uint_value" is the default boolean value if
51061da546Spatrick     // "definition.default_cstr_value" is NULL, otherwise interpret
52061da546Spatrick     // "definition.default_cstr_value" as a string value that represents the
53061da546Spatrick     // default value.
54061da546Spatrick     if (definition.default_cstr_value)
55061da546Spatrick       m_value_sp =
56061da546Spatrick           std::make_shared<OptionValueBoolean>(OptionArgParser::ToBoolean(
57061da546Spatrick               llvm::StringRef(definition.default_cstr_value), false, nullptr));
58061da546Spatrick     else
59061da546Spatrick       m_value_sp = std::make_shared<OptionValueBoolean>(
60061da546Spatrick           definition.default_uint_value != 0);
61061da546Spatrick     break;
62061da546Spatrick 
63061da546Spatrick   case OptionValue::eTypeChar: {
64061da546Spatrick     llvm::StringRef s(definition.default_cstr_value ? definition.default_cstr_value : "");
65061da546Spatrick     m_value_sp = std::make_shared<OptionValueChar>(
66061da546Spatrick         OptionArgParser::ToChar(s, '\0', nullptr));
67061da546Spatrick     break;
68061da546Spatrick   }
69061da546Spatrick   case OptionValue::eTypeDictionary:
70061da546Spatrick     // "definition.default_uint_value" is always a OptionValue::Type
71*f6aab3d8Srobert     m_value_sp = std::make_shared<OptionValueDictionary>(
72*f6aab3d8Srobert         OptionValue::ConvertTypeToMask(
73*f6aab3d8Srobert             (OptionValue::Type)definition.default_uint_value),
74*f6aab3d8Srobert         definition.enum_values);
75061da546Spatrick     break;
76061da546Spatrick 
77061da546Spatrick   case OptionValue::eTypeEnum:
78061da546Spatrick     // "definition.default_uint_value" is the default enumeration value if
79061da546Spatrick     // "definition.default_cstr_value" is NULL, otherwise interpret
80061da546Spatrick     // "definition.default_cstr_value" as a string value that represents the
81061da546Spatrick     // default value.
82061da546Spatrick     {
83061da546Spatrick       OptionValueEnumeration *enum_value = new OptionValueEnumeration(
84061da546Spatrick           definition.enum_values, definition.default_uint_value);
85061da546Spatrick       m_value_sp.reset(enum_value);
86061da546Spatrick       if (definition.default_cstr_value) {
87061da546Spatrick         if (enum_value
88061da546Spatrick                 ->SetValueFromString(
89061da546Spatrick                     llvm::StringRef(definition.default_cstr_value))
90061da546Spatrick                 .Success()) {
91061da546Spatrick           enum_value->SetDefaultValue(enum_value->GetCurrentValue());
92061da546Spatrick           // Call Clear() since we don't want the value to appear as having
93061da546Spatrick           // been set since we called SetValueFromString() above. Clear will
94061da546Spatrick           // set the current value to the default and clear the boolean that
95061da546Spatrick           // says that the value has been set.
96061da546Spatrick           enum_value->Clear();
97061da546Spatrick         }
98061da546Spatrick       }
99061da546Spatrick     }
100061da546Spatrick     break;
101061da546Spatrick 
102be691f3bSpatrick   case OptionValue::eTypeFileLineColumn:
103be691f3bSpatrick     // "definition.default_uint_value" is not used for a
104be691f3bSpatrick     // OptionValue::eTypeFileSpecList
105be691f3bSpatrick     m_value_sp = std::make_shared<OptionValueFileColonLine>();
106be691f3bSpatrick     break;
107be691f3bSpatrick 
108061da546Spatrick   case OptionValue::eTypeFileSpec: {
109061da546Spatrick     // "definition.default_uint_value" represents if the
110061da546Spatrick     // "definition.default_cstr_value" should be resolved or not
111061da546Spatrick     const bool resolve = definition.default_uint_value != 0;
112061da546Spatrick     FileSpec file_spec = FileSpec(definition.default_cstr_value);
113061da546Spatrick     if (resolve)
114061da546Spatrick       FileSystem::Instance().Resolve(file_spec);
115061da546Spatrick     m_value_sp = std::make_shared<OptionValueFileSpec>(file_spec, resolve);
116061da546Spatrick     break;
117061da546Spatrick   }
118061da546Spatrick 
119061da546Spatrick   case OptionValue::eTypeFileSpecList:
120061da546Spatrick     // "definition.default_uint_value" is not used for a
121061da546Spatrick     // OptionValue::eTypeFileSpecList
122061da546Spatrick     m_value_sp = std::make_shared<OptionValueFileSpecList>();
123061da546Spatrick     break;
124061da546Spatrick 
125061da546Spatrick   case OptionValue::eTypeFormat:
126061da546Spatrick     // "definition.default_uint_value" is the default format enumeration value
127061da546Spatrick     // if "definition.default_cstr_value" is NULL, otherwise interpret
128061da546Spatrick     // "definition.default_cstr_value" as a string value that represents the
129061da546Spatrick     // default value.
130061da546Spatrick     {
131061da546Spatrick       Format new_format = eFormatInvalid;
132061da546Spatrick       if (definition.default_cstr_value)
133061da546Spatrick         OptionArgParser::ToFormat(definition.default_cstr_value, new_format,
134061da546Spatrick                                   nullptr);
135061da546Spatrick       else
136061da546Spatrick         new_format = (Format)definition.default_uint_value;
137061da546Spatrick       m_value_sp = std::make_shared<OptionValueFormat>(new_format);
138061da546Spatrick     }
139061da546Spatrick     break;
140061da546Spatrick 
141061da546Spatrick   case OptionValue::eTypeLanguage:
142061da546Spatrick     // "definition.default_uint_value" is the default language enumeration
143061da546Spatrick     // value if "definition.default_cstr_value" is NULL, otherwise interpret
144061da546Spatrick     // "definition.default_cstr_value" as a string value that represents the
145061da546Spatrick     // default value.
146061da546Spatrick     {
147061da546Spatrick       LanguageType new_lang = eLanguageTypeUnknown;
148061da546Spatrick       if (definition.default_cstr_value)
149061da546Spatrick         Language::GetLanguageTypeFromString(
150061da546Spatrick             llvm::StringRef(definition.default_cstr_value));
151061da546Spatrick       else
152061da546Spatrick         new_lang = (LanguageType)definition.default_uint_value;
153061da546Spatrick       m_value_sp = std::make_shared<OptionValueLanguage>(new_lang);
154061da546Spatrick     }
155061da546Spatrick     break;
156061da546Spatrick 
157061da546Spatrick   case OptionValue::eTypeFormatEntity:
158061da546Spatrick     // "definition.default_cstr_value" as a string value that represents the
159061da546Spatrick     // default
160061da546Spatrick     m_value_sp = std::make_shared<OptionValueFormatEntity>(
161061da546Spatrick         definition.default_cstr_value);
162061da546Spatrick     break;
163061da546Spatrick 
164061da546Spatrick   case OptionValue::eTypePathMap:
165061da546Spatrick     // "definition.default_uint_value" tells us if notifications should occur
166061da546Spatrick     // for path mappings
167061da546Spatrick     m_value_sp = std::make_shared<OptionValuePathMappings>(
168061da546Spatrick         definition.default_uint_value != 0);
169061da546Spatrick     break;
170061da546Spatrick 
171061da546Spatrick   case OptionValue::eTypeRegex:
172061da546Spatrick     // "definition.default_uint_value" is used to the regular expression flags
173061da546Spatrick     // "definition.default_cstr_value" the default regular expression value
174061da546Spatrick     // value.
175061da546Spatrick     m_value_sp =
176061da546Spatrick         std::make_shared<OptionValueRegex>(definition.default_cstr_value);
177061da546Spatrick     break;
178061da546Spatrick 
179*f6aab3d8Srobert   case OptionValue::eTypeSInt64: {
180061da546Spatrick     // "definition.default_uint_value" is the default integer value if
181061da546Spatrick     // "definition.default_cstr_value" is NULL, otherwise interpret
182061da546Spatrick     // "definition.default_cstr_value" as a string value that represents the
183061da546Spatrick     // default value.
184*f6aab3d8Srobert     int64_t value = 0;
185*f6aab3d8Srobert     // FIXME: improve error handling for llvm::to_integer()
186*f6aab3d8Srobert     if (definition.default_cstr_value)
187*f6aab3d8Srobert       llvm::to_integer(definition.default_cstr_value, value);
188061da546Spatrick     m_value_sp = std::make_shared<OptionValueSInt64>(
189*f6aab3d8Srobert         definition.default_cstr_value ? value : definition.default_uint_value);
190061da546Spatrick     break;
191*f6aab3d8Srobert   }
192*f6aab3d8Srobert   case OptionValue::eTypeUInt64: {
193*f6aab3d8Srobert     uint64_t value = 0;
194*f6aab3d8Srobert     // FIXME: improve error handling for llvm::to_integer()
195*f6aab3d8Srobert     if (definition.default_cstr_value)
196*f6aab3d8Srobert       llvm::to_integer(definition.default_cstr_value, value);
197061da546Spatrick     // "definition.default_uint_value" is the default unsigned integer value if
198061da546Spatrick     // "definition.default_cstr_value" is NULL, otherwise interpret
199061da546Spatrick     // "definition.default_cstr_value" as a string value that represents the
200061da546Spatrick     // default value.
201061da546Spatrick     m_value_sp = std::make_shared<OptionValueUInt64>(
202*f6aab3d8Srobert         definition.default_cstr_value ? value : definition.default_uint_value);
203061da546Spatrick     break;
204*f6aab3d8Srobert   }
205061da546Spatrick   case OptionValue::eTypeUUID:
206061da546Spatrick     // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID
207061da546Spatrick     // "definition.default_cstr_value" can contain a default UUID value
208061da546Spatrick     {
209061da546Spatrick       UUID uuid;
210061da546Spatrick       if (definition.default_cstr_value)
211061da546Spatrick         uuid.SetFromStringRef(definition.default_cstr_value);
212061da546Spatrick       m_value_sp = std::make_shared<OptionValueUUID>(uuid);
213061da546Spatrick     }
214061da546Spatrick     break;
215061da546Spatrick 
216061da546Spatrick   case OptionValue::eTypeString:
217061da546Spatrick     // "definition.default_uint_value" can contain the string option flags
218061da546Spatrick     // OR'ed together "definition.default_cstr_value" can contain a default
219061da546Spatrick     // string value
220061da546Spatrick     {
221061da546Spatrick       OptionValueString *string_value =
222061da546Spatrick           new OptionValueString(definition.default_cstr_value);
223061da546Spatrick       if (definition.default_uint_value != 0)
224061da546Spatrick         string_value->GetOptions().Reset(definition.default_uint_value);
225061da546Spatrick       m_value_sp.reset(string_value);
226061da546Spatrick     }
227061da546Spatrick     break;
228061da546Spatrick   }
229061da546Spatrick }
230061da546Spatrick 
Property(llvm::StringRef name,llvm::StringRef desc,bool is_global,const lldb::OptionValueSP & value_sp)231*f6aab3d8Srobert Property::Property(llvm::StringRef name, llvm::StringRef desc, bool is_global,
232*f6aab3d8Srobert                    const lldb::OptionValueSP &value_sp)
233061da546Spatrick     : m_name(name), m_description(desc), m_value_sp(value_sp),
234061da546Spatrick       m_is_global(is_global) {}
235061da546Spatrick 
DumpQualifiedName(Stream & strm) const236061da546Spatrick bool Property::DumpQualifiedName(Stream &strm) const {
237*f6aab3d8Srobert   if (!m_name.empty()) {
238061da546Spatrick     if (m_value_sp->DumpQualifiedName(strm))
239061da546Spatrick       strm.PutChar('.');
240061da546Spatrick     strm << m_name;
241061da546Spatrick     return true;
242061da546Spatrick   }
243061da546Spatrick   return false;
244061da546Spatrick }
245061da546Spatrick 
Dump(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask) const246061da546Spatrick void Property::Dump(const ExecutionContext *exe_ctx, Stream &strm,
247061da546Spatrick                     uint32_t dump_mask) const {
248061da546Spatrick   if (m_value_sp) {
249061da546Spatrick     const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription;
250061da546Spatrick     const bool dump_cmd = dump_mask & OptionValue::eDumpOptionCommand;
251061da546Spatrick     const bool transparent = m_value_sp->ValueIsTransparent();
252061da546Spatrick     if (dump_cmd && !transparent)
253061da546Spatrick       strm << "settings set -f ";
254061da546Spatrick     if (dump_desc || !transparent) {
255*f6aab3d8Srobert       if ((dump_mask & OptionValue::eDumpOptionName) && !m_name.empty()) {
256061da546Spatrick         DumpQualifiedName(strm);
257061da546Spatrick         if (dump_mask & ~OptionValue::eDumpOptionName)
258061da546Spatrick           strm.PutChar(' ');
259061da546Spatrick       }
260061da546Spatrick     }
261061da546Spatrick     if (dump_desc) {
262061da546Spatrick       llvm::StringRef desc = GetDescription();
263061da546Spatrick       if (!desc.empty())
264061da546Spatrick         strm << "-- " << desc;
265061da546Spatrick 
266061da546Spatrick       if (transparent && (dump_mask == (OptionValue::eDumpOptionName |
267061da546Spatrick                                         OptionValue::eDumpOptionDescription)))
268061da546Spatrick         strm.EOL();
269061da546Spatrick     }
270061da546Spatrick     m_value_sp->DumpValue(exe_ctx, strm, dump_mask);
271061da546Spatrick   }
272061da546Spatrick }
273061da546Spatrick 
DumpDescription(CommandInterpreter & interpreter,Stream & strm,uint32_t output_width,bool display_qualified_name) const274061da546Spatrick void Property::DumpDescription(CommandInterpreter &interpreter, Stream &strm,
275061da546Spatrick                                uint32_t output_width,
276061da546Spatrick                                bool display_qualified_name) const {
277061da546Spatrick   if (!m_value_sp)
278061da546Spatrick     return;
279061da546Spatrick   llvm::StringRef desc = GetDescription();
280061da546Spatrick 
281061da546Spatrick   if (desc.empty())
282061da546Spatrick     return;
283061da546Spatrick 
284061da546Spatrick   StreamString qualified_name;
285061da546Spatrick   const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties();
286061da546Spatrick   if (sub_properties) {
287061da546Spatrick     strm.EOL();
288061da546Spatrick 
289061da546Spatrick     if (m_value_sp->DumpQualifiedName(qualified_name))
290061da546Spatrick       strm.Printf("'%s' variables:\n\n", qualified_name.GetData());
291061da546Spatrick     sub_properties->DumpAllDescriptions(interpreter, strm);
292061da546Spatrick   } else {
293061da546Spatrick     if (display_qualified_name) {
294061da546Spatrick       StreamString qualified_name;
295061da546Spatrick       DumpQualifiedName(qualified_name);
296061da546Spatrick       interpreter.OutputFormattedHelpText(strm, qualified_name.GetString(),
297061da546Spatrick                                           "--", desc, output_width);
298061da546Spatrick     } else {
299*f6aab3d8Srobert       interpreter.OutputFormattedHelpText(strm, m_name, "--", desc,
300*f6aab3d8Srobert                                           output_width);
301061da546Spatrick     }
302061da546Spatrick   }
303061da546Spatrick }
304061da546Spatrick 
SetValueChangedCallback(std::function<void ()> callback)305061da546Spatrick void Property::SetValueChangedCallback(std::function<void()> callback) {
306061da546Spatrick   if (m_value_sp)
307061da546Spatrick     m_value_sp->SetValueChangedCallback(std::move(callback));
308061da546Spatrick }
309