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 value.
55     if (definition.default_cstr_value)
56       m_value_sp.reset(new OptionValueBoolean(Args::StringToBoolean(
57           llvm::StringRef(definition.default_cstr_value), false, nullptr)));
58     else
59       m_value_sp.reset(
60           new OptionValueBoolean(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>(Args::StringToChar(s, '\0', nullptr));
66     break;
67   }
68   case OptionValue::eTypeDictionary:
69     // "definition.default_uint_value" is always a OptionValue::Type
70     m_value_sp.reset(new OptionValueDictionary(OptionValue::ConvertTypeToMask(
71         (OptionValue::Type)definition.default_uint_value)));
72     break;
73 
74   case OptionValue::eTypeEnum:
75     // "definition.default_uint_value" is the default enumeration value if
76     // "definition.default_cstr_value" is NULL, otherwise interpret
77     // "definition.default_cstr_value" as a string value that represents the
78     // default
79     // value.
80     {
81       OptionValueEnumeration *enum_value = new OptionValueEnumeration(
82           definition.enum_values, definition.default_uint_value);
83       m_value_sp.reset(enum_value);
84       if (definition.default_cstr_value) {
85         if (enum_value->SetValueFromString(definition.default_cstr_value)
86                 .Success()) {
87           enum_value->SetDefaultValue(enum_value->GetCurrentValue());
88           // Call Clear() since we don't want the value to appear as
89           // having been set since we called SetValueFromString() above.
90           // Clear will set the current value to the default and clear
91           // the boolean that says that the value has been set.
92           enum_value->Clear();
93         }
94       }
95     }
96     break;
97 
98   case OptionValue::eTypeFileSpec: {
99     // "definition.default_uint_value" represents if the
100     // "definition.default_cstr_value" should
101     // be resolved or not
102     const bool resolve = definition.default_uint_value != 0;
103     m_value_sp.reset(new OptionValueFileSpec(
104         FileSpec(definition.default_cstr_value, resolve), resolve));
105     break;
106   }
107 
108   case OptionValue::eTypeFileSpecList:
109     // "definition.default_uint_value" is not used for a
110     // OptionValue::eTypeFileSpecList
111     m_value_sp.reset(new OptionValueFileSpecList());
112     break;
113 
114   case OptionValue::eTypeFormat:
115     // "definition.default_uint_value" is the default format enumeration value
116     // if
117     // "definition.default_cstr_value" is NULL, otherwise interpret
118     // "definition.default_cstr_value" as a string value that represents the
119     // default
120     // value.
121     {
122       Format new_format = eFormatInvalid;
123       if (definition.default_cstr_value)
124         Args::StringToFormat(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 value
134     // if
135     // "definition.default_cstr_value" is NULL, otherwise interpret
136     // "definition.default_cstr_value" as a string value that represents the
137     // default
138     // value.
139     {
140       LanguageType new_lang = eLanguageTypeUnknown;
141       if (definition.default_cstr_value)
142         Language::GetLanguageTypeFromString(
143             llvm::StringRef(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