1 //===-- OptionValueEnumeration.cpp ----------------------------------------===//
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/OptionValueEnumeration.h"
10
11 #include "lldb/Utility/StringList.h"
12
13 using namespace lldb;
14 using namespace lldb_private;
15
OptionValueEnumeration(const OptionEnumValues & enumerators,enum_type value)16 OptionValueEnumeration::OptionValueEnumeration(
17 const OptionEnumValues &enumerators, enum_type value)
18 : OptionValue(), m_current_value(value), m_default_value(value),
19 m_enumerations() {
20 SetEnumerations(enumerators);
21 }
22
~OptionValueEnumeration()23 OptionValueEnumeration::~OptionValueEnumeration() {}
24
DumpValue(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask)25 void OptionValueEnumeration::DumpValue(const ExecutionContext *exe_ctx,
26 Stream &strm, uint32_t dump_mask) {
27 if (dump_mask & eDumpOptionType)
28 strm.Printf("(%s)", GetTypeAsCString());
29 if (dump_mask & eDumpOptionValue) {
30 if (dump_mask & eDumpOptionType)
31 strm.PutCString(" = ");
32 const size_t count = m_enumerations.GetSize();
33 for (size_t i = 0; i < count; ++i) {
34 if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) {
35 strm.PutCString(m_enumerations.GetCStringAtIndex(i).GetStringRef());
36 return;
37 }
38 }
39 strm.Printf("%" PRIu64, (uint64_t)m_current_value);
40 }
41 }
42
SetValueFromString(llvm::StringRef value,VarSetOperationType op)43 Status OptionValueEnumeration::SetValueFromString(llvm::StringRef value,
44 VarSetOperationType op) {
45 Status error;
46 switch (op) {
47 case eVarSetOperationClear:
48 Clear();
49 NotifyValueChanged();
50 break;
51
52 case eVarSetOperationReplace:
53 case eVarSetOperationAssign: {
54 ConstString const_enumerator_name(value.trim());
55 const EnumerationMapEntry *enumerator_entry =
56 m_enumerations.FindFirstValueForName(const_enumerator_name);
57 if (enumerator_entry) {
58 m_current_value = enumerator_entry->value.value;
59 NotifyValueChanged();
60 } else {
61 StreamString error_strm;
62 error_strm.Printf("invalid enumeration value '%s'", value.str().c_str());
63 const size_t count = m_enumerations.GetSize();
64 if (count) {
65 error_strm.Printf(", valid values are: %s",
66 m_enumerations.GetCStringAtIndex(0).GetCString());
67 for (size_t i = 1; i < count; ++i) {
68 error_strm.Printf(", %s",
69 m_enumerations.GetCStringAtIndex(i).GetCString());
70 }
71 }
72 error.SetErrorString(error_strm.GetString());
73 }
74 break;
75 }
76
77 case eVarSetOperationInsertBefore:
78 case eVarSetOperationInsertAfter:
79 case eVarSetOperationRemove:
80 case eVarSetOperationAppend:
81 case eVarSetOperationInvalid:
82 error = OptionValue::SetValueFromString(value, op);
83 break;
84 }
85 return error;
86 }
87
SetEnumerations(const OptionEnumValues & enumerators)88 void OptionValueEnumeration::SetEnumerations(
89 const OptionEnumValues &enumerators) {
90 m_enumerations.Clear();
91
92 for (const auto &enumerator : enumerators) {
93 ConstString const_enumerator_name(enumerator.string_value);
94 EnumeratorInfo enumerator_info = {enumerator.value, enumerator.usage};
95 m_enumerations.Append(const_enumerator_name, enumerator_info);
96 }
97
98 m_enumerations.Sort();
99 }
100
DeepCopy() const101 lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const {
102 return OptionValueSP(new OptionValueEnumeration(*this));
103 }
104
AutoComplete(CommandInterpreter & interpreter,CompletionRequest & request)105 void OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter,
106 CompletionRequest &request) {
107 const uint32_t num_enumerators = m_enumerations.GetSize();
108 if (!request.GetCursorArgumentPrefix().empty()) {
109 for (size_t i = 0; i < num_enumerators; ++i) {
110 llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef();
111 request.TryCompleteCurrentArg(name);
112 }
113 return;
114 }
115 for (size_t i = 0; i < num_enumerators; ++i)
116 request.AddCompletion(m_enumerations.GetCStringAtIndex(i).GetStringRef());
117 }
118