1 //===-- OptionValueFileSpec.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Interpreter/OptionValueFileSpec.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/State.h"
17 #include "lldb/DataFormatters/FormatManager.h"
18 #include "lldb/Interpreter/Args.h"
19 #include "lldb/Interpreter/CommandCompletions.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 
26 OptionValueFileSpec::OptionValueFileSpec (bool resolve) :
27     OptionValue(),
28     m_current_value (),
29     m_default_value (),
30     m_data_sp(),
31     m_data_mod_time (),
32     m_completion_mask (CommandCompletions::eDiskFileCompletion),
33     m_resolve (resolve)
34 {
35 }
36 
37 OptionValueFileSpec::OptionValueFileSpec (const FileSpec &value,
38                                           bool resolve) :
39     OptionValue(),
40     m_current_value (value),
41     m_default_value (value),
42     m_data_sp(),
43     m_data_mod_time (),
44     m_completion_mask (CommandCompletions::eDiskFileCompletion),
45     m_resolve (resolve)
46 {
47 }
48 
49 OptionValueFileSpec::OptionValueFileSpec (const FileSpec &current_value,
50                                           const FileSpec &default_value,
51                                           bool resolve) :
52     OptionValue(),
53     m_current_value (current_value),
54     m_default_value (default_value),
55     m_data_sp(),
56     m_data_mod_time (),
57     m_completion_mask (CommandCompletions::eDiskFileCompletion),
58     m_resolve (resolve)
59 {
60 }
61 
62 void
63 OptionValueFileSpec::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
64 {
65     if (dump_mask & eDumpOptionType)
66         strm.Printf ("(%s)", GetTypeAsCString ());
67     if (dump_mask & eDumpOptionValue)
68     {
69         if (dump_mask & eDumpOptionType)
70             strm.PutCString (" = ");
71 
72         if (m_current_value)
73         {
74             strm << '"' << m_current_value.GetPath().c_str() << '"';
75         }
76     }
77 }
78 
79 Error
80 OptionValueFileSpec::SetValueFromString (llvm::StringRef value,
81                                           VarSetOperationType op)
82 {
83     Error error;
84     switch (op)
85     {
86     case eVarSetOperationClear:
87         Clear ();
88         NotifyValueChanged();
89         break;
90 
91     case eVarSetOperationReplace:
92     case eVarSetOperationAssign:
93         if (value.size() > 0)
94         {
95             // The setting value may have whitespace, double-quotes, or single-quotes around the file
96             // path to indicate that internal spaces are not word breaks.  Strip off any ws & quotes
97             // from the start and end of the file path - we aren't doing any word // breaking here so
98             // the quoting is unnecessary.  NB this will cause a problem if someone tries to specify
99             // a file path that legitimately begins or ends with a " or ' character, or whitespace.
100             value = value.trim("\"' \t");
101             m_value_was_set = true;
102             m_current_value.SetFile(value.str().c_str(), m_resolve);
103             m_data_sp.reset();
104             m_data_mod_time.Clear();
105             NotifyValueChanged();
106         }
107         else
108         {
109             error.SetErrorString("invalid value string");
110         }
111         break;
112 
113     case eVarSetOperationInsertBefore:
114     case eVarSetOperationInsertAfter:
115     case eVarSetOperationRemove:
116     case eVarSetOperationAppend:
117     case eVarSetOperationInvalid:
118         error = OptionValue::SetValueFromString (value, op);
119         break;
120     }
121     return error;
122 }
123 
124 lldb::OptionValueSP
125 OptionValueFileSpec::DeepCopy () const
126 {
127     return OptionValueSP(new OptionValueFileSpec(*this));
128 }
129 
130 
131 size_t
132 OptionValueFileSpec::AutoComplete (CommandInterpreter &interpreter,
133                                    const char *s,
134                                    int match_start_point,
135                                    int max_return_elements,
136                                    bool &word_complete,
137                                    StringList &matches)
138 {
139     word_complete = false;
140     matches.Clear();
141     CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
142                                                          m_completion_mask,
143                                                          s,
144                                                          match_start_point,
145                                                          max_return_elements,
146                                                          nullptr,
147                                                          word_complete,
148                                                          matches);
149     return matches.GetSize();
150 }
151 
152 
153 
154 const lldb::DataBufferSP &
155 OptionValueFileSpec::GetFileContents(bool null_terminate)
156 {
157     if (m_current_value)
158     {
159         const TimeValue file_mod_time = m_current_value.GetModificationTime();
160         if (m_data_sp && m_data_mod_time == file_mod_time)
161             return m_data_sp;
162         if (null_terminate)
163             m_data_sp = m_current_value.ReadFileContentsAsCString();
164         else
165             m_data_sp = m_current_value.ReadFileContents();
166         m_data_mod_time = file_mod_time;
167     }
168     return m_data_sp;
169 }
170 
171 
172