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