OptionValuePathMappings.cpp revision 280031
1//===-- OptionValuePathMappings.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/OptionValuePathMappings.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 23OptionValuePathMappings::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_path_mappings.GetSize() > 0) ? "\n" : ""); 31 m_path_mappings.Dump(&strm); 32 } 33} 34 35Error 36OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperationType op) 37{ 38 Error error; 39 Args args(value); 40 const size_t argc = args.GetArgumentCount(); 41 42 switch (op) 43 { 44 case eVarSetOperationClear: 45 Clear (); 46 NotifyValueChanged(); 47 break; 48 49 case eVarSetOperationReplace: 50 // Must be at least one index + 1 pair of paths, and the pair count must be even 51 if (argc >= 3 && (((argc - 1) & 1) == 0)) 52 { 53 uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); 54 const uint32_t count = m_path_mappings.GetSize(); 55 if (idx > count) 56 { 57 error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); 58 } 59 else 60 { 61 for (size_t i=1; i<argc; i += 2, ++idx) 62 { 63 ConstString a(args.GetArgumentAtIndex(i)); 64 ConstString b(args.GetArgumentAtIndex(i+1)); 65 if (!m_path_mappings.Replace (a, b, idx, m_notify_changes)) 66 m_path_mappings.Append(a, b, m_notify_changes); 67 } 68 NotifyValueChanged(); 69 } 70 } 71 else 72 { 73 error.SetErrorString("replace operation takes an array index followed by one or more path pairs"); 74 } 75 break; 76 77 78 79 case eVarSetOperationAssign: 80 if (argc < 2 || (argc & 1)) 81 { 82 error.SetErrorString("assign operation takes one or more path pairs"); 83 break; 84 } 85 m_path_mappings.Clear(m_notify_changes); 86 // Fall through to append case 87 case eVarSetOperationAppend: 88 if (argc < 2 || (argc & 1)) 89 { 90 error.SetErrorString("append operation takes one or more path pairs"); 91 break; 92 } 93 else 94 { 95 for (size_t i=0; i<argc; i += 2) 96 { 97 ConstString a(args.GetArgumentAtIndex(i)); 98 ConstString b(args.GetArgumentAtIndex(i+1)); 99 m_path_mappings.Append(a, b, m_notify_changes); 100 m_value_was_set = true; 101 } 102 NotifyValueChanged(); 103 } 104 break; 105 106 case eVarSetOperationInsertBefore: 107 case eVarSetOperationInsertAfter: 108 // Must be at least one index + 1 pair of paths, and the pair count must be even 109 if (argc >= 3 && (((argc - 1) & 1) == 0)) 110 { 111 uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); 112 const uint32_t count = m_path_mappings.GetSize(); 113 if (idx > count) 114 { 115 error.SetErrorStringWithFormat("invalid 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 += 2, ++idx) 122 { 123 ConstString a(args.GetArgumentAtIndex(i)); 124 ConstString b(args.GetArgumentAtIndex(i+1)); 125 m_path_mappings.Insert (a, b, idx, m_notify_changes); 126 } 127 NotifyValueChanged(); 128 } 129 } 130 else 131 { 132 error.SetErrorString("insert operation takes an array index followed by one or more path pairs"); 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 = Args::StringToSInt32(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_path_mappings.Remove (j, m_notify_changes); 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::SetValueFromCString (value, op); 178 break; 179 } 180 return error; 181} 182 183lldb::OptionValueSP 184OptionValuePathMappings::DeepCopy () const 185{ 186 return OptionValueSP(new OptionValuePathMappings(*this)); 187} 188