19dba64beSDimitry Andric //===-- OptionValueFileSpecList.cpp ---------------------------------------===//
29dba64beSDimitry Andric //
39dba64beSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49dba64beSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
59dba64beSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69dba64beSDimitry Andric //
79dba64beSDimitry Andric //===----------------------------------------------------------------------===//
89dba64beSDimitry Andric
99dba64beSDimitry Andric #include "lldb/Interpreter/OptionValueFileSpecList.h"
109dba64beSDimitry Andric
119dba64beSDimitry Andric #include "lldb/Utility/Args.h"
129dba64beSDimitry Andric #include "lldb/Utility/Stream.h"
139dba64beSDimitry Andric
149dba64beSDimitry Andric using namespace lldb;
159dba64beSDimitry Andric using namespace lldb_private;
169dba64beSDimitry Andric
DumpValue(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask)179dba64beSDimitry Andric void OptionValueFileSpecList::DumpValue(const ExecutionContext *exe_ctx,
189dba64beSDimitry Andric Stream &strm, uint32_t dump_mask) {
199dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> lock(m_mutex);
209dba64beSDimitry Andric if (dump_mask & eDumpOptionType)
219dba64beSDimitry Andric strm.Printf("(%s)", GetTypeAsCString());
229dba64beSDimitry Andric if (dump_mask & eDumpOptionValue) {
239dba64beSDimitry Andric const bool one_line = dump_mask & eDumpOptionCommand;
249dba64beSDimitry Andric const uint32_t size = m_current_value.GetSize();
259dba64beSDimitry Andric if (dump_mask & eDumpOptionType)
269dba64beSDimitry Andric strm.Printf(" =%s",
279dba64beSDimitry Andric (m_current_value.GetSize() > 0 && !one_line) ? "\n" : "");
289dba64beSDimitry Andric if (!one_line)
299dba64beSDimitry Andric strm.IndentMore();
309dba64beSDimitry Andric for (uint32_t i = 0; i < size; ++i) {
319dba64beSDimitry Andric if (!one_line) {
329dba64beSDimitry Andric strm.Indent();
339dba64beSDimitry Andric strm.Printf("[%u]: ", i);
349dba64beSDimitry Andric }
35480093f4SDimitry Andric m_current_value.GetFileSpecAtIndex(i).Dump(strm.AsRawOstream());
369dba64beSDimitry Andric if (one_line)
379dba64beSDimitry Andric strm << ' ';
389dba64beSDimitry Andric }
399dba64beSDimitry Andric if (!one_line)
409dba64beSDimitry Andric strm.IndentLess();
419dba64beSDimitry Andric }
429dba64beSDimitry Andric }
439dba64beSDimitry Andric
SetValueFromString(llvm::StringRef value,VarSetOperationType op)449dba64beSDimitry Andric Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value,
459dba64beSDimitry Andric VarSetOperationType op) {
469dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> lock(m_mutex);
479dba64beSDimitry Andric Status error;
489dba64beSDimitry Andric Args args(value.str());
499dba64beSDimitry Andric const size_t argc = args.GetArgumentCount();
509dba64beSDimitry Andric
519dba64beSDimitry Andric switch (op) {
529dba64beSDimitry Andric case eVarSetOperationClear:
539dba64beSDimitry Andric Clear();
549dba64beSDimitry Andric NotifyValueChanged();
559dba64beSDimitry Andric break;
569dba64beSDimitry Andric
579dba64beSDimitry Andric case eVarSetOperationReplace:
589dba64beSDimitry Andric if (argc > 1) {
59349cc55cSDimitry Andric uint32_t idx;
609dba64beSDimitry Andric const uint32_t count = m_current_value.GetSize();
61349cc55cSDimitry Andric if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) {
629dba64beSDimitry Andric error.SetErrorStringWithFormat(
63349cc55cSDimitry Andric "invalid file list index %s, index must be 0 through %u",
64349cc55cSDimitry Andric args.GetArgumentAtIndex(0), count);
659dba64beSDimitry Andric } else {
669dba64beSDimitry Andric for (size_t i = 1; i < argc; ++i, ++idx) {
679dba64beSDimitry Andric FileSpec file(args.GetArgumentAtIndex(i));
689dba64beSDimitry Andric if (idx < count)
699dba64beSDimitry Andric m_current_value.Replace(idx, file);
709dba64beSDimitry Andric else
719dba64beSDimitry Andric m_current_value.Append(file);
729dba64beSDimitry Andric }
739dba64beSDimitry Andric NotifyValueChanged();
749dba64beSDimitry Andric }
759dba64beSDimitry Andric } else {
769dba64beSDimitry Andric error.SetErrorString("replace operation takes an array index followed by "
779dba64beSDimitry Andric "one or more values");
789dba64beSDimitry Andric }
799dba64beSDimitry Andric break;
809dba64beSDimitry Andric
819dba64beSDimitry Andric case eVarSetOperationAssign:
829dba64beSDimitry Andric m_current_value.Clear();
839dba64beSDimitry Andric // Fall through to append case
84*bdd1243dSDimitry Andric [[fallthrough]];
859dba64beSDimitry Andric case eVarSetOperationAppend:
869dba64beSDimitry Andric if (argc > 0) {
879dba64beSDimitry Andric m_value_was_set = true;
889dba64beSDimitry Andric for (size_t i = 0; i < argc; ++i) {
899dba64beSDimitry Andric FileSpec file(args.GetArgumentAtIndex(i));
909dba64beSDimitry Andric m_current_value.Append(file);
919dba64beSDimitry Andric }
929dba64beSDimitry Andric NotifyValueChanged();
939dba64beSDimitry Andric } else {
949dba64beSDimitry Andric error.SetErrorString(
959dba64beSDimitry Andric "assign operation takes at least one file path argument");
969dba64beSDimitry Andric }
979dba64beSDimitry Andric break;
989dba64beSDimitry Andric
999dba64beSDimitry Andric case eVarSetOperationInsertBefore:
1009dba64beSDimitry Andric case eVarSetOperationInsertAfter:
1019dba64beSDimitry Andric if (argc > 1) {
102349cc55cSDimitry Andric uint32_t idx;
1039dba64beSDimitry Andric const uint32_t count = m_current_value.GetSize();
104349cc55cSDimitry Andric if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) {
1059dba64beSDimitry Andric error.SetErrorStringWithFormat(
106349cc55cSDimitry Andric "invalid insert file list index %s, index must be 0 through %u",
107349cc55cSDimitry Andric args.GetArgumentAtIndex(0), count);
1089dba64beSDimitry Andric } else {
1099dba64beSDimitry Andric if (op == eVarSetOperationInsertAfter)
1109dba64beSDimitry Andric ++idx;
1119dba64beSDimitry Andric for (size_t i = 1; i < argc; ++i, ++idx) {
1129dba64beSDimitry Andric FileSpec file(args.GetArgumentAtIndex(i));
1139dba64beSDimitry Andric m_current_value.Insert(idx, file);
1149dba64beSDimitry Andric }
1159dba64beSDimitry Andric NotifyValueChanged();
1169dba64beSDimitry Andric }
1179dba64beSDimitry Andric } else {
1189dba64beSDimitry Andric error.SetErrorString("insert operation takes an array index followed by "
1199dba64beSDimitry Andric "one or more values");
1209dba64beSDimitry Andric }
1219dba64beSDimitry Andric break;
1229dba64beSDimitry Andric
1239dba64beSDimitry Andric case eVarSetOperationRemove:
1249dba64beSDimitry Andric if (argc > 0) {
1259dba64beSDimitry Andric std::vector<int> remove_indexes;
1269dba64beSDimitry Andric bool all_indexes_valid = true;
1279dba64beSDimitry Andric size_t i;
1289dba64beSDimitry Andric for (i = 0; all_indexes_valid && i < argc; ++i) {
129349cc55cSDimitry Andric int idx;
130349cc55cSDimitry Andric if (!llvm::to_integer(args.GetArgumentAtIndex(i), idx))
1319dba64beSDimitry Andric all_indexes_valid = false;
1329dba64beSDimitry Andric else
1339dba64beSDimitry Andric remove_indexes.push_back(idx);
1349dba64beSDimitry Andric }
1359dba64beSDimitry Andric
1369dba64beSDimitry Andric if (all_indexes_valid) {
1379dba64beSDimitry Andric size_t num_remove_indexes = remove_indexes.size();
1389dba64beSDimitry Andric if (num_remove_indexes) {
1399dba64beSDimitry Andric // Sort and then erase in reverse so indexes are always valid
140fcaf7f86SDimitry Andric llvm::sort(remove_indexes);
1419dba64beSDimitry Andric for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) {
1429dba64beSDimitry Andric m_current_value.Remove(j);
1439dba64beSDimitry Andric }
1449dba64beSDimitry Andric }
1459dba64beSDimitry Andric NotifyValueChanged();
1469dba64beSDimitry Andric } else {
1479dba64beSDimitry Andric error.SetErrorStringWithFormat(
1489dba64beSDimitry Andric "invalid array index '%s', aborting remove operation",
1499dba64beSDimitry Andric args.GetArgumentAtIndex(i));
1509dba64beSDimitry Andric }
1519dba64beSDimitry Andric } else {
1529dba64beSDimitry Andric error.SetErrorString("remove operation takes one or more array index");
1539dba64beSDimitry Andric }
1549dba64beSDimitry Andric break;
1559dba64beSDimitry Andric
1569dba64beSDimitry Andric case eVarSetOperationInvalid:
1579dba64beSDimitry Andric error = OptionValue::SetValueFromString(value, op);
1589dba64beSDimitry Andric break;
1599dba64beSDimitry Andric }
1609dba64beSDimitry Andric return error;
1619dba64beSDimitry Andric }
1629dba64beSDimitry Andric
Clone() const163fe6060f1SDimitry Andric OptionValueSP OptionValueFileSpecList::Clone() const {
1649dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> lock(m_mutex);
165fe6060f1SDimitry Andric return Cloneable::Clone();
1669dba64beSDimitry Andric }
167