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