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