Property.cpp revision 341825
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
23using namespace lldb;
24using namespace lldb_private;
25
26Property::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
217Property::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
222bool 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
232void 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
257void 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
288void Property::SetValueChangedCallback(OptionValueChangedCallback callback,
289                                       void *baton) {
290  if (m_value_sp)
291    m_value_sp->SetValueChangedCallback(callback, baton);
292}
293