blob: 0740329069fa8d464e6cab340b56abd86d651808 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Jim Inghamebc09c32010-07-07 03:36:20 +000012#include "CommandObjectCommands.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
Greg Clayton0e5e5a72011-04-20 22:55:21 +000017#include "llvm/ADT/StringRef.h"
18
Jim Inghamebc09c32010-07-07 03:36:20 +000019// Project includes
Jim Inghamebc09c32010-07-07 03:36:20 +000020#include "lldb/Core/Debugger.h"
Greg Clayton44d93782014-01-27 23:43:24 +000021#include "lldb/Core/IOHandler.h"
Enrico Granatabe93a352011-08-16 16:49:25 +000022#include "lldb/Core/StringList.h"
Greg Claytonde164aa2011-04-20 16:37:46 +000023#include "lldb/Interpreter/Args.h"
Enrico Granata7594f142013-06-17 22:51:50 +000024#include "lldb/Interpreter/CommandHistory.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000025#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytonde164aa2011-04-20 16:37:46 +000026#include "lldb/Interpreter/CommandObjectRegexCommand.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000027#include "lldb/Interpreter/CommandReturnObject.h"
Enrico Granata012d4fc2013-06-11 01:26:35 +000028#include "lldb/Interpreter/OptionValueBoolean.h"
Enrico Granata7594f142013-06-17 22:51:50 +000029#include "lldb/Interpreter/OptionValueUInt64.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000030#include "lldb/Interpreter/Options.h"
Enrico Granata99f0b8f2011-08-17 01:30:04 +000031#include "lldb/Interpreter/ScriptInterpreter.h"
32#include "lldb/Interpreter/ScriptInterpreterPython.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000033
34using namespace lldb;
35using namespace lldb_private;
36
Jim Inghamebc09c32010-07-07 03:36:20 +000037//-------------------------------------------------------------------------
38// CommandObjectCommandsSource
39//-------------------------------------------------------------------------
40
Jim Ingham5a988412012-06-08 21:56:10 +000041class CommandObjectCommandsHistory : public CommandObjectParsed
Jim Inghama5a97eb2011-07-12 03:12:18 +000042{
Jim Ingham5a988412012-06-08 21:56:10 +000043public:
44 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
45 CommandObjectParsed (interpreter,
46 "command history",
47 "Dump the history of commands in this session.",
48 NULL),
49 m_options (interpreter)
50 {
51 }
52
53 ~CommandObjectCommandsHistory () {}
54
55 virtual Options *
56 GetOptions ()
57 {
58 return &m_options;
59 }
60
61protected:
Jim Inghama5a97eb2011-07-12 03:12:18 +000062
63 class CommandOptions : public Options
64 {
65 public:
66
67 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata7594f142013-06-17 22:51:50 +000068 Options (interpreter),
69 m_start_idx(0),
70 m_stop_idx(0),
71 m_count(0),
Enrico Granata63123b62013-06-17 23:28:27 +000072 m_clear(false)
Jim Inghama5a97eb2011-07-12 03:12:18 +000073 {
74 }
75
76 virtual
77 ~CommandOptions (){}
78
79 virtual Error
80 SetOptionValue (uint32_t option_idx, const char *option_arg)
81 {
82 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000083 const int short_option = m_getopt_table[option_idx].val;
Jim Inghama5a97eb2011-07-12 03:12:18 +000084
85 switch (short_option)
86 {
87 case 'c':
Pavel Labathc95f7e22015-02-20 11:14:59 +000088 error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
Jim Inghama5a97eb2011-07-12 03:12:18 +000089 break;
90 case 's':
Enrico Granata7594f142013-06-17 22:51:50 +000091 if (option_arg && strcmp("end", option_arg) == 0)
92 {
93 m_start_idx.SetCurrentValue(UINT64_MAX);
94 m_start_idx.SetOptionWasSet();
95 }
96 else
Pavel Labathc95f7e22015-02-20 11:14:59 +000097 error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
Enrico Granata7594f142013-06-17 22:51:50 +000098 break;
99 case 'e':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000100 error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
Enrico Granata7594f142013-06-17 22:51:50 +0000101 break;
Enrico Granata63123b62013-06-17 23:28:27 +0000102 case 'C':
103 m_clear.SetCurrentValue(true);
104 m_clear.SetOptionWasSet();
Jim Inghama5a97eb2011-07-12 03:12:18 +0000105 break;
106 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000107 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghama5a97eb2011-07-12 03:12:18 +0000108 break;
109 }
110
111 return error;
112 }
113
114 void
115 OptionParsingStarting ()
116 {
Enrico Granata7594f142013-06-17 22:51:50 +0000117 m_start_idx.Clear();
118 m_stop_idx.Clear();
119 m_count.Clear();
Enrico Granata63123b62013-06-17 23:28:27 +0000120 m_clear.Clear();
Jim Inghama5a97eb2011-07-12 03:12:18 +0000121 }
122
123 const OptionDefinition*
124 GetDefinitions ()
125 {
126 return g_option_table;
127 }
128
129 // Options table: Required for subclasses of Options.
130
131 static OptionDefinition g_option_table[];
132
133 // Instance variables to hold the values for command options.
134
Enrico Granata7594f142013-06-17 22:51:50 +0000135 OptionValueUInt64 m_start_idx;
136 OptionValueUInt64 m_stop_idx;
137 OptionValueUInt64 m_count;
Enrico Granata63123b62013-06-17 23:28:27 +0000138 OptionValueBoolean m_clear;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000139 };
140
Jim Inghama5a97eb2011-07-12 03:12:18 +0000141 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000142 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghama5a97eb2011-07-12 03:12:18 +0000143 {
Enrico Granata63123b62013-06-17 23:28:27 +0000144 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
Enrico Granata7594f142013-06-17 22:51:50 +0000145 {
146 m_interpreter.GetCommandHistory().Clear();
147 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
148 }
149 else
150 {
151 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
152 {
153 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
154 result.SetStatus(lldb::eReturnStatusFailed);
155 }
156 else
157 {
Virgile Bello84400ec2013-08-27 16:22:29 +0000158 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
159 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
160 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
Enrico Granata7594f142013-06-17 22:51:50 +0000161
162 const CommandHistory& history(m_interpreter.GetCommandHistory());
163
164 if (start_idx.first && start_idx.second == UINT64_MAX)
165 {
166 if (count.first)
167 {
168 start_idx.second = history.GetSize() - count.second;
169 stop_idx.second = history.GetSize() - 1;
170 }
171 else if (stop_idx.first)
172 {
173 start_idx.second = stop_idx.second;
174 stop_idx.second = history.GetSize() - 1;
175 }
176 else
177 {
178 start_idx.second = 0;
179 stop_idx.second = history.GetSize() - 1;
180 }
181 }
182 else
183 {
184 if (!start_idx.first && !stop_idx.first && !count.first)
185 {
186 start_idx.second = 0;
187 stop_idx.second = history.GetSize() - 1;
188 }
189 else if (start_idx.first)
190 {
191 if (count.first)
192 {
193 stop_idx.second = start_idx.second + count.second - 1;
194 }
195 else if (!stop_idx.first)
196 {
197 stop_idx.second = history.GetSize() - 1;
198 }
199 }
200 else if (stop_idx.first)
201 {
202 if (count.first)
203 {
204 if (stop_idx.second >= count.second)
205 start_idx.second = stop_idx.second - count.second + 1;
206 else
207 start_idx.second = 0;
208 }
209 }
210 else /* if (count.first) */
211 {
212 start_idx.second = 0;
213 stop_idx.second = count.second - 1;
214 }
215 }
216 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
217 }
218 }
Jim Inghama5a97eb2011-07-12 03:12:18 +0000219 return result.Succeeded();
220
221 }
Jim Ingham5a988412012-06-08 21:56:10 +0000222
223 CommandOptions m_options;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000224};
225
226OptionDefinition
227CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
228{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000229{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
230{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
231{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
232{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean, "Clears the current command history."},
233{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Inghama5a97eb2011-07-12 03:12:18 +0000234};
235
236
237//-------------------------------------------------------------------------
238// CommandObjectCommandsSource
239//-------------------------------------------------------------------------
240
Jim Ingham5a988412012-06-08 21:56:10 +0000241class CommandObjectCommandsSource : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000242{
Jim Ingham5a988412012-06-08 21:56:10 +0000243public:
244 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
245 CommandObjectParsed (interpreter,
246 "command source",
247 "Read in debugger commands from the file <filename> and execute them.",
248 NULL),
249 m_options (interpreter)
250 {
251 CommandArgumentEntry arg;
252 CommandArgumentData file_arg;
253
254 // Define the first (and only) variant of this arg.
255 file_arg.arg_type = eArgTypeFilename;
256 file_arg.arg_repetition = eArgRepeatPlain;
257
258 // There is only one variant this argument could be; put it into the argument entry.
259 arg.push_back (file_arg);
260
261 // Push the data for the first argument into the m_arguments vector.
262 m_arguments.push_back (arg);
263 }
264
265 ~CommandObjectCommandsSource () {}
266
267 virtual const char*
268 GetRepeatCommand (Args &current_command_args, uint32_t index)
269 {
270 return "";
271 }
272
Greg Claytonc7bece562013-01-25 18:06:21 +0000273 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +0000274 HandleArgumentCompletion (Args &input,
275 int &cursor_index,
276 int &cursor_char_position,
277 OptionElementVector &opt_element_vector,
278 int match_start_point,
279 int max_return_elements,
280 bool &word_complete,
281 StringList &matches)
282 {
283 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
284 completion_str.erase (cursor_char_position);
285
286 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
287 CommandCompletions::eDiskFileCompletion,
288 completion_str.c_str(),
289 match_start_point,
290 max_return_elements,
291 NULL,
292 word_complete,
293 matches);
294 return matches.GetSize();
295 }
296
297 virtual Options *
298 GetOptions ()
299 {
300 return &m_options;
301 }
302
303protected:
Jim Inghame16c50a2011-02-18 00:54:25 +0000304
305 class CommandOptions : public Options
306 {
307 public:
308
Greg Claytoneb0103f2011-04-07 22:46:35 +0000309 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata012d4fc2013-06-11 01:26:35 +0000310 Options (interpreter),
Greg Clayton340b0302014-02-05 17:57:57 +0000311 m_stop_on_error (true),
312 m_silent_run (false),
313 m_stop_on_continue (true)
Greg Claytoneb0103f2011-04-07 22:46:35 +0000314 {
315 }
Jim Inghame16c50a2011-02-18 00:54:25 +0000316
317 virtual
318 ~CommandOptions (){}
319
320 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000321 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame16c50a2011-02-18 00:54:25 +0000322 {
323 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000324 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame16c50a2011-02-18 00:54:25 +0000325
326 switch (short_option)
327 {
328 case 'e':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000329 error = m_stop_on_error.SetValueFromString(option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000330 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000331
Jim Inghame16c50a2011-02-18 00:54:25 +0000332 case 'c':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000333 error = m_stop_on_continue.SetValueFromString(option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000334 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000335
Michael Sartain60986172013-07-09 23:22:53 +0000336 case 's':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000337 error = m_silent_run.SetValueFromString(option_arg);
Michael Sartain60986172013-07-09 23:22:53 +0000338 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000339
Jim Inghame16c50a2011-02-18 00:54:25 +0000340 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000341 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghame16c50a2011-02-18 00:54:25 +0000342 break;
343 }
344
345 return error;
346 }
347
348 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000349 OptionParsingStarting ()
Jim Inghame16c50a2011-02-18 00:54:25 +0000350 {
Enrico Granata012d4fc2013-06-11 01:26:35 +0000351 m_stop_on_error.Clear();
Greg Clayton340b0302014-02-05 17:57:57 +0000352 m_silent_run.Clear();
353 m_stop_on_continue.Clear();
Jim Inghame16c50a2011-02-18 00:54:25 +0000354 }
355
Greg Claytone0d378b2011-03-24 21:19:54 +0000356 const OptionDefinition*
Jim Inghame16c50a2011-02-18 00:54:25 +0000357 GetDefinitions ()
358 {
359 return g_option_table;
360 }
361
362 // Options table: Required for subclasses of Options.
363
Greg Claytone0d378b2011-03-24 21:19:54 +0000364 static OptionDefinition g_option_table[];
Jim Inghame16c50a2011-02-18 00:54:25 +0000365
366 // Instance variables to hold the values for command options.
367
Enrico Granata012d4fc2013-06-11 01:26:35 +0000368 OptionValueBoolean m_stop_on_error;
Jim Ingham7d8555c2014-11-18 19:12:13 +0000369 OptionValueBoolean m_silent_run;
Greg Clayton340b0302014-02-05 17:57:57 +0000370 OptionValueBoolean m_stop_on_continue;
Jim Inghame16c50a2011-02-18 00:54:25 +0000371 };
372
Jim Inghamebc09c32010-07-07 03:36:20 +0000373 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000374 DoExecute(Args& command, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000375 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000376 const size_t argc = command.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000377 if (argc == 1)
378 {
Jim Ingham5a988412012-06-08 21:56:10 +0000379 const char *filename = command.GetArgumentAtIndex(0);
Jim Inghamebc09c32010-07-07 03:36:20 +0000380
Johnny Chen1ee38532010-10-20 21:40:50 +0000381 FileSpec cmd_file (filename, true);
Jim Inghame16c50a2011-02-18 00:54:25 +0000382 ExecutionContext *exe_ctx = NULL; // Just use the default context.
Greg Clayton340b0302014-02-05 17:57:57 +0000383
384 // If any options were set, then use them
385 if (m_options.m_stop_on_error.OptionWasSet() ||
386 m_options.m_silent_run.OptionWasSet() ||
387 m_options.m_stop_on_continue.OptionWasSet())
388 {
389 // Use user set settings
Jim Ingham26c7bf92014-10-11 00:38:27 +0000390 CommandInterpreterRunOptions options;
391 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
392 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
Jim Ingham7d8555c2014-11-18 19:12:13 +0000393 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
394 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
Jim Ingham26c7bf92014-10-11 00:38:27 +0000395
Greg Clayton340b0302014-02-05 17:57:57 +0000396 m_interpreter.HandleCommandsFromFile (cmd_file,
397 exe_ctx,
Jim Ingham26c7bf92014-10-11 00:38:27 +0000398 options,
Greg Clayton340b0302014-02-05 17:57:57 +0000399 result);
400
401 }
402 else
403 {
404 // No options were set, inherit any settings from nested "command source" commands,
405 // or set to sane default settings...
Jim Ingham26c7bf92014-10-11 00:38:27 +0000406 CommandInterpreterRunOptions options;
Greg Clayton340b0302014-02-05 17:57:57 +0000407 m_interpreter.HandleCommandsFromFile (cmd_file,
408 exe_ctx,
Jim Ingham26c7bf92014-10-11 00:38:27 +0000409 options,
Greg Clayton340b0302014-02-05 17:57:57 +0000410 result);
411
412 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000413 }
414 else
415 {
416 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
417 result.SetStatus (eReturnStatusFailed);
418 }
419 return result.Succeeded();
420
421 }
Jim Ingham5a988412012-06-08 21:56:10 +0000422 CommandOptions m_options;
Jim Inghamebc09c32010-07-07 03:36:20 +0000423};
424
Greg Claytone0d378b2011-03-24 21:19:54 +0000425OptionDefinition
Jim Inghame16c50a2011-02-18 00:54:25 +0000426CommandObjectCommandsSource::CommandOptions::g_option_table[] =
427{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000428{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
429{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
430{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
431{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Jim Inghame16c50a2011-02-18 00:54:25 +0000432};
433
Jim Inghamebc09c32010-07-07 03:36:20 +0000434#pragma mark CommandObjectCommandsAlias
435//-------------------------------------------------------------------------
436// CommandObjectCommandsAlias
437//-------------------------------------------------------------------------
438
Enrico Granatabe93a352011-08-16 16:49:25 +0000439static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
440 "You must define a Python function with this signature:\n"
Greg Clayton44d93782014-01-27 23:43:24 +0000441 "def my_command_impl(debugger, args, result, internal_dict):\n";
Enrico Granatabe93a352011-08-16 16:49:25 +0000442
443
Jim Ingham5a988412012-06-08 21:56:10 +0000444class CommandObjectCommandsAlias : public CommandObjectRaw
Jim Inghamebc09c32010-07-07 03:36:20 +0000445{
Enrico Granatabe93a352011-08-16 16:49:25 +0000446
Enrico Granatabe93a352011-08-16 16:49:25 +0000447
Jim Inghamebc09c32010-07-07 03:36:20 +0000448public:
Greg Claytona7015092010-09-18 01:14:36 +0000449 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000450 CommandObjectRaw (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000451 "command alias",
Caroline Ticee3d26312010-09-08 21:06:11 +0000452 "Allow users to define their own debugger command abbreviations.",
Caroline Tice405fe672010-10-04 22:28:36 +0000453 NULL)
Jim Inghamebc09c32010-07-07 03:36:20 +0000454 {
455 SetHelpLong(
456 "'alias' allows the user to create a short-cut or abbreviation for long \n\
457 commands, multi-word commands, and commands that take particular options. \n\
458 Below are some simple examples of how one might use the 'alias' command: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000459 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000460 // command. \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000461 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000462 // command. Since breakpoint commands are two-word \n\
463 // commands, the user will still need to enter the \n\
464 // second word after 'bp', e.g. 'bp enable' or \n\
465 // 'bp delete'. \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000466 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000467 // two-word command 'breakpoint list'. \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000468 \nAn alias can include some options for the command, with the values either \n\
469 filled in at the time the alias is created, or specified as positional \n\
470 arguments, to be filled in when the alias is invoked. The following example \n\
471 shows how to create aliases with options: \n\
472 \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000473 'command alias bfl breakpoint set -f %1 -l %2' \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000474 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
475 options already part of the alias. So if the user wants to set a breakpoint \n\
476 by file and line without explicitly having to use the -f and -l options, the \n\
477 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
478 for the actual arguments that will be passed when the alias command is used. \n\
479 The number in the placeholder refers to the position/order the actual value \n\
Jim Ingham81ded932011-08-18 02:29:05 +0000480 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000481 will be replaced with the first argument, all the occurrences of '%2' in the \n\
482 alias will be replaced with the second argument, and so on. This also allows \n\
483 actual arguments to be used multiple times within an alias (see 'process \n\
Jim Ingham81ded932011-08-18 02:29:05 +0000484 launch' example below). \n\
485 Note: the positional arguments must substitute as whole words in the resultant\n\
486 command, so you can't at present do something like:\n\
487 \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000488 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
Jim Ingham81ded932011-08-18 02:29:05 +0000489 \n\
490 to get the file extension \".cpp\" automatically appended. For more complex\n\
491 aliasing, use the \"command regex\" command instead.\n\
492 \nSo in the 'bfl' case, the actual file value will be \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000493 filled in with the first argument following 'bfl' and the actual line number \n\
494 value will be filled in with the second argument. The user would use this \n\
495 alias as follows: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000496 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000497 <... some time later ...> \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000498 (lldb) bfl my-file.c 137 \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000499 \nThis would be the same as if the user had entered \n\
500 'breakpoint set -f my-file.c -l 137'. \n\
501 \nAnother example: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000502 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000503 (lldb) pltty /dev/tty0 \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000504 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000505 \nIf the user always wanted to pass the same value to a particular option, the \n\
506 alias could be defined with that value directly in the alias as a constant, \n\
507 rather than using a positional placeholder: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000508 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000509 // 3 of whatever file is indicated. \n");
Jim Inghamebc09c32010-07-07 03:36:20 +0000510
Caroline Tice405fe672010-10-04 22:28:36 +0000511 CommandArgumentEntry arg1;
512 CommandArgumentEntry arg2;
513 CommandArgumentEntry arg3;
514 CommandArgumentData alias_arg;
515 CommandArgumentData cmd_arg;
516 CommandArgumentData options_arg;
517
518 // Define the first (and only) variant of this arg.
519 alias_arg.arg_type = eArgTypeAliasName;
520 alias_arg.arg_repetition = eArgRepeatPlain;
521
522 // There is only one variant this argument could be; put it into the argument entry.
523 arg1.push_back (alias_arg);
524
525 // Define the first (and only) variant of this arg.
526 cmd_arg.arg_type = eArgTypeCommandName;
527 cmd_arg.arg_repetition = eArgRepeatPlain;
528
529 // There is only one variant this argument could be; put it into the argument entry.
530 arg2.push_back (cmd_arg);
531
532 // Define the first (and only) variant of this arg.
533 options_arg.arg_type = eArgTypeAliasOptions;
534 options_arg.arg_repetition = eArgRepeatOptional;
535
536 // There is only one variant this argument could be; put it into the argument entry.
537 arg3.push_back (options_arg);
538
539 // Push the data for the first argument into the m_arguments vector.
540 m_arguments.push_back (arg1);
541 m_arguments.push_back (arg2);
542 m_arguments.push_back (arg3);
Jim Inghamebc09c32010-07-07 03:36:20 +0000543 }
544
545 ~CommandObjectCommandsAlias ()
546 {
547 }
548
Jim Ingham5a988412012-06-08 21:56:10 +0000549protected:
550 virtual bool
551 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Caroline Tice844d2302010-12-09 22:52:49 +0000552 {
553 Args args (raw_command_line);
554 std::string raw_command_string (raw_command_line);
555
556 size_t argc = args.GetArgumentCount();
557
558 if (argc < 2)
559 {
560 result.AppendError ("'alias' requires at least two arguments");
561 result.SetStatus (eReturnStatusFailed);
562 return false;
563 }
564
565 // Get the alias command.
566
567 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatabe93a352011-08-16 16:49:25 +0000568
Caroline Tice844d2302010-12-09 22:52:49 +0000569 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
570 // does the stripping itself.
571 size_t pos = raw_command_string.find (alias_command);
572 if (pos == 0)
573 {
574 raw_command_string = raw_command_string.substr (alias_command.size());
575 pos = raw_command_string.find_first_not_of (' ');
576 if ((pos != std::string::npos) && (pos > 0))
577 raw_command_string = raw_command_string.substr (pos);
578 }
579 else
580 {
581 result.AppendError ("Error parsing command string. No alias created.");
582 result.SetStatus (eReturnStatusFailed);
583 return false;
584 }
585
586
587 // Verify that the command is alias-able.
588 if (m_interpreter.CommandExists (alias_command.c_str()))
589 {
590 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
591 alias_command.c_str());
592 result.SetStatus (eReturnStatusFailed);
593 return false;
594 }
595
596 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
597 // raw_command_string is returned with the name of the command object stripped off the front.
598 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
599
600 if (!cmd_obj)
601 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000602 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
Caroline Tice844d2302010-12-09 22:52:49 +0000603 " No alias created.", raw_command_string.c_str());
604 result.SetStatus (eReturnStatusFailed);
605 return false;
606 }
607 else if (!cmd_obj->WantsRawCommandString ())
608 {
609 // Note that args was initialized with the original command, and has not been updated to this point.
610 // 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 +0000611 return HandleAliasingNormalCommand (args, result);
Caroline Tice844d2302010-12-09 22:52:49 +0000612 }
613 else
614 {
Jim Ingham5a988412012-06-08 21:56:10 +0000615 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
616 }
617 return result.Succeeded();
618 }
619
620 bool
621 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
622 {
Caroline Tice844d2302010-12-09 22:52:49 +0000623 // Verify & handle any options/arguments passed to the alias command
624
625 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
626 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
627
Jim Ingham5a988412012-06-08 21:56:10 +0000628 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
Caroline Ticeca90c472011-05-06 21:37:15 +0000629
630 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Tice844d2302010-12-09 22:52:49 +0000631 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000632 result.AppendError ("Unable to create requested alias.\n");
633 result.SetStatus (eReturnStatusFailed);
634 return false;
Caroline Tice844d2302010-12-09 22:52:49 +0000635 }
636
637 // Create the alias
638 if (m_interpreter.AliasExists (alias_command.c_str())
639 || m_interpreter.UserCommandExists (alias_command.c_str()))
640 {
641 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
642 if (temp_option_arg_sp.get())
643 {
644 if (option_arg_vector->size() == 0)
645 m_interpreter.RemoveAliasOptions (alias_command.c_str());
646 }
647 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
648 alias_command.c_str());
649 }
650
Caroline Tice472362e2010-12-14 18:51:39 +0000651 if (cmd_obj_sp)
652 {
653 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
654 if (option_arg_vector->size() > 0)
655 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
656 result.SetStatus (eReturnStatusSuccessFinishNoResult);
657 }
658 else
659 {
660 result.AppendError ("Unable to create requested alias.\n");
661 result.SetStatus (eReturnStatusFailed);
662 }
Jim Ingham5a988412012-06-08 21:56:10 +0000663 return result.Succeeded ();
Caroline Tice844d2302010-12-09 22:52:49 +0000664 }
Jim Ingham5a988412012-06-08 21:56:10 +0000665
Jim Inghamebc09c32010-07-07 03:36:20 +0000666 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000667 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000668 {
Caroline Tice867b185d2010-09-21 23:25:40 +0000669 size_t argc = args.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000670
671 if (argc < 2)
Greg Claytonc982c762010-07-09 20:39:50 +0000672 {
Jim Inghamebc09c32010-07-07 03:36:20 +0000673 result.AppendError ("'alias' requires at least two arguments");
674 result.SetStatus (eReturnStatusFailed);
675 return false;
Greg Claytonc982c762010-07-09 20:39:50 +0000676 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000677
678 const std::string alias_command = args.GetArgumentAtIndex(0);
679 const std::string actual_command = args.GetArgumentAtIndex(1);
680
681 args.Shift(); // Shift the alias command word off the argument vector.
682 args.Shift(); // Shift the old command word off the argument vector.
683
684 // Verify that the command is alias'able, and get the appropriate command object.
685
Greg Claytona7015092010-09-18 01:14:36 +0000686 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000687 {
688 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
689 alias_command.c_str());
690 result.SetStatus (eReturnStatusFailed);
691 }
692 else
693 {
Greg Claytona7015092010-09-18 01:14:36 +0000694 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Inghamebc09c32010-07-07 03:36:20 +0000695 CommandObjectSP subcommand_obj_sp;
696 bool use_subcommand = false;
697 if (command_obj_sp.get())
698 {
699 CommandObject *cmd_obj = command_obj_sp.get();
Greg Claytonc982c762010-07-09 20:39:50 +0000700 CommandObject *sub_cmd_obj = NULL;
Jim Inghamebc09c32010-07-07 03:36:20 +0000701 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
702 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
703
Caroline Tice844d2302010-12-09 22:52:49 +0000704 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Inghamebc09c32010-07-07 03:36:20 +0000705 {
706 if (argc >= 3)
707 {
708 const std::string sub_command = args.GetArgumentAtIndex(0);
709 assert (sub_command.length() != 0);
Greg Clayton998255b2012-10-13 02:07:45 +0000710 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000711 if (subcommand_obj_sp.get())
712 {
713 sub_cmd_obj = subcommand_obj_sp.get();
714 use_subcommand = true;
715 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Tice844d2302010-12-09 22:52:49 +0000716 cmd_obj = sub_cmd_obj;
Jim Inghamebc09c32010-07-07 03:36:20 +0000717 }
718 else
719 {
Caroline Ticef415eeb2010-11-02 19:00:04 +0000720 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
721 "Unable to create alias.\n",
722 sub_command.c_str(), actual_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000723 result.SetStatus (eReturnStatusFailed);
724 return false;
725 }
726 }
727 }
728
729 // Verify & handle any options/arguments passed to the alias command
730
731 if (args.GetArgumentCount () > 0)
732 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000733 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
734 if (use_subcommand)
735 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
736
737 std::string args_string;
738 args.GetCommandString (args_string);
739
740 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
741 {
742 result.AppendError ("Unable to create requested alias.\n");
743 result.SetStatus (eReturnStatusFailed);
744 return false;
745 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000746 }
747
748 // Create the alias.
749
Greg Claytona7015092010-09-18 01:14:36 +0000750 if (m_interpreter.AliasExists (alias_command.c_str())
751 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000752 {
Greg Claytona7015092010-09-18 01:14:36 +0000753 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Inghamebc09c32010-07-07 03:36:20 +0000754 if (tmp_option_arg_sp.get())
755 {
756 if (option_arg_vector->size() == 0)
Greg Claytona7015092010-09-18 01:14:36 +0000757 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000758 }
759 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
760 alias_command.c_str());
761 }
762
763 if (use_subcommand)
Greg Claytona7015092010-09-18 01:14:36 +0000764 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000765 else
Greg Claytona7015092010-09-18 01:14:36 +0000766 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000767 if (option_arg_vector->size() > 0)
Greg Claytona7015092010-09-18 01:14:36 +0000768 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000769 result.SetStatus (eReturnStatusSuccessFinishNoResult);
770 }
771 else
772 {
773 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
774 result.SetStatus (eReturnStatusFailed);
Caroline Ticee7941792010-10-28 23:17:48 +0000775 return false;
Jim Inghamebc09c32010-07-07 03:36:20 +0000776 }
777 }
778
779 return result.Succeeded();
780 }
Jim Ingham5a988412012-06-08 21:56:10 +0000781
Jim Inghamebc09c32010-07-07 03:36:20 +0000782};
783
784#pragma mark CommandObjectCommandsUnalias
785//-------------------------------------------------------------------------
786// CommandObjectCommandsUnalias
787//-------------------------------------------------------------------------
788
Jim Ingham5a988412012-06-08 21:56:10 +0000789class CommandObjectCommandsUnalias : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000790{
791public:
Greg Claytona7015092010-09-18 01:14:36 +0000792 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000793 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000794 "command unalias",
Caroline Tice86ddae52010-09-12 04:56:10 +0000795 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice405fe672010-10-04 22:28:36 +0000796 NULL)
Jim Inghamebc09c32010-07-07 03:36:20 +0000797 {
Caroline Tice405fe672010-10-04 22:28:36 +0000798 CommandArgumentEntry arg;
799 CommandArgumentData alias_arg;
800
801 // Define the first (and only) variant of this arg.
802 alias_arg.arg_type = eArgTypeAliasName;
803 alias_arg.arg_repetition = eArgRepeatPlain;
804
805 // There is only one variant this argument could be; put it into the argument entry.
806 arg.push_back (alias_arg);
807
808 // Push the data for the first argument into the m_arguments vector.
809 m_arguments.push_back (arg);
Jim Inghamebc09c32010-07-07 03:36:20 +0000810 }
811
812 ~CommandObjectCommandsUnalias()
813 {
814 }
815
Jim Ingham5a988412012-06-08 21:56:10 +0000816protected:
Jim Inghamebc09c32010-07-07 03:36:20 +0000817 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000818 DoExecute (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000819 {
820 CommandObject::CommandMap::iterator pos;
821 CommandObject *cmd_obj;
822
823 if (args.GetArgumentCount() != 0)
824 {
825 const char *command_name = args.GetArgumentAtIndex(0);
Greg Claytona7015092010-09-18 01:14:36 +0000826 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Inghamebc09c32010-07-07 03:36:20 +0000827 if (cmd_obj)
828 {
Greg Claytona7015092010-09-18 01:14:36 +0000829 if (m_interpreter.CommandExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000830 {
Greg Claytonb5472782015-01-09 19:08:20 +0000831 if (cmd_obj->IsRemovable())
832 {
833 result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
834 command_name);
835 }
836 else
837 {
838 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
839 command_name);
840 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000841 result.SetStatus (eReturnStatusFailed);
842 }
843 else
844 {
845
Greg Claytona7015092010-09-18 01:14:36 +0000846 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Inghamebc09c32010-07-07 03:36:20 +0000847 {
Greg Claytona7015092010-09-18 01:14:36 +0000848 if (m_interpreter.AliasExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000849 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
850 command_name);
851 else
852 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
853 result.SetStatus (eReturnStatusFailed);
854 }
855 else
856 result.SetStatus (eReturnStatusSuccessFinishNoResult);
857 }
858 }
859 else
860 {
861 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
862 "current list of commands.\n",
863 command_name);
864 result.SetStatus (eReturnStatusFailed);
865 }
866 }
867 else
868 {
869 result.AppendError ("must call 'unalias' with a valid alias");
870 result.SetStatus (eReturnStatusFailed);
871 }
872
873 return result.Succeeded();
874 }
875};
876
Greg Claytonb5472782015-01-09 19:08:20 +0000877#pragma mark CommandObjectCommandsDelete
878//-------------------------------------------------------------------------
879// CommandObjectCommandsDelete
880//-------------------------------------------------------------------------
881
882class CommandObjectCommandsDelete : public CommandObjectParsed
883{
884public:
885 CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
886 CommandObjectParsed (interpreter,
887 "command delete",
888 "Allow the user to delete user-defined regular expression, python or multi-word commands.",
889 NULL)
890 {
891 CommandArgumentEntry arg;
892 CommandArgumentData alias_arg;
893
894 // Define the first (and only) variant of this arg.
895 alias_arg.arg_type = eArgTypeCommandName;
896 alias_arg.arg_repetition = eArgRepeatPlain;
897
898 // There is only one variant this argument could be; put it into the argument entry.
899 arg.push_back (alias_arg);
900
901 // Push the data for the first argument into the m_arguments vector.
902 m_arguments.push_back (arg);
903 }
904
905 ~CommandObjectCommandsDelete()
906 {
907 }
908
909protected:
910 bool
911 DoExecute (Args& args, CommandReturnObject &result)
912 {
913 CommandObject::CommandMap::iterator pos;
914
915 if (args.GetArgumentCount() != 0)
916 {
917 const char *command_name = args.GetArgumentAtIndex(0);
918 if (m_interpreter.CommandExists (command_name))
919 {
920 if (m_interpreter.RemoveCommand (command_name))
921 {
922 result.SetStatus (eReturnStatusSuccessFinishNoResult);
923 }
924 else
925 {
926 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
927 command_name);
928 result.SetStatus (eReturnStatusFailed);
929 }
930 }
931 else
932 {
933 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
934 command_name);
935 result.SetStatus (eReturnStatusFailed);
936 }
937 }
938 else
939 {
940 result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
941 result.SetStatus (eReturnStatusFailed);
942 }
943
944 return result.Succeeded();
945 }
946};
947
Greg Claytonde164aa2011-04-20 16:37:46 +0000948//-------------------------------------------------------------------------
949// CommandObjectCommandsAddRegex
950//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000951#pragma mark CommandObjectCommandsAddRegex
Greg Claytonde164aa2011-04-20 16:37:46 +0000952
Greg Clayton44d93782014-01-27 23:43:24 +0000953class CommandObjectCommandsAddRegex :
954 public CommandObjectParsed,
Greg Claytonea508632014-11-18 00:43:17 +0000955 public IOHandlerDelegateMultiline
Greg Claytonde164aa2011-04-20 16:37:46 +0000956{
957public:
958 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000959 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000960 "command regex",
Greg Claytonde164aa2011-04-20 16:37:46 +0000961 "Allow the user to create a regular expression command.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000962 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytonea508632014-11-18 00:43:17 +0000963 IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
Greg Claytonde164aa2011-04-20 16:37:46 +0000964 m_options (interpreter)
965 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000966 SetHelpLong(
967"This command allows the user to create powerful regular expression commands\n"
968"with substitutions. The regular expressions and substitutions are specified\n"
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000969"using the regular expression substitution format of:\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000970"\n"
971" s/<regex>/<subst>/\n"
972"\n"
973"<regex> is a regular expression that can use parenthesis to capture regular\n"
974"expression input and substitute the captured matches in the output using %1\n"
975"for the first match, %2 for the second, and so on.\n"
976"\n"
977"The regular expressions can all be specified on the command line if more than\n"
978"one argument is provided. If just the command name is provided on the command\n"
979"line, then the regular expressions and substitutions can be entered on separate\n"
980" lines, followed by an empty line to terminate the command definition.\n"
981"\n"
982"EXAMPLES\n"
983"\n"
Sean Callananadc43c92012-08-16 21:46:58 +0000984"The following example will define a regular expression command named 'f' that\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000985"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
986"a number follows 'f':\n"
Sean Callananadc43c92012-08-16 21:46:58 +0000987"\n"
988" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
989"\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000990 );
Greg Claytonde164aa2011-04-20 16:37:46 +0000991 }
992
993 ~CommandObjectCommandsAddRegex()
994 {
995 }
996
997
Jim Ingham5a988412012-06-08 21:56:10 +0000998protected:
Greg Clayton44d93782014-01-27 23:43:24 +0000999
Greg Claytonea508632014-11-18 00:43:17 +00001000 void
1001 IOHandlerActivated (IOHandler &io_handler) override
Greg Clayton44d93782014-01-27 23:43:24 +00001002 {
1003 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1004 if (output_sp)
1005 {
1006 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");
1007 output_sp->Flush();
1008 }
1009 }
1010
Greg Claytonea508632014-11-18 00:43:17 +00001011 void
1012 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
Greg Clayton44d93782014-01-27 23:43:24 +00001013 {
1014 io_handler.SetIsDone(true);
1015 if (m_regex_cmd_ap.get())
1016 {
1017 StringList lines;
1018 if (lines.SplitIntoLines (data))
1019 {
1020 const size_t num_lines = lines.GetSize();
1021 bool check_only = false;
1022 for (size_t i=0; i<num_lines; ++i)
1023 {
Greg Clayton44d93782014-01-27 23:43:24 +00001024 llvm::StringRef bytes_strref (lines[i]);
1025 Error error = AppendRegexSubstitution (bytes_strref, check_only);
1026 if (error.Fail())
1027 {
1028 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
1029 {
1030 StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
1031 out_stream->Printf("error: %s\n", error.AsCString());
1032 }
1033 }
1034 }
1035 }
1036 if (m_regex_cmd_ap->HasRegexEntries())
1037 {
1038 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1039 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1040 }
1041 }
1042 }
Greg Clayton44d93782014-01-27 23:43:24 +00001043
Greg Claytonde164aa2011-04-20 16:37:46 +00001044 bool
Eric Christopherb0a18142014-11-18 22:40:27 +00001045 DoExecute (Args& command, CommandReturnObject &result) override
Greg Claytonde164aa2011-04-20 16:37:46 +00001046 {
Jim Ingham5a988412012-06-08 21:56:10 +00001047 const size_t argc = command.GetArgumentCount();
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001048 if (argc == 0)
Greg Claytonde164aa2011-04-20 16:37:46 +00001049 {
Jason Molenda69c12cc2011-11-10 22:43:35 +00001050 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001051 result.SetStatus (eReturnStatusFailed);
1052 }
1053 else
1054 {
1055 Error error;
Jim Ingham5a988412012-06-08 21:56:10 +00001056 const char *name = command.GetArgumentAtIndex(0);
Greg Claytonde164aa2011-04-20 16:37:46 +00001057 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1058 name,
1059 m_options.GetHelp (),
1060 m_options.GetSyntax (),
Greg Claytonb5472782015-01-09 19:08:20 +00001061 10,
1062 0,
1063 true));
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001064
1065 if (argc == 1)
Greg Claytonde164aa2011-04-20 16:37:46 +00001066 {
Greg Clayton44d93782014-01-27 23:43:24 +00001067 Debugger &debugger = m_interpreter.GetDebugger();
Kate Stonee30f11d2014-11-17 19:06:59 +00001068 bool color_prompt = debugger.GetUseColor();
Greg Clayton44d93782014-01-27 23:43:24 +00001069 const bool multiple_lines = true; // Get multiple lines
1070 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
Kate Stonee30f11d2014-11-17 19:06:59 +00001071 IOHandler::Type::Other,
Greg Clayton73d80fa2014-07-09 20:18:54 +00001072 "lldb-regex", // Name of input reader for history
Greg Claytonea508632014-11-18 00:43:17 +00001073 "> ", // Prompt
Kate Stonee30f11d2014-11-17 19:06:59 +00001074 NULL, // Continuation prompt
Greg Clayton44d93782014-01-27 23:43:24 +00001075 multiple_lines,
Kate Stonee30f11d2014-11-17 19:06:59 +00001076 color_prompt,
Greg Claytonf6913cd2014-03-07 00:53:24 +00001077 0, // Don't show line numbers
Greg Clayton44d93782014-01-27 23:43:24 +00001078 *this));
1079
1080 if (io_handler_sp)
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001081 {
Greg Clayton44d93782014-01-27 23:43:24 +00001082 debugger.PushIOHandler(io_handler_sp);
1083 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonde164aa2011-04-20 16:37:46 +00001084 }
1085 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001086 else
1087 {
1088 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
1089 {
Jim Ingham5a988412012-06-08 21:56:10 +00001090 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton44d93782014-01-27 23:43:24 +00001091 bool check_only = false;
1092 error = AppendRegexSubstitution (arg_strref, check_only);
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001093 if (error.Fail())
1094 break;
1095 }
1096
1097 if (error.Success())
1098 {
1099 AddRegexCommandToInterpreter();
1100 }
1101 }
1102 if (error.Fail())
1103 {
1104 result.AppendError (error.AsCString());
1105 result.SetStatus (eReturnStatusFailed);
1106 }
Greg Claytonde164aa2011-04-20 16:37:46 +00001107 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001108
Greg Claytonde164aa2011-04-20 16:37:46 +00001109 return result.Succeeded();
1110 }
1111
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001112 Error
Greg Clayton44d93782014-01-27 23:43:24 +00001113 AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
Greg Claytonde164aa2011-04-20 16:37:46 +00001114 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001115 Error error;
1116
1117 if (m_regex_cmd_ap.get() == NULL)
Greg Claytonde164aa2011-04-20 16:37:46 +00001118 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001119 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
1120 (int)regex_sed.size(),
1121 regex_sed.data());
1122 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001123 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001124
1125 size_t regex_sed_size = regex_sed.size();
1126
1127 if (regex_sed_size <= 1)
1128 {
1129 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
1130 (int)regex_sed.size(),
1131 regex_sed.data());
1132 return error;
1133 }
1134
1135 if (regex_sed[0] != 's')
1136 {
1137 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
1138 (int)regex_sed.size(),
1139 regex_sed.data());
1140 return error;
1141 }
1142 const size_t first_separator_char_pos = 1;
1143 // use the char that follows 's' as the regex separator character
1144 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1145 const char separator_char = regex_sed[first_separator_char_pos];
1146 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1147
1148 if (second_separator_char_pos == std::string::npos)
1149 {
Greg Claytonea508632014-11-18 00:43:17 +00001150 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001151 separator_char,
1152 (int)(regex_sed.size() - first_separator_char_pos - 1),
Greg Claytonea508632014-11-18 00:43:17 +00001153 regex_sed.data() + (first_separator_char_pos + 1),
1154 (int)regex_sed.size(),
1155 regex_sed.data());
1156 return error;
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001157 }
1158
1159 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1160
1161 if (third_separator_char_pos == std::string::npos)
1162 {
Greg Claytonea508632014-11-18 00:43:17 +00001163 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001164 separator_char,
1165 (int)(regex_sed.size() - second_separator_char_pos - 1),
Greg Claytonea508632014-11-18 00:43:17 +00001166 regex_sed.data() + (second_separator_char_pos + 1),
1167 (int)regex_sed.size(),
1168 regex_sed.data());
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001169 return error;
1170 }
1171
1172 if (third_separator_char_pos != regex_sed_size - 1)
1173 {
1174 // Make sure that everything that follows the last regex
1175 // separator char
1176 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1177 {
1178 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1179 (int)third_separator_char_pos + 1,
1180 regex_sed.data(),
1181 (int)(regex_sed.size() - third_separator_char_pos - 1),
1182 regex_sed.data() + (third_separator_char_pos + 1));
1183 return error;
1184 }
1185
1186 }
1187 else if (first_separator_char_pos + 1 == second_separator_char_pos)
1188 {
1189 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1190 separator_char,
1191 separator_char,
1192 separator_char,
1193 (int)regex_sed.size(),
1194 regex_sed.data());
1195 return error;
1196 }
1197 else if (second_separator_char_pos + 1 == third_separator_char_pos)
1198 {
1199 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1200 separator_char,
1201 separator_char,
1202 separator_char,
1203 (int)regex_sed.size(),
1204 regex_sed.data());
1205 return error;
1206 }
Greg Clayton44d93782014-01-27 23:43:24 +00001207
1208 if (check_only == false)
1209 {
1210 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1211 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1212 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1213 subst.c_str());
1214 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001215 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001216 }
1217
1218 void
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001219 AddRegexCommandToInterpreter()
Greg Claytonde164aa2011-04-20 16:37:46 +00001220 {
1221 if (m_regex_cmd_ap.get())
1222 {
1223 if (m_regex_cmd_ap->HasRegexEntries())
1224 {
1225 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1226 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1227 }
1228 }
1229 }
1230
Greg Claytonde164aa2011-04-20 16:37:46 +00001231private:
Greg Clayton7b0992d2013-04-18 22:45:39 +00001232 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
Greg Claytonde164aa2011-04-20 16:37:46 +00001233
1234 class CommandOptions : public Options
1235 {
1236 public:
1237
1238 CommandOptions (CommandInterpreter &interpreter) :
1239 Options (interpreter)
1240 {
1241 }
1242
1243 virtual
1244 ~CommandOptions (){}
1245
1246 virtual Error
1247 SetOptionValue (uint32_t option_idx, const char *option_arg)
1248 {
1249 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001250 const int short_option = m_getopt_table[option_idx].val;
Greg Claytonde164aa2011-04-20 16:37:46 +00001251
1252 switch (short_option)
1253 {
1254 case 'h':
1255 m_help.assign (option_arg);
1256 break;
1257 case 's':
1258 m_syntax.assign (option_arg);
1259 break;
1260
1261 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001262 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytonde164aa2011-04-20 16:37:46 +00001263 break;
1264 }
1265
1266 return error;
1267 }
1268
1269 void
1270 OptionParsingStarting ()
1271 {
1272 m_help.clear();
1273 m_syntax.clear();
1274 }
1275
1276 const OptionDefinition*
1277 GetDefinitions ()
1278 {
1279 return g_option_table;
1280 }
1281
1282 // Options table: Required for subclasses of Options.
1283
1284 static OptionDefinition g_option_table[];
1285
1286 const char *
1287 GetHelp ()
1288 {
1289 if (m_help.empty())
1290 return NULL;
1291 return m_help.c_str();
1292 }
1293 const char *
1294 GetSyntax ()
1295 {
1296 if (m_syntax.empty())
1297 return NULL;
1298 return m_syntax.c_str();
1299 }
1300 // Instance variables to hold the values for command options.
1301 protected:
1302 std::string m_help;
1303 std::string m_syntax;
1304 };
Jim Ingham5a988412012-06-08 21:56:10 +00001305
Eric Christopherb0a18142014-11-18 22:40:27 +00001306 Options *
1307 GetOptions () override
Greg Claytonde164aa2011-04-20 16:37:46 +00001308 {
1309 return &m_options;
1310 }
Jim Ingham5a988412012-06-08 21:56:10 +00001311
1312 CommandOptions m_options;
Greg Claytonde164aa2011-04-20 16:37:46 +00001313};
1314
Greg Claytonde164aa2011-04-20 16:37:46 +00001315OptionDefinition
1316CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1317{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001318{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1319{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1320{ 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL }
Greg Claytonde164aa2011-04-20 16:37:46 +00001321};
1322
1323
Jim Ingham5a988412012-06-08 21:56:10 +00001324class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata223383e2011-08-16 23:24:13 +00001325{
1326private:
1327 std::string m_function_name;
Enrico Granata0a305db2011-11-07 22:57:04 +00001328 ScriptedCommandSynchronicity m_synchro;
Enrico Granatafac939e2012-09-18 21:53:02 +00001329 bool m_fetched_help_long;
Enrico Granata223383e2011-08-16 23:24:13 +00001330
1331public:
1332
1333 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1334 std::string name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001335 std::string funct,
Enrico Granata735152e2014-09-15 17:52:44 +00001336 std::string help,
Enrico Granata0a305db2011-11-07 22:57:04 +00001337 ScriptedCommandSynchronicity synch) :
Jim Ingham5a988412012-06-08 21:56:10 +00001338 CommandObjectRaw (interpreter,
1339 name.c_str(),
Enrico Granata735152e2014-09-15 17:52:44 +00001340 NULL,
Jim Ingham5a988412012-06-08 21:56:10 +00001341 NULL),
1342 m_function_name(funct),
Enrico Granatafac939e2012-09-18 21:53:02 +00001343 m_synchro(synch),
1344 m_fetched_help_long(false)
Enrico Granata223383e2011-08-16 23:24:13 +00001345 {
Enrico Granata735152e2014-09-15 17:52:44 +00001346 if (!help.empty())
1347 SetHelp(help.c_str());
1348 else
1349 {
1350 StreamString stream;
1351 stream.Printf("For more information run 'help %s'",name.c_str());
1352 SetHelp(stream.GetData());
1353 }
Enrico Granata223383e2011-08-16 23:24:13 +00001354 }
1355
1356 virtual
1357 ~CommandObjectPythonFunction ()
1358 {
1359 }
1360
1361 virtual bool
Greg Clayton3a18e312012-10-08 22:41:53 +00001362 IsRemovable () const
Jim Ingham5a988412012-06-08 21:56:10 +00001363 {
1364 return true;
1365 }
1366
1367 const std::string&
1368 GetFunctionName ()
1369 {
1370 return m_function_name;
1371 }
1372
1373 ScriptedCommandSynchronicity
1374 GetSynchronicity ()
1375 {
1376 return m_synchro;
1377 }
1378
Enrico Granatafac939e2012-09-18 21:53:02 +00001379 virtual const char *
1380 GetHelpLong ()
1381 {
1382 if (!m_fetched_help_long)
1383 {
1384 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1385 if (scripter)
1386 {
1387 std::string docstring;
1388 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1389 if (!docstring.empty())
1390 SetHelpLong(docstring);
1391 }
1392 }
1393 return CommandObjectRaw::GetHelpLong();
1394 }
1395
Jim Ingham5a988412012-06-08 21:56:10 +00001396protected:
1397 virtual bool
1398 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001399 {
1400 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1401
1402 Error error;
1403
Jim Ingham70f11f82012-06-27 17:25:36 +00001404 result.SetStatus(eReturnStatusInvalid);
1405
Enrico Granata223383e2011-08-16 23:24:13 +00001406 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1407 raw_command_line,
Enrico Granata0a305db2011-11-07 22:57:04 +00001408 m_synchro,
Enrico Granata223383e2011-08-16 23:24:13 +00001409 result,
Enrico Granata06be0592014-10-01 21:47:29 +00001410 error,
1411 m_exe_ctx) == false)
Enrico Granata223383e2011-08-16 23:24:13 +00001412 {
1413 result.AppendError(error.AsCString());
1414 result.SetStatus(eReturnStatusFailed);
1415 }
1416 else
Jim Ingham70f11f82012-06-27 17:25:36 +00001417 {
1418 // Don't change the status if the command already set it...
1419 if (result.GetStatus() == eReturnStatusInvalid)
1420 {
Daniel Malea9a71a7d2013-07-03 17:58:31 +00001421 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
Jim Ingham70f11f82012-06-27 17:25:36 +00001422 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1423 else
1424 result.SetStatus(eReturnStatusSuccessFinishResult);
1425 }
1426 }
Enrico Granata223383e2011-08-16 23:24:13 +00001427
1428 return result.Succeeded();
1429 }
1430
Enrico Granata223383e2011-08-16 23:24:13 +00001431};
1432
Enrico Granataa9dbf432011-10-17 21:45:27 +00001433//-------------------------------------------------------------------------
1434// CommandObjectCommandsScriptImport
1435//-------------------------------------------------------------------------
1436
Jim Ingham5a988412012-06-08 21:56:10 +00001437class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granataa9dbf432011-10-17 21:45:27 +00001438{
Jim Ingham5a988412012-06-08 21:56:10 +00001439public:
1440 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1441 CommandObjectParsed (interpreter,
1442 "command script import",
1443 "Import a scripting module in LLDB.",
1444 NULL),
1445 m_options(interpreter)
1446 {
1447 CommandArgumentEntry arg1;
1448 CommandArgumentData cmd_arg;
1449
1450 // Define the first (and only) variant of this arg.
1451 cmd_arg.arg_type = eArgTypeFilename;
1452 cmd_arg.arg_repetition = eArgRepeatPlain;
1453
1454 // There is only one variant this argument could be; put it into the argument entry.
1455 arg1.push_back (cmd_arg);
1456
1457 // Push the data for the first argument into the m_arguments vector.
1458 m_arguments.push_back (arg1);
1459 }
1460
1461 ~CommandObjectCommandsScriptImport ()
1462 {
1463 }
1464
Greg Claytonc7bece562013-01-25 18:06:21 +00001465 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +00001466 HandleArgumentCompletion (Args &input,
1467 int &cursor_index,
1468 int &cursor_char_position,
1469 OptionElementVector &opt_element_vector,
1470 int match_start_point,
1471 int max_return_elements,
1472 bool &word_complete,
1473 StringList &matches)
1474 {
1475 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1476 completion_str.erase (cursor_char_position);
1477
1478 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1479 CommandCompletions::eDiskFileCompletion,
1480 completion_str.c_str(),
1481 match_start_point,
1482 max_return_elements,
1483 NULL,
1484 word_complete,
1485 matches);
1486 return matches.GetSize();
1487 }
1488
1489 virtual Options *
1490 GetOptions ()
1491 {
1492 return &m_options;
1493 }
1494
1495protected:
Enrico Granata0a305db2011-11-07 22:57:04 +00001496
1497 class CommandOptions : public Options
1498 {
1499 public:
1500
1501 CommandOptions (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001502 Options (interpreter)
Enrico Granata0a305db2011-11-07 22:57:04 +00001503 {
1504 }
1505
1506 virtual
1507 ~CommandOptions (){}
1508
1509 virtual Error
1510 SetOptionValue (uint32_t option_idx, const char *option_arg)
1511 {
1512 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001513 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata0a305db2011-11-07 22:57:04 +00001514
1515 switch (short_option)
1516 {
1517 case 'r':
1518 m_allow_reload = true;
1519 break;
1520 default:
1521 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1522 break;
1523 }
1524
1525 return error;
1526 }
1527
1528 void
1529 OptionParsingStarting ()
1530 {
Enrico Granatae0c70f12013-05-31 01:03:09 +00001531 m_allow_reload = true;
Enrico Granata0a305db2011-11-07 22:57:04 +00001532 }
1533
1534 const OptionDefinition*
1535 GetDefinitions ()
1536 {
1537 return g_option_table;
1538 }
1539
1540 // Options table: Required for subclasses of Options.
1541
1542 static OptionDefinition g_option_table[];
1543
1544 // Instance variables to hold the values for command options.
1545
1546 bool m_allow_reload;
1547 };
Enrico Granata0a305db2011-11-07 22:57:04 +00001548
Enrico Granataa9dbf432011-10-17 21:45:27 +00001549 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001550 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001551 {
1552
1553 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1554 {
1555 result.AppendError ("only scripting language supported for module importing is currently Python");
1556 result.SetStatus (eReturnStatusFailed);
1557 return false;
1558 }
1559
Jim Ingham5a988412012-06-08 21:56:10 +00001560 size_t argc = command.GetArgumentCount();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001561
1562 if (argc != 1)
1563 {
1564 result.AppendError ("'command script import' requires one argument");
1565 result.SetStatus (eReturnStatusFailed);
1566 return false;
1567 }
1568
Jim Ingham5a988412012-06-08 21:56:10 +00001569 std::string path = command.GetArgumentAtIndex(0);
Enrico Granataa9dbf432011-10-17 21:45:27 +00001570 Error error;
1571
Greg Claytonc9d645d2012-10-18 22:40:37 +00001572 const bool init_session = true;
Enrico Granata078551c2013-05-09 19:33:49 +00001573 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1574 // commands won't ever be recursively invoked, but it's actually possible to craft
1575 // a Python script that does other "command script imports" in __lldb_init_module
1576 // the real fix is to have recursive commands possible with a CommandInvocation object
1577 // separate from the CommandObject itself, so that recursive command invocations
1578 // won't stomp on each other (wrt to execution contents, options, and more)
1579 m_exe_ctx.Clear();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001580 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata0a305db2011-11-07 22:57:04 +00001581 m_options.m_allow_reload,
Greg Claytonc9d645d2012-10-18 22:40:37 +00001582 init_session,
Enrico Granataa9dbf432011-10-17 21:45:27 +00001583 error))
1584 {
1585 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1586 }
1587 else
1588 {
1589 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1590 result.SetStatus (eReturnStatusFailed);
1591 }
1592
1593 return result.Succeeded();
1594 }
Enrico Granata0a305db2011-11-07 22:57:04 +00001595
Jim Ingham5a988412012-06-08 21:56:10 +00001596 CommandOptions m_options;
Enrico Granataa9dbf432011-10-17 21:45:27 +00001597};
Enrico Granata223383e2011-08-16 23:24:13 +00001598
Enrico Granata0a305db2011-11-07 22:57:04 +00001599OptionDefinition
1600CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1601{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001602 { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, NULL, 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."},
1603 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Enrico Granata0a305db2011-11-07 22:57:04 +00001604};
1605
1606
Enrico Granata223383e2011-08-16 23:24:13 +00001607//-------------------------------------------------------------------------
1608// CommandObjectCommandsScriptAdd
1609//-------------------------------------------------------------------------
1610
Greg Clayton44d93782014-01-27 23:43:24 +00001611class CommandObjectCommandsScriptAdd :
1612 public CommandObjectParsed,
1613 public IOHandlerDelegateMultiline
Enrico Granata223383e2011-08-16 23:24:13 +00001614{
Jim Ingham5a988412012-06-08 21:56:10 +00001615public:
1616 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1617 CommandObjectParsed (interpreter,
1618 "command script add",
1619 "Add a scripted function as an LLDB command.",
1620 NULL),
Greg Claytonc3d874a2014-05-08 16:59:00 +00001621 IOHandlerDelegateMultiline ("DONE"),
Jim Ingham5a988412012-06-08 21:56:10 +00001622 m_options (interpreter)
1623 {
1624 CommandArgumentEntry arg1;
1625 CommandArgumentData cmd_arg;
1626
1627 // Define the first (and only) variant of this arg.
1628 cmd_arg.arg_type = eArgTypeCommandName;
1629 cmd_arg.arg_repetition = eArgRepeatPlain;
1630
1631 // There is only one variant this argument could be; put it into the argument entry.
1632 arg1.push_back (cmd_arg);
1633
1634 // Push the data for the first argument into the m_arguments vector.
1635 m_arguments.push_back (arg1);
1636 }
1637
1638 ~CommandObjectCommandsScriptAdd ()
1639 {
1640 }
1641
1642 virtual Options *
1643 GetOptions ()
1644 {
1645 return &m_options;
1646 }
1647
1648protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001649
1650 class CommandOptions : public Options
1651 {
1652 public:
1653
1654 CommandOptions (CommandInterpreter &interpreter) :
Greg Clayton44d93782014-01-27 23:43:24 +00001655 Options (interpreter)
Enrico Granata223383e2011-08-16 23:24:13 +00001656 {
1657 }
1658
1659 virtual
1660 ~CommandOptions (){}
1661
1662 virtual Error
1663 SetOptionValue (uint32_t option_idx, const char *option_arg)
1664 {
1665 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001666 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata223383e2011-08-16 23:24:13 +00001667
1668 switch (short_option)
1669 {
1670 case 'f':
Enrico Granata735152e2014-09-15 17:52:44 +00001671 if (option_arg)
1672 m_funct_name.assign(option_arg);
1673 break;
1674 case 'h':
1675 if (option_arg)
1676 m_short_help.assign(option_arg);
Enrico Granata223383e2011-08-16 23:24:13 +00001677 break;
Enrico Granata0a305db2011-11-07 22:57:04 +00001678 case 's':
Greg Clayton44d93782014-01-27 23:43:24 +00001679 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
Enrico Granata0a305db2011-11-07 22:57:04 +00001680 if (!error.Success())
1681 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1682 break;
Enrico Granata223383e2011-08-16 23:24:13 +00001683 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001684 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata223383e2011-08-16 23:24:13 +00001685 break;
1686 }
1687
1688 return error;
1689 }
1690
1691 void
1692 OptionParsingStarting ()
1693 {
Enrico Granata735152e2014-09-15 17:52:44 +00001694 m_funct_name.clear();
1695 m_short_help.clear();
Greg Clayton44d93782014-01-27 23:43:24 +00001696 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001697 }
1698
1699 const OptionDefinition*
1700 GetDefinitions ()
1701 {
1702 return g_option_table;
1703 }
1704
1705 // Options table: Required for subclasses of Options.
1706
1707 static OptionDefinition g_option_table[];
1708
1709 // Instance variables to hold the values for command options.
1710
1711 std::string m_funct_name;
Enrico Granata735152e2014-09-15 17:52:44 +00001712 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00001713 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001714 };
Jim Ingham5a988412012-06-08 21:56:10 +00001715
Greg Clayton44d93782014-01-27 23:43:24 +00001716 virtual void
1717 IOHandlerActivated (IOHandler &io_handler)
Enrico Granata223383e2011-08-16 23:24:13 +00001718 {
Greg Clayton44d93782014-01-27 23:43:24 +00001719 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1720 if (output_sp)
Enrico Granata223383e2011-08-16 23:24:13 +00001721 {
Greg Clayton44d93782014-01-27 23:43:24 +00001722 output_sp->PutCString(g_python_command_instructions);
1723 output_sp->Flush();
Enrico Granata223383e2011-08-16 23:24:13 +00001724 }
Greg Clayton44d93782014-01-27 23:43:24 +00001725 }
Enrico Granata223383e2011-08-16 23:24:13 +00001726
Greg Clayton44d93782014-01-27 23:43:24 +00001727
1728 virtual void
1729 IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1730 {
1731 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1732
1733 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1734 if (interpreter)
1735 {
1736
1737 StringList lines;
1738 lines.SplitIntoLines(data);
1739 if (lines.GetSize() > 0)
1740 {
1741 std::string funct_name_str;
1742 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1743 {
1744 if (funct_name_str.empty())
1745 {
1746 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1747 error_sp->Flush();
1748 }
1749 else
1750 {
1751 // everything should be fine now, let's add this alias
1752
1753 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1754 m_cmd_name,
1755 funct_name_str.c_str(),
Enrico Granata735152e2014-09-15 17:52:44 +00001756 m_short_help,
Greg Clayton44d93782014-01-27 23:43:24 +00001757 m_synchronicity));
1758
1759 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1760 {
1761 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
1762 error_sp->Flush();
1763 }
1764 }
1765 }
1766 else
1767 {
1768 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
1769 error_sp->Flush();
1770 }
1771 }
1772 else
1773 {
1774 error_sp->Printf ("error: empty function, didn't add python command.\n");
1775 error_sp->Flush();
1776 }
1777 }
1778 else
1779 {
1780 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
1781 error_sp->Flush();
1782 }
1783
1784 io_handler.SetIsDone(true);
1785
1786
1787 }
1788
Jim Ingham5a988412012-06-08 21:56:10 +00001789protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001790 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001791 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001792 {
Enrico Granata99f0b8f2011-08-17 01:30:04 +00001793
1794 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1795 {
1796 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1797 result.SetStatus (eReturnStatusFailed);
1798 return false;
1799 }
1800
Jim Ingham5a988412012-06-08 21:56:10 +00001801 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001802
1803 if (argc != 1)
1804 {
1805 result.AppendError ("'command script add' requires one argument");
1806 result.SetStatus (eReturnStatusFailed);
1807 return false;
1808 }
1809
Enrico Granata735152e2014-09-15 17:52:44 +00001810 // Store the options in case we get multi-line input
Greg Clayton44d93782014-01-27 23:43:24 +00001811 m_cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata735152e2014-09-15 17:52:44 +00001812 m_short_help.assign(m_options.m_short_help);
Greg Clayton44d93782014-01-27 23:43:24 +00001813 m_synchronicity = m_options.m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001814
1815 if (m_options.m_funct_name.empty())
1816 {
Greg Clayton44d93782014-01-27 23:43:24 +00001817 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
1818 *this, // IOHandlerDelegate
1819 true, // Run IOHandler in async mode
1820 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
Enrico Granata223383e2011-08-16 23:24:13 +00001821 }
1822 else
1823 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001824 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
Greg Clayton44d93782014-01-27 23:43:24 +00001825 m_cmd_name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001826 m_options.m_funct_name,
Enrico Granata735152e2014-09-15 17:52:44 +00001827 m_options.m_short_help,
Greg Clayton44d93782014-01-27 23:43:24 +00001828 m_synchronicity));
1829 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
Enrico Granata223383e2011-08-16 23:24:13 +00001830 {
1831 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1832 }
1833 else
1834 {
1835 result.AppendError("cannot add command");
1836 result.SetStatus (eReturnStatusFailed);
1837 }
1838 }
1839
1840 return result.Succeeded();
1841
1842 }
Jim Ingham5a988412012-06-08 21:56:10 +00001843
1844 CommandOptions m_options;
Greg Clayton44d93782014-01-27 23:43:24 +00001845 std::string m_cmd_name;
Enrico Granata735152e2014-09-15 17:52:44 +00001846 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00001847 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001848};
1849
Enrico Granata0a305db2011-11-07 22:57:04 +00001850static OptionEnumValueElement g_script_synchro_type[] =
1851{
1852 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1853 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1854 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1855 { 0, NULL, NULL }
1856};
1857
Enrico Granata223383e2011-08-16 23:24:13 +00001858OptionDefinition
1859CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1860{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001861 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
Enrico Granata735152e2014-09-15 17:52:44 +00001862 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
Zachary Turnerd37221d2014-07-09 16:31:49 +00001863 { LLDB_OPT_SET_1, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
1864 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Enrico Granata223383e2011-08-16 23:24:13 +00001865};
1866
1867//-------------------------------------------------------------------------
1868// CommandObjectCommandsScriptList
1869//-------------------------------------------------------------------------
1870
Jim Ingham5a988412012-06-08 21:56:10 +00001871class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001872{
1873private:
Enrico Granata0a305db2011-11-07 22:57:04 +00001874
Enrico Granata223383e2011-08-16 23:24:13 +00001875public:
1876 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001877 CommandObjectParsed (interpreter,
Enrico Granata223383e2011-08-16 23:24:13 +00001878 "command script list",
1879 "List defined scripted commands.",
1880 NULL)
1881 {
1882 }
1883
1884 ~CommandObjectCommandsScriptList ()
1885 {
1886 }
1887
1888 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001889 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001890 {
1891
1892 m_interpreter.GetHelp(result,
1893 CommandInterpreter::eCommandTypesUserDef);
1894
1895 result.SetStatus (eReturnStatusSuccessFinishResult);
1896
1897 return true;
1898
1899
1900 }
1901};
1902
1903//-------------------------------------------------------------------------
1904// CommandObjectCommandsScriptClear
1905//-------------------------------------------------------------------------
1906
Jim Ingham5a988412012-06-08 21:56:10 +00001907class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001908{
1909private:
1910
1911public:
1912 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001913 CommandObjectParsed (interpreter,
1914 "command script clear",
1915 "Delete all scripted commands.",
1916 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00001917 {
1918 }
1919
1920 ~CommandObjectCommandsScriptClear ()
1921 {
1922 }
1923
Jim Ingham5a988412012-06-08 21:56:10 +00001924protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001925 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001926 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001927 {
1928
1929 m_interpreter.RemoveAllUser();
1930
1931 result.SetStatus (eReturnStatusSuccessFinishResult);
1932
1933 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00001934 }
1935};
1936
1937//-------------------------------------------------------------------------
1938// CommandObjectCommandsScriptDelete
1939//-------------------------------------------------------------------------
1940
Jim Ingham5a988412012-06-08 21:56:10 +00001941class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001942{
Enrico Granata223383e2011-08-16 23:24:13 +00001943public:
1944 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001945 CommandObjectParsed (interpreter,
1946 "command script delete",
1947 "Delete a scripted command.",
1948 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00001949 {
1950 CommandArgumentEntry arg1;
1951 CommandArgumentData cmd_arg;
1952
1953 // Define the first (and only) variant of this arg.
1954 cmd_arg.arg_type = eArgTypeCommandName;
1955 cmd_arg.arg_repetition = eArgRepeatPlain;
1956
1957 // There is only one variant this argument could be; put it into the argument entry.
1958 arg1.push_back (cmd_arg);
1959
1960 // Push the data for the first argument into the m_arguments vector.
1961 m_arguments.push_back (arg1);
1962 }
1963
1964 ~CommandObjectCommandsScriptDelete ()
1965 {
1966 }
1967
Jim Ingham5a988412012-06-08 21:56:10 +00001968protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001969 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001970 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001971 {
1972
Jim Ingham5a988412012-06-08 21:56:10 +00001973 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001974
1975 if (argc != 1)
1976 {
1977 result.AppendError ("'command script delete' requires one argument");
1978 result.SetStatus (eReturnStatusFailed);
1979 return false;
1980 }
1981
Jim Ingham5a988412012-06-08 21:56:10 +00001982 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00001983
1984 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1985 {
1986 m_interpreter.RemoveUser(cmd_name);
1987 result.SetStatus (eReturnStatusSuccessFinishResult);
1988 }
1989 else
1990 {
1991 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1992 result.SetStatus (eReturnStatusFailed);
1993 }
1994
1995 return result.Succeeded();
1996
1997 }
1998};
1999
2000#pragma mark CommandObjectMultiwordCommandsScript
2001
2002//-------------------------------------------------------------------------
2003// CommandObjectMultiwordCommandsScript
2004//-------------------------------------------------------------------------
2005
2006class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2007{
2008public:
2009 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2010 CommandObjectMultiword (interpreter,
2011 "command script",
2012 "A set of commands for managing or customizing script commands.",
2013 "command script <subcommand> [<subcommand-options>]")
2014 {
Greg Claytonb5472782015-01-09 19:08:20 +00002015 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2016 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2017 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002018 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002019 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002020 }
2021
2022 ~CommandObjectMultiwordCommandsScript ()
2023 {
2024 }
2025
2026};
2027
2028
Jim Inghamebc09c32010-07-07 03:36:20 +00002029#pragma mark CommandObjectMultiwordCommands
2030
2031//-------------------------------------------------------------------------
2032// CommandObjectMultiwordCommands
2033//-------------------------------------------------------------------------
2034
2035CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002036 CommandObjectMultiword (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002037 "command",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002038 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002039 "command <subcommand> [<subcommand-options>]")
Jim Inghamebc09c32010-07-07 03:36:20 +00002040{
Greg Claytona7015092010-09-18 01:14:36 +00002041 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2042 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2043 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002044 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
Greg Claytonde164aa2011-04-20 16:37:46 +00002045 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002046 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2047 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Inghamebc09c32010-07-07 03:36:20 +00002048}
2049
2050CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
2051{
2052}
2053