blob: 7bbf943913de381e170b75aab791e6929b761474 [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,
Enrico Granata01bc2d42012-05-31 01:09:06 +0000287 print_results,
288 eLazyBoolCalculate,
Jim Ingham949d5ac2011-02-18 00:54:25 +0000289 result);
Jim Ingham767af882010-07-07 03:36:20 +0000290 }
291 else
292 {
293 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
294 result.SetStatus (eReturnStatusFailed);
295 }
296 return result.Succeeded();
297
298 }
Enrico Granata01bc2d42012-05-31 01:09:06 +0000299
300 virtual const char*
301 GetRepeatCommand (Args &current_command_args, uint32_t index)
302 {
303 return "";
304 }
305
306 int
307 HandleArgumentCompletion (Args &input,
308 int &cursor_index,
309 int &cursor_char_position,
310 OptionElementVector &opt_element_vector,
311 int match_start_point,
312 int max_return_elements,
313 bool &word_complete,
314 StringList &matches)
315 {
316 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
317 completion_str.erase (cursor_char_position);
318
319 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
320 CommandCompletions::eDiskFileCompletion,
321 completion_str.c_str(),
322 match_start_point,
323 max_return_elements,
324 NULL,
325 word_complete,
326 matches);
327 return matches.GetSize();
328 }
Jim Ingham767af882010-07-07 03:36:20 +0000329};
330
Greg Claytonb3448432011-03-24 21:19:54 +0000331OptionDefinition
Jim Ingham949d5ac2011-02-18 00:54:25 +0000332CommandObjectCommandsSource::CommandOptions::g_option_table[] =
333{
334{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
335{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
336{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
337};
338
Jim Ingham767af882010-07-07 03:36:20 +0000339#pragma mark CommandObjectCommandsAlias
340//-------------------------------------------------------------------------
341// CommandObjectCommandsAlias
342//-------------------------------------------------------------------------
343
Enrico Granatac2a28252011-08-16 16:49:25 +0000344static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
345 "You must define a Python function with this signature:\n"
Enrico Granata6b1596d2011-08-16 23:24:13 +0000346 "def my_command_impl(debugger, args, result, dict):";
Enrico Granatac2a28252011-08-16 16:49:25 +0000347
348
Jim Ingham767af882010-07-07 03:36:20 +0000349class CommandObjectCommandsAlias : public CommandObject
350{
Enrico Granatac2a28252011-08-16 16:49:25 +0000351
Enrico Granatac2a28252011-08-16 16:49:25 +0000352
Jim Ingham767af882010-07-07 03:36:20 +0000353public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000354 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
355 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000356 "command alias",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000357 "Allow users to define their own debugger command abbreviations.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000358 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000359 {
360 SetHelpLong(
361 "'alias' allows the user to create a short-cut or abbreviation for long \n\
362 commands, multi-word commands, and commands that take particular options. \n\
363 Below are some simple examples of how one might use the 'alias' command: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000364 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000365 // command. \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000366 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000367 // command. Since breakpoint commands are two-word \n\
368 // commands, the user will still need to enter the \n\
369 // second word after 'bp', e.g. 'bp enable' or \n\
370 // 'bp delete'. \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000371 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000372 // two-word command 'breakpoint list'. \n\
Jim Ingham767af882010-07-07 03:36:20 +0000373 \nAn alias can include some options for the command, with the values either \n\
374 filled in at the time the alias is created, or specified as positional \n\
375 arguments, to be filled in when the alias is invoked. The following example \n\
376 shows how to create aliases with options: \n\
377 \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000378 'command alias bfl breakpoint set -f %1 -l %2' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000379 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
380 options already part of the alias. So if the user wants to set a breakpoint \n\
381 by file and line without explicitly having to use the -f and -l options, the \n\
382 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
383 for the actual arguments that will be passed when the alias command is used. \n\
384 The number in the placeholder refers to the position/order the actual value \n\
Jim Ingham536f6332011-08-18 02:29:05 +0000385 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
Jim Ingham767af882010-07-07 03:36:20 +0000386 will be replaced with the first argument, all the occurrences of '%2' in the \n\
387 alias will be replaced with the second argument, and so on. This also allows \n\
388 actual arguments to be used multiple times within an alias (see 'process \n\
Jim Ingham536f6332011-08-18 02:29:05 +0000389 launch' example below). \n\
390 Note: the positional arguments must substitute as whole words in the resultant\n\
391 command, so you can't at present do something like:\n\
392 \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000393 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
Jim Ingham536f6332011-08-18 02:29:05 +0000394 \n\
395 to get the file extension \".cpp\" automatically appended. For more complex\n\
396 aliasing, use the \"command regex\" command instead.\n\
397 \nSo in the 'bfl' case, the actual file value will be \n\
Jim Ingham767af882010-07-07 03:36:20 +0000398 filled in with the first argument following 'bfl' and the actual line number \n\
399 value will be filled in with the second argument. The user would use this \n\
400 alias as follows: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000401 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000402 <... some time later ...> \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000403 (lldb) bfl my-file.c 137 \n\
Jim Ingham767af882010-07-07 03:36:20 +0000404 \nThis would be the same as if the user had entered \n\
405 'breakpoint set -f my-file.c -l 137'. \n\
406 \nAnother example: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000407 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000408 (lldb) pltty /dev/tty0 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000409 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000410 \nIf the user always wanted to pass the same value to a particular option, the \n\
411 alias could be defined with that value directly in the alias as a constant, \n\
412 rather than using a positional placeholder: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000413 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000414 // 3 of whatever file is indicated. \n");
Jim Ingham767af882010-07-07 03:36:20 +0000415
Caroline Tice43b014a2010-10-04 22:28:36 +0000416 CommandArgumentEntry arg1;
417 CommandArgumentEntry arg2;
418 CommandArgumentEntry arg3;
419 CommandArgumentData alias_arg;
420 CommandArgumentData cmd_arg;
421 CommandArgumentData options_arg;
422
423 // Define the first (and only) variant of this arg.
424 alias_arg.arg_type = eArgTypeAliasName;
425 alias_arg.arg_repetition = eArgRepeatPlain;
426
427 // There is only one variant this argument could be; put it into the argument entry.
428 arg1.push_back (alias_arg);
429
430 // Define the first (and only) variant of this arg.
431 cmd_arg.arg_type = eArgTypeCommandName;
432 cmd_arg.arg_repetition = eArgRepeatPlain;
433
434 // There is only one variant this argument could be; put it into the argument entry.
435 arg2.push_back (cmd_arg);
436
437 // Define the first (and only) variant of this arg.
438 options_arg.arg_type = eArgTypeAliasOptions;
439 options_arg.arg_repetition = eArgRepeatOptional;
440
441 // There is only one variant this argument could be; put it into the argument entry.
442 arg3.push_back (options_arg);
443
444 // Push the data for the first argument into the m_arguments vector.
445 m_arguments.push_back (arg1);
446 m_arguments.push_back (arg2);
447 m_arguments.push_back (arg3);
Jim Ingham767af882010-07-07 03:36:20 +0000448 }
449
450 ~CommandObjectCommandsAlias ()
451 {
452 }
453
Caroline Ticee0da7a52010-12-09 22:52:49 +0000454 bool
455 WantsRawCommandString ()
456 {
457 return true;
458 }
459
460 bool
461 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
462 {
463 Args args (raw_command_line);
464 std::string raw_command_string (raw_command_line);
465
466 size_t argc = args.GetArgumentCount();
467
468 if (argc < 2)
469 {
470 result.AppendError ("'alias' requires at least two arguments");
471 result.SetStatus (eReturnStatusFailed);
472 return false;
473 }
474
475 // Get the alias command.
476
477 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatac2a28252011-08-16 16:49:25 +0000478
Caroline Ticee0da7a52010-12-09 22:52:49 +0000479 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
480 // does the stripping itself.
481 size_t pos = raw_command_string.find (alias_command);
482 if (pos == 0)
483 {
484 raw_command_string = raw_command_string.substr (alias_command.size());
485 pos = raw_command_string.find_first_not_of (' ');
486 if ((pos != std::string::npos) && (pos > 0))
487 raw_command_string = raw_command_string.substr (pos);
488 }
489 else
490 {
491 result.AppendError ("Error parsing command string. No alias created.");
492 result.SetStatus (eReturnStatusFailed);
493 return false;
494 }
495
496
497 // Verify that the command is alias-able.
498 if (m_interpreter.CommandExists (alias_command.c_str()))
499 {
500 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
501 alias_command.c_str());
502 result.SetStatus (eReturnStatusFailed);
503 return false;
504 }
505
506 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
507 // raw_command_string is returned with the name of the command object stripped off the front.
508 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
509
510 if (!cmd_obj)
511 {
Greg Clayton9c236732011-10-26 00:56:27 +0000512 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
Caroline Ticee0da7a52010-12-09 22:52:49 +0000513 " No alias created.", raw_command_string.c_str());
514 result.SetStatus (eReturnStatusFailed);
515 return false;
516 }
517 else if (!cmd_obj->WantsRawCommandString ())
518 {
519 // Note that args was initialized with the original command, and has not been updated to this point.
520 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
521 return Execute (args, result);
522 }
523 else
524 {
525 // Verify & handle any options/arguments passed to the alias command
526
527 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
528 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
529
Caroline Tice5ddbe212011-05-06 21:37:15 +0000530 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
531
532 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Ticee0da7a52010-12-09 22:52:49 +0000533 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000534 result.AppendError ("Unable to create requested alias.\n");
535 result.SetStatus (eReturnStatusFailed);
536 return false;
Caroline Ticee0da7a52010-12-09 22:52:49 +0000537 }
538
539 // Create the alias
540 if (m_interpreter.AliasExists (alias_command.c_str())
541 || m_interpreter.UserCommandExists (alias_command.c_str()))
542 {
543 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
544 if (temp_option_arg_sp.get())
545 {
546 if (option_arg_vector->size() == 0)
547 m_interpreter.RemoveAliasOptions (alias_command.c_str());
548 }
549 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
550 alias_command.c_str());
551 }
552
Caroline Tice56d2fc42010-12-14 18:51:39 +0000553 if (cmd_obj_sp)
554 {
555 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
556 if (option_arg_vector->size() > 0)
557 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
558 result.SetStatus (eReturnStatusSuccessFinishNoResult);
559 }
560 else
561 {
562 result.AppendError ("Unable to create requested alias.\n");
563 result.SetStatus (eReturnStatusFailed);
564 }
Caroline Ticee0da7a52010-12-09 22:52:49 +0000565 }
566 return result.Succeeded();
567 }
Jim Ingham767af882010-07-07 03:36:20 +0000568
569 bool
570 Execute
571 (
Jim Ingham767af882010-07-07 03:36:20 +0000572 Args& args,
573 CommandReturnObject &result
574 )
575 {
Caroline Tice8bb61f02010-09-21 23:25:40 +0000576 size_t argc = args.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000577
578 if (argc < 2)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000579 {
Jim Ingham767af882010-07-07 03:36:20 +0000580 result.AppendError ("'alias' requires at least two arguments");
581 result.SetStatus (eReturnStatusFailed);
582 return false;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000583 }
Jim Ingham767af882010-07-07 03:36:20 +0000584
585 const std::string alias_command = args.GetArgumentAtIndex(0);
586 const std::string actual_command = args.GetArgumentAtIndex(1);
587
588 args.Shift(); // Shift the alias command word off the argument vector.
589 args.Shift(); // Shift the old command word off the argument vector.
590
591 // Verify that the command is alias'able, and get the appropriate command object.
592
Greg Clayton238c0a12010-09-18 01:14:36 +0000593 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000594 {
595 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
596 alias_command.c_str());
597 result.SetStatus (eReturnStatusFailed);
598 }
599 else
600 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000601 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Ingham767af882010-07-07 03:36:20 +0000602 CommandObjectSP subcommand_obj_sp;
603 bool use_subcommand = false;
604 if (command_obj_sp.get())
605 {
606 CommandObject *cmd_obj = command_obj_sp.get();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000607 CommandObject *sub_cmd_obj = NULL;
Jim Ingham767af882010-07-07 03:36:20 +0000608 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
609 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
610
Caroline Ticee0da7a52010-12-09 22:52:49 +0000611 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Ingham767af882010-07-07 03:36:20 +0000612 {
613 if (argc >= 3)
614 {
615 const std::string sub_command = args.GetArgumentAtIndex(0);
616 assert (sub_command.length() != 0);
617 subcommand_obj_sp =
618 (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
619 if (subcommand_obj_sp.get())
620 {
621 sub_cmd_obj = subcommand_obj_sp.get();
622 use_subcommand = true;
623 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Ticee0da7a52010-12-09 22:52:49 +0000624 cmd_obj = sub_cmd_obj;
Jim Ingham767af882010-07-07 03:36:20 +0000625 }
626 else
627 {
Caroline Tice5d53b622010-11-02 19:00:04 +0000628 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
629 "Unable to create alias.\n",
630 sub_command.c_str(), actual_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000631 result.SetStatus (eReturnStatusFailed);
632 return false;
633 }
634 }
635 }
636
637 // Verify & handle any options/arguments passed to the alias command
638
639 if (args.GetArgumentCount () > 0)
640 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000641 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
642 if (use_subcommand)
643 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
644
645 std::string args_string;
646 args.GetCommandString (args_string);
647
648 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
649 {
650 result.AppendError ("Unable to create requested alias.\n");
651 result.SetStatus (eReturnStatusFailed);
652 return false;
653 }
Jim Ingham767af882010-07-07 03:36:20 +0000654 }
655
656 // Create the alias.
657
Greg Clayton238c0a12010-09-18 01:14:36 +0000658 if (m_interpreter.AliasExists (alias_command.c_str())
659 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000660 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000661 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Ingham767af882010-07-07 03:36:20 +0000662 if (tmp_option_arg_sp.get())
663 {
664 if (option_arg_vector->size() == 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000665 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000666 }
667 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
668 alias_command.c_str());
669 }
670
671 if (use_subcommand)
Greg Clayton238c0a12010-09-18 01:14:36 +0000672 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000673 else
Greg Clayton238c0a12010-09-18 01:14:36 +0000674 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000675 if (option_arg_vector->size() > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000676 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000677 result.SetStatus (eReturnStatusSuccessFinishNoResult);
678 }
679 else
680 {
681 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
682 result.SetStatus (eReturnStatusFailed);
Caroline Ticee6866a32010-10-28 23:17:48 +0000683 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000684 }
685 }
686
687 return result.Succeeded();
688 }
689};
690
691#pragma mark CommandObjectCommandsUnalias
692//-------------------------------------------------------------------------
693// CommandObjectCommandsUnalias
694//-------------------------------------------------------------------------
695
696class CommandObjectCommandsUnalias : public CommandObject
697{
698public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000699 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
700 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000701 "command unalias",
Caroline Tice146292c2010-09-12 04:56:10 +0000702 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000703 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000704 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000705 CommandArgumentEntry arg;
706 CommandArgumentData alias_arg;
707
708 // Define the first (and only) variant of this arg.
709 alias_arg.arg_type = eArgTypeAliasName;
710 alias_arg.arg_repetition = eArgRepeatPlain;
711
712 // There is only one variant this argument could be; put it into the argument entry.
713 arg.push_back (alias_arg);
714
715 // Push the data for the first argument into the m_arguments vector.
716 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000717 }
718
719 ~CommandObjectCommandsUnalias()
720 {
721 }
722
723
724 bool
725 Execute
726 (
Jim Ingham767af882010-07-07 03:36:20 +0000727 Args& args,
728 CommandReturnObject &result
729 )
730 {
731 CommandObject::CommandMap::iterator pos;
732 CommandObject *cmd_obj;
733
734 if (args.GetArgumentCount() != 0)
735 {
736 const char *command_name = args.GetArgumentAtIndex(0);
Greg Clayton238c0a12010-09-18 01:14:36 +0000737 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Ingham767af882010-07-07 03:36:20 +0000738 if (cmd_obj)
739 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000740 if (m_interpreter.CommandExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000741 {
742 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
743 command_name);
744 result.SetStatus (eReturnStatusFailed);
745 }
746 else
747 {
748
Greg Clayton238c0a12010-09-18 01:14:36 +0000749 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Ingham767af882010-07-07 03:36:20 +0000750 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000751 if (m_interpreter.AliasExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000752 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
753 command_name);
754 else
755 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
756 result.SetStatus (eReturnStatusFailed);
757 }
758 else
759 result.SetStatus (eReturnStatusSuccessFinishNoResult);
760 }
761 }
762 else
763 {
764 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
765 "current list of commands.\n",
766 command_name);
767 result.SetStatus (eReturnStatusFailed);
768 }
769 }
770 else
771 {
772 result.AppendError ("must call 'unalias' with a valid alias");
773 result.SetStatus (eReturnStatusFailed);
774 }
775
776 return result.Succeeded();
777 }
778};
779
Greg Claytond12aeab2011-04-20 16:37:46 +0000780#pragma mark CommandObjectCommandsAddRegex
781//-------------------------------------------------------------------------
782// CommandObjectCommandsAddRegex
783//-------------------------------------------------------------------------
784
785class CommandObjectCommandsAddRegex : public CommandObject
786{
787public:
788 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
789 CommandObject (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000790 "command regex",
Greg Claytond12aeab2011-04-20 16:37:46 +0000791 "Allow the user to create a regular expression command.",
Greg Clayton40e48242011-04-20 22:55:21 +0000792 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytond12aeab2011-04-20 16:37:46 +0000793 m_options (interpreter)
794 {
Greg Clayton40e48242011-04-20 22:55:21 +0000795 SetHelpLong(
796"This command allows the user to create powerful regular expression commands\n"
797"with substitutions. The regular expressions and substitutions are specified\n"
798"using the regular exression substitution format of:\n"
799"\n"
800" s/<regex>/<subst>/\n"
801"\n"
802"<regex> is a regular expression that can use parenthesis to capture regular\n"
803"expression input and substitute the captured matches in the output using %1\n"
804"for the first match, %2 for the second, and so on.\n"
805"\n"
806"The regular expressions can all be specified on the command line if more than\n"
807"one argument is provided. If just the command name is provided on the command\n"
808"line, then the regular expressions and substitutions can be entered on separate\n"
809" lines, followed by an empty line to terminate the command definition.\n"
810"\n"
811"EXAMPLES\n"
812"\n"
813"The following example with define a regular expression command named 'f' that\n"
814"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
815"a number follows 'f':\n"
816"(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
817 );
Greg Claytond12aeab2011-04-20 16:37:46 +0000818 }
819
820 ~CommandObjectCommandsAddRegex()
821 {
822 }
823
824
825 bool
826 Execute (Args& args, CommandReturnObject &result)
827 {
Greg Clayton40e48242011-04-20 22:55:21 +0000828 const size_t argc = args.GetArgumentCount();
829 if (argc == 0)
Greg Claytond12aeab2011-04-20 16:37:46 +0000830 {
Jason Molenda4049bc32011-11-10 22:43:35 +0000831 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton40e48242011-04-20 22:55:21 +0000832 result.SetStatus (eReturnStatusFailed);
833 }
834 else
835 {
836 Error error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000837 const char *name = args.GetArgumentAtIndex(0);
Greg Claytond12aeab2011-04-20 16:37:46 +0000838 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
839 name,
840 m_options.GetHelp (),
841 m_options.GetSyntax (),
842 10));
Greg Clayton40e48242011-04-20 22:55:21 +0000843
844 if (argc == 1)
Greg Claytond12aeab2011-04-20 16:37:46 +0000845 {
Greg Clayton40e48242011-04-20 22:55:21 +0000846 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
847 if (reader_sp)
848 {
849 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
Greg Claytond12aeab2011-04-20 16:37:46 +0000850 this, // baton
851 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton40e48242011-04-20 22:55:21 +0000852 NULL, // end token
Greg Claytond12aeab2011-04-20 16:37:46 +0000853 "> ", // prompt
Greg Clayton40e48242011-04-20 22:55:21 +0000854 true); // echo input
855 if (error.Success())
856 {
857 m_interpreter.GetDebugger().PushInputReader (reader_sp);
858 result.SetStatus (eReturnStatusSuccessFinishNoResult);
859 return true;
860 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000861 }
862 }
Greg Clayton40e48242011-04-20 22:55:21 +0000863 else
864 {
865 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
866 {
867 llvm::StringRef arg_strref (args.GetArgumentAtIndex(arg_idx));
868 error = AppendRegexSubstitution (arg_strref);
869 if (error.Fail())
870 break;
871 }
872
873 if (error.Success())
874 {
875 AddRegexCommandToInterpreter();
876 }
877 }
878 if (error.Fail())
879 {
880 result.AppendError (error.AsCString());
881 result.SetStatus (eReturnStatusFailed);
882 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000883 }
Greg Clayton40e48242011-04-20 22:55:21 +0000884
Greg Claytond12aeab2011-04-20 16:37:46 +0000885 return result.Succeeded();
886 }
887
Greg Clayton40e48242011-04-20 22:55:21 +0000888 Error
889 AppendRegexSubstitution (const llvm::StringRef &regex_sed)
Greg Claytond12aeab2011-04-20 16:37:46 +0000890 {
Greg Clayton40e48242011-04-20 22:55:21 +0000891 Error error;
892
893 if (m_regex_cmd_ap.get() == NULL)
Greg Claytond12aeab2011-04-20 16:37:46 +0000894 {
Greg Clayton40e48242011-04-20 22:55:21 +0000895 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
896 (int)regex_sed.size(),
897 regex_sed.data());
898 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000899 }
Greg Clayton40e48242011-04-20 22:55:21 +0000900
901 size_t regex_sed_size = regex_sed.size();
902
903 if (regex_sed_size <= 1)
904 {
905 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
906 (int)regex_sed.size(),
907 regex_sed.data());
908 return error;
909 }
910
911 if (regex_sed[0] != 's')
912 {
913 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
914 (int)regex_sed.size(),
915 regex_sed.data());
916 return error;
917 }
918 const size_t first_separator_char_pos = 1;
919 // use the char that follows 's' as the regex separator character
920 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
921 const char separator_char = regex_sed[first_separator_char_pos];
922 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
923
924 if (second_separator_char_pos == std::string::npos)
925 {
926 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
927 separator_char,
928 (int)(regex_sed.size() - first_separator_char_pos - 1),
929 regex_sed.data() + (first_separator_char_pos + 1));
930 return error;
931 }
932
933 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
934
935 if (third_separator_char_pos == std::string::npos)
936 {
937 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
938 separator_char,
939 (int)(regex_sed.size() - second_separator_char_pos - 1),
940 regex_sed.data() + (second_separator_char_pos + 1));
941 return error;
942 }
943
944 if (third_separator_char_pos != regex_sed_size - 1)
945 {
946 // Make sure that everything that follows the last regex
947 // separator char
948 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
949 {
950 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
951 (int)third_separator_char_pos + 1,
952 regex_sed.data(),
953 (int)(regex_sed.size() - third_separator_char_pos - 1),
954 regex_sed.data() + (third_separator_char_pos + 1));
955 return error;
956 }
957
958 }
959 else if (first_separator_char_pos + 1 == second_separator_char_pos)
960 {
961 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
962 separator_char,
963 separator_char,
964 separator_char,
965 (int)regex_sed.size(),
966 regex_sed.data());
967 return error;
968 }
969 else if (second_separator_char_pos + 1 == third_separator_char_pos)
970 {
971 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
972 separator_char,
973 separator_char,
974 separator_char,
975 (int)regex_sed.size(),
976 regex_sed.data());
977 return error;
978 }
979 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
980 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
981 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
982 subst.c_str());
983 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000984 }
985
986 void
Greg Clayton40e48242011-04-20 22:55:21 +0000987 AddRegexCommandToInterpreter()
Greg Claytond12aeab2011-04-20 16:37:46 +0000988 {
989 if (m_regex_cmd_ap.get())
990 {
991 if (m_regex_cmd_ap->HasRegexEntries())
992 {
993 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
994 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
995 }
996 }
997 }
998
Greg Clayton40e48242011-04-20 22:55:21 +0000999 void
1000 InputReaderDidCancel()
1001 {
1002 m_regex_cmd_ap.reset();
1003 }
1004
Greg Claytond12aeab2011-04-20 16:37:46 +00001005 static size_t
1006 InputReaderCallback (void *baton,
1007 InputReader &reader,
1008 lldb::InputReaderAction notification,
1009 const char *bytes,
1010 size_t bytes_len);
1011private:
1012 std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1013
1014 class CommandOptions : public Options
1015 {
1016 public:
1017
1018 CommandOptions (CommandInterpreter &interpreter) :
1019 Options (interpreter)
1020 {
1021 }
1022
1023 virtual
1024 ~CommandOptions (){}
1025
1026 virtual Error
1027 SetOptionValue (uint32_t option_idx, const char *option_arg)
1028 {
1029 Error error;
1030 char short_option = (char) m_getopt_table[option_idx].val;
1031
1032 switch (short_option)
1033 {
1034 case 'h':
1035 m_help.assign (option_arg);
1036 break;
1037 case 's':
1038 m_syntax.assign (option_arg);
1039 break;
1040
1041 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001042 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytond12aeab2011-04-20 16:37:46 +00001043 break;
1044 }
1045
1046 return error;
1047 }
1048
1049 void
1050 OptionParsingStarting ()
1051 {
1052 m_help.clear();
1053 m_syntax.clear();
1054 }
1055
1056 const OptionDefinition*
1057 GetDefinitions ()
1058 {
1059 return g_option_table;
1060 }
1061
1062 // Options table: Required for subclasses of Options.
1063
1064 static OptionDefinition g_option_table[];
1065
1066 const char *
1067 GetHelp ()
1068 {
1069 if (m_help.empty())
1070 return NULL;
1071 return m_help.c_str();
1072 }
1073 const char *
1074 GetSyntax ()
1075 {
1076 if (m_syntax.empty())
1077 return NULL;
1078 return m_syntax.c_str();
1079 }
1080 // Instance variables to hold the values for command options.
1081 protected:
1082 std::string m_help;
1083 std::string m_syntax;
1084 };
1085
1086 CommandOptions m_options;
1087
1088 virtual Options *
1089 GetOptions ()
1090 {
1091 return &m_options;
1092 }
1093
1094};
1095
1096size_t
1097CommandObjectCommandsAddRegex::InputReaderCallback (void *baton,
1098 InputReader &reader,
1099 lldb::InputReaderAction notification,
1100 const char *bytes,
1101 size_t bytes_len)
1102{
1103 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
Caroline Tice892fadd2011-06-16 16:27:19 +00001104 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Greg Claytond12aeab2011-04-20 16:37:46 +00001105
1106 switch (notification)
1107 {
1108 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00001109 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001110 {
1111 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1112 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1113 out_stream->Flush();
1114 }
Greg Claytond12aeab2011-04-20 16:37:46 +00001115 break;
1116 case eInputReaderReactivate:
1117 break;
1118
1119 case eInputReaderDeactivate:
1120 break;
Caroline Tice4a348082011-05-02 20:41:46 +00001121
1122 case eInputReaderAsynchronousOutputWritten:
1123 break;
1124
Greg Claytond12aeab2011-04-20 16:37:46 +00001125 case eInputReaderGotToken:
Greg Clayton40e48242011-04-20 22:55:21 +00001126 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1127 --bytes_len;
Greg Claytond12aeab2011-04-20 16:37:46 +00001128 if (bytes_len == 0)
1129 reader.SetIsDone(true);
1130 else if (bytes)
1131 {
Greg Clayton40e48242011-04-20 22:55:21 +00001132 llvm::StringRef bytes_strref (bytes, bytes_len);
1133 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1134 if (error.Fail())
Greg Claytond12aeab2011-04-20 16:37:46 +00001135 {
Caroline Tice892fadd2011-06-16 16:27:19 +00001136 if (!batch_mode)
1137 {
1138 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1139 out_stream->Printf("error: %s\n", error.AsCString());
1140 out_stream->Flush();
1141 }
Greg Clayton40e48242011-04-20 22:55:21 +00001142 add_regex_cmd->InputReaderDidCancel ();
1143 reader.SetIsDone (true);
Greg Claytond12aeab2011-04-20 16:37:46 +00001144 }
1145 }
1146 break;
1147
1148 case eInputReaderInterrupt:
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001149 {
1150 reader.SetIsDone (true);
Caroline Tice892fadd2011-06-16 16:27:19 +00001151 if (!batch_mode)
1152 {
1153 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1154 out_stream->PutCString("Regular expression command creations was cancelled.\n");
1155 out_stream->Flush();
1156 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +00001157 add_regex_cmd->InputReaderDidCancel ();
1158 }
Greg Claytond12aeab2011-04-20 16:37:46 +00001159 break;
1160
1161 case eInputReaderEndOfFile:
1162 reader.SetIsDone (true);
1163 break;
1164
1165 case eInputReaderDone:
Greg Clayton40e48242011-04-20 22:55:21 +00001166 add_regex_cmd->AddRegexCommandToInterpreter();
Greg Claytond12aeab2011-04-20 16:37:46 +00001167 break;
1168 }
1169
1170 return bytes_len;
1171}
1172
1173
1174OptionDefinition
1175CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1176{
Greg Clayton40e48242011-04-20 22:55:21 +00001177{ 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 +00001178{ 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 +00001179{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytond12aeab2011-04-20 16:37:46 +00001180};
1181
1182
Enrico Granata6b1596d2011-08-16 23:24:13 +00001183class CommandObjectPythonFunction : public CommandObject
1184{
1185private:
1186 std::string m_function_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001187 ScriptedCommandSynchronicity m_synchro;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001188
1189public:
1190
1191 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1192 std::string name,
Enrico Granata6010ace2011-11-07 22:57:04 +00001193 std::string funct,
1194 ScriptedCommandSynchronicity synch) :
Enrico Granata6b1596d2011-08-16 23:24:13 +00001195 CommandObject (interpreter,
1196 name.c_str(),
1197 (std::string("Run Python function ") + funct).c_str(),
1198 NULL),
Enrico Granata6010ace2011-11-07 22:57:04 +00001199 m_function_name(funct),
1200 m_synchro(synch)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001201 {
Enrico Granatae5e34cb2011-08-17 01:30:04 +00001202 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1203 if (scripter)
1204 {
1205 std::string docstring = scripter->GetDocumentationForItem(funct.c_str());
1206 if (!docstring.empty())
1207 SetHelpLong(docstring);
1208 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001209 }
1210
1211 virtual
1212 ~CommandObjectPythonFunction ()
1213 {
1214 }
1215
1216 virtual bool
1217 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
1218 {
1219 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1220
1221 Error error;
1222
1223 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1224 raw_command_line,
Enrico Granata6010ace2011-11-07 22:57:04 +00001225 m_synchro,
Enrico Granata6b1596d2011-08-16 23:24:13 +00001226 result,
1227 error) == false)
1228 {
1229 result.AppendError(error.AsCString());
1230 result.SetStatus(eReturnStatusFailed);
1231 }
1232 else
1233 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1234
1235 return result.Succeeded();
1236 }
1237
1238 virtual bool
1239 WantsRawCommandString ()
1240 {
1241 return true;
1242 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001243
Enrico Granata6b1596d2011-08-16 23:24:13 +00001244 bool
1245 Execute (Args& command,
1246 CommandReturnObject &result)
1247 {
1248 std::string cmd_string;
1249 command.GetCommandString(cmd_string);
1250 return ExecuteRawCommandString(cmd_string.c_str(), result);
1251 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001252
Enrico Granata6b1596d2011-08-16 23:24:13 +00001253 virtual bool
Enrico Granata6010ace2011-11-07 22:57:04 +00001254 IsRemovable ()
1255 {
1256 return true;
1257 }
1258
1259 const std::string&
1260 GetFunctionName ()
1261 {
1262 return m_function_name;
1263 }
1264
1265 ScriptedCommandSynchronicity
1266 GetSynchronicity ()
1267 {
1268 return m_synchro;
1269 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001270
1271};
1272
Enrico Granata59df36f2011-10-17 21:45:27 +00001273//-------------------------------------------------------------------------
1274// CommandObjectCommandsScriptImport
1275//-------------------------------------------------------------------------
1276
1277class CommandObjectCommandsScriptImport : public CommandObject
1278{
Enrico Granata6010ace2011-11-07 22:57:04 +00001279private:
1280
1281 class CommandOptions : public Options
1282 {
1283 public:
1284
1285 CommandOptions (CommandInterpreter &interpreter) :
1286 Options (interpreter)
1287 {
1288 }
1289
1290 virtual
1291 ~CommandOptions (){}
1292
1293 virtual Error
1294 SetOptionValue (uint32_t option_idx, const char *option_arg)
1295 {
1296 Error error;
1297 char short_option = (char) m_getopt_table[option_idx].val;
1298
1299 switch (short_option)
1300 {
1301 case 'r':
1302 m_allow_reload = true;
1303 break;
1304 default:
1305 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1306 break;
1307 }
1308
1309 return error;
1310 }
1311
1312 void
1313 OptionParsingStarting ()
1314 {
1315 m_allow_reload = false;
1316 }
1317
1318 const OptionDefinition*
1319 GetDefinitions ()
1320 {
1321 return g_option_table;
1322 }
1323
1324 // Options table: Required for subclasses of Options.
1325
1326 static OptionDefinition g_option_table[];
1327
1328 // Instance variables to hold the values for command options.
1329
1330 bool m_allow_reload;
1331 };
1332
1333 CommandOptions m_options;
1334
1335 virtual Options *
1336 GetOptions ()
1337 {
1338 return &m_options;
1339 }
1340
Enrico Granata59df36f2011-10-17 21:45:27 +00001341public:
1342 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1343 CommandObject (interpreter,
1344 "command script import",
1345 "Import a scripting module in LLDB.",
Enrico Granata6010ace2011-11-07 22:57:04 +00001346 NULL),
1347 m_options(interpreter)
Enrico Granata59df36f2011-10-17 21:45:27 +00001348 {
1349 CommandArgumentEntry arg1;
1350 CommandArgumentData cmd_arg;
1351
1352 // Define the first (and only) variant of this arg.
Enrico Granata6010ace2011-11-07 22:57:04 +00001353 cmd_arg.arg_type = eArgTypeFilename;
Enrico Granata59df36f2011-10-17 21:45:27 +00001354 cmd_arg.arg_repetition = eArgRepeatPlain;
1355
1356 // There is only one variant this argument could be; put it into the argument entry.
1357 arg1.push_back (cmd_arg);
1358
1359 // Push the data for the first argument into the m_arguments vector.
1360 m_arguments.push_back (arg1);
1361 }
1362
1363 ~CommandObjectCommandsScriptImport ()
1364 {
1365 }
1366
1367 bool
1368 Execute
1369 (
1370 Args& args,
1371 CommandReturnObject &result
1372 )
1373 {
1374
1375 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1376 {
1377 result.AppendError ("only scripting language supported for module importing is currently Python");
1378 result.SetStatus (eReturnStatusFailed);
1379 return false;
1380 }
1381
1382 size_t argc = args.GetArgumentCount();
1383
1384 if (argc != 1)
1385 {
1386 result.AppendError ("'command script import' requires one argument");
1387 result.SetStatus (eReturnStatusFailed);
1388 return false;
1389 }
1390
1391 std::string path = args.GetArgumentAtIndex(0);
1392 Error error;
1393
1394 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001395 m_options.m_allow_reload,
Enrico Granata59df36f2011-10-17 21:45:27 +00001396 error))
1397 {
1398 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1399 }
1400 else
1401 {
1402 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1403 result.SetStatus (eReturnStatusFailed);
1404 }
1405
1406 return result.Succeeded();
1407 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001408
1409 int
1410 HandleArgumentCompletion (Args &input,
1411 int &cursor_index,
1412 int &cursor_char_position,
1413 OptionElementVector &opt_element_vector,
1414 int match_start_point,
1415 int max_return_elements,
1416 bool &word_complete,
1417 StringList &matches)
1418 {
1419 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1420 completion_str.erase (cursor_char_position);
1421
1422 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1423 CommandCompletions::eDiskFileCompletion,
1424 completion_str.c_str(),
1425 match_start_point,
1426 max_return_elements,
1427 NULL,
1428 word_complete,
1429 matches);
1430 return matches.GetSize();
1431 }
Enrico Granata59df36f2011-10-17 21:45:27 +00001432};
Enrico Granata6b1596d2011-08-16 23:24:13 +00001433
Enrico Granata6010ace2011-11-07 22:57:04 +00001434OptionDefinition
1435CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1436{
1437 { 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)."},
1438 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1439};
1440
1441
Enrico Granata6b1596d2011-08-16 23:24:13 +00001442//-------------------------------------------------------------------------
1443// CommandObjectCommandsScriptAdd
1444//-------------------------------------------------------------------------
1445
1446class CommandObjectCommandsScriptAdd : public CommandObject
1447{
1448private:
1449
1450 class CommandOptions : public Options
1451 {
1452 public:
1453
1454 CommandOptions (CommandInterpreter &interpreter) :
1455 Options (interpreter)
1456 {
1457 }
1458
1459 virtual
1460 ~CommandOptions (){}
1461
1462 virtual Error
1463 SetOptionValue (uint32_t option_idx, const char *option_arg)
1464 {
1465 Error error;
1466 char short_option = (char) m_getopt_table[option_idx].val;
1467
1468 switch (short_option)
1469 {
1470 case 'f':
1471 m_funct_name = std::string(option_arg);
1472 break;
Enrico Granata6010ace2011-11-07 22:57:04 +00001473 case 's':
1474 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1475 if (!error.Success())
1476 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1477 break;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001478 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001479 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001480 break;
1481 }
1482
1483 return error;
1484 }
1485
1486 void
1487 OptionParsingStarting ()
1488 {
1489 m_funct_name = "";
Enrico Granata6010ace2011-11-07 22:57:04 +00001490 m_synchronous = eScriptedCommandSynchronicitySynchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001491 }
1492
1493 const OptionDefinition*
1494 GetDefinitions ()
1495 {
1496 return g_option_table;
1497 }
1498
1499 // Options table: Required for subclasses of Options.
1500
1501 static OptionDefinition g_option_table[];
1502
1503 // Instance variables to hold the values for command options.
1504
1505 std::string m_funct_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001506 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001507 };
1508
1509 CommandOptions m_options;
1510
1511 virtual Options *
1512 GetOptions ()
1513 {
1514 return &m_options;
1515 }
1516
1517 class PythonAliasReader : public InputReaderEZ
1518 {
1519 private:
1520 CommandInterpreter& m_interpreter;
1521 std::string m_cmd_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001522 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001523 StringList m_user_input;
1524 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1525 public:
1526 PythonAliasReader(Debugger& debugger,
1527 CommandInterpreter& interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001528 std::string cmd_name,
1529 ScriptedCommandSynchronicity synch) :
Enrico Granata6b1596d2011-08-16 23:24:13 +00001530 InputReaderEZ(debugger),
1531 m_interpreter(interpreter),
1532 m_cmd_name(cmd_name),
Enrico Granata6010ace2011-11-07 22:57:04 +00001533 m_synchronous(synch),
Enrico Granata6b1596d2011-08-16 23:24:13 +00001534 m_user_input()
1535 {}
1536
1537 virtual
1538 ~PythonAliasReader()
1539 {
1540 }
1541
1542 virtual void ActivateHandler(HandlerData& data)
1543 {
1544 StreamSP out_stream = data.GetOutStream();
1545 bool batch_mode = data.GetBatchMode();
1546 if (!batch_mode)
1547 {
1548 out_stream->Printf ("%s\n", g_python_command_instructions);
1549 if (data.reader.GetPrompt())
1550 out_stream->Printf ("%s", data.reader.GetPrompt());
1551 out_stream->Flush();
1552 }
1553 }
1554
1555 virtual void ReactivateHandler(HandlerData& data)
1556 {
1557 StreamSP out_stream = data.GetOutStream();
1558 bool batch_mode = data.GetBatchMode();
1559 if (data.reader.GetPrompt() && !batch_mode)
1560 {
1561 out_stream->Printf ("%s", data.reader.GetPrompt());
1562 out_stream->Flush();
1563 }
1564 }
1565 virtual void GotTokenHandler(HandlerData& data)
1566 {
1567 StreamSP out_stream = data.GetOutStream();
1568 bool batch_mode = data.GetBatchMode();
1569 if (data.bytes && data.bytes_len)
1570 {
1571 m_user_input.AppendString(data.bytes, data.bytes_len);
1572 }
1573 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1574 {
1575 out_stream->Printf ("%s", data.reader.GetPrompt());
1576 out_stream->Flush();
1577 }
1578 }
1579 virtual void InterruptHandler(HandlerData& data)
1580 {
1581 StreamSP out_stream = data.GetOutStream();
1582 bool batch_mode = data.GetBatchMode();
1583 data.reader.SetIsDone (true);
1584 if (!batch_mode)
1585 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001586 out_stream->Printf ("Warning: No script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001587 out_stream->Flush();
1588 }
1589 }
1590 virtual void EOFHandler(HandlerData& data)
1591 {
1592 data.reader.SetIsDone (true);
1593 }
1594 virtual void DoneHandler(HandlerData& data)
1595 {
1596 StreamSP out_stream = data.GetOutStream();
1597
1598 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1599 if (!interpreter)
1600 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001601 out_stream->Printf ("Script interpreter missing: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001602 out_stream->Flush();
1603 return;
1604 }
Enrico Granata400105d2012-03-06 23:42:15 +00001605 std::string funct_name_str;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001606 if (!interpreter->GenerateScriptAliasFunction (m_user_input,
Enrico Granata400105d2012-03-06 23:42:15 +00001607 funct_name_str))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001608 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001609 out_stream->Printf ("Unable to create function: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001610 out_stream->Flush();
1611 return;
1612 }
Enrico Granata400105d2012-03-06 23:42:15 +00001613 if (funct_name_str.empty())
Enrico Granata6b1596d2011-08-16 23:24:13 +00001614 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001615 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001616 out_stream->Flush();
1617 return;
1618 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001619 // everything should be fine now, let's add this alias
1620
1621 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1622 m_cmd_name,
Enrico Granata400105d2012-03-06 23:42:15 +00001623 funct_name_str.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001624 m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001625
Enrico Granata6010ace2011-11-07 22:57:04 +00001626 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001627 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001628 out_stream->Printf ("Unable to add selected command: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001629 out_stream->Flush();
1630 return;
1631 }
1632 }
1633 };
1634
1635public:
1636 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1637 CommandObject (interpreter,
1638 "command script add",
1639 "Add a scripted function as an LLDB command.",
1640 NULL),
1641 m_options (interpreter)
1642 {
1643 CommandArgumentEntry arg1;
1644 CommandArgumentData cmd_arg;
1645
1646 // Define the first (and only) variant of this arg.
1647 cmd_arg.arg_type = eArgTypeCommandName;
1648 cmd_arg.arg_repetition = eArgRepeatPlain;
1649
1650 // There is only one variant this argument could be; put it into the argument entry.
1651 arg1.push_back (cmd_arg);
1652
1653 // Push the data for the first argument into the m_arguments vector.
1654 m_arguments.push_back (arg1);
1655 }
1656
1657 ~CommandObjectCommandsScriptAdd ()
1658 {
1659 }
1660
1661 bool
1662 Execute
1663 (
1664 Args& args,
1665 CommandReturnObject &result
1666 )
1667 {
Enrico Granatae5e34cb2011-08-17 01:30:04 +00001668
1669 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1670 {
1671 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1672 result.SetStatus (eReturnStatusFailed);
1673 return false;
1674 }
1675
Enrico Granata6b1596d2011-08-16 23:24:13 +00001676 size_t argc = args.GetArgumentCount();
1677
1678 if (argc != 1)
1679 {
1680 result.AppendError ("'command script add' requires one argument");
1681 result.SetStatus (eReturnStatusFailed);
1682 return false;
1683 }
1684
1685 std::string cmd_name = args.GetArgumentAtIndex(0);
1686
1687 if (m_options.m_funct_name.empty())
1688 {
1689 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1690 m_interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001691 cmd_name,
1692 m_options.m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001693
1694 if (reader_sp)
1695 {
1696
1697 InputReaderEZ::InitializationParameters ipr;
1698
1699 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
1700 if (err.Success())
1701 {
1702 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1703 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1704 }
1705 else
1706 {
1707 result.AppendError (err.AsCString());
1708 result.SetStatus (eReturnStatusFailed);
1709 }
1710 }
1711 else
1712 {
1713 result.AppendError("out of memory");
1714 result.SetStatus (eReturnStatusFailed);
1715 }
1716 }
1717 else
1718 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001719 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1720 cmd_name,
1721 m_options.m_funct_name,
1722 m_options.m_synchronous));
1723 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001724 {
1725 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1726 }
1727 else
1728 {
1729 result.AppendError("cannot add command");
1730 result.SetStatus (eReturnStatusFailed);
1731 }
1732 }
1733
1734 return result.Succeeded();
1735
1736 }
1737};
1738
Enrico Granata6010ace2011-11-07 22:57:04 +00001739static OptionEnumValueElement g_script_synchro_type[] =
1740{
1741 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1742 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1743 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1744 { 0, NULL, NULL }
1745};
1746
Enrico Granata6b1596d2011-08-16 23:24:13 +00001747OptionDefinition
1748CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1749{
Enrico Granata91544802011-09-06 19:20:51 +00001750 { 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 +00001751 { 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 +00001752 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1753};
1754
1755//-------------------------------------------------------------------------
1756// CommandObjectCommandsScriptList
1757//-------------------------------------------------------------------------
1758
1759class CommandObjectCommandsScriptList : public CommandObject
1760{
1761private:
Enrico Granata6010ace2011-11-07 22:57:04 +00001762
Enrico Granata6b1596d2011-08-16 23:24:13 +00001763public:
1764 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
1765 CommandObject (interpreter,
1766 "command script list",
1767 "List defined scripted commands.",
1768 NULL)
1769 {
1770 }
1771
1772 ~CommandObjectCommandsScriptList ()
1773 {
1774 }
1775
1776 bool
1777 Execute
1778 (
1779 Args& args,
1780 CommandReturnObject &result
1781 )
1782 {
1783
1784 m_interpreter.GetHelp(result,
1785 CommandInterpreter::eCommandTypesUserDef);
1786
1787 result.SetStatus (eReturnStatusSuccessFinishResult);
1788
1789 return true;
1790
1791
1792 }
1793};
1794
1795//-------------------------------------------------------------------------
1796// CommandObjectCommandsScriptClear
1797//-------------------------------------------------------------------------
1798
1799class CommandObjectCommandsScriptClear : public CommandObject
1800{
1801private:
1802
1803public:
1804 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
1805 CommandObject (interpreter,
1806 "command script clear",
1807 "Delete all scripted commands.",
1808 NULL)
1809 {
1810 }
1811
1812 ~CommandObjectCommandsScriptClear ()
1813 {
1814 }
1815
1816 bool
1817 Execute
1818 (
1819 Args& args,
1820 CommandReturnObject &result
1821 )
1822 {
1823
1824 m_interpreter.RemoveAllUser();
1825
1826 result.SetStatus (eReturnStatusSuccessFinishResult);
1827
1828 return true;
1829
1830
1831 }
1832};
1833
1834//-------------------------------------------------------------------------
1835// CommandObjectCommandsScriptDelete
1836//-------------------------------------------------------------------------
1837
1838class CommandObjectCommandsScriptDelete : public CommandObject
1839{
1840private:
1841
1842public:
1843 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
1844 CommandObject (interpreter,
1845 "command script delete",
1846 "Delete a scripted command.",
1847 NULL)
1848 {
1849 CommandArgumentEntry arg1;
1850 CommandArgumentData cmd_arg;
1851
1852 // Define the first (and only) variant of this arg.
1853 cmd_arg.arg_type = eArgTypeCommandName;
1854 cmd_arg.arg_repetition = eArgRepeatPlain;
1855
1856 // There is only one variant this argument could be; put it into the argument entry.
1857 arg1.push_back (cmd_arg);
1858
1859 // Push the data for the first argument into the m_arguments vector.
1860 m_arguments.push_back (arg1);
1861 }
1862
1863 ~CommandObjectCommandsScriptDelete ()
1864 {
1865 }
1866
1867 bool
1868 Execute
1869 (
1870 Args& args,
1871 CommandReturnObject &result
1872 )
1873 {
1874
1875 size_t argc = args.GetArgumentCount();
1876
1877 if (argc != 1)
1878 {
1879 result.AppendError ("'command script delete' requires one argument");
1880 result.SetStatus (eReturnStatusFailed);
1881 return false;
1882 }
1883
1884 const char* cmd_name = args.GetArgumentAtIndex(0);
1885
1886 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1887 {
1888 m_interpreter.RemoveUser(cmd_name);
1889 result.SetStatus (eReturnStatusSuccessFinishResult);
1890 }
1891 else
1892 {
1893 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1894 result.SetStatus (eReturnStatusFailed);
1895 }
1896
1897 return result.Succeeded();
1898
1899 }
1900};
1901
1902#pragma mark CommandObjectMultiwordCommandsScript
1903
1904//-------------------------------------------------------------------------
1905// CommandObjectMultiwordCommandsScript
1906//-------------------------------------------------------------------------
1907
1908class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1909{
1910public:
1911 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1912 CommandObjectMultiword (interpreter,
1913 "command script",
1914 "A set of commands for managing or customizing script commands.",
1915 "command script <subcommand> [<subcommand-options>]")
1916 {
1917 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1918 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1919 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1920 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Enrico Granata59df36f2011-10-17 21:45:27 +00001921 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001922 }
1923
1924 ~CommandObjectMultiwordCommandsScript ()
1925 {
1926 }
1927
1928};
1929
1930
Jim Ingham767af882010-07-07 03:36:20 +00001931#pragma mark CommandObjectMultiwordCommands
1932
1933//-------------------------------------------------------------------------
1934// CommandObjectMultiwordCommands
1935//-------------------------------------------------------------------------
1936
1937CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001938 CommandObjectMultiword (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +00001939 "command",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001940 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton40e48242011-04-20 22:55:21 +00001941 "command <subcommand> [<subcommand-options>]")
Jim Ingham767af882010-07-07 03:36:20 +00001942{
Greg Clayton238c0a12010-09-18 01:14:36 +00001943 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1944 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1945 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytond12aeab2011-04-20 16:37:46 +00001946 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Ingham6247dbe2011-07-12 03:12:18 +00001947 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001948 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Ingham767af882010-07-07 03:36:20 +00001949}
1950
1951CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1952{
1953}
1954