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 
19 OptionGroupFormat::OptionGroupFormat(lldb::Format default_format,
20  uint64_t default_byte_size,
21  uint64_t default_count)
22  : m_format(default_format, default_format),
23  m_byte_size(default_byte_size, default_byte_size),
24  m_count(default_count, default_count), m_prev_gdb_format('x'),
25  m_prev_gdb_size('w') {}
26 
28 
29 static constexpr OptionDefinition g_option_table[] = {
30  {LLDB_OPT_SET_1, false, "format", 'f', OptionParser::eRequiredArgument,
31  nullptr, {}, 0, eArgTypeFormat,
32  "Specify a format to be used for display."},
33  {LLDB_OPT_SET_2, false, "gdb-format", 'G', OptionParser::eRequiredArgument,
34  nullptr, {}, 0, eArgTypeGDBFormat,
35  "Specify a format using a GDB format specifier string."},
36  {LLDB_OPT_SET_3, false, "size", 's', OptionParser::eRequiredArgument,
37  nullptr, {}, 0, eArgTypeByteSize,
38  "The size in bytes to use when displaying with the selected format."},
39  {LLDB_OPT_SET_4, false, "count", 'c', OptionParser::eRequiredArgument,
40  nullptr, {}, 0, eArgTypeCount,
41  "The number of total items to display."},
42 };
43 
44 llvm::ArrayRef<OptionDefinition> OptionGroupFormat::GetDefinitions() {
45  auto result = llvm::makeArrayRef(g_option_table);
48  return result;
49  else
50  return result.take_front(3);
51  }
52  return result.take_front(2);
53 }
54 
56  llvm::StringRef option_arg,
57  ExecutionContext *execution_context) {
58  Status error;
59  const int short_option = g_option_table[option_idx].short_option;
60 
61  switch (short_option) {
62  case 'f':
63  error = m_format.SetValueFromString(option_arg);
64  break;
65 
66  case 'c':
67  if (m_count.GetDefaultValue() == 0) {
68  error.SetErrorString("--count option is disabled");
69  } else {
70  error = m_count.SetValueFromString(option_arg);
71  if (m_count.GetCurrentValue() == 0)
72  error.SetErrorStringWithFormat("invalid --count option value '%s'",
73  option_arg.str().c_str());
74  }
75  break;
76 
77  case 's':
78  if (m_byte_size.GetDefaultValue() == 0) {
79  error.SetErrorString("--size option is disabled");
80  } else {
81  error = m_byte_size.SetValueFromString(option_arg);
82  if (m_byte_size.GetCurrentValue() == 0)
83  error.SetErrorStringWithFormat("invalid --size option value '%s'",
84  option_arg.str().c_str());
85  }
86  break;
87 
88  case 'G': {
89  uint64_t count = 0;
90  llvm::StringRef gdb_format_str = option_arg;
91  gdb_format_str.consumeInteger(0, count);
92 
93  Format format = eFormatDefault;
94  uint32_t byte_size = 0;
95 
96  while (!gdb_format_str.empty() &&
97  ParserGDBFormatLetter(execution_context, gdb_format_str[0], format,
98  byte_size)) {
99  gdb_format_str = gdb_format_str.drop_front();
100  }
101 
102  // We the first character of the "gdb_format_str" is not the
103  // NULL terminator, we didn't consume the entire string and
104  // something is wrong. Also, if none of the format, size or count was
105  // specified correctly, then abort.
106  if (!gdb_format_str.empty() ||
107  (format == eFormatInvalid && byte_size == 0 && count == 0)) {
108  // Nothing got set correctly
109  error.SetErrorStringWithFormat("invalid gdb format string '%s'",
110  option_arg.str().c_str());
111  return error;
112  }
113 
114  // At least one of the format, size or count was set correctly. Anything
115  // that wasn't set correctly should be set to the previous default
116  if (format == eFormatInvalid)
117  ParserGDBFormatLetter(execution_context, m_prev_gdb_format, format,
118  byte_size);
119 
120  const bool byte_size_enabled = m_byte_size.GetDefaultValue() < UINT64_MAX;
121  const bool count_enabled = m_count.GetDefaultValue() < UINT64_MAX;
122  if (byte_size_enabled) {
123  // Byte size is enabled
124  if (byte_size == 0)
125  ParserGDBFormatLetter(execution_context, m_prev_gdb_size, format,
126  byte_size);
127  } else {
128  // Byte size is disabled, make sure it wasn't specified but if this is an
129  // address, it's actually necessary to specify one so don't error out
130  if (byte_size > 0 && format != lldb::eFormatAddressInfo) {
131  error.SetErrorString(
132  "this command doesn't support specifying a byte size");
133  return error;
134  }
135  }
136 
137  if (count_enabled) {
138  // Count is enabled and was not set, set it to the default for gdb format
139  // statements (which is 1).
140  if (count == 0)
141  count = 1;
142  } else {
143  // Count is disabled, make sure it wasn't specified
144  if (count > 0) {
145  error.SetErrorString("this command doesn't support specifying a count");
146  return error;
147  }
148  }
149 
150  m_format.SetCurrentValue(format);
152  if (byte_size_enabled) {
153  m_byte_size.SetCurrentValue(byte_size);
155  }
156  if (count_enabled) {
157  m_count.SetCurrentValue(count);
159  }
160  } break;
161 
162  default:
163  llvm_unreachable("Unimplemented option");
164  }
165 
166  return error;
167 }
168 
170  ExecutionContext *execution_context, char format_letter, Format &format,
171  uint32_t &byte_size) {
172  m_has_gdb_format = true;
173  switch (format_letter) {
174  case 'o':
175  format = eFormatOctal;
176  m_prev_gdb_format = format_letter;
177  return true;
178  case 'x':
179  format = eFormatHex;
180  m_prev_gdb_format = format_letter;
181  return true;
182  case 'd':
183  format = eFormatDecimal;
184  m_prev_gdb_format = format_letter;
185  return true;
186  case 'u':
187  format = eFormatUnsigned;
188  m_prev_gdb_format = format_letter;
189  return true;
190  case 't':
191  format = eFormatBinary;
192  m_prev_gdb_format = format_letter;
193  return true;
194  case 'f':
195  format = eFormatFloat;
196  m_prev_gdb_format = format_letter;
197  return true;
198  case 'a':
199  format = eFormatAddressInfo;
200  {
201  TargetSP target_sp =
202  execution_context ? execution_context->GetTargetSP() : TargetSP();
203  if (target_sp)
204  byte_size = target_sp->GetArchitecture().GetAddressByteSize();
205  m_prev_gdb_format = format_letter;
206  return true;
207  }
208  case 'i':
209  format = eFormatInstruction;
210  m_prev_gdb_format = format_letter;
211  return true;
212  case 'c':
213  format = eFormatChar;
214  m_prev_gdb_format = format_letter;
215  return true;
216  case 's':
217  format = eFormatCString;
218  m_prev_gdb_format = format_letter;
219  return true;
220  case 'T':
221  format = eFormatOSType;
222  m_prev_gdb_format = format_letter;
223  return true;
224  case 'A':
225  format = eFormatHexFloat;
226  m_prev_gdb_format = format_letter;
227  return true;
228 
229  case 'b':
230  case 'h':
231  case 'w':
232  case 'g':
233  {
234  // Size isn't used for printing instructions, so if a size is specified,
235  // and the previous format was 'i', then we should reset it to the
236  // default ('x'). Otherwise we'll continue to print as instructions,
237  // which isn't expected.
238  if (format_letter == 'b')
239  byte_size = 1;
240  else if (format_letter == 'h')
241  byte_size = 2;
242  else if (format_letter == 'w')
243  byte_size = 4;
244  else if (format_letter == 'g')
245  byte_size = 8;
246 
247  m_prev_gdb_size = format_letter;
248  if (m_prev_gdb_format == 'i')
249  m_prev_gdb_format = 'x';
250  return true;
251  }
252  break;
253  default:
254  break;
255  }
256 
257 
258  return false;
259 }
260 
262  ExecutionContext *execution_context) {
263  m_format.Clear();
264  m_byte_size.Clear();
265  m_count.Clear();
266  m_has_gdb_format = false;
267 }
Describe what an address points to (func + offset.
A class that represents a running process on the host machine.
const lldb::TargetSP & GetTargetSP() const
Get accessor to get the target shared pointer.
Disassemble an opcode.
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void OptionParsingStarting(ExecutionContext *execution_context) override
Format
Display format definitions.
bool ParserGDBFormatLetter(ExecutionContext *execution_context, char format_letter, lldb::Format &format, uint32_t &byte_size)
#define LLDB_OPT_SET_3
Definition: lldb-defines.h:113
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:242
void SetCurrentValue(lldb::Format value)
static constexpr OptionDefinition g_option_table[]
void SetCurrentValue(uint64_t value)
#define LLDB_OPT_SET_4
Definition: lldb-defines.h:114
ISO C99 hex float string.
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
NULL terminated C strings.
Definition: SBAddress.h:15
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:256
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
#define UINT64_MAX
Definition: lldb-defines.h:35
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
OS character codes encoded into an integer &#39;PICT&#39; &#39;text&#39; etc...
An error handling class.
Definition: Status.h:44