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