183108e75SAdrian Prantl //===-- OptionValueFileSpecList.cpp ---------------------------------------===// 283108e75SAdrian Prantl // 383108e75SAdrian Prantl // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 483108e75SAdrian Prantl // See https://llvm.org/LICENSE.txt for license information. 583108e75SAdrian Prantl // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 683108e75SAdrian Prantl // 783108e75SAdrian Prantl //===----------------------------------------------------------------------===// 883108e75SAdrian Prantl 983108e75SAdrian Prantl #include "lldb/Interpreter/OptionValueFileSpecList.h" 1083108e75SAdrian Prantl 1183108e75SAdrian Prantl #include "lldb/Host/StringConvert.h" 1283108e75SAdrian Prantl #include "lldb/Utility/Args.h" 1383108e75SAdrian Prantl #include "lldb/Utility/Stream.h" 1483108e75SAdrian Prantl 1583108e75SAdrian Prantl using namespace lldb; 1683108e75SAdrian Prantl using namespace lldb_private; 1783108e75SAdrian Prantl 1883108e75SAdrian Prantl void OptionValueFileSpecList::DumpValue(const ExecutionContext *exe_ctx, 1983108e75SAdrian Prantl Stream &strm, uint32_t dump_mask) { 2083108e75SAdrian Prantl std::lock_guard<std::recursive_mutex> lock(m_mutex); 2183108e75SAdrian Prantl if (dump_mask & eDumpOptionType) 2283108e75SAdrian Prantl strm.Printf("(%s)", GetTypeAsCString()); 2383108e75SAdrian Prantl if (dump_mask & eDumpOptionValue) { 2483108e75SAdrian Prantl const bool one_line = dump_mask & eDumpOptionCommand; 2583108e75SAdrian Prantl const uint32_t size = m_current_value.GetSize(); 2683108e75SAdrian Prantl if (dump_mask & eDumpOptionType) 2783108e75SAdrian Prantl strm.Printf(" =%s", 2883108e75SAdrian Prantl (m_current_value.GetSize() > 0 && !one_line) ? "\n" : ""); 2983108e75SAdrian Prantl if (!one_line) 3083108e75SAdrian Prantl strm.IndentMore(); 3183108e75SAdrian Prantl for (uint32_t i = 0; i < size; ++i) { 3283108e75SAdrian Prantl if (!one_line) { 3383108e75SAdrian Prantl strm.Indent(); 3483108e75SAdrian Prantl strm.Printf("[%u]: ", i); 3583108e75SAdrian Prantl } 36*4dac97ebSRaphael Isemann m_current_value.GetFileSpecAtIndex(i).Dump(strm.AsRawOstream()); 3783108e75SAdrian Prantl if (one_line) 3883108e75SAdrian Prantl strm << ' '; 3983108e75SAdrian Prantl } 4083108e75SAdrian Prantl if (!one_line) 4183108e75SAdrian Prantl strm.IndentLess(); 4283108e75SAdrian Prantl } 4383108e75SAdrian Prantl } 4483108e75SAdrian Prantl 4583108e75SAdrian Prantl Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, 4683108e75SAdrian Prantl VarSetOperationType op) { 4783108e75SAdrian Prantl std::lock_guard<std::recursive_mutex> lock(m_mutex); 4883108e75SAdrian Prantl Status error; 4983108e75SAdrian Prantl Args args(value.str()); 5083108e75SAdrian Prantl const size_t argc = args.GetArgumentCount(); 5183108e75SAdrian Prantl 5283108e75SAdrian Prantl switch (op) { 5383108e75SAdrian Prantl case eVarSetOperationClear: 5483108e75SAdrian Prantl Clear(); 5583108e75SAdrian Prantl NotifyValueChanged(); 5683108e75SAdrian Prantl break; 5783108e75SAdrian Prantl 5883108e75SAdrian Prantl case eVarSetOperationReplace: 5983108e75SAdrian Prantl if (argc > 1) { 6083108e75SAdrian Prantl uint32_t idx = 6183108e75SAdrian Prantl StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); 6283108e75SAdrian Prantl const uint32_t count = m_current_value.GetSize(); 6383108e75SAdrian Prantl if (idx > count) { 6483108e75SAdrian Prantl error.SetErrorStringWithFormat( 6583108e75SAdrian Prantl "invalid file list index %u, index must be 0 through %u", idx, 6683108e75SAdrian Prantl count); 6783108e75SAdrian Prantl } else { 6883108e75SAdrian Prantl for (size_t i = 1; i < argc; ++i, ++idx) { 6983108e75SAdrian Prantl FileSpec file(args.GetArgumentAtIndex(i)); 7083108e75SAdrian Prantl if (idx < count) 7183108e75SAdrian Prantl m_current_value.Replace(idx, file); 7283108e75SAdrian Prantl else 7383108e75SAdrian Prantl m_current_value.Append(file); 7483108e75SAdrian Prantl } 7583108e75SAdrian Prantl NotifyValueChanged(); 7683108e75SAdrian Prantl } 7783108e75SAdrian Prantl } else { 7883108e75SAdrian Prantl error.SetErrorString("replace operation takes an array index followed by " 7983108e75SAdrian Prantl "one or more values"); 8083108e75SAdrian Prantl } 8183108e75SAdrian Prantl break; 8283108e75SAdrian Prantl 8383108e75SAdrian Prantl case eVarSetOperationAssign: 8483108e75SAdrian Prantl m_current_value.Clear(); 8583108e75SAdrian Prantl // Fall through to append case 8683108e75SAdrian Prantl LLVM_FALLTHROUGH; 8783108e75SAdrian Prantl case eVarSetOperationAppend: 8883108e75SAdrian Prantl if (argc > 0) { 8983108e75SAdrian Prantl m_value_was_set = true; 9083108e75SAdrian Prantl for (size_t i = 0; i < argc; ++i) { 9183108e75SAdrian Prantl FileSpec file(args.GetArgumentAtIndex(i)); 9283108e75SAdrian Prantl m_current_value.Append(file); 9383108e75SAdrian Prantl } 9483108e75SAdrian Prantl NotifyValueChanged(); 9583108e75SAdrian Prantl } else { 9683108e75SAdrian Prantl error.SetErrorString( 9783108e75SAdrian Prantl "assign operation takes at least one file path argument"); 9883108e75SAdrian Prantl } 9983108e75SAdrian Prantl break; 10083108e75SAdrian Prantl 10183108e75SAdrian Prantl case eVarSetOperationInsertBefore: 10283108e75SAdrian Prantl case eVarSetOperationInsertAfter: 10383108e75SAdrian Prantl if (argc > 1) { 10483108e75SAdrian Prantl uint32_t idx = 10583108e75SAdrian Prantl StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); 10683108e75SAdrian Prantl const uint32_t count = m_current_value.GetSize(); 10783108e75SAdrian Prantl if (idx > count) { 10883108e75SAdrian Prantl error.SetErrorStringWithFormat( 10983108e75SAdrian Prantl "invalid insert file list index %u, index must be 0 through %u", 11083108e75SAdrian Prantl idx, count); 11183108e75SAdrian Prantl } else { 11283108e75SAdrian Prantl if (op == eVarSetOperationInsertAfter) 11383108e75SAdrian Prantl ++idx; 11483108e75SAdrian Prantl for (size_t i = 1; i < argc; ++i, ++idx) { 11583108e75SAdrian Prantl FileSpec file(args.GetArgumentAtIndex(i)); 11683108e75SAdrian Prantl m_current_value.Insert(idx, file); 11783108e75SAdrian Prantl } 11883108e75SAdrian Prantl NotifyValueChanged(); 11983108e75SAdrian Prantl } 12083108e75SAdrian Prantl } else { 12183108e75SAdrian Prantl error.SetErrorString("insert operation takes an array index followed by " 12283108e75SAdrian Prantl "one or more values"); 12383108e75SAdrian Prantl } 12483108e75SAdrian Prantl break; 12583108e75SAdrian Prantl 12683108e75SAdrian Prantl case eVarSetOperationRemove: 12783108e75SAdrian Prantl if (argc > 0) { 12883108e75SAdrian Prantl std::vector<int> remove_indexes; 12983108e75SAdrian Prantl bool all_indexes_valid = true; 13083108e75SAdrian Prantl size_t i; 13183108e75SAdrian Prantl for (i = 0; all_indexes_valid && i < argc; ++i) { 13283108e75SAdrian Prantl const int idx = 13383108e75SAdrian Prantl StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); 13483108e75SAdrian Prantl if (idx == INT32_MAX) 13583108e75SAdrian Prantl all_indexes_valid = false; 13683108e75SAdrian Prantl else 13783108e75SAdrian Prantl remove_indexes.push_back(idx); 13883108e75SAdrian Prantl } 13983108e75SAdrian Prantl 14083108e75SAdrian Prantl if (all_indexes_valid) { 14183108e75SAdrian Prantl size_t num_remove_indexes = remove_indexes.size(); 14283108e75SAdrian Prantl if (num_remove_indexes) { 14383108e75SAdrian Prantl // Sort and then erase in reverse so indexes are always valid 14483108e75SAdrian Prantl llvm::sort(remove_indexes.begin(), remove_indexes.end()); 14583108e75SAdrian Prantl for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) { 14683108e75SAdrian Prantl m_current_value.Remove(j); 14783108e75SAdrian Prantl } 14883108e75SAdrian Prantl } 14983108e75SAdrian Prantl NotifyValueChanged(); 15083108e75SAdrian Prantl } else { 15183108e75SAdrian Prantl error.SetErrorStringWithFormat( 15283108e75SAdrian Prantl "invalid array index '%s', aborting remove operation", 15383108e75SAdrian Prantl args.GetArgumentAtIndex(i)); 15483108e75SAdrian Prantl } 15583108e75SAdrian Prantl } else { 15683108e75SAdrian Prantl error.SetErrorString("remove operation takes one or more array index"); 15783108e75SAdrian Prantl } 15883108e75SAdrian Prantl break; 15983108e75SAdrian Prantl 16083108e75SAdrian Prantl case eVarSetOperationInvalid: 16183108e75SAdrian Prantl error = OptionValue::SetValueFromString(value, op); 16283108e75SAdrian Prantl break; 16383108e75SAdrian Prantl } 16483108e75SAdrian Prantl return error; 16583108e75SAdrian Prantl } 16683108e75SAdrian Prantl 16783108e75SAdrian Prantl lldb::OptionValueSP OptionValueFileSpecList::DeepCopy() const { 16883108e75SAdrian Prantl std::lock_guard<std::recursive_mutex> lock(m_mutex); 16983108e75SAdrian Prantl return OptionValueSP(new OptionValueFileSpecList(m_current_value)); 17083108e75SAdrian Prantl } 171