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 
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 
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 
120 Status OptionValueString::SetCurrentValue(llvm::StringRef value) {
121   if (m_validator) {
122     Status error(m_validator(value.str().c_str(), m_validator_baton));
123     if (error.Fail())
124       return error;
125   }
126   m_current_value.assign(std::string(value));
127   return Status();
128 }
129 
130 Status OptionValueString::AppendToCurrentValue(const char *value) {
131   if (value && value[0]) {
132     if (m_validator) {
133       std::string new_value(m_current_value);
134       new_value.append(value);
135       Status error(m_validator(value, m_validator_baton));
136       if (error.Fail())
137         return error;
138       m_current_value.assign(new_value);
139     } else
140       m_current_value.append(value);
141   }
142   return Status();
143 }
144