]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Interpreter / OptionValueFileSpecLIst.cpp
1 //===-- OptionValueFileSpecLIst.cpp -----------------------------*- C++ -*-===//
2 //
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
16 #include "lldb/Host/StringConvert.h"
17 #include "lldb/Utility/Args.h"
18 #include "lldb/Utility/Stream.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22
23 void 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) {
28     if (dump_mask & eDumpOptionType)
29       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
41 Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value,
42                                                    VarSetOperationType op) {
43   Status error;
44   Args args(value.str());
45   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);
69         }
70         NotifyValueChanged();
71       }
72     } else {
73       error.SetErrorString("replace operation takes an array index followed by "
74                            "one or more values");
75     }
76     break;
77
78   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");
93     }
94     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;
160 }
161
162 lldb::OptionValueSP OptionValueFileSpecList::DeepCopy() const {
163   return OptionValueSP(new OptionValueFileSpecList(*this));
164 }