1 //===-- OptionValue.h -------------------------------------------*- 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 #ifndef liblldb_OptionValue_h_
11 #define liblldb_OptionValue_h_
12 
13 #include "lldb/Core/FormatEntity.h"
14 #include "lldb/Utility/CompletionRequest.h"
15 #include "lldb/Utility/ConstString.h"
16 #include "lldb/Utility/Status.h"
17 #include "lldb/lldb-defines.h"
18 #include "lldb/lldb-private-enumerations.h"
19 #include "lldb/lldb-private-interfaces.h"
20 
21 namespace lldb_private {
22 
23 //---------------------------------------------------------------------
24 // OptionValue
25 //---------------------------------------------------------------------
26 class OptionValue {
27 public:
28   typedef enum {
29     eTypeInvalid = 0,
30     eTypeArch,
31     eTypeArgs,
32     eTypeArray,
33     eTypeBoolean,
34     eTypeChar,
35     eTypeDictionary,
36     eTypeEnum,
37     eTypeFileSpec,
38     eTypeFileSpecList,
39     eTypeFormat,
40     eTypeLanguage,
41     eTypePathMap,
42     eTypeProperties,
43     eTypeRegex,
44     eTypeSInt64,
45     eTypeString,
46     eTypeUInt64,
47     eTypeUUID,
48     eTypeFormatEntity
49   } Type;
50 
51   enum {
52     eDumpOptionName = (1u << 0),
53     eDumpOptionType = (1u << 1),
54     eDumpOptionValue = (1u << 2),
55     eDumpOptionDescription = (1u << 3),
56     eDumpOptionRaw = (1u << 4),
57     eDumpOptionCommand = (1u << 5),
58     eDumpGroupValue = (eDumpOptionName | eDumpOptionType | eDumpOptionValue),
59     eDumpGroupHelp =
60         (eDumpOptionName | eDumpOptionType | eDumpOptionDescription),
61     eDumpGroupExport = (eDumpOptionCommand | eDumpOptionName | eDumpOptionValue)
62   };
63 
OptionValue()64   OptionValue()
65       : m_callback(nullptr), m_baton(nullptr), m_value_was_set(false) {}
66 
OptionValue(const OptionValue & rhs)67   OptionValue(const OptionValue &rhs)
68       : m_callback(rhs.m_callback), m_baton(rhs.m_baton),
69         m_value_was_set(rhs.m_value_was_set) {}
70 
71   virtual ~OptionValue() = default;
72 
73   //-----------------------------------------------------------------
74   // Subclasses should override these functions
75   //-----------------------------------------------------------------
76   virtual Type GetType() const = 0;
77 
78   // If this value is always hidden, the avoid showing any info on this value,
79   // just show the info for the child values.
ValueIsTransparent()80   virtual bool ValueIsTransparent() const {
81     return GetType() == eTypeProperties;
82   }
83 
GetTypeAsCString()84   virtual const char *GetTypeAsCString() const {
85     return GetBuiltinTypeAsCString(GetType());
86   }
87 
88   static const char *GetBuiltinTypeAsCString(Type t);
89 
90   virtual void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
91                          uint32_t dump_mask) = 0;
92 
93   virtual Status
94   SetValueFromString(llvm::StringRef value,
95                      VarSetOperationType op = eVarSetOperationAssign);
96 
97   virtual bool Clear() = 0;
98 
99   virtual lldb::OptionValueSP DeepCopy() const = 0;
100 
101   virtual size_t AutoComplete(CommandInterpreter &interpreter,
102                               CompletionRequest &request);
103 
104   //-----------------------------------------------------------------
105   // Subclasses can override these functions
106   //-----------------------------------------------------------------
GetSubValue(const ExecutionContext * exe_ctx,llvm::StringRef name,bool will_modify,Status & error)107   virtual lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx,
108                                           llvm::StringRef name,
109                                           bool will_modify,
110                                           Status &error) const {
111     error.SetErrorStringWithFormat("'%s' is not a value subvalue", name.str().c_str());
112     return lldb::OptionValueSP();
113   }
114 
115   virtual Status SetSubValue(const ExecutionContext *exe_ctx,
116                              VarSetOperationType op, llvm::StringRef name,
117                              llvm::StringRef value);
118 
IsAggregateValue()119   virtual bool IsAggregateValue() const { return false; }
120 
GetName()121   virtual ConstString GetName() const { return ConstString(); }
122 
123   virtual bool DumpQualifiedName(Stream &strm) const;
124 
125   //-----------------------------------------------------------------
126   // Subclasses should NOT override these functions as they use the above
127   // functions to implement functionality
128   //-----------------------------------------------------------------
GetTypeAsMask()129   uint32_t GetTypeAsMask() { return 1u << GetType(); }
130 
ConvertTypeToMask(OptionValue::Type type)131   static uint32_t ConvertTypeToMask(OptionValue::Type type) {
132     return 1u << type;
133   }
134 
ConvertTypeMaskToType(uint32_t type_mask)135   static OptionValue::Type ConvertTypeMaskToType(uint32_t type_mask) {
136     // If only one bit is set, then return an appropriate enumeration
137     switch (type_mask) {
138     case 1u << eTypeArch:
139       return eTypeArch;
140     case 1u << eTypeArgs:
141       return eTypeArgs;
142     case 1u << eTypeArray:
143       return eTypeArray;
144     case 1u << eTypeBoolean:
145       return eTypeBoolean;
146     case 1u << eTypeChar:
147       return eTypeChar;
148     case 1u << eTypeDictionary:
149       return eTypeDictionary;
150     case 1u << eTypeEnum:
151       return eTypeEnum;
152     case 1u << eTypeFileSpec:
153       return eTypeFileSpec;
154     case 1u << eTypeFileSpecList:
155       return eTypeFileSpecList;
156     case 1u << eTypeFormat:
157       return eTypeFormat;
158     case 1u << eTypeLanguage:
159       return eTypeLanguage;
160     case 1u << eTypePathMap:
161       return eTypePathMap;
162     case 1u << eTypeProperties:
163       return eTypeProperties;
164     case 1u << eTypeRegex:
165       return eTypeRegex;
166     case 1u << eTypeSInt64:
167       return eTypeSInt64;
168     case 1u << eTypeString:
169       return eTypeString;
170     case 1u << eTypeUInt64:
171       return eTypeUInt64;
172     case 1u << eTypeUUID:
173       return eTypeUUID;
174     }
175     // Else return invalid
176     return eTypeInvalid;
177   }
178 
179   static lldb::OptionValueSP
180   CreateValueFromCStringForTypeMask(const char *value_cstr, uint32_t type_mask,
181                                     Status &error);
182 
183   // Get this value as a uint64_t value if it is encoded as a boolean, uint64_t
184   // or int64_t. Other types will cause "fail_value" to be returned
185   uint64_t GetUInt64Value(uint64_t fail_value, bool *success_ptr);
186 
187   OptionValueArch *GetAsArch();
188 
189   const OptionValueArch *GetAsArch() const;
190 
191   OptionValueArray *GetAsArray();
192 
193   const OptionValueArray *GetAsArray() const;
194 
195   OptionValueArgs *GetAsArgs();
196 
197   const OptionValueArgs *GetAsArgs() const;
198 
199   OptionValueBoolean *GetAsBoolean();
200 
201   OptionValueChar *GetAsChar();
202 
203   const OptionValueBoolean *GetAsBoolean() const;
204 
205   const OptionValueChar *GetAsChar() const;
206 
207   OptionValueDictionary *GetAsDictionary();
208 
209   const OptionValueDictionary *GetAsDictionary() const;
210 
211   OptionValueEnumeration *GetAsEnumeration();
212 
213   const OptionValueEnumeration *GetAsEnumeration() const;
214 
215   OptionValueFileSpec *GetAsFileSpec();
216 
217   const OptionValueFileSpec *GetAsFileSpec() const;
218 
219   OptionValueFileSpecList *GetAsFileSpecList();
220 
221   const OptionValueFileSpecList *GetAsFileSpecList() const;
222 
223   OptionValueFormat *GetAsFormat();
224 
225   const OptionValueFormat *GetAsFormat() const;
226 
227   OptionValueLanguage *GetAsLanguage();
228 
229   const OptionValueLanguage *GetAsLanguage() const;
230 
231   OptionValuePathMappings *GetAsPathMappings();
232 
233   const OptionValuePathMappings *GetAsPathMappings() const;
234 
235   OptionValueProperties *GetAsProperties();
236 
237   const OptionValueProperties *GetAsProperties() const;
238 
239   OptionValueRegex *GetAsRegex();
240 
241   const OptionValueRegex *GetAsRegex() const;
242 
243   OptionValueSInt64 *GetAsSInt64();
244 
245   const OptionValueSInt64 *GetAsSInt64() const;
246 
247   OptionValueString *GetAsString();
248 
249   const OptionValueString *GetAsString() const;
250 
251   OptionValueUInt64 *GetAsUInt64();
252 
253   const OptionValueUInt64 *GetAsUInt64() const;
254 
255   OptionValueUUID *GetAsUUID();
256 
257   const OptionValueUUID *GetAsUUID() const;
258 
259   OptionValueFormatEntity *GetAsFormatEntity();
260 
261   const OptionValueFormatEntity *GetAsFormatEntity() const;
262 
263   bool GetBooleanValue(bool fail_value = false) const;
264 
265   bool SetBooleanValue(bool new_value);
266 
267   char GetCharValue(char fail_value) const;
268 
269   char SetCharValue(char new_value);
270 
271   int64_t GetEnumerationValue(int64_t fail_value = -1) const;
272 
273   bool SetEnumerationValue(int64_t value);
274 
275   FileSpec GetFileSpecValue() const;
276 
277   bool SetFileSpecValue(const FileSpec &file_spec);
278 
279   FileSpecList GetFileSpecListValue() const;
280 
281   lldb::Format
282   GetFormatValue(lldb::Format fail_value = lldb::eFormatDefault) const;
283 
284   bool SetFormatValue(lldb::Format new_value);
285 
286   lldb::LanguageType GetLanguageValue(
287       lldb::LanguageType fail_value = lldb::eLanguageTypeUnknown) const;
288 
289   bool SetLanguageValue(lldb::LanguageType new_language);
290 
291   const FormatEntity::Entry *GetFormatEntity() const;
292 
293   const RegularExpression *GetRegexValue() const;
294 
295   int64_t GetSInt64Value(int64_t fail_value = 0) const;
296 
297   bool SetSInt64Value(int64_t new_value);
298 
299   llvm::StringRef GetStringValue(llvm::StringRef fail_value) const;
GetStringValue()300   llvm::StringRef GetStringValue() const { return GetStringValue(llvm::StringRef()); }
301 
302   bool SetStringValue(llvm::StringRef new_value);
303 
304   uint64_t GetUInt64Value(uint64_t fail_value = 0) const;
305 
306   bool SetUInt64Value(uint64_t new_value);
307 
308   UUID GetUUIDValue() const;
309 
310   bool SetUUIDValue(const UUID &uuid);
311 
OptionWasSet()312   bool OptionWasSet() const { return m_value_was_set; }
313 
SetOptionWasSet()314   void SetOptionWasSet() { m_value_was_set = true; }
315 
SetParent(const lldb::OptionValueSP & parent_sp)316   void SetParent(const lldb::OptionValueSP &parent_sp) {
317     m_parent_wp = parent_sp;
318   }
319 
SetValueChangedCallback(OptionValueChangedCallback callback,void * baton)320   void SetValueChangedCallback(OptionValueChangedCallback callback,
321                                void *baton) {
322     assert(m_callback == nullptr);
323     m_callback = callback;
324     m_baton = baton;
325   }
326 
NotifyValueChanged()327   void NotifyValueChanged() {
328     if (m_callback)
329       m_callback(m_baton, this);
330   }
331 
332 protected:
333   lldb::OptionValueWP m_parent_wp;
334   OptionValueChangedCallback m_callback;
335   void *m_baton;
336   bool m_value_was_set; // This can be used to see if a value has been set
337                         // by a call to SetValueFromCString(). It is often
338                         // handy to know if an option value was set from the
339                         // command line or as a setting, versus if we just have
340                         // the default value that was already populated in the
341                         // option value.
342 };
343 
344 } // namespace lldb_private
345 
346 #endif // liblldb_OptionValue_h_
347