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