1 //===-- OptionGroupFormat.cpp ---------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Interpreter/OptionGroupFormat.h"
11 #include "lldb/Host/OptionParser.h"
12 #include "lldb/Interpreter/CommandInterpreter.h"
13 #include "lldb/Target/ExecutionContext.h"
14 #include "lldb/Target/Target.h"
17 using namespace lldb_private
;
19 static constexpr OptionDefinition g_default_option_definitions
[] = {
20 {LLDB_OPT_SET_1
, false, "format", 'f', OptionParser::eRequiredArgument
,
21 nullptr, {}, 0, eArgTypeFormat
,
22 "Specify a format to be used for display."},
23 {LLDB_OPT_SET_2
, false, "gdb-format", 'G', OptionParser::eRequiredArgument
,
24 nullptr, {}, 0, eArgTypeGDBFormat
,
25 "Specify a format using a GDB format specifier string."},
26 {LLDB_OPT_SET_3
, false, "size", 's', OptionParser::eRequiredArgument
,
27 nullptr, {}, 0, eArgTypeByteSize
,
28 "The size in bytes to use when displaying with the selected format."},
29 {LLDB_OPT_SET_4
, false, "count", 'c', OptionParser::eRequiredArgument
,
30 nullptr, {}, 0, eArgTypeCount
,
31 "The number of total items to display."},
34 OptionGroupFormat::OptionGroupFormat(
35 lldb::Format default_format
, uint64_t default_byte_size
,
36 uint64_t default_count
, OptionGroupFormatUsageTextVector usage_text_vector
)
37 : m_format(default_format
, default_format
),
38 m_byte_size(default_byte_size
, default_byte_size
),
39 m_count(default_count
, default_count
), m_prev_gdb_format('x'),
40 m_prev_gdb_size('w'), m_has_gdb_format(false) {
41 // Copy the default option definitions.
42 std::copy(std::begin(g_default_option_definitions
),
43 std::end(g_default_option_definitions
),
44 std::begin(m_option_definitions
));
46 for (auto usage_text_tuple
: usage_text_vector
) {
47 switch (std::get
<0>(usage_text_tuple
)) {
49 m_option_definitions
[0].usage_text
= std::get
<1>(usage_text_tuple
);
51 case eArgTypeByteSize
:
52 m_option_definitions
[2].usage_text
= std::get
<1>(usage_text_tuple
);
55 llvm_unreachable("Unimplemented option");
60 llvm::ArrayRef
<OptionDefinition
> OptionGroupFormat::GetDefinitions() {
61 auto result
= llvm::ArrayRef(m_option_definitions
);
62 if (m_byte_size
.GetDefaultValue() < UINT64_MAX
) {
63 if (m_count
.GetDefaultValue() < UINT64_MAX
)
66 return result
.take_front(3);
68 return result
.take_front(2);
71 Status
OptionGroupFormat::SetOptionValue(uint32_t option_idx
,
72 llvm::StringRef option_arg
,
73 ExecutionContext
*execution_context
) {
75 const int short_option
= m_option_definitions
[option_idx
].short_option
;
77 switch (short_option
) {
79 error
= m_format
.SetValueFromString(option_arg
);
83 if (m_count
.GetDefaultValue() == 0) {
84 error
= Status::FromErrorString("--count option is disabled");
86 error
= m_count
.SetValueFromString(option_arg
);
87 if (m_count
.GetCurrentValue() == 0)
88 error
= Status::FromErrorStringWithFormat(
89 "invalid --count option value '%s'", option_arg
.str().c_str());
94 if (m_byte_size
.GetDefaultValue() == 0) {
95 error
= Status::FromErrorString("--size option is disabled");
97 error
= m_byte_size
.SetValueFromString(option_arg
);
98 if (m_byte_size
.GetCurrentValue() == 0)
99 error
= Status::FromErrorStringWithFormat(
100 "invalid --size option value '%s'", option_arg
.str().c_str());
106 llvm::StringRef gdb_format_str
= option_arg
;
107 gdb_format_str
.consumeInteger(0, count
);
109 Format format
= eFormatDefault
;
110 uint32_t byte_size
= 0;
112 while (!gdb_format_str
.empty() &&
113 ParserGDBFormatLetter(execution_context
, gdb_format_str
[0], format
,
115 gdb_format_str
= gdb_format_str
.drop_front();
118 // We the first character of the "gdb_format_str" is not the
119 // NULL terminator, we didn't consume the entire string and
120 // something is wrong. Also, if none of the format, size or count was
121 // specified correctly, then abort.
122 if (!gdb_format_str
.empty() ||
123 (format
== eFormatInvalid
&& byte_size
== 0 && count
== 0)) {
124 // Nothing got set correctly
125 error
= Status::FromErrorStringWithFormat(
126 "invalid gdb format string '%s'", option_arg
.str().c_str());
130 // At least one of the format, size or count was set correctly. Anything
131 // that wasn't set correctly should be set to the previous default
132 if (format
== eFormatInvalid
)
133 ParserGDBFormatLetter(execution_context
, m_prev_gdb_format
, format
,
136 const bool byte_size_enabled
= m_byte_size
.GetDefaultValue() < UINT64_MAX
;
137 const bool count_enabled
= m_count
.GetDefaultValue() < UINT64_MAX
;
138 if (byte_size_enabled
) {
139 // Byte size is enabled
141 ParserGDBFormatLetter(execution_context
, m_prev_gdb_size
, format
,
144 // Byte size is disabled, make sure it wasn't specified but if this is an
145 // address, it's actually necessary to specify one so don't error out
146 if (byte_size
> 0 && format
!= lldb::eFormatAddressInfo
) {
147 error
= Status::FromErrorString(
148 "this command doesn't support specifying a byte size");
154 // Count is enabled and was not set, set it to the default for gdb format
155 // statements (which is 1).
159 // Count is disabled, make sure it wasn't specified
161 error
= Status::FromErrorString(
162 "this command doesn't support specifying a count");
167 m_format
.SetCurrentValue(format
);
168 m_format
.SetOptionWasSet();
169 if (byte_size_enabled
) {
170 m_byte_size
.SetCurrentValue(byte_size
);
171 m_byte_size
.SetOptionWasSet();
174 m_count
.SetCurrentValue(count
);
175 m_count
.SetOptionWasSet();
180 llvm_unreachable("Unimplemented option");
186 bool OptionGroupFormat::ParserGDBFormatLetter(
187 ExecutionContext
*execution_context
, char format_letter
, Format
&format
,
188 uint32_t &byte_size
) {
189 m_has_gdb_format
= true;
190 switch (format_letter
) {
192 format
= eFormatOctal
;
193 m_prev_gdb_format
= format_letter
;
197 m_prev_gdb_format
= format_letter
;
200 format
= eFormatDecimal
;
201 m_prev_gdb_format
= format_letter
;
204 format
= eFormatUnsigned
;
205 m_prev_gdb_format
= format_letter
;
208 format
= eFormatBinary
;
209 m_prev_gdb_format
= format_letter
;
212 format
= eFormatFloat
;
213 m_prev_gdb_format
= format_letter
;
216 format
= eFormatAddressInfo
;
219 execution_context
? execution_context
->GetTargetSP() : TargetSP();
221 byte_size
= target_sp
->GetArchitecture().GetAddressByteSize();
222 m_prev_gdb_format
= format_letter
;
226 format
= eFormatInstruction
;
227 m_prev_gdb_format
= format_letter
;
230 format
= eFormatChar
;
231 m_prev_gdb_format
= format_letter
;
234 format
= eFormatCString
;
235 m_prev_gdb_format
= format_letter
;
238 format
= eFormatOSType
;
239 m_prev_gdb_format
= format_letter
;
242 format
= eFormatHexFloat
;
243 m_prev_gdb_format
= format_letter
;
251 // Size isn't used for printing instructions, so if a size is specified,
252 // and the previous format was 'i', then we should reset it to the
253 // default ('x'). Otherwise we'll continue to print as instructions,
254 // which isn't expected.
255 if (format_letter
== 'b')
257 else if (format_letter
== 'h')
259 else if (format_letter
== 'w')
261 else if (format_letter
== 'g')
264 m_prev_gdb_size
= format_letter
;
265 if (m_prev_gdb_format
== 'i')
266 m_prev_gdb_format
= 'x';
278 void OptionGroupFormat::OptionParsingStarting(
279 ExecutionContext
*execution_context
) {
283 m_has_gdb_format
= false;