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