OptionValueEnumeration.cpp revision 360784
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
13using namespace lldb;
14using namespace lldb_private;
15
16OptionValueEnumeration::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
23OptionValueEnumeration::~OptionValueEnumeration() {}
24
25void 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
43Status 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
88void 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
101lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const {
102  return OptionValueSP(new OptionValueEnumeration(*this));
103}
104
105void 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