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 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/StringList.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 OptionValueEnumeration::OptionValueEnumeration (const OptionEnumValueElement *enumerators,
22                                                 enum_type value) :
23     OptionValue(),
24     m_current_value (value),
25     m_default_value (value),
26     m_enumerations ()
27 {
28     SetEnumerations(enumerators);
29 }
30 
31 OptionValueEnumeration::~OptionValueEnumeration()
32 {
33 }
34 
35 void
36 OptionValueEnumeration::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
37 {
38     if (dump_mask & eDumpOptionType)
39         strm.Printf ("(%s)", GetTypeAsCString ());
40     if (dump_mask & eDumpOptionValue)
41     {
42         if (dump_mask & eDumpOptionType)
43             strm.PutCString (" = ");
44         const size_t count = m_enumerations.GetSize ();
45         for (size_t i=0; i<count; ++i)
46         {
47             if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value)
48             {
49                 strm.PutCString(m_enumerations.GetCStringAtIndex(i));
50                 return;
51             }
52         }
53         strm.Printf("%" PRIu64, (uint64_t)m_current_value);
54     }
55 }
56 
57 Error
58 OptionValueEnumeration::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
59 {
60     Error error;
61     switch (op)
62     {
63         case eVarSetOperationClear:
64             Clear ();
65             NotifyValueChanged();
66             break;
67 
68         case eVarSetOperationReplace:
69         case eVarSetOperationAssign:
70             {
71                 ConstString const_enumerator_name(value.trim());
72                 const EnumerationMapEntry *enumerator_entry = m_enumerations.FindFirstValueForName (const_enumerator_name.GetCString());
73                 if (enumerator_entry)
74                 {
75                     m_current_value = enumerator_entry->value.value;
76                     NotifyValueChanged();
77                 }
78                 else
79                 {
80                     StreamString error_strm;
81                     error_strm.Printf("invalid enumeration value '%s'", value.str().c_str());
82                     const size_t count = m_enumerations.GetSize ();
83                     if (count)
84                     {
85                         error_strm.Printf(", valid values are: %s", m_enumerations.GetCStringAtIndex(0));
86                         for (size_t i=1; i<count; ++i)
87                         {
88                             error_strm.Printf (", %s", m_enumerations.GetCStringAtIndex(i));
89                         }
90                     }
91                     error.SetErrorString(error_strm.GetData());
92                 }
93                 break;
94             }
95 
96         case eVarSetOperationInsertBefore:
97         case eVarSetOperationInsertAfter:
98         case eVarSetOperationRemove:
99         case eVarSetOperationAppend:
100         case eVarSetOperationInvalid:
101             error = OptionValue::SetValueFromString (value, op);
102             break;
103     }
104     return error;
105 }
106 
107 void
108 OptionValueEnumeration::SetEnumerations (const OptionEnumValueElement *enumerators)
109 {
110     m_enumerations.Clear();
111     if (enumerators)
112     {
113         for (size_t i=0; enumerators[i].string_value != nullptr; ++i)
114         {
115             ConstString const_enumerator_name(enumerators[i].string_value);
116             EnumeratorInfo enumerator_info = { enumerators[i].value, enumerators[i].usage };
117             m_enumerations.Append (const_enumerator_name.GetCString(), enumerator_info);
118         }
119         m_enumerations.Sort();
120     }
121 }
122 
123 
124 lldb::OptionValueSP
125 OptionValueEnumeration::DeepCopy () const
126 {
127     return OptionValueSP(new OptionValueEnumeration(*this));
128 }
129 
130 size_t
131 OptionValueEnumeration::AutoComplete (CommandInterpreter &interpreter,
132                                       const char *s,
133                                       int match_start_point,
134                                       int max_return_elements,
135                                       bool &word_complete,
136                                       StringList &matches)
137 {
138     word_complete = false;
139     matches.Clear();
140 
141     const uint32_t num_enumerators = m_enumerations.GetSize();
142     if (s && s[0])
143     {
144         const size_t s_len = strlen(s);
145         for (size_t i=0; i<num_enumerators; ++i)
146         {
147             const char *name = m_enumerations.GetCStringAtIndex(i);
148             if (::strncmp(s, name, s_len) == 0)
149                 matches.AppendString(name);
150         }
151     }
152     else
153     {
154         // only suggest "true" or "false" by default
155         for (size_t i=0; i<num_enumerators; ++i)
156             matches.AppendString(m_enumerations.GetCStringAtIndex(i));
157     }
158     return matches.GetSize();
159 }
160 
161 
162 
163 
164