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