1 //===-- OptionValueString.cpp ------------------------------------*- C++
2 //-*-===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #include "lldb/Interpreter/OptionValueString.h"
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Core/Stream.h"
18 #include "lldb/Interpreter/Args.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 void OptionValueString::DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
24                                   uint32_t dump_mask) {
25   if (dump_mask & eDumpOptionType)
26     strm.Printf("(%s)", GetTypeAsCString());
27   if (dump_mask & eDumpOptionValue) {
28     if (dump_mask & eDumpOptionType)
29       strm.PutCString(" = ");
30     if (!m_current_value.empty() || m_value_was_set) {
31       if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) {
32         std::string expanded_escape_value;
33         Args::ExpandEscapedCharacters(m_current_value.c_str(),
34                                       expanded_escape_value);
35         if (dump_mask & eDumpOptionRaw)
36           strm.Printf("%s", expanded_escape_value.c_str());
37         else
38           strm.Printf("\"%s\"", expanded_escape_value.c_str());
39       } else {
40         if (dump_mask & eDumpOptionRaw)
41           strm.Printf("%s", m_current_value.c_str());
42         else
43           strm.Printf("\"%s\"", m_current_value.c_str());
44       }
45     }
46   }
47 }
48 
49 Error OptionValueString::SetValueFromString(llvm::StringRef value,
50                                             VarSetOperationType op) {
51   Error error;
52 
53   std::string value_str = value.str();
54   value = value.trim();
55   if (value.size() > 0) {
56     switch (value.front()) {
57     case '"':
58     case '\'': {
59       if (value.size() <= 1 || value.back() != value.front()) {
60         error.SetErrorString("mismatched quotes");
61         return error;
62       }
63       value = value.drop_front().drop_back();
64     } break;
65     }
66     value_str = value.str();
67   }
68 
69   switch (op) {
70   case eVarSetOperationInvalid:
71   case eVarSetOperationInsertBefore:
72   case eVarSetOperationInsertAfter:
73   case eVarSetOperationRemove:
74     if (m_validator) {
75       error = m_validator(value_str.c_str(), m_validator_baton);
76       if (error.Fail())
77         return error;
78     }
79     error = OptionValue::SetValueFromString(value, op);
80     break;
81 
82   case eVarSetOperationAppend: {
83     std::string new_value(m_current_value);
84     if (value.size() > 0) {
85       if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) {
86         std::string str;
87         Args::EncodeEscapeSequences(value_str.c_str(), str);
88         new_value.append(str);
89       } else
90         new_value.append(value);
91     }
92     if (m_validator) {
93       error = m_validator(new_value.c_str(), m_validator_baton);
94       if (error.Fail())
95         return error;
96     }
97     m_current_value.assign(new_value);
98     NotifyValueChanged();
99   } break;
100 
101   case eVarSetOperationClear:
102     Clear();
103     NotifyValueChanged();
104     break;
105 
106   case eVarSetOperationReplace:
107   case eVarSetOperationAssign:
108     if (m_validator) {
109       error = m_validator(value_str.c_str(), m_validator_baton);
110       if (error.Fail())
111         return error;
112     }
113     m_value_was_set = true;
114     if (m_options.Test(eOptionEncodeCharacterEscapeSequences)) {
115       Args::EncodeEscapeSequences(value_str.c_str(), m_current_value);
116     } else {
117       SetCurrentValue(value_str);
118     }
119     NotifyValueChanged();
120     break;
121   }
122   return error;
123 }
124 
125 lldb::OptionValueSP OptionValueString::DeepCopy() const {
126   return OptionValueSP(new OptionValueString(*this));
127 }
128 
129 Error OptionValueString::SetCurrentValue(llvm::StringRef value) {
130   if (m_validator) {
131     Error error(m_validator(value.str().c_str(), m_validator_baton));
132     if (error.Fail())
133       return error;
134   }
135   m_current_value.assign(value);
136   return Error();
137 }
138 
139 Error OptionValueString::AppendToCurrentValue(const char *value) {
140   if (value && value[0]) {
141     if (m_validator) {
142       std::string new_value(m_current_value);
143       new_value.append(value);
144       Error error(m_validator(value, m_validator_baton));
145       if (error.Fail())
146         return error;
147       m_current_value.assign(new_value);
148     } else
149       m_current_value.append(value);
150   }
151   return Error();
152 }
153