blob: 5999f7c89355d080c4e696f2d3c2d5fcd1532101 [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 Inghamda26bd22012-06-08 21:56:10 +000037class CommandObjectCommandsHistory : public CommandObjectParsed
Jim Ingham6247dbe2011-07-12 03:12:18 +000038{
Jim Inghamda26bd22012-06-08 21:56:10 +000039public:
40 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
41 CommandObjectParsed (interpreter,
42 "command history",
43 "Dump the history of commands in this session.",
44 NULL),
45 m_options (interpreter)
46 {
47 }
48
49 ~CommandObjectCommandsHistory () {}
50
51 virtual Options *
52 GetOptions ()
53 {
54 return &m_options;
55 }
56
57protected:
Jim Ingham6247dbe2011-07-12 03:12:18 +000058
59 class CommandOptions : public Options
60 {
61 public:
62
63 CommandOptions (CommandInterpreter &interpreter) :
64 Options (interpreter)
65 {
66 }
67
68 virtual
69 ~CommandOptions (){}
70
71 virtual Error
72 SetOptionValue (uint32_t option_idx, const char *option_arg)
73 {
74 Error error;
75 char short_option = (char) m_getopt_table[option_idx].val;
76 bool success;
77
78 switch (short_option)
79 {
80 case 'c':
81 m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
82 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000083 error.SetErrorStringWithFormat("invalid value for count: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000084 if (m_end_idx != 0)
85 m_end_idx--;
86 m_start_idx = 0;
87 break;
88 case 'e':
89 m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
90 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000091 error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000092 break;
93 case 's':
94 m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
95 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000096 error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000097 break;
98 default:
Greg Clayton9c236732011-10-26 00:56:27 +000099 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Ingham6247dbe2011-07-12 03:12:18 +0000100 break;
101 }
102
103 return error;
104 }
105
106 void
107 OptionParsingStarting ()
108 {
109 m_start_idx = 0;
110 m_end_idx = UINT_MAX;
111 }
112
113 const OptionDefinition*
114 GetDefinitions ()
115 {
116 return g_option_table;
117 }
118
119 // Options table: Required for subclasses of Options.
120
121 static OptionDefinition g_option_table[];
122
123 // Instance variables to hold the values for command options.
124
125 uint32_t m_start_idx;
126 uint32_t m_end_idx;
127 };
128
Jim Ingham6247dbe2011-07-12 03:12:18 +0000129 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000130 DoExecute (Args& command, CommandReturnObject &result)
Jim Ingham6247dbe2011-07-12 03:12:18 +0000131 {
132
133 m_interpreter.DumpHistory (result.GetOutputStream(),
134 m_options.m_start_idx,
135 m_options.m_end_idx);
136 return result.Succeeded();
137
138 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000139
140 CommandOptions m_options;
Jim Ingham6247dbe2011-07-12 03:12:18 +0000141};
142
143OptionDefinition
144CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
145{
146{ LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
147{ LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands."},
148{ LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
149{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
150};
151
152
153//-------------------------------------------------------------------------
154// CommandObjectCommandsSource
155//-------------------------------------------------------------------------
156
Jim Inghamda26bd22012-06-08 21:56:10 +0000157class CommandObjectCommandsSource : public CommandObjectParsed
Jim Ingham767af882010-07-07 03:36:20 +0000158{
Jim Inghamda26bd22012-06-08 21:56:10 +0000159public:
160 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
161 CommandObjectParsed (interpreter,
162 "command source",
163 "Read in debugger commands from the file <filename> and execute them.",
164 NULL),
165 m_options (interpreter)
166 {
167 CommandArgumentEntry arg;
168 CommandArgumentData file_arg;
169
170 // Define the first (and only) variant of this arg.
171 file_arg.arg_type = eArgTypeFilename;
172 file_arg.arg_repetition = eArgRepeatPlain;
173
174 // There is only one variant this argument could be; put it into the argument entry.
175 arg.push_back (file_arg);
176
177 // Push the data for the first argument into the m_arguments vector.
178 m_arguments.push_back (arg);
179 }
180
181 ~CommandObjectCommandsSource () {}
182
183 virtual const char*
184 GetRepeatCommand (Args &current_command_args, uint32_t index)
185 {
186 return "";
187 }
188
189 int
190 HandleArgumentCompletion (Args &input,
191 int &cursor_index,
192 int &cursor_char_position,
193 OptionElementVector &opt_element_vector,
194 int match_start_point,
195 int max_return_elements,
196 bool &word_complete,
197 StringList &matches)
198 {
199 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
200 completion_str.erase (cursor_char_position);
201
202 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
203 CommandCompletions::eDiskFileCompletion,
204 completion_str.c_str(),
205 match_start_point,
206 max_return_elements,
207 NULL,
208 word_complete,
209 matches);
210 return matches.GetSize();
211 }
212
213 virtual Options *
214 GetOptions ()
215 {
216 return &m_options;
217 }
218
219protected:
Jim Ingham949d5ac2011-02-18 00:54:25 +0000220
221 class CommandOptions : public Options
222 {
223 public:
224
Greg Claytonf15996e2011-04-07 22:46:35 +0000225 CommandOptions (CommandInterpreter &interpreter) :
226 Options (interpreter)
227 {
228 }
Jim Ingham949d5ac2011-02-18 00:54:25 +0000229
230 virtual
231 ~CommandOptions (){}
232
233 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000234 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham949d5ac2011-02-18 00:54:25 +0000235 {
236 Error error;
237 char short_option = (char) m_getopt_table[option_idx].val;
238 bool success;
239
240 switch (short_option)
241 {
242 case 'e':
243 m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
244 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000245 error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000246 break;
247 case 'c':
248 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
249 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000250 error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000251 break;
252 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000253 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000254 break;
255 }
256
257 return error;
258 }
259
260 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000261 OptionParsingStarting ()
Jim Ingham949d5ac2011-02-18 00:54:25 +0000262 {
Jim Ingham949d5ac2011-02-18 00:54:25 +0000263 m_stop_on_error = true;
264 m_stop_on_continue = true;
265 }
266
Greg Claytonb3448432011-03-24 21:19:54 +0000267 const OptionDefinition*
Jim Ingham949d5ac2011-02-18 00:54:25 +0000268 GetDefinitions ()
269 {
270 return g_option_table;
271 }
272
273 // Options table: Required for subclasses of Options.
274
Greg Claytonb3448432011-03-24 21:19:54 +0000275 static OptionDefinition g_option_table[];
Jim Ingham949d5ac2011-02-18 00:54:25 +0000276
277 // Instance variables to hold the values for command options.
278
279 bool m_stop_on_error;
280 bool m_stop_on_continue;
281 };
282
Jim Ingham767af882010-07-07 03:36:20 +0000283 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000284 DoExecute(Args& command, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000285 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000286 const int argc = command.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000287 if (argc == 1)
288 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000289 const char *filename = command.GetArgumentAtIndex(0);
Jim Ingham767af882010-07-07 03:36:20 +0000290
291 result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
292
Johnny Chena83ea882010-10-20 21:40:50 +0000293 FileSpec cmd_file (filename, true);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000294 ExecutionContext *exe_ctx = NULL; // Just use the default context.
295 bool echo_commands = true;
296 bool print_results = true;
Jim Ingham767af882010-07-07 03:36:20 +0000297
Jim Ingham949d5ac2011-02-18 00:54:25 +0000298 m_interpreter.HandleCommandsFromFile (cmd_file,
299 exe_ctx,
300 m_options.m_stop_on_continue,
301 m_options.m_stop_on_error,
302 echo_commands,
Enrico Granata01bc2d42012-05-31 01:09:06 +0000303 print_results,
304 eLazyBoolCalculate,
Jim Ingham949d5ac2011-02-18 00:54:25 +0000305 result);
Jim Ingham767af882010-07-07 03:36:20 +0000306 }
307 else
308 {
309 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
310 result.SetStatus (eReturnStatusFailed);
311 }
312 return result.Succeeded();
313
314 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000315 CommandOptions m_options;
Jim Ingham767af882010-07-07 03:36:20 +0000316};
317
Greg Claytonb3448432011-03-24 21:19:54 +0000318OptionDefinition
Jim Ingham949d5ac2011-02-18 00:54:25 +0000319CommandObjectCommandsSource::CommandOptions::g_option_table[] =
320{
321{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
322{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
323{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
324};
325
Jim Ingham767af882010-07-07 03:36:20 +0000326#pragma mark CommandObjectCommandsAlias
327//-------------------------------------------------------------------------
328// CommandObjectCommandsAlias
329//-------------------------------------------------------------------------
330
Enrico Granatac2a28252011-08-16 16:49:25 +0000331static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
332 "You must define a Python function with this signature:\n"
Enrico Granatac1ca9dc2012-08-08 02:06:30 +0000333 "def my_command_impl(debugger, args, result, internal_dict):";
Enrico Granatac2a28252011-08-16 16:49:25 +0000334
335
Jim Inghamda26bd22012-06-08 21:56:10 +0000336class CommandObjectCommandsAlias : public CommandObjectRaw
Jim Ingham767af882010-07-07 03:36:20 +0000337{
Enrico Granatac2a28252011-08-16 16:49:25 +0000338
Enrico Granatac2a28252011-08-16 16:49:25 +0000339
Jim Ingham767af882010-07-07 03:36:20 +0000340public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000341 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000342 CommandObjectRaw (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000343 "command alias",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000344 "Allow users to define their own debugger command abbreviations.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000345 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000346 {
347 SetHelpLong(
348 "'alias' allows the user to create a short-cut or abbreviation for long \n\
349 commands, multi-word commands, and commands that take particular options. \n\
350 Below are some simple examples of how one might use the 'alias' command: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000351 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000352 // command. \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000353 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000354 // command. Since breakpoint commands are two-word \n\
355 // commands, the user will still need to enter the \n\
356 // second word after 'bp', e.g. 'bp enable' or \n\
357 // 'bp delete'. \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000358 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000359 // two-word command 'breakpoint list'. \n\
Jim Ingham767af882010-07-07 03:36:20 +0000360 \nAn alias can include some options for the command, with the values either \n\
361 filled in at the time the alias is created, or specified as positional \n\
362 arguments, to be filled in when the alias is invoked. The following example \n\
363 shows how to create aliases with options: \n\
364 \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000365 'command alias bfl breakpoint set -f %1 -l %2' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000366 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
367 options already part of the alias. So if the user wants to set a breakpoint \n\
368 by file and line without explicitly having to use the -f and -l options, the \n\
369 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
370 for the actual arguments that will be passed when the alias command is used. \n\
371 The number in the placeholder refers to the position/order the actual value \n\
Jim Ingham536f6332011-08-18 02:29:05 +0000372 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
Jim Ingham767af882010-07-07 03:36:20 +0000373 will be replaced with the first argument, all the occurrences of '%2' in the \n\
374 alias will be replaced with the second argument, and so on. This also allows \n\
375 actual arguments to be used multiple times within an alias (see 'process \n\
Jim Ingham536f6332011-08-18 02:29:05 +0000376 launch' example below). \n\
377 Note: the positional arguments must substitute as whole words in the resultant\n\
378 command, so you can't at present do something like:\n\
379 \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000380 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
Jim Ingham536f6332011-08-18 02:29:05 +0000381 \n\
382 to get the file extension \".cpp\" automatically appended. For more complex\n\
383 aliasing, use the \"command regex\" command instead.\n\
384 \nSo in the 'bfl' case, the actual file value will be \n\
Jim Ingham767af882010-07-07 03:36:20 +0000385 filled in with the first argument following 'bfl' and the actual line number \n\
386 value will be filled in with the second argument. The user would use this \n\
387 alias as follows: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000388 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000389 <... some time later ...> \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000390 (lldb) bfl my-file.c 137 \n\
Jim Ingham767af882010-07-07 03:36:20 +0000391 \nThis would be the same as if the user had entered \n\
392 'breakpoint set -f my-file.c -l 137'. \n\
393 \nAnother example: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000394 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000395 (lldb) pltty /dev/tty0 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000396 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000397 \nIf the user always wanted to pass the same value to a particular option, the \n\
398 alias could be defined with that value directly in the alias as a constant, \n\
399 rather than using a positional placeholder: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000400 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000401 // 3 of whatever file is indicated. \n");
Jim Ingham767af882010-07-07 03:36:20 +0000402
Caroline Tice43b014a2010-10-04 22:28:36 +0000403 CommandArgumentEntry arg1;
404 CommandArgumentEntry arg2;
405 CommandArgumentEntry arg3;
406 CommandArgumentData alias_arg;
407 CommandArgumentData cmd_arg;
408 CommandArgumentData options_arg;
409
410 // Define the first (and only) variant of this arg.
411 alias_arg.arg_type = eArgTypeAliasName;
412 alias_arg.arg_repetition = eArgRepeatPlain;
413
414 // There is only one variant this argument could be; put it into the argument entry.
415 arg1.push_back (alias_arg);
416
417 // Define the first (and only) variant of this arg.
418 cmd_arg.arg_type = eArgTypeCommandName;
419 cmd_arg.arg_repetition = eArgRepeatPlain;
420
421 // There is only one variant this argument could be; put it into the argument entry.
422 arg2.push_back (cmd_arg);
423
424 // Define the first (and only) variant of this arg.
425 options_arg.arg_type = eArgTypeAliasOptions;
426 options_arg.arg_repetition = eArgRepeatOptional;
427
428 // There is only one variant this argument could be; put it into the argument entry.
429 arg3.push_back (options_arg);
430
431 // Push the data for the first argument into the m_arguments vector.
432 m_arguments.push_back (arg1);
433 m_arguments.push_back (arg2);
434 m_arguments.push_back (arg3);
Jim Ingham767af882010-07-07 03:36:20 +0000435 }
436
437 ~CommandObjectCommandsAlias ()
438 {
439 }
440
Jim Inghamda26bd22012-06-08 21:56:10 +0000441protected:
442 virtual bool
443 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Caroline Ticee0da7a52010-12-09 22:52:49 +0000444 {
445 Args args (raw_command_line);
446 std::string raw_command_string (raw_command_line);
447
448 size_t argc = args.GetArgumentCount();
449
450 if (argc < 2)
451 {
452 result.AppendError ("'alias' requires at least two arguments");
453 result.SetStatus (eReturnStatusFailed);
454 return false;
455 }
456
457 // Get the alias command.
458
459 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatac2a28252011-08-16 16:49:25 +0000460
Caroline Ticee0da7a52010-12-09 22:52:49 +0000461 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
462 // does the stripping itself.
463 size_t pos = raw_command_string.find (alias_command);
464 if (pos == 0)
465 {
466 raw_command_string = raw_command_string.substr (alias_command.size());
467 pos = raw_command_string.find_first_not_of (' ');
468 if ((pos != std::string::npos) && (pos > 0))
469 raw_command_string = raw_command_string.substr (pos);
470 }
471 else
472 {
473 result.AppendError ("Error parsing command string. No alias created.");
474 result.SetStatus (eReturnStatusFailed);
475 return false;
476 }
477
478
479 // Verify that the command is alias-able.
480 if (m_interpreter.CommandExists (alias_command.c_str()))
481 {
482 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
483 alias_command.c_str());
484 result.SetStatus (eReturnStatusFailed);
485 return false;
486 }
487
488 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
489 // raw_command_string is returned with the name of the command object stripped off the front.
490 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
491
492 if (!cmd_obj)
493 {
Greg Clayton9c236732011-10-26 00:56:27 +0000494 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
Caroline Ticee0da7a52010-12-09 22:52:49 +0000495 " No alias created.", raw_command_string.c_str());
496 result.SetStatus (eReturnStatusFailed);
497 return false;
498 }
499 else if (!cmd_obj->WantsRawCommandString ())
500 {
501 // Note that args was initialized with the original command, and has not been updated to this point.
502 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
Jim Inghamda26bd22012-06-08 21:56:10 +0000503 return HandleAliasingNormalCommand (args, result);
Caroline Ticee0da7a52010-12-09 22:52:49 +0000504 }
505 else
506 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000507 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
508 }
509 return result.Succeeded();
510 }
511
512 bool
513 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
514 {
Caroline Ticee0da7a52010-12-09 22:52:49 +0000515 // Verify & handle any options/arguments passed to the alias command
516
517 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
518 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
519
Jim Inghamda26bd22012-06-08 21:56:10 +0000520 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
Caroline Tice5ddbe212011-05-06 21:37:15 +0000521
522 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Ticee0da7a52010-12-09 22:52:49 +0000523 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000524 result.AppendError ("Unable to create requested alias.\n");
525 result.SetStatus (eReturnStatusFailed);
526 return false;
Caroline Ticee0da7a52010-12-09 22:52:49 +0000527 }
528
529 // Create the alias
530 if (m_interpreter.AliasExists (alias_command.c_str())
531 || m_interpreter.UserCommandExists (alias_command.c_str()))
532 {
533 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
534 if (temp_option_arg_sp.get())
535 {
536 if (option_arg_vector->size() == 0)
537 m_interpreter.RemoveAliasOptions (alias_command.c_str());
538 }
539 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
540 alias_command.c_str());
541 }
542
Caroline Tice56d2fc42010-12-14 18:51:39 +0000543 if (cmd_obj_sp)
544 {
545 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
546 if (option_arg_vector->size() > 0)
547 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
548 result.SetStatus (eReturnStatusSuccessFinishNoResult);
549 }
550 else
551 {
552 result.AppendError ("Unable to create requested alias.\n");
553 result.SetStatus (eReturnStatusFailed);
554 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000555 return result.Succeeded ();
Caroline Ticee0da7a52010-12-09 22:52:49 +0000556 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000557
Jim Ingham767af882010-07-07 03:36:20 +0000558 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000559 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000560 {
Caroline Tice8bb61f02010-09-21 23:25:40 +0000561 size_t argc = args.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000562
563 if (argc < 2)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000564 {
Jim Ingham767af882010-07-07 03:36:20 +0000565 result.AppendError ("'alias' requires at least two arguments");
566 result.SetStatus (eReturnStatusFailed);
567 return false;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000568 }
Jim Ingham767af882010-07-07 03:36:20 +0000569
570 const std::string alias_command = args.GetArgumentAtIndex(0);
571 const std::string actual_command = args.GetArgumentAtIndex(1);
572
573 args.Shift(); // Shift the alias command word off the argument vector.
574 args.Shift(); // Shift the old command word off the argument vector.
575
576 // Verify that the command is alias'able, and get the appropriate command object.
577
Greg Clayton238c0a12010-09-18 01:14:36 +0000578 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000579 {
580 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
581 alias_command.c_str());
582 result.SetStatus (eReturnStatusFailed);
583 }
584 else
585 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000586 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Ingham767af882010-07-07 03:36:20 +0000587 CommandObjectSP subcommand_obj_sp;
588 bool use_subcommand = false;
589 if (command_obj_sp.get())
590 {
591 CommandObject *cmd_obj = command_obj_sp.get();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000592 CommandObject *sub_cmd_obj = NULL;
Jim Ingham767af882010-07-07 03:36:20 +0000593 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
594 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
595
Caroline Ticee0da7a52010-12-09 22:52:49 +0000596 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Ingham767af882010-07-07 03:36:20 +0000597 {
598 if (argc >= 3)
599 {
600 const std::string sub_command = args.GetArgumentAtIndex(0);
601 assert (sub_command.length() != 0);
Greg Clayton13193d52012-10-13 02:07:45 +0000602 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000603 if (subcommand_obj_sp.get())
604 {
605 sub_cmd_obj = subcommand_obj_sp.get();
606 use_subcommand = true;
607 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Ticee0da7a52010-12-09 22:52:49 +0000608 cmd_obj = sub_cmd_obj;
Jim Ingham767af882010-07-07 03:36:20 +0000609 }
610 else
611 {
Caroline Tice5d53b622010-11-02 19:00:04 +0000612 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
613 "Unable to create alias.\n",
614 sub_command.c_str(), actual_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000615 result.SetStatus (eReturnStatusFailed);
616 return false;
617 }
618 }
619 }
620
621 // Verify & handle any options/arguments passed to the alias command
622
623 if (args.GetArgumentCount () > 0)
624 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000625 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
626 if (use_subcommand)
627 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
628
629 std::string args_string;
630 args.GetCommandString (args_string);
631
632 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
633 {
634 result.AppendError ("Unable to create requested alias.\n");
635 result.SetStatus (eReturnStatusFailed);
636 return false;
637 }
Jim Ingham767af882010-07-07 03:36:20 +0000638 }
639
640 // Create the alias.
641
Greg Clayton238c0a12010-09-18 01:14:36 +0000642 if (m_interpreter.AliasExists (alias_command.c_str())
643 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000644 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000645 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Ingham767af882010-07-07 03:36:20 +0000646 if (tmp_option_arg_sp.get())
647 {
648 if (option_arg_vector->size() == 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000649 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000650 }
651 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
652 alias_command.c_str());
653 }
654
655 if (use_subcommand)
Greg Clayton238c0a12010-09-18 01:14:36 +0000656 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000657 else
Greg Clayton238c0a12010-09-18 01:14:36 +0000658 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000659 if (option_arg_vector->size() > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000660 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000661 result.SetStatus (eReturnStatusSuccessFinishNoResult);
662 }
663 else
664 {
665 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
666 result.SetStatus (eReturnStatusFailed);
Caroline Ticee6866a32010-10-28 23:17:48 +0000667 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000668 }
669 }
670
671 return result.Succeeded();
672 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000673
Jim Ingham767af882010-07-07 03:36:20 +0000674};
675
676#pragma mark CommandObjectCommandsUnalias
677//-------------------------------------------------------------------------
678// CommandObjectCommandsUnalias
679//-------------------------------------------------------------------------
680
Jim Inghamda26bd22012-06-08 21:56:10 +0000681class CommandObjectCommandsUnalias : public CommandObjectParsed
Jim Ingham767af882010-07-07 03:36:20 +0000682{
683public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000684 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000685 CommandObjectParsed (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000686 "command unalias",
Caroline Tice146292c2010-09-12 04:56:10 +0000687 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000688 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000689 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000690 CommandArgumentEntry arg;
691 CommandArgumentData alias_arg;
692
693 // Define the first (and only) variant of this arg.
694 alias_arg.arg_type = eArgTypeAliasName;
695 alias_arg.arg_repetition = eArgRepeatPlain;
696
697 // There is only one variant this argument could be; put it into the argument entry.
698 arg.push_back (alias_arg);
699
700 // Push the data for the first argument into the m_arguments vector.
701 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000702 }
703
704 ~CommandObjectCommandsUnalias()
705 {
706 }
707
Jim Inghamda26bd22012-06-08 21:56:10 +0000708protected:
Jim Ingham767af882010-07-07 03:36:20 +0000709 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000710 DoExecute (Args& args, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000711 {
712 CommandObject::CommandMap::iterator pos;
713 CommandObject *cmd_obj;
714
715 if (args.GetArgumentCount() != 0)
716 {
717 const char *command_name = args.GetArgumentAtIndex(0);
Greg Clayton238c0a12010-09-18 01:14:36 +0000718 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Ingham767af882010-07-07 03:36:20 +0000719 if (cmd_obj)
720 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000721 if (m_interpreter.CommandExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000722 {
723 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
724 command_name);
725 result.SetStatus (eReturnStatusFailed);
726 }
727 else
728 {
729
Greg Clayton238c0a12010-09-18 01:14:36 +0000730 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Ingham767af882010-07-07 03:36:20 +0000731 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000732 if (m_interpreter.AliasExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000733 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
734 command_name);
735 else
736 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
737 result.SetStatus (eReturnStatusFailed);
738 }
739 else
740 result.SetStatus (eReturnStatusSuccessFinishNoResult);
741 }
742 }
743 else
744 {
745 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
746 "current list of commands.\n",
747 command_name);
748 result.SetStatus (eReturnStatusFailed);
749 }
750 }
751 else
752 {
753 result.AppendError ("must call 'unalias' with a valid alias");
754 result.SetStatus (eReturnStatusFailed);
755 }
756
757 return result.Succeeded();
758 }
759};
760
Greg Claytond12aeab2011-04-20 16:37:46 +0000761//-------------------------------------------------------------------------
762// CommandObjectCommandsAddRegex
763//-------------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000764#pragma mark CommandObjectCommandsAddRegex
Greg Claytond12aeab2011-04-20 16:37:46 +0000765
Jim Inghamda26bd22012-06-08 21:56:10 +0000766class CommandObjectCommandsAddRegex : public CommandObjectParsed
Greg Claytond12aeab2011-04-20 16:37:46 +0000767{
768public:
769 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000770 CommandObjectParsed (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000771 "command regex",
Greg Claytond12aeab2011-04-20 16:37:46 +0000772 "Allow the user to create a regular expression command.",
Greg Clayton40e48242011-04-20 22:55:21 +0000773 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytond12aeab2011-04-20 16:37:46 +0000774 m_options (interpreter)
775 {
Greg Clayton40e48242011-04-20 22:55:21 +0000776 SetHelpLong(
777"This command allows the user to create powerful regular expression commands\n"
778"with substitutions. The regular expressions and substitutions are specified\n"
779"using the regular exression substitution format of:\n"
780"\n"
781" s/<regex>/<subst>/\n"
782"\n"
783"<regex> is a regular expression that can use parenthesis to capture regular\n"
784"expression input and substitute the captured matches in the output using %1\n"
785"for the first match, %2 for the second, and so on.\n"
786"\n"
787"The regular expressions can all be specified on the command line if more than\n"
788"one argument is provided. If just the command name is provided on the command\n"
789"line, then the regular expressions and substitutions can be entered on separate\n"
790" lines, followed by an empty line to terminate the command definition.\n"
791"\n"
792"EXAMPLES\n"
793"\n"
Sean Callanan7acd60a2012-08-16 21:46:58 +0000794"The following example will define a regular expression command named 'f' that\n"
Greg Clayton40e48242011-04-20 22:55:21 +0000795"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
796"a number follows 'f':\n"
Sean Callanan7acd60a2012-08-16 21:46:58 +0000797"\n"
798" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
799"\n"
Greg Clayton40e48242011-04-20 22:55:21 +0000800 );
Greg Claytond12aeab2011-04-20 16:37:46 +0000801 }
802
803 ~CommandObjectCommandsAddRegex()
804 {
805 }
806
807
Jim Inghamda26bd22012-06-08 21:56:10 +0000808protected:
Greg Claytond12aeab2011-04-20 16:37:46 +0000809 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000810 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytond12aeab2011-04-20 16:37:46 +0000811 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000812 const size_t argc = command.GetArgumentCount();
Greg Clayton40e48242011-04-20 22:55:21 +0000813 if (argc == 0)
Greg Claytond12aeab2011-04-20 16:37:46 +0000814 {
Jason Molenda4049bc32011-11-10 22:43:35 +0000815 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton40e48242011-04-20 22:55:21 +0000816 result.SetStatus (eReturnStatusFailed);
817 }
818 else
819 {
820 Error error;
Jim Inghamda26bd22012-06-08 21:56:10 +0000821 const char *name = command.GetArgumentAtIndex(0);
Greg Claytond12aeab2011-04-20 16:37:46 +0000822 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
823 name,
824 m_options.GetHelp (),
825 m_options.GetSyntax (),
826 10));
Greg Clayton40e48242011-04-20 22:55:21 +0000827
828 if (argc == 1)
Greg Claytond12aeab2011-04-20 16:37:46 +0000829 {
Greg Clayton40e48242011-04-20 22:55:21 +0000830 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
831 if (reader_sp)
832 {
833 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
Greg Claytond12aeab2011-04-20 16:37:46 +0000834 this, // baton
835 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton40e48242011-04-20 22:55:21 +0000836 NULL, // end token
Greg Claytond12aeab2011-04-20 16:37:46 +0000837 "> ", // prompt
Greg Clayton40e48242011-04-20 22:55:21 +0000838 true); // echo input
839 if (error.Success())
840 {
841 m_interpreter.GetDebugger().PushInputReader (reader_sp);
842 result.SetStatus (eReturnStatusSuccessFinishNoResult);
843 return true;
844 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000845 }
846 }
Greg Clayton40e48242011-04-20 22:55:21 +0000847 else
848 {
849 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
850 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000851 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton40e48242011-04-20 22:55:21 +0000852 error = AppendRegexSubstitution (arg_strref);
853 if (error.Fail())
854 break;
855 }
856
857 if (error.Success())
858 {
859 AddRegexCommandToInterpreter();
860 }
861 }
862 if (error.Fail())
863 {
864 result.AppendError (error.AsCString());
865 result.SetStatus (eReturnStatusFailed);
866 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000867 }
Greg Clayton40e48242011-04-20 22:55:21 +0000868
Greg Claytond12aeab2011-04-20 16:37:46 +0000869 return result.Succeeded();
870 }
871
Greg Clayton40e48242011-04-20 22:55:21 +0000872 Error
873 AppendRegexSubstitution (const llvm::StringRef &regex_sed)
Greg Claytond12aeab2011-04-20 16:37:46 +0000874 {
Greg Clayton40e48242011-04-20 22:55:21 +0000875 Error error;
876
877 if (m_regex_cmd_ap.get() == NULL)
Greg Claytond12aeab2011-04-20 16:37:46 +0000878 {
Greg Clayton40e48242011-04-20 22:55:21 +0000879 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
880 (int)regex_sed.size(),
881 regex_sed.data());
882 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000883 }
Greg Clayton40e48242011-04-20 22:55:21 +0000884
885 size_t regex_sed_size = regex_sed.size();
886
887 if (regex_sed_size <= 1)
888 {
889 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
890 (int)regex_sed.size(),
891 regex_sed.data());
892 return error;
893 }
894
895 if (regex_sed[0] != 's')
896 {
897 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
898 (int)regex_sed.size(),
899 regex_sed.data());
900 return error;
901 }
902 const size_t first_separator_char_pos = 1;
903 // use the char that follows 's' as the regex separator character
904 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
905 const char separator_char = regex_sed[first_separator_char_pos];
906 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
907
908 if (second_separator_char_pos == std::string::npos)
909 {
910 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
911 separator_char,
912 (int)(regex_sed.size() - first_separator_char_pos - 1),
913 regex_sed.data() + (first_separator_char_pos + 1));
914 return error;
915 }
916
917 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
918
919 if (third_separator_char_pos == std::string::npos)
920 {
921 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
922 separator_char,
923 (int)(regex_sed.size() - second_separator_char_pos - 1),
924 regex_sed.data() + (second_separator_char_pos + 1));
925 return error;
926 }
927
928 if (third_separator_char_pos != regex_sed_size - 1)
929 {
930 // Make sure that everything that follows the last regex
931 // separator char
932 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
933 {
934 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
935 (int)third_separator_char_pos + 1,
936 regex_sed.data(),
937 (int)(regex_sed.size() - third_separator_char_pos - 1),
938 regex_sed.data() + (third_separator_char_pos + 1));
939 return error;
940 }
941
942 }
943 else if (first_separator_char_pos + 1 == second_separator_char_pos)
944 {
945 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
946 separator_char,
947 separator_char,
948 separator_char,
949 (int)regex_sed.size(),
950 regex_sed.data());
951 return error;
952 }
953 else if (second_separator_char_pos + 1 == third_separator_char_pos)
954 {
955 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
956 separator_char,
957 separator_char,
958 separator_char,
959 (int)regex_sed.size(),
960 regex_sed.data());
961 return error;
962 }
963 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
964 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
965 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
966 subst.c_str());
967 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000968 }
969
970 void
Greg Clayton40e48242011-04-20 22:55:21 +0000971 AddRegexCommandToInterpreter()
Greg Claytond12aeab2011-04-20 16:37:46 +0000972 {
973 if (m_regex_cmd_ap.get())
974 {
975 if (m_regex_cmd_ap->HasRegexEntries())
976 {
977 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
978 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
979 }
980 }
981 }
982
Greg Clayton40e48242011-04-20 22:55:21 +0000983 void
984 InputReaderDidCancel()
985 {
986 m_regex_cmd_ap.reset();
987 }
988
Greg Claytond12aeab2011-04-20 16:37:46 +0000989 static size_t
990 InputReaderCallback (void *baton,
991 InputReader &reader,
992 lldb::InputReaderAction notification,
993 const char *bytes,
Jim Inghamda26bd22012-06-08 21:56:10 +0000994 size_t bytes_len)
995 {
996 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
997 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
998
999 switch (notification)
1000 {
1001 case eInputReaderActivate:
1002 if (!batch_mode)
1003 {
1004 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1005 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1006 out_stream->Flush();
1007 }
1008 break;
1009 case eInputReaderReactivate:
1010 break;
1011
1012 case eInputReaderDeactivate:
1013 break;
1014
1015 case eInputReaderAsynchronousOutputWritten:
1016 break;
1017
1018 case eInputReaderGotToken:
1019 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1020 --bytes_len;
1021 if (bytes_len == 0)
1022 reader.SetIsDone(true);
1023 else if (bytes)
1024 {
1025 llvm::StringRef bytes_strref (bytes, bytes_len);
1026 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1027 if (error.Fail())
1028 {
1029 if (!batch_mode)
1030 {
1031 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1032 out_stream->Printf("error: %s\n", error.AsCString());
1033 out_stream->Flush();
1034 }
1035 add_regex_cmd->InputReaderDidCancel ();
1036 reader.SetIsDone (true);
1037 }
1038 }
1039 break;
1040
1041 case eInputReaderInterrupt:
1042 {
1043 reader.SetIsDone (true);
1044 if (!batch_mode)
1045 {
1046 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1047 out_stream->PutCString("Regular expression command creations was cancelled.\n");
1048 out_stream->Flush();
1049 }
1050 add_regex_cmd->InputReaderDidCancel ();
1051 }
1052 break;
1053
1054 case eInputReaderEndOfFile:
1055 reader.SetIsDone (true);
1056 break;
1057
1058 case eInputReaderDone:
1059 add_regex_cmd->AddRegexCommandToInterpreter();
1060 break;
1061 }
1062
1063 return bytes_len;
1064 }
1065
Greg Claytond12aeab2011-04-20 16:37:46 +00001066private:
1067 std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1068
1069 class CommandOptions : public Options
1070 {
1071 public:
1072
1073 CommandOptions (CommandInterpreter &interpreter) :
1074 Options (interpreter)
1075 {
1076 }
1077
1078 virtual
1079 ~CommandOptions (){}
1080
1081 virtual Error
1082 SetOptionValue (uint32_t option_idx, const char *option_arg)
1083 {
1084 Error error;
1085 char short_option = (char) m_getopt_table[option_idx].val;
1086
1087 switch (short_option)
1088 {
1089 case 'h':
1090 m_help.assign (option_arg);
1091 break;
1092 case 's':
1093 m_syntax.assign (option_arg);
1094 break;
1095
1096 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001097 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytond12aeab2011-04-20 16:37:46 +00001098 break;
1099 }
1100
1101 return error;
1102 }
1103
1104 void
1105 OptionParsingStarting ()
1106 {
1107 m_help.clear();
1108 m_syntax.clear();
1109 }
1110
1111 const OptionDefinition*
1112 GetDefinitions ()
1113 {
1114 return g_option_table;
1115 }
1116
1117 // Options table: Required for subclasses of Options.
1118
1119 static OptionDefinition g_option_table[];
1120
1121 const char *
1122 GetHelp ()
1123 {
1124 if (m_help.empty())
1125 return NULL;
1126 return m_help.c_str();
1127 }
1128 const char *
1129 GetSyntax ()
1130 {
1131 if (m_syntax.empty())
1132 return NULL;
1133 return m_syntax.c_str();
1134 }
1135 // Instance variables to hold the values for command options.
1136 protected:
1137 std::string m_help;
1138 std::string m_syntax;
1139 };
Jim Inghamda26bd22012-06-08 21:56:10 +00001140
Greg Claytond12aeab2011-04-20 16:37:46 +00001141 virtual Options *
1142 GetOptions ()
1143 {
1144 return &m_options;
1145 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001146
1147 CommandOptions m_options;
Greg Claytond12aeab2011-04-20 16:37:46 +00001148};
1149
Greg Claytond12aeab2011-04-20 16:37:46 +00001150OptionDefinition
1151CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1152{
Greg Clayton40e48242011-04-20 22:55:21 +00001153{ 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 +00001154{ 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 +00001155{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytond12aeab2011-04-20 16:37:46 +00001156};
1157
1158
Jim Inghamda26bd22012-06-08 21:56:10 +00001159class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata6b1596d2011-08-16 23:24:13 +00001160{
1161private:
1162 std::string m_function_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001163 ScriptedCommandSynchronicity m_synchro;
Enrico Granata5b9f7772012-09-18 21:53:02 +00001164 bool m_fetched_help_long;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001165
1166public:
1167
1168 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1169 std::string name,
Enrico Granata6010ace2011-11-07 22:57:04 +00001170 std::string funct,
1171 ScriptedCommandSynchronicity synch) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001172 CommandObjectRaw (interpreter,
1173 name.c_str(),
1174 (std::string("Run Python function ") + funct).c_str(),
1175 NULL),
1176 m_function_name(funct),
Enrico Granata5b9f7772012-09-18 21:53:02 +00001177 m_synchro(synch),
1178 m_fetched_help_long(false)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001179 {
1180 }
1181
1182 virtual
1183 ~CommandObjectPythonFunction ()
1184 {
1185 }
1186
1187 virtual bool
Greg Claytonf737d372012-10-08 22:41:53 +00001188 IsRemovable () const
Jim Inghamda26bd22012-06-08 21:56:10 +00001189 {
1190 return true;
1191 }
1192
1193 const std::string&
1194 GetFunctionName ()
1195 {
1196 return m_function_name;
1197 }
1198
1199 ScriptedCommandSynchronicity
1200 GetSynchronicity ()
1201 {
1202 return m_synchro;
1203 }
1204
Enrico Granata5b9f7772012-09-18 21:53:02 +00001205 virtual const char *
1206 GetHelpLong ()
1207 {
1208 if (!m_fetched_help_long)
1209 {
1210 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1211 if (scripter)
1212 {
1213 std::string docstring;
1214 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1215 if (!docstring.empty())
1216 SetHelpLong(docstring);
1217 }
1218 }
1219 return CommandObjectRaw::GetHelpLong();
1220 }
1221
Jim Inghamda26bd22012-06-08 21:56:10 +00001222protected:
1223 virtual bool
1224 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001225 {
1226 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1227
1228 Error error;
1229
Jim Ingham839de392012-06-27 17:25:36 +00001230 result.SetStatus(eReturnStatusInvalid);
1231
Enrico Granata6b1596d2011-08-16 23:24:13 +00001232 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1233 raw_command_line,
Enrico Granata6010ace2011-11-07 22:57:04 +00001234 m_synchro,
Enrico Granata6b1596d2011-08-16 23:24:13 +00001235 result,
1236 error) == false)
1237 {
1238 result.AppendError(error.AsCString());
1239 result.SetStatus(eReturnStatusFailed);
1240 }
1241 else
Jim Ingham839de392012-06-27 17:25:36 +00001242 {
1243 // Don't change the status if the command already set it...
1244 if (result.GetStatus() == eReturnStatusInvalid)
1245 {
1246 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1247 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1248 else
1249 result.SetStatus(eReturnStatusSuccessFinishResult);
1250 }
1251 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001252
1253 return result.Succeeded();
1254 }
1255
Enrico Granata6b1596d2011-08-16 23:24:13 +00001256};
1257
Enrico Granata59df36f2011-10-17 21:45:27 +00001258//-------------------------------------------------------------------------
1259// CommandObjectCommandsScriptImport
1260//-------------------------------------------------------------------------
1261
Jim Inghamda26bd22012-06-08 21:56:10 +00001262class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granata59df36f2011-10-17 21:45:27 +00001263{
Jim Inghamda26bd22012-06-08 21:56:10 +00001264public:
1265 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1266 CommandObjectParsed (interpreter,
1267 "command script import",
1268 "Import a scripting module in LLDB.",
1269 NULL),
1270 m_options(interpreter)
1271 {
1272 CommandArgumentEntry arg1;
1273 CommandArgumentData cmd_arg;
1274
1275 // Define the first (and only) variant of this arg.
1276 cmd_arg.arg_type = eArgTypeFilename;
1277 cmd_arg.arg_repetition = eArgRepeatPlain;
1278
1279 // There is only one variant this argument could be; put it into the argument entry.
1280 arg1.push_back (cmd_arg);
1281
1282 // Push the data for the first argument into the m_arguments vector.
1283 m_arguments.push_back (arg1);
1284 }
1285
1286 ~CommandObjectCommandsScriptImport ()
1287 {
1288 }
1289
1290 int
1291 HandleArgumentCompletion (Args &input,
1292 int &cursor_index,
1293 int &cursor_char_position,
1294 OptionElementVector &opt_element_vector,
1295 int match_start_point,
1296 int max_return_elements,
1297 bool &word_complete,
1298 StringList &matches)
1299 {
1300 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1301 completion_str.erase (cursor_char_position);
1302
1303 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1304 CommandCompletions::eDiskFileCompletion,
1305 completion_str.c_str(),
1306 match_start_point,
1307 max_return_elements,
1308 NULL,
1309 word_complete,
1310 matches);
1311 return matches.GetSize();
1312 }
1313
1314 virtual Options *
1315 GetOptions ()
1316 {
1317 return &m_options;
1318 }
1319
1320protected:
Enrico Granata6010ace2011-11-07 22:57:04 +00001321
1322 class CommandOptions : public Options
1323 {
1324 public:
1325
1326 CommandOptions (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001327 Options (interpreter)
Enrico Granata6010ace2011-11-07 22:57:04 +00001328 {
1329 }
1330
1331 virtual
1332 ~CommandOptions (){}
1333
1334 virtual Error
1335 SetOptionValue (uint32_t option_idx, const char *option_arg)
1336 {
1337 Error error;
1338 char short_option = (char) m_getopt_table[option_idx].val;
1339
1340 switch (short_option)
1341 {
1342 case 'r':
1343 m_allow_reload = true;
1344 break;
1345 default:
1346 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1347 break;
1348 }
1349
1350 return error;
1351 }
1352
1353 void
1354 OptionParsingStarting ()
1355 {
1356 m_allow_reload = false;
1357 }
1358
1359 const OptionDefinition*
1360 GetDefinitions ()
1361 {
1362 return g_option_table;
1363 }
1364
1365 // Options table: Required for subclasses of Options.
1366
1367 static OptionDefinition g_option_table[];
1368
1369 // Instance variables to hold the values for command options.
1370
1371 bool m_allow_reload;
1372 };
Enrico Granata6010ace2011-11-07 22:57:04 +00001373
Enrico Granata59df36f2011-10-17 21:45:27 +00001374 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001375 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata59df36f2011-10-17 21:45:27 +00001376 {
1377
1378 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1379 {
1380 result.AppendError ("only scripting language supported for module importing is currently Python");
1381 result.SetStatus (eReturnStatusFailed);
1382 return false;
1383 }
1384
Jim Inghamda26bd22012-06-08 21:56:10 +00001385 size_t argc = command.GetArgumentCount();
Enrico Granata59df36f2011-10-17 21:45:27 +00001386
1387 if (argc != 1)
1388 {
1389 result.AppendError ("'command script import' requires one argument");
1390 result.SetStatus (eReturnStatusFailed);
1391 return false;
1392 }
1393
Jim Inghamda26bd22012-06-08 21:56:10 +00001394 std::string path = command.GetArgumentAtIndex(0);
Enrico Granata59df36f2011-10-17 21:45:27 +00001395 Error error;
1396
Greg Clayton2e7f3132012-10-18 22:40:37 +00001397 const bool init_session = true;
Enrico Granata59df36f2011-10-17 21:45:27 +00001398 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001399 m_options.m_allow_reload,
Greg Clayton2e7f3132012-10-18 22:40:37 +00001400 init_session,
Enrico Granata59df36f2011-10-17 21:45:27 +00001401 error))
1402 {
1403 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1404 }
1405 else
1406 {
1407 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1408 result.SetStatus (eReturnStatusFailed);
1409 }
1410
1411 return result.Succeeded();
1412 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001413
Jim Inghamda26bd22012-06-08 21:56:10 +00001414 CommandOptions m_options;
Enrico Granata59df36f2011-10-17 21:45:27 +00001415};
Enrico Granata6b1596d2011-08-16 23:24:13 +00001416
Enrico Granata6010ace2011-11-07 22:57:04 +00001417OptionDefinition
1418CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1419{
1420 { 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)."},
1421 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1422};
1423
1424
Enrico Granata6b1596d2011-08-16 23:24:13 +00001425//-------------------------------------------------------------------------
1426// CommandObjectCommandsScriptAdd
1427//-------------------------------------------------------------------------
1428
Jim Inghamda26bd22012-06-08 21:56:10 +00001429class CommandObjectCommandsScriptAdd : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001430{
Jim Inghamda26bd22012-06-08 21:56:10 +00001431public:
1432 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1433 CommandObjectParsed (interpreter,
1434 "command script add",
1435 "Add a scripted function as an LLDB command.",
1436 NULL),
1437 m_options (interpreter)
1438 {
1439 CommandArgumentEntry arg1;
1440 CommandArgumentData cmd_arg;
1441
1442 // Define the first (and only) variant of this arg.
1443 cmd_arg.arg_type = eArgTypeCommandName;
1444 cmd_arg.arg_repetition = eArgRepeatPlain;
1445
1446 // There is only one variant this argument could be; put it into the argument entry.
1447 arg1.push_back (cmd_arg);
1448
1449 // Push the data for the first argument into the m_arguments vector.
1450 m_arguments.push_back (arg1);
1451 }
1452
1453 ~CommandObjectCommandsScriptAdd ()
1454 {
1455 }
1456
1457 virtual Options *
1458 GetOptions ()
1459 {
1460 return &m_options;
1461 }
1462
1463protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001464
1465 class CommandOptions : public Options
1466 {
1467 public:
1468
1469 CommandOptions (CommandInterpreter &interpreter) :
1470 Options (interpreter)
1471 {
1472 }
1473
1474 virtual
1475 ~CommandOptions (){}
1476
1477 virtual Error
1478 SetOptionValue (uint32_t option_idx, const char *option_arg)
1479 {
1480 Error error;
1481 char short_option = (char) m_getopt_table[option_idx].val;
1482
1483 switch (short_option)
1484 {
1485 case 'f':
1486 m_funct_name = std::string(option_arg);
1487 break;
Enrico Granata6010ace2011-11-07 22:57:04 +00001488 case 's':
1489 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1490 if (!error.Success())
1491 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1492 break;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001493 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001494 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001495 break;
1496 }
1497
1498 return error;
1499 }
1500
1501 void
1502 OptionParsingStarting ()
1503 {
1504 m_funct_name = "";
Enrico Granata6010ace2011-11-07 22:57:04 +00001505 m_synchronous = eScriptedCommandSynchronicitySynchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001506 }
1507
1508 const OptionDefinition*
1509 GetDefinitions ()
1510 {
1511 return g_option_table;
1512 }
1513
1514 // Options table: Required for subclasses of Options.
1515
1516 static OptionDefinition g_option_table[];
1517
1518 // Instance variables to hold the values for command options.
1519
1520 std::string m_funct_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001521 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001522 };
Jim Inghamda26bd22012-06-08 21:56:10 +00001523
1524private:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001525 class PythonAliasReader : public InputReaderEZ
1526 {
1527 private:
1528 CommandInterpreter& m_interpreter;
1529 std::string m_cmd_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001530 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001531 StringList m_user_input;
1532 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1533 public:
1534 PythonAliasReader(Debugger& debugger,
1535 CommandInterpreter& interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001536 std::string cmd_name,
1537 ScriptedCommandSynchronicity synch) :
Enrico Granata6b1596d2011-08-16 23:24:13 +00001538 InputReaderEZ(debugger),
1539 m_interpreter(interpreter),
1540 m_cmd_name(cmd_name),
Enrico Granata6010ace2011-11-07 22:57:04 +00001541 m_synchronous(synch),
Enrico Granata6b1596d2011-08-16 23:24:13 +00001542 m_user_input()
1543 {}
1544
1545 virtual
1546 ~PythonAliasReader()
1547 {
1548 }
1549
1550 virtual void ActivateHandler(HandlerData& data)
1551 {
1552 StreamSP out_stream = data.GetOutStream();
1553 bool batch_mode = data.GetBatchMode();
1554 if (!batch_mode)
1555 {
1556 out_stream->Printf ("%s\n", g_python_command_instructions);
1557 if (data.reader.GetPrompt())
1558 out_stream->Printf ("%s", data.reader.GetPrompt());
1559 out_stream->Flush();
1560 }
1561 }
1562
1563 virtual void ReactivateHandler(HandlerData& data)
1564 {
1565 StreamSP out_stream = data.GetOutStream();
1566 bool batch_mode = data.GetBatchMode();
1567 if (data.reader.GetPrompt() && !batch_mode)
1568 {
1569 out_stream->Printf ("%s", data.reader.GetPrompt());
1570 out_stream->Flush();
1571 }
1572 }
1573 virtual void GotTokenHandler(HandlerData& data)
1574 {
1575 StreamSP out_stream = data.GetOutStream();
1576 bool batch_mode = data.GetBatchMode();
1577 if (data.bytes && data.bytes_len)
1578 {
1579 m_user_input.AppendString(data.bytes, data.bytes_len);
1580 }
1581 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1582 {
1583 out_stream->Printf ("%s", data.reader.GetPrompt());
1584 out_stream->Flush();
1585 }
1586 }
1587 virtual void InterruptHandler(HandlerData& data)
1588 {
1589 StreamSP out_stream = data.GetOutStream();
1590 bool batch_mode = data.GetBatchMode();
1591 data.reader.SetIsDone (true);
1592 if (!batch_mode)
1593 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001594 out_stream->Printf ("Warning: No script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001595 out_stream->Flush();
1596 }
1597 }
1598 virtual void EOFHandler(HandlerData& data)
1599 {
1600 data.reader.SetIsDone (true);
1601 }
1602 virtual void DoneHandler(HandlerData& data)
1603 {
1604 StreamSP out_stream = data.GetOutStream();
1605
1606 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1607 if (!interpreter)
1608 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001609 out_stream->Printf ("Script interpreter missing: 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 std::string funct_name_str;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001614 if (!interpreter->GenerateScriptAliasFunction (m_user_input,
Enrico Granata400105d2012-03-06 23:42:15 +00001615 funct_name_str))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001616 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001617 out_stream->Printf ("Unable to create function: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001618 out_stream->Flush();
1619 return;
1620 }
Enrico Granata400105d2012-03-06 23:42:15 +00001621 if (funct_name_str.empty())
Enrico Granata6b1596d2011-08-16 23:24:13 +00001622 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001623 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001624 out_stream->Flush();
1625 return;
1626 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001627 // everything should be fine now, let's add this alias
1628
1629 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1630 m_cmd_name,
Enrico Granata400105d2012-03-06 23:42:15 +00001631 funct_name_str.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001632 m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001633
Enrico Granata6010ace2011-11-07 22:57:04 +00001634 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001635 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001636 out_stream->Printf ("Unable to add selected command: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001637 out_stream->Flush();
1638 return;
1639 }
1640 }
1641 };
1642
Jim Inghamda26bd22012-06-08 21:56:10 +00001643protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001644 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001645 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001646 {
Enrico Granatae5e34cb2011-08-17 01:30:04 +00001647
1648 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1649 {
1650 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1651 result.SetStatus (eReturnStatusFailed);
1652 return false;
1653 }
1654
Jim Inghamda26bd22012-06-08 21:56:10 +00001655 size_t argc = command.GetArgumentCount();
Enrico Granata6b1596d2011-08-16 23:24:13 +00001656
1657 if (argc != 1)
1658 {
1659 result.AppendError ("'command script add' requires one argument");
1660 result.SetStatus (eReturnStatusFailed);
1661 return false;
1662 }
1663
Jim Inghamda26bd22012-06-08 21:56:10 +00001664 std::string cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001665
1666 if (m_options.m_funct_name.empty())
1667 {
1668 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1669 m_interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001670 cmd_name,
1671 m_options.m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001672
1673 if (reader_sp)
1674 {
1675
1676 InputReaderEZ::InitializationParameters ipr;
1677
1678 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
1679 if (err.Success())
1680 {
1681 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1682 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1683 }
1684 else
1685 {
1686 result.AppendError (err.AsCString());
1687 result.SetStatus (eReturnStatusFailed);
1688 }
1689 }
1690 else
1691 {
1692 result.AppendError("out of memory");
1693 result.SetStatus (eReturnStatusFailed);
1694 }
1695 }
1696 else
1697 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001698 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1699 cmd_name,
1700 m_options.m_funct_name,
1701 m_options.m_synchronous));
1702 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001703 {
1704 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1705 }
1706 else
1707 {
1708 result.AppendError("cannot add command");
1709 result.SetStatus (eReturnStatusFailed);
1710 }
1711 }
1712
1713 return result.Succeeded();
1714
1715 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001716
1717 CommandOptions m_options;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001718};
1719
Enrico Granata6010ace2011-11-07 22:57:04 +00001720static OptionEnumValueElement g_script_synchro_type[] =
1721{
1722 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1723 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1724 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1725 { 0, NULL, NULL }
1726};
1727
Enrico Granata6b1596d2011-08-16 23:24:13 +00001728OptionDefinition
1729CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1730{
Enrico Granata91544802011-09-06 19:20:51 +00001731 { 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 +00001732 { 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 +00001733 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1734};
1735
1736//-------------------------------------------------------------------------
1737// CommandObjectCommandsScriptList
1738//-------------------------------------------------------------------------
1739
Jim Inghamda26bd22012-06-08 21:56:10 +00001740class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001741{
1742private:
Enrico Granata6010ace2011-11-07 22:57:04 +00001743
Enrico Granata6b1596d2011-08-16 23:24:13 +00001744public:
1745 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001746 CommandObjectParsed (interpreter,
Enrico Granata6b1596d2011-08-16 23:24:13 +00001747 "command script list",
1748 "List defined scripted commands.",
1749 NULL)
1750 {
1751 }
1752
1753 ~CommandObjectCommandsScriptList ()
1754 {
1755 }
1756
1757 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001758 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001759 {
1760
1761 m_interpreter.GetHelp(result,
1762 CommandInterpreter::eCommandTypesUserDef);
1763
1764 result.SetStatus (eReturnStatusSuccessFinishResult);
1765
1766 return true;
1767
1768
1769 }
1770};
1771
1772//-------------------------------------------------------------------------
1773// CommandObjectCommandsScriptClear
1774//-------------------------------------------------------------------------
1775
Jim Inghamda26bd22012-06-08 21:56:10 +00001776class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001777{
1778private:
1779
1780public:
1781 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001782 CommandObjectParsed (interpreter,
1783 "command script clear",
1784 "Delete all scripted commands.",
1785 NULL)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001786 {
1787 }
1788
1789 ~CommandObjectCommandsScriptClear ()
1790 {
1791 }
1792
Jim Inghamda26bd22012-06-08 21:56:10 +00001793protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001794 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001795 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001796 {
1797
1798 m_interpreter.RemoveAllUser();
1799
1800 result.SetStatus (eReturnStatusSuccessFinishResult);
1801
1802 return true;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001803 }
1804};
1805
1806//-------------------------------------------------------------------------
1807// CommandObjectCommandsScriptDelete
1808//-------------------------------------------------------------------------
1809
Jim Inghamda26bd22012-06-08 21:56:10 +00001810class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001811{
Enrico Granata6b1596d2011-08-16 23:24:13 +00001812public:
1813 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001814 CommandObjectParsed (interpreter,
1815 "command script delete",
1816 "Delete a scripted command.",
1817 NULL)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001818 {
1819 CommandArgumentEntry arg1;
1820 CommandArgumentData cmd_arg;
1821
1822 // Define the first (and only) variant of this arg.
1823 cmd_arg.arg_type = eArgTypeCommandName;
1824 cmd_arg.arg_repetition = eArgRepeatPlain;
1825
1826 // There is only one variant this argument could be; put it into the argument entry.
1827 arg1.push_back (cmd_arg);
1828
1829 // Push the data for the first argument into the m_arguments vector.
1830 m_arguments.push_back (arg1);
1831 }
1832
1833 ~CommandObjectCommandsScriptDelete ()
1834 {
1835 }
1836
Jim Inghamda26bd22012-06-08 21:56:10 +00001837protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001838 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001839 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001840 {
1841
Jim Inghamda26bd22012-06-08 21:56:10 +00001842 size_t argc = command.GetArgumentCount();
Enrico Granata6b1596d2011-08-16 23:24:13 +00001843
1844 if (argc != 1)
1845 {
1846 result.AppendError ("'command script delete' requires one argument");
1847 result.SetStatus (eReturnStatusFailed);
1848 return false;
1849 }
1850
Jim Inghamda26bd22012-06-08 21:56:10 +00001851 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001852
1853 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1854 {
1855 m_interpreter.RemoveUser(cmd_name);
1856 result.SetStatus (eReturnStatusSuccessFinishResult);
1857 }
1858 else
1859 {
1860 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1861 result.SetStatus (eReturnStatusFailed);
1862 }
1863
1864 return result.Succeeded();
1865
1866 }
1867};
1868
1869#pragma mark CommandObjectMultiwordCommandsScript
1870
1871//-------------------------------------------------------------------------
1872// CommandObjectMultiwordCommandsScript
1873//-------------------------------------------------------------------------
1874
1875class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1876{
1877public:
1878 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1879 CommandObjectMultiword (interpreter,
1880 "command script",
1881 "A set of commands for managing or customizing script commands.",
1882 "command script <subcommand> [<subcommand-options>]")
1883 {
1884 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1885 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1886 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1887 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Enrico Granata59df36f2011-10-17 21:45:27 +00001888 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001889 }
1890
1891 ~CommandObjectMultiwordCommandsScript ()
1892 {
1893 }
1894
1895};
1896
1897
Jim Ingham767af882010-07-07 03:36:20 +00001898#pragma mark CommandObjectMultiwordCommands
1899
1900//-------------------------------------------------------------------------
1901// CommandObjectMultiwordCommands
1902//-------------------------------------------------------------------------
1903
1904CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001905 CommandObjectMultiword (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +00001906 "command",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001907 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton40e48242011-04-20 22:55:21 +00001908 "command <subcommand> [<subcommand-options>]")
Jim Ingham767af882010-07-07 03:36:20 +00001909{
Greg Clayton238c0a12010-09-18 01:14:36 +00001910 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1911 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1912 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytond12aeab2011-04-20 16:37:46 +00001913 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Ingham6247dbe2011-07-12 03:12:18 +00001914 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001915 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Ingham767af882010-07-07 03:36:20 +00001916}
1917
1918CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1919{
1920}
1921