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