1 //===-- OptionValueString.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/OptionValueString.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Stream.h"
17 #include "lldb/Interpreter/Args.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 void
23 OptionValueString::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
24 {
25     if (dump_mask & eDumpOptionType)
26         strm.Printf ("(%s)", GetTypeAsCString ());
27     if (dump_mask & eDumpOptionValue)
28     {
29         if (dump_mask & eDumpOptionType)
30             strm.PutCString (" = ");
31         if (!m_current_value.empty() || m_value_was_set)
32         {
33             if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
34             {
35                 std::string expanded_escape_value;
36                 Args::ExpandEscapedCharacters(m_current_value.c_str(), expanded_escape_value);
37                 if (dump_mask & eDumpOptionRaw)
38                     strm.Printf ("%s", expanded_escape_value.c_str());
39                 else
40                     strm.Printf ("\"%s\"", expanded_escape_value.c_str());
41             }
42             else
43             {
44                 if (dump_mask & eDumpOptionRaw)
45                     strm.Printf ("%s", m_current_value.c_str());
46                 else
47                     strm.Printf ("\"%s\"", m_current_value.c_str());
48             }
49         }
50     }
51 }
52 
53 Error
54 OptionValueString::SetValueFromCString (const char *value_cstr,
55                                         VarSetOperationType op)
56 {
57     Error error;
58 
59     std::string value_str_no_quotes;
60     llvm::StringRef trimmed = value_cstr ? llvm::StringRef(value_cstr).trim() : llvm::StringRef();
61     if (trimmed.size() > 0)
62     {
63         switch (trimmed.front())
64         {
65         case '"':
66         case '\'':
67             {
68                 if (trimmed.size() <= 1 || trimmed.back() != trimmed.front())
69                 {
70                     error.SetErrorString("mismatched quotes");
71                     return error;
72                 }
73                 trimmed = trimmed.drop_front().drop_back().str();
74             }
75             break;
76         }
77         value_str_no_quotes = trimmed.str();
78         value_cstr = value_str_no_quotes.c_str();
79     }
80 
81     switch (op)
82     {
83     case eVarSetOperationInvalid:
84     case eVarSetOperationInsertBefore:
85     case eVarSetOperationInsertAfter:
86     case eVarSetOperationRemove:
87         if (m_validator)
88         {
89             error = m_validator(value_cstr,m_validator_baton);
90             if (error.Fail())
91                 return error;
92         }
93         error = OptionValue::SetValueFromCString (value_cstr, op);
94         break;
95 
96     case eVarSetOperationAppend:
97         {
98             std::string new_value(m_current_value);
99             if (value_cstr && value_cstr[0])
100             {
101                 if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
102                 {
103                     std::string str;
104                     Args::EncodeEscapeSequences (value_cstr, str);
105                     new_value.append(str);
106                 }
107                 else
108                     new_value.append(value_cstr);
109             }
110             if (m_validator)
111             {
112                 error = m_validator(new_value.c_str(),m_validator_baton);
113                 if (error.Fail())
114                     return error;
115             }
116             m_current_value.assign(new_value);
117             NotifyValueChanged();
118         }
119         break;
120 
121     case eVarSetOperationClear:
122         Clear ();
123         NotifyValueChanged();
124         break;
125 
126     case eVarSetOperationReplace:
127     case eVarSetOperationAssign:
128         if (m_validator)
129         {
130             error = m_validator(value_cstr,m_validator_baton);
131             if (error.Fail())
132                 return error;
133         }
134         m_value_was_set = true;
135         if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
136         {
137             Args::EncodeEscapeSequences (value_cstr, m_current_value);
138         }
139         else
140         {
141             SetCurrentValue (value_cstr);
142         }
143         NotifyValueChanged();
144         break;
145     }
146     return error;
147 }
148 
149 
150 lldb::OptionValueSP
151 OptionValueString::DeepCopy () const
152 {
153     return OptionValueSP(new OptionValueString(*this));
154 }
155 
156 Error
157 OptionValueString::SetCurrentValue (const char *value)
158 {
159     if (m_validator)
160     {
161         Error error(m_validator(value,m_validator_baton));
162         if (error.Fail())
163             return error;
164     }
165     if (value && value[0])
166         m_current_value.assign (value);
167     else
168         m_current_value.clear();
169     return Error();
170 }
171 
172 Error
173 OptionValueString::AppendToCurrentValue (const char *value)
174 {
175     if (value && value[0])
176     {
177         if (m_validator)
178         {
179             std::string new_value(m_current_value);
180             new_value.append(value);
181             Error error(m_validator(value,m_validator_baton));
182             if (error.Fail())
183                 return error;
184             m_current_value.assign(new_value);
185         }
186         else
187             m_current_value.append (value);
188     }
189     return Error();
190 }
191