OptionValue.cpp revision 360784
1//===-- OptionValue.cpp -----------------------------------------*- 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#include "lldb/Interpreter/OptionValue.h"
10
11#include "lldb/Interpreter/OptionValues.h"
12#include "lldb/Utility/StringList.h"
13
14using namespace lldb;
15using namespace lldb_private;
16
17// Get this value as a uint64_t value if it is encoded as a boolean, uint64_t
18// or int64_t. Other types will cause "fail_value" to be returned
19uint64_t OptionValue::GetUInt64Value(uint64_t fail_value, bool *success_ptr) {
20  if (success_ptr)
21    *success_ptr = true;
22  switch (GetType()) {
23  case OptionValue::eTypeBoolean:
24    return static_cast<OptionValueBoolean *>(this)->GetCurrentValue();
25  case OptionValue::eTypeSInt64:
26    return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue();
27  case OptionValue::eTypeUInt64:
28    return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
29  default:
30    break;
31  }
32  if (success_ptr)
33    *success_ptr = false;
34  return fail_value;
35}
36
37Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx,
38                                VarSetOperationType op, llvm::StringRef name,
39                                llvm::StringRef value) {
40  Status error;
41  error.SetErrorStringWithFormat("SetSubValue is not supported");
42  return error;
43}
44
45OptionValueBoolean *OptionValue::GetAsBoolean() {
46  if (GetType() == OptionValue::eTypeBoolean)
47    return static_cast<OptionValueBoolean *>(this);
48  return nullptr;
49}
50
51const OptionValueBoolean *OptionValue::GetAsBoolean() const {
52  if (GetType() == OptionValue::eTypeBoolean)
53    return static_cast<const OptionValueBoolean *>(this);
54  return nullptr;
55}
56
57const OptionValueChar *OptionValue::GetAsChar() const {
58  if (GetType() == OptionValue::eTypeChar)
59    return static_cast<const OptionValueChar *>(this);
60  return nullptr;
61}
62
63OptionValueChar *OptionValue::GetAsChar() {
64  if (GetType() == OptionValue::eTypeChar)
65    return static_cast<OptionValueChar *>(this);
66  return nullptr;
67}
68
69OptionValueFileSpec *OptionValue::GetAsFileSpec() {
70  if (GetType() == OptionValue::eTypeFileSpec)
71    return static_cast<OptionValueFileSpec *>(this);
72  return nullptr;
73}
74
75const OptionValueFileSpec *OptionValue::GetAsFileSpec() const {
76  if (GetType() == OptionValue::eTypeFileSpec)
77    return static_cast<const OptionValueFileSpec *>(this);
78  return nullptr;
79}
80
81OptionValueFileSpecList *OptionValue::GetAsFileSpecList() {
82  if (GetType() == OptionValue::eTypeFileSpecList)
83    return static_cast<OptionValueFileSpecList *>(this);
84  return nullptr;
85}
86
87const OptionValueFileSpecList *OptionValue::GetAsFileSpecList() const {
88  if (GetType() == OptionValue::eTypeFileSpecList)
89    return static_cast<const OptionValueFileSpecList *>(this);
90  return nullptr;
91}
92
93OptionValueArch *OptionValue::GetAsArch() {
94  if (GetType() == OptionValue::eTypeArch)
95    return static_cast<OptionValueArch *>(this);
96  return nullptr;
97}
98
99const OptionValueArch *OptionValue::GetAsArch() const {
100  if (GetType() == OptionValue::eTypeArch)
101    return static_cast<const OptionValueArch *>(this);
102  return nullptr;
103}
104
105OptionValueArray *OptionValue::GetAsArray() {
106  if (GetType() == OptionValue::eTypeArray)
107    return static_cast<OptionValueArray *>(this);
108  return nullptr;
109}
110
111const OptionValueArray *OptionValue::GetAsArray() const {
112  if (GetType() == OptionValue::eTypeArray)
113    return static_cast<const OptionValueArray *>(this);
114  return nullptr;
115}
116
117OptionValueArgs *OptionValue::GetAsArgs() {
118  if (GetType() == OptionValue::eTypeArgs)
119    return static_cast<OptionValueArgs *>(this);
120  return nullptr;
121}
122
123const OptionValueArgs *OptionValue::GetAsArgs() const {
124  if (GetType() == OptionValue::eTypeArgs)
125    return static_cast<const OptionValueArgs *>(this);
126  return nullptr;
127}
128
129OptionValueDictionary *OptionValue::GetAsDictionary() {
130  if (GetType() == OptionValue::eTypeDictionary)
131    return static_cast<OptionValueDictionary *>(this);
132  return nullptr;
133}
134
135const OptionValueDictionary *OptionValue::GetAsDictionary() const {
136  if (GetType() == OptionValue::eTypeDictionary)
137    return static_cast<const OptionValueDictionary *>(this);
138  return nullptr;
139}
140
141OptionValueEnumeration *OptionValue::GetAsEnumeration() {
142  if (GetType() == OptionValue::eTypeEnum)
143    return static_cast<OptionValueEnumeration *>(this);
144  return nullptr;
145}
146
147const OptionValueEnumeration *OptionValue::GetAsEnumeration() const {
148  if (GetType() == OptionValue::eTypeEnum)
149    return static_cast<const OptionValueEnumeration *>(this);
150  return nullptr;
151}
152
153OptionValueFormat *OptionValue::GetAsFormat() {
154  if (GetType() == OptionValue::eTypeFormat)
155    return static_cast<OptionValueFormat *>(this);
156  return nullptr;
157}
158
159const OptionValueFormat *OptionValue::GetAsFormat() const {
160  if (GetType() == OptionValue::eTypeFormat)
161    return static_cast<const OptionValueFormat *>(this);
162  return nullptr;
163}
164
165OptionValueLanguage *OptionValue::GetAsLanguage() {
166  if (GetType() == OptionValue::eTypeLanguage)
167    return static_cast<OptionValueLanguage *>(this);
168  return nullptr;
169}
170
171const OptionValueLanguage *OptionValue::GetAsLanguage() const {
172  if (GetType() == OptionValue::eTypeLanguage)
173    return static_cast<const OptionValueLanguage *>(this);
174  return nullptr;
175}
176
177OptionValueFormatEntity *OptionValue::GetAsFormatEntity() {
178  if (GetType() == OptionValue::eTypeFormatEntity)
179    return static_cast<OptionValueFormatEntity *>(this);
180  return nullptr;
181}
182
183const OptionValueFormatEntity *OptionValue::GetAsFormatEntity() const {
184  if (GetType() == OptionValue::eTypeFormatEntity)
185    return static_cast<const OptionValueFormatEntity *>(this);
186  return nullptr;
187}
188
189OptionValuePathMappings *OptionValue::GetAsPathMappings() {
190  if (GetType() == OptionValue::eTypePathMap)
191    return static_cast<OptionValuePathMappings *>(this);
192  return nullptr;
193}
194
195const OptionValuePathMappings *OptionValue::GetAsPathMappings() const {
196  if (GetType() == OptionValue::eTypePathMap)
197    return static_cast<const OptionValuePathMappings *>(this);
198  return nullptr;
199}
200
201OptionValueProperties *OptionValue::GetAsProperties() {
202  if (GetType() == OptionValue::eTypeProperties)
203    return static_cast<OptionValueProperties *>(this);
204  return nullptr;
205}
206
207const OptionValueProperties *OptionValue::GetAsProperties() const {
208  if (GetType() == OptionValue::eTypeProperties)
209    return static_cast<const OptionValueProperties *>(this);
210  return nullptr;
211}
212
213OptionValueRegex *OptionValue::GetAsRegex() {
214  if (GetType() == OptionValue::eTypeRegex)
215    return static_cast<OptionValueRegex *>(this);
216  return nullptr;
217}
218
219const OptionValueRegex *OptionValue::GetAsRegex() const {
220  if (GetType() == OptionValue::eTypeRegex)
221    return static_cast<const OptionValueRegex *>(this);
222  return nullptr;
223}
224
225OptionValueSInt64 *OptionValue::GetAsSInt64() {
226  if (GetType() == OptionValue::eTypeSInt64)
227    return static_cast<OptionValueSInt64 *>(this);
228  return nullptr;
229}
230
231const OptionValueSInt64 *OptionValue::GetAsSInt64() const {
232  if (GetType() == OptionValue::eTypeSInt64)
233    return static_cast<const OptionValueSInt64 *>(this);
234  return nullptr;
235}
236
237OptionValueString *OptionValue::GetAsString() {
238  if (GetType() == OptionValue::eTypeString)
239    return static_cast<OptionValueString *>(this);
240  return nullptr;
241}
242
243const OptionValueString *OptionValue::GetAsString() const {
244  if (GetType() == OptionValue::eTypeString)
245    return static_cast<const OptionValueString *>(this);
246  return nullptr;
247}
248
249OptionValueUInt64 *OptionValue::GetAsUInt64() {
250  if (GetType() == OptionValue::eTypeUInt64)
251    return static_cast<OptionValueUInt64 *>(this);
252  return nullptr;
253}
254
255const OptionValueUInt64 *OptionValue::GetAsUInt64() const {
256  if (GetType() == OptionValue::eTypeUInt64)
257    return static_cast<const OptionValueUInt64 *>(this);
258  return nullptr;
259}
260
261OptionValueUUID *OptionValue::GetAsUUID() {
262  if (GetType() == OptionValue::eTypeUUID)
263    return static_cast<OptionValueUUID *>(this);
264  return nullptr;
265}
266
267const OptionValueUUID *OptionValue::GetAsUUID() const {
268  if (GetType() == OptionValue::eTypeUUID)
269    return static_cast<const OptionValueUUID *>(this);
270  return nullptr;
271}
272
273bool OptionValue::GetBooleanValue(bool fail_value) const {
274  const OptionValueBoolean *option_value = GetAsBoolean();
275  if (option_value)
276    return option_value->GetCurrentValue();
277  return fail_value;
278}
279
280bool OptionValue::SetBooleanValue(bool new_value) {
281  OptionValueBoolean *option_value = GetAsBoolean();
282  if (option_value) {
283    option_value->SetCurrentValue(new_value);
284    return true;
285  }
286  return false;
287}
288
289char OptionValue::GetCharValue(char fail_value) const {
290  const OptionValueChar *option_value = GetAsChar();
291  if (option_value)
292    return option_value->GetCurrentValue();
293  return fail_value;
294}
295
296char OptionValue::SetCharValue(char new_value) {
297  OptionValueChar *option_value = GetAsChar();
298  if (option_value) {
299    option_value->SetCurrentValue(new_value);
300    return true;
301  }
302  return false;
303}
304
305int64_t OptionValue::GetEnumerationValue(int64_t fail_value) const {
306  const OptionValueEnumeration *option_value = GetAsEnumeration();
307  if (option_value)
308    return option_value->GetCurrentValue();
309  return fail_value;
310}
311
312bool OptionValue::SetEnumerationValue(int64_t value) {
313  OptionValueEnumeration *option_value = GetAsEnumeration();
314  if (option_value) {
315    option_value->SetCurrentValue(value);
316    return true;
317  }
318  return false;
319}
320
321FileSpec OptionValue::GetFileSpecValue() const {
322  const OptionValueFileSpec *option_value = GetAsFileSpec();
323  if (option_value)
324    return option_value->GetCurrentValue();
325  return FileSpec();
326}
327
328bool OptionValue::SetFileSpecValue(const FileSpec &file_spec) {
329  OptionValueFileSpec *option_value = GetAsFileSpec();
330  if (option_value) {
331    option_value->SetCurrentValue(file_spec, false);
332    return true;
333  }
334  return false;
335}
336
337FileSpecList OptionValue::GetFileSpecListValue() const {
338  const OptionValueFileSpecList *option_value = GetAsFileSpecList();
339  if (option_value)
340    return option_value->GetCurrentValue();
341  return FileSpecList();
342}
343
344lldb::Format OptionValue::GetFormatValue(lldb::Format fail_value) const {
345  const OptionValueFormat *option_value = GetAsFormat();
346  if (option_value)
347    return option_value->GetCurrentValue();
348  return fail_value;
349}
350
351bool OptionValue::SetFormatValue(lldb::Format new_value) {
352  OptionValueFormat *option_value = GetAsFormat();
353  if (option_value) {
354    option_value->SetCurrentValue(new_value);
355    return true;
356  }
357  return false;
358}
359
360lldb::LanguageType
361OptionValue::GetLanguageValue(lldb::LanguageType fail_value) const {
362  const OptionValueLanguage *option_value = GetAsLanguage();
363  if (option_value)
364    return option_value->GetCurrentValue();
365  return fail_value;
366}
367
368bool OptionValue::SetLanguageValue(lldb::LanguageType new_language) {
369  OptionValueLanguage *option_value = GetAsLanguage();
370  if (option_value) {
371    option_value->SetCurrentValue(new_language);
372    return true;
373  }
374  return false;
375}
376
377const FormatEntity::Entry *OptionValue::GetFormatEntity() const {
378  const OptionValueFormatEntity *option_value = GetAsFormatEntity();
379  if (option_value)
380    return &option_value->GetCurrentValue();
381  return nullptr;
382}
383
384const RegularExpression *OptionValue::GetRegexValue() const {
385  const OptionValueRegex *option_value = GetAsRegex();
386  if (option_value)
387    return option_value->GetCurrentValue();
388  return nullptr;
389}
390
391int64_t OptionValue::GetSInt64Value(int64_t fail_value) const {
392  const OptionValueSInt64 *option_value = GetAsSInt64();
393  if (option_value)
394    return option_value->GetCurrentValue();
395  return fail_value;
396}
397
398bool OptionValue::SetSInt64Value(int64_t new_value) {
399  OptionValueSInt64 *option_value = GetAsSInt64();
400  if (option_value) {
401    option_value->SetCurrentValue(new_value);
402    return true;
403  }
404  return false;
405}
406
407llvm::StringRef OptionValue::GetStringValue(llvm::StringRef fail_value) const {
408  const OptionValueString *option_value = GetAsString();
409  if (option_value)
410    return option_value->GetCurrentValueAsRef();
411  return fail_value;
412}
413
414bool OptionValue::SetStringValue(llvm::StringRef new_value) {
415  OptionValueString *option_value = GetAsString();
416  if (option_value) {
417    option_value->SetCurrentValue(new_value);
418    return true;
419  }
420  return false;
421}
422
423uint64_t OptionValue::GetUInt64Value(uint64_t fail_value) const {
424  const OptionValueUInt64 *option_value = GetAsUInt64();
425  if (option_value)
426    return option_value->GetCurrentValue();
427  return fail_value;
428}
429
430bool OptionValue::SetUInt64Value(uint64_t new_value) {
431  OptionValueUInt64 *option_value = GetAsUInt64();
432  if (option_value) {
433    option_value->SetCurrentValue(new_value);
434    return true;
435  }
436  return false;
437}
438
439UUID OptionValue::GetUUIDValue() const {
440  const OptionValueUUID *option_value = GetAsUUID();
441  if (option_value)
442    return option_value->GetCurrentValue();
443  return UUID();
444}
445
446bool OptionValue::SetUUIDValue(const UUID &uuid) {
447  OptionValueUUID *option_value = GetAsUUID();
448  if (option_value) {
449    option_value->SetCurrentValue(uuid);
450    return true;
451  }
452  return false;
453}
454
455const char *OptionValue::GetBuiltinTypeAsCString(Type t) {
456  switch (t) {
457  case eTypeInvalid:
458    return "invalid";
459  case eTypeArch:
460    return "arch";
461  case eTypeArgs:
462    return "arguments";
463  case eTypeArray:
464    return "array";
465  case eTypeBoolean:
466    return "boolean";
467  case eTypeChar:
468    return "char";
469  case eTypeDictionary:
470    return "dictionary";
471  case eTypeEnum:
472    return "enum";
473  case eTypeFileSpec:
474    return "file";
475  case eTypeFileSpecList:
476    return "file-list";
477  case eTypeFormat:
478    return "format";
479  case eTypeFormatEntity:
480    return "format-string";
481  case eTypeLanguage:
482    return "language";
483  case eTypePathMap:
484    return "path-map";
485  case eTypeProperties:
486    return "properties";
487  case eTypeRegex:
488    return "regex";
489  case eTypeSInt64:
490    return "int";
491  case eTypeString:
492    return "string";
493  case eTypeUInt64:
494    return "unsigned";
495  case eTypeUUID:
496    return "uuid";
497  }
498  return nullptr;
499}
500
501lldb::OptionValueSP OptionValue::CreateValueFromCStringForTypeMask(
502    const char *value_cstr, uint32_t type_mask, Status &error) {
503  // If only 1 bit is set in the type mask for a dictionary or array then we
504  // know how to decode a value from a cstring
505  lldb::OptionValueSP value_sp;
506  switch (type_mask) {
507  case 1u << eTypeArch:
508    value_sp.reset(new OptionValueArch());
509    break;
510  case 1u << eTypeBoolean:
511    value_sp.reset(new OptionValueBoolean(false));
512    break;
513  case 1u << eTypeChar:
514    value_sp.reset(new OptionValueChar('\0'));
515    break;
516  case 1u << eTypeFileSpec:
517    value_sp.reset(new OptionValueFileSpec());
518    break;
519  case 1u << eTypeFormat:
520    value_sp.reset(new OptionValueFormat(eFormatInvalid));
521    break;
522  case 1u << eTypeFormatEntity:
523    value_sp.reset(new OptionValueFormatEntity(nullptr));
524    break;
525  case 1u << eTypeLanguage:
526    value_sp.reset(new OptionValueLanguage(eLanguageTypeUnknown));
527    break;
528  case 1u << eTypeSInt64:
529    value_sp.reset(new OptionValueSInt64());
530    break;
531  case 1u << eTypeString:
532    value_sp.reset(new OptionValueString());
533    break;
534  case 1u << eTypeUInt64:
535    value_sp.reset(new OptionValueUInt64());
536    break;
537  case 1u << eTypeUUID:
538    value_sp.reset(new OptionValueUUID());
539    break;
540  }
541
542  if (value_sp)
543    error = value_sp->SetValueFromString(
544        llvm::StringRef::withNullAsEmpty(value_cstr), eVarSetOperationAssign);
545  else
546    error.SetErrorString("unsupported type mask");
547  return value_sp;
548}
549
550bool OptionValue::DumpQualifiedName(Stream &strm) const {
551  bool dumped_something = false;
552  lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
553  if (m_parent_sp) {
554    if (m_parent_sp->DumpQualifiedName(strm))
555      dumped_something = true;
556  }
557  ConstString name(GetName());
558  if (name) {
559    if (dumped_something)
560      strm.PutChar('.');
561    else
562      dumped_something = true;
563    strm << name;
564  }
565  return dumped_something;
566}
567
568void OptionValue::AutoComplete(CommandInterpreter &interpreter,
569                               CompletionRequest &request) {}
570
571Status OptionValue::SetValueFromString(llvm::StringRef value,
572                                       VarSetOperationType op) {
573  Status error;
574  switch (op) {
575  case eVarSetOperationReplace:
576    error.SetErrorStringWithFormat(
577        "%s objects do not support the 'replace' operation",
578        GetTypeAsCString());
579    break;
580  case eVarSetOperationInsertBefore:
581    error.SetErrorStringWithFormat(
582        "%s objects do not support the 'insert-before' operation",
583        GetTypeAsCString());
584    break;
585  case eVarSetOperationInsertAfter:
586    error.SetErrorStringWithFormat(
587        "%s objects do not support the 'insert-after' operation",
588        GetTypeAsCString());
589    break;
590  case eVarSetOperationRemove:
591    error.SetErrorStringWithFormat(
592        "%s objects do not support the 'remove' operation", GetTypeAsCString());
593    break;
594  case eVarSetOperationAppend:
595    error.SetErrorStringWithFormat(
596        "%s objects do not support the 'append' operation", GetTypeAsCString());
597    break;
598  case eVarSetOperationClear:
599    error.SetErrorStringWithFormat(
600        "%s objects do not support the 'clear' operation", GetTypeAsCString());
601    break;
602  case eVarSetOperationAssign:
603    error.SetErrorStringWithFormat(
604        "%s objects do not support the 'assign' operation", GetTypeAsCString());
605    break;
606  case eVarSetOperationInvalid:
607    error.SetErrorStringWithFormat("invalid operation performed on a %s object",
608                                   GetTypeAsCString());
609    break;
610  }
611  return error;
612}
613