1 //===-- OptionValueFormatEntity.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/OptionValueFormatEntity.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Stream.h"
18 #include "lldb/Core/StringList.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 
24 OptionValueFormatEntity::OptionValueFormatEntity (const char *default_format) :
25     OptionValue(),
26     m_current_format (),
27     m_default_format (),
28     m_current_entry (),
29     m_default_entry ()
30 {
31     if (default_format && default_format[0])
32     {
33         llvm::StringRef default_format_str(default_format);
34         Error error = FormatEntity::Parse(default_format_str, m_default_entry);
35         if (error.Success())
36         {
37             m_default_format = default_format;
38             m_current_format = default_format;
39             m_current_entry = m_default_entry;
40         }
41     }
42 }
43 
44 bool
45 OptionValueFormatEntity::Clear ()
46 {
47     m_current_entry = m_default_entry;
48     m_current_format = m_default_format;
49     m_value_was_set = false;
50     return true;
51 }
52 
53 
54 void
55 OptionValueFormatEntity::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
56 {
57     if (dump_mask & eDumpOptionType)
58         strm.Printf ("(%s)", GetTypeAsCString ());
59     if (dump_mask & eDumpOptionValue)
60     {
61         if (dump_mask & eDumpOptionType)
62             strm.PutCString (" = \"");
63         strm << m_current_format.c_str() << '"';
64     }
65 }
66 
67 Error
68 OptionValueFormatEntity::SetValueFromString (llvm::StringRef value_str,
69                                              VarSetOperationType op)
70 {
71     Error error;
72     switch (op)
73     {
74         case eVarSetOperationClear:
75             Clear();
76             NotifyValueChanged();
77             break;
78 
79         case eVarSetOperationReplace:
80         case eVarSetOperationAssign:
81             {
82                 // Check if the string starts with a quote character after removing leading and trailing spaces.
83                 // If it does start with a quote character, make sure it ends with the same quote character
84                 // and remove the quotes before we parse the format string. If the string doesn't start with
85                 // a quote, leave the string alone and parse as is.
86                 llvm::StringRef trimmed_value_str = value_str.trim();
87                 if (!trimmed_value_str.empty())
88                 {
89                     const char first_char = trimmed_value_str[0];
90                     if (first_char == '"' || first_char == '\'')
91                     {
92                         const size_t trimmed_len = trimmed_value_str.size();
93                         if (trimmed_len == 1 || value_str[trimmed_len-1] != first_char)
94                         {
95                             error.SetErrorStringWithFormat("mismatched quotes");
96                             return error;
97                         }
98                         value_str = trimmed_value_str.substr(1,trimmed_len-2);
99                     }
100                 }
101                 FormatEntity::Entry entry;
102                 error = FormatEntity::Parse(value_str, entry);
103                 if (error.Success())
104                 {
105                     m_current_entry = std::move(entry);
106                     m_current_format = value_str;
107                     m_value_was_set = true;
108                     NotifyValueChanged();
109                 }
110             }
111             break;
112 
113         case eVarSetOperationInsertBefore:
114         case eVarSetOperationInsertAfter:
115         case eVarSetOperationRemove:
116         case eVarSetOperationAppend:
117         case eVarSetOperationInvalid:
118             error = OptionValue::SetValueFromString (value_str, op);
119             break;
120     }
121     return error;
122 }
123 
124 lldb::OptionValueSP
125 OptionValueFormatEntity::DeepCopy () const
126 {
127     return OptionValueSP(new OptionValueFormatEntity(*this));
128 }
129 
130 size_t
131 OptionValueFormatEntity::AutoComplete (CommandInterpreter &interpreter,
132                                        const char *s,
133                                        int match_start_point,
134                                        int max_return_elements,
135                                        bool &word_complete,
136                                        StringList &matches)
137 {
138     return FormatEntity::AutoComplete (s, match_start_point, max_return_elements, word_complete, matches);
139 }
140 
141