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