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(format: "(%s)" , GetTypeAsCString()); |
22 | if (dump_mask & eDumpOptionValue) { |
23 | if (dump_mask & eDumpOptionType) |
24 | strm.PutCString(cstr: " = " ); |
25 | if (!m_current_value.empty() || m_value_was_set) { |
26 | if (m_options.Test(bit: eOptionEncodeCharacterEscapeSequences)) { |
27 | std::string expanded_escape_value; |
28 | Args::ExpandEscapedCharacters(src: m_current_value.c_str(), |
29 | dst&: expanded_escape_value); |
30 | if (dump_mask & eDumpOptionRaw) |
31 | strm.Printf(format: "%s" , expanded_escape_value.c_str()); |
32 | else |
33 | strm.Printf(format: "\"%s\"" , expanded_escape_value.c_str()); |
34 | } else { |
35 | if (dump_mask & eDumpOptionRaw) |
36 | strm.Printf(format: "%s" , m_current_value.c_str()); |
37 | else |
38 | strm.Printf(format: "\"%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(bit: eOptionEncodeCharacterEscapeSequences)) { |
81 | std::string str; |
82 | Args::EncodeEscapeSequences(src: value_str.c_str(), dst&: str); |
83 | new_value.append(str: str); |
84 | } else |
85 | new_value.append(str: 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(str: 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(bit: eOptionEncodeCharacterEscapeSequences)) { |
110 | Args::EncodeEscapeSequences(src: value_str.c_str(), dst&: 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(str: 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(s: value); |
135 | Status error(m_validator(value, m_validator_baton)); |
136 | if (error.Fail()) |
137 | return error; |
138 | m_current_value.assign(str: new_value); |
139 | } else |
140 | m_current_value.append(s: value); |
141 | } |
142 | return Status(); |
143 | } |
144 | |