LLDB  mainline
CommandAlias.cpp
Go to the documentation of this file.
1 //===-- CommandAlias.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 "llvm/Support/ErrorHandling.h"
12 
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp,
23  llvm::StringRef options_args,
24  OptionArgVectorSP &option_arg_vector_sp) {
25  bool success = true;
26  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
27 
28  if (options_args.size() < 1)
29  return true;
30 
31  Args args(options_args);
32  std::string options_string(options_args);
33  // TODO: Find a way to propagate errors in this CommandReturnObject up the
34  // stack.
35  CommandReturnObject result(false);
36  // Check to see if the command being aliased can take any command options.
37  Options *options = cmd_obj_sp->GetOptions();
38  if (options) {
39  // See if any options were specified as part of the alias; if so, handle
40  // them appropriately.
41  ExecutionContext exe_ctx =
42  cmd_obj_sp->GetCommandInterpreter().GetExecutionContext();
43  options->NotifyOptionParsingStarting(&exe_ctx);
44 
45  llvm::Expected<Args> args_or =
46  options->ParseAlias(args, option_arg_vector, options_string);
47  if (!args_or) {
48  result.AppendError(toString(args_or.takeError()));
49  result.AppendError("Unable to create requested alias.\n");
51  return false;
52  }
53  args = std::move(*args_or);
54  options->VerifyPartialOptions(result);
55  if (!result.Succeeded() &&
57  result.AppendError("Unable to create requested alias.\n");
58  return false;
59  }
60  }
61 
62  if (!options_string.empty()) {
63  if (cmd_obj_sp->WantsRawCommandString())
64  option_arg_vector->emplace_back("<argument>", -1, options_string);
65  else {
66  for (auto &entry : args.entries()) {
67  if (!entry.ref().empty())
68  option_arg_vector->emplace_back(std::string("<argument>"), -1,
69  std::string(entry.ref()));
70  }
71  }
72  }
73 
74  return success;
75 }
76 
77 CommandAlias::CommandAlias(CommandInterpreter &interpreter,
78  lldb::CommandObjectSP cmd_sp,
79  llvm::StringRef options_args, llvm::StringRef name,
80  llvm::StringRef help, llvm::StringRef syntax,
81  uint32_t flags)
82  : CommandObject(interpreter, name, help, syntax, flags),
83  m_option_string(std::string(options_args)),
84  m_option_args_sp(new OptionArgVector),
85  m_is_dashdash_alias(eLazyBoolCalculate), m_did_set_help(false),
86  m_did_set_help_long(false) {
87  if (ProcessAliasOptionsArgs(cmd_sp, options_args, m_option_args_sp)) {
88  m_underlying_command_sp = cmd_sp;
89  for (int i = 0;
90  auto cmd_entry = m_underlying_command_sp->GetArgumentEntryAtIndex(i);
91  i++) {
92  m_arguments.push_back(*cmd_entry);
93  }
94  if (!help.empty()) {
95  StreamString sstr;
96  StreamString translation_and_help;
97  GetAliasExpansion(sstr);
98 
99  translation_and_help.Printf(
100  "(%s) %s", sstr.GetData(),
101  GetUnderlyingCommand()->GetHelp().str().c_str());
102  SetHelp(translation_and_help.GetString());
103  }
104  }
105 }
106 
108  if (IsValid())
109  return m_underlying_command_sp->WantsRawCommandString();
110  return false;
111 }
112 
114  if (IsValid())
115  return m_underlying_command_sp->WantsCompletion();
116  return false;
117 }
118 
120  if (IsValid())
121  m_underlying_command_sp->HandleCompletion(request);
122 }
123 
125  CompletionRequest &request, OptionElementVector &opt_element_vector) {
126  if (IsValid())
127  m_underlying_command_sp->HandleArgumentCompletion(request,
128  opt_element_vector);
129 }
130 
132  if (IsValid())
133  return m_underlying_command_sp->GetOptions();
134  return nullptr;
135 }
136 
137 bool CommandAlias::Execute(const char *args_string,
138  CommandReturnObject &result) {
139  llvm_unreachable("CommandAlias::Execute is not to be called");
140 }
141 
143  llvm::StringRef command_name = m_underlying_command_sp->GetCommandName();
144  help_string.Printf("'%*s", (int)command_name.size(), command_name.data());
145 
146  if (!m_option_args_sp) {
147  help_string.Printf("'");
148  return;
149  }
150 
151  OptionArgVector *options = m_option_args_sp.get();
152  std::string opt;
153  std::string value;
154 
155  for (const auto &opt_entry : *options) {
156  std::tie(opt, std::ignore, value) = opt_entry;
157  if (opt == "<argument>") {
158  help_string.Printf(" %s", value.c_str());
159  } else {
160  help_string.Printf(" %s", opt.c_str());
161  if ((value != "<no-argument>") && (value != "<need-argument")) {
162  help_string.Printf(" %s", value.c_str());
163  }
164  }
165  }
166 
167  help_string.Printf("'");
168 }
169 
172  return (m_is_dashdash_alias == eLazyBoolYes);
174  if (!IsValid())
175  return false;
176 
177  std::string opt;
178  std::string value;
179 
180  for (const auto &opt_entry : *GetOptionArguments()) {
181  std::tie(opt, std::ignore, value) = opt_entry;
182  if (opt == "<argument>" && !value.empty() &&
183  llvm::StringRef(value).endswith("--")) {
185  break;
186  }
187  }
188 
189  // if this is a nested alias, it may be adding arguments on top of an already
190  // dash-dash alias
193  (GetUnderlyingCommand()->IsDashDashCommand() ? eLazyBoolYes
194  : eLazyBoolNo);
195  return (m_is_dashdash_alias == eLazyBoolYes);
196 }
197 
199  if (GetUnderlyingCommand())
200  return GetUnderlyingCommand()->IsAlias();
201  return false;
202 }
203 
204 std::pair<lldb::CommandObjectSP, OptionArgVectorSP> CommandAlias::Desugar() {
205  auto underlying = GetUnderlyingCommand();
206  if (!underlying)
207  return {nullptr, nullptr};
208 
209  if (underlying->IsAlias()) {
210  auto desugared = ((CommandAlias *)underlying.get())->Desugar();
211  auto options = GetOptionArguments();
212  options->insert(options->begin(), desugared.second->begin(),
213  desugared.second->end());
214  return {desugared.first, options};
215  }
216 
217  return {underlying, GetOptionArguments()};
218 }
219 
220 // allow CommandAlias objects to provide their own help, but fallback to the
221 // info for the underlying command if no customization has been provided
222 void CommandAlias::SetHelp(llvm::StringRef str) {
223  this->CommandObject::SetHelp(str);
224  m_did_set_help = true;
225 }
226 
227 void CommandAlias::SetHelpLong(llvm::StringRef str) {
228  this->CommandObject::SetHelpLong(str);
229  m_did_set_help_long = true;
230 }
231 
232 llvm::StringRef CommandAlias::GetHelp() {
233  if (!m_cmd_help_short.empty() || m_did_set_help)
234  return m_cmd_help_short;
235  if (IsValid())
236  return m_underlying_command_sp->GetHelp();
237  return llvm::StringRef();
238 }
239 
240 llvm::StringRef CommandAlias::GetHelpLong() {
241  if (!m_cmd_help_long.empty() || m_did_set_help_long)
242  return m_cmd_help_long;
243  if (IsValid())
244  return m_underlying_command_sp->GetHelpLong();
245  return llvm::StringRef();
246 }
CommandAlias.h
lldb_private::CommandAlias::GetOptions
Options * GetOptions() override
Definition: CommandAlias.cpp:131
lldb_private::CommandAlias::GetHelpLong
llvm::StringRef GetHelpLong() override
Definition: CommandAlias.cpp:240
lldb_private::ExecutionContext
Definition: ExecutionContext.h:291
lldb_private::CommandAlias::IsNestedAlias
bool IsNestedAlias()
Definition: CommandAlias.cpp:198
lldb_private::CommandReturnObject::GetStatus
lldb::ReturnStatus GetStatus()
Definition: CommandReturnObject.cpp:133
lldb_private::CommandObject::m_cmd_help_short
std::string m_cmd_help_short
Definition: CommandObject.h:362
lldb_private::Options::NotifyOptionParsingStarting
void NotifyOptionParsingStarting(ExecutionContext *execution_context)
Definition: Options.cpp:32
lldb_private::CommandAlias::IsDashDashCommand
bool IsDashDashCommand() override
Definition: CommandAlias.cpp:170
lldb_private::CommandAlias::m_is_dashdash_alias
LazyBool m_is_dashdash_alias
Definition: CommandAlias.h:78
lldb_private::eLazyBoolYes
@ eLazyBoolYes
Definition: lldb-private-enumerations.h:115
lldb_private::CommandObject::SetHelpLong
virtual void SetHelpLong(llvm::StringRef str)
Definition: CommandObject.cpp:90
lldb_private::Args
Definition: Args.h:33
lldb_private::CommandObject::SetHelp
virtual void SetHelp(llvm::StringRef str)
Definition: CommandObject.cpp:86
CommandReturnObject.h
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
lldb_private::CommandObject::m_arguments
std::vector< CommandArgumentEntry > m_arguments
Definition: CommandObject.h:366
lldb_private::CommandAlias::IsValid
bool IsValid() const
Definition: CommandAlias.h:31
lldb_private::CommandAlias::WantsRawCommandString
bool WantsRawCommandString() override
Definition: CommandAlias.cpp:107
Options.h
lldb_private::Options
Definition: Options.h:57
lldb_private::breakpad::toString
llvm::StringRef toString(Record::Kind K)
Definition: BreakpadRecords.cpp:483
lldb_private::CommandAlias::m_option_args_sp
OptionArgVectorSP m_option_args_sp
Definition: CommandAlias.h:77
lldb_private::CommandReturnObject::SetStatus
void SetStatus(lldb::ReturnStatus status)
Definition: CommandReturnObject.cpp:131
lldb::eReturnStatusStarted
@ eReturnStatusStarted
Definition: lldb-enumerations.h:264
lldb_private::StreamString::GetData
const char * GetData() const
Definition: StreamString.h:43
StreamString.h
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::Args::entries
llvm::ArrayRef< ArgEntry > entries() const
Definition: Args.h:130
ProcessAliasOptionsArgs
static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp, llvm::StringRef options_args, OptionArgVectorSP &option_arg_vector_sp)
Definition: CommandAlias.cpp:22
lldb_private::CommandInterpreter
Definition: CommandInterpreter.h:221
lldb_private::CommandAlias::m_did_set_help
bool m_did_set_help
Definition: CommandAlias.h:79
lldb::eReturnStatusFailed
@ eReturnStatusFailed
Definition: lldb-enumerations.h:265
lldb_private::OptionElementVector
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:42
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:38
lldb_private::Options::VerifyPartialOptions
bool VerifyPartialOptions(CommandReturnObject &result)
Definition: Options.cpp:623
lldb_private::CommandAlias::SetHelp
void SetHelp(llvm::StringRef str) override
Definition: CommandAlias.cpp:222
lldb_private::CommandAlias::GetHelp
llvm::StringRef GetHelp() override
Definition: CommandAlias.cpp:232
lldb_private::CommandObject
Definition: CommandObject.h:67
lldb_private::CommandAlias
Definition: CommandAlias.h:20
lldb_private::OptionArgVector
std::vector< std::tuple< std::string, int, std::string > > OptionArgVector
Definition: Options.h:26
lldb_private::CommandAlias::SetHelpLong
void SetHelpLong(llvm::StringRef str) override
Definition: CommandAlias.cpp:227
lldb_private::CommandAlias::HandleCompletion
void HandleCompletion(CompletionRequest &request) override
This default version handles calling option argument completions and then calls HandleArgumentComplet...
Definition: CommandAlias.cpp:119
lldb_private::CommandAlias::Execute
bool Execute(const char *args_string, CommandReturnObject &result) override
Definition: CommandAlias.cpp:137
lldb_private::CommandReturnObject
Definition: CommandReturnObject.h:25
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
CommandObject.h
lldb_private::CommandAlias::Desugar
std::pair< lldb::CommandObjectSP, OptionArgVectorSP > Desugar()
Definition: CommandAlias.cpp:204
lldb_private::CommandAlias::GetAliasExpansion
void GetAliasExpansion(StreamString &help_string) const
Definition: CommandAlias.cpp:142
lldb_private::CommandAlias::HandleArgumentCompletion
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
Definition: CommandAlias.cpp:124
lldb_private::CommandReturnObject::Succeeded
bool Succeeded()
Definition: CommandReturnObject.cpp:135
lldb_private::CommandAlias::GetUnderlyingCommand
lldb::CommandObjectSP GetUnderlyingCommand()
Definition: CommandAlias.h:61
lldb_private::CommandObject::m_cmd_help_long
std::string m_cmd_help_long
Definition: CommandObject.h:363
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::eLazyBoolCalculate
@ eLazyBoolCalculate
Definition: lldb-private-enumerations.h:115
lldb_private::CommandAlias::GetOptionArguments
OptionArgVectorSP GetOptionArguments() const
Definition: CommandAlias.h:64
CommandInterpreter.h
lldb_private::CommandAlias::m_underlying_command_sp
lldb::CommandObjectSP m_underlying_command_sp
Definition: CommandAlias.h:75
lldb_private::CommandReturnObject::AppendError
void void AppendError(llvm::StringRef in_string)
Definition: CommandReturnObject.cpp:100
lldb_private::CommandAlias::m_did_set_help_long
bool m_did_set_help_long
Definition: CommandAlias.h:80
lldb
Definition: SBAddress.h:15
lldb_private::Options::ParseAlias
llvm::Expected< Args > ParseAlias(const Args &args, OptionArgVector *option_arg_vector, std::string &input_line)
Definition: Options.cpp:971
lldb_private::CompletionRequest
Definition: CompletionRequest.h:100
lldb_private::OptionArgVectorSP
std::shared_ptr< OptionArgVector > OptionArgVectorSP
Definition: Options.h:29
lldb_private::CommandAlias::WantsCompletion
bool WantsCompletion() override
Definition: CommandAlias.cpp:113