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