LLDB  mainline
OptionGroupFormat.cpp
Go to the documentation of this file.
1 //===-- OptionGroupFormat.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 
10 
11 #include "lldb/Host/OptionParser.h"
14 #include "lldb/Target/Target.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
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."},
32 };
33 
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') {
41  // Copy the default option definitions.
42  std::copy(std::begin(g_default_option_definitions),
44  std::begin(m_option_definitions));
45 
46  for (auto usage_text_tuple : usage_text_vector) {
47  switch (std::get<0>(usage_text_tuple)) {
48  case eArgTypeFormat:
49  m_option_definitions[0].usage_text = std::get<1>(usage_text_tuple);
50  break;
51  case eArgTypeByteSize:
52  m_option_definitions[2].usage_text = std::get<1>(usage_text_tuple);
53  break;
54  default:
55  llvm_unreachable("Unimplemented option");
56  }
57  }
58 }
59 
60 llvm::ArrayRef<OptionDefinition> OptionGroupFormat::GetDefinitions() {
61  auto result = llvm::makeArrayRef(m_option_definitions);
64  return result;
65  else
66  return result.take_front(3);
67  }
68  return result.take_front(2);
69 }
70 
72  llvm::StringRef option_arg,
73  ExecutionContext *execution_context) {
74  Status error;
75  const int short_option = m_option_definitions[option_idx].short_option;
76 
77  switch (short_option) {
78  case 'f':
79  error = m_format.SetValueFromString(option_arg);
80  break;
81 
82  case 'c':
83  if (m_count.GetDefaultValue() == 0) {
84  error.SetErrorString("--count option is disabled");
85  } else {
86  error = m_count.SetValueFromString(option_arg);
87  if (m_count.GetCurrentValue() == 0)
88  error.SetErrorStringWithFormat("invalid --count option value '%s'",
89  option_arg.str().c_str());
90  }
91  break;
92 
93  case 's':
94  if (m_byte_size.GetDefaultValue() == 0) {
95  error.SetErrorString("--size option is disabled");
96  } else {
97  error = m_byte_size.SetValueFromString(option_arg);
98  if (m_byte_size.GetCurrentValue() == 0)
99  error.SetErrorStringWithFormat("invalid --size option value '%s'",
100  option_arg.str().c_str());
101  }
102  break;
103 
104  case 'G': {
105  uint64_t count = 0;
106  llvm::StringRef gdb_format_str = option_arg;
107  gdb_format_str.consumeInteger(0, count);
108 
109  Format format = eFormatDefault;
110  uint32_t byte_size = 0;
111 
112  while (!gdb_format_str.empty() &&
113  ParserGDBFormatLetter(execution_context, gdb_format_str[0], format,
114  byte_size)) {
115  gdb_format_str = gdb_format_str.drop_front();
116  }
117 
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.SetErrorStringWithFormat("invalid gdb format string '%s'",
126  option_arg.str().c_str());
127  return error;
128  }
129 
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,
134  byte_size);
135 
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
140  if (byte_size == 0)
141  ParserGDBFormatLetter(execution_context, m_prev_gdb_size, format,
142  byte_size);
143  } else {
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.SetErrorString(
148  "this command doesn't support specifying a byte size");
149  return error;
150  }
151  }
152 
153  if (count_enabled) {
154  // Count is enabled and was not set, set it to the default for gdb format
155  // statements (which is 1).
156  if (count == 0)
157  count = 1;
158  } else {
159  // Count is disabled, make sure it wasn't specified
160  if (count > 0) {
161  error.SetErrorString("this command doesn't support specifying a count");
162  return error;
163  }
164  }
165 
166  m_format.SetCurrentValue(format);
168  if (byte_size_enabled) {
169  m_byte_size.SetCurrentValue(byte_size);
171  }
172  if (count_enabled) {
173  m_count.SetCurrentValue(count);
175  }
176  } break;
177 
178  default:
179  llvm_unreachable("Unimplemented option");
180  }
181 
182  return error;
183 }
184 
186  ExecutionContext *execution_context, char format_letter, Format &format,
187  uint32_t &byte_size) {
188  m_has_gdb_format = true;
189  switch (format_letter) {
190  case 'o':
191  format = eFormatOctal;
192  m_prev_gdb_format = format_letter;
193  return true;
194  case 'x':
195  format = eFormatHex;
196  m_prev_gdb_format = format_letter;
197  return true;
198  case 'd':
199  format = eFormatDecimal;
200  m_prev_gdb_format = format_letter;
201  return true;
202  case 'u':
203  format = eFormatUnsigned;
204  m_prev_gdb_format = format_letter;
205  return true;
206  case 't':
207  format = eFormatBinary;
208  m_prev_gdb_format = format_letter;
209  return true;
210  case 'f':
211  format = eFormatFloat;
212  m_prev_gdb_format = format_letter;
213  return true;
214  case 'a':
215  format = eFormatAddressInfo;
216  {
217  TargetSP target_sp =
218  execution_context ? execution_context->GetTargetSP() : TargetSP();
219  if (target_sp)
220  byte_size = target_sp->GetArchitecture().GetAddressByteSize();
221  m_prev_gdb_format = format_letter;
222  return true;
223  }
224  case 'i':
225  format = eFormatInstruction;
226  m_prev_gdb_format = format_letter;
227  return true;
228  case 'c':
229  format = eFormatChar;
230  m_prev_gdb_format = format_letter;
231  return true;
232  case 's':
233  format = eFormatCString;
234  m_prev_gdb_format = format_letter;
235  return true;
236  case 'T':
237  format = eFormatOSType;
238  m_prev_gdb_format = format_letter;
239  return true;
240  case 'A':
241  format = eFormatHexFloat;
242  m_prev_gdb_format = format_letter;
243  return true;
244 
245  case 'b':
246  case 'h':
247  case 'w':
248  case 'g':
249  {
250  // Size isn't used for printing instructions, so if a size is specified,
251  // and the previous format was 'i', then we should reset it to the
252  // default ('x'). Otherwise we'll continue to print as instructions,
253  // which isn't expected.
254  if (format_letter == 'b')
255  byte_size = 1;
256  else if (format_letter == 'h')
257  byte_size = 2;
258  else if (format_letter == 'w')
259  byte_size = 4;
260  else if (format_letter == 'g')
261  byte_size = 8;
262 
263  m_prev_gdb_size = format_letter;
264  if (m_prev_gdb_format == 'i')
265  m_prev_gdb_format = 'x';
266  return true;
267  }
268  break;
269  default:
270  break;
271  }
272 
273 
274  return false;
275 }
276 
278  ExecutionContext *execution_context) {
279  m_format.Clear();
280  m_byte_size.Clear();
281  m_count.Clear();
282  m_has_gdb_format = false;
283 }
lldb_private::OptionGroupFormat::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *execution_context) override
Definition: OptionGroupFormat.cpp:277
lldb::eFormatOSType
@ eFormatOSType
OS character codes encoded into an integer 'PICT' 'text' etc...
Definition: lldb-enumerations.h:173
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
OptionGroupFormat.h
lldb_private::OptionValue::SetOptionWasSet
void SetOptionWasSet()
Definition: OptionValue.h:305
lldb_private::OptionValueUInt64::GetCurrentValue
uint64_t GetCurrentValue() const
Definition: OptionValueUInt64.h:59
lldb::Format
Format
Display format definitions.
Definition: lldb-enumerations.h:155
lldb_private::OptionGroupFormat::m_byte_size
OptionValueUInt64 m_byte_size
Definition: OptionGroupFormat.h:77
lldb_private::OptionGroupFormat::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
Definition: OptionGroupFormat.cpp:71
lldb_private::OptionGroupFormat::ParserGDBFormatLetter
bool ParserGDBFormatLetter(ExecutionContext *execution_context, char format_letter, lldb::Format &format, uint32_t &byte_size)
Definition: OptionGroupFormat.cpp:185
lldb_private::OptionGroupFormat::m_count
OptionValueUInt64 m_count
Definition: OptionGroupFormat.h:78
lldb::eFormatInstruction
@ eFormatInstruction
Disassemble an opcode.
Definition: lldb-enumerations.h:199
Target.h
lldb::eArgTypeByteSize
@ eArgTypeByteSize
Definition: lldb-enumerations.h:525
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::OptionDefinition::usage_text
const char * usage_text
Full text explaining what this options does and what (if any) argument to pass it.
Definition: OptionDefinition.h:47
lldb::eArgTypeCount
@ eArgTypeCount
Definition: lldb-enumerations.h:528
lldb_private::OptionGroupFormat::m_has_gdb_format
bool m_has_gdb_format
Definition: OptionGroupFormat.h:81
lldb_private::OptionGroupFormat::m_prev_gdb_format
char m_prev_gdb_format
Definition: OptionGroupFormat.h:79
LLDB_OPT_SET_1
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:101
LLDB_OPT_SET_3
#define LLDB_OPT_SET_3
Definition: lldb-defines.h:103
lldb_private::OptionGroupFormat::m_prev_gdb_size
char m_prev_gdb_size
Definition: OptionGroupFormat.h:80
lldb_private::OptionGroupFormat::m_option_definitions
OptionDefinition m_option_definitions[4]
Definition: OptionGroupFormat.h:82
lldb_private::OptionGroupFormat::GetDefinitions
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: OptionGroupFormat.cpp:60
lldb_private::OptionValueUInt64::Clear
void Clear() override
Definition: OptionValueUInt64.h:45
lldb::eFormatDecimal
@ eFormatDecimal
Definition: lldb-enumerations.h:167
lldb::eArgTypeGDBFormat
@ eArgTypeGDBFormat
Definition: lldb-enumerations.h:543
lldb_private::OptionGroupFormat::m_format
OptionValueFormat m_format
Definition: OptionGroupFormat.h:76
lldb::eFormatChar
@ eFormatChar
Definition: lldb-enumerations.h:162
lldb::eFormatHexFloat
@ eFormatHexFloat
ISO C99 hex float string.
Definition: lldb-enumerations.h:198
lldb::eFormatUnsigned
@ eFormatUnsigned
Definition: lldb-enumerations.h:177
lldb_private::Status
Definition: Status.h:44
lldb_private::OptionValueFormat::Clear
void Clear() override
Definition: OptionValueFormat.h:38
uint32_t
lldb::eFormatCString
@ eFormatCString
NULL terminated C strings.
Definition: lldb-enumerations.h:166
lldb_private::OptionGroupFormatUsageTextVector
std::vector< std::tuple< lldb::CommandArgumentType, const char * > > OptionGroupFormatUsageTextVector
Definition: OptionGroupFormat.h:20
LLDB_OPT_SET_4
#define LLDB_OPT_SET_4
Definition: lldb-defines.h:104
lldb_private::ExecutionContext::GetTargetSP
const lldb::TargetSP & GetTargetSP() const
Get accessor to get the target shared pointer.
Definition: ExecutionContext.h:454
lldb::eArgTypeFormat
@ eArgTypeFormat
Definition: lldb-enumerations.h:538
lldb::eFormatBinary
@ eFormatBinary
Definition: lldb-enumerations.h:159
OptionParser.h
lldb_private::OptionValueUInt64::GetDefaultValue
uint64_t GetDefaultValue() const
Definition: OptionValueUInt64.h:61
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb::eFormatHex
@ eFormatHex
Definition: lldb-enumerations.h:169
g_default_option_definitions
static constexpr OptionDefinition g_default_option_definitions[]
Definition: OptionGroupFormat.cpp:19
lldb_private::OptionDefinition
Definition: OptionDefinition.h:20
CommandInterpreter.h
lldb_private::OptionValueFormat::SetCurrentValue
void SetCurrentValue(lldb::Format value)
Definition: OptionValueFormat.h:49
lldb::eFormatFloat
@ eFormatFloat
Definition: lldb-enumerations.h:171
lldb_private::OptionDefinition::short_option
int short_option
Single character for this option.
Definition: OptionDefinition.h:32
LLDB_OPT_SET_2
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:102
lldb
Definition: SBAddress.h:15
lldb::eFormatAddressInfo
@ eFormatAddressInfo
Describe what an address points to (func + offset.
Definition: lldb-enumerations.h:196
lldb::eFormatDefault
@ eFormatDefault
Definition: lldb-enumerations.h:156
ExecutionContext.h
UINT64_MAX
#define UINT64_MAX
Definition: lldb-defines.h:23
lldb_private::OptionValueUInt64::SetValueFromString
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
Definition: OptionValueUInt64.cpp:36
lldb::eFormatOctal
@ eFormatOctal
Definition: lldb-enumerations.h:172
lldb_private::OptionValueFormat::SetValueFromString
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
Definition: OptionValueFormat.cpp:29
lldb_private::OptionValueUInt64::SetCurrentValue
void SetCurrentValue(uint64_t value)
Definition: OptionValueUInt64.h:63
lldb::eFormatInvalid
@ eFormatInvalid
Definition: lldb-enumerations.h:157