1 //===-- OptionValueEnumeration.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/OptionValueEnumeration.h" 10 11 #include "lldb/Utility/StringList.h" 12 13 using namespace lldb; 14 using namespace lldb_private; 15 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 23 OptionValueEnumeration::~OptionValueEnumeration() {} 24 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 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 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 101 lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const { 102 return OptionValueSP(new OptionValueEnumeration(*this)); 103 } 104 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