LLDB  mainline
OptionGroupFormat.cpp
Go to the documentation of this file.
1 //===-- OptionGroupFormat.cpp -----------------------------------*- C++ -*-===//
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  error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
164  break;
165  }
166 
167  return error;
168 }
169 
171  ExecutionContext *execution_context, char format_letter, Format &format,
172  uint32_t &byte_size) {
173  m_has_gdb_format = true;
174  switch (format_letter) {
175  case 'o':
176  format = eFormatOctal;
177  m_prev_gdb_format = format_letter;
178  return true;
179  case 'x':
180  format = eFormatHex;
181  m_prev_gdb_format = format_letter;
182  return true;
183  case 'd':
184  format = eFormatDecimal;
185  m_prev_gdb_format = format_letter;
186  return true;
187  case 'u':
188  format = eFormatUnsigned;
189  m_prev_gdb_format = format_letter;
190  return true;
191  case 't':
192  format = eFormatBinary;
193  m_prev_gdb_format = format_letter;
194  return true;
195  case 'f':
196  format = eFormatFloat;
197  m_prev_gdb_format = format_letter;
198  return true;
199  case 'a':
200  format = eFormatAddressInfo;
201  {
202  TargetSP target_sp =
203  execution_context ? execution_context->GetTargetSP() : TargetSP();
204  if (target_sp)
205  byte_size = target_sp->GetArchitecture().GetAddressByteSize();
206  m_prev_gdb_format = format_letter;
207  return true;
208  }
209  case 'i':
210  format = eFormatInstruction;
211  m_prev_gdb_format = format_letter;
212  return true;
213  case 'c':
214  format = eFormatChar;
215  m_prev_gdb_format = format_letter;
216  return true;
217  case 's':
218  format = eFormatCString;
219  m_prev_gdb_format = format_letter;
220  return true;
221  case 'T':
222  format = eFormatOSType;
223  m_prev_gdb_format = format_letter;
224  return true;
225  case 'A':
226  format = eFormatHexFloat;
227  m_prev_gdb_format = format_letter;
228  return true;
229 
230  case 'b':
231  case 'h':
232  case 'w':
233  case 'g':
234  {
235  // Size isn't used for printing instructions, so if a size is specified,
236  // and the previous format was 'i', then we should reset it to the
237  // default ('x'). Otherwise we'll continue to print as instructions,
238  // which isn't expected.
239  if (format_letter == 'b')
240  byte_size = 1;
241  else if (format_letter == 'h')
242  byte_size = 2;
243  else if (format_letter == 'w')
244  byte_size = 4;
245  else if (format_letter == 'g')
246  byte_size = 8;
247 
248  m_prev_gdb_size = format_letter;
249  if (m_prev_gdb_format == 'i')
250  m_prev_gdb_format = 'x';
251  return true;
252  }
253  break;
254  default:
255  break;
256  }
257 
258 
259  return false;
260 }
261 
263  ExecutionContext *execution_context) {
264  m_format.Clear();
265  m_byte_size.Clear();
266  m_count.Clear();
267  m_has_gdb_format = false;
268 }
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const lldb::TargetSP & GetTargetSP() const
Get accessor to get the target shared pointer.
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
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:241
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
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
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:255
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
#define UINT64_MAX
Definition: lldb-defines.h:35
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
An error handling class.
Definition: Status.h:44