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