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