1254721Semaste//===-- OptionValueFileSpec.cpp ---------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "lldb/Interpreter/OptionValueFileSpec.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/Core/State.h"
19254721Semaste#include "lldb/DataFormatters/FormatManager.h"
20254721Semaste#include "lldb/Interpreter/Args.h"
21254721Semaste#include "lldb/Interpreter/CommandCompletions.h"
22254721Semaste
23254721Semasteusing namespace lldb;
24254721Semasteusing namespace lldb_private;
25254721Semaste
26254721Semaste
27254721SemasteOptionValueFileSpec::OptionValueFileSpec () :
28254721Semaste    OptionValue(),
29254721Semaste    m_current_value (),
30254721Semaste    m_default_value (),
31254721Semaste    m_data_sp(),
32254721Semaste    m_completion_mask (CommandCompletions::eDiskFileCompletion)
33254721Semaste{
34254721Semaste}
35254721Semaste
36254721SemasteOptionValueFileSpec::OptionValueFileSpec (const FileSpec &value) :
37254721Semaste    OptionValue(),
38254721Semaste    m_current_value (value),
39254721Semaste    m_default_value (value),
40254721Semaste    m_data_sp(),
41254721Semaste    m_completion_mask (CommandCompletions::eDiskFileCompletion)
42254721Semaste{
43254721Semaste}
44254721Semaste
45254721SemasteOptionValueFileSpec::OptionValueFileSpec (const FileSpec &current_value,
46254721Semaste                                          const FileSpec &default_value) :
47254721Semaste    OptionValue(),
48254721Semaste    m_current_value (current_value),
49254721Semaste    m_default_value (default_value),
50254721Semaste    m_data_sp(),
51254721Semaste    m_completion_mask (CommandCompletions::eDiskFileCompletion)
52254721Semaste{
53254721Semaste}
54254721Semaste
55254721Semastevoid
56254721SemasteOptionValueFileSpec::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
57254721Semaste{
58254721Semaste    if (dump_mask & eDumpOptionType)
59254721Semaste        strm.Printf ("(%s)", GetTypeAsCString ());
60254721Semaste    if (dump_mask & eDumpOptionValue)
61254721Semaste    {
62254721Semaste        if (dump_mask & eDumpOptionType)
63254721Semaste            strm.PutCString (" = ");
64254721Semaste
65254721Semaste        if (m_current_value)
66254721Semaste        {
67254721Semaste            strm << '"' << m_current_value.GetPath().c_str() << '"';
68254721Semaste        }
69254721Semaste    }
70254721Semaste}
71254721Semaste
72254721SemasteError
73254721SemasteOptionValueFileSpec::SetValueFromCString (const char *value_cstr,
74254721Semaste                                          VarSetOperationType op)
75254721Semaste{
76254721Semaste    Error error;
77254721Semaste    switch (op)
78254721Semaste    {
79254721Semaste    case eVarSetOperationClear:
80254721Semaste        Clear ();
81254721Semaste        break;
82254721Semaste
83254721Semaste    case eVarSetOperationReplace:
84254721Semaste    case eVarSetOperationAssign:
85254721Semaste        if (value_cstr && value_cstr[0])
86254721Semaste        {
87263363Semaste            // The setting value may have whitespace, double-quotes, or single-quotes around the file
88263363Semaste            // path to indicate that internal spaces are not word breaks.  Strip off any ws & quotes
89263363Semaste            // from the start and end of the file path - we aren't doing any word // breaking here so
90263363Semaste            // the quoting is unnecessary.  NB this will cause a problem if someone tries to specify
91263363Semaste            // a file path that legitimately begins or ends with a " or ' character, or whitespace.
92263363Semaste            std::string filepath(value_cstr);
93263363Semaste            auto prefix_chars_to_trim = filepath.find_first_not_of ("\"' \t");
94263363Semaste            if (prefix_chars_to_trim != std::string::npos && prefix_chars_to_trim > 0)
95263363Semaste                filepath.erase(0, prefix_chars_to_trim);
96263363Semaste            auto suffix_chars_to_trim = filepath.find_last_not_of ("\"' \t");
97263363Semaste            if (suffix_chars_to_trim != std::string::npos && suffix_chars_to_trim < filepath.size())
98263363Semaste                filepath.erase (suffix_chars_to_trim + 1);
99263363Semaste
100263363Semaste            m_value_was_set = true;
101263363Semaste            m_current_value.SetFile(filepath.c_str(), true);
102254721Semaste        }
103254721Semaste        else
104254721Semaste        {
105254721Semaste            error.SetErrorString("invalid value string");
106254721Semaste        }
107254721Semaste        break;
108254721Semaste
109254721Semaste    case eVarSetOperationInsertBefore:
110254721Semaste    case eVarSetOperationInsertAfter:
111254721Semaste    case eVarSetOperationRemove:
112254721Semaste    case eVarSetOperationAppend:
113254721Semaste    case eVarSetOperationInvalid:
114254721Semaste        error = OptionValue::SetValueFromCString (value_cstr, op);
115254721Semaste        break;
116254721Semaste    }
117254721Semaste    return error;
118254721Semaste}
119254721Semaste
120254721Semastelldb::OptionValueSP
121254721SemasteOptionValueFileSpec::DeepCopy () const
122254721Semaste{
123254721Semaste    return OptionValueSP(new OptionValueFileSpec(*this));
124254721Semaste}
125254721Semaste
126254721Semaste
127254721Semastesize_t
128254721SemasteOptionValueFileSpec::AutoComplete (CommandInterpreter &interpreter,
129254721Semaste                                   const char *s,
130254721Semaste                                   int match_start_point,
131254721Semaste                                   int max_return_elements,
132254721Semaste                                   bool &word_complete,
133254721Semaste                                   StringList &matches)
134254721Semaste{
135254721Semaste    word_complete = false;
136254721Semaste    matches.Clear();
137254721Semaste    CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
138254721Semaste                                                         m_completion_mask,
139254721Semaste                                                         s,
140254721Semaste                                                         match_start_point,
141254721Semaste                                                         max_return_elements,
142254721Semaste                                                         NULL,
143254721Semaste                                                         word_complete,
144254721Semaste                                                         matches);
145254721Semaste    return matches.GetSize();
146254721Semaste}
147254721Semaste
148254721Semaste
149254721Semaste
150254721Semasteconst lldb::DataBufferSP &
151254721SemasteOptionValueFileSpec::GetFileContents(bool null_terminate)
152254721Semaste{
153254721Semaste    if (!m_data_sp && m_current_value)
154254721Semaste    {
155254721Semaste        if (null_terminate)
156254721Semaste            m_data_sp = m_current_value.ReadFileContentsAsCString();
157254721Semaste        else
158254721Semaste            m_data_sp = m_current_value.ReadFileContents();
159254721Semaste    }
160254721Semaste    return m_data_sp;
161254721Semaste}
162254721Semaste
163254721Semaste
164