1 //===-- OptionValueFileSpecList.cpp ---------------------------------------===//
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/Utility/Args.h"
12 #include "lldb/Utility/Stream.h"
15 using namespace lldb_private
;
17 void 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("(%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
)
27 (m_current_value
.GetSize() > 0 && !one_line
) ? "\n" : "");
30 for (uint32_t i
= 0; i
< size
; ++i
) {
33 strm
.Printf("[%u]: ", i
);
35 m_current_value
.GetFileSpecAtIndex(i
).Dump(strm
.AsRawOstream());
44 Status
OptionValueFileSpecList::SetValueFromString(llvm::StringRef value
,
45 VarSetOperationType op
) {
46 std::lock_guard
<std::recursive_mutex
> lock(m_mutex
);
48 Args
args(value
.str());
49 const size_t argc
= args
.GetArgumentCount();
52 case eVarSetOperationClear
:
57 case eVarSetOperationReplace
:
60 const uint32_t count
= m_current_value
.GetSize();
61 if (!llvm::to_integer(args
.GetArgumentAtIndex(0), idx
) || idx
> count
) {
62 error
.SetErrorStringWithFormat(
63 "invalid file list index %s, index must be 0 through %u",
64 args
.GetArgumentAtIndex(0), count
);
66 for (size_t i
= 1; i
< argc
; ++i
, ++idx
) {
67 FileSpec
file(args
.GetArgumentAtIndex(i
));
69 m_current_value
.Replace(idx
, file
);
71 m_current_value
.Append(file
);
76 error
.SetErrorString("replace operation takes an array index followed by "
77 "one or more values");
81 case eVarSetOperationAssign
:
82 m_current_value
.Clear();
83 // Fall through to append case
85 case eVarSetOperationAppend
:
87 m_value_was_set
= true;
88 for (size_t i
= 0; i
< argc
; ++i
) {
89 FileSpec
file(args
.GetArgumentAtIndex(i
));
90 m_current_value
.Append(file
);
95 "assign operation takes at least one file path argument");
99 case eVarSetOperationInsertBefore
:
100 case eVarSetOperationInsertAfter
:
103 const uint32_t count
= m_current_value
.GetSize();
104 if (!llvm::to_integer(args
.GetArgumentAtIndex(0), idx
) || idx
> count
) {
105 error
.SetErrorStringWithFormat(
106 "invalid insert file list index %s, index must be 0 through %u",
107 args
.GetArgumentAtIndex(0), count
);
109 if (op
== eVarSetOperationInsertAfter
)
111 for (size_t i
= 1; i
< argc
; ++i
, ++idx
) {
112 FileSpec
file(args
.GetArgumentAtIndex(i
));
113 m_current_value
.Insert(idx
, file
);
115 NotifyValueChanged();
118 error
.SetErrorString("insert operation takes an array index followed by "
119 "one or more values");
123 case eVarSetOperationRemove
:
125 std::vector
<int> remove_indexes
;
126 bool all_indexes_valid
= true;
128 for (i
= 0; all_indexes_valid
&& i
< argc
; ++i
) {
130 if (!llvm::to_integer(args
.GetArgumentAtIndex(i
), idx
))
131 all_indexes_valid
= false;
133 remove_indexes
.push_back(idx
);
136 if (all_indexes_valid
) {
137 size_t num_remove_indexes
= remove_indexes
.size();
138 if (num_remove_indexes
) {
139 // Sort and then erase in reverse so indexes are always valid
140 llvm::sort(remove_indexes
);
141 for (size_t j
= num_remove_indexes
- 1; j
< num_remove_indexes
; ++j
) {
142 m_current_value
.Remove(j
);
145 NotifyValueChanged();
147 error
.SetErrorStringWithFormat(
148 "invalid array index '%s', aborting remove operation",
149 args
.GetArgumentAtIndex(i
));
152 error
.SetErrorString("remove operation takes one or more array index");
156 case eVarSetOperationInvalid
:
157 error
= OptionValue::SetValueFromString(value
, op
);
163 OptionValueSP
OptionValueFileSpecList::Clone() const {
164 std::lock_guard
<std::recursive_mutex
> lock(m_mutex
);
165 return Cloneable::Clone();