1 //===-- OptionValueFileSpec.cpp -------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Interpreter/OptionValueFileSpec.h"
10 
11 #include "lldb/DataFormatters/FormatManager.h"
12 #include "lldb/Host/FileSystem.h"
13 #include "lldb/Interpreter/CommandCompletions.h"
14 #include "lldb/Interpreter/CommandInterpreter.h"
15 #include "lldb/Utility/Args.h"
16 #include "lldb/Utility/State.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 OptionValueFileSpec::OptionValueFileSpec(bool resolve)
22     : m_completion_mask(CommandCompletions::eDiskFileCompletion),
23       m_resolve(resolve) {}
24 
25 OptionValueFileSpec::OptionValueFileSpec(const FileSpec &value, bool resolve)
26     : m_current_value(value), m_default_value(value),
27       m_completion_mask(CommandCompletions::eDiskFileCompletion),
28       m_resolve(resolve) {}
29 
30 OptionValueFileSpec::OptionValueFileSpec(const FileSpec &current_value,
31                                          const FileSpec &default_value,
32                                          bool resolve)
33     : m_current_value(current_value), m_default_value(default_value),
34       m_completion_mask(CommandCompletions::eDiskFileCompletion),
35       m_resolve(resolve) {}
36 
37 void OptionValueFileSpec::DumpValue(const ExecutionContext *exe_ctx,
38                                     Stream &strm, uint32_t dump_mask) {
39   if (dump_mask & eDumpOptionType)
40     strm.Printf("(%s)", GetTypeAsCString());
41   if (dump_mask & eDumpOptionValue) {
42     if (dump_mask & eDumpOptionType)
43       strm.PutCString(" = ");
44 
45     if (m_current_value) {
46       strm << '"' << m_current_value.GetPath().c_str() << '"';
47     }
48   }
49 }
50 
51 Status OptionValueFileSpec::SetValueFromString(llvm::StringRef value,
52                                                VarSetOperationType op) {
53   Status error;
54   switch (op) {
55   case eVarSetOperationClear:
56     Clear();
57     NotifyValueChanged();
58     break;
59 
60   case eVarSetOperationReplace:
61   case eVarSetOperationAssign:
62     if (value.size() > 0) {
63       value = value.trim("\"' \t");
64       m_value_was_set = true;
65       m_current_value.SetFile(value.str(), FileSpec::Style::native);
66       if (m_resolve)
67         FileSystem::Instance().Resolve(m_current_value);
68       m_data_sp.reset();
69       m_data_mod_time = llvm::sys::TimePoint<>();
70       NotifyValueChanged();
71     } else {
72       error.SetErrorString("invalid value string");
73     }
74     break;
75 
76   case eVarSetOperationInsertBefore:
77   case eVarSetOperationInsertAfter:
78   case eVarSetOperationRemove:
79   case eVarSetOperationAppend:
80   case eVarSetOperationInvalid:
81     error = OptionValue::SetValueFromString(value, op);
82     break;
83   }
84   return error;
85 }
86 
87 lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const {
88   return OptionValueSP(new OptionValueFileSpec(*this));
89 }
90 
91 void OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
92                                        CompletionRequest &request) {
93   CommandCompletions::InvokeCommonCompletionCallbacks(
94       interpreter, m_completion_mask, request, nullptr);
95 }
96 
97 const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() {
98   if (m_current_value) {
99     const auto file_mod_time = FileSystem::Instance().GetModificationTime(m_current_value);
100     if (m_data_sp && m_data_mod_time == file_mod_time)
101       return m_data_sp;
102     m_data_sp =
103         FileSystem::Instance().CreateDataBuffer(m_current_value.GetPath());
104     m_data_mod_time = file_mod_time;
105   }
106   return m_data_sp;
107 }
108