blob: 7fdc3c7802392713d8961182da0d85e29f58b17c [file] [log] [blame]
Alexander Shaposhnikov696bd632016-11-26 05:23:44 +00001//===-- OptionValueFileSpecLIst.cpp -----------------------------*- C++ -*-===//
Greg Clayton67cc0632012-08-22 17:17:09 +00002//
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/OptionValueFileSpecList.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Vince Harron5275aaa2015-01-15 20:08:35 +000016#include "lldb/Host/StringConvert.h"
Pavel Labath145d95c2018-04-17 18:53:35 +000017#include "lldb/Utility/Args.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000018#include "lldb/Utility/Stream.h"
Greg Clayton67cc0632012-08-22 17:17:09 +000019
20using namespace lldb;
21using namespace lldb_private;
22
Kate Stoneb9c1b512016-09-06 20:57:50 +000023void OptionValueFileSpecList::DumpValue(const ExecutionContext *exe_ctx,
24 Stream &strm, uint32_t dump_mask) {
25 if (dump_mask & eDumpOptionType)
26 strm.Printf("(%s)", GetTypeAsCString());
27 if (dump_mask & eDumpOptionValue) {
Greg Clayton67cc0632012-08-22 17:17:09 +000028 if (dump_mask & eDumpOptionType)
Kate Stoneb9c1b512016-09-06 20:57:50 +000029 strm.Printf(" =%s", m_current_value.GetSize() > 0 ? "\n" : "");
30 strm.IndentMore();
31 const uint32_t size = m_current_value.GetSize();
32 for (uint32_t i = 0; i < size; ++i) {
33 strm.Indent();
34 strm.Printf("[%u]: ", i);
35 m_current_value.GetFileSpecAtIndex(i).Dump(&strm);
36 }
37 strm.IndentLess();
38 }
39}
40
Zachary Turner97206d52017-05-12 04:51:55 +000041Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value,
42 VarSetOperationType op) {
43 Status error;
Malcolm Parsons771ef6d2016-11-02 20:34:10 +000044 Args args(value.str());
Kate Stoneb9c1b512016-09-06 20:57:50 +000045 const size_t argc = args.GetArgumentCount();
46
47 switch (op) {
48 case eVarSetOperationClear:
49 Clear();
50 NotifyValueChanged();
51 break;
52
53 case eVarSetOperationReplace:
54 if (argc > 1) {
55 uint32_t idx =
56 StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
57 const uint32_t count = m_current_value.GetSize();
58 if (idx > count) {
59 error.SetErrorStringWithFormat(
60 "invalid file list index %u, index must be 0 through %u", idx,
61 count);
62 } else {
63 for (size_t i = 1; i < argc; ++i, ++idx) {
64 FileSpec file(args.GetArgumentAtIndex(i), false);
65 if (idx < count)
66 m_current_value.Replace(idx, file);
67 else
68 m_current_value.Append(file);
Greg Clayton67cc0632012-08-22 17:17:09 +000069 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000070 NotifyValueChanged();
71 }
72 } else {
73 error.SetErrorString("replace operation takes an array index followed by "
74 "one or more values");
Greg Clayton67cc0632012-08-22 17:17:09 +000075 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000076 break;
Greg Clayton67cc0632012-08-22 17:17:09 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 case eVarSetOperationAssign:
79 m_current_value.Clear();
80 // Fall through to append case
81 LLVM_FALLTHROUGH;
82 case eVarSetOperationAppend:
83 if (argc > 0) {
84 m_value_was_set = true;
85 for (size_t i = 0; i < argc; ++i) {
86 FileSpec file(args.GetArgumentAtIndex(i), false);
87 m_current_value.Append(file);
88 }
89 NotifyValueChanged();
90 } else {
91 error.SetErrorString(
92 "assign operation takes at least one file path argument");
Greg Clayton67cc0632012-08-22 17:17:09 +000093 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000094 break;
95
96 case eVarSetOperationInsertBefore:
97 case eVarSetOperationInsertAfter:
98 if (argc > 1) {
99 uint32_t idx =
100 StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
101 const uint32_t count = m_current_value.GetSize();
102 if (idx > count) {
103 error.SetErrorStringWithFormat(
104 "invalid insert file list index %u, index must be 0 through %u",
105 idx, count);
106 } else {
107 if (op == eVarSetOperationInsertAfter)
108 ++idx;
109 for (size_t i = 1; i < argc; ++i, ++idx) {
110 FileSpec file(args.GetArgumentAtIndex(i), false);
111 m_current_value.Insert(idx, file);
112 }
113 NotifyValueChanged();
114 }
115 } else {
116 error.SetErrorString("insert operation takes an array index followed by "
117 "one or more values");
118 }
119 break;
120
121 case eVarSetOperationRemove:
122 if (argc > 0) {
123 std::vector<int> remove_indexes;
124 bool all_indexes_valid = true;
125 size_t i;
126 for (i = 0; all_indexes_valid && i < argc; ++i) {
127 const int idx =
128 StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
129 if (idx == INT32_MAX)
130 all_indexes_valid = false;
131 else
132 remove_indexes.push_back(idx);
133 }
134
135 if (all_indexes_valid) {
136 size_t num_remove_indexes = remove_indexes.size();
137 if (num_remove_indexes) {
138 // Sort and then erase in reverse so indexes are always valid
139 std::sort(remove_indexes.begin(), remove_indexes.end());
140 for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) {
141 m_current_value.Remove(j);
142 }
143 }
144 NotifyValueChanged();
145 } else {
146 error.SetErrorStringWithFormat(
147 "invalid array index '%s', aborting remove operation",
148 args.GetArgumentAtIndex(i));
149 }
150 } else {
151 error.SetErrorString("remove operation takes one or more array index");
152 }
153 break;
154
155 case eVarSetOperationInvalid:
156 error = OptionValue::SetValueFromString(value, op);
157 break;
158 }
159 return error;
Greg Clayton67cc0632012-08-22 17:17:09 +0000160}
161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162lldb::OptionValueSP OptionValueFileSpecList::DeepCopy() const {
163 return OptionValueSP(new OptionValueFileSpecList(*this));
Greg Clayton67cc0632012-08-22 17:17:09 +0000164}