1 //===-- Property.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Interpreter/Property.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/UserSettingsController.h"
17 #include "lldb/Host/StringConvert.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Interpreter/OptionArgParser.h"
20 #include "lldb/Interpreter/OptionValues.h"
21 #include "lldb/Target/Language.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 Property::Property(const PropertyDefinition &definition)
27     : m_name(definition.name), m_description(definition.description),
28       m_value_sp(), m_is_global(definition.global) {
29   switch (definition.type) {
30   case OptionValue::eTypeInvalid:
31   case OptionValue::eTypeProperties:
32     break;
33   case OptionValue::eTypeArch:
34     // "definition.default_uint_value" is not used
35     // "definition.default_cstr_value" as a string value that represents the
36     // default string value for the architecture/triple
37     m_value_sp.reset(new OptionValueArch(definition.default_cstr_value));
38     break;
39 
40   case OptionValue::eTypeArgs:
41     // "definition.default_uint_value" is always a OptionValue::Type
42     m_value_sp.reset(new OptionValueArgs());
43     break;
44 
45   case OptionValue::eTypeArray:
46     // "definition.default_uint_value" is always a OptionValue::Type
47     m_value_sp.reset(new OptionValueArray(OptionValue::ConvertTypeToMask(
48         (OptionValue::Type)definition.default_uint_value)));
49     break;
50 
51   case OptionValue::eTypeBoolean:
52     // "definition.default_uint_value" is the default boolean value if
53     // "definition.default_cstr_value" is NULL, otherwise interpret
54     // "definition.default_cstr_value" as a string value that represents the
55     // default value.
56     if (definition.default_cstr_value)
57       m_value_sp.reset(new OptionValueBoolean(OptionArgParser::ToBoolean(
58           llvm::StringRef(definition.default_cstr_value), false, nullptr)));
59     else
60       m_value_sp.reset(
61           new OptionValueBoolean(definition.default_uint_value != 0));
62     break;
63 
64   case OptionValue::eTypeChar: {
65     llvm::StringRef s(definition.default_cstr_value ? definition.default_cstr_value : "");
66     m_value_sp = std::make_shared<OptionValueChar>(
67         OptionArgParser::ToChar(s, '\0', nullptr));
68     break;
69   }
70   case OptionValue::eTypeDictionary:
71     // "definition.default_uint_value" is always a OptionValue::Type
72     m_value_sp.reset(new 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::eTypeFileSpec: {
102     // "definition.default_uint_value" represents if the
103     // "definition.default_cstr_value" should be resolved or not
104     const bool resolve = definition.default_uint_value != 0;
105     m_value_sp.reset(new OptionValueFileSpec(
106         FileSpec(definition.default_cstr_value, resolve), resolve));
107     break;
108   }
109 
110   case OptionValue::eTypeFileSpecList:
111     // "definition.default_uint_value" is not used for a
112     // OptionValue::eTypeFileSpecList
113     m_value_sp.reset(new OptionValueFileSpecList());
114     break;
115 
116   case OptionValue::eTypeFormat:
117     // "definition.default_uint_value" is the default format enumeration value
118     // if "definition.default_cstr_value" is NULL, otherwise interpret
119     // "definition.default_cstr_value" as a string value that represents the
120     // default value.
121     {
122       Format new_format = eFormatInvalid;
123       if (definition.default_cstr_value)
124         OptionArgParser::ToFormat(definition.default_cstr_value, new_format,
125                                   nullptr);
126       else
127         new_format = (Format)definition.default_uint_value;
128       m_value_sp.reset(new OptionValueFormat(new_format));
129     }
130     break;
131 
132   case OptionValue::eTypeLanguage:
133     // "definition.default_uint_value" is the default language enumeration
134     // value if "definition.default_cstr_value" is NULL, otherwise interpret
135     // "definition.default_cstr_value" as a string value that represents the
136     // default value.
137     {
138       LanguageType new_lang = eLanguageTypeUnknown;
139       if (definition.default_cstr_value)
140         Language::GetLanguageTypeFromString(
141             llvm::StringRef(definition.default_cstr_value));
142       else
143         new_lang = (LanguageType)definition.default_uint_value;
144       m_value_sp.reset(new OptionValueLanguage(new_lang));
145     }
146     break;
147 
148   case OptionValue::eTypeFormatEntity:
149     // "definition.default_cstr_value" as a string value that represents the
150     // default
151     m_value_sp.reset(
152         new OptionValueFormatEntity(definition.default_cstr_value));
153     break;
154 
155   case OptionValue::eTypePathMap:
156     // "definition.default_uint_value" tells us if notifications should occur
157     // for path mappings
158     m_value_sp.reset(
159         new OptionValuePathMappings(definition.default_uint_value != 0));
160     break;
161 
162   case OptionValue::eTypeRegex:
163     // "definition.default_uint_value" is used to the regular expression flags
164     // "definition.default_cstr_value" the default regular expression value
165     // value.
166     m_value_sp.reset(new OptionValueRegex(definition.default_cstr_value));
167     break;
168 
169   case OptionValue::eTypeSInt64:
170     // "definition.default_uint_value" is the default integer value if
171     // "definition.default_cstr_value" is NULL, otherwise interpret
172     // "definition.default_cstr_value" as a string value that represents the
173     // default value.
174     m_value_sp.reset(new OptionValueSInt64(
175         definition.default_cstr_value
176             ? StringConvert::ToSInt64(definition.default_cstr_value)
177             : definition.default_uint_value));
178     break;
179 
180   case OptionValue::eTypeUInt64:
181     // "definition.default_uint_value" is the default unsigned integer value if
182     // "definition.default_cstr_value" is NULL, otherwise interpret
183     // "definition.default_cstr_value" as a string value that represents the
184     // default value.
185     m_value_sp.reset(new OptionValueUInt64(
186         definition.default_cstr_value
187             ? StringConvert::ToUInt64(definition.default_cstr_value)
188             : definition.default_uint_value));
189     break;
190 
191   case OptionValue::eTypeUUID:
192     // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID
193     // "definition.default_cstr_value" can contain a default UUID value
194     {
195       UUID uuid;
196       if (definition.default_cstr_value)
197         uuid.SetFromStringRef(definition.default_cstr_value);
198       m_value_sp.reset(new OptionValueUUID(uuid));
199     }
200     break;
201 
202   case OptionValue::eTypeString:
203     // "definition.default_uint_value" can contain the string option flags
204     // OR'ed together "definition.default_cstr_value" can contain a default
205     // string value
206     {
207       OptionValueString *string_value =
208           new OptionValueString(definition.default_cstr_value);
209       if (definition.default_uint_value != 0)
210         string_value->GetOptions().Reset(definition.default_uint_value);
211       m_value_sp.reset(string_value);
212     }
213     break;
214   }
215 }
216 
217 Property::Property(const ConstString &name, const ConstString &desc,
218                    bool is_global, const lldb::OptionValueSP &value_sp)
219     : m_name(name), m_description(desc), m_value_sp(value_sp),
220       m_is_global(is_global) {}
221 
222 bool Property::DumpQualifiedName(Stream &strm) const {
223   if (m_name) {
224     if (m_value_sp->DumpQualifiedName(strm))
225       strm.PutChar('.');
226     strm << m_name;
227     return true;
228   }
229   return false;
230 }
231 
232 void Property::Dump(const ExecutionContext *exe_ctx, Stream &strm,
233                     uint32_t dump_mask) const {
234   if (m_value_sp) {
235     const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription;
236     const bool transparent = m_value_sp->ValueIsTransparent();
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