1 //===-- OptionValuePathMappings.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/OptionValuePathMappings.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Stream.h"
17 #include "lldb/Interpreter/Args.h"
18
19 using namespace lldb;
20 using namespace lldb_private;
21
22 void
DumpValue(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask)23 OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
24 {
25 if (dump_mask & eDumpOptionType)
26 strm.Printf ("(%s)", GetTypeAsCString ());
27 if (dump_mask & eDumpOptionValue)
28 {
29 if (dump_mask & eDumpOptionType)
30 strm.Printf (" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : "");
31 m_path_mappings.Dump(&strm);
32 }
33 }
34
35 Error
SetValueFromCString(const char * value,VarSetOperationType op)36 OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperationType op)
37 {
38 Error error;
39 Args args(value);
40 const size_t argc = args.GetArgumentCount();
41
42 switch (op)
43 {
44 case eVarSetOperationClear:
45 Clear ();
46 break;
47
48 case eVarSetOperationReplace:
49 // Must be at least one index + 1 pair of paths, and the pair count must be even
50 if (argc >= 3 && (((argc - 1) & 1) == 0))
51 {
52 uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
53 const uint32_t count = m_path_mappings.GetSize();
54 if (idx > count)
55 {
56 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
57 }
58 else
59 {
60 for (size_t i=1; i<argc; i += 2, ++idx)
61 {
62 ConstString a(args.GetArgumentAtIndex(i));
63 ConstString b(args.GetArgumentAtIndex(i+1));
64 if (!m_path_mappings.Replace (a, b, idx, m_notify_changes))
65 m_path_mappings.Append(a, b, m_notify_changes);
66 }
67 }
68 }
69 else
70 {
71 error.SetErrorString("replace operation takes an array index followed by one or more path pairs");
72 }
73 break;
74
75
76
77 case eVarSetOperationAssign:
78 if (argc < 2 || (argc & 1))
79 {
80 error.SetErrorString("assign operation takes one or more path pairs");
81 break;
82 }
83 m_path_mappings.Clear(m_notify_changes);
84 // Fall through to append case
85 case eVarSetOperationAppend:
86 if (argc < 2 || (argc & 1))
87 {
88 error.SetErrorString("append operation takes one or more path pairs");
89 break;
90 }
91 else
92 {
93 for (size_t i=0; i<argc; i += 2)
94 {
95 ConstString a(args.GetArgumentAtIndex(i));
96 ConstString b(args.GetArgumentAtIndex(i+1));
97 m_path_mappings.Append(a, b, m_notify_changes);
98 m_value_was_set = true;
99 }
100 }
101 break;
102
103 case eVarSetOperationInsertBefore:
104 case eVarSetOperationInsertAfter:
105 // Must be at least one index + 1 pair of paths, and the pair count must be even
106 if (argc >= 3 && (((argc - 1) & 1) == 0))
107 {
108 uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
109 const uint32_t count = m_path_mappings.GetSize();
110 if (idx > count)
111 {
112 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
113 }
114 else
115 {
116 if (op == eVarSetOperationInsertAfter)
117 ++idx;
118 for (size_t i=1; i<argc; i += 2, ++idx)
119 {
120 ConstString a(args.GetArgumentAtIndex(i));
121 ConstString b(args.GetArgumentAtIndex(i+1));
122 m_path_mappings.Insert (a, b, idx, m_notify_changes);
123 }
124 }
125 }
126 else
127 {
128 error.SetErrorString("insert operation takes an array index followed by one or more path pairs");
129 }
130 break;
131
132 case eVarSetOperationRemove:
133 if (argc > 0)
134 {
135 std::vector<int> remove_indexes;
136 bool all_indexes_valid = true;
137 size_t i;
138 for (i=0; all_indexes_valid && i<argc; ++i)
139 {
140 const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
141 if (idx == INT32_MAX)
142 all_indexes_valid = false;
143 else
144 remove_indexes.push_back(idx);
145 }
146
147 if (all_indexes_valid)
148 {
149 size_t num_remove_indexes = remove_indexes.size();
150 if (num_remove_indexes)
151 {
152 // Sort and then erase in reverse so indexes are always valid
153 std::sort(remove_indexes.begin(), remove_indexes.end());
154 for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j)
155 {
156 m_path_mappings.Remove (j, m_notify_changes);
157 }
158 }
159 }
160 else
161 {
162 error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
163 }
164 }
165 else
166 {
167 error.SetErrorString("remove operation takes one or more array index");
168 }
169 break;
170
171 case eVarSetOperationInvalid:
172 error = OptionValue::SetValueFromCString (value, op);
173 break;
174 }
175 return error;
176
177 m_value_was_set = true;
178 return Error();
179 }
180
181 lldb::OptionValueSP
DeepCopy() const182 OptionValuePathMappings::DeepCopy () const
183 {
184 return OptionValueSP(new OptionValuePathMappings(*this));
185 }
186