xref: /freebsd-src/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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