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