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");
50  return false;
51  }
52  args = std::move(*args_or);
53  options->VerifyPartialOptions(result);
54  if (!result.Succeeded() &&
56  result.AppendError("Unable to create requested alias.\n");
57  return false;
58  }
59  }
60 
61  if (!options_string.empty()) {
62  if (cmd_obj_sp->WantsRawCommandString())
63  option_arg_vector->emplace_back("<argument>", -1, options_string);
64  else {
65  for (auto &entry : args.entries()) {
66  if (!entry.ref().empty())
67  option_arg_vector->emplace_back(std::string("<argument>"), -1,
68  std::string(entry.ref()));
69  }
70  }
71  }
72 
73  return success;
74 }
75 
76 CommandAlias::CommandAlias(CommandInterpreter &interpreter,
77  lldb::CommandObjectSP cmd_sp,
78  llvm::StringRef options_args, llvm::StringRef name,
79  llvm::StringRef help, llvm::StringRef syntax,
80  uint32_t flags)
81  : CommandObject(interpreter, name, help, syntax, flags),
82  m_option_string(std::string(options_args)),
83  m_option_args_sp(new OptionArgVector),
84  m_is_dashdash_alias(eLazyBoolCalculate), m_did_set_help(false),
85  m_did_set_help_long(false) {
86  if (ProcessAliasOptionsArgs(cmd_sp, options_args, m_option_args_sp)) {
87  m_underlying_command_sp = cmd_sp;
88  for (int i = 0;
89  auto cmd_entry = m_underlying_command_sp->GetArgumentEntryAtIndex(i);
90  i++) {
91  m_arguments.push_back(*cmd_entry);
92  }
93  if (!help.empty()) {
94  StreamString sstr;
95  StreamString translation_and_help;
96  GetAliasExpansion(sstr);
97 
98  translation_and_help.Printf(
99  "(%s) %s", sstr.GetData(),
100  GetUnderlyingCommand()->GetHelp().str().c_str());
101  SetHelp(translation_and_help.GetString());
102  }
103  }
104 }
105 
107  if (IsValid())
108  return m_underlying_command_sp->WantsRawCommandString();
109  return false;
110 }
111 
113  if (IsValid())
114  return m_underlying_command_sp->WantsCompletion();
115  return false;
116 }
117 
119  if (IsValid())
120  m_underlying_command_sp->HandleCompletion(request);
121 }
122 
124  CompletionRequest &request, OptionElementVector &opt_element_vector) {
125  if (IsValid())
126  m_underlying_command_sp->HandleArgumentCompletion(request,
127  opt_element_vector);
128 }
129 
131  if (IsValid())
132  return m_underlying_command_sp->GetOptions();
133  return nullptr;
134 }
135 
136 bool CommandAlias::Execute(const char *args_string,
137  CommandReturnObject &result) {
138  llvm_unreachable("CommandAlias::Execute is not to be called");
139 }
140 
142  llvm::StringRef command_name = m_underlying_command_sp->GetCommandName();
143  help_string.Printf("'%*s", (int)command_name.size(), command_name.data());
144 
145  if (!m_option_args_sp) {
146  help_string.Printf("'");
147  return;
148  }
149 
150  OptionArgVector *options = m_option_args_sp.get();
151  std::string opt;
152  std::string value;
153 
154  for (const auto &opt_entry : *options) {
155  std::tie(opt, std::ignore, value) = opt_entry;
156  if (opt == "<argument>") {
157  help_string.Printf(" %s", value.c_str());
158  } else {
159  help_string.Printf(" %s", opt.c_str());
160  if ((value != "<no-argument>") && (value != "<need-argument")) {
161  help_string.Printf(" %s", value.c_str());
162  }
163  }
164  }
165 
166  help_string.Printf("'");
167 }
168 
171  return (m_is_dashdash_alias == eLazyBoolYes);
173  if (!IsValid())
174  return false;
175 
176  std::string opt;
177  std::string value;
178 
179  for (const auto &opt_entry : *GetOptionArguments()) {
180  std::tie(opt, std::ignore, value) = opt_entry;
181  if (opt == "<argument>" && !value.empty() &&
182  llvm::StringRef(value).endswith("--")) {
184  break;
185  }
186  }
187 
188  // if this is a nested alias, it may be adding arguments on top of an already
189  // dash-dash alias
192  (GetUnderlyingCommand()->IsDashDashCommand() ? eLazyBoolYes
193  : eLazyBoolNo);
194  return (m_is_dashdash_alias == eLazyBoolYes);
195 }
196 
198  if (GetUnderlyingCommand())
199  return GetUnderlyingCommand()->IsAlias();
200  return false;
201 }
202 
203 std::pair<lldb::CommandObjectSP, OptionArgVectorSP> CommandAlias::Desugar() {
204  auto underlying = GetUnderlyingCommand();
205  if (!underlying)
206  return {nullptr, nullptr};
207 
208  if (underlying->IsAlias()) {
209  auto desugared = ((CommandAlias *)underlying.get())->Desugar();
210  auto options = GetOptionArguments();
211  options->insert(options->begin(), desugared.second->begin(),
212  desugared.second->end());
213  return {desugared.first, options};
214  }
215 
216  return {underlying, GetOptionArguments()};
217 }
218 
219 // allow CommandAlias objects to provide their own help, but fallback to the
220 // info for the underlying command if no customization has been provided
221 void CommandAlias::SetHelp(llvm::StringRef str) {
222  this->CommandObject::SetHelp(str);
223  m_did_set_help = true;
224 }
225 
226 void CommandAlias::SetHelpLong(llvm::StringRef str) {
227  this->CommandObject::SetHelpLong(str);
228  m_did_set_help_long = true;
229 }
230 
231 llvm::StringRef CommandAlias::GetHelp() {
232  if (!m_cmd_help_short.empty() || m_did_set_help)
233  return m_cmd_help_short;
234  if (IsValid())
235  return m_underlying_command_sp->GetHelp();
236  return llvm::StringRef();
237 }
238 
239 llvm::StringRef CommandAlias::GetHelpLong() {
240  if (!m_cmd_help_long.empty() || m_did_set_help_long)
241  return m_cmd_help_long;
242  if (IsValid())
243  return m_underlying_command_sp->GetHelpLong();
244  return llvm::StringRef();
245 }
lldb_private::toString
const char * toString(AppleArm64ExceptionClass EC)
Definition: AppleArm64ExceptionClass.h:38
CommandAlias.h
lldb_private::CommandAlias::GetOptions
Options * GetOptions() override
Definition: CommandAlias.cpp:130
lldb_private::CommandAlias::GetHelpLong
llvm::StringRef GetHelpLong() override
Definition: CommandAlias.cpp:239
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::CommandAlias::IsNestedAlias
bool IsNestedAlias()
Definition: CommandAlias.cpp:197
lldb_private::CommandReturnObject::GetStatus
lldb::ReturnStatus GetStatus()
Definition: CommandReturnObject.cpp:123
lldb_private::CommandObject::m_cmd_help_short
std::string m_cmd_help_short
Definition: CommandObject.h:377
lldb_private::Options::NotifyOptionParsingStarting
void NotifyOptionParsingStarting(ExecutionContext *execution_context)
Definition: Options.cpp:32
lldb_private::CommandAlias::IsDashDashCommand
bool IsDashDashCommand() override
Definition: CommandAlias.cpp:169
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:381
lldb_private::CommandAlias::IsValid
bool IsValid() const
Definition: CommandAlias.h:31
lldb_private::CommandAlias::WantsRawCommandString
bool WantsRawCommandString() override
Definition: CommandAlias.cpp:106
Options.h
lldb_private::Options
Definition: Options.h:57
lldb_private::CommandAlias::m_option_args_sp
OptionArgVectorSP m_option_args_sp
Definition: CommandAlias.h:77
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:214
lldb_private::CommandAlias::m_did_set_help
bool m_did_set_help
Definition: CommandAlias.h:79
lldb_private::OptionElementVector
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:42
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::Options::VerifyPartialOptions
bool VerifyPartialOptions(CommandReturnObject &result)
Definition: Options.cpp:622
lldb_private::CommandAlias::SetHelp
void SetHelp(llvm::StringRef str) override
Definition: CommandAlias.cpp:221
lldb_private::CommandAlias::GetHelp
llvm::StringRef GetHelp() override
Definition: CommandAlias.cpp:231
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:226
lldb_private::CommandAlias::HandleCompletion
void HandleCompletion(CompletionRequest &request) override
This default version handles calling option argument completions and then calls HandleArgumentComplet...
Definition: CommandAlias.cpp:118
lldb_private::CommandAlias::Execute
bool Execute(const char *args_string, CommandReturnObject &result) override
Definition: CommandAlias.cpp:136
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:203
lldb_private::CommandAlias::GetAliasExpansion
void GetAliasExpansion(StreamString &help_string) const
Definition: CommandAlias.cpp:141
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:123
lldb_private::CommandReturnObject::Succeeded
bool Succeeded()
Definition: CommandReturnObject.cpp:125
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:378
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:970
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:112