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::SetValueFromString (llvm::StringRef value,
55                                         VarSetOperationType op)
56 {
57     Error error;
58 
59     std::string value_str = value.str();
60     value = value.trim();
61     if (value.size() > 0)
62     {
63         switch (value.front())
64         {
65         case '"':
66         case '\'':
67             {
68                 if (value.size() <= 1 || value.back() != value.front())
69                 {
70                     error.SetErrorString("mismatched quotes");
71                     return error;
72                 }
73                 value = value.drop_front().drop_back();
74             }
75             break;
76         }
77         value_str = value.str();
78     }
79 
80     switch (op)
81     {
82     case eVarSetOperationInvalid:
83     case eVarSetOperationInsertBefore:
84     case eVarSetOperationInsertAfter:
85     case eVarSetOperationRemove:
86         if (m_validator)
87         {
88             error = m_validator(value_str.c_str(),m_validator_baton);
89             if (error.Fail())
90                 return error;
91         }
92         error = OptionValue::SetValueFromString (value, op);
93         break;
94 
95     case eVarSetOperationAppend:
96         {
97             std::string new_value(m_current_value);
98             if (value.size() > 0)
99             {
100                 if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
101                 {
102                     std::string str;
103                     Args::EncodeEscapeSequences (value_str.c_str(), str);
104                     new_value.append(str);
105                 }
106                 else
107                     new_value.append(value);
108             }
109             if (m_validator)
110             {
111                 error = m_validator(new_value.c_str(),m_validator_baton);
112                 if (error.Fail())
113                     return error;
114             }
115             m_current_value.assign(new_value);
116             NotifyValueChanged();
117         }
118         break;
119 
120     case eVarSetOperationClear:
121         Clear ();
122         NotifyValueChanged();
123         break;
124 
125     case eVarSetOperationReplace:
126     case eVarSetOperationAssign:
127         if (m_validator)
128         {
129             error = m_validator(value_str.c_str(), m_validator_baton);
130             if (error.Fail())
131                 return error;
132         }
133         m_value_was_set = true;
134         if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
135         {
136             Args::EncodeEscapeSequences (value_str.c_str(), m_current_value);
137         }
138         else
139         {
140             SetCurrentValue (value_str.c_str());
141         }
142         NotifyValueChanged();
143         break;
144     }
145     return error;
146 }
147 
148 
149 lldb::OptionValueSP
150 OptionValueString::DeepCopy () const
151 {
152     return OptionValueSP(new OptionValueString(*this));
153 }
154 
155 Error
156 OptionValueString::SetCurrentValue (const char *value)
157 {
158     if (m_validator)
159     {
160         Error error(m_validator(value,m_validator_baton));
161         if (error.Fail())
162             return error;
163     }
164     if (value && value[0])
165         m_current_value.assign (value);
166     else
167         m_current_value.clear();
168     return Error();
169 }
170 
171 Error
172 OptionValueString::AppendToCurrentValue (const char *value)
173 {
174     if (value && value[0])
175     {
176         if (m_validator)
177         {
178             std::string new_value(m_current_value);
179             new_value.append(value);
180             Error error(m_validator(value,m_validator_baton));
181             if (error.Fail())
182                 return error;
183             m_current_value.assign(new_value);
184         }
185         else
186             m_current_value.append (value);
187     }
188     return Error();
189 }
190