blob: f3f146f1f8c628c07714a3f3c3b259b56278306a [file] [log] [blame]
Greg Clayton67cc0632012-08-22 17:17:09 +00001//===-- 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"
Greg Clayton6a311642016-07-08 23:06:38 +000017#include "lldb/Host/FileSpec.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000018#include "lldb/Host/StringConvert.h"
Greg Clayton67cc0632012-08-22 17:17:09 +000019#include "lldb/Interpreter/Args.h"
20
21using namespace lldb;
22using namespace lldb_private;
Greg Clayton6a311642016-07-08 23:06:38 +000023namespace
24{
25 static bool
26 VerifyPathExists(const char *path)
27 {
28 if (path && path[0])
29 return FileSpec(path, false).Exists();
30 else
31 return false;
32 }
33}
34
Greg Clayton67cc0632012-08-22 17:17:09 +000035
36void
37OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
38{
39 if (dump_mask & eDumpOptionType)
40 strm.Printf ("(%s)", GetTypeAsCString ());
41 if (dump_mask & eDumpOptionValue)
42 {
43 if (dump_mask & eDumpOptionType)
44 strm.Printf (" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : "");
45 m_path_mappings.Dump(&strm);
46 }
47}
48
49Error
Pavel Labathc95f7e22015-02-20 11:14:59 +000050OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
Greg Clayton67cc0632012-08-22 17:17:09 +000051{
52 Error error;
Pavel Labathc95f7e22015-02-20 11:14:59 +000053 Args args(value.str().c_str());
Greg Clayton67cc0632012-08-22 17:17:09 +000054 const size_t argc = args.GetArgumentCount();
55
56 switch (op)
57 {
58 case eVarSetOperationClear:
59 Clear ();
Greg Clayton332e8b12015-01-13 21:13:08 +000060 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +000061 break;
62
63 case eVarSetOperationReplace:
64 // Must be at least one index + 1 pair of paths, and the pair count must be even
65 if (argc >= 3 && (((argc - 1) & 1) == 0))
66 {
Vince Harron5275aaa2015-01-15 20:08:35 +000067 uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
Greg Clayton67cc0632012-08-22 17:17:09 +000068 const uint32_t count = m_path_mappings.GetSize();
69 if (idx > count)
70 {
71 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
72 }
73 else
74 {
Greg Clayton6a311642016-07-08 23:06:38 +000075 bool changed = false;
Greg Clayton67cc0632012-08-22 17:17:09 +000076 for (size_t i=1; i<argc; i += 2, ++idx)
77 {
Greg Clayton6a311642016-07-08 23:06:38 +000078 const char *orginal_path = args.GetArgumentAtIndex(i);
79 const char *replace_path = args.GetArgumentAtIndex(i+1);
80 if (VerifyPathExists(replace_path))
81 {
82 ConstString a(orginal_path);
83 ConstString b(replace_path);
84 if (!m_path_mappings.Replace (a, b, idx, m_notify_changes))
85 m_path_mappings.Append(a, b, m_notify_changes);
86 changed = true;
87 }
88 else
89 {
90 error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
91 break;
92 }
Greg Clayton67cc0632012-08-22 17:17:09 +000093 }
Greg Clayton6a311642016-07-08 23:06:38 +000094 if (changed)
95 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +000096 }
97 }
98 else
99 {
100 error.SetErrorString("replace operation takes an array index followed by one or more path pairs");
101 }
102 break;
103
104
105
106 case eVarSetOperationAssign:
107 if (argc < 2 || (argc & 1))
108 {
109 error.SetErrorString("assign operation takes one or more path pairs");
110 break;
111 }
112 m_path_mappings.Clear(m_notify_changes);
113 // Fall through to append case
Jason Molenda62e06812016-02-16 04:14:33 +0000114 LLVM_FALLTHROUGH;
Greg Clayton67cc0632012-08-22 17:17:09 +0000115 case eVarSetOperationAppend:
116 if (argc < 2 || (argc & 1))
117 {
118 error.SetErrorString("append operation takes one or more path pairs");
119 break;
120 }
121 else
122 {
Greg Clayton6a311642016-07-08 23:06:38 +0000123 bool changed = false;
Greg Clayton67cc0632012-08-22 17:17:09 +0000124 for (size_t i=0; i<argc; i += 2)
125 {
Greg Clayton6a311642016-07-08 23:06:38 +0000126 const char *orginal_path = args.GetArgumentAtIndex(i);
127 const char *replace_path = args.GetArgumentAtIndex(i+1);
128 if (VerifyPathExists(replace_path))
129 {
130 ConstString a(orginal_path);
131 ConstString b(replace_path);
132 m_path_mappings.Append(a, b, m_notify_changes);
133 m_value_was_set = true;
134 changed = true;
135 }
136 else
137 {
138 error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
139 break;
140 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000141 }
Greg Clayton6a311642016-07-08 23:06:38 +0000142 if (changed)
143 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +0000144 }
145 break;
146
147 case eVarSetOperationInsertBefore:
148 case eVarSetOperationInsertAfter:
149 // Must be at least one index + 1 pair of paths, and the pair count must be even
150 if (argc >= 3 && (((argc - 1) & 1) == 0))
151 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000152 uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
Greg Clayton67cc0632012-08-22 17:17:09 +0000153 const uint32_t count = m_path_mappings.GetSize();
154 if (idx > count)
155 {
156 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
157 }
158 else
159 {
Greg Clayton6a311642016-07-08 23:06:38 +0000160 bool changed = false;
Greg Clayton67cc0632012-08-22 17:17:09 +0000161 if (op == eVarSetOperationInsertAfter)
162 ++idx;
163 for (size_t i=1; i<argc; i += 2, ++idx)
164 {
Greg Clayton6a311642016-07-08 23:06:38 +0000165 const char *orginal_path = args.GetArgumentAtIndex(i);
166 const char *replace_path = args.GetArgumentAtIndex(i+1);
167 if (VerifyPathExists(replace_path))
168 {
169 ConstString a(orginal_path);
170 ConstString b(replace_path);
171 m_path_mappings.Insert (a, b, idx, m_notify_changes);
172 changed = true;
173 }
174 else
175 {
176 error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
177 break;
178 }
Greg Clayton67cc0632012-08-22 17:17:09 +0000179 }
Greg Clayton6a311642016-07-08 23:06:38 +0000180 if (changed)
181 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +0000182 }
183 }
184 else
185 {
186 error.SetErrorString("insert operation takes an array index followed by one or more path pairs");
187 }
188 break;
189
190 case eVarSetOperationRemove:
191 if (argc > 0)
192 {
193 std::vector<int> remove_indexes;
194 bool all_indexes_valid = true;
195 size_t i;
196 for (i=0; all_indexes_valid && i<argc; ++i)
197 {
Vince Harron5275aaa2015-01-15 20:08:35 +0000198 const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
Greg Clayton67cc0632012-08-22 17:17:09 +0000199 if (idx == INT32_MAX)
200 all_indexes_valid = false;
201 else
202 remove_indexes.push_back(idx);
203 }
204
205 if (all_indexes_valid)
206 {
207 size_t num_remove_indexes = remove_indexes.size();
208 if (num_remove_indexes)
209 {
210 // Sort and then erase in reverse so indexes are always valid
211 std::sort(remove_indexes.begin(), remove_indexes.end());
Andy Gibbsa297a972013-06-19 19:04:53 +0000212 for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j)
Greg Clayton67cc0632012-08-22 17:17:09 +0000213 {
Jason Molendaccd41e52012-10-04 22:47:07 +0000214 m_path_mappings.Remove (j, m_notify_changes);
Greg Clayton67cc0632012-08-22 17:17:09 +0000215 }
216 }
Greg Clayton332e8b12015-01-13 21:13:08 +0000217 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +0000218 }
219 else
220 {
221 error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
222 }
223 }
224 else
225 {
226 error.SetErrorString("remove operation takes one or more array index");
227 }
228 break;
229
230 case eVarSetOperationInvalid:
Pavel Labathc95f7e22015-02-20 11:14:59 +0000231 error = OptionValue::SetValueFromString (value, op);
Greg Clayton67cc0632012-08-22 17:17:09 +0000232 break;
233 }
234 return error;
Greg Clayton67cc0632012-08-22 17:17:09 +0000235}
236
237lldb::OptionValueSP
238OptionValuePathMappings::DeepCopy () const
239{
240 return OptionValueSP(new OptionValuePathMappings(*this));
241}