blob: 5dae9a078cd22206ae7129358ae0244c7d877285 [file] [log] [blame]
Jim Inghamebc09c32010-07-07 03:36:20 +00001//===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Jim Inghamebc09c32010-07-07 03:36:20 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
Greg Clayton0e5e5a72011-04-20 22:55:21 +000013#include "llvm/ADT/StringRef.h"
14
Jim Inghamebc09c32010-07-07 03:36:20 +000015// Project includes
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +000016#include "CommandObjectCommands.h"
Enrico Granata46d4aa22016-02-29 23:22:53 +000017#include "CommandObjectHelp.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000018#include "lldb/Core/Debugger.h"
Greg Clayton44d93782014-01-27 23:43:24 +000019#include "lldb/Core/IOHandler.h"
Enrico Granatabe93a352011-08-16 16:49:25 +000020#include "lldb/Core/StringList.h"
Greg Claytonde164aa2011-04-20 16:37:46 +000021#include "lldb/Interpreter/Args.h"
Enrico Granata7594f142013-06-17 22:51:50 +000022#include "lldb/Interpreter/CommandHistory.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000023#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytonde164aa2011-04-20 16:37:46 +000024#include "lldb/Interpreter/CommandObjectRegexCommand.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000025#include "lldb/Interpreter/CommandReturnObject.h"
Enrico Granata012d4fc2013-06-11 01:26:35 +000026#include "lldb/Interpreter/OptionValueBoolean.h"
Enrico Granata45d0e232016-03-31 01:10:54 +000027#include "lldb/Interpreter/OptionValueString.h"
Enrico Granata7594f142013-06-17 22:51:50 +000028#include "lldb/Interpreter/OptionValueUInt64.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000029#include "lldb/Interpreter/Options.h"
Enrico Granata99f0b8f2011-08-17 01:30:04 +000030#include "lldb/Interpreter/ScriptInterpreter.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000031
32using namespace lldb;
33using namespace lldb_private;
34
Jim Inghamebc09c32010-07-07 03:36:20 +000035//-------------------------------------------------------------------------
36// CommandObjectCommandsSource
37//-------------------------------------------------------------------------
38
Jim Ingham5a988412012-06-08 21:56:10 +000039class CommandObjectCommandsHistory : public CommandObjectParsed
Jim Inghama5a97eb2011-07-12 03:12:18 +000040{
Jim Ingham5a988412012-06-08 21:56:10 +000041public:
42 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +000043 CommandObjectParsed(interpreter,
44 "command history",
45 "Dump the history of commands in this session.",
46 nullptr),
Jim Ingham5a988412012-06-08 21:56:10 +000047 m_options (interpreter)
48 {
49 }
50
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +000051 ~CommandObjectCommandsHistory() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +000052
Bruce Mitchener13d21e92015-10-07 16:56:17 +000053 Options *
54 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +000055 {
56 return &m_options;
57 }
58
59protected:
Jim Inghama5a97eb2011-07-12 03:12:18 +000060 class CommandOptions : public Options
61 {
62 public:
Jim Inghama5a97eb2011-07-12 03:12:18 +000063 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata7594f142013-06-17 22:51:50 +000064 Options (interpreter),
65 m_start_idx(0),
66 m_stop_idx(0),
67 m_count(0),
Enrico Granata63123b62013-06-17 23:28:27 +000068 m_clear(false)
Jim Inghama5a97eb2011-07-12 03:12:18 +000069 {
70 }
71
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +000072 ~CommandOptions() override = default;
Jim Inghama5a97eb2011-07-12 03:12:18 +000073
Bruce Mitchener13d21e92015-10-07 16:56:17 +000074 Error
75 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Inghama5a97eb2011-07-12 03:12:18 +000076 {
77 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000078 const int short_option = m_getopt_table[option_idx].val;
Jim Inghama5a97eb2011-07-12 03:12:18 +000079
80 switch (short_option)
81 {
82 case 'c':
Pavel Labathc95f7e22015-02-20 11:14:59 +000083 error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
Jim Inghama5a97eb2011-07-12 03:12:18 +000084 break;
85 case 's':
Enrico Granata7594f142013-06-17 22:51:50 +000086 if (option_arg && strcmp("end", option_arg) == 0)
87 {
88 m_start_idx.SetCurrentValue(UINT64_MAX);
89 m_start_idx.SetOptionWasSet();
90 }
91 else
Pavel Labathc95f7e22015-02-20 11:14:59 +000092 error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
Enrico Granata7594f142013-06-17 22:51:50 +000093 break;
94 case 'e':
Pavel Labathc95f7e22015-02-20 11:14:59 +000095 error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
Enrico Granata7594f142013-06-17 22:51:50 +000096 break;
Enrico Granata63123b62013-06-17 23:28:27 +000097 case 'C':
98 m_clear.SetCurrentValue(true);
99 m_clear.SetOptionWasSet();
Jim Inghama5a97eb2011-07-12 03:12:18 +0000100 break;
101 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000102 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghama5a97eb2011-07-12 03:12:18 +0000103 break;
104 }
105
106 return error;
107 }
108
109 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000110 OptionParsingStarting () override
Jim Inghama5a97eb2011-07-12 03:12:18 +0000111 {
Enrico Granata7594f142013-06-17 22:51:50 +0000112 m_start_idx.Clear();
113 m_stop_idx.Clear();
114 m_count.Clear();
Enrico Granata63123b62013-06-17 23:28:27 +0000115 m_clear.Clear();
Jim Inghama5a97eb2011-07-12 03:12:18 +0000116 }
117
118 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000119 GetDefinitions () override
Jim Inghama5a97eb2011-07-12 03:12:18 +0000120 {
121 return g_option_table;
122 }
123
124 // Options table: Required for subclasses of Options.
125
126 static OptionDefinition g_option_table[];
127
128 // Instance variables to hold the values for command options.
129
Enrico Granata7594f142013-06-17 22:51:50 +0000130 OptionValueUInt64 m_start_idx;
131 OptionValueUInt64 m_stop_idx;
132 OptionValueUInt64 m_count;
Enrico Granata63123b62013-06-17 23:28:27 +0000133 OptionValueBoolean m_clear;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000134 };
135
Jim Inghama5a97eb2011-07-12 03:12:18 +0000136 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000137 DoExecute (Args& command, CommandReturnObject &result) override
Jim Inghama5a97eb2011-07-12 03:12:18 +0000138 {
Enrico Granata63123b62013-06-17 23:28:27 +0000139 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
Enrico Granata7594f142013-06-17 22:51:50 +0000140 {
141 m_interpreter.GetCommandHistory().Clear();
142 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
143 }
144 else
145 {
146 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
147 {
148 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
149 result.SetStatus(lldb::eReturnStatusFailed);
150 }
151 else
152 {
Virgile Bello84400ec2013-08-27 16:22:29 +0000153 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
154 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
155 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
Enrico Granata7594f142013-06-17 22:51:50 +0000156
157 const CommandHistory& history(m_interpreter.GetCommandHistory());
158
159 if (start_idx.first && start_idx.second == UINT64_MAX)
160 {
161 if (count.first)
162 {
163 start_idx.second = history.GetSize() - count.second;
164 stop_idx.second = history.GetSize() - 1;
165 }
166 else if (stop_idx.first)
167 {
168 start_idx.second = stop_idx.second;
169 stop_idx.second = history.GetSize() - 1;
170 }
171 else
172 {
173 start_idx.second = 0;
174 stop_idx.second = history.GetSize() - 1;
175 }
176 }
177 else
178 {
179 if (!start_idx.first && !stop_idx.first && !count.first)
180 {
181 start_idx.second = 0;
182 stop_idx.second = history.GetSize() - 1;
183 }
184 else if (start_idx.first)
185 {
186 if (count.first)
187 {
188 stop_idx.second = start_idx.second + count.second - 1;
189 }
190 else if (!stop_idx.first)
191 {
192 stop_idx.second = history.GetSize() - 1;
193 }
194 }
195 else if (stop_idx.first)
196 {
197 if (count.first)
198 {
199 if (stop_idx.second >= count.second)
200 start_idx.second = stop_idx.second - count.second + 1;
201 else
202 start_idx.second = 0;
203 }
204 }
205 else /* if (count.first) */
206 {
207 start_idx.second = 0;
208 stop_idx.second = count.second - 1;
209 }
210 }
211 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
212 }
213 }
Jim Inghama5a97eb2011-07-12 03:12:18 +0000214 return result.Succeeded();
215
216 }
Jim Ingham5a988412012-06-08 21:56:10 +0000217
218 CommandOptions m_options;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000219};
220
221OptionDefinition
222CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
223{
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000224{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
225{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
226{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
227{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clears the current command history."},
228{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Inghama5a97eb2011-07-12 03:12:18 +0000229};
230
Jim Inghama5a97eb2011-07-12 03:12:18 +0000231//-------------------------------------------------------------------------
232// CommandObjectCommandsSource
233//-------------------------------------------------------------------------
234
Jim Ingham5a988412012-06-08 21:56:10 +0000235class CommandObjectCommandsSource : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000236{
Jim Ingham5a988412012-06-08 21:56:10 +0000237public:
238 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000239 CommandObjectParsed(interpreter,
240 "command source",
241 "Read in debugger commands from the file <filename> and execute them.",
242 nullptr),
Jim Ingham5a988412012-06-08 21:56:10 +0000243 m_options (interpreter)
244 {
245 CommandArgumentEntry arg;
246 CommandArgumentData file_arg;
247
248 // Define the first (and only) variant of this arg.
249 file_arg.arg_type = eArgTypeFilename;
250 file_arg.arg_repetition = eArgRepeatPlain;
251
252 // There is only one variant this argument could be; put it into the argument entry.
253 arg.push_back (file_arg);
254
255 // Push the data for the first argument into the m_arguments vector.
256 m_arguments.push_back (arg);
257 }
258
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000259 ~CommandObjectCommandsSource() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000260
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000261 const char*
262 GetRepeatCommand (Args &current_command_args, uint32_t index) override
Jim Ingham5a988412012-06-08 21:56:10 +0000263 {
264 return "";
265 }
266
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000267 int
Jim Ingham5a988412012-06-08 21:56:10 +0000268 HandleArgumentCompletion (Args &input,
269 int &cursor_index,
270 int &cursor_char_position,
271 OptionElementVector &opt_element_vector,
272 int match_start_point,
273 int max_return_elements,
274 bool &word_complete,
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000275 StringList &matches) override
Jim Ingham5a988412012-06-08 21:56:10 +0000276 {
277 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
278 completion_str.erase (cursor_char_position);
279
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000280 CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
281 CommandCompletions::eDiskFileCompletion,
282 completion_str.c_str(),
283 match_start_point,
284 max_return_elements,
285 nullptr,
286 word_complete,
287 matches);
Jim Ingham5a988412012-06-08 21:56:10 +0000288 return matches.GetSize();
289 }
290
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000291 Options *
292 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +0000293 {
294 return &m_options;
295 }
296
297protected:
Jim Inghame16c50a2011-02-18 00:54:25 +0000298 class CommandOptions : public Options
299 {
300 public:
Greg Claytoneb0103f2011-04-07 22:46:35 +0000301 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata012d4fc2013-06-11 01:26:35 +0000302 Options (interpreter),
Greg Clayton340b0302014-02-05 17:57:57 +0000303 m_stop_on_error (true),
304 m_silent_run (false),
305 m_stop_on_continue (true)
Greg Claytoneb0103f2011-04-07 22:46:35 +0000306 {
307 }
Jim Inghame16c50a2011-02-18 00:54:25 +0000308
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000309 ~CommandOptions() override = default;
Jim Inghame16c50a2011-02-18 00:54:25 +0000310
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000311 Error
312 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Jim Inghame16c50a2011-02-18 00:54:25 +0000313 {
314 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000315 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame16c50a2011-02-18 00:54:25 +0000316
317 switch (short_option)
318 {
319 case 'e':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000320 error = m_stop_on_error.SetValueFromString(option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000321 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000322
Jim Inghame16c50a2011-02-18 00:54:25 +0000323 case 'c':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000324 error = m_stop_on_continue.SetValueFromString(option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000325 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000326
Michael Sartain60986172013-07-09 23:22:53 +0000327 case 's':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000328 error = m_silent_run.SetValueFromString(option_arg);
Michael Sartain60986172013-07-09 23:22:53 +0000329 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000330
Jim Inghame16c50a2011-02-18 00:54:25 +0000331 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000332 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghame16c50a2011-02-18 00:54:25 +0000333 break;
334 }
335
336 return error;
337 }
338
339 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000340 OptionParsingStarting () override
Jim Inghame16c50a2011-02-18 00:54:25 +0000341 {
Enrico Granata012d4fc2013-06-11 01:26:35 +0000342 m_stop_on_error.Clear();
Greg Clayton340b0302014-02-05 17:57:57 +0000343 m_silent_run.Clear();
344 m_stop_on_continue.Clear();
Jim Inghame16c50a2011-02-18 00:54:25 +0000345 }
346
Greg Claytone0d378b2011-03-24 21:19:54 +0000347 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000348 GetDefinitions () override
Jim Inghame16c50a2011-02-18 00:54:25 +0000349 {
350 return g_option_table;
351 }
352
353 // Options table: Required for subclasses of Options.
354
Greg Claytone0d378b2011-03-24 21:19:54 +0000355 static OptionDefinition g_option_table[];
Jim Inghame16c50a2011-02-18 00:54:25 +0000356
357 // Instance variables to hold the values for command options.
358
Enrico Granata012d4fc2013-06-11 01:26:35 +0000359 OptionValueBoolean m_stop_on_error;
Jim Ingham7d8555c2014-11-18 19:12:13 +0000360 OptionValueBoolean m_silent_run;
Greg Clayton340b0302014-02-05 17:57:57 +0000361 OptionValueBoolean m_stop_on_continue;
Jim Inghame16c50a2011-02-18 00:54:25 +0000362 };
363
Jim Inghamebc09c32010-07-07 03:36:20 +0000364 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000365 DoExecute(Args& command, CommandReturnObject &result) override
Jim Inghamebc09c32010-07-07 03:36:20 +0000366 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000367 const size_t argc = command.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000368 if (argc == 1)
369 {
Jim Ingham5a988412012-06-08 21:56:10 +0000370 const char *filename = command.GetArgumentAtIndex(0);
Jim Inghamebc09c32010-07-07 03:36:20 +0000371
Johnny Chen1ee38532010-10-20 21:40:50 +0000372 FileSpec cmd_file (filename, true);
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000373 ExecutionContext *exe_ctx = nullptr; // Just use the default context.
Greg Clayton340b0302014-02-05 17:57:57 +0000374
375 // If any options were set, then use them
376 if (m_options.m_stop_on_error.OptionWasSet() ||
377 m_options.m_silent_run.OptionWasSet() ||
378 m_options.m_stop_on_continue.OptionWasSet())
379 {
380 // Use user set settings
Jim Ingham26c7bf92014-10-11 00:38:27 +0000381 CommandInterpreterRunOptions options;
382 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
383 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
Jim Ingham7d8555c2014-11-18 19:12:13 +0000384 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
385 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
Jim Ingham26c7bf92014-10-11 00:38:27 +0000386
Greg Clayton340b0302014-02-05 17:57:57 +0000387 m_interpreter.HandleCommandsFromFile (cmd_file,
388 exe_ctx,
Jim Ingham26c7bf92014-10-11 00:38:27 +0000389 options,
Greg Clayton340b0302014-02-05 17:57:57 +0000390 result);
Greg Clayton340b0302014-02-05 17:57:57 +0000391 }
392 else
393 {
394 // No options were set, inherit any settings from nested "command source" commands,
395 // or set to sane default settings...
Jim Ingham26c7bf92014-10-11 00:38:27 +0000396 CommandInterpreterRunOptions options;
Greg Clayton340b0302014-02-05 17:57:57 +0000397 m_interpreter.HandleCommandsFromFile (cmd_file,
398 exe_ctx,
Jim Ingham26c7bf92014-10-11 00:38:27 +0000399 options,
Greg Clayton340b0302014-02-05 17:57:57 +0000400 result);
Greg Clayton340b0302014-02-05 17:57:57 +0000401 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000402 }
403 else
404 {
405 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
406 result.SetStatus (eReturnStatusFailed);
407 }
408 return result.Succeeded();
Jim Inghamebc09c32010-07-07 03:36:20 +0000409 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000410
Jim Ingham5a988412012-06-08 21:56:10 +0000411 CommandOptions m_options;
Jim Inghamebc09c32010-07-07 03:36:20 +0000412};
413
Greg Claytone0d378b2011-03-24 21:19:54 +0000414OptionDefinition
Jim Inghame16c50a2011-02-18 00:54:25 +0000415CommandObjectCommandsSource::CommandOptions::g_option_table[] =
416{
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000417{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
418{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
419{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
420{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Jim Inghame16c50a2011-02-18 00:54:25 +0000421};
422
Jim Inghamebc09c32010-07-07 03:36:20 +0000423#pragma mark CommandObjectCommandsAlias
424//-------------------------------------------------------------------------
425// CommandObjectCommandsAlias
426//-------------------------------------------------------------------------
427
Enrico Granatabe93a352011-08-16 16:49:25 +0000428static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
429 "You must define a Python function with this signature:\n"
Greg Clayton44d93782014-01-27 23:43:24 +0000430 "def my_command_impl(debugger, args, result, internal_dict):\n";
Enrico Granatabe93a352011-08-16 16:49:25 +0000431
Jim Ingham5a988412012-06-08 21:56:10 +0000432class CommandObjectCommandsAlias : public CommandObjectRaw
Jim Inghamebc09c32010-07-07 03:36:20 +0000433{
Enrico Granata45d0e232016-03-31 01:10:54 +0000434protected:
435 class CommandOptions : public OptionGroup
436 {
437 public:
438 CommandOptions () :
439 OptionGroup(),
440 m_help(),
441 m_long_help()
442 {}
443
444 ~CommandOptions() override = default;
445
446 uint32_t
447 GetNumDefinitions () override
448 {
449 return 3;
450 }
451
452 const OptionDefinition*
453 GetDefinitions () override
454 {
455 return g_option_table;
456 }
457
458 Error
459 SetOptionValue (CommandInterpreter &interpreter,
460 uint32_t option_idx,
461 const char *option_value) override
462 {
463 Error error;
464
465 const int short_option = g_option_table[option_idx].short_option;
466
467 switch (short_option)
468 {
469 case 'h':
470 m_help.SetCurrentValue(option_value);
471 m_help.SetOptionWasSet();
472 break;
473
474 case 'H':
475 m_long_help.SetCurrentValue(option_value);
476 m_long_help.SetOptionWasSet();
477 break;
478
479 default:
480 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
481 break;
482 }
483
484 return error;
485 }
486
487 void
488 OptionParsingStarting (CommandInterpreter &interpreter) override
489 {
490 m_help.Clear();
491 m_long_help.Clear();
492 }
493
494 // Options table: Required for subclasses of Options.
495
496 static OptionDefinition g_option_table[];
497 OptionValueString m_help;
498 OptionValueString m_long_help;
499 };
500
501 OptionGroupOptions m_option_group;
502 CommandOptions m_command_options;
503
Jim Inghamebc09c32010-07-07 03:36:20 +0000504public:
Enrico Granata45d0e232016-03-31 01:10:54 +0000505 Options *
506 GetOptions () override
507 {
508 return &m_option_group;
509 }
510
Greg Claytona7015092010-09-18 01:14:36 +0000511 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000512 CommandObjectRaw(interpreter,
513 "command alias",
514 "Allow users to define their own debugger command abbreviations.",
Enrico Granata45d0e232016-03-31 01:10:54 +0000515 nullptr),
516 m_option_group(interpreter),
517 m_command_options()
Jim Inghamebc09c32010-07-07 03:36:20 +0000518 {
Enrico Granata45d0e232016-03-31 01:10:54 +0000519 m_option_group.Append(&m_command_options);
520 m_option_group.Finalize();
521
Jim Inghamebc09c32010-07-07 03:36:20 +0000522 SetHelpLong(
Kate Stoneea671fb2015-07-14 05:48:36 +0000523"'alias' allows the user to create a short-cut or abbreviation for long \
524commands, multi-word commands, and commands that take particular options. \
525Below are some simple examples of how one might use the 'alias' command:" R"(
526
527(lldb) command alias sc script
528
529 Creates the abbreviation 'sc' for the 'script' command.
530
531(lldb) command alias bp breakpoint
532
533)" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
534breakpoint commands are two-word commands, the user would still need to \
535enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
536
537(lldb) command alias bpl breakpoint list
538
539 Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
540
541)" "An alias can include some options for the command, with the values either \
542filled in at the time the alias is created, or specified as positional \
543arguments, to be filled in when the alias is invoked. The following example \
544shows how to create aliases with options:" R"(
545
546(lldb) command alias bfl breakpoint set -f %1 -l %2
547
548)" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
549options already part of the alias. So if the user wants to set a breakpoint \
550by file and line without explicitly having to use the -f and -l options, the \
551user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \
552for the actual arguments that will be passed when the alias command is used. \
553The number in the placeholder refers to the position/order the actual value \
554occupies when the alias is used. All the occurrences of '%1' in the alias \
555will be replaced with the first argument, all the occurrences of '%2' in the \
556alias will be replaced with the second argument, and so on. This also allows \
557actual arguments to be used multiple times within an alias (see 'process \
558launch' example below)." R"(
559
560)" "Note: the positional arguments must substitute as whole words in the resultant \
561command, so you can't at present do something like this to append the file extension \
562\".cpp\":" R"(
563
564(lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
565
566)" "For more complex aliasing, use the \"command regex\" command instead. In the \
567'bfl' case above, the actual file value will be filled in with the first argument \
568following 'bfl' and the actual line number value will be filled in with the second \
569argument. The user would use this alias as follows:" R"(
570
571(lldb) command alias bfl breakpoint set -f %1 -l %2
572(lldb) bfl my-file.c 137
573
574This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
575
576Another example:
577
578(lldb) command alias pltty process launch -s -o %1 -e %1
579(lldb) pltty /dev/tty0
580
581 Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
582
583)" "If the user always wanted to pass the same value to a particular option, the \
584alias could be defined with that value directly in the alias as a constant, \
585rather than using a positional placeholder:" R"(
586
587(lldb) command alias bl3 breakpoint set -f %1 -l 3
588
589 Always sets a breakpoint on line 3 of whatever file is indicated.)"
590 );
Jim Inghamebc09c32010-07-07 03:36:20 +0000591
Caroline Tice405fe672010-10-04 22:28:36 +0000592 CommandArgumentEntry arg1;
593 CommandArgumentEntry arg2;
594 CommandArgumentEntry arg3;
595 CommandArgumentData alias_arg;
596 CommandArgumentData cmd_arg;
597 CommandArgumentData options_arg;
598
599 // Define the first (and only) variant of this arg.
600 alias_arg.arg_type = eArgTypeAliasName;
601 alias_arg.arg_repetition = eArgRepeatPlain;
602
603 // There is only one variant this argument could be; put it into the argument entry.
604 arg1.push_back (alias_arg);
605
606 // Define the first (and only) variant of this arg.
607 cmd_arg.arg_type = eArgTypeCommandName;
608 cmd_arg.arg_repetition = eArgRepeatPlain;
609
610 // There is only one variant this argument could be; put it into the argument entry.
611 arg2.push_back (cmd_arg);
612
613 // Define the first (and only) variant of this arg.
614 options_arg.arg_type = eArgTypeAliasOptions;
615 options_arg.arg_repetition = eArgRepeatOptional;
616
617 // There is only one variant this argument could be; put it into the argument entry.
618 arg3.push_back (options_arg);
619
620 // Push the data for the first argument into the m_arguments vector.
621 m_arguments.push_back (arg1);
622 m_arguments.push_back (arg2);
623 m_arguments.push_back (arg3);
Jim Inghamebc09c32010-07-07 03:36:20 +0000624 }
625
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000626 ~CommandObjectCommandsAlias() override = default;
Jim Inghamebc09c32010-07-07 03:36:20 +0000627
Jim Ingham5a988412012-06-08 21:56:10 +0000628protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000629 bool
630 DoExecute (const char *raw_command_line, CommandReturnObject &result) override
Caroline Tice844d2302010-12-09 22:52:49 +0000631 {
Enrico Granata45d0e232016-03-31 01:10:54 +0000632 if (!raw_command_line || !raw_command_line[0])
633 {
Enrico Granatad72e4122016-04-08 17:56:57 +0000634 result.AppendError ("'command alias' requires at least two arguments");
Enrico Granata45d0e232016-03-31 01:10:54 +0000635 return false;
636 }
637
638 m_option_group.NotifyOptionParsingStarting();
639
640 const char * remainder = nullptr;
641
642 if (raw_command_line[0] == '-')
643 {
644 // We have some options and these options MUST end with --.
645 const char *end_options = nullptr;
646 const char *s = raw_command_line;
647 while (s && s[0])
648 {
649 end_options = ::strstr (s, "--");
650 if (end_options)
651 {
652 end_options += 2; // Get past the "--"
653 if (::isspace (end_options[0]))
654 {
655 remainder = end_options;
656 while (::isspace (*remainder))
657 ++remainder;
658 break;
659 }
660 }
661 s = end_options;
662 }
663
664 if (end_options)
665 {
666 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
667 if (!ParseOptions (args, result))
668 return false;
669
670 Error error (m_option_group.NotifyOptionParsingFinished());
671 if (error.Fail())
672 {
673 result.AppendError (error.AsCString());
674 result.SetStatus (eReturnStatusFailed);
675 return false;
676 }
677 }
678 }
679 if (nullptr == remainder)
680 remainder = raw_command_line;
681
682 std::string raw_command_string (remainder);
683 Args args (raw_command_string.c_str());
Caroline Tice844d2302010-12-09 22:52:49 +0000684
685 size_t argc = args.GetArgumentCount();
686
687 if (argc < 2)
688 {
Enrico Granatad72e4122016-04-08 17:56:57 +0000689 result.AppendError ("'command alias' requires at least two arguments");
Caroline Tice844d2302010-12-09 22:52:49 +0000690 result.SetStatus (eReturnStatusFailed);
691 return false;
692 }
693
694 // Get the alias command.
695
696 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatad72e4122016-04-08 17:56:57 +0000697 if (alias_command.size() > 1 &&
698 alias_command[0] == '-')
699 {
700 result.AppendError("aliases starting with a dash are not supported");
701 if (alias_command == "--help" || alias_command == "--long-help")
702 {
703 result.AppendWarning("if trying to pass options to 'command alias' add a -- at the end of the options");
704 }
705 result.SetStatus (eReturnStatusFailed);
706 return false;
707 }
Enrico Granatabe93a352011-08-16 16:49:25 +0000708
Caroline Tice844d2302010-12-09 22:52:49 +0000709 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
710 // does the stripping itself.
711 size_t pos = raw_command_string.find (alias_command);
712 if (pos == 0)
713 {
714 raw_command_string = raw_command_string.substr (alias_command.size());
715 pos = raw_command_string.find_first_not_of (' ');
716 if ((pos != std::string::npos) && (pos > 0))
717 raw_command_string = raw_command_string.substr (pos);
718 }
719 else
720 {
721 result.AppendError ("Error parsing command string. No alias created.");
722 result.SetStatus (eReturnStatusFailed);
723 return false;
724 }
725
726
727 // Verify that the command is alias-able.
728 if (m_interpreter.CommandExists (alias_command.c_str()))
729 {
730 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
731 alias_command.c_str());
732 result.SetStatus (eReturnStatusFailed);
733 return false;
734 }
735
736 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
737 // raw_command_string is returned with the name of the command object stripped off the front.
Enrico Granatad72e4122016-04-08 17:56:57 +0000738 std::string original_raw_command_string(raw_command_string);
Caroline Tice844d2302010-12-09 22:52:49 +0000739 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
740
741 if (!cmd_obj)
742 {
Enrico Granatad72e4122016-04-08 17:56:57 +0000743 result.AppendErrorWithFormat ("invalid command given to 'command alias'. '%s' does not begin with a valid command."
744 " No alias created.", original_raw_command_string.c_str());
Caroline Tice844d2302010-12-09 22:52:49 +0000745 result.SetStatus (eReturnStatusFailed);
746 return false;
747 }
748 else if (!cmd_obj->WantsRawCommandString ())
749 {
750 // Note that args was initialized with the original command, and has not been updated to this point.
751 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
Jim Ingham5a988412012-06-08 21:56:10 +0000752 return HandleAliasingNormalCommand (args, result);
Caroline Tice844d2302010-12-09 22:52:49 +0000753 }
754 else
755 {
Jim Ingham5a988412012-06-08 21:56:10 +0000756 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
757 }
758 return result.Succeeded();
759 }
760
761 bool
762 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
763 {
Caroline Tice844d2302010-12-09 22:52:49 +0000764 // Verify & handle any options/arguments passed to the alias command
765
766 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
Enrico Granata5e550302016-03-08 03:00:27 +0000767
Enrico Granata212130a2016-03-08 05:37:15 +0000768 if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false))
769 {
770 if (m_interpreter.AliasExists (alias_command.c_str())
771 || m_interpreter.UserCommandExists (alias_command.c_str()))
772 {
773 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
774 alias_command.c_str());
775 }
Enrico Granata45d0e232016-03-31 01:10:54 +0000776 if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str()))
Enrico Granata212130a2016-03-08 05:37:15 +0000777 {
Enrico Granata45d0e232016-03-31 01:10:54 +0000778 if (m_command_options.m_help.OptionWasSet())
779 alias->SetHelp(m_command_options.m_help.GetCurrentValue());
780 if (m_command_options.m_long_help.OptionWasSet())
781 alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
Enrico Granata212130a2016-03-08 05:37:15 +0000782 result.SetStatus (eReturnStatusSuccessFinishNoResult);
783 }
784 else
785 {
786 result.AppendError ("Unable to create requested alias.\n");
787 result.SetStatus (eReturnStatusFailed);
788 }
Caroline Ticeca90c472011-05-06 21:37:15 +0000789
Caroline Tice472362e2010-12-14 18:51:39 +0000790 }
791 else
792 {
793 result.AppendError ("Unable to create requested alias.\n");
794 result.SetStatus (eReturnStatusFailed);
795 }
Enrico Granata212130a2016-03-08 05:37:15 +0000796
Jim Ingham5a988412012-06-08 21:56:10 +0000797 return result.Succeeded ();
Caroline Tice844d2302010-12-09 22:52:49 +0000798 }
Jim Ingham5a988412012-06-08 21:56:10 +0000799
Jim Inghamebc09c32010-07-07 03:36:20 +0000800 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000801 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000802 {
Caroline Tice867b185d2010-09-21 23:25:40 +0000803 size_t argc = args.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000804
805 if (argc < 2)
Greg Claytonc982c762010-07-09 20:39:50 +0000806 {
Enrico Granatad72e4122016-04-08 17:56:57 +0000807 result.AppendError ("'command alias' requires at least two arguments");
Jim Inghamebc09c32010-07-07 03:36:20 +0000808 result.SetStatus (eReturnStatusFailed);
809 return false;
Greg Claytonc982c762010-07-09 20:39:50 +0000810 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000811
812 const std::string alias_command = args.GetArgumentAtIndex(0);
813 const std::string actual_command = args.GetArgumentAtIndex(1);
814
815 args.Shift(); // Shift the alias command word off the argument vector.
816 args.Shift(); // Shift the old command word off the argument vector.
817
818 // Verify that the command is alias'able, and get the appropriate command object.
819
Greg Claytona7015092010-09-18 01:14:36 +0000820 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000821 {
822 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
823 alias_command.c_str());
824 result.SetStatus (eReturnStatusFailed);
825 }
826 else
827 {
Greg Claytona7015092010-09-18 01:14:36 +0000828 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Inghamebc09c32010-07-07 03:36:20 +0000829 CommandObjectSP subcommand_obj_sp;
830 bool use_subcommand = false;
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000831 if (command_obj_sp)
Jim Inghamebc09c32010-07-07 03:36:20 +0000832 {
833 CommandObject *cmd_obj = command_obj_sp.get();
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000834 CommandObject *sub_cmd_obj = nullptr;
Jim Inghamebc09c32010-07-07 03:36:20 +0000835 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
Jim Inghamebc09c32010-07-07 03:36:20 +0000836
Caroline Tice844d2302010-12-09 22:52:49 +0000837 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Inghamebc09c32010-07-07 03:36:20 +0000838 {
839 if (argc >= 3)
840 {
841 const std::string sub_command = args.GetArgumentAtIndex(0);
842 assert (sub_command.length() != 0);
Greg Clayton998255b2012-10-13 02:07:45 +0000843 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000844 if (subcommand_obj_sp)
Jim Inghamebc09c32010-07-07 03:36:20 +0000845 {
846 sub_cmd_obj = subcommand_obj_sp.get();
847 use_subcommand = true;
848 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Tice844d2302010-12-09 22:52:49 +0000849 cmd_obj = sub_cmd_obj;
Jim Inghamebc09c32010-07-07 03:36:20 +0000850 }
851 else
852 {
Caroline Ticef415eeb2010-11-02 19:00:04 +0000853 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
854 "Unable to create alias.\n",
855 sub_command.c_str(), actual_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000856 result.SetStatus (eReturnStatusFailed);
857 return false;
858 }
859 }
860 }
861
862 // Verify & handle any options/arguments passed to the alias command
863
Enrico Granata212130a2016-03-08 05:37:15 +0000864 std::string args_string;
865
Jim Inghamebc09c32010-07-07 03:36:20 +0000866 if (args.GetArgumentCount () > 0)
867 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000868 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
869 if (use_subcommand)
870 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
871
Caroline Ticeca90c472011-05-06 21:37:15 +0000872 args.GetCommandString (args_string);
Jim Inghamebc09c32010-07-07 03:36:20 +0000873 }
Enrico Granata212130a2016-03-08 05:37:15 +0000874
Greg Claytona7015092010-09-18 01:14:36 +0000875 if (m_interpreter.AliasExists (alias_command.c_str())
876 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000877 {
Enrico Granata212130a2016-03-08 05:37:15 +0000878 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
Jim Inghamebc09c32010-07-07 03:36:20 +0000879 alias_command.c_str());
880 }
Enrico Granata212130a2016-03-08 05:37:15 +0000881
Enrico Granata45d0e232016-03-31 01:10:54 +0000882 if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(),
883 use_subcommand ? subcommand_obj_sp : command_obj_sp,
884 args_string.c_str()))
Enrico Granata212130a2016-03-08 05:37:15 +0000885 {
Enrico Granata45d0e232016-03-31 01:10:54 +0000886 if (m_command_options.m_help.OptionWasSet())
887 alias->SetHelp(m_command_options.m_help.GetCurrentValue());
888 if (m_command_options.m_long_help.OptionWasSet())
889 alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
Enrico Granata212130a2016-03-08 05:37:15 +0000890 result.SetStatus (eReturnStatusSuccessFinishNoResult);
891 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000892 else
Enrico Granata212130a2016-03-08 05:37:15 +0000893 {
894 result.AppendError ("Unable to create requested alias.\n");
895 result.SetStatus (eReturnStatusFailed);
896 return false;
897 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000898 }
899 else
900 {
901 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
902 result.SetStatus (eReturnStatusFailed);
Caroline Ticee7941792010-10-28 23:17:48 +0000903 return false;
Jim Inghamebc09c32010-07-07 03:36:20 +0000904 }
905 }
906
907 return result.Succeeded();
908 }
909};
910
Enrico Granata45d0e232016-03-31 01:10:54 +0000911OptionDefinition
912CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
913{
914 { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Help text for this command"},
915 { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Long help text for this command"},
916 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
917};
918
Jim Inghamebc09c32010-07-07 03:36:20 +0000919#pragma mark CommandObjectCommandsUnalias
920//-------------------------------------------------------------------------
921// CommandObjectCommandsUnalias
922//-------------------------------------------------------------------------
923
Jim Ingham5a988412012-06-08 21:56:10 +0000924class CommandObjectCommandsUnalias : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000925{
926public:
Greg Claytona7015092010-09-18 01:14:36 +0000927 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000928 CommandObjectParsed(interpreter,
929 "command unalias",
930 "Allow the user to remove/delete a user-defined command abbreviation.",
931 nullptr)
Jim Inghamebc09c32010-07-07 03:36:20 +0000932 {
Caroline Tice405fe672010-10-04 22:28:36 +0000933 CommandArgumentEntry arg;
934 CommandArgumentData alias_arg;
935
936 // Define the first (and only) variant of this arg.
937 alias_arg.arg_type = eArgTypeAliasName;
938 alias_arg.arg_repetition = eArgRepeatPlain;
939
940 // There is only one variant this argument could be; put it into the argument entry.
941 arg.push_back (alias_arg);
942
943 // Push the data for the first argument into the m_arguments vector.
944 m_arguments.push_back (arg);
Jim Inghamebc09c32010-07-07 03:36:20 +0000945 }
946
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000947 ~CommandObjectCommandsUnalias() override = default;
Jim Inghamebc09c32010-07-07 03:36:20 +0000948
Jim Ingham5a988412012-06-08 21:56:10 +0000949protected:
Jim Inghamebc09c32010-07-07 03:36:20 +0000950 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +0000951 DoExecute (Args& args, CommandReturnObject &result) override
Jim Inghamebc09c32010-07-07 03:36:20 +0000952 {
953 CommandObject::CommandMap::iterator pos;
954 CommandObject *cmd_obj;
955
956 if (args.GetArgumentCount() != 0)
957 {
958 const char *command_name = args.GetArgumentAtIndex(0);
Greg Claytona7015092010-09-18 01:14:36 +0000959 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Inghamebc09c32010-07-07 03:36:20 +0000960 if (cmd_obj)
961 {
Greg Claytona7015092010-09-18 01:14:36 +0000962 if (m_interpreter.CommandExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000963 {
Greg Claytonb5472782015-01-09 19:08:20 +0000964 if (cmd_obj->IsRemovable())
965 {
966 result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
967 command_name);
968 }
969 else
970 {
971 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
972 command_name);
973 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000974 result.SetStatus (eReturnStatusFailed);
975 }
976 else
977 {
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +0000978 if (!m_interpreter.RemoveAlias(command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000979 {
Greg Claytona7015092010-09-18 01:14:36 +0000980 if (m_interpreter.AliasExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000981 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
982 command_name);
983 else
984 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
985 result.SetStatus (eReturnStatusFailed);
986 }
987 else
988 result.SetStatus (eReturnStatusSuccessFinishNoResult);
989 }
990 }
991 else
992 {
993 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
994 "current list of commands.\n",
995 command_name);
996 result.SetStatus (eReturnStatusFailed);
997 }
998 }
999 else
1000 {
1001 result.AppendError ("must call 'unalias' with a valid alias");
1002 result.SetStatus (eReturnStatusFailed);
1003 }
1004
1005 return result.Succeeded();
1006 }
1007};
1008
Greg Claytonb5472782015-01-09 19:08:20 +00001009#pragma mark CommandObjectCommandsDelete
1010//-------------------------------------------------------------------------
1011// CommandObjectCommandsDelete
1012//-------------------------------------------------------------------------
1013
1014class CommandObjectCommandsDelete : public CommandObjectParsed
1015{
1016public:
1017 CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001018 CommandObjectParsed(interpreter,
1019 "command delete",
1020 "Allow the user to delete user-defined regular expression, python or multi-word commands.",
1021 nullptr)
Greg Claytonb5472782015-01-09 19:08:20 +00001022 {
1023 CommandArgumentEntry arg;
1024 CommandArgumentData alias_arg;
1025
1026 // Define the first (and only) variant of this arg.
1027 alias_arg.arg_type = eArgTypeCommandName;
1028 alias_arg.arg_repetition = eArgRepeatPlain;
1029
1030 // There is only one variant this argument could be; put it into the argument entry.
1031 arg.push_back (alias_arg);
1032
1033 // Push the data for the first argument into the m_arguments vector.
1034 m_arguments.push_back (arg);
1035 }
1036
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001037 ~CommandObjectCommandsDelete() override = default;
Greg Claytonb5472782015-01-09 19:08:20 +00001038
1039protected:
1040 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001041 DoExecute (Args& args, CommandReturnObject &result) override
Greg Claytonb5472782015-01-09 19:08:20 +00001042 {
1043 CommandObject::CommandMap::iterator pos;
1044
1045 if (args.GetArgumentCount() != 0)
1046 {
1047 const char *command_name = args.GetArgumentAtIndex(0);
1048 if (m_interpreter.CommandExists (command_name))
1049 {
1050 if (m_interpreter.RemoveCommand (command_name))
1051 {
1052 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1053 }
1054 else
1055 {
1056 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
1057 command_name);
1058 result.SetStatus (eReturnStatusFailed);
1059 }
1060 }
1061 else
1062 {
Enrico Granata46d4aa22016-02-29 23:22:53 +00001063 StreamString error_msg_stream;
1064 const bool generate_apropos = true;
1065 const bool generate_type_lookup = false;
1066 CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
1067 command_name,
1068 nullptr,
1069 nullptr,
1070 generate_apropos,
1071 generate_type_lookup);
1072 result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
Greg Claytonb5472782015-01-09 19:08:20 +00001073 result.SetStatus (eReturnStatusFailed);
1074 }
1075 }
1076 else
1077 {
1078 result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
1079 result.SetStatus (eReturnStatusFailed);
1080 }
1081
1082 return result.Succeeded();
1083 }
1084};
1085
Greg Claytonde164aa2011-04-20 16:37:46 +00001086//-------------------------------------------------------------------------
1087// CommandObjectCommandsAddRegex
1088//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +00001089#pragma mark CommandObjectCommandsAddRegex
Greg Claytonde164aa2011-04-20 16:37:46 +00001090
Greg Clayton44d93782014-01-27 23:43:24 +00001091class CommandObjectCommandsAddRegex :
1092 public CommandObjectParsed,
Greg Claytonea508632014-11-18 00:43:17 +00001093 public IOHandlerDelegateMultiline
Greg Claytonde164aa2011-04-20 16:37:46 +00001094{
1095public:
1096 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001097 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001098 "command regex",
Greg Claytonde164aa2011-04-20 16:37:46 +00001099 "Allow the user to create a regular expression command.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001100 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytonea508632014-11-18 00:43:17 +00001101 IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
Greg Claytonde164aa2011-04-20 16:37:46 +00001102 m_options (interpreter)
1103 {
Kate Stoneea671fb2015-07-14 05:48:36 +00001104 SetHelpLong(R"(
1105)" "This command allows the user to create powerful regular expression commands \
1106with substitutions. The regular expressions and substitutions are specified \
1107using the regular expression substitution format of:" R"(
1108
1109 s/<regex>/<subst>/
1110
1111)" "<regex> is a regular expression that can use parenthesis to capture regular \
1112expression input and substitute the captured matches in the output using %1 \
1113for the first match, %2 for the second, and so on." R"(
1114
1115)" "The regular expressions can all be specified on the command line if more than \
1116one argument is provided. If just the command name is provided on the command \
1117line, then the regular expressions and substitutions can be entered on separate \
1118lines, followed by an empty line to terminate the command definition." R"(
1119
1120EXAMPLES
1121
1122)" "The following example will define a regular expression command named 'f' that \
1123will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
1124a number follows 'f':" R"(
1125
1126 (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
1127 );
Greg Claytonde164aa2011-04-20 16:37:46 +00001128 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001129
1130 ~CommandObjectCommandsAddRegex() override = default;
1131
Jim Ingham5a988412012-06-08 21:56:10 +00001132protected:
Greg Claytonea508632014-11-18 00:43:17 +00001133 void
1134 IOHandlerActivated (IOHandler &io_handler) override
Greg Clayton44d93782014-01-27 23:43:24 +00001135 {
1136 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1137 if (output_sp)
1138 {
1139 output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n");
1140 output_sp->Flush();
1141 }
1142 }
1143
Greg Claytonea508632014-11-18 00:43:17 +00001144 void
1145 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
Greg Clayton44d93782014-01-27 23:43:24 +00001146 {
1147 io_handler.SetIsDone(true);
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001148 if (m_regex_cmd_ap)
Greg Clayton44d93782014-01-27 23:43:24 +00001149 {
1150 StringList lines;
1151 if (lines.SplitIntoLines (data))
1152 {
1153 const size_t num_lines = lines.GetSize();
1154 bool check_only = false;
1155 for (size_t i=0; i<num_lines; ++i)
1156 {
Greg Clayton44d93782014-01-27 23:43:24 +00001157 llvm::StringRef bytes_strref (lines[i]);
1158 Error error = AppendRegexSubstitution (bytes_strref, check_only);
1159 if (error.Fail())
1160 {
1161 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
1162 {
1163 StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
1164 out_stream->Printf("error: %s\n", error.AsCString());
1165 }
1166 }
1167 }
1168 }
1169 if (m_regex_cmd_ap->HasRegexEntries())
1170 {
1171 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1172 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1173 }
1174 }
1175 }
Greg Clayton44d93782014-01-27 23:43:24 +00001176
Greg Claytonde164aa2011-04-20 16:37:46 +00001177 bool
Eric Christopherb0a18142014-11-18 22:40:27 +00001178 DoExecute (Args& command, CommandReturnObject &result) override
Greg Claytonde164aa2011-04-20 16:37:46 +00001179 {
Jim Ingham5a988412012-06-08 21:56:10 +00001180 const size_t argc = command.GetArgumentCount();
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001181 if (argc == 0)
Greg Claytonde164aa2011-04-20 16:37:46 +00001182 {
Jason Molenda69c12cc2011-11-10 22:43:35 +00001183 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001184 result.SetStatus (eReturnStatusFailed);
1185 }
1186 else
1187 {
1188 Error error;
Jim Ingham5a988412012-06-08 21:56:10 +00001189 const char *name = command.GetArgumentAtIndex(0);
Greg Claytonde164aa2011-04-20 16:37:46 +00001190 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1191 name,
1192 m_options.GetHelp (),
1193 m_options.GetSyntax (),
Greg Claytonb5472782015-01-09 19:08:20 +00001194 10,
1195 0,
1196 true));
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001197
1198 if (argc == 1)
Greg Claytonde164aa2011-04-20 16:37:46 +00001199 {
Greg Clayton44d93782014-01-27 23:43:24 +00001200 Debugger &debugger = m_interpreter.GetDebugger();
Kate Stonee30f11d2014-11-17 19:06:59 +00001201 bool color_prompt = debugger.GetUseColor();
Greg Clayton44d93782014-01-27 23:43:24 +00001202 const bool multiple_lines = true; // Get multiple lines
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001203 IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
1204 IOHandler::Type::Other,
1205 "lldb-regex", // Name of input reader for history
1206 "> ", // Prompt
1207 nullptr, // Continuation prompt
1208 multiple_lines,
1209 color_prompt,
1210 0, // Don't show line numbers
1211 *this));
Greg Clayton44d93782014-01-27 23:43:24 +00001212
1213 if (io_handler_sp)
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001214 {
Greg Clayton44d93782014-01-27 23:43:24 +00001215 debugger.PushIOHandler(io_handler_sp);
1216 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonde164aa2011-04-20 16:37:46 +00001217 }
1218 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001219 else
1220 {
1221 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
1222 {
Jim Ingham5a988412012-06-08 21:56:10 +00001223 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton44d93782014-01-27 23:43:24 +00001224 bool check_only = false;
1225 error = AppendRegexSubstitution (arg_strref, check_only);
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001226 if (error.Fail())
1227 break;
1228 }
1229
1230 if (error.Success())
1231 {
1232 AddRegexCommandToInterpreter();
1233 }
1234 }
1235 if (error.Fail())
1236 {
1237 result.AppendError (error.AsCString());
1238 result.SetStatus (eReturnStatusFailed);
1239 }
Greg Claytonde164aa2011-04-20 16:37:46 +00001240 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001241
Greg Claytonde164aa2011-04-20 16:37:46 +00001242 return result.Succeeded();
1243 }
1244
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001245 Error
Greg Clayton44d93782014-01-27 23:43:24 +00001246 AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
Greg Claytonde164aa2011-04-20 16:37:46 +00001247 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001248 Error error;
1249
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001250 if (!m_regex_cmd_ap)
Greg Claytonde164aa2011-04-20 16:37:46 +00001251 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001252 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
1253 (int)regex_sed.size(),
1254 regex_sed.data());
1255 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001256 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001257
1258 size_t regex_sed_size = regex_sed.size();
1259
1260 if (regex_sed_size <= 1)
1261 {
1262 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
1263 (int)regex_sed.size(),
1264 regex_sed.data());
1265 return error;
1266 }
1267
1268 if (regex_sed[0] != 's')
1269 {
1270 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
1271 (int)regex_sed.size(),
1272 regex_sed.data());
1273 return error;
1274 }
1275 const size_t first_separator_char_pos = 1;
1276 // use the char that follows 's' as the regex separator character
1277 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1278 const char separator_char = regex_sed[first_separator_char_pos];
1279 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1280
1281 if (second_separator_char_pos == std::string::npos)
1282 {
Greg Claytonea508632014-11-18 00:43:17 +00001283 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001284 separator_char,
1285 (int)(regex_sed.size() - first_separator_char_pos - 1),
Greg Claytonea508632014-11-18 00:43:17 +00001286 regex_sed.data() + (first_separator_char_pos + 1),
1287 (int)regex_sed.size(),
1288 regex_sed.data());
1289 return error;
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001290 }
1291
1292 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1293
1294 if (third_separator_char_pos == std::string::npos)
1295 {
Greg Claytonea508632014-11-18 00:43:17 +00001296 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001297 separator_char,
1298 (int)(regex_sed.size() - second_separator_char_pos - 1),
Greg Claytonea508632014-11-18 00:43:17 +00001299 regex_sed.data() + (second_separator_char_pos + 1),
1300 (int)regex_sed.size(),
1301 regex_sed.data());
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001302 return error;
1303 }
1304
1305 if (third_separator_char_pos != regex_sed_size - 1)
1306 {
1307 // Make sure that everything that follows the last regex
1308 // separator char
1309 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1310 {
1311 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1312 (int)third_separator_char_pos + 1,
1313 regex_sed.data(),
1314 (int)(regex_sed.size() - third_separator_char_pos - 1),
1315 regex_sed.data() + (third_separator_char_pos + 1));
1316 return error;
1317 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001318 }
1319 else if (first_separator_char_pos + 1 == second_separator_char_pos)
1320 {
1321 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1322 separator_char,
1323 separator_char,
1324 separator_char,
1325 (int)regex_sed.size(),
1326 regex_sed.data());
1327 return error;
1328 }
1329 else if (second_separator_char_pos + 1 == third_separator_char_pos)
1330 {
1331 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1332 separator_char,
1333 separator_char,
1334 separator_char,
1335 (int)regex_sed.size(),
1336 regex_sed.data());
1337 return error;
1338 }
Greg Clayton44d93782014-01-27 23:43:24 +00001339
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001340 if (!check_only)
Greg Clayton44d93782014-01-27 23:43:24 +00001341 {
1342 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1343 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1344 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1345 subst.c_str());
1346 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001347 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001348 }
1349
1350 void
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001351 AddRegexCommandToInterpreter()
Greg Claytonde164aa2011-04-20 16:37:46 +00001352 {
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001353 if (m_regex_cmd_ap)
Greg Claytonde164aa2011-04-20 16:37:46 +00001354 {
1355 if (m_regex_cmd_ap->HasRegexEntries())
1356 {
1357 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1358 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1359 }
1360 }
1361 }
1362
Greg Claytonde164aa2011-04-20 16:37:46 +00001363private:
Greg Clayton7b0992d2013-04-18 22:45:39 +00001364 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
Greg Claytonde164aa2011-04-20 16:37:46 +00001365
1366 class CommandOptions : public Options
1367 {
1368 public:
Greg Claytonde164aa2011-04-20 16:37:46 +00001369 CommandOptions (CommandInterpreter &interpreter) :
1370 Options (interpreter)
1371 {
1372 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001373
1374 ~CommandOptions() override = default;
1375
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001376 Error
1377 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Greg Claytonde164aa2011-04-20 16:37:46 +00001378 {
1379 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001380 const int short_option = m_getopt_table[option_idx].val;
Greg Claytonde164aa2011-04-20 16:37:46 +00001381
1382 switch (short_option)
1383 {
1384 case 'h':
1385 m_help.assign (option_arg);
1386 break;
1387 case 's':
1388 m_syntax.assign (option_arg);
1389 break;
Greg Claytonde164aa2011-04-20 16:37:46 +00001390 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001391 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytonde164aa2011-04-20 16:37:46 +00001392 break;
1393 }
1394
1395 return error;
1396 }
1397
1398 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001399 OptionParsingStarting () override
Greg Claytonde164aa2011-04-20 16:37:46 +00001400 {
1401 m_help.clear();
1402 m_syntax.clear();
1403 }
1404
1405 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001406 GetDefinitions () override
Greg Claytonde164aa2011-04-20 16:37:46 +00001407 {
1408 return g_option_table;
1409 }
1410
1411 // Options table: Required for subclasses of Options.
1412
1413 static OptionDefinition g_option_table[];
1414
1415 const char *
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001416 GetHelp()
Greg Claytonde164aa2011-04-20 16:37:46 +00001417 {
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001418 return (m_help.empty() ? nullptr : m_help.c_str());
Greg Claytonde164aa2011-04-20 16:37:46 +00001419 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001420
Greg Claytonde164aa2011-04-20 16:37:46 +00001421 const char *
1422 GetSyntax ()
1423 {
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001424 return (m_syntax.empty() ? nullptr : m_syntax.c_str());
Greg Claytonde164aa2011-04-20 16:37:46 +00001425 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001426
Greg Claytonde164aa2011-04-20 16:37:46 +00001427 protected:
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001428 // Instance variables to hold the values for command options.
1429
Greg Claytonde164aa2011-04-20 16:37:46 +00001430 std::string m_help;
1431 std::string m_syntax;
1432 };
Jim Ingham5a988412012-06-08 21:56:10 +00001433
Eric Christopherb0a18142014-11-18 22:40:27 +00001434 Options *
1435 GetOptions () override
Greg Claytonde164aa2011-04-20 16:37:46 +00001436 {
1437 return &m_options;
1438 }
Jim Ingham5a988412012-06-08 21:56:10 +00001439
1440 CommandOptions m_options;
Greg Claytonde164aa2011-04-20 16:37:46 +00001441};
1442
Greg Claytonde164aa2011-04-20 16:37:46 +00001443OptionDefinition
1444CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1445{
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001446{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."},
1447{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1448{ 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
Greg Claytonde164aa2011-04-20 16:37:46 +00001449};
1450
Jim Ingham5a988412012-06-08 21:56:10 +00001451class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata223383e2011-08-16 23:24:13 +00001452{
Enrico Granata223383e2011-08-16 23:24:13 +00001453public:
Enrico Granata223383e2011-08-16 23:24:13 +00001454 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1455 std::string name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001456 std::string funct,
Enrico Granata735152e2014-09-15 17:52:44 +00001457 std::string help,
Enrico Granata0a305db2011-11-07 22:57:04 +00001458 ScriptedCommandSynchronicity synch) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001459 CommandObjectRaw(interpreter,
1460 name.c_str(),
1461 nullptr,
1462 nullptr),
Jim Ingham5a988412012-06-08 21:56:10 +00001463 m_function_name(funct),
Enrico Granatafac939e2012-09-18 21:53:02 +00001464 m_synchro(synch),
1465 m_fetched_help_long(false)
Enrico Granata223383e2011-08-16 23:24:13 +00001466 {
Enrico Granata735152e2014-09-15 17:52:44 +00001467 if (!help.empty())
1468 SetHelp(help.c_str());
1469 else
1470 {
1471 StreamString stream;
1472 stream.Printf("For more information run 'help %s'",name.c_str());
1473 SetHelp(stream.GetData());
1474 }
Enrico Granata223383e2011-08-16 23:24:13 +00001475 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001476
1477 ~CommandObjectPythonFunction() override = default;
1478
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001479 bool
1480 IsRemovable () const override
Jim Ingham5a988412012-06-08 21:56:10 +00001481 {
1482 return true;
1483 }
1484
1485 const std::string&
1486 GetFunctionName ()
1487 {
1488 return m_function_name;
1489 }
1490
1491 ScriptedCommandSynchronicity
1492 GetSynchronicity ()
1493 {
1494 return m_synchro;
1495 }
1496
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001497 const char *
1498 GetHelpLong () override
Enrico Granatafac939e2012-09-18 21:53:02 +00001499 {
1500 if (!m_fetched_help_long)
1501 {
1502 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1503 if (scripter)
1504 {
1505 std::string docstring;
1506 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1507 if (!docstring.empty())
Enrico Granatabfb75e92016-03-22 22:12:59 +00001508 SetHelpLong(docstring.c_str());
Enrico Granatafac939e2012-09-18 21:53:02 +00001509 }
1510 }
1511 return CommandObjectRaw::GetHelpLong();
1512 }
1513
Jim Ingham5a988412012-06-08 21:56:10 +00001514protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001515 bool
1516 DoExecute (const char *raw_command_line, CommandReturnObject &result) override
Enrico Granata223383e2011-08-16 23:24:13 +00001517 {
1518 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1519
1520 Error error;
1521
Jim Ingham70f11f82012-06-27 17:25:36 +00001522 result.SetStatus(eReturnStatusInvalid);
1523
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001524 if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(),
1525 raw_command_line,
1526 m_synchro,
1527 result,
1528 error,
1529 m_exe_ctx))
Enrico Granata223383e2011-08-16 23:24:13 +00001530 {
1531 result.AppendError(error.AsCString());
1532 result.SetStatus(eReturnStatusFailed);
1533 }
1534 else
Jim Ingham70f11f82012-06-27 17:25:36 +00001535 {
1536 // Don't change the status if the command already set it...
1537 if (result.GetStatus() == eReturnStatusInvalid)
1538 {
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001539 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
Jim Ingham70f11f82012-06-27 17:25:36 +00001540 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1541 else
1542 result.SetStatus(eReturnStatusSuccessFinishResult);
1543 }
1544 }
Enrico Granata223383e2011-08-16 23:24:13 +00001545
1546 return result.Succeeded();
1547 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001548
1549private:
1550 std::string m_function_name;
1551 ScriptedCommandSynchronicity m_synchro;
1552 bool m_fetched_help_long;
Enrico Granata223383e2011-08-16 23:24:13 +00001553};
1554
Enrico Granata9fe00e52015-03-13 02:20:41 +00001555class CommandObjectScriptingObject : public CommandObjectRaw
1556{
Enrico Granata9fe00e52015-03-13 02:20:41 +00001557public:
Enrico Granata9fe00e52015-03-13 02:20:41 +00001558 CommandObjectScriptingObject (CommandInterpreter &interpreter,
1559 std::string name,
Zachary Turner0641ca12015-03-17 20:04:04 +00001560 StructuredData::GenericSP cmd_obj_sp,
Enrico Granata9fe00e52015-03-13 02:20:41 +00001561 ScriptedCommandSynchronicity synch) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001562 CommandObjectRaw(interpreter,
1563 name.c_str(),
1564 nullptr,
1565 nullptr),
1566 m_cmd_obj_sp(cmd_obj_sp),
1567 m_synchro(synch),
1568 m_fetched_help_short(false),
1569 m_fetched_help_long(false)
Enrico Granata9fe00e52015-03-13 02:20:41 +00001570 {
1571 StreamString stream;
1572 stream.Printf("For more information run 'help %s'",name.c_str());
1573 SetHelp(stream.GetData());
Enrico Granatae87764f2015-05-27 05:04:35 +00001574 if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1575 GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
Enrico Granata9fe00e52015-03-13 02:20:41 +00001576 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001577
1578 ~CommandObjectScriptingObject() override = default;
1579
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001580 bool
1581 IsRemovable () const override
Enrico Granata9fe00e52015-03-13 02:20:41 +00001582 {
1583 return true;
1584 }
1585
Zachary Turner0641ca12015-03-17 20:04:04 +00001586 StructuredData::GenericSP
Enrico Granata9fe00e52015-03-13 02:20:41 +00001587 GetImplementingObject ()
1588 {
1589 return m_cmd_obj_sp;
1590 }
1591
1592 ScriptedCommandSynchronicity
1593 GetSynchronicity ()
1594 {
1595 return m_synchro;
1596 }
Enrico Granata6f79bb22015-03-13 22:22:28 +00001597
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001598 const char *
1599 GetHelp () override
Enrico Granata6f79bb22015-03-13 22:22:28 +00001600 {
1601 if (!m_fetched_help_short)
1602 {
1603 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1604 if (scripter)
1605 {
1606 std::string docstring;
1607 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
1608 if (!docstring.empty())
Enrico Granatabfb75e92016-03-22 22:12:59 +00001609 SetHelp(docstring.c_str());
Enrico Granata6f79bb22015-03-13 22:22:28 +00001610 }
1611 }
1612 return CommandObjectRaw::GetHelp();
1613 }
Enrico Granata9fe00e52015-03-13 02:20:41 +00001614
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001615 const char *
1616 GetHelpLong () override
Enrico Granata9fe00e52015-03-13 02:20:41 +00001617 {
Enrico Granata6f79bb22015-03-13 22:22:28 +00001618 if (!m_fetched_help_long)
1619 {
1620 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1621 if (scripter)
1622 {
1623 std::string docstring;
1624 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
1625 if (!docstring.empty())
Enrico Granatabfb75e92016-03-22 22:12:59 +00001626 SetHelpLong(docstring.c_str());
Enrico Granata6f79bb22015-03-13 22:22:28 +00001627 }
1628 }
Enrico Granata9fe00e52015-03-13 02:20:41 +00001629 return CommandObjectRaw::GetHelpLong();
1630 }
1631
1632protected:
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001633 bool
1634 DoExecute (const char *raw_command_line, CommandReturnObject &result) override
Enrico Granata9fe00e52015-03-13 02:20:41 +00001635 {
1636 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1637
1638 Error error;
1639
1640 result.SetStatus(eReturnStatusInvalid);
1641
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001642 if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp,
1643 raw_command_line,
1644 m_synchro,
1645 result,
1646 error,
1647 m_exe_ctx))
Enrico Granata9fe00e52015-03-13 02:20:41 +00001648 {
1649 result.AppendError(error.AsCString());
1650 result.SetStatus(eReturnStatusFailed);
1651 }
1652 else
1653 {
1654 // Don't change the status if the command already set it...
1655 if (result.GetStatus() == eReturnStatusInvalid)
1656 {
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001657 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
Enrico Granata9fe00e52015-03-13 02:20:41 +00001658 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1659 else
1660 result.SetStatus(eReturnStatusSuccessFinishResult);
1661 }
1662 }
1663
1664 return result.Succeeded();
1665 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001666
1667private:
1668 StructuredData::GenericSP m_cmd_obj_sp;
1669 ScriptedCommandSynchronicity m_synchro;
1670 bool m_fetched_help_short: 1;
1671 bool m_fetched_help_long: 1;
Enrico Granata9fe00e52015-03-13 02:20:41 +00001672};
1673
Enrico Granataa9dbf432011-10-17 21:45:27 +00001674//-------------------------------------------------------------------------
1675// CommandObjectCommandsScriptImport
1676//-------------------------------------------------------------------------
1677
Jim Ingham5a988412012-06-08 21:56:10 +00001678class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granataa9dbf432011-10-17 21:45:27 +00001679{
Jim Ingham5a988412012-06-08 21:56:10 +00001680public:
1681 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001682 CommandObjectParsed(interpreter,
1683 "command script import",
1684 "Import a scripting module in LLDB.",
1685 nullptr),
Jim Ingham5a988412012-06-08 21:56:10 +00001686 m_options(interpreter)
1687 {
1688 CommandArgumentEntry arg1;
1689 CommandArgumentData cmd_arg;
1690
1691 // Define the first (and only) variant of this arg.
1692 cmd_arg.arg_type = eArgTypeFilename;
Enrico Granata3b00e352015-06-16 18:31:04 +00001693 cmd_arg.arg_repetition = eArgRepeatPlus;
Jim Ingham5a988412012-06-08 21:56:10 +00001694
1695 // There is only one variant this argument could be; put it into the argument entry.
1696 arg1.push_back (cmd_arg);
1697
1698 // Push the data for the first argument into the m_arguments vector.
1699 m_arguments.push_back (arg1);
1700 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001701
1702 ~CommandObjectCommandsScriptImport() override = default;
1703
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001704 int
Jim Ingham5a988412012-06-08 21:56:10 +00001705 HandleArgumentCompletion (Args &input,
1706 int &cursor_index,
1707 int &cursor_char_position,
1708 OptionElementVector &opt_element_vector,
1709 int match_start_point,
1710 int max_return_elements,
1711 bool &word_complete,
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001712 StringList &matches) override
Jim Ingham5a988412012-06-08 21:56:10 +00001713 {
1714 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1715 completion_str.erase (cursor_char_position);
1716
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001717 CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
1718 CommandCompletions::eDiskFileCompletion,
1719 completion_str.c_str(),
1720 match_start_point,
1721 max_return_elements,
1722 nullptr,
1723 word_complete,
1724 matches);
Jim Ingham5a988412012-06-08 21:56:10 +00001725 return matches.GetSize();
1726 }
1727
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001728 Options *
1729 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001730 {
1731 return &m_options;
1732 }
1733
1734protected:
Enrico Granata0a305db2011-11-07 22:57:04 +00001735 class CommandOptions : public Options
1736 {
1737 public:
Enrico Granata0a305db2011-11-07 22:57:04 +00001738 CommandOptions (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001739 Options (interpreter)
Enrico Granata0a305db2011-11-07 22:57:04 +00001740 {
1741 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001742
1743 ~CommandOptions() override = default;
1744
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001745 Error
1746 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Enrico Granata0a305db2011-11-07 22:57:04 +00001747 {
1748 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001749 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata0a305db2011-11-07 22:57:04 +00001750
1751 switch (short_option)
1752 {
1753 case 'r':
1754 m_allow_reload = true;
1755 break;
1756 default:
1757 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1758 break;
1759 }
1760
1761 return error;
1762 }
1763
1764 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001765 OptionParsingStarting () override
Enrico Granata0a305db2011-11-07 22:57:04 +00001766 {
Enrico Granatae0c70f12013-05-31 01:03:09 +00001767 m_allow_reload = true;
Enrico Granata0a305db2011-11-07 22:57:04 +00001768 }
1769
1770 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001771 GetDefinitions () override
Enrico Granata0a305db2011-11-07 22:57:04 +00001772 {
1773 return g_option_table;
1774 }
1775
1776 // Options table: Required for subclasses of Options.
1777
1778 static OptionDefinition g_option_table[];
1779
1780 // Instance variables to hold the values for command options.
1781
1782 bool m_allow_reload;
1783 };
Enrico Granata0a305db2011-11-07 22:57:04 +00001784
Enrico Granataa9dbf432011-10-17 21:45:27 +00001785 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001786 DoExecute (Args& command, CommandReturnObject &result) override
Enrico Granataa9dbf432011-10-17 21:45:27 +00001787 {
Enrico Granataa9dbf432011-10-17 21:45:27 +00001788 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1789 {
1790 result.AppendError ("only scripting language supported for module importing is currently Python");
1791 result.SetStatus (eReturnStatusFailed);
1792 return false;
1793 }
1794
Jim Ingham5a988412012-06-08 21:56:10 +00001795 size_t argc = command.GetArgumentCount();
Enrico Granata3b00e352015-06-16 18:31:04 +00001796 if (0 == argc)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001797 {
Enrico Granata3b00e352015-06-16 18:31:04 +00001798 result.AppendError("command script import needs one or more arguments");
Enrico Granataa9dbf432011-10-17 21:45:27 +00001799 result.SetStatus (eReturnStatusFailed);
1800 return false;
1801 }
1802
Ed Maste0e978482015-06-17 17:29:56 +00001803 for (size_t i = 0;
Enrico Granata3b00e352015-06-16 18:31:04 +00001804 i < argc;
1805 i++)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001806 {
Enrico Granata3b00e352015-06-16 18:31:04 +00001807 std::string path = command.GetArgumentAtIndex(i);
1808 Error error;
1809
1810 const bool init_session = true;
1811 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1812 // commands won't ever be recursively invoked, but it's actually possible to craft
1813 // a Python script that does other "command script imports" in __lldb_init_module
1814 // the real fix is to have recursive commands possible with a CommandInvocation object
1815 // separate from the CommandObject itself, so that recursive command invocations
1816 // won't stomp on each other (wrt to execution contents, options, and more)
1817 m_exe_ctx.Clear();
1818 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
1819 m_options.m_allow_reload,
1820 init_session,
1821 error))
1822 {
1823 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1824 }
1825 else
1826 {
1827 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1828 result.SetStatus (eReturnStatusFailed);
1829 }
Enrico Granataa9dbf432011-10-17 21:45:27 +00001830 }
1831
1832 return result.Succeeded();
1833 }
Enrico Granata0a305db2011-11-07 22:57:04 +00001834
Jim Ingham5a988412012-06-08 21:56:10 +00001835 CommandOptions m_options;
Enrico Granataa9dbf432011-10-17 21:45:27 +00001836};
Enrico Granata223383e2011-08-16 23:24:13 +00001837
Enrico Granata0a305db2011-11-07 22:57:04 +00001838OptionDefinition
1839CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1840{
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001841 { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."},
1842 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Enrico Granata0a305db2011-11-07 22:57:04 +00001843};
1844
Enrico Granata223383e2011-08-16 23:24:13 +00001845//-------------------------------------------------------------------------
1846// CommandObjectCommandsScriptAdd
1847//-------------------------------------------------------------------------
1848
Greg Clayton44d93782014-01-27 23:43:24 +00001849class CommandObjectCommandsScriptAdd :
1850 public CommandObjectParsed,
1851 public IOHandlerDelegateMultiline
Enrico Granata223383e2011-08-16 23:24:13 +00001852{
Jim Ingham5a988412012-06-08 21:56:10 +00001853public:
1854 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001855 CommandObjectParsed(interpreter,
1856 "command script add",
1857 "Add a scripted function as an LLDB command.",
1858 nullptr),
Greg Claytonc3d874a2014-05-08 16:59:00 +00001859 IOHandlerDelegateMultiline ("DONE"),
Jim Ingham5a988412012-06-08 21:56:10 +00001860 m_options (interpreter)
1861 {
1862 CommandArgumentEntry arg1;
1863 CommandArgumentData cmd_arg;
1864
1865 // Define the first (and only) variant of this arg.
1866 cmd_arg.arg_type = eArgTypeCommandName;
1867 cmd_arg.arg_repetition = eArgRepeatPlain;
1868
1869 // There is only one variant this argument could be; put it into the argument entry.
1870 arg1.push_back (cmd_arg);
1871
1872 // Push the data for the first argument into the m_arguments vector.
1873 m_arguments.push_back (arg1);
1874 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001875
1876 ~CommandObjectCommandsScriptAdd() override = default;
1877
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001878 Options *
1879 GetOptions () override
Jim Ingham5a988412012-06-08 21:56:10 +00001880 {
1881 return &m_options;
1882 }
1883
1884protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001885 class CommandOptions : public Options
1886 {
1887 public:
Enrico Granata223383e2011-08-16 23:24:13 +00001888 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata9fe00e52015-03-13 02:20:41 +00001889 Options (interpreter),
1890 m_class_name(),
1891 m_funct_name(),
1892 m_short_help(),
1893 m_synchronicity(eScriptedCommandSynchronicitySynchronous)
Enrico Granata223383e2011-08-16 23:24:13 +00001894 {
1895 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00001896
1897 ~CommandOptions() override = default;
1898
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001899 Error
1900 SetOptionValue (uint32_t option_idx, const char *option_arg) override
Enrico Granata223383e2011-08-16 23:24:13 +00001901 {
1902 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001903 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata223383e2011-08-16 23:24:13 +00001904
1905 switch (short_option)
1906 {
1907 case 'f':
Enrico Granata735152e2014-09-15 17:52:44 +00001908 if (option_arg)
1909 m_funct_name.assign(option_arg);
1910 break;
Enrico Granata9fe00e52015-03-13 02:20:41 +00001911 case 'c':
1912 if (option_arg)
1913 m_class_name.assign(option_arg);
1914 break;
Enrico Granata735152e2014-09-15 17:52:44 +00001915 case 'h':
1916 if (option_arg)
1917 m_short_help.assign(option_arg);
Enrico Granata223383e2011-08-16 23:24:13 +00001918 break;
Enrico Granata0a305db2011-11-07 22:57:04 +00001919 case 's':
Greg Clayton44d93782014-01-27 23:43:24 +00001920 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
Enrico Granata0a305db2011-11-07 22:57:04 +00001921 if (!error.Success())
1922 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1923 break;
Enrico Granata223383e2011-08-16 23:24:13 +00001924 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001925 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata223383e2011-08-16 23:24:13 +00001926 break;
1927 }
1928
1929 return error;
1930 }
1931
1932 void
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001933 OptionParsingStarting () override
Enrico Granata223383e2011-08-16 23:24:13 +00001934 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001935 m_class_name.clear();
Enrico Granata735152e2014-09-15 17:52:44 +00001936 m_funct_name.clear();
1937 m_short_help.clear();
Greg Clayton44d93782014-01-27 23:43:24 +00001938 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001939 }
1940
1941 const OptionDefinition*
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001942 GetDefinitions () override
Enrico Granata223383e2011-08-16 23:24:13 +00001943 {
1944 return g_option_table;
1945 }
1946
1947 // Options table: Required for subclasses of Options.
1948
1949 static OptionDefinition g_option_table[];
1950
1951 // Instance variables to hold the values for command options.
1952
Enrico Granata9fe00e52015-03-13 02:20:41 +00001953 std::string m_class_name;
Enrico Granata223383e2011-08-16 23:24:13 +00001954 std::string m_funct_name;
Enrico Granata735152e2014-09-15 17:52:44 +00001955 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00001956 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001957 };
Jim Ingham5a988412012-06-08 21:56:10 +00001958
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001959 void
1960 IOHandlerActivated (IOHandler &io_handler) override
Enrico Granata223383e2011-08-16 23:24:13 +00001961 {
Greg Clayton44d93782014-01-27 23:43:24 +00001962 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1963 if (output_sp)
Enrico Granata223383e2011-08-16 23:24:13 +00001964 {
Greg Clayton44d93782014-01-27 23:43:24 +00001965 output_sp->PutCString(g_python_command_instructions);
1966 output_sp->Flush();
Enrico Granata223383e2011-08-16 23:24:13 +00001967 }
Greg Clayton44d93782014-01-27 23:43:24 +00001968 }
Enrico Granata223383e2011-08-16 23:24:13 +00001969
Greg Clayton44d93782014-01-27 23:43:24 +00001970
Bruce Mitchener13d21e92015-10-07 16:56:17 +00001971 void
1972 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
Greg Clayton44d93782014-01-27 23:43:24 +00001973 {
1974 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1975
1976 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1977 if (interpreter)
1978 {
1979
1980 StringList lines;
1981 lines.SplitIntoLines(data);
1982 if (lines.GetSize() > 0)
1983 {
1984 std::string funct_name_str;
1985 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1986 {
1987 if (funct_name_str.empty())
1988 {
1989 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1990 error_sp->Flush();
1991 }
1992 else
1993 {
1994 // everything should be fine now, let's add this alias
1995
1996 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1997 m_cmd_name,
1998 funct_name_str.c_str(),
Enrico Granata735152e2014-09-15 17:52:44 +00001999 m_short_help,
Greg Clayton44d93782014-01-27 23:43:24 +00002000 m_synchronicity));
2001
2002 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
2003 {
2004 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
2005 error_sp->Flush();
2006 }
2007 }
2008 }
2009 else
2010 {
2011 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
2012 error_sp->Flush();
2013 }
2014 }
2015 else
2016 {
2017 error_sp->Printf ("error: empty function, didn't add python command.\n");
2018 error_sp->Flush();
2019 }
2020 }
2021 else
2022 {
2023 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
2024 error_sp->Flush();
2025 }
2026
2027 io_handler.SetIsDone(true);
Greg Clayton44d93782014-01-27 23:43:24 +00002028 }
2029
Jim Ingham5a988412012-06-08 21:56:10 +00002030protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002031 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002032 DoExecute (Args& command, CommandReturnObject &result) override
Enrico Granata223383e2011-08-16 23:24:13 +00002033 {
Enrico Granata99f0b8f2011-08-17 01:30:04 +00002034 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
2035 {
2036 result.AppendError ("only scripting language supported for scripted commands is currently Python");
2037 result.SetStatus (eReturnStatusFailed);
2038 return false;
2039 }
2040
Jim Ingham5a988412012-06-08 21:56:10 +00002041 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00002042
2043 if (argc != 1)
2044 {
2045 result.AppendError ("'command script add' requires one argument");
2046 result.SetStatus (eReturnStatusFailed);
2047 return false;
2048 }
2049
Enrico Granata735152e2014-09-15 17:52:44 +00002050 // Store the options in case we get multi-line input
Greg Clayton44d93782014-01-27 23:43:24 +00002051 m_cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata735152e2014-09-15 17:52:44 +00002052 m_short_help.assign(m_options.m_short_help);
Greg Clayton44d93782014-01-27 23:43:24 +00002053 m_synchronicity = m_options.m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00002054
Enrico Granata9fe00e52015-03-13 02:20:41 +00002055 if (m_options.m_class_name.empty())
Enrico Granata223383e2011-08-16 23:24:13 +00002056 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00002057 if (m_options.m_funct_name.empty())
2058 {
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002059 m_interpreter.GetPythonCommandsFromIOHandler(" ", // Prompt
2060 *this, // IOHandlerDelegate
2061 true, // Run IOHandler in async mode
2062 nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
Enrico Granata9fe00e52015-03-13 02:20:41 +00002063 }
2064 else
2065 {
2066 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
2067 m_cmd_name,
2068 m_options.m_funct_name,
2069 m_options.m_short_help,
2070 m_synchronicity));
2071 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
2072 {
2073 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2074 }
2075 else
2076 {
2077 result.AppendError("cannot add command");
2078 result.SetStatus (eReturnStatusFailed);
2079 }
2080 }
Enrico Granata223383e2011-08-16 23:24:13 +00002081 }
2082 else
2083 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00002084 ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
2085 if (!interpreter)
2086 {
2087 result.AppendError("cannot find ScriptInterpreter");
2088 result.SetStatus(eReturnStatusFailed);
2089 return false;
2090 }
2091
2092 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
2093 if (!cmd_obj_sp)
2094 {
2095 result.AppendError("cannot create helper object");
2096 result.SetStatus(eReturnStatusFailed);
2097 return false;
2098 }
2099
2100 CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
2101 m_cmd_name,
2102 cmd_obj_sp,
2103 m_synchronicity));
Greg Clayton44d93782014-01-27 23:43:24 +00002104 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
Enrico Granata223383e2011-08-16 23:24:13 +00002105 {
2106 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2107 }
2108 else
2109 {
2110 result.AppendError("cannot add command");
2111 result.SetStatus (eReturnStatusFailed);
2112 }
2113 }
2114
2115 return result.Succeeded();
Enrico Granata223383e2011-08-16 23:24:13 +00002116 }
Jim Ingham5a988412012-06-08 21:56:10 +00002117
2118 CommandOptions m_options;
Greg Clayton44d93782014-01-27 23:43:24 +00002119 std::string m_cmd_name;
Enrico Granata735152e2014-09-15 17:52:44 +00002120 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00002121 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00002122};
2123
Enrico Granata0a305db2011-11-07 22:57:04 +00002124static OptionEnumValueElement g_script_synchro_type[] =
2125{
2126 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
2127 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
2128 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002129 { 0, nullptr, nullptr }
Enrico Granata0a305db2011-11-07 22:57:04 +00002130};
2131
Enrico Granata223383e2011-08-16 23:24:13 +00002132OptionDefinition
2133CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2134{
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002135 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
2136 { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."},
2137 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."},
2138 { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
2139 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Enrico Granata223383e2011-08-16 23:24:13 +00002140};
2141
2142//-------------------------------------------------------------------------
2143// CommandObjectCommandsScriptList
2144//-------------------------------------------------------------------------
2145
Jim Ingham5a988412012-06-08 21:56:10 +00002146class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002147{
Enrico Granata223383e2011-08-16 23:24:13 +00002148public:
2149 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002150 CommandObjectParsed(interpreter,
2151 "command script list",
2152 "List defined scripted commands.",
2153 nullptr)
Enrico Granata223383e2011-08-16 23:24:13 +00002154 {
2155 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002156
2157 ~CommandObjectCommandsScriptList() override = default;
2158
Enrico Granata223383e2011-08-16 23:24:13 +00002159 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002160 DoExecute (Args& command, CommandReturnObject &result) override
Enrico Granata223383e2011-08-16 23:24:13 +00002161 {
Enrico Granata223383e2011-08-16 23:24:13 +00002162 m_interpreter.GetHelp(result,
2163 CommandInterpreter::eCommandTypesUserDef);
2164
2165 result.SetStatus (eReturnStatusSuccessFinishResult);
2166
2167 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00002168 }
2169};
2170
2171//-------------------------------------------------------------------------
2172// CommandObjectCommandsScriptClear
2173//-------------------------------------------------------------------------
2174
Jim Ingham5a988412012-06-08 21:56:10 +00002175class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002176{
Enrico Granata223383e2011-08-16 23:24:13 +00002177public:
2178 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002179 CommandObjectParsed(interpreter,
2180 "command script clear",
2181 "Delete all scripted commands.",
2182 nullptr)
Enrico Granata223383e2011-08-16 23:24:13 +00002183 {
2184 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002185
2186 ~CommandObjectCommandsScriptClear() override = default;
2187
Jim Ingham5a988412012-06-08 21:56:10 +00002188protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002189 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002190 DoExecute (Args& command, CommandReturnObject &result) override
Enrico Granata223383e2011-08-16 23:24:13 +00002191 {
Enrico Granata223383e2011-08-16 23:24:13 +00002192 m_interpreter.RemoveAllUser();
2193
2194 result.SetStatus (eReturnStatusSuccessFinishResult);
2195
2196 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00002197 }
2198};
2199
2200//-------------------------------------------------------------------------
2201// CommandObjectCommandsScriptDelete
2202//-------------------------------------------------------------------------
2203
Jim Ingham5a988412012-06-08 21:56:10 +00002204class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002205{
Enrico Granata223383e2011-08-16 23:24:13 +00002206public:
2207 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002208 CommandObjectParsed(interpreter,
2209 "command script delete",
2210 "Delete a scripted command.",
2211 nullptr)
Enrico Granata223383e2011-08-16 23:24:13 +00002212 {
2213 CommandArgumentEntry arg1;
2214 CommandArgumentData cmd_arg;
2215
2216 // Define the first (and only) variant of this arg.
2217 cmd_arg.arg_type = eArgTypeCommandName;
2218 cmd_arg.arg_repetition = eArgRepeatPlain;
2219
2220 // There is only one variant this argument could be; put it into the argument entry.
2221 arg1.push_back (cmd_arg);
2222
2223 // Push the data for the first argument into the m_arguments vector.
2224 m_arguments.push_back (arg1);
2225 }
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002226
2227 ~CommandObjectCommandsScriptDelete() override = default;
2228
Jim Ingham5a988412012-06-08 21:56:10 +00002229protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002230 bool
Bruce Mitchener13d21e92015-10-07 16:56:17 +00002231 DoExecute (Args& command, CommandReturnObject &result) override
Enrico Granata223383e2011-08-16 23:24:13 +00002232 {
2233
Jim Ingham5a988412012-06-08 21:56:10 +00002234 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00002235
2236 if (argc != 1)
2237 {
2238 result.AppendError ("'command script delete' requires one argument");
2239 result.SetStatus (eReturnStatusFailed);
2240 return false;
2241 }
2242
Jim Ingham5a988412012-06-08 21:56:10 +00002243 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00002244
2245 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2246 {
2247 m_interpreter.RemoveUser(cmd_name);
2248 result.SetStatus (eReturnStatusSuccessFinishResult);
2249 }
2250 else
2251 {
2252 result.AppendErrorWithFormat ("command %s not found", cmd_name);
2253 result.SetStatus (eReturnStatusFailed);
2254 }
2255
2256 return result.Succeeded();
Enrico Granata223383e2011-08-16 23:24:13 +00002257 }
2258};
2259
2260#pragma mark CommandObjectMultiwordCommandsScript
2261
2262//-------------------------------------------------------------------------
2263// CommandObjectMultiwordCommandsScript
2264//-------------------------------------------------------------------------
2265
2266class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2267{
2268public:
2269 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2270 CommandObjectMultiword (interpreter,
2271 "command script",
2272 "A set of commands for managing or customizing script commands.",
2273 "command script <subcommand> [<subcommand-options>]")
2274 {
Greg Claytonb5472782015-01-09 19:08:20 +00002275 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2276 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2277 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002278 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002279 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002280 }
2281
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002282 ~CommandObjectMultiwordCommandsScript() override = default;
Enrico Granata223383e2011-08-16 23:24:13 +00002283};
2284
Jim Inghamebc09c32010-07-07 03:36:20 +00002285#pragma mark CommandObjectMultiwordCommands
2286
2287//-------------------------------------------------------------------------
2288// CommandObjectMultiwordCommands
2289//-------------------------------------------------------------------------
2290
2291CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002292 CommandObjectMultiword (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002293 "command",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002294 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002295 "command <subcommand> [<subcommand-options>]")
Jim Inghamebc09c32010-07-07 03:36:20 +00002296{
Greg Claytona7015092010-09-18 01:14:36 +00002297 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2298 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2299 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002300 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
Greg Claytonde164aa2011-04-20 16:37:46 +00002301 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002302 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2303 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Inghamebc09c32010-07-07 03:36:20 +00002304}
2305
Eugene Zelenko6e3d8e72016-02-22 23:46:47 +00002306CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default;