1254721Semaste//===-- OptionValuePathMappings.cpp -----------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Interpreter/OptionValuePathMappings.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste// Project includes 16254721Semaste#include "lldb/Core/Stream.h" 17254721Semaste#include "lldb/Interpreter/Args.h" 18254721Semaste 19254721Semasteusing namespace lldb; 20254721Semasteusing namespace lldb_private; 21254721Semaste 22254721Semastevoid 23254721SemasteOptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) 24254721Semaste{ 25254721Semaste if (dump_mask & eDumpOptionType) 26254721Semaste strm.Printf ("(%s)", GetTypeAsCString ()); 27254721Semaste if (dump_mask & eDumpOptionValue) 28254721Semaste { 29254721Semaste if (dump_mask & eDumpOptionType) 30254721Semaste strm.Printf (" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : ""); 31254721Semaste m_path_mappings.Dump(&strm); 32254721Semaste } 33254721Semaste} 34254721Semaste 35254721SemasteError 36254721SemasteOptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperationType op) 37254721Semaste{ 38254721Semaste Error error; 39254721Semaste Args args(value); 40254721Semaste const size_t argc = args.GetArgumentCount(); 41254721Semaste 42254721Semaste switch (op) 43254721Semaste { 44254721Semaste case eVarSetOperationClear: 45254721Semaste Clear (); 46254721Semaste break; 47254721Semaste 48254721Semaste case eVarSetOperationReplace: 49254721Semaste // Must be at least one index + 1 pair of paths, and the pair count must be even 50254721Semaste if (argc >= 3 && (((argc - 1) & 1) == 0)) 51254721Semaste { 52254721Semaste uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); 53254721Semaste const uint32_t count = m_path_mappings.GetSize(); 54254721Semaste if (idx > count) 55254721Semaste { 56254721Semaste error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); 57254721Semaste } 58254721Semaste else 59254721Semaste { 60254721Semaste for (size_t i=1; i<argc; i += 2, ++idx) 61254721Semaste { 62254721Semaste ConstString a(args.GetArgumentAtIndex(i)); 63254721Semaste ConstString b(args.GetArgumentAtIndex(i+1)); 64254721Semaste if (!m_path_mappings.Replace (a, b, idx, m_notify_changes)) 65254721Semaste m_path_mappings.Append(a, b, m_notify_changes); 66254721Semaste } 67254721Semaste } 68254721Semaste } 69254721Semaste else 70254721Semaste { 71254721Semaste error.SetErrorString("replace operation takes an array index followed by one or more path pairs"); 72254721Semaste } 73254721Semaste break; 74254721Semaste 75254721Semaste 76254721Semaste 77254721Semaste case eVarSetOperationAssign: 78254721Semaste if (argc < 2 || (argc & 1)) 79254721Semaste { 80254721Semaste error.SetErrorString("assign operation takes one or more path pairs"); 81254721Semaste break; 82254721Semaste } 83254721Semaste m_path_mappings.Clear(m_notify_changes); 84254721Semaste // Fall through to append case 85254721Semaste case eVarSetOperationAppend: 86254721Semaste if (argc < 2 || (argc & 1)) 87254721Semaste { 88254721Semaste error.SetErrorString("append operation takes one or more path pairs"); 89254721Semaste break; 90254721Semaste } 91254721Semaste else 92254721Semaste { 93254721Semaste for (size_t i=0; i<argc; i += 2) 94254721Semaste { 95254721Semaste ConstString a(args.GetArgumentAtIndex(i)); 96254721Semaste ConstString b(args.GetArgumentAtIndex(i+1)); 97254721Semaste m_path_mappings.Append(a, b, m_notify_changes); 98254721Semaste m_value_was_set = true; 99254721Semaste } 100254721Semaste } 101254721Semaste break; 102254721Semaste 103254721Semaste case eVarSetOperationInsertBefore: 104254721Semaste case eVarSetOperationInsertAfter: 105254721Semaste // Must be at least one index + 1 pair of paths, and the pair count must be even 106254721Semaste if (argc >= 3 && (((argc - 1) & 1) == 0)) 107254721Semaste { 108254721Semaste uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); 109254721Semaste const uint32_t count = m_path_mappings.GetSize(); 110254721Semaste if (idx > count) 111254721Semaste { 112254721Semaste error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); 113254721Semaste } 114254721Semaste else 115254721Semaste { 116254721Semaste if (op == eVarSetOperationInsertAfter) 117254721Semaste ++idx; 118254721Semaste for (size_t i=1; i<argc; i += 2, ++idx) 119254721Semaste { 120254721Semaste ConstString a(args.GetArgumentAtIndex(i)); 121254721Semaste ConstString b(args.GetArgumentAtIndex(i+1)); 122254721Semaste m_path_mappings.Insert (a, b, idx, m_notify_changes); 123254721Semaste } 124254721Semaste } 125254721Semaste } 126254721Semaste else 127254721Semaste { 128254721Semaste error.SetErrorString("insert operation takes an array index followed by one or more path pairs"); 129254721Semaste } 130254721Semaste break; 131254721Semaste 132254721Semaste case eVarSetOperationRemove: 133254721Semaste if (argc > 0) 134254721Semaste { 135254721Semaste std::vector<int> remove_indexes; 136254721Semaste bool all_indexes_valid = true; 137254721Semaste size_t i; 138254721Semaste for (i=0; all_indexes_valid && i<argc; ++i) 139254721Semaste { 140254721Semaste const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); 141254721Semaste if (idx == INT32_MAX) 142254721Semaste all_indexes_valid = false; 143254721Semaste else 144254721Semaste remove_indexes.push_back(idx); 145254721Semaste } 146254721Semaste 147254721Semaste if (all_indexes_valid) 148254721Semaste { 149254721Semaste size_t num_remove_indexes = remove_indexes.size(); 150254721Semaste if (num_remove_indexes) 151254721Semaste { 152254721Semaste // Sort and then erase in reverse so indexes are always valid 153254721Semaste std::sort(remove_indexes.begin(), remove_indexes.end()); 154254721Semaste for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j) 155254721Semaste { 156254721Semaste m_path_mappings.Remove (j, m_notify_changes); 157254721Semaste } 158254721Semaste } 159254721Semaste } 160254721Semaste else 161254721Semaste { 162254721Semaste error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); 163254721Semaste } 164254721Semaste } 165254721Semaste else 166254721Semaste { 167254721Semaste error.SetErrorString("remove operation takes one or more array index"); 168254721Semaste } 169254721Semaste break; 170254721Semaste 171254721Semaste case eVarSetOperationInvalid: 172254721Semaste error = OptionValue::SetValueFromCString (value, op); 173254721Semaste break; 174254721Semaste } 175254721Semaste return error; 176254721Semaste 177254721Semaste m_value_was_set = true; 178254721Semaste return Error(); 179254721Semaste} 180254721Semaste 181254721Semastelldb::OptionValueSP 182254721SemasteOptionValuePathMappings::DeepCopy () const 183254721Semaste{ 184254721Semaste return OptionValueSP(new OptionValuePathMappings(*this)); 185254721Semaste} 186