167cc0636SGreg Clayton //===-- OptionValuePathMappings.cpp -----------------------------*- C++ -*-===// 267cc0636SGreg Clayton // 367cc0636SGreg Clayton // The LLVM Compiler Infrastructure 467cc0636SGreg Clayton // 567cc0636SGreg Clayton // This file is distributed under the University of Illinois Open Source 667cc0636SGreg Clayton // License. See LICENSE.TXT for details. 767cc0636SGreg Clayton // 867cc0636SGreg Clayton //===----------------------------------------------------------------------===// 967cc0636SGreg Clayton 1067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValuePathMappings.h" 1167cc0636SGreg Clayton 1267cc0636SGreg Clayton // C Includes 1367cc0636SGreg Clayton // C++ Includes 1467cc0636SGreg Clayton // Other libraries and framework includes 1567cc0636SGreg Clayton // Project includes 1667cc0636SGreg Clayton #include "lldb/Core/Stream.h" 17*5275aaa0SVince Harron #include "lldb/Host/StringConvert.h" 1867cc0636SGreg Clayton #include "lldb/Interpreter/Args.h" 1967cc0636SGreg Clayton 2067cc0636SGreg Clayton using namespace lldb; 2167cc0636SGreg Clayton using namespace lldb_private; 2267cc0636SGreg Clayton 2367cc0636SGreg Clayton void 2467cc0636SGreg Clayton OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) 2567cc0636SGreg Clayton { 2667cc0636SGreg Clayton if (dump_mask & eDumpOptionType) 2767cc0636SGreg Clayton strm.Printf ("(%s)", GetTypeAsCString ()); 2867cc0636SGreg Clayton if (dump_mask & eDumpOptionValue) 2967cc0636SGreg Clayton { 3067cc0636SGreg Clayton if (dump_mask & eDumpOptionType) 3167cc0636SGreg Clayton strm.Printf (" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : ""); 3267cc0636SGreg Clayton m_path_mappings.Dump(&strm); 3367cc0636SGreg Clayton } 3467cc0636SGreg Clayton } 3567cc0636SGreg Clayton 3667cc0636SGreg Clayton Error 3767cc0636SGreg Clayton OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperationType op) 3867cc0636SGreg Clayton { 3967cc0636SGreg Clayton Error error; 4067cc0636SGreg Clayton Args args(value); 4167cc0636SGreg Clayton const size_t argc = args.GetArgumentCount(); 4267cc0636SGreg Clayton 4367cc0636SGreg Clayton switch (op) 4467cc0636SGreg Clayton { 4567cc0636SGreg Clayton case eVarSetOperationClear: 4667cc0636SGreg Clayton Clear (); 47332e8b1cSGreg Clayton NotifyValueChanged(); 4867cc0636SGreg Clayton break; 4967cc0636SGreg Clayton 5067cc0636SGreg Clayton case eVarSetOperationReplace: 5167cc0636SGreg Clayton // Must be at least one index + 1 pair of paths, and the pair count must be even 5267cc0636SGreg Clayton if (argc >= 3 && (((argc - 1) & 1) == 0)) 5367cc0636SGreg Clayton { 54*5275aaa0SVince Harron uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); 5567cc0636SGreg Clayton const uint32_t count = m_path_mappings.GetSize(); 5667cc0636SGreg Clayton if (idx > count) 5767cc0636SGreg Clayton { 5867cc0636SGreg Clayton error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); 5967cc0636SGreg Clayton } 6067cc0636SGreg Clayton else 6167cc0636SGreg Clayton { 6267cc0636SGreg Clayton for (size_t i=1; i<argc; i += 2, ++idx) 6367cc0636SGreg Clayton { 6467cc0636SGreg Clayton ConstString a(args.GetArgumentAtIndex(i)); 6567cc0636SGreg Clayton ConstString b(args.GetArgumentAtIndex(i+1)); 6667cc0636SGreg Clayton if (!m_path_mappings.Replace (a, b, idx, m_notify_changes)) 6767cc0636SGreg Clayton m_path_mappings.Append(a, b, m_notify_changes); 6867cc0636SGreg Clayton } 69332e8b1cSGreg Clayton NotifyValueChanged(); 7067cc0636SGreg Clayton } 7167cc0636SGreg Clayton } 7267cc0636SGreg Clayton else 7367cc0636SGreg Clayton { 7467cc0636SGreg Clayton error.SetErrorString("replace operation takes an array index followed by one or more path pairs"); 7567cc0636SGreg Clayton } 7667cc0636SGreg Clayton break; 7767cc0636SGreg Clayton 7867cc0636SGreg Clayton 7967cc0636SGreg Clayton 8067cc0636SGreg Clayton case eVarSetOperationAssign: 8167cc0636SGreg Clayton if (argc < 2 || (argc & 1)) 8267cc0636SGreg Clayton { 8367cc0636SGreg Clayton error.SetErrorString("assign operation takes one or more path pairs"); 8467cc0636SGreg Clayton break; 8567cc0636SGreg Clayton } 8667cc0636SGreg Clayton m_path_mappings.Clear(m_notify_changes); 8767cc0636SGreg Clayton // Fall through to append case 8867cc0636SGreg Clayton case eVarSetOperationAppend: 8967cc0636SGreg Clayton if (argc < 2 || (argc & 1)) 9067cc0636SGreg Clayton { 9167cc0636SGreg Clayton error.SetErrorString("append operation takes one or more path pairs"); 9267cc0636SGreg Clayton break; 9367cc0636SGreg Clayton } 9467cc0636SGreg Clayton else 9567cc0636SGreg Clayton { 9667cc0636SGreg Clayton for (size_t i=0; i<argc; i += 2) 9767cc0636SGreg Clayton { 9867cc0636SGreg Clayton ConstString a(args.GetArgumentAtIndex(i)); 9967cc0636SGreg Clayton ConstString b(args.GetArgumentAtIndex(i+1)); 10067cc0636SGreg Clayton m_path_mappings.Append(a, b, m_notify_changes); 10167cc0636SGreg Clayton m_value_was_set = true; 10267cc0636SGreg Clayton } 103332e8b1cSGreg Clayton NotifyValueChanged(); 10467cc0636SGreg Clayton } 10567cc0636SGreg Clayton break; 10667cc0636SGreg Clayton 10767cc0636SGreg Clayton case eVarSetOperationInsertBefore: 10867cc0636SGreg Clayton case eVarSetOperationInsertAfter: 10967cc0636SGreg Clayton // Must be at least one index + 1 pair of paths, and the pair count must be even 11067cc0636SGreg Clayton if (argc >= 3 && (((argc - 1) & 1) == 0)) 11167cc0636SGreg Clayton { 112*5275aaa0SVince Harron uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); 11367cc0636SGreg Clayton const uint32_t count = m_path_mappings.GetSize(); 11467cc0636SGreg Clayton if (idx > count) 11567cc0636SGreg Clayton { 11667cc0636SGreg Clayton error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count); 11767cc0636SGreg Clayton } 11867cc0636SGreg Clayton else 11967cc0636SGreg Clayton { 12067cc0636SGreg Clayton if (op == eVarSetOperationInsertAfter) 12167cc0636SGreg Clayton ++idx; 12267cc0636SGreg Clayton for (size_t i=1; i<argc; i += 2, ++idx) 12367cc0636SGreg Clayton { 12467cc0636SGreg Clayton ConstString a(args.GetArgumentAtIndex(i)); 12567cc0636SGreg Clayton ConstString b(args.GetArgumentAtIndex(i+1)); 12667cc0636SGreg Clayton m_path_mappings.Insert (a, b, idx, m_notify_changes); 12767cc0636SGreg Clayton } 128332e8b1cSGreg Clayton NotifyValueChanged(); 12967cc0636SGreg Clayton } 13067cc0636SGreg Clayton } 13167cc0636SGreg Clayton else 13267cc0636SGreg Clayton { 13367cc0636SGreg Clayton error.SetErrorString("insert operation takes an array index followed by one or more path pairs"); 13467cc0636SGreg Clayton } 13567cc0636SGreg Clayton break; 13667cc0636SGreg Clayton 13767cc0636SGreg Clayton case eVarSetOperationRemove: 13867cc0636SGreg Clayton if (argc > 0) 13967cc0636SGreg Clayton { 14067cc0636SGreg Clayton std::vector<int> remove_indexes; 14167cc0636SGreg Clayton bool all_indexes_valid = true; 14267cc0636SGreg Clayton size_t i; 14367cc0636SGreg Clayton for (i=0; all_indexes_valid && i<argc; ++i) 14467cc0636SGreg Clayton { 145*5275aaa0SVince Harron const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); 14667cc0636SGreg Clayton if (idx == INT32_MAX) 14767cc0636SGreg Clayton all_indexes_valid = false; 14867cc0636SGreg Clayton else 14967cc0636SGreg Clayton remove_indexes.push_back(idx); 15067cc0636SGreg Clayton } 15167cc0636SGreg Clayton 15267cc0636SGreg Clayton if (all_indexes_valid) 15367cc0636SGreg Clayton { 15467cc0636SGreg Clayton size_t num_remove_indexes = remove_indexes.size(); 15567cc0636SGreg Clayton if (num_remove_indexes) 15667cc0636SGreg Clayton { 15767cc0636SGreg Clayton // Sort and then erase in reverse so indexes are always valid 15867cc0636SGreg Clayton std::sort(remove_indexes.begin(), remove_indexes.end()); 159a297a97eSAndy Gibbs for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j) 16067cc0636SGreg Clayton { 161ccd41e55SJason Molenda m_path_mappings.Remove (j, m_notify_changes); 16267cc0636SGreg Clayton } 16367cc0636SGreg Clayton } 164332e8b1cSGreg Clayton NotifyValueChanged(); 16567cc0636SGreg Clayton } 16667cc0636SGreg Clayton else 16767cc0636SGreg Clayton { 16867cc0636SGreg Clayton error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); 16967cc0636SGreg Clayton } 17067cc0636SGreg Clayton } 17167cc0636SGreg Clayton else 17267cc0636SGreg Clayton { 17367cc0636SGreg Clayton error.SetErrorString("remove operation takes one or more array index"); 17467cc0636SGreg Clayton } 17567cc0636SGreg Clayton break; 17667cc0636SGreg Clayton 17767cc0636SGreg Clayton case eVarSetOperationInvalid: 17867cc0636SGreg Clayton error = OptionValue::SetValueFromCString (value, op); 17967cc0636SGreg Clayton break; 18067cc0636SGreg Clayton } 18167cc0636SGreg Clayton return error; 18267cc0636SGreg Clayton } 18367cc0636SGreg Clayton 18467cc0636SGreg Clayton lldb::OptionValueSP 18567cc0636SGreg Clayton OptionValuePathMappings::DeepCopy () const 18667cc0636SGreg Clayton { 18767cc0636SGreg Clayton return OptionValueSP(new OptionValuePathMappings(*this)); 18867cc0636SGreg Clayton } 189