1 //===-- OptionValuePathMappings.cpp -----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Interpreter/OptionValuePathMappings.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/Stream.h"
17 #include "lldb/Host/FileSpec.h"
18 #include "lldb/Host/StringConvert.h"
19 #include "lldb/Interpreter/Args.h"
22 using namespace lldb_private;
26 VerifyPathExists(const char *path)
29 return FileSpec(path, false).Exists();
37 OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
39 if (dump_mask & eDumpOptionType)
40 strm.Printf ("(%s)", GetTypeAsCString ());
41 if (dump_mask & eDumpOptionValue)
43 if (dump_mask & eDumpOptionType)
44 strm.Printf (" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : "");
45 m_path_mappings.Dump(&strm);
50 OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
53 Args args(value.str().c_str());
54 const size_t argc = args.GetArgumentCount();
58 case eVarSetOperationClear:
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))
67 uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
68 const uint32_t count = m_path_mappings.GetSize();
71 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
76 for (size_t i=1; i<argc; i += 2, ++idx)
78 const char *orginal_path = args.GetArgumentAtIndex(i);
79 const char *replace_path = args.GetArgumentAtIndex(i+1);
80 if (VerifyPathExists(replace_path))
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);
90 error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
100 error.SetErrorString("replace operation takes an array index followed by one or more path pairs");
106 case eVarSetOperationAssign:
107 if (argc < 2 || (argc & 1))
109 error.SetErrorString("assign operation takes one or more path pairs");
112 m_path_mappings.Clear(m_notify_changes);
113 // Fall through to append case
115 case eVarSetOperationAppend:
116 if (argc < 2 || (argc & 1))
118 error.SetErrorString("append operation takes one or more path pairs");
123 bool changed = false;
124 for (size_t i=0; i<argc; i += 2)
126 const char *orginal_path = args.GetArgumentAtIndex(i);
127 const char *replace_path = args.GetArgumentAtIndex(i+1);
128 if (VerifyPathExists(replace_path))
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;
138 error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
143 NotifyValueChanged();
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))
152 uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
153 const uint32_t count = m_path_mappings.GetSize();
156 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
160 bool changed = false;
161 if (op == eVarSetOperationInsertAfter)
163 for (size_t i=1; i<argc; i += 2, ++idx)
165 const char *orginal_path = args.GetArgumentAtIndex(i);
166 const char *replace_path = args.GetArgumentAtIndex(i+1);
167 if (VerifyPathExists(replace_path))
169 ConstString a(orginal_path);
170 ConstString b(replace_path);
171 m_path_mappings.Insert (a, b, idx, m_notify_changes);
176 error.SetErrorStringWithFormat("the replacement path doesn't exist: \"%s\"", replace_path);
181 NotifyValueChanged();
186 error.SetErrorString("insert operation takes an array index followed by one or more path pairs");
190 case eVarSetOperationRemove:
193 std::vector<int> remove_indexes;
194 bool all_indexes_valid = true;
196 for (i=0; all_indexes_valid && i<argc; ++i)
198 const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
199 if (idx == INT32_MAX)
200 all_indexes_valid = false;
202 remove_indexes.push_back(idx);
205 if (all_indexes_valid)
207 size_t num_remove_indexes = remove_indexes.size();
208 if (num_remove_indexes)
210 // Sort and then erase in reverse so indexes are always valid
211 std::sort(remove_indexes.begin(), remove_indexes.end());
212 for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j)
214 m_path_mappings.Remove (j, m_notify_changes);
217 NotifyValueChanged();
221 error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
226 error.SetErrorString("remove operation takes one or more array index");
230 case eVarSetOperationInvalid:
231 error = OptionValue::SetValueFromString (value, op);
238 OptionValuePathMappings::DeepCopy () const
240 return OptionValueSP(new OptionValuePathMappings(*this));