blob: febbfa873836f9deddee16292eda10b1b5fc8961 [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 Granata9fe00e52015-03-13 02:20:41 +00001433class CommandObjectScriptingObject : public CommandObjectRaw
1434{
1435private:
1436 lldb::ScriptInterpreterObjectSP m_cmd_obj_sp;
1437 ScriptedCommandSynchronicity m_synchro;
1438
1439public:
1440
1441 CommandObjectScriptingObject (CommandInterpreter &interpreter,
1442 std::string name,
1443 lldb::ScriptInterpreterObjectSP cmd_obj_sp,
1444 ScriptedCommandSynchronicity synch) :
1445 CommandObjectRaw (interpreter,
1446 name.c_str(),
1447 NULL,
1448 NULL),
1449 m_cmd_obj_sp(cmd_obj_sp),
1450 m_synchro(synch)
1451 {
1452 StreamString stream;
1453 stream.Printf("For more information run 'help %s'",name.c_str());
1454 SetHelp(stream.GetData());
1455 }
1456
1457 virtual
1458 ~CommandObjectScriptingObject ()
1459 {
1460 }
1461
1462 virtual bool
1463 IsRemovable () const
1464 {
1465 return true;
1466 }
1467
1468 lldb::ScriptInterpreterObjectSP
1469 GetImplementingObject ()
1470 {
1471 return m_cmd_obj_sp;
1472 }
1473
1474 ScriptedCommandSynchronicity
1475 GetSynchronicity ()
1476 {
1477 return m_synchro;
1478 }
1479
1480 virtual const char *
1481 GetHelpLong ()
1482 {
1483 return CommandObjectRaw::GetHelpLong();
1484 }
1485
1486protected:
1487 virtual bool
1488 DoExecute (const char *raw_command_line, CommandReturnObject &result)
1489 {
1490 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1491
1492 Error error;
1493
1494 result.SetStatus(eReturnStatusInvalid);
1495
1496 if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
1497 raw_command_line,
1498 m_synchro,
1499 result,
1500 error,
1501 m_exe_ctx) == false)
1502 {
1503 result.AppendError(error.AsCString());
1504 result.SetStatus(eReturnStatusFailed);
1505 }
1506 else
1507 {
1508 // Don't change the status if the command already set it...
1509 if (result.GetStatus() == eReturnStatusInvalid)
1510 {
1511 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1512 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1513 else
1514 result.SetStatus(eReturnStatusSuccessFinishResult);
1515 }
1516 }
1517
1518 return result.Succeeded();
1519 }
1520
1521};
1522
Enrico Granataa9dbf432011-10-17 21:45:27 +00001523//-------------------------------------------------------------------------
1524// CommandObjectCommandsScriptImport
1525//-------------------------------------------------------------------------
1526
Jim Ingham5a988412012-06-08 21:56:10 +00001527class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granataa9dbf432011-10-17 21:45:27 +00001528{
Jim Ingham5a988412012-06-08 21:56:10 +00001529public:
1530 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1531 CommandObjectParsed (interpreter,
1532 "command script import",
1533 "Import a scripting module in LLDB.",
1534 NULL),
1535 m_options(interpreter)
1536 {
1537 CommandArgumentEntry arg1;
1538 CommandArgumentData cmd_arg;
1539
1540 // Define the first (and only) variant of this arg.
1541 cmd_arg.arg_type = eArgTypeFilename;
1542 cmd_arg.arg_repetition = eArgRepeatPlain;
1543
1544 // There is only one variant this argument could be; put it into the argument entry.
1545 arg1.push_back (cmd_arg);
1546
1547 // Push the data for the first argument into the m_arguments vector.
1548 m_arguments.push_back (arg1);
1549 }
1550
1551 ~CommandObjectCommandsScriptImport ()
1552 {
1553 }
1554
Greg Claytonc7bece562013-01-25 18:06:21 +00001555 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +00001556 HandleArgumentCompletion (Args &input,
1557 int &cursor_index,
1558 int &cursor_char_position,
1559 OptionElementVector &opt_element_vector,
1560 int match_start_point,
1561 int max_return_elements,
1562 bool &word_complete,
1563 StringList &matches)
1564 {
1565 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1566 completion_str.erase (cursor_char_position);
1567
1568 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1569 CommandCompletions::eDiskFileCompletion,
1570 completion_str.c_str(),
1571 match_start_point,
1572 max_return_elements,
1573 NULL,
1574 word_complete,
1575 matches);
1576 return matches.GetSize();
1577 }
1578
1579 virtual Options *
1580 GetOptions ()
1581 {
1582 return &m_options;
1583 }
1584
1585protected:
Enrico Granata0a305db2011-11-07 22:57:04 +00001586
1587 class CommandOptions : public Options
1588 {
1589 public:
1590
1591 CommandOptions (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001592 Options (interpreter)
Enrico Granata0a305db2011-11-07 22:57:04 +00001593 {
1594 }
1595
1596 virtual
1597 ~CommandOptions (){}
1598
1599 virtual Error
1600 SetOptionValue (uint32_t option_idx, const char *option_arg)
1601 {
1602 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001603 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata0a305db2011-11-07 22:57:04 +00001604
1605 switch (short_option)
1606 {
1607 case 'r':
1608 m_allow_reload = true;
1609 break;
1610 default:
1611 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1612 break;
1613 }
1614
1615 return error;
1616 }
1617
1618 void
1619 OptionParsingStarting ()
1620 {
Enrico Granatae0c70f12013-05-31 01:03:09 +00001621 m_allow_reload = true;
Enrico Granata0a305db2011-11-07 22:57:04 +00001622 }
1623
1624 const OptionDefinition*
1625 GetDefinitions ()
1626 {
1627 return g_option_table;
1628 }
1629
1630 // Options table: Required for subclasses of Options.
1631
1632 static OptionDefinition g_option_table[];
1633
1634 // Instance variables to hold the values for command options.
1635
1636 bool m_allow_reload;
1637 };
Enrico Granata0a305db2011-11-07 22:57:04 +00001638
Enrico Granataa9dbf432011-10-17 21:45:27 +00001639 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001640 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001641 {
1642
1643 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1644 {
1645 result.AppendError ("only scripting language supported for module importing is currently Python");
1646 result.SetStatus (eReturnStatusFailed);
1647 return false;
1648 }
1649
Jim Ingham5a988412012-06-08 21:56:10 +00001650 size_t argc = command.GetArgumentCount();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001651
1652 if (argc != 1)
1653 {
1654 result.AppendError ("'command script import' requires one argument");
1655 result.SetStatus (eReturnStatusFailed);
1656 return false;
1657 }
1658
Jim Ingham5a988412012-06-08 21:56:10 +00001659 std::string path = command.GetArgumentAtIndex(0);
Enrico Granataa9dbf432011-10-17 21:45:27 +00001660 Error error;
1661
Greg Claytonc9d645d2012-10-18 22:40:37 +00001662 const bool init_session = true;
Enrico Granata078551c2013-05-09 19:33:49 +00001663 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1664 // commands won't ever be recursively invoked, but it's actually possible to craft
1665 // a Python script that does other "command script imports" in __lldb_init_module
1666 // the real fix is to have recursive commands possible with a CommandInvocation object
1667 // separate from the CommandObject itself, so that recursive command invocations
1668 // won't stomp on each other (wrt to execution contents, options, and more)
1669 m_exe_ctx.Clear();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001670 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata0a305db2011-11-07 22:57:04 +00001671 m_options.m_allow_reload,
Greg Claytonc9d645d2012-10-18 22:40:37 +00001672 init_session,
Enrico Granataa9dbf432011-10-17 21:45:27 +00001673 error))
1674 {
1675 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1676 }
1677 else
1678 {
1679 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1680 result.SetStatus (eReturnStatusFailed);
1681 }
1682
1683 return result.Succeeded();
1684 }
Enrico Granata0a305db2011-11-07 22:57:04 +00001685
Jim Ingham5a988412012-06-08 21:56:10 +00001686 CommandOptions m_options;
Enrico Granataa9dbf432011-10-17 21:45:27 +00001687};
Enrico Granata223383e2011-08-16 23:24:13 +00001688
Enrico Granata0a305db2011-11-07 22:57:04 +00001689OptionDefinition
1690CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1691{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001692 { 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."},
1693 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Enrico Granata0a305db2011-11-07 22:57:04 +00001694};
1695
1696
Enrico Granata223383e2011-08-16 23:24:13 +00001697//-------------------------------------------------------------------------
1698// CommandObjectCommandsScriptAdd
1699//-------------------------------------------------------------------------
1700
Greg Clayton44d93782014-01-27 23:43:24 +00001701class CommandObjectCommandsScriptAdd :
1702 public CommandObjectParsed,
1703 public IOHandlerDelegateMultiline
Enrico Granata223383e2011-08-16 23:24:13 +00001704{
Jim Ingham5a988412012-06-08 21:56:10 +00001705public:
1706 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1707 CommandObjectParsed (interpreter,
1708 "command script add",
1709 "Add a scripted function as an LLDB command.",
1710 NULL),
Greg Claytonc3d874a2014-05-08 16:59:00 +00001711 IOHandlerDelegateMultiline ("DONE"),
Jim Ingham5a988412012-06-08 21:56:10 +00001712 m_options (interpreter)
1713 {
1714 CommandArgumentEntry arg1;
1715 CommandArgumentData cmd_arg;
1716
1717 // Define the first (and only) variant of this arg.
1718 cmd_arg.arg_type = eArgTypeCommandName;
1719 cmd_arg.arg_repetition = eArgRepeatPlain;
1720
1721 // There is only one variant this argument could be; put it into the argument entry.
1722 arg1.push_back (cmd_arg);
1723
1724 // Push the data for the first argument into the m_arguments vector.
1725 m_arguments.push_back (arg1);
1726 }
1727
1728 ~CommandObjectCommandsScriptAdd ()
1729 {
1730 }
1731
1732 virtual Options *
1733 GetOptions ()
1734 {
1735 return &m_options;
1736 }
1737
1738protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001739
1740 class CommandOptions : public Options
1741 {
1742 public:
1743
1744 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata9fe00e52015-03-13 02:20:41 +00001745 Options (interpreter),
1746 m_class_name(),
1747 m_funct_name(),
1748 m_short_help(),
1749 m_synchronicity(eScriptedCommandSynchronicitySynchronous)
Enrico Granata223383e2011-08-16 23:24:13 +00001750 {
1751 }
1752
1753 virtual
1754 ~CommandOptions (){}
1755
1756 virtual Error
1757 SetOptionValue (uint32_t option_idx, const char *option_arg)
1758 {
1759 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001760 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata223383e2011-08-16 23:24:13 +00001761
1762 switch (short_option)
1763 {
1764 case 'f':
Enrico Granata735152e2014-09-15 17:52:44 +00001765 if (option_arg)
1766 m_funct_name.assign(option_arg);
1767 break;
Enrico Granata9fe00e52015-03-13 02:20:41 +00001768 case 'c':
1769 if (option_arg)
1770 m_class_name.assign(option_arg);
1771 break;
Enrico Granata735152e2014-09-15 17:52:44 +00001772 case 'h':
1773 if (option_arg)
1774 m_short_help.assign(option_arg);
Enrico Granata223383e2011-08-16 23:24:13 +00001775 break;
Enrico Granata0a305db2011-11-07 22:57:04 +00001776 case 's':
Greg Clayton44d93782014-01-27 23:43:24 +00001777 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
Enrico Granata0a305db2011-11-07 22:57:04 +00001778 if (!error.Success())
1779 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1780 break;
Enrico Granata223383e2011-08-16 23:24:13 +00001781 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001782 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata223383e2011-08-16 23:24:13 +00001783 break;
1784 }
1785
1786 return error;
1787 }
1788
1789 void
1790 OptionParsingStarting ()
1791 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001792 m_class_name.clear();
Enrico Granata735152e2014-09-15 17:52:44 +00001793 m_funct_name.clear();
1794 m_short_help.clear();
Greg Clayton44d93782014-01-27 23:43:24 +00001795 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001796 }
1797
1798 const OptionDefinition*
1799 GetDefinitions ()
1800 {
1801 return g_option_table;
1802 }
1803
1804 // Options table: Required for subclasses of Options.
1805
1806 static OptionDefinition g_option_table[];
1807
1808 // Instance variables to hold the values for command options.
1809
Enrico Granata9fe00e52015-03-13 02:20:41 +00001810 std::string m_class_name;
Enrico Granata223383e2011-08-16 23:24:13 +00001811 std::string m_funct_name;
Enrico Granata735152e2014-09-15 17:52:44 +00001812 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00001813 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001814 };
Jim Ingham5a988412012-06-08 21:56:10 +00001815
Greg Clayton44d93782014-01-27 23:43:24 +00001816 virtual void
1817 IOHandlerActivated (IOHandler &io_handler)
Enrico Granata223383e2011-08-16 23:24:13 +00001818 {
Greg Clayton44d93782014-01-27 23:43:24 +00001819 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1820 if (output_sp)
Enrico Granata223383e2011-08-16 23:24:13 +00001821 {
Greg Clayton44d93782014-01-27 23:43:24 +00001822 output_sp->PutCString(g_python_command_instructions);
1823 output_sp->Flush();
Enrico Granata223383e2011-08-16 23:24:13 +00001824 }
Greg Clayton44d93782014-01-27 23:43:24 +00001825 }
Enrico Granata223383e2011-08-16 23:24:13 +00001826
Greg Clayton44d93782014-01-27 23:43:24 +00001827
1828 virtual void
1829 IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1830 {
1831 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1832
1833 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1834 if (interpreter)
1835 {
1836
1837 StringList lines;
1838 lines.SplitIntoLines(data);
1839 if (lines.GetSize() > 0)
1840 {
1841 std::string funct_name_str;
1842 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1843 {
1844 if (funct_name_str.empty())
1845 {
1846 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1847 error_sp->Flush();
1848 }
1849 else
1850 {
1851 // everything should be fine now, let's add this alias
1852
1853 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1854 m_cmd_name,
1855 funct_name_str.c_str(),
Enrico Granata735152e2014-09-15 17:52:44 +00001856 m_short_help,
Greg Clayton44d93782014-01-27 23:43:24 +00001857 m_synchronicity));
1858
1859 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1860 {
1861 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
1862 error_sp->Flush();
1863 }
1864 }
1865 }
1866 else
1867 {
1868 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
1869 error_sp->Flush();
1870 }
1871 }
1872 else
1873 {
1874 error_sp->Printf ("error: empty function, didn't add python command.\n");
1875 error_sp->Flush();
1876 }
1877 }
1878 else
1879 {
1880 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
1881 error_sp->Flush();
1882 }
1883
1884 io_handler.SetIsDone(true);
1885
1886
1887 }
1888
Jim Ingham5a988412012-06-08 21:56:10 +00001889protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001890 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001891 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001892 {
Enrico Granata99f0b8f2011-08-17 01:30:04 +00001893
1894 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1895 {
1896 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1897 result.SetStatus (eReturnStatusFailed);
1898 return false;
1899 }
1900
Jim Ingham5a988412012-06-08 21:56:10 +00001901 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001902
1903 if (argc != 1)
1904 {
1905 result.AppendError ("'command script add' requires one argument");
1906 result.SetStatus (eReturnStatusFailed);
1907 return false;
1908 }
1909
Enrico Granata735152e2014-09-15 17:52:44 +00001910 // Store the options in case we get multi-line input
Greg Clayton44d93782014-01-27 23:43:24 +00001911 m_cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata735152e2014-09-15 17:52:44 +00001912 m_short_help.assign(m_options.m_short_help);
Greg Clayton44d93782014-01-27 23:43:24 +00001913 m_synchronicity = m_options.m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001914
Enrico Granata9fe00e52015-03-13 02:20:41 +00001915 if (m_options.m_class_name.empty())
Enrico Granata223383e2011-08-16 23:24:13 +00001916 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001917 if (m_options.m_funct_name.empty())
1918 {
1919 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
1920 *this, // IOHandlerDelegate
1921 true, // Run IOHandler in async mode
1922 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1923 }
1924 else
1925 {
1926 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1927 m_cmd_name,
1928 m_options.m_funct_name,
1929 m_options.m_short_help,
1930 m_synchronicity));
1931 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
1932 {
1933 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1934 }
1935 else
1936 {
1937 result.AppendError("cannot add command");
1938 result.SetStatus (eReturnStatusFailed);
1939 }
1940 }
Enrico Granata223383e2011-08-16 23:24:13 +00001941 }
1942 else
1943 {
Enrico Granata9fe00e52015-03-13 02:20:41 +00001944 ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
1945 if (!interpreter)
1946 {
1947 result.AppendError("cannot find ScriptInterpreter");
1948 result.SetStatus(eReturnStatusFailed);
1949 return false;
1950 }
1951
1952 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
1953 if (!cmd_obj_sp)
1954 {
1955 result.AppendError("cannot create helper object");
1956 result.SetStatus(eReturnStatusFailed);
1957 return false;
1958 }
1959
1960 CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
1961 m_cmd_name,
1962 cmd_obj_sp,
1963 m_synchronicity));
Greg Clayton44d93782014-01-27 23:43:24 +00001964 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
Enrico Granata223383e2011-08-16 23:24:13 +00001965 {
1966 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1967 }
1968 else
1969 {
1970 result.AppendError("cannot add command");
1971 result.SetStatus (eReturnStatusFailed);
1972 }
1973 }
1974
1975 return result.Succeeded();
1976
1977 }
Jim Ingham5a988412012-06-08 21:56:10 +00001978
1979 CommandOptions m_options;
Greg Clayton44d93782014-01-27 23:43:24 +00001980 std::string m_cmd_name;
Enrico Granata735152e2014-09-15 17:52:44 +00001981 std::string m_short_help;
Greg Clayton44d93782014-01-27 23:43:24 +00001982 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001983};
1984
Enrico Granata0a305db2011-11-07 22:57:04 +00001985static OptionEnumValueElement g_script_synchro_type[] =
1986{
1987 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1988 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1989 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1990 { 0, NULL, NULL }
1991};
1992
Enrico Granata223383e2011-08-16 23:24:13 +00001993OptionDefinition
1994CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1995{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001996 { 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 Granata9fe00e52015-03-13 02:20:41 +00001997 { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."},
1998 { LLDB_OPT_SET_ALL, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
1999 { LLDB_OPT_SET_ALL, 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."},
Zachary Turnerd37221d2014-07-09 16:31:49 +00002000 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
Enrico Granata223383e2011-08-16 23:24:13 +00002001};
2002
2003//-------------------------------------------------------------------------
2004// CommandObjectCommandsScriptList
2005//-------------------------------------------------------------------------
2006
Jim Ingham5a988412012-06-08 21:56:10 +00002007class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002008{
2009private:
Enrico Granata0a305db2011-11-07 22:57:04 +00002010
Enrico Granata223383e2011-08-16 23:24:13 +00002011public:
2012 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002013 CommandObjectParsed (interpreter,
Enrico Granata223383e2011-08-16 23:24:13 +00002014 "command script list",
2015 "List defined scripted commands.",
2016 NULL)
2017 {
2018 }
2019
2020 ~CommandObjectCommandsScriptList ()
2021 {
2022 }
2023
2024 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002025 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002026 {
2027
2028 m_interpreter.GetHelp(result,
2029 CommandInterpreter::eCommandTypesUserDef);
2030
2031 result.SetStatus (eReturnStatusSuccessFinishResult);
2032
2033 return true;
2034
2035
2036 }
2037};
2038
2039//-------------------------------------------------------------------------
2040// CommandObjectCommandsScriptClear
2041//-------------------------------------------------------------------------
2042
Jim Ingham5a988412012-06-08 21:56:10 +00002043class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002044{
2045private:
2046
2047public:
2048 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002049 CommandObjectParsed (interpreter,
2050 "command script clear",
2051 "Delete all scripted commands.",
2052 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00002053 {
2054 }
2055
2056 ~CommandObjectCommandsScriptClear ()
2057 {
2058 }
2059
Jim Ingham5a988412012-06-08 21:56:10 +00002060protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002061 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002062 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002063 {
2064
2065 m_interpreter.RemoveAllUser();
2066
2067 result.SetStatus (eReturnStatusSuccessFinishResult);
2068
2069 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00002070 }
2071};
2072
2073//-------------------------------------------------------------------------
2074// CommandObjectCommandsScriptDelete
2075//-------------------------------------------------------------------------
2076
Jim Ingham5a988412012-06-08 21:56:10 +00002077class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00002078{
Enrico Granata223383e2011-08-16 23:24:13 +00002079public:
2080 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00002081 CommandObjectParsed (interpreter,
2082 "command script delete",
2083 "Delete a scripted command.",
2084 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00002085 {
2086 CommandArgumentEntry arg1;
2087 CommandArgumentData cmd_arg;
2088
2089 // Define the first (and only) variant of this arg.
2090 cmd_arg.arg_type = eArgTypeCommandName;
2091 cmd_arg.arg_repetition = eArgRepeatPlain;
2092
2093 // There is only one variant this argument could be; put it into the argument entry.
2094 arg1.push_back (cmd_arg);
2095
2096 // Push the data for the first argument into the m_arguments vector.
2097 m_arguments.push_back (arg1);
2098 }
2099
2100 ~CommandObjectCommandsScriptDelete ()
2101 {
2102 }
2103
Jim Ingham5a988412012-06-08 21:56:10 +00002104protected:
Enrico Granata223383e2011-08-16 23:24:13 +00002105 bool
Jim Ingham5a988412012-06-08 21:56:10 +00002106 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00002107 {
2108
Jim Ingham5a988412012-06-08 21:56:10 +00002109 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00002110
2111 if (argc != 1)
2112 {
2113 result.AppendError ("'command script delete' requires one argument");
2114 result.SetStatus (eReturnStatusFailed);
2115 return false;
2116 }
2117
Jim Ingham5a988412012-06-08 21:56:10 +00002118 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00002119
2120 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2121 {
2122 m_interpreter.RemoveUser(cmd_name);
2123 result.SetStatus (eReturnStatusSuccessFinishResult);
2124 }
2125 else
2126 {
2127 result.AppendErrorWithFormat ("command %s not found", cmd_name);
2128 result.SetStatus (eReturnStatusFailed);
2129 }
2130
2131 return result.Succeeded();
2132
2133 }
2134};
2135
2136#pragma mark CommandObjectMultiwordCommandsScript
2137
2138//-------------------------------------------------------------------------
2139// CommandObjectMultiwordCommandsScript
2140//-------------------------------------------------------------------------
2141
2142class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2143{
2144public:
2145 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2146 CommandObjectMultiword (interpreter,
2147 "command script",
2148 "A set of commands for managing or customizing script commands.",
2149 "command script <subcommand> [<subcommand-options>]")
2150 {
Greg Claytonb5472782015-01-09 19:08:20 +00002151 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2152 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2153 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002154 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002155 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00002156 }
2157
2158 ~CommandObjectMultiwordCommandsScript ()
2159 {
2160 }
2161
2162};
2163
2164
Jim Inghamebc09c32010-07-07 03:36:20 +00002165#pragma mark CommandObjectMultiwordCommands
2166
2167//-------------------------------------------------------------------------
2168// CommandObjectMultiwordCommands
2169//-------------------------------------------------------------------------
2170
2171CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00002172 CommandObjectMultiword (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002173 "command",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00002174 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00002175 "command <subcommand> [<subcommand-options>]")
Jim Inghamebc09c32010-07-07 03:36:20 +00002176{
Greg Claytona7015092010-09-18 01:14:36 +00002177 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2178 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2179 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002180 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
Greg Claytonde164aa2011-04-20 16:37:46 +00002181 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Greg Claytonb5472782015-01-09 19:08:20 +00002182 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2183 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Inghamebc09c32010-07-07 03:36:20 +00002184}
2185
2186CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
2187{
2188}
2189