1ac7ddfbfSEd Maste //===-- OptionValueFileSpec.cpp ---------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionValueFileSpec.h"
11ac7ddfbfSEd Maste 
12ac7ddfbfSEd Maste #include "lldb/DataFormatters/FormatManager.h"
13435933ddSDimitry Andric #include "lldb/Host/FileSystem.h"
14ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandCompletions.h"
15435933ddSDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
164ba319b5SDimitry Andric #include "lldb/Utility/Args.h"
17*b5893f02SDimitry Andric #include "lldb/Utility/State.h"
18ac7ddfbfSEd Maste 
19ac7ddfbfSEd Maste using namespace lldb;
20ac7ddfbfSEd Maste using namespace lldb_private;
21ac7ddfbfSEd Maste 
OptionValueFileSpec(bool resolve)22435933ddSDimitry Andric OptionValueFileSpec::OptionValueFileSpec(bool resolve)
23435933ddSDimitry Andric     : OptionValue(), m_current_value(), m_default_value(), m_data_sp(),
241c3bbb01SEd Maste       m_data_mod_time(),
251c3bbb01SEd Maste       m_completion_mask(CommandCompletions::eDiskFileCompletion),
26435933ddSDimitry Andric       m_resolve(resolve) {}
27ac7ddfbfSEd Maste 
OptionValueFileSpec(const FileSpec & value,bool resolve)28435933ddSDimitry Andric OptionValueFileSpec::OptionValueFileSpec(const FileSpec &value, bool resolve)
29435933ddSDimitry Andric     : OptionValue(), m_current_value(value), m_default_value(value),
30435933ddSDimitry Andric       m_data_sp(), m_data_mod_time(),
311c3bbb01SEd Maste       m_completion_mask(CommandCompletions::eDiskFileCompletion),
32435933ddSDimitry Andric       m_resolve(resolve) {}
33ac7ddfbfSEd Maste 
OptionValueFileSpec(const FileSpec & current_value,const FileSpec & default_value,bool resolve)34ac7ddfbfSEd Maste OptionValueFileSpec::OptionValueFileSpec(const FileSpec &current_value,
351c3bbb01SEd Maste                                          const FileSpec &default_value,
36435933ddSDimitry Andric                                          bool resolve)
37435933ddSDimitry Andric     : OptionValue(), m_current_value(current_value),
38435933ddSDimitry Andric       m_default_value(default_value), m_data_sp(), m_data_mod_time(),
391c3bbb01SEd Maste       m_completion_mask(CommandCompletions::eDiskFileCompletion),
40435933ddSDimitry Andric       m_resolve(resolve) {}
41ac7ddfbfSEd Maste 
DumpValue(const ExecutionContext * exe_ctx,Stream & strm,uint32_t dump_mask)42435933ddSDimitry Andric void OptionValueFileSpec::DumpValue(const ExecutionContext *exe_ctx,
43435933ddSDimitry Andric                                     Stream &strm, uint32_t dump_mask) {
44ac7ddfbfSEd Maste   if (dump_mask & eDumpOptionType)
45ac7ddfbfSEd Maste     strm.Printf("(%s)", GetTypeAsCString());
46435933ddSDimitry Andric   if (dump_mask & eDumpOptionValue) {
47ac7ddfbfSEd Maste     if (dump_mask & eDumpOptionType)
48ac7ddfbfSEd Maste       strm.PutCString(" = ");
49ac7ddfbfSEd Maste 
50435933ddSDimitry Andric     if (m_current_value) {
51ac7ddfbfSEd Maste       strm << '"' << m_current_value.GetPath().c_str() << '"';
52ac7ddfbfSEd Maste     }
53ac7ddfbfSEd Maste   }
54ac7ddfbfSEd Maste }
55ac7ddfbfSEd Maste 
SetValueFromString(llvm::StringRef value,VarSetOperationType op)565517e702SDimitry Andric Status OptionValueFileSpec::SetValueFromString(llvm::StringRef value,
57435933ddSDimitry Andric                                                VarSetOperationType op) {
585517e702SDimitry Andric   Status error;
59435933ddSDimitry Andric   switch (op) {
60ac7ddfbfSEd Maste   case eVarSetOperationClear:
61ac7ddfbfSEd Maste     Clear();
627aa51b79SEd Maste     NotifyValueChanged();
63ac7ddfbfSEd Maste     break;
64ac7ddfbfSEd Maste 
65ac7ddfbfSEd Maste   case eVarSetOperationReplace:
66ac7ddfbfSEd Maste   case eVarSetOperationAssign:
67435933ddSDimitry Andric     if (value.size() > 0) {
68435933ddSDimitry Andric       // The setting value may have whitespace, double-quotes, or single-quotes
694ba319b5SDimitry Andric       // around the file path to indicate that internal spaces are not word
704ba319b5SDimitry Andric       // breaks.  Strip off any ws & quotes from the start and end of the file
714ba319b5SDimitry Andric       // path - we aren't doing any word // breaking here so the quoting is
724ba319b5SDimitry Andric       // unnecessary.  NB this will cause a problem if someone tries to specify
73435933ddSDimitry Andric       // a file path that legitimately begins or ends with a " or ' character,
74435933ddSDimitry Andric       // or whitespace.
751c3bbb01SEd Maste       value = value.trim("\"' \t");
76ac7ddfbfSEd Maste       m_value_was_set = true;
77*b5893f02SDimitry Andric       m_current_value.SetFile(value.str(), FileSpec::Style::native);
78*b5893f02SDimitry Andric       if (m_resolve)
79*b5893f02SDimitry Andric         FileSystem::Instance().Resolve(m_current_value);
800127ef0fSEd Maste       m_data_sp.reset();
81435933ddSDimitry Andric       m_data_mod_time = llvm::sys::TimePoint<>();
827aa51b79SEd Maste       NotifyValueChanged();
83435933ddSDimitry Andric     } else {
84ac7ddfbfSEd Maste       error.SetErrorString("invalid value string");
85ac7ddfbfSEd Maste     }
86ac7ddfbfSEd Maste     break;
87ac7ddfbfSEd Maste 
88ac7ddfbfSEd Maste   case eVarSetOperationInsertBefore:
89ac7ddfbfSEd Maste   case eVarSetOperationInsertAfter:
90ac7ddfbfSEd Maste   case eVarSetOperationRemove:
91ac7ddfbfSEd Maste   case eVarSetOperationAppend:
92ac7ddfbfSEd Maste   case eVarSetOperationInvalid:
931c3bbb01SEd Maste     error = OptionValue::SetValueFromString(value, op);
94ac7ddfbfSEd Maste     break;
95ac7ddfbfSEd Maste   }
96ac7ddfbfSEd Maste   return error;
97ac7ddfbfSEd Maste }
98ac7ddfbfSEd Maste 
DeepCopy() const99435933ddSDimitry Andric lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const {
100ac7ddfbfSEd Maste   return OptionValueSP(new OptionValueFileSpec(*this));
101ac7ddfbfSEd Maste }
102ac7ddfbfSEd Maste 
AutoComplete(CommandInterpreter & interpreter,CompletionRequest & request)1034ba319b5SDimitry Andric size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
1044ba319b5SDimitry Andric                                          CompletionRequest &request) {
1054ba319b5SDimitry Andric   request.SetWordComplete(false);
106435933ddSDimitry Andric   CommandCompletions::InvokeCommonCompletionCallbacks(
1074ba319b5SDimitry Andric       interpreter, m_completion_mask, request, nullptr);
1084ba319b5SDimitry Andric   return request.GetNumberOfMatches();
109ac7ddfbfSEd Maste }
110ac7ddfbfSEd Maste 
GetFileContents()11138638513SDimitry Andric const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() {
112435933ddSDimitry Andric   if (m_current_value) {
113*b5893f02SDimitry Andric     const auto file_mod_time = FileSystem::Instance().GetModificationTime(m_current_value);
1141c3bbb01SEd Maste     if (m_data_sp && m_data_mod_time == file_mod_time)
1151c3bbb01SEd Maste       return m_data_sp;
116*b5893f02SDimitry Andric     m_data_sp =
117*b5893f02SDimitry Andric         FileSystem::Instance().CreateDataBuffer(m_current_value.GetPath());
1181c3bbb01SEd Maste     m_data_mod_time = file_mod_time;
119ac7ddfbfSEd Maste   }
120ac7ddfbfSEd Maste   return m_data_sp;
121ac7ddfbfSEd Maste }
122