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