blob: c881a6feea6b5b432ffae9430c3fc814dd303f8f [file] [log] [blame]
Jim Ingham767af882010-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
10#include "CommandObjectCommands.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
Greg Clayton40e48242011-04-20 22:55:21 +000015#include "llvm/ADT/StringRef.h"
16
Jim Ingham767af882010-07-07 03:36:20 +000017// Project includes
Jim Ingham767af882010-07-07 03:36:20 +000018#include "lldb/Core/Debugger.h"
Greg Claytond12aeab2011-04-20 16:37:46 +000019#include "lldb/Core/InputReader.h"
Enrico Granatac2a28252011-08-16 16:49:25 +000020#include "lldb/Core/InputReaderEZ.h"
21#include "lldb/Core/StringList.h"
Greg Claytond12aeab2011-04-20 16:37:46 +000022#include "lldb/Interpreter/Args.h"
Jim Ingham767af882010-07-07 03:36:20 +000023#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytond12aeab2011-04-20 16:37:46 +000024#include "lldb/Interpreter/CommandObjectRegexCommand.h"
Jim Ingham767af882010-07-07 03:36:20 +000025#include "lldb/Interpreter/CommandReturnObject.h"
26#include "lldb/Interpreter/Options.h"
Enrico Granatae5e34cb2011-08-17 01:30:04 +000027#include "lldb/Interpreter/ScriptInterpreter.h"
28#include "lldb/Interpreter/ScriptInterpreterPython.h"
Jim Ingham767af882010-07-07 03:36:20 +000029
30using namespace lldb;
31using namespace lldb_private;
32
Jim Ingham767af882010-07-07 03:36:20 +000033//-------------------------------------------------------------------------
34// CommandObjectCommandsSource
35//-------------------------------------------------------------------------
36
Jim Ingham6247dbe2011-07-12 03:12:18 +000037class CommandObjectCommandsHistory : public CommandObject
38{
39private:
40
41 class CommandOptions : public Options
42 {
43 public:
44
45 CommandOptions (CommandInterpreter &interpreter) :
46 Options (interpreter)
47 {
48 }
49
50 virtual
51 ~CommandOptions (){}
52
53 virtual Error
54 SetOptionValue (uint32_t option_idx, const char *option_arg)
55 {
56 Error error;
57 char short_option = (char) m_getopt_table[option_idx].val;
58 bool success;
59
60 switch (short_option)
61 {
62 case 'c':
63 m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
64 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000065 error.SetErrorStringWithFormat("invalid value for count: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000066 if (m_end_idx != 0)
67 m_end_idx--;
68 m_start_idx = 0;
69 break;
70 case 'e':
71 m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
72 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000073 error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000074 break;
75 case 's':
76 m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
77 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000078 error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000079 break;
80 default:
Greg Clayton9c236732011-10-26 00:56:27 +000081 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Ingham6247dbe2011-07-12 03:12:18 +000082 break;
83 }
84
85 return error;
86 }
87
88 void
89 OptionParsingStarting ()
90 {
91 m_start_idx = 0;
92 m_end_idx = UINT_MAX;
93 }
94
95 const OptionDefinition*
96 GetDefinitions ()
97 {
98 return g_option_table;
99 }
100
101 // Options table: Required for subclasses of Options.
102
103 static OptionDefinition g_option_table[];
104
105 // Instance variables to hold the values for command options.
106
107 uint32_t m_start_idx;
108 uint32_t m_end_idx;
109 };
110
111 CommandOptions m_options;
112
113 virtual Options *
114 GetOptions ()
115 {
116 return &m_options;
117 }
118
119public:
120 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
121 CommandObject (interpreter,
122 "command history",
123 "Dump the history of commands in this session.",
124 NULL),
125 m_options (interpreter)
126 {
127 }
128
129 ~CommandObjectCommandsHistory ()
130 {
131 }
132
133 bool
134 Execute
135 (
136 Args& args,
137 CommandReturnObject &result
138 )
139 {
140
141 m_interpreter.DumpHistory (result.GetOutputStream(),
142 m_options.m_start_idx,
143 m_options.m_end_idx);
144 return result.Succeeded();
145
146 }
147};
148
149OptionDefinition
150CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
151{
152{ LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
153{ LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands."},
154{ LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
155{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
156};
157
158
159//-------------------------------------------------------------------------
160// CommandObjectCommandsSource
161//-------------------------------------------------------------------------
162
Jim Ingham767af882010-07-07 03:36:20 +0000163class CommandObjectCommandsSource : public CommandObject
164{
Jim Ingham949d5ac2011-02-18 00:54:25 +0000165private:
166
167 class CommandOptions : public Options
168 {
169 public:
170
Greg Claytonf15996e2011-04-07 22:46:35 +0000171 CommandOptions (CommandInterpreter &interpreter) :
172 Options (interpreter)
173 {
174 }
Jim Ingham949d5ac2011-02-18 00:54:25 +0000175
176 virtual
177 ~CommandOptions (){}
178
179 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000180 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham949d5ac2011-02-18 00:54:25 +0000181 {
182 Error error;
183 char short_option = (char) m_getopt_table[option_idx].val;
184 bool success;
185
186 switch (short_option)
187 {
188 case 'e':
189 m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
190 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000191 error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000192 break;
193 case 'c':
194 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
195 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000196 error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000197 break;
198 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000199 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000200 break;
201 }
202
203 return error;
204 }
205
206 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000207 OptionParsingStarting ()
Jim Ingham949d5ac2011-02-18 00:54:25 +0000208 {
Jim Ingham949d5ac2011-02-18 00:54:25 +0000209 m_stop_on_error = true;
210 m_stop_on_continue = true;
211 }
212
Greg Claytonb3448432011-03-24 21:19:54 +0000213 const OptionDefinition*
Jim Ingham949d5ac2011-02-18 00:54:25 +0000214 GetDefinitions ()
215 {
216 return g_option_table;
217 }
218
219 // Options table: Required for subclasses of Options.
220
Greg Claytonb3448432011-03-24 21:19:54 +0000221 static OptionDefinition g_option_table[];
Jim Ingham949d5ac2011-02-18 00:54:25 +0000222
223 // Instance variables to hold the values for command options.
224
225 bool m_stop_on_error;
226 bool m_stop_on_continue;
227 };
228
Jim Ingham949d5ac2011-02-18 00:54:25 +0000229 CommandOptions m_options;
230
231 virtual Options *
232 GetOptions ()
233 {
234 return &m_options;
235 }
236
Jim Ingham767af882010-07-07 03:36:20 +0000237public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000238 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
239 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000240 "command source",
Greg Clayton238c0a12010-09-18 01:14:36 +0000241 "Read in debugger commands from the file <filename> and execute them.",
Greg Claytonf15996e2011-04-07 22:46:35 +0000242 NULL),
243 m_options (interpreter)
Jim Ingham767af882010-07-07 03:36:20 +0000244 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000245 CommandArgumentEntry arg;
246 CommandArgumentData file_arg;
247
248 // Define the first (and only) variant of this arg.
249 file_arg.arg_type = eArgTypeFilename;
250 file_arg.arg_repetition = eArgRepeatPlain;
251
252 // There is only one variant this argument could be; put it into the argument entry.
253 arg.push_back (file_arg);
254
255 // Push the data for the first argument into the m_arguments vector.
256 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000257 }
258
259 ~CommandObjectCommandsSource ()
260 {
261 }
262
263 bool
264 Execute
265 (
Jim Ingham767af882010-07-07 03:36:20 +0000266 Args& args,
267 CommandReturnObject &result
268 )
269 {
270 const int argc = args.GetArgumentCount();
271 if (argc == 1)
272 {
273 const char *filename = args.GetArgumentAtIndex(0);
Jim Ingham767af882010-07-07 03:36:20 +0000274
275 result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
276
Johnny Chena83ea882010-10-20 21:40:50 +0000277 FileSpec cmd_file (filename, true);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000278 ExecutionContext *exe_ctx = NULL; // Just use the default context.
279 bool echo_commands = true;
280 bool print_results = true;
Jim Ingham767af882010-07-07 03:36:20 +0000281
Jim Ingham949d5ac2011-02-18 00:54:25 +0000282 m_interpreter.HandleCommandsFromFile (cmd_file,
283 exe_ctx,
284 m_options.m_stop_on_continue,
285 m_options.m_stop_on_error,
286 echo_commands,
287 print_results,
288 result);
Jim Ingham767af882010-07-07 03:36:20 +0000289 }
290 else
291 {
292 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
293 result.SetStatus (eReturnStatusFailed);
294 }
295 return result.Succeeded();
296
297 }
298};
299
Greg Claytonb3448432011-03-24 21:19:54 +0000300OptionDefinition
Jim Ingham949d5ac2011-02-18 00:54:25 +0000301CommandObjectCommandsSource::CommandOptions::g_option_table[] =
302{
303{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
304{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
305{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
306};
307
Jim Ingham767af882010-07-07 03:36:20 +0000308#pragma mark CommandObjectCommandsAlias
309//-------------------------------------------------------------------------
310// CommandObjectCommandsAlias
311//-------------------------------------------------------------------------
312
Enrico Granatac2a28252011-08-16 16:49:25 +0000313static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
314 "You must define a Python function with this signature:\n"
Enrico Granata6b1596d2011-08-16 23:24:13 +0000315 "def my_command_impl(debugger, args, result, dict):";
Enrico Granatac2a28252011-08-16 16:49:25 +0000316
317
Jim Ingham767af882010-07-07 03:36:20 +0000318class CommandObjectCommandsAlias : public CommandObject
319{
Enrico Granatac2a28252011-08-16 16:49:25 +0000320
Enrico Granatac2a28252011-08-16 16:49:25 +0000321
Jim Ingham767af882010-07-07 03:36:20 +0000322public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000323 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
324 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000325 "command alias",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000326 "Allow users to define their own debugger command abbreviations.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000327 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000328 {
329 SetHelpLong(
330 "'alias' allows the user to create a short-cut or abbreviation for long \n\
331 commands, multi-word commands, and commands that take particular options. \n\
332 Below are some simple examples of how one might use the 'alias' command: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000333 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000334 // command. \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000335 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000336 // command. Since breakpoint commands are two-word \n\
337 // commands, the user will still need to enter the \n\
338 // second word after 'bp', e.g. 'bp enable' or \n\
339 // 'bp delete'. \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000340 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000341 // two-word command 'breakpoint list'. \n\
Jim Ingham767af882010-07-07 03:36:20 +0000342 \nAn alias can include some options for the command, with the values either \n\
343 filled in at the time the alias is created, or specified as positional \n\
344 arguments, to be filled in when the alias is invoked. The following example \n\
345 shows how to create aliases with options: \n\
346 \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000347 'command alias bfl breakpoint set -f %1 -l %2' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000348 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
349 options already part of the alias. So if the user wants to set a breakpoint \n\
350 by file and line without explicitly having to use the -f and -l options, the \n\
351 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
352 for the actual arguments that will be passed when the alias command is used. \n\
353 The number in the placeholder refers to the position/order the actual value \n\
Jim Ingham536f6332011-08-18 02:29:05 +0000354 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
Jim Ingham767af882010-07-07 03:36:20 +0000355 will be replaced with the first argument, all the occurrences of '%2' in the \n\
356 alias will be replaced with the second argument, and so on. This also allows \n\
357 actual arguments to be used multiple times within an alias (see 'process \n\
Jim Ingham536f6332011-08-18 02:29:05 +0000358 launch' example below). \n\
359 Note: the positional arguments must substitute as whole words in the resultant\n\
360 command, so you can't at present do something like:\n\
361 \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000362 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
Jim Ingham536f6332011-08-18 02:29:05 +0000363 \n\
364 to get the file extension \".cpp\" automatically appended. For more complex\n\
365 aliasing, use the \"command regex\" command instead.\n\
366 \nSo in the 'bfl' case, the actual file value will be \n\
Jim Ingham767af882010-07-07 03:36:20 +0000367 filled in with the first argument following 'bfl' and the actual line number \n\
368 value will be filled in with the second argument. The user would use this \n\
369 alias as follows: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000370 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000371 <... some time later ...> \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000372 (lldb) bfl my-file.c 137 \n\
Jim Ingham767af882010-07-07 03:36:20 +0000373 \nThis would be the same as if the user had entered \n\
374 'breakpoint set -f my-file.c -l 137'. \n\
375 \nAnother example: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000376 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000377 (lldb) pltty /dev/tty0 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000378 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000379 \nIf the user always wanted to pass the same value to a particular option, the \n\
380 alias could be defined with that value directly in the alias as a constant, \n\
381 rather than using a positional placeholder: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000382 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000383 // 3 of whatever file is indicated. \n");
Jim Ingham767af882010-07-07 03:36:20 +0000384
Caroline Tice43b014a2010-10-04 22:28:36 +0000385 CommandArgumentEntry arg1;
386 CommandArgumentEntry arg2;
387 CommandArgumentEntry arg3;
388 CommandArgumentData alias_arg;
389 CommandArgumentData cmd_arg;
390 CommandArgumentData options_arg;
391
392 // Define the first (and only) variant of this arg.
393 alias_arg.arg_type = eArgTypeAliasName;
394 alias_arg.arg_repetition = eArgRepeatPlain;
395
396 // There is only one variant this argument could be; put it into the argument entry.
397 arg1.push_back (alias_arg);
398
399 // Define the first (and only) variant of this arg.
400 cmd_arg.arg_type = eArgTypeCommandName;
401 cmd_arg.arg_repetition = eArgRepeatPlain;
402
403 // There is only one variant this argument could be; put it into the argument entry.
404 arg2.push_back (cmd_arg);
405
406 // Define the first (and only) variant of this arg.
407 options_arg.arg_type = eArgTypeAliasOptions;
408 options_arg.arg_repetition = eArgRepeatOptional;
409
410 // There is only one variant this argument could be; put it into the argument entry.
411 arg3.push_back (options_arg);
412
413 // Push the data for the first argument into the m_arguments vector.
414 m_arguments.push_back (arg1);
415 m_arguments.push_back (arg2);
416 m_arguments.push_back (arg3);
Jim Ingham767af882010-07-07 03:36:20 +0000417 }
418
419 ~CommandObjectCommandsAlias ()
420 {
421 }
422
Caroline Ticee0da7a52010-12-09 22:52:49 +0000423 bool
424 WantsRawCommandString ()
425 {
426 return true;
427 }
428
429 bool
430 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
431 {
432 Args args (raw_command_line);
433 std::string raw_command_string (raw_command_line);
434
435 size_t argc = args.GetArgumentCount();
436
437 if (argc < 2)
438 {
439 result.AppendError ("'alias' requires at least two arguments");
440 result.SetStatus (eReturnStatusFailed);
441 return false;
442 }
443
444 // Get the alias command.
445
446 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatac2a28252011-08-16 16:49:25 +0000447
Caroline Ticee0da7a52010-12-09 22:52:49 +0000448 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
449 // does the stripping itself.
450 size_t pos = raw_command_string.find (alias_command);
451 if (pos == 0)
452 {
453 raw_command_string = raw_command_string.substr (alias_command.size());
454 pos = raw_command_string.find_first_not_of (' ');
455 if ((pos != std::string::npos) && (pos > 0))
456 raw_command_string = raw_command_string.substr (pos);
457 }
458 else
459 {
460 result.AppendError ("Error parsing command string. No alias created.");
461 result.SetStatus (eReturnStatusFailed);
462 return false;
463 }
464
465
466 // Verify that the command is alias-able.
467 if (m_interpreter.CommandExists (alias_command.c_str()))
468 {
469 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
470 alias_command.c_str());
471 result.SetStatus (eReturnStatusFailed);
472 return false;
473 }
474
475 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
476 // raw_command_string is returned with the name of the command object stripped off the front.
477 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
478
479 if (!cmd_obj)
480 {
Greg Clayton9c236732011-10-26 00:56:27 +0000481 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
Caroline Ticee0da7a52010-12-09 22:52:49 +0000482 " No alias created.", raw_command_string.c_str());
483 result.SetStatus (eReturnStatusFailed);
484 return false;
485 }
486 else if (!cmd_obj->WantsRawCommandString ())
487 {
488 // Note that args was initialized with the original command, and has not been updated to this point.
489 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
490 return Execute (args, result);
491 }
492 else
493 {
494 // Verify & handle any options/arguments passed to the alias command
495
496 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
497 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
498
Caroline Tice5ddbe212011-05-06 21:37:15 +0000499 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
500
501 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Ticee0da7a52010-12-09 22:52:49 +0000502 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000503 result.AppendError ("Unable to create requested alias.\n");
504 result.SetStatus (eReturnStatusFailed);
505 return false;
Caroline Ticee0da7a52010-12-09 22:52:49 +0000506 }
507
508 // Create the alias
509 if (m_interpreter.AliasExists (alias_command.c_str())
510 || m_interpreter.UserCommandExists (alias_command.c_str()))
511 {
512 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
513 if (temp_option_arg_sp.get())
514 {
515 if (option_arg_vector->size() == 0)
516 m_interpreter.RemoveAliasOptions (alias_command.c_str());
517 }
518 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
519 alias_command.c_str());
520 }
521
Caroline Tice56d2fc42010-12-14 18:51:39 +0000522 if (cmd_obj_sp)
523 {
524 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
525 if (option_arg_vector->size() > 0)
526 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
527 result.SetStatus (eReturnStatusSuccessFinishNoResult);
528 }
529 else
530 {
531 result.AppendError ("Unable to create requested alias.\n");
532 result.SetStatus (eReturnStatusFailed);
533 }
Caroline Ticee0da7a52010-12-09 22:52:49 +0000534 }
535 return result.Succeeded();
536 }
Jim Ingham767af882010-07-07 03:36:20 +0000537
538 bool
539 Execute
540 (
Jim Ingham767af882010-07-07 03:36:20 +0000541 Args& args,
542 CommandReturnObject &result
543 )
544 {
Caroline Tice8bb61f02010-09-21 23:25:40 +0000545 size_t argc = args.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000546
547 if (argc < 2)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000548 {
Jim Ingham767af882010-07-07 03:36:20 +0000549 result.AppendError ("'alias' requires at least two arguments");
550 result.SetStatus (eReturnStatusFailed);
551 return false;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000552 }
Jim Ingham767af882010-07-07 03:36:20 +0000553
554 const std::string alias_command = args.GetArgumentAtIndex(0);
555 const std::string actual_command = args.GetArgumentAtIndex(1);
556
557 args.Shift(); // Shift the alias command word off the argument vector.
558 args.Shift(); // Shift the old command word off the argument vector.
559
560 // Verify that the command is alias'able, and get the appropriate command object.
561
Greg Clayton238c0a12010-09-18 01:14:36 +0000562 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000563 {
564 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
565 alias_command.c_str());
566 result.SetStatus (eReturnStatusFailed);
567 }
568 else
569 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000570 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Ingham767af882010-07-07 03:36:20 +0000571 CommandObjectSP subcommand_obj_sp;
572 bool use_subcommand = false;
573 if (command_obj_sp.get())
574 {
575 CommandObject *cmd_obj = command_obj_sp.get();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000576 CommandObject *sub_cmd_obj = NULL;
Jim Ingham767af882010-07-07 03:36:20 +0000577 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
578 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
579
Caroline Ticee0da7a52010-12-09 22:52:49 +0000580 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Ingham767af882010-07-07 03:36:20 +0000581 {
582 if (argc >= 3)
583 {
584 const std::string sub_command = args.GetArgumentAtIndex(0);
585 assert (sub_command.length() != 0);
586 subcommand_obj_sp =
587 (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
588 if (subcommand_obj_sp.get())
589 {
590 sub_cmd_obj = subcommand_obj_sp.get();
591 use_subcommand = true;
592 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Ticee0da7a52010-12-09 22:52:49 +0000593 cmd_obj = sub_cmd_obj;
Jim Ingham767af882010-07-07 03:36:20 +0000594 }
595 else
596 {
Caroline Tice5d53b622010-11-02 19:00:04 +0000597 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
598 "Unable to create alias.\n",
599 sub_command.c_str(), actual_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000600 result.SetStatus (eReturnStatusFailed);
601 return false;
602 }
603 }
604 }
605
606 // Verify & handle any options/arguments passed to the alias command
607
608 if (args.GetArgumentCount () > 0)
609 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000610 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
611 if (use_subcommand)
612 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
613
614 std::string args_string;
615 args.GetCommandString (args_string);
616
617 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
618 {
619 result.AppendError ("Unable to create requested alias.\n");
620 result.SetStatus (eReturnStatusFailed);
621 return false;
622 }
Jim Ingham767af882010-07-07 03:36:20 +0000623 }
624
625 // Create the alias.
626
Greg Clayton238c0a12010-09-18 01:14:36 +0000627 if (m_interpreter.AliasExists (alias_command.c_str())
628 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000629 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000630 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Ingham767af882010-07-07 03:36:20 +0000631 if (tmp_option_arg_sp.get())
632 {
633 if (option_arg_vector->size() == 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000634 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000635 }
636 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
637 alias_command.c_str());
638 }
639
640 if (use_subcommand)
Greg Clayton238c0a12010-09-18 01:14:36 +0000641 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000642 else
Greg Clayton238c0a12010-09-18 01:14:36 +0000643 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000644 if (option_arg_vector->size() > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000645 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000646 result.SetStatus (eReturnStatusSuccessFinishNoResult);
647 }
648 else
649 {
650 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
651 result.SetStatus (eReturnStatusFailed);
Caroline Ticee6866a32010-10-28 23:17:48 +0000652 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000653 }
654 }
655
656 return result.Succeeded();
657 }
658};
659
660#pragma mark CommandObjectCommandsUnalias
661//-------------------------------------------------------------------------
662// CommandObjectCommandsUnalias
663//-------------------------------------------------------------------------
664
665class CommandObjectCommandsUnalias : public CommandObject
666{
667public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000668 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
669 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000670 "command unalias",
Caroline Tice146292c2010-09-12 04:56:10 +0000671 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000672 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000673 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000674 CommandArgumentEntry arg;
675 CommandArgumentData alias_arg;
676
677 // Define the first (and only) variant of this arg.
678 alias_arg.arg_type = eArgTypeAliasName;
679 alias_arg.arg_repetition = eArgRepeatPlain;
680
681 // There is only one variant this argument could be; put it into the argument entry.
682 arg.push_back (alias_arg);
683
684 // Push the data for the first argument into the m_arguments vector.
685 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000686 }
687
688 ~CommandObjectCommandsUnalias()
689 {
690 }
691
692
693 bool
694 Execute
695 (
Jim Ingham767af882010-07-07 03:36:20 +0000696 Args& args,
697 CommandReturnObject &result
698 )
699 {
700 CommandObject::CommandMap::iterator pos;
701 CommandObject *cmd_obj;
702
703 if (args.GetArgumentCount() != 0)
704 {
705 const char *command_name = args.GetArgumentAtIndex(0);
Greg Clayton238c0a12010-09-18 01:14:36 +0000706 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Ingham767af882010-07-07 03:36:20 +0000707 if (cmd_obj)
708 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000709 if (m_interpreter.CommandExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000710 {
711 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
712 command_name);
713 result.SetStatus (eReturnStatusFailed);
714 }
715 else
716 {
717
Greg Clayton238c0a12010-09-18 01:14:36 +0000718 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Ingham767af882010-07-07 03:36:20 +0000719 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000720 if (m_interpreter.AliasExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000721 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
722 command_name);
723 else
724 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
725 result.SetStatus (eReturnStatusFailed);
726 }
727 else
728 result.SetStatus (eReturnStatusSuccessFinishNoResult);
729 }
730 }
731 else
732 {
733 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
734 "current list of commands.\n",
735 command_name);
736 result.SetStatus (eReturnStatusFailed);
737 }
738 }
739 else
740 {
741 result.AppendError ("must call 'unalias' with a valid alias");
742 result.SetStatus (eReturnStatusFailed);
743 }
744
745 return result.Succeeded();
746 }
747};
748
Greg Claytond12aeab2011-04-20 16:37:46 +0000749#pragma mark CommandObjectCommandsAddRegex
750//-------------------------------------------------------------------------
751// CommandObjectCommandsAddRegex
752//-------------------------------------------------------------------------
753
754class CommandObjectCommandsAddRegex : public CommandObject
755{
756public:
757 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
758 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000759 "command regex",
Greg Claytond12aeab2011-04-20 16:37:46 +0000760 "Allow the user to create a regular expression command.",
Greg Clayton40e48242011-04-20 22:55:21 +0000761 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytond12aeab2011-04-20 16:37:46 +0000762 m_options (interpreter)
763 {
Greg Clayton40e48242011-04-20 22:55:21 +0000764 SetHelpLong(
765"This command allows the user to create powerful regular expression commands\n"
766"with substitutions. The regular expressions and substitutions are specified\n"
767"using the regular exression substitution format of:\n"
768"\n"
769" s/<regex>/<subst>/\n"
770"\n"
771"<regex> is a regular expression that can use parenthesis to capture regular\n"
772"expression input and substitute the captured matches in the output using %1\n"
773"for the first match, %2 for the second, and so on.\n"
774"\n"
775"The regular expressions can all be specified on the command line if more than\n"
776"one argument is provided. If just the command name is provided on the command\n"
777"line, then the regular expressions and substitutions can be entered on separate\n"
778" lines, followed by an empty line to terminate the command definition.\n"
779"\n"
780"EXAMPLES\n"
781"\n"
782"The following example with define a regular expression command named 'f' that\n"
783"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
784"a number follows 'f':\n"
785"(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
786 );
Greg Claytond12aeab2011-04-20 16:37:46 +0000787 }
788
789 ~CommandObjectCommandsAddRegex()
790 {
791 }
792
793
794 bool
795 Execute (Args& args, CommandReturnObject &result)
796 {
Greg Clayton40e48242011-04-20 22:55:21 +0000797 const size_t argc = args.GetArgumentCount();
798 if (argc == 0)
Greg Claytond12aeab2011-04-20 16:37:46 +0000799 {
Jason Molenda4049bc32011-11-10 22:43:35 +0000800 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton40e48242011-04-20 22:55:21 +0000801 result.SetStatus (eReturnStatusFailed);
802 }
803 else
804 {
805 Error error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000806 const char *name = args.GetArgumentAtIndex(0);
Greg Claytond12aeab2011-04-20 16:37:46 +0000807 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
808 name,
809 m_options.GetHelp (),
810 m_options.GetSyntax (),
811 10));
Greg Clayton40e48242011-04-20 22:55:21 +0000812
813 if (argc == 1)
Greg Claytond12aeab2011-04-20 16:37:46 +0000814 {
Greg Clayton40e48242011-04-20 22:55:21 +0000815 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
816 if (reader_sp)
817 {
818 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
Greg Claytond12aeab2011-04-20 16:37:46 +0000819 this, // baton
820 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton40e48242011-04-20 22:55:21 +0000821 NULL, // end token
Greg Claytond12aeab2011-04-20 16:37:46 +0000822 "> ", // prompt
Greg Clayton40e48242011-04-20 22:55:21 +0000823 true); // echo input
824 if (error.Success())
825 {
826 m_interpreter.GetDebugger().PushInputReader (reader_sp);
827 result.SetStatus (eReturnStatusSuccessFinishNoResult);
828 return true;
829 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000830 }
831 }
Greg Clayton40e48242011-04-20 22:55:21 +0000832 else
833 {
834 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
835 {
836 llvm::StringRef arg_strref (args.GetArgumentAtIndex(arg_idx));
837 error = AppendRegexSubstitution (arg_strref);
838 if (error.Fail())
839 break;
840 }
841
842 if (error.Success())
843 {
844 AddRegexCommandToInterpreter();
845 }
846 }
847 if (error.Fail())
848 {
849 result.AppendError (error.AsCString());
850 result.SetStatus (eReturnStatusFailed);
851 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000852 }
Greg Clayton40e48242011-04-20 22:55:21 +0000853
Greg Claytond12aeab2011-04-20 16:37:46 +0000854 return result.Succeeded();
855 }
856
Greg Clayton40e48242011-04-20 22:55:21 +0000857 Error
858 AppendRegexSubstitution (const llvm::StringRef &regex_sed)
Greg Claytond12aeab2011-04-20 16:37:46 +0000859 {
Greg Clayton40e48242011-04-20 22:55:21 +0000860 Error error;
861
862 if (m_regex_cmd_ap.get() == NULL)
Greg Claytond12aeab2011-04-20 16:37:46 +0000863 {
Greg Clayton40e48242011-04-20 22:55:21 +0000864 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
865 (int)regex_sed.size(),
866 regex_sed.data());
867 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000868 }
Greg Clayton40e48242011-04-20 22:55:21 +0000869
870 size_t regex_sed_size = regex_sed.size();
871
872 if (regex_sed_size <= 1)
873 {
874 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
875 (int)regex_sed.size(),
876 regex_sed.data());
877 return error;
878 }
879
880 if (regex_sed[0] != 's')
881 {
882 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
883 (int)regex_sed.size(),
884 regex_sed.data());
885 return error;
886 }
887 const size_t first_separator_char_pos = 1;
888 // use the char that follows 's' as the regex separator character
889 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
890 const char separator_char = regex_sed[first_separator_char_pos];
891 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
892
893 if (second_separator_char_pos == std::string::npos)
894 {
895 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
896 separator_char,
897 (int)(regex_sed.size() - first_separator_char_pos - 1),
898 regex_sed.data() + (first_separator_char_pos + 1));
899 return error;
900 }
901
902 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
903
904 if (third_separator_char_pos == std::string::npos)
905 {
906 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
907 separator_char,
908 (int)(regex_sed.size() - second_separator_char_pos - 1),
909 regex_sed.data() + (second_separator_char_pos + 1));
910 return error;
911 }
912
913 if (third_separator_char_pos != regex_sed_size - 1)
914 {
915 // Make sure that everything that follows the last regex
916 // separator char
917 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
918 {
919 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
920 (int)third_separator_char_pos + 1,
921 regex_sed.data(),
922 (int)(regex_sed.size() - third_separator_char_pos - 1),
923 regex_sed.data() + (third_separator_char_pos + 1));
924 return error;
925 }
926
927 }
928 else if (first_separator_char_pos + 1 == second_separator_char_pos)
929 {
930 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
931 separator_char,
932 separator_char,
933 separator_char,
934 (int)regex_sed.size(),
935 regex_sed.data());
936 return error;
937 }
938 else if (second_separator_char_pos + 1 == third_separator_char_pos)
939 {
940 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
941 separator_char,
942 separator_char,
943 separator_char,
944 (int)regex_sed.size(),
945 regex_sed.data());
946 return error;
947 }
948 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
949 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
950 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
951 subst.c_str());
952 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000953 }
954
955 void
Greg Clayton40e48242011-04-20 22:55:21 +0000956 AddRegexCommandToInterpreter()
Greg Claytond12aeab2011-04-20 16:37:46 +0000957 {
958 if (m_regex_cmd_ap.get())
959 {
960 if (m_regex_cmd_ap->HasRegexEntries())
961 {
962 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
963 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
964 }
965 }
966 }
967
Greg Clayton40e48242011-04-20 22:55:21 +0000968 void
969 InputReaderDidCancel()
970 {
971 m_regex_cmd_ap.reset();
972 }
973
Greg Claytond12aeab2011-04-20 16:37:46 +0000974 static size_t
975 InputReaderCallback (void *baton,
976 InputReader &reader,
977 lldb::InputReaderAction notification,
978 const char *bytes,
979 size_t bytes_len);
980private:
981 std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
982
983 class CommandOptions : public Options
984 {
985 public:
986
987 CommandOptions (CommandInterpreter &interpreter) :
988 Options (interpreter)
989 {
990 }
991
992 virtual
993 ~CommandOptions (){}
994
995 virtual Error
996 SetOptionValue (uint32_t option_idx, const char *option_arg)
997 {
998 Error error;
999 char short_option = (char) m_getopt_table[option_idx].val;
1000
1001 switch (short_option)
1002 {
1003 case 'h':
1004 m_help.assign (option_arg);
1005 break;
1006 case 's':
1007 m_syntax.assign (option_arg);
1008 break;
1009
1010 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001011 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytond12aeab2011-04-20 16:37:46 +00001012 break;
1013 }
1014
1015 return error;
1016 }
1017
1018 void
1019 OptionParsingStarting ()
1020 {
1021 m_help.clear();
1022 m_syntax.clear();
1023 }
1024
1025 const OptionDefinition*
1026 GetDefinitions ()
1027 {
1028 return g_option_table;
1029 }
1030
1031 // Options table: Required for subclasses of Options.
1032
1033 static OptionDefinition g_option_table[];
1034
1035 const char *
1036 GetHelp ()
1037 {
1038 if (m_help.empty())
1039 return NULL;
1040 return m_help.c_str();
1041 }
1042 const char *
1043 GetSyntax ()
1044 {
1045 if (m_syntax.empty())
1046 return NULL;
1047 return m_syntax.c_str();
1048 }
1049 // Instance variables to hold the values for command options.
1050 protected:
1051 std::string m_help;
1052 std::string m_syntax;
1053 };
1054
1055 CommandOptions m_options;
1056
1057 virtual Options *
1058 GetOptions ()
1059 {
1060 return &m_options;
1061 }
1062
1063};
1064
1065size_t
1066CommandObjectCommandsAddRegex::InputReaderCallback (void *baton,
1067 InputReader &reader,
1068 lldb::InputReaderAction notification,
1069 const char *bytes,
1070 size_t bytes_len)
1071{
1072 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
Caroline Tice892fadd2011-06-16 16:27:19 +00001073 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Greg Claytond12aeab2011-04-20 16:37:46 +00001074
1075 switch (notification)
1076 {
1077 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00001078 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001079 {
1080 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1081 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1082 out_stream->Flush();
1083 }
Greg Claytond12aeab2011-04-20 16:37:46 +00001084 break;
1085 case eInputReaderReactivate:
1086 break;
1087
1088 case eInputReaderDeactivate:
1089 break;
Caroline Tice4a348082011-05-02 20:41:46 +00001090
1091 case eInputReaderAsynchronousOutputWritten:
1092 break;
1093
Greg Claytond12aeab2011-04-20 16:37:46 +00001094 case eInputReaderGotToken:
Greg Clayton40e48242011-04-20 22:55:21 +00001095 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1096 --bytes_len;
Greg Claytond12aeab2011-04-20 16:37:46 +00001097 if (bytes_len == 0)
1098 reader.SetIsDone(true);
1099 else if (bytes)
1100 {
Greg Clayton40e48242011-04-20 22:55:21 +00001101 llvm::StringRef bytes_strref (bytes, bytes_len);
1102 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1103 if (error.Fail())
Greg Claytond12aeab2011-04-20 16:37:46 +00001104 {
Caroline Tice892fadd2011-06-16 16:27:19 +00001105 if (!batch_mode)
1106 {
1107 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1108 out_stream->Printf("error: %s\n", error.AsCString());
1109 out_stream->Flush();
1110 }
Greg Clayton40e48242011-04-20 22:55:21 +00001111 add_regex_cmd->InputReaderDidCancel ();
1112 reader.SetIsDone (true);
Greg Claytond12aeab2011-04-20 16:37:46 +00001113 }
1114 }
1115 break;
1116
1117 case eInputReaderInterrupt:
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001118 {
1119 reader.SetIsDone (true);
Caroline Tice892fadd2011-06-16 16:27:19 +00001120 if (!batch_mode)
1121 {
1122 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1123 out_stream->PutCString("Regular expression command creations was cancelled.\n");
1124 out_stream->Flush();
1125 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001126 add_regex_cmd->InputReaderDidCancel ();
1127 }
Greg Claytond12aeab2011-04-20 16:37:46 +00001128 break;
1129
1130 case eInputReaderEndOfFile:
1131 reader.SetIsDone (true);
1132 break;
1133
1134 case eInputReaderDone:
Greg Clayton40e48242011-04-20 22:55:21 +00001135 add_regex_cmd->AddRegexCommandToInterpreter();
Greg Claytond12aeab2011-04-20 16:37:46 +00001136 break;
1137 }
1138
1139 return bytes_len;
1140}
1141
1142
1143OptionDefinition
1144CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1145{
Greg Clayton40e48242011-04-20 22:55:21 +00001146{ LLDB_OPT_SET_1, false, "help" , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
Greg Claytond12aeab2011-04-20 16:37:46 +00001147{ LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
Greg Clayton40e48242011-04-20 22:55:21 +00001148{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytond12aeab2011-04-20 16:37:46 +00001149};
1150
1151
Enrico Granata6b1596d2011-08-16 23:24:13 +00001152class CommandObjectPythonFunction : public CommandObject
1153{
1154private:
1155 std::string m_function_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001156 ScriptedCommandSynchronicity m_synchro;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001157
1158public:
1159
1160 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1161 std::string name,
Enrico Granata6010ace2011-11-07 22:57:04 +00001162 std::string funct,
1163 ScriptedCommandSynchronicity synch) :
Enrico Granata6b1596d2011-08-16 23:24:13 +00001164 CommandObject (interpreter,
1165 name.c_str(),
1166 (std::string("Run Python function ") + funct).c_str(),
1167 NULL),
Enrico Granata6010ace2011-11-07 22:57:04 +00001168 m_function_name(funct),
1169 m_synchro(synch)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001170 {
Enrico Granatae5e34cb2011-08-17 01:30:04 +00001171 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1172 if (scripter)
1173 {
1174 std::string docstring = scripter->GetDocumentationForItem(funct.c_str());
1175 if (!docstring.empty())
1176 SetHelpLong(docstring);
1177 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001178 }
1179
1180 virtual
1181 ~CommandObjectPythonFunction ()
1182 {
1183 }
1184
1185 virtual bool
1186 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
1187 {
1188 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1189
1190 Error error;
1191
1192 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1193 raw_command_line,
Enrico Granata6010ace2011-11-07 22:57:04 +00001194 m_synchro,
Enrico Granata6b1596d2011-08-16 23:24:13 +00001195 result,
1196 error) == false)
1197 {
1198 result.AppendError(error.AsCString());
1199 result.SetStatus(eReturnStatusFailed);
1200 }
1201 else
1202 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1203
1204 return result.Succeeded();
1205 }
1206
1207 virtual bool
1208 WantsRawCommandString ()
1209 {
1210 return true;
1211 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001212
Enrico Granata6b1596d2011-08-16 23:24:13 +00001213 bool
1214 Execute (Args& command,
1215 CommandReturnObject &result)
1216 {
1217 std::string cmd_string;
1218 command.GetCommandString(cmd_string);
1219 return ExecuteRawCommandString(cmd_string.c_str(), result);
1220 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001221
Enrico Granata6b1596d2011-08-16 23:24:13 +00001222 virtual bool
Enrico Granata6010ace2011-11-07 22:57:04 +00001223 IsRemovable ()
1224 {
1225 return true;
1226 }
1227
1228 const std::string&
1229 GetFunctionName ()
1230 {
1231 return m_function_name;
1232 }
1233
1234 ScriptedCommandSynchronicity
1235 GetSynchronicity ()
1236 {
1237 return m_synchro;
1238 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001239
1240};
1241
Enrico Granata59df36f2011-10-17 21:45:27 +00001242//-------------------------------------------------------------------------
1243// CommandObjectCommandsScriptImport
1244//-------------------------------------------------------------------------
1245
1246class CommandObjectCommandsScriptImport : public CommandObject
1247{
Enrico Granata6010ace2011-11-07 22:57:04 +00001248private:
1249
1250 class CommandOptions : public Options
1251 {
1252 public:
1253
1254 CommandOptions (CommandInterpreter &interpreter) :
1255 Options (interpreter)
1256 {
1257 }
1258
1259 virtual
1260 ~CommandOptions (){}
1261
1262 virtual Error
1263 SetOptionValue (uint32_t option_idx, const char *option_arg)
1264 {
1265 Error error;
1266 char short_option = (char) m_getopt_table[option_idx].val;
1267
1268 switch (short_option)
1269 {
1270 case 'r':
1271 m_allow_reload = true;
1272 break;
1273 default:
1274 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1275 break;
1276 }
1277
1278 return error;
1279 }
1280
1281 void
1282 OptionParsingStarting ()
1283 {
1284 m_allow_reload = false;
1285 }
1286
1287 const OptionDefinition*
1288 GetDefinitions ()
1289 {
1290 return g_option_table;
1291 }
1292
1293 // Options table: Required for subclasses of Options.
1294
1295 static OptionDefinition g_option_table[];
1296
1297 // Instance variables to hold the values for command options.
1298
1299 bool m_allow_reload;
1300 };
1301
1302 CommandOptions m_options;
1303
1304 virtual Options *
1305 GetOptions ()
1306 {
1307 return &m_options;
1308 }
1309
Enrico Granata59df36f2011-10-17 21:45:27 +00001310public:
1311 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1312 CommandObject (interpreter,
1313 "command script import",
1314 "Import a scripting module in LLDB.",
Enrico Granata6010ace2011-11-07 22:57:04 +00001315 NULL),
1316 m_options(interpreter)
Enrico Granata59df36f2011-10-17 21:45:27 +00001317 {
1318 CommandArgumentEntry arg1;
1319 CommandArgumentData cmd_arg;
1320
1321 // Define the first (and only) variant of this arg.
Enrico Granata6010ace2011-11-07 22:57:04 +00001322 cmd_arg.arg_type = eArgTypeFilename;
Enrico Granata59df36f2011-10-17 21:45:27 +00001323 cmd_arg.arg_repetition = eArgRepeatPlain;
1324
1325 // There is only one variant this argument could be; put it into the argument entry.
1326 arg1.push_back (cmd_arg);
1327
1328 // Push the data for the first argument into the m_arguments vector.
1329 m_arguments.push_back (arg1);
1330 }
1331
1332 ~CommandObjectCommandsScriptImport ()
1333 {
1334 }
1335
1336 bool
1337 Execute
1338 (
1339 Args& args,
1340 CommandReturnObject &result
1341 )
1342 {
1343
1344 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1345 {
1346 result.AppendError ("only scripting language supported for module importing is currently Python");
1347 result.SetStatus (eReturnStatusFailed);
1348 return false;
1349 }
1350
1351 size_t argc = args.GetArgumentCount();
1352
1353 if (argc != 1)
1354 {
1355 result.AppendError ("'command script import' requires one argument");
1356 result.SetStatus (eReturnStatusFailed);
1357 return false;
1358 }
1359
1360 std::string path = args.GetArgumentAtIndex(0);
1361 Error error;
1362
1363 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001364 m_options.m_allow_reload,
Enrico Granata59df36f2011-10-17 21:45:27 +00001365 error))
1366 {
1367 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1368 }
1369 else
1370 {
1371 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1372 result.SetStatus (eReturnStatusFailed);
1373 }
1374
1375 return result.Succeeded();
1376 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001377
1378 int
1379 HandleArgumentCompletion (Args &input,
1380 int &cursor_index,
1381 int &cursor_char_position,
1382 OptionElementVector &opt_element_vector,
1383 int match_start_point,
1384 int max_return_elements,
1385 bool &word_complete,
1386 StringList &matches)
1387 {
1388 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1389 completion_str.erase (cursor_char_position);
1390
1391 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1392 CommandCompletions::eDiskFileCompletion,
1393 completion_str.c_str(),
1394 match_start_point,
1395 max_return_elements,
1396 NULL,
1397 word_complete,
1398 matches);
1399 return matches.GetSize();
1400 }
Enrico Granata59df36f2011-10-17 21:45:27 +00001401};
Enrico Granata6b1596d2011-08-16 23:24:13 +00001402
Enrico Granata6010ace2011-11-07 22:57:04 +00001403OptionDefinition
1404CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1405{
1406 { LLDB_OPT_SET_1, false, "allow-reload", 'r', no_argument, NULL, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before (for Python, the __lldb_init_module function will be called again, but the module will not be reloaded from disk)."},
1407 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1408};
1409
1410
Enrico Granata6b1596d2011-08-16 23:24:13 +00001411//-------------------------------------------------------------------------
1412// CommandObjectCommandsScriptAdd
1413//-------------------------------------------------------------------------
1414
1415class CommandObjectCommandsScriptAdd : public CommandObject
1416{
1417private:
1418
1419 class CommandOptions : public Options
1420 {
1421 public:
1422
1423 CommandOptions (CommandInterpreter &interpreter) :
1424 Options (interpreter)
1425 {
1426 }
1427
1428 virtual
1429 ~CommandOptions (){}
1430
1431 virtual Error
1432 SetOptionValue (uint32_t option_idx, const char *option_arg)
1433 {
1434 Error error;
1435 char short_option = (char) m_getopt_table[option_idx].val;
1436
1437 switch (short_option)
1438 {
1439 case 'f':
1440 m_funct_name = std::string(option_arg);
1441 break;
Enrico Granata6010ace2011-11-07 22:57:04 +00001442 case 's':
1443 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1444 if (!error.Success())
1445 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1446 break;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001447 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001448 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001449 break;
1450 }
1451
1452 return error;
1453 }
1454
1455 void
1456 OptionParsingStarting ()
1457 {
1458 m_funct_name = "";
Enrico Granata6010ace2011-11-07 22:57:04 +00001459 m_synchronous = eScriptedCommandSynchronicitySynchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001460 }
1461
1462 const OptionDefinition*
1463 GetDefinitions ()
1464 {
1465 return g_option_table;
1466 }
1467
1468 // Options table: Required for subclasses of Options.
1469
1470 static OptionDefinition g_option_table[];
1471
1472 // Instance variables to hold the values for command options.
1473
1474 std::string m_funct_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001475 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001476 };
1477
1478 CommandOptions m_options;
1479
1480 virtual Options *
1481 GetOptions ()
1482 {
1483 return &m_options;
1484 }
1485
1486 class PythonAliasReader : public InputReaderEZ
1487 {
1488 private:
1489 CommandInterpreter& m_interpreter;
1490 std::string m_cmd_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001491 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001492 StringList m_user_input;
1493 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1494 public:
1495 PythonAliasReader(Debugger& debugger,
1496 CommandInterpreter& interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001497 std::string cmd_name,
1498 ScriptedCommandSynchronicity synch) :
Enrico Granata6b1596d2011-08-16 23:24:13 +00001499 InputReaderEZ(debugger),
1500 m_interpreter(interpreter),
1501 m_cmd_name(cmd_name),
Enrico Granata6010ace2011-11-07 22:57:04 +00001502 m_synchronous(synch),
Enrico Granata6b1596d2011-08-16 23:24:13 +00001503 m_user_input()
1504 {}
1505
1506 virtual
1507 ~PythonAliasReader()
1508 {
1509 }
1510
1511 virtual void ActivateHandler(HandlerData& data)
1512 {
1513 StreamSP out_stream = data.GetOutStream();
1514 bool batch_mode = data.GetBatchMode();
1515 if (!batch_mode)
1516 {
1517 out_stream->Printf ("%s\n", g_python_command_instructions);
1518 if (data.reader.GetPrompt())
1519 out_stream->Printf ("%s", data.reader.GetPrompt());
1520 out_stream->Flush();
1521 }
1522 }
1523
1524 virtual void ReactivateHandler(HandlerData& data)
1525 {
1526 StreamSP out_stream = data.GetOutStream();
1527 bool batch_mode = data.GetBatchMode();
1528 if (data.reader.GetPrompt() && !batch_mode)
1529 {
1530 out_stream->Printf ("%s", data.reader.GetPrompt());
1531 out_stream->Flush();
1532 }
1533 }
1534 virtual void GotTokenHandler(HandlerData& data)
1535 {
1536 StreamSP out_stream = data.GetOutStream();
1537 bool batch_mode = data.GetBatchMode();
1538 if (data.bytes && data.bytes_len)
1539 {
1540 m_user_input.AppendString(data.bytes, data.bytes_len);
1541 }
1542 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1543 {
1544 out_stream->Printf ("%s", data.reader.GetPrompt());
1545 out_stream->Flush();
1546 }
1547 }
1548 virtual void InterruptHandler(HandlerData& data)
1549 {
1550 StreamSP out_stream = data.GetOutStream();
1551 bool batch_mode = data.GetBatchMode();
1552 data.reader.SetIsDone (true);
1553 if (!batch_mode)
1554 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001555 out_stream->Printf ("Warning: No script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001556 out_stream->Flush();
1557 }
1558 }
1559 virtual void EOFHandler(HandlerData& data)
1560 {
1561 data.reader.SetIsDone (true);
1562 }
1563 virtual void DoneHandler(HandlerData& data)
1564 {
1565 StreamSP out_stream = data.GetOutStream();
1566
1567 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1568 if (!interpreter)
1569 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001570 out_stream->Printf ("Script interpreter missing: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001571 out_stream->Flush();
1572 return;
1573 }
Enrico Granata400105d2012-03-06 23:42:15 +00001574 std::string funct_name_str;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001575 if (!interpreter->GenerateScriptAliasFunction (m_user_input,
Enrico Granata400105d2012-03-06 23:42:15 +00001576 funct_name_str))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001577 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001578 out_stream->Printf ("Unable to create function: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001579 out_stream->Flush();
1580 return;
1581 }
Enrico Granata400105d2012-03-06 23:42:15 +00001582 if (funct_name_str.empty())
Enrico Granata6b1596d2011-08-16 23:24:13 +00001583 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001584 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001585 out_stream->Flush();
1586 return;
1587 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001588 // everything should be fine now, let's add this alias
1589
1590 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1591 m_cmd_name,
Enrico Granata400105d2012-03-06 23:42:15 +00001592 funct_name_str.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001593 m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001594
Enrico Granata6010ace2011-11-07 22:57:04 +00001595 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001596 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001597 out_stream->Printf ("Unable to add selected command: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001598 out_stream->Flush();
1599 return;
1600 }
1601 }
1602 };
1603
1604public:
1605 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1606 CommandObject (interpreter,
1607 "command script add",
1608 "Add a scripted function as an LLDB command.",
1609 NULL),
1610 m_options (interpreter)
1611 {
1612 CommandArgumentEntry arg1;
1613 CommandArgumentData cmd_arg;
1614
1615 // Define the first (and only) variant of this arg.
1616 cmd_arg.arg_type = eArgTypeCommandName;
1617 cmd_arg.arg_repetition = eArgRepeatPlain;
1618
1619 // There is only one variant this argument could be; put it into the argument entry.
1620 arg1.push_back (cmd_arg);
1621
1622 // Push the data for the first argument into the m_arguments vector.
1623 m_arguments.push_back (arg1);
1624 }
1625
1626 ~CommandObjectCommandsScriptAdd ()
1627 {
1628 }
1629
1630 bool
1631 Execute
1632 (
1633 Args& args,
1634 CommandReturnObject &result
1635 )
1636 {
Enrico Granatae5e34cb2011-08-17 01:30:04 +00001637
1638 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1639 {
1640 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1641 result.SetStatus (eReturnStatusFailed);
1642 return false;
1643 }
1644
Enrico Granata6b1596d2011-08-16 23:24:13 +00001645 size_t argc = args.GetArgumentCount();
1646
1647 if (argc != 1)
1648 {
1649 result.AppendError ("'command script add' requires one argument");
1650 result.SetStatus (eReturnStatusFailed);
1651 return false;
1652 }
1653
1654 std::string cmd_name = args.GetArgumentAtIndex(0);
1655
1656 if (m_options.m_funct_name.empty())
1657 {
1658 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1659 m_interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001660 cmd_name,
1661 m_options.m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001662
1663 if (reader_sp)
1664 {
1665
1666 InputReaderEZ::InitializationParameters ipr;
1667
1668 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
1669 if (err.Success())
1670 {
1671 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1672 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1673 }
1674 else
1675 {
1676 result.AppendError (err.AsCString());
1677 result.SetStatus (eReturnStatusFailed);
1678 }
1679 }
1680 else
1681 {
1682 result.AppendError("out of memory");
1683 result.SetStatus (eReturnStatusFailed);
1684 }
1685 }
1686 else
1687 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001688 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1689 cmd_name,
1690 m_options.m_funct_name,
1691 m_options.m_synchronous));
1692 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001693 {
1694 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1695 }
1696 else
1697 {
1698 result.AppendError("cannot add command");
1699 result.SetStatus (eReturnStatusFailed);
1700 }
1701 }
1702
1703 return result.Succeeded();
1704
1705 }
1706};
1707
Enrico Granata6010ace2011-11-07 22:57:04 +00001708static OptionEnumValueElement g_script_synchro_type[] =
1709{
1710 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1711 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1712 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1713 { 0, NULL, NULL }
1714};
1715
Enrico Granata6b1596d2011-08-16 23:24:13 +00001716OptionDefinition
1717CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1718{
Enrico Granata91544802011-09-06 19:20:51 +00001719 { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
Enrico Granata6010ace2011-11-07 22:57:04 +00001720 { LLDB_OPT_SET_1, false, "synchronicity", 's', required_argument, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
Enrico Granata6b1596d2011-08-16 23:24:13 +00001721 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1722};
1723
1724//-------------------------------------------------------------------------
1725// CommandObjectCommandsScriptList
1726//-------------------------------------------------------------------------
1727
1728class CommandObjectCommandsScriptList : public CommandObject
1729{
1730private:
Enrico Granata6010ace2011-11-07 22:57:04 +00001731
Enrico Granata6b1596d2011-08-16 23:24:13 +00001732public:
1733 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
1734 CommandObject (interpreter,
1735 "command script list",
1736 "List defined scripted commands.",
1737 NULL)
1738 {
1739 }
1740
1741 ~CommandObjectCommandsScriptList ()
1742 {
1743 }
1744
1745 bool
1746 Execute
1747 (
1748 Args& args,
1749 CommandReturnObject &result
1750 )
1751 {
1752
1753 m_interpreter.GetHelp(result,
1754 CommandInterpreter::eCommandTypesUserDef);
1755
1756 result.SetStatus (eReturnStatusSuccessFinishResult);
1757
1758 return true;
1759
1760
1761 }
1762};
1763
1764//-------------------------------------------------------------------------
1765// CommandObjectCommandsScriptClear
1766//-------------------------------------------------------------------------
1767
1768class CommandObjectCommandsScriptClear : public CommandObject
1769{
1770private:
1771
1772public:
1773 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
1774 CommandObject (interpreter,
1775 "command script clear",
1776 "Delete all scripted commands.",
1777 NULL)
1778 {
1779 }
1780
1781 ~CommandObjectCommandsScriptClear ()
1782 {
1783 }
1784
1785 bool
1786 Execute
1787 (
1788 Args& args,
1789 CommandReturnObject &result
1790 )
1791 {
1792
1793 m_interpreter.RemoveAllUser();
1794
1795 result.SetStatus (eReturnStatusSuccessFinishResult);
1796
1797 return true;
1798
1799
1800 }
1801};
1802
1803//-------------------------------------------------------------------------
1804// CommandObjectCommandsScriptDelete
1805//-------------------------------------------------------------------------
1806
1807class CommandObjectCommandsScriptDelete : public CommandObject
1808{
1809private:
1810
1811public:
1812 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
1813 CommandObject (interpreter,
1814 "command script delete",
1815 "Delete a scripted command.",
1816 NULL)
1817 {
1818 CommandArgumentEntry arg1;
1819 CommandArgumentData cmd_arg;
1820
1821 // Define the first (and only) variant of this arg.
1822 cmd_arg.arg_type = eArgTypeCommandName;
1823 cmd_arg.arg_repetition = eArgRepeatPlain;
1824
1825 // There is only one variant this argument could be; put it into the argument entry.
1826 arg1.push_back (cmd_arg);
1827
1828 // Push the data for the first argument into the m_arguments vector.
1829 m_arguments.push_back (arg1);
1830 }
1831
1832 ~CommandObjectCommandsScriptDelete ()
1833 {
1834 }
1835
1836 bool
1837 Execute
1838 (
1839 Args& args,
1840 CommandReturnObject &result
1841 )
1842 {
1843
1844 size_t argc = args.GetArgumentCount();
1845
1846 if (argc != 1)
1847 {
1848 result.AppendError ("'command script delete' requires one argument");
1849 result.SetStatus (eReturnStatusFailed);
1850 return false;
1851 }
1852
1853 const char* cmd_name = args.GetArgumentAtIndex(0);
1854
1855 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1856 {
1857 m_interpreter.RemoveUser(cmd_name);
1858 result.SetStatus (eReturnStatusSuccessFinishResult);
1859 }
1860 else
1861 {
1862 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1863 result.SetStatus (eReturnStatusFailed);
1864 }
1865
1866 return result.Succeeded();
1867
1868 }
1869};
1870
1871#pragma mark CommandObjectMultiwordCommandsScript
1872
1873//-------------------------------------------------------------------------
1874// CommandObjectMultiwordCommandsScript
1875//-------------------------------------------------------------------------
1876
1877class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1878{
1879public:
1880 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1881 CommandObjectMultiword (interpreter,
1882 "command script",
1883 "A set of commands for managing or customizing script commands.",
1884 "command script <subcommand> [<subcommand-options>]")
1885 {
1886 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1887 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1888 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1889 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Enrico Granata59df36f2011-10-17 21:45:27 +00001890 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001891 }
1892
1893 ~CommandObjectMultiwordCommandsScript ()
1894 {
1895 }
1896
1897};
1898
1899
Jim Ingham767af882010-07-07 03:36:20 +00001900#pragma mark CommandObjectMultiwordCommands
1901
1902//-------------------------------------------------------------------------
1903// CommandObjectMultiwordCommands
1904//-------------------------------------------------------------------------
1905
1906CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001907 CommandObjectMultiword (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +00001908 "command",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001909 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton40e48242011-04-20 22:55:21 +00001910 "command <subcommand> [<subcommand-options>]")
Jim Ingham767af882010-07-07 03:36:20 +00001911{
Greg Clayton238c0a12010-09-18 01:14:36 +00001912 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1913 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1914 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytond12aeab2011-04-20 16:37:46 +00001915 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Ingham6247dbe2011-07-12 03:12:18 +00001916 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001917 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Ingham767af882010-07-07 03:36:20 +00001918}
1919
1920CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1921{
1922}
1923