1//===-- OptionValueFileSpecList.cpp ---------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Interpreter/OptionValueFileSpecList.h"
10
11#include "lldb/Utility/Args.h"
12#include "lldb/Utility/Stream.h"
13
14using namespace lldb;
15using namespace lldb_private;
16
17void OptionValueFileSpecList::DumpValue(const ExecutionContext *exe_ctx,
18 Stream &strm, uint32_t dump_mask) {
19 std::lock_guard<std::recursive_mutex> lock(m_mutex);
20 if (dump_mask & eDumpOptionType)
21 strm.Printf(format: "(%s)", GetTypeAsCString());
22 if (dump_mask & eDumpOptionValue) {
23 const bool one_line = dump_mask & eDumpOptionCommand;
24 const uint32_t size = m_current_value.GetSize();
25 if (dump_mask & eDumpOptionType)
26 strm.Printf(format: " =%s",
27 (m_current_value.GetSize() > 0 && !one_line) ? "\n" : "");
28 if (!one_line)
29 strm.IndentMore();
30 for (uint32_t i = 0; i < size; ++i) {
31 if (!one_line) {
32 strm.Indent();
33 strm.Printf(format: "[%u]: ", i);
34 }
35 m_current_value.GetFileSpecAtIndex(idx: i).Dump(s&: strm.AsRawOstream());
36 if (one_line)
37 strm << ' ';
38 }
39 if (!one_line)
40 strm.IndentLess();
41 }
42}
43
44llvm::json::Value
45OptionValueFileSpecList::ToJSON(const ExecutionContext *exe_ctx) const {
46 std::lock_guard<std::recursive_mutex> lock(m_mutex);
47 llvm::json::Array array;
48 for (const auto &file_spec : m_current_value)
49 array.emplace_back(A: file_spec.ToJSON());
50 return array;
51}
52
53Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value,
54 VarSetOperationType op) {
55 std::lock_guard<std::recursive_mutex> lock(m_mutex);
56 Status error;
57 Args args(value.str());
58 const size_t argc = args.GetArgumentCount();
59
60 switch (op) {
61 case eVarSetOperationClear:
62 Clear();
63 NotifyValueChanged();
64 break;
65
66 case eVarSetOperationReplace:
67 if (argc > 1) {
68 uint32_t idx;
69 const uint32_t count = m_current_value.GetSize();
70 if (!llvm::to_integer(S: args.GetArgumentAtIndex(idx: 0), Num&: idx) || idx > count) {
71 error = Status::FromErrorStringWithFormat(
72 format: "invalid file list index %s, index must be 0 through %u",
73 args.GetArgumentAtIndex(idx: 0), count);
74 } else {
75 for (size_t i = 1; i < argc; ++i, ++idx) {
76 FileSpec file(args.GetArgumentAtIndex(idx: i));
77 if (idx < count)
78 m_current_value.Replace(idx, file);
79 else
80 m_current_value.Append(file);
81 }
82 NotifyValueChanged();
83 }
84 } else {
85 error = Status::FromErrorString(
86 str: "replace operation takes an array index followed by "
87 "one or more values");
88 }
89 break;
90
91 case eVarSetOperationAssign:
92 m_current_value.Clear();
93 // Fall through to append case
94 [[fallthrough]];
95 case eVarSetOperationAppend:
96 if (argc > 0) {
97 m_value_was_set = true;
98 for (size_t i = 0; i < argc; ++i) {
99 FileSpec file(args.GetArgumentAtIndex(idx: i));
100 m_current_value.Append(file);
101 }
102 NotifyValueChanged();
103 } else {
104 error = Status::FromErrorString(
105 str: "assign operation takes at least one file path argument");
106 }
107 break;
108
109 case eVarSetOperationInsertBefore:
110 case eVarSetOperationInsertAfter:
111 if (argc > 1) {
112 uint32_t idx;
113 const uint32_t count = m_current_value.GetSize();
114 if (!llvm::to_integer(S: args.GetArgumentAtIndex(idx: 0), Num&: idx) || idx > count) {
115 error = Status::FromErrorStringWithFormat(
116 format: "invalid insert file list index %s, index must be 0 through %u",
117 args.GetArgumentAtIndex(idx: 0), count);
118 } else {
119 if (op == eVarSetOperationInsertAfter)
120 ++idx;
121 for (size_t i = 1; i < argc; ++i, ++idx) {
122 FileSpec file(args.GetArgumentAtIndex(idx: i));
123 m_current_value.Insert(idx, file);
124 }
125 NotifyValueChanged();
126 }
127 } else {
128 error = Status::FromErrorString(
129 str: "insert operation takes an array index followed by "
130 "one or more values");
131 }
132 break;
133
134 case eVarSetOperationRemove:
135 if (argc > 0) {
136 std::vector<int> remove_indexes;
137 bool all_indexes_valid = true;
138 size_t i;
139 for (i = 0; all_indexes_valid && i < argc; ++i) {
140 int idx;
141 if (!llvm::to_integer(S: args.GetArgumentAtIndex(idx: i), Num&: idx))
142 all_indexes_valid = false;
143 else
144 remove_indexes.push_back(x: idx);
145 }
146
147 if (all_indexes_valid) {
148 size_t num_remove_indexes = remove_indexes.size();
149 if (num_remove_indexes) {
150 // Sort and then erase in reverse so indexes are always valid
151 llvm::sort(C&: remove_indexes);
152 for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) {
153 m_current_value.Remove(idx: j);
154 }
155 }
156 NotifyValueChanged();
157 } else {
158 error = Status::FromErrorStringWithFormat(
159 format: "invalid array index '%s', aborting remove operation",
160 args.GetArgumentAtIndex(idx: i));
161 }
162 } else {
163 error = Status::FromErrorString(
164 str: "remove operation takes one or more array index");
165 }
166 break;
167
168 case eVarSetOperationInvalid:
169 error = OptionValue::SetValueFromString(value, op);
170 break;
171 }
172 return error;
173}
174
175OptionValueSP OptionValueFileSpecList::Clone() const {
176 std::lock_guard<std::recursive_mutex> lock(m_mutex);
177 return Cloneable::Clone();
178}
179

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of lldb/source/Interpreter/OptionValueFileSpecList.cpp