blob: 56f2ecf4f5fe4af14f84e79592432c86b21ad205 [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"
17#include "lldb/Interpreter/Args.h"
18
19using namespace lldb;
20using namespace lldb_private;
21
22void
23OptionValuePathMappings::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
35Error
36OptionValuePathMappings::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 ();
Greg Clayton332e8b12015-01-13 21:13:08 +000046 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +000047 break;
48
49 case eVarSetOperationReplace:
50 // Must be at least one index + 1 pair of paths, and the pair count must be even
51 if (argc >= 3 && (((argc - 1) & 1) == 0))
52 {
53 uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
54 const uint32_t count = m_path_mappings.GetSize();
55 if (idx > count)
56 {
57 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
58 }
59 else
60 {
61 for (size_t i=1; i<argc; i += 2, ++idx)
62 {
63 ConstString a(args.GetArgumentAtIndex(i));
64 ConstString b(args.GetArgumentAtIndex(i+1));
65 if (!m_path_mappings.Replace (a, b, idx, m_notify_changes))
66 m_path_mappings.Append(a, b, m_notify_changes);
67 }
Greg Clayton332e8b12015-01-13 21:13:08 +000068 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +000069 }
70 }
71 else
72 {
73 error.SetErrorString("replace operation takes an array index followed by one or more path pairs");
74 }
75 break;
76
77
78
79 case eVarSetOperationAssign:
80 if (argc < 2 || (argc & 1))
81 {
82 error.SetErrorString("assign operation takes one or more path pairs");
83 break;
84 }
85 m_path_mappings.Clear(m_notify_changes);
86 // Fall through to append case
87 case eVarSetOperationAppend:
88 if (argc < 2 || (argc & 1))
89 {
90 error.SetErrorString("append operation takes one or more path pairs");
91 break;
92 }
93 else
94 {
95 for (size_t i=0; i<argc; i += 2)
96 {
97 ConstString a(args.GetArgumentAtIndex(i));
98 ConstString b(args.GetArgumentAtIndex(i+1));
99 m_path_mappings.Append(a, b, m_notify_changes);
100 m_value_was_set = true;
101 }
Greg Clayton332e8b12015-01-13 21:13:08 +0000102 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +0000103 }
104 break;
105
106 case eVarSetOperationInsertBefore:
107 case eVarSetOperationInsertAfter:
108 // Must be at least one index + 1 pair of paths, and the pair count must be even
109 if (argc >= 3 && (((argc - 1) & 1) == 0))
110 {
111 uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
112 const uint32_t count = m_path_mappings.GetSize();
113 if (idx > count)
114 {
115 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
116 }
117 else
118 {
119 if (op == eVarSetOperationInsertAfter)
120 ++idx;
121 for (size_t i=1; i<argc; i += 2, ++idx)
122 {
123 ConstString a(args.GetArgumentAtIndex(i));
124 ConstString b(args.GetArgumentAtIndex(i+1));
125 m_path_mappings.Insert (a, b, idx, m_notify_changes);
126 }
Greg Clayton332e8b12015-01-13 21:13:08 +0000127 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +0000128 }
129 }
130 else
131 {
132 error.SetErrorString("insert operation takes an array index followed by one or more path pairs");
133 }
134 break;
135
136 case eVarSetOperationRemove:
137 if (argc > 0)
138 {
139 std::vector<int> remove_indexes;
140 bool all_indexes_valid = true;
141 size_t i;
142 for (i=0; all_indexes_valid && i<argc; ++i)
143 {
144 const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
145 if (idx == INT32_MAX)
146 all_indexes_valid = false;
147 else
148 remove_indexes.push_back(idx);
149 }
150
151 if (all_indexes_valid)
152 {
153 size_t num_remove_indexes = remove_indexes.size();
154 if (num_remove_indexes)
155 {
156 // Sort and then erase in reverse so indexes are always valid
157 std::sort(remove_indexes.begin(), remove_indexes.end());
Andy Gibbsa297a972013-06-19 19:04:53 +0000158 for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j)
Greg Clayton67cc0632012-08-22 17:17:09 +0000159 {
Jason Molendaccd41e52012-10-04 22:47:07 +0000160 m_path_mappings.Remove (j, m_notify_changes);
Greg Clayton67cc0632012-08-22 17:17:09 +0000161 }
162 }
Greg Clayton332e8b12015-01-13 21:13:08 +0000163 NotifyValueChanged();
Greg Clayton67cc0632012-08-22 17:17:09 +0000164 }
165 else
166 {
167 error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
168 }
169 }
170 else
171 {
172 error.SetErrorString("remove operation takes one or more array index");
173 }
174 break;
175
176 case eVarSetOperationInvalid:
177 error = OptionValue::SetValueFromCString (value, op);
178 break;
179 }
180 return error;
Greg Clayton67cc0632012-08-22 17:17:09 +0000181}
182
183lldb::OptionValueSP
184OptionValuePathMappings::DeepCopy () const
185{
186 return OptionValueSP(new OptionValuePathMappings(*this));
187}