1 //===-- OptionValueFileSpecLIst.cpp -----------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Interpreter/OptionValueFileSpecList.h"
11 #include "lldb/Host/StringConvert.h"
12 #include "lldb/Utility/Args.h"
13 #include "lldb/Utility/Stream.h"
16 using namespace lldb_private;
18 void OptionValueFileSpecList::DumpValue(const ExecutionContext *exe_ctx,
19 Stream &strm, uint32_t dump_mask) {
20 std::lock_guard<std::recursive_mutex> lock(m_mutex);
21 if (dump_mask & eDumpOptionType)
22 strm.Printf("(%s)", GetTypeAsCString());
23 if (dump_mask & eDumpOptionValue) {
24 const bool one_line = dump_mask & eDumpOptionCommand;
25 const uint32_t size = m_current_value.GetSize();
26 if (dump_mask & eDumpOptionType)
28 (m_current_value.GetSize() > 0 && !one_line) ? "\n" : "");
31 for (uint32_t i = 0; i < size; ++i) {
34 strm.Printf("[%u]: ", i);
36 m_current_value.GetFileSpecAtIndex(i).Dump(&strm);
45 Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value,
46 VarSetOperationType op) {
47 std::lock_guard<std::recursive_mutex> lock(m_mutex);
49 Args args(value.str());
50 const size_t argc = args.GetArgumentCount();
53 case eVarSetOperationClear:
58 case eVarSetOperationReplace:
61 StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
62 const uint32_t count = m_current_value.GetSize();
64 error.SetErrorStringWithFormat(
65 "invalid file list index %u, index must be 0 through %u", idx,
68 for (size_t i = 1; i < argc; ++i, ++idx) {
69 FileSpec file(args.GetArgumentAtIndex(i));
71 m_current_value.Replace(idx, file);
73 m_current_value.Append(file);
78 error.SetErrorString("replace operation takes an array index followed by "
79 "one or more values");
83 case eVarSetOperationAssign:
84 m_current_value.Clear();
85 // Fall through to append case
87 case eVarSetOperationAppend:
89 m_value_was_set = true;
90 for (size_t i = 0; i < argc; ++i) {
91 FileSpec file(args.GetArgumentAtIndex(i));
92 m_current_value.Append(file);
97 "assign operation takes at least one file path argument");
101 case eVarSetOperationInsertBefore:
102 case eVarSetOperationInsertAfter:
105 StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
106 const uint32_t count = m_current_value.GetSize();
108 error.SetErrorStringWithFormat(
109 "invalid insert file list index %u, index must be 0 through %u",
112 if (op == eVarSetOperationInsertAfter)
114 for (size_t i = 1; i < argc; ++i, ++idx) {
115 FileSpec file(args.GetArgumentAtIndex(i));
116 m_current_value.Insert(idx, file);
118 NotifyValueChanged();
121 error.SetErrorString("insert operation takes an array index followed by "
122 "one or more values");
126 case eVarSetOperationRemove:
128 std::vector<int> remove_indexes;
129 bool all_indexes_valid = true;
131 for (i = 0; all_indexes_valid && i < argc; ++i) {
133 StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
134 if (idx == INT32_MAX)
135 all_indexes_valid = false;
137 remove_indexes.push_back(idx);
140 if (all_indexes_valid) {
141 size_t num_remove_indexes = remove_indexes.size();
142 if (num_remove_indexes) {
143 // Sort and then erase in reverse so indexes are always valid
144 llvm::sort(remove_indexes.begin(), remove_indexes.end());
145 for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) {
146 m_current_value.Remove(j);
149 NotifyValueChanged();
151 error.SetErrorStringWithFormat(
152 "invalid array index '%s', aborting remove operation",
153 args.GetArgumentAtIndex(i));
156 error.SetErrorString("remove operation takes one or more array index");
160 case eVarSetOperationInvalid:
161 error = OptionValue::SetValueFromString(value, op);
167 lldb::OptionValueSP OptionValueFileSpecList::DeepCopy() const {
168 std::lock_guard<std::recursive_mutex> lock(m_mutex);
169 return OptionValueSP(new OptionValueFileSpecList(m_current_value));