blob: 64f80a0f51da3b44b4b6dd4191ed2e21749e031f [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);
602 subcommand_obj_sp =
603 (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
604 if (subcommand_obj_sp.get())
605 {
606 sub_cmd_obj = subcommand_obj_sp.get();
607 use_subcommand = true;
608 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Ticee0da7a52010-12-09 22:52:49 +0000609 cmd_obj = sub_cmd_obj;
Jim Ingham767af882010-07-07 03:36:20 +0000610 }
611 else
612 {
Caroline Tice5d53b622010-11-02 19:00:04 +0000613 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
614 "Unable to create alias.\n",
615 sub_command.c_str(), actual_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000616 result.SetStatus (eReturnStatusFailed);
617 return false;
618 }
619 }
620 }
621
622 // Verify & handle any options/arguments passed to the alias command
623
624 if (args.GetArgumentCount () > 0)
625 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000626 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
627 if (use_subcommand)
628 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
629
630 std::string args_string;
631 args.GetCommandString (args_string);
632
633 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
634 {
635 result.AppendError ("Unable to create requested alias.\n");
636 result.SetStatus (eReturnStatusFailed);
637 return false;
638 }
Jim Ingham767af882010-07-07 03:36:20 +0000639 }
640
641 // Create the alias.
642
Greg Clayton238c0a12010-09-18 01:14:36 +0000643 if (m_interpreter.AliasExists (alias_command.c_str())
644 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000645 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000646 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Ingham767af882010-07-07 03:36:20 +0000647 if (tmp_option_arg_sp.get())
648 {
649 if (option_arg_vector->size() == 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000650 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000651 }
652 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
653 alias_command.c_str());
654 }
655
656 if (use_subcommand)
Greg Clayton238c0a12010-09-18 01:14:36 +0000657 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000658 else
Greg Clayton238c0a12010-09-18 01:14:36 +0000659 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000660 if (option_arg_vector->size() > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000661 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000662 result.SetStatus (eReturnStatusSuccessFinishNoResult);
663 }
664 else
665 {
666 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
667 result.SetStatus (eReturnStatusFailed);
Caroline Ticee6866a32010-10-28 23:17:48 +0000668 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000669 }
670 }
671
672 return result.Succeeded();
673 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000674
Jim Ingham767af882010-07-07 03:36:20 +0000675};
676
677#pragma mark CommandObjectCommandsUnalias
678//-------------------------------------------------------------------------
679// CommandObjectCommandsUnalias
680//-------------------------------------------------------------------------
681
Jim Inghamda26bd22012-06-08 21:56:10 +0000682class CommandObjectCommandsUnalias : public CommandObjectParsed
Jim Ingham767af882010-07-07 03:36:20 +0000683{
684public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000685 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000686 CommandObjectParsed (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000687 "command unalias",
Caroline Tice146292c2010-09-12 04:56:10 +0000688 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000689 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000690 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000691 CommandArgumentEntry arg;
692 CommandArgumentData alias_arg;
693
694 // Define the first (and only) variant of this arg.
695 alias_arg.arg_type = eArgTypeAliasName;
696 alias_arg.arg_repetition = eArgRepeatPlain;
697
698 // There is only one variant this argument could be; put it into the argument entry.
699 arg.push_back (alias_arg);
700
701 // Push the data for the first argument into the m_arguments vector.
702 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000703 }
704
705 ~CommandObjectCommandsUnalias()
706 {
707 }
708
Jim Inghamda26bd22012-06-08 21:56:10 +0000709protected:
Jim Ingham767af882010-07-07 03:36:20 +0000710 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000711 DoExecute (Args& args, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000712 {
713 CommandObject::CommandMap::iterator pos;
714 CommandObject *cmd_obj;
715
716 if (args.GetArgumentCount() != 0)
717 {
718 const char *command_name = args.GetArgumentAtIndex(0);
Greg Clayton238c0a12010-09-18 01:14:36 +0000719 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Ingham767af882010-07-07 03:36:20 +0000720 if (cmd_obj)
721 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000722 if (m_interpreter.CommandExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000723 {
724 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
725 command_name);
726 result.SetStatus (eReturnStatusFailed);
727 }
728 else
729 {
730
Greg Clayton238c0a12010-09-18 01:14:36 +0000731 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Ingham767af882010-07-07 03:36:20 +0000732 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000733 if (m_interpreter.AliasExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000734 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
735 command_name);
736 else
737 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
738 result.SetStatus (eReturnStatusFailed);
739 }
740 else
741 result.SetStatus (eReturnStatusSuccessFinishNoResult);
742 }
743 }
744 else
745 {
746 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
747 "current list of commands.\n",
748 command_name);
749 result.SetStatus (eReturnStatusFailed);
750 }
751 }
752 else
753 {
754 result.AppendError ("must call 'unalias' with a valid alias");
755 result.SetStatus (eReturnStatusFailed);
756 }
757
758 return result.Succeeded();
759 }
760};
761
Greg Claytond12aeab2011-04-20 16:37:46 +0000762//-------------------------------------------------------------------------
763// CommandObjectCommandsAddRegex
764//-------------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000765#pragma mark CommandObjectCommandsAddRegex
Greg Claytond12aeab2011-04-20 16:37:46 +0000766
Jim Inghamda26bd22012-06-08 21:56:10 +0000767class CommandObjectCommandsAddRegex : public CommandObjectParsed
Greg Claytond12aeab2011-04-20 16:37:46 +0000768{
769public:
770 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000771 CommandObjectParsed (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000772 "command regex",
Greg Claytond12aeab2011-04-20 16:37:46 +0000773 "Allow the user to create a regular expression command.",
Greg Clayton40e48242011-04-20 22:55:21 +0000774 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytond12aeab2011-04-20 16:37:46 +0000775 m_options (interpreter)
776 {
Greg Clayton40e48242011-04-20 22:55:21 +0000777 SetHelpLong(
778"This command allows the user to create powerful regular expression commands\n"
779"with substitutions. The regular expressions and substitutions are specified\n"
780"using the regular exression substitution format of:\n"
781"\n"
782" s/<regex>/<subst>/\n"
783"\n"
784"<regex> is a regular expression that can use parenthesis to capture regular\n"
785"expression input and substitute the captured matches in the output using %1\n"
786"for the first match, %2 for the second, and so on.\n"
787"\n"
788"The regular expressions can all be specified on the command line if more than\n"
789"one argument is provided. If just the command name is provided on the command\n"
790"line, then the regular expressions and substitutions can be entered on separate\n"
791" lines, followed by an empty line to terminate the command definition.\n"
792"\n"
793"EXAMPLES\n"
794"\n"
Sean Callanan7acd60a2012-08-16 21:46:58 +0000795"The following example will define a regular expression command named 'f' that\n"
Greg Clayton40e48242011-04-20 22:55:21 +0000796"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
797"a number follows 'f':\n"
Sean Callanan7acd60a2012-08-16 21:46:58 +0000798"\n"
799" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
800"\n"
Greg Clayton40e48242011-04-20 22:55:21 +0000801 );
Greg Claytond12aeab2011-04-20 16:37:46 +0000802 }
803
804 ~CommandObjectCommandsAddRegex()
805 {
806 }
807
808
Jim Inghamda26bd22012-06-08 21:56:10 +0000809protected:
Greg Claytond12aeab2011-04-20 16:37:46 +0000810 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000811 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytond12aeab2011-04-20 16:37:46 +0000812 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000813 const size_t argc = command.GetArgumentCount();
Greg Clayton40e48242011-04-20 22:55:21 +0000814 if (argc == 0)
Greg Claytond12aeab2011-04-20 16:37:46 +0000815 {
Jason Molenda4049bc32011-11-10 22:43:35 +0000816 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton40e48242011-04-20 22:55:21 +0000817 result.SetStatus (eReturnStatusFailed);
818 }
819 else
820 {
821 Error error;
Jim Inghamda26bd22012-06-08 21:56:10 +0000822 const char *name = command.GetArgumentAtIndex(0);
Greg Claytond12aeab2011-04-20 16:37:46 +0000823 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
824 name,
825 m_options.GetHelp (),
826 m_options.GetSyntax (),
827 10));
Greg Clayton40e48242011-04-20 22:55:21 +0000828
829 if (argc == 1)
Greg Claytond12aeab2011-04-20 16:37:46 +0000830 {
Greg Clayton40e48242011-04-20 22:55:21 +0000831 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
832 if (reader_sp)
833 {
834 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
Greg Claytond12aeab2011-04-20 16:37:46 +0000835 this, // baton
836 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton40e48242011-04-20 22:55:21 +0000837 NULL, // end token
Greg Claytond12aeab2011-04-20 16:37:46 +0000838 "> ", // prompt
Greg Clayton40e48242011-04-20 22:55:21 +0000839 true); // echo input
840 if (error.Success())
841 {
842 m_interpreter.GetDebugger().PushInputReader (reader_sp);
843 result.SetStatus (eReturnStatusSuccessFinishNoResult);
844 return true;
845 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000846 }
847 }
Greg Clayton40e48242011-04-20 22:55:21 +0000848 else
849 {
850 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
851 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000852 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton40e48242011-04-20 22:55:21 +0000853 error = AppendRegexSubstitution (arg_strref);
854 if (error.Fail())
855 break;
856 }
857
858 if (error.Success())
859 {
860 AddRegexCommandToInterpreter();
861 }
862 }
863 if (error.Fail())
864 {
865 result.AppendError (error.AsCString());
866 result.SetStatus (eReturnStatusFailed);
867 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000868 }
Greg Clayton40e48242011-04-20 22:55:21 +0000869
Greg Claytond12aeab2011-04-20 16:37:46 +0000870 return result.Succeeded();
871 }
872
Greg Clayton40e48242011-04-20 22:55:21 +0000873 Error
874 AppendRegexSubstitution (const llvm::StringRef &regex_sed)
Greg Claytond12aeab2011-04-20 16:37:46 +0000875 {
Greg Clayton40e48242011-04-20 22:55:21 +0000876 Error error;
877
878 if (m_regex_cmd_ap.get() == NULL)
Greg Claytond12aeab2011-04-20 16:37:46 +0000879 {
Greg Clayton40e48242011-04-20 22:55:21 +0000880 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
881 (int)regex_sed.size(),
882 regex_sed.data());
883 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000884 }
Greg Clayton40e48242011-04-20 22:55:21 +0000885
886 size_t regex_sed_size = regex_sed.size();
887
888 if (regex_sed_size <= 1)
889 {
890 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
891 (int)regex_sed.size(),
892 regex_sed.data());
893 return error;
894 }
895
896 if (regex_sed[0] != 's')
897 {
898 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
899 (int)regex_sed.size(),
900 regex_sed.data());
901 return error;
902 }
903 const size_t first_separator_char_pos = 1;
904 // use the char that follows 's' as the regex separator character
905 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
906 const char separator_char = regex_sed[first_separator_char_pos];
907 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
908
909 if (second_separator_char_pos == std::string::npos)
910 {
911 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
912 separator_char,
913 (int)(regex_sed.size() - first_separator_char_pos - 1),
914 regex_sed.data() + (first_separator_char_pos + 1));
915 return error;
916 }
917
918 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
919
920 if (third_separator_char_pos == std::string::npos)
921 {
922 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
923 separator_char,
924 (int)(regex_sed.size() - second_separator_char_pos - 1),
925 regex_sed.data() + (second_separator_char_pos + 1));
926 return error;
927 }
928
929 if (third_separator_char_pos != regex_sed_size - 1)
930 {
931 // Make sure that everything that follows the last regex
932 // separator char
933 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
934 {
935 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
936 (int)third_separator_char_pos + 1,
937 regex_sed.data(),
938 (int)(regex_sed.size() - third_separator_char_pos - 1),
939 regex_sed.data() + (third_separator_char_pos + 1));
940 return error;
941 }
942
943 }
944 else if (first_separator_char_pos + 1 == second_separator_char_pos)
945 {
946 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
947 separator_char,
948 separator_char,
949 separator_char,
950 (int)regex_sed.size(),
951 regex_sed.data());
952 return error;
953 }
954 else if (second_separator_char_pos + 1 == third_separator_char_pos)
955 {
956 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
957 separator_char,
958 separator_char,
959 separator_char,
960 (int)regex_sed.size(),
961 regex_sed.data());
962 return error;
963 }
964 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
965 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
966 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
967 subst.c_str());
968 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000969 }
970
971 void
Greg Clayton40e48242011-04-20 22:55:21 +0000972 AddRegexCommandToInterpreter()
Greg Claytond12aeab2011-04-20 16:37:46 +0000973 {
974 if (m_regex_cmd_ap.get())
975 {
976 if (m_regex_cmd_ap->HasRegexEntries())
977 {
978 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
979 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
980 }
981 }
982 }
983
Greg Clayton40e48242011-04-20 22:55:21 +0000984 void
985 InputReaderDidCancel()
986 {
987 m_regex_cmd_ap.reset();
988 }
989
Greg Claytond12aeab2011-04-20 16:37:46 +0000990 static size_t
991 InputReaderCallback (void *baton,
992 InputReader &reader,
993 lldb::InputReaderAction notification,
994 const char *bytes,
Jim Inghamda26bd22012-06-08 21:56:10 +0000995 size_t bytes_len)
996 {
997 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
998 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
999
1000 switch (notification)
1001 {
1002 case eInputReaderActivate:
1003 if (!batch_mode)
1004 {
1005 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1006 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1007 out_stream->Flush();
1008 }
1009 break;
1010 case eInputReaderReactivate:
1011 break;
1012
1013 case eInputReaderDeactivate:
1014 break;
1015
1016 case eInputReaderAsynchronousOutputWritten:
1017 break;
1018
1019 case eInputReaderGotToken:
1020 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1021 --bytes_len;
1022 if (bytes_len == 0)
1023 reader.SetIsDone(true);
1024 else if (bytes)
1025 {
1026 llvm::StringRef bytes_strref (bytes, bytes_len);
1027 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1028 if (error.Fail())
1029 {
1030 if (!batch_mode)
1031 {
1032 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1033 out_stream->Printf("error: %s\n", error.AsCString());
1034 out_stream->Flush();
1035 }
1036 add_regex_cmd->InputReaderDidCancel ();
1037 reader.SetIsDone (true);
1038 }
1039 }
1040 break;
1041
1042 case eInputReaderInterrupt:
1043 {
1044 reader.SetIsDone (true);
1045 if (!batch_mode)
1046 {
1047 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1048 out_stream->PutCString("Regular expression command creations was cancelled.\n");
1049 out_stream->Flush();
1050 }
1051 add_regex_cmd->InputReaderDidCancel ();
1052 }
1053 break;
1054
1055 case eInputReaderEndOfFile:
1056 reader.SetIsDone (true);
1057 break;
1058
1059 case eInputReaderDone:
1060 add_regex_cmd->AddRegexCommandToInterpreter();
1061 break;
1062 }
1063
1064 return bytes_len;
1065 }
1066
Greg Claytond12aeab2011-04-20 16:37:46 +00001067private:
1068 std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1069
1070 class CommandOptions : public Options
1071 {
1072 public:
1073
1074 CommandOptions (CommandInterpreter &interpreter) :
1075 Options (interpreter)
1076 {
1077 }
1078
1079 virtual
1080 ~CommandOptions (){}
1081
1082 virtual Error
1083 SetOptionValue (uint32_t option_idx, const char *option_arg)
1084 {
1085 Error error;
1086 char short_option = (char) m_getopt_table[option_idx].val;
1087
1088 switch (short_option)
1089 {
1090 case 'h':
1091 m_help.assign (option_arg);
1092 break;
1093 case 's':
1094 m_syntax.assign (option_arg);
1095 break;
1096
1097 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001098 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytond12aeab2011-04-20 16:37:46 +00001099 break;
1100 }
1101
1102 return error;
1103 }
1104
1105 void
1106 OptionParsingStarting ()
1107 {
1108 m_help.clear();
1109 m_syntax.clear();
1110 }
1111
1112 const OptionDefinition*
1113 GetDefinitions ()
1114 {
1115 return g_option_table;
1116 }
1117
1118 // Options table: Required for subclasses of Options.
1119
1120 static OptionDefinition g_option_table[];
1121
1122 const char *
1123 GetHelp ()
1124 {
1125 if (m_help.empty())
1126 return NULL;
1127 return m_help.c_str();
1128 }
1129 const char *
1130 GetSyntax ()
1131 {
1132 if (m_syntax.empty())
1133 return NULL;
1134 return m_syntax.c_str();
1135 }
1136 // Instance variables to hold the values for command options.
1137 protected:
1138 std::string m_help;
1139 std::string m_syntax;
1140 };
Jim Inghamda26bd22012-06-08 21:56:10 +00001141
Greg Claytond12aeab2011-04-20 16:37:46 +00001142 virtual Options *
1143 GetOptions ()
1144 {
1145 return &m_options;
1146 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001147
1148 CommandOptions m_options;
Greg Claytond12aeab2011-04-20 16:37:46 +00001149};
1150
Greg Claytond12aeab2011-04-20 16:37:46 +00001151OptionDefinition
1152CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1153{
Greg Clayton40e48242011-04-20 22:55:21 +00001154{ 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 +00001155{ 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 +00001156{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytond12aeab2011-04-20 16:37:46 +00001157};
1158
1159
Jim Inghamda26bd22012-06-08 21:56:10 +00001160class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata6b1596d2011-08-16 23:24:13 +00001161{
1162private:
1163 std::string m_function_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001164 ScriptedCommandSynchronicity m_synchro;
Enrico Granata5b9f7772012-09-18 21:53:02 +00001165 bool m_fetched_help_long;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001166
1167public:
1168
1169 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1170 std::string name,
Enrico Granata6010ace2011-11-07 22:57:04 +00001171 std::string funct,
1172 ScriptedCommandSynchronicity synch) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001173 CommandObjectRaw (interpreter,
1174 name.c_str(),
1175 (std::string("Run Python function ") + funct).c_str(),
1176 NULL),
1177 m_function_name(funct),
Enrico Granata5b9f7772012-09-18 21:53:02 +00001178 m_synchro(synch),
1179 m_fetched_help_long(false)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001180 {
1181 }
1182
1183 virtual
1184 ~CommandObjectPythonFunction ()
1185 {
1186 }
1187
1188 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001189 IsRemovable ()
1190 {
1191 return true;
1192 }
1193
1194 const std::string&
1195 GetFunctionName ()
1196 {
1197 return m_function_name;
1198 }
1199
1200 ScriptedCommandSynchronicity
1201 GetSynchronicity ()
1202 {
1203 return m_synchro;
1204 }
1205
Enrico Granata5b9f7772012-09-18 21:53:02 +00001206 virtual const char *
1207 GetHelpLong ()
1208 {
1209 if (!m_fetched_help_long)
1210 {
1211 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1212 if (scripter)
1213 {
1214 std::string docstring;
1215 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1216 if (!docstring.empty())
1217 SetHelpLong(docstring);
1218 }
1219 }
1220 return CommandObjectRaw::GetHelpLong();
1221 }
1222
Jim Inghamda26bd22012-06-08 21:56:10 +00001223protected:
1224 virtual bool
1225 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001226 {
1227 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1228
1229 Error error;
1230
Jim Ingham839de392012-06-27 17:25:36 +00001231 result.SetStatus(eReturnStatusInvalid);
1232
Enrico Granata6b1596d2011-08-16 23:24:13 +00001233 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1234 raw_command_line,
Enrico Granata6010ace2011-11-07 22:57:04 +00001235 m_synchro,
Enrico Granata6b1596d2011-08-16 23:24:13 +00001236 result,
1237 error) == false)
1238 {
1239 result.AppendError(error.AsCString());
1240 result.SetStatus(eReturnStatusFailed);
1241 }
1242 else
Jim Ingham839de392012-06-27 17:25:36 +00001243 {
1244 // Don't change the status if the command already set it...
1245 if (result.GetStatus() == eReturnStatusInvalid)
1246 {
1247 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1248 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1249 else
1250 result.SetStatus(eReturnStatusSuccessFinishResult);
1251 }
1252 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001253
1254 return result.Succeeded();
1255 }
1256
Enrico Granata6b1596d2011-08-16 23:24:13 +00001257};
1258
Enrico Granata59df36f2011-10-17 21:45:27 +00001259//-------------------------------------------------------------------------
1260// CommandObjectCommandsScriptImport
1261//-------------------------------------------------------------------------
1262
Jim Inghamda26bd22012-06-08 21:56:10 +00001263class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granata59df36f2011-10-17 21:45:27 +00001264{
Jim Inghamda26bd22012-06-08 21:56:10 +00001265public:
1266 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1267 CommandObjectParsed (interpreter,
1268 "command script import",
1269 "Import a scripting module in LLDB.",
1270 NULL),
1271 m_options(interpreter)
1272 {
1273 CommandArgumentEntry arg1;
1274 CommandArgumentData cmd_arg;
1275
1276 // Define the first (and only) variant of this arg.
1277 cmd_arg.arg_type = eArgTypeFilename;
1278 cmd_arg.arg_repetition = eArgRepeatPlain;
1279
1280 // There is only one variant this argument could be; put it into the argument entry.
1281 arg1.push_back (cmd_arg);
1282
1283 // Push the data for the first argument into the m_arguments vector.
1284 m_arguments.push_back (arg1);
1285 }
1286
1287 ~CommandObjectCommandsScriptImport ()
1288 {
1289 }
1290
1291 int
1292 HandleArgumentCompletion (Args &input,
1293 int &cursor_index,
1294 int &cursor_char_position,
1295 OptionElementVector &opt_element_vector,
1296 int match_start_point,
1297 int max_return_elements,
1298 bool &word_complete,
1299 StringList &matches)
1300 {
1301 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1302 completion_str.erase (cursor_char_position);
1303
1304 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1305 CommandCompletions::eDiskFileCompletion,
1306 completion_str.c_str(),
1307 match_start_point,
1308 max_return_elements,
1309 NULL,
1310 word_complete,
1311 matches);
1312 return matches.GetSize();
1313 }
1314
1315 virtual Options *
1316 GetOptions ()
1317 {
1318 return &m_options;
1319 }
1320
1321protected:
Enrico Granata6010ace2011-11-07 22:57:04 +00001322
1323 class CommandOptions : public Options
1324 {
1325 public:
1326
1327 CommandOptions (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001328 Options (interpreter)
Enrico Granata6010ace2011-11-07 22:57:04 +00001329 {
1330 }
1331
1332 virtual
1333 ~CommandOptions (){}
1334
1335 virtual Error
1336 SetOptionValue (uint32_t option_idx, const char *option_arg)
1337 {
1338 Error error;
1339 char short_option = (char) m_getopt_table[option_idx].val;
1340
1341 switch (short_option)
1342 {
1343 case 'r':
1344 m_allow_reload = true;
1345 break;
1346 default:
1347 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1348 break;
1349 }
1350
1351 return error;
1352 }
1353
1354 void
1355 OptionParsingStarting ()
1356 {
1357 m_allow_reload = false;
1358 }
1359
1360 const OptionDefinition*
1361 GetDefinitions ()
1362 {
1363 return g_option_table;
1364 }
1365
1366 // Options table: Required for subclasses of Options.
1367
1368 static OptionDefinition g_option_table[];
1369
1370 // Instance variables to hold the values for command options.
1371
1372 bool m_allow_reload;
1373 };
Enrico Granata6010ace2011-11-07 22:57:04 +00001374
Enrico Granata59df36f2011-10-17 21:45:27 +00001375 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001376 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata59df36f2011-10-17 21:45:27 +00001377 {
1378
1379 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1380 {
1381 result.AppendError ("only scripting language supported for module importing is currently Python");
1382 result.SetStatus (eReturnStatusFailed);
1383 return false;
1384 }
1385
Jim Inghamda26bd22012-06-08 21:56:10 +00001386 size_t argc = command.GetArgumentCount();
Enrico Granata59df36f2011-10-17 21:45:27 +00001387
1388 if (argc != 1)
1389 {
1390 result.AppendError ("'command script import' requires one argument");
1391 result.SetStatus (eReturnStatusFailed);
1392 return false;
1393 }
1394
Jim Inghamda26bd22012-06-08 21:56:10 +00001395 std::string path = command.GetArgumentAtIndex(0);
Enrico Granata59df36f2011-10-17 21:45:27 +00001396 Error error;
1397
1398 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001399 m_options.m_allow_reload,
Enrico Granata59df36f2011-10-17 21:45:27 +00001400 error))
1401 {
1402 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1403 }
1404 else
1405 {
1406 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1407 result.SetStatus (eReturnStatusFailed);
1408 }
1409
1410 return result.Succeeded();
1411 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001412
Jim Inghamda26bd22012-06-08 21:56:10 +00001413 CommandOptions m_options;
Enrico Granata59df36f2011-10-17 21:45:27 +00001414};
Enrico Granata6b1596d2011-08-16 23:24:13 +00001415
Enrico Granata6010ace2011-11-07 22:57:04 +00001416OptionDefinition
1417CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1418{
1419 { 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)."},
1420 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1421};
1422
1423
Enrico Granata6b1596d2011-08-16 23:24:13 +00001424//-------------------------------------------------------------------------
1425// CommandObjectCommandsScriptAdd
1426//-------------------------------------------------------------------------
1427
Jim Inghamda26bd22012-06-08 21:56:10 +00001428class CommandObjectCommandsScriptAdd : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001429{
Jim Inghamda26bd22012-06-08 21:56:10 +00001430public:
1431 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1432 CommandObjectParsed (interpreter,
1433 "command script add",
1434 "Add a scripted function as an LLDB command.",
1435 NULL),
1436 m_options (interpreter)
1437 {
1438 CommandArgumentEntry arg1;
1439 CommandArgumentData cmd_arg;
1440
1441 // Define the first (and only) variant of this arg.
1442 cmd_arg.arg_type = eArgTypeCommandName;
1443 cmd_arg.arg_repetition = eArgRepeatPlain;
1444
1445 // There is only one variant this argument could be; put it into the argument entry.
1446 arg1.push_back (cmd_arg);
1447
1448 // Push the data for the first argument into the m_arguments vector.
1449 m_arguments.push_back (arg1);
1450 }
1451
1452 ~CommandObjectCommandsScriptAdd ()
1453 {
1454 }
1455
1456 virtual Options *
1457 GetOptions ()
1458 {
1459 return &m_options;
1460 }
1461
1462protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001463
1464 class CommandOptions : public Options
1465 {
1466 public:
1467
1468 CommandOptions (CommandInterpreter &interpreter) :
1469 Options (interpreter)
1470 {
1471 }
1472
1473 virtual
1474 ~CommandOptions (){}
1475
1476 virtual Error
1477 SetOptionValue (uint32_t option_idx, const char *option_arg)
1478 {
1479 Error error;
1480 char short_option = (char) m_getopt_table[option_idx].val;
1481
1482 switch (short_option)
1483 {
1484 case 'f':
1485 m_funct_name = std::string(option_arg);
1486 break;
Enrico Granata6010ace2011-11-07 22:57:04 +00001487 case 's':
1488 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1489 if (!error.Success())
1490 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1491 break;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001492 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001493 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001494 break;
1495 }
1496
1497 return error;
1498 }
1499
1500 void
1501 OptionParsingStarting ()
1502 {
1503 m_funct_name = "";
Enrico Granata6010ace2011-11-07 22:57:04 +00001504 m_synchronous = eScriptedCommandSynchronicitySynchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001505 }
1506
1507 const OptionDefinition*
1508 GetDefinitions ()
1509 {
1510 return g_option_table;
1511 }
1512
1513 // Options table: Required for subclasses of Options.
1514
1515 static OptionDefinition g_option_table[];
1516
1517 // Instance variables to hold the values for command options.
1518
1519 std::string m_funct_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001520 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001521 };
Jim Inghamda26bd22012-06-08 21:56:10 +00001522
1523private:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001524 class PythonAliasReader : public InputReaderEZ
1525 {
1526 private:
1527 CommandInterpreter& m_interpreter;
1528 std::string m_cmd_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001529 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001530 StringList m_user_input;
1531 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1532 public:
1533 PythonAliasReader(Debugger& debugger,
1534 CommandInterpreter& interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001535 std::string cmd_name,
1536 ScriptedCommandSynchronicity synch) :
Enrico Granata6b1596d2011-08-16 23:24:13 +00001537 InputReaderEZ(debugger),
1538 m_interpreter(interpreter),
1539 m_cmd_name(cmd_name),
Enrico Granata6010ace2011-11-07 22:57:04 +00001540 m_synchronous(synch),
Enrico Granata6b1596d2011-08-16 23:24:13 +00001541 m_user_input()
1542 {}
1543
1544 virtual
1545 ~PythonAliasReader()
1546 {
1547 }
1548
1549 virtual void ActivateHandler(HandlerData& data)
1550 {
1551 StreamSP out_stream = data.GetOutStream();
1552 bool batch_mode = data.GetBatchMode();
1553 if (!batch_mode)
1554 {
1555 out_stream->Printf ("%s\n", g_python_command_instructions);
1556 if (data.reader.GetPrompt())
1557 out_stream->Printf ("%s", data.reader.GetPrompt());
1558 out_stream->Flush();
1559 }
1560 }
1561
1562 virtual void ReactivateHandler(HandlerData& data)
1563 {
1564 StreamSP out_stream = data.GetOutStream();
1565 bool batch_mode = data.GetBatchMode();
1566 if (data.reader.GetPrompt() && !batch_mode)
1567 {
1568 out_stream->Printf ("%s", data.reader.GetPrompt());
1569 out_stream->Flush();
1570 }
1571 }
1572 virtual void GotTokenHandler(HandlerData& data)
1573 {
1574 StreamSP out_stream = data.GetOutStream();
1575 bool batch_mode = data.GetBatchMode();
1576 if (data.bytes && data.bytes_len)
1577 {
1578 m_user_input.AppendString(data.bytes, data.bytes_len);
1579 }
1580 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1581 {
1582 out_stream->Printf ("%s", data.reader.GetPrompt());
1583 out_stream->Flush();
1584 }
1585 }
1586 virtual void InterruptHandler(HandlerData& data)
1587 {
1588 StreamSP out_stream = data.GetOutStream();
1589 bool batch_mode = data.GetBatchMode();
1590 data.reader.SetIsDone (true);
1591 if (!batch_mode)
1592 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001593 out_stream->Printf ("Warning: No script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001594 out_stream->Flush();
1595 }
1596 }
1597 virtual void EOFHandler(HandlerData& data)
1598 {
1599 data.reader.SetIsDone (true);
1600 }
1601 virtual void DoneHandler(HandlerData& data)
1602 {
1603 StreamSP out_stream = data.GetOutStream();
1604
1605 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1606 if (!interpreter)
1607 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001608 out_stream->Printf ("Script interpreter missing: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001609 out_stream->Flush();
1610 return;
1611 }
Enrico Granata400105d2012-03-06 23:42:15 +00001612 std::string funct_name_str;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001613 if (!interpreter->GenerateScriptAliasFunction (m_user_input,
Enrico Granata400105d2012-03-06 23:42:15 +00001614 funct_name_str))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001615 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001616 out_stream->Printf ("Unable to create function: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001617 out_stream->Flush();
1618 return;
1619 }
Enrico Granata400105d2012-03-06 23:42:15 +00001620 if (funct_name_str.empty())
Enrico Granata6b1596d2011-08-16 23:24:13 +00001621 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001622 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001623 out_stream->Flush();
1624 return;
1625 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001626 // everything should be fine now, let's add this alias
1627
1628 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1629 m_cmd_name,
Enrico Granata400105d2012-03-06 23:42:15 +00001630 funct_name_str.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001631 m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001632
Enrico Granata6010ace2011-11-07 22:57:04 +00001633 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001634 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001635 out_stream->Printf ("Unable to add selected command: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001636 out_stream->Flush();
1637 return;
1638 }
1639 }
1640 };
1641
Jim Inghamda26bd22012-06-08 21:56:10 +00001642protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001643 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001644 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001645 {
Enrico Granatae5e34cb2011-08-17 01:30:04 +00001646
1647 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1648 {
1649 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1650 result.SetStatus (eReturnStatusFailed);
1651 return false;
1652 }
1653
Jim Inghamda26bd22012-06-08 21:56:10 +00001654 size_t argc = command.GetArgumentCount();
Enrico Granata6b1596d2011-08-16 23:24:13 +00001655
1656 if (argc != 1)
1657 {
1658 result.AppendError ("'command script add' requires one argument");
1659 result.SetStatus (eReturnStatusFailed);
1660 return false;
1661 }
1662
Jim Inghamda26bd22012-06-08 21:56:10 +00001663 std::string cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001664
1665 if (m_options.m_funct_name.empty())
1666 {
1667 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1668 m_interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001669 cmd_name,
1670 m_options.m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001671
1672 if (reader_sp)
1673 {
1674
1675 InputReaderEZ::InitializationParameters ipr;
1676
1677 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
1678 if (err.Success())
1679 {
1680 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1681 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1682 }
1683 else
1684 {
1685 result.AppendError (err.AsCString());
1686 result.SetStatus (eReturnStatusFailed);
1687 }
1688 }
1689 else
1690 {
1691 result.AppendError("out of memory");
1692 result.SetStatus (eReturnStatusFailed);
1693 }
1694 }
1695 else
1696 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001697 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1698 cmd_name,
1699 m_options.m_funct_name,
1700 m_options.m_synchronous));
1701 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001702 {
1703 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1704 }
1705 else
1706 {
1707 result.AppendError("cannot add command");
1708 result.SetStatus (eReturnStatusFailed);
1709 }
1710 }
1711
1712 return result.Succeeded();
1713
1714 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001715
1716 CommandOptions m_options;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001717};
1718
Enrico Granata6010ace2011-11-07 22:57:04 +00001719static OptionEnumValueElement g_script_synchro_type[] =
1720{
1721 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1722 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1723 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1724 { 0, NULL, NULL }
1725};
1726
Enrico Granata6b1596d2011-08-16 23:24:13 +00001727OptionDefinition
1728CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1729{
Enrico Granata91544802011-09-06 19:20:51 +00001730 { 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 +00001731 { 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 +00001732 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1733};
1734
1735//-------------------------------------------------------------------------
1736// CommandObjectCommandsScriptList
1737//-------------------------------------------------------------------------
1738
Jim Inghamda26bd22012-06-08 21:56:10 +00001739class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001740{
1741private:
Enrico Granata6010ace2011-11-07 22:57:04 +00001742
Enrico Granata6b1596d2011-08-16 23:24:13 +00001743public:
1744 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001745 CommandObjectParsed (interpreter,
Enrico Granata6b1596d2011-08-16 23:24:13 +00001746 "command script list",
1747 "List defined scripted commands.",
1748 NULL)
1749 {
1750 }
1751
1752 ~CommandObjectCommandsScriptList ()
1753 {
1754 }
1755
1756 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001757 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001758 {
1759
1760 m_interpreter.GetHelp(result,
1761 CommandInterpreter::eCommandTypesUserDef);
1762
1763 result.SetStatus (eReturnStatusSuccessFinishResult);
1764
1765 return true;
1766
1767
1768 }
1769};
1770
1771//-------------------------------------------------------------------------
1772// CommandObjectCommandsScriptClear
1773//-------------------------------------------------------------------------
1774
Jim Inghamda26bd22012-06-08 21:56:10 +00001775class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001776{
1777private:
1778
1779public:
1780 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001781 CommandObjectParsed (interpreter,
1782 "command script clear",
1783 "Delete all scripted commands.",
1784 NULL)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001785 {
1786 }
1787
1788 ~CommandObjectCommandsScriptClear ()
1789 {
1790 }
1791
Jim Inghamda26bd22012-06-08 21:56:10 +00001792protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001793 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001794 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001795 {
1796
1797 m_interpreter.RemoveAllUser();
1798
1799 result.SetStatus (eReturnStatusSuccessFinishResult);
1800
1801 return true;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001802 }
1803};
1804
1805//-------------------------------------------------------------------------
1806// CommandObjectCommandsScriptDelete
1807//-------------------------------------------------------------------------
1808
Jim Inghamda26bd22012-06-08 21:56:10 +00001809class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001810{
Enrico Granata6b1596d2011-08-16 23:24:13 +00001811public:
1812 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001813 CommandObjectParsed (interpreter,
1814 "command script delete",
1815 "Delete a scripted command.",
1816 NULL)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001817 {
1818 CommandArgumentEntry arg1;
1819 CommandArgumentData cmd_arg;
1820
1821 // Define the first (and only) variant of this arg.
1822 cmd_arg.arg_type = eArgTypeCommandName;
1823 cmd_arg.arg_repetition = eArgRepeatPlain;
1824
1825 // There is only one variant this argument could be; put it into the argument entry.
1826 arg1.push_back (cmd_arg);
1827
1828 // Push the data for the first argument into the m_arguments vector.
1829 m_arguments.push_back (arg1);
1830 }
1831
1832 ~CommandObjectCommandsScriptDelete ()
1833 {
1834 }
1835
Jim Inghamda26bd22012-06-08 21:56:10 +00001836protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001837 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001838 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001839 {
1840
Jim Inghamda26bd22012-06-08 21:56:10 +00001841 size_t argc = command.GetArgumentCount();
Enrico Granata6b1596d2011-08-16 23:24:13 +00001842
1843 if (argc != 1)
1844 {
1845 result.AppendError ("'command script delete' requires one argument");
1846 result.SetStatus (eReturnStatusFailed);
1847 return false;
1848 }
1849
Jim Inghamda26bd22012-06-08 21:56:10 +00001850 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001851
1852 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1853 {
1854 m_interpreter.RemoveUser(cmd_name);
1855 result.SetStatus (eReturnStatusSuccessFinishResult);
1856 }
1857 else
1858 {
1859 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1860 result.SetStatus (eReturnStatusFailed);
1861 }
1862
1863 return result.Succeeded();
1864
1865 }
1866};
1867
1868#pragma mark CommandObjectMultiwordCommandsScript
1869
1870//-------------------------------------------------------------------------
1871// CommandObjectMultiwordCommandsScript
1872//-------------------------------------------------------------------------
1873
1874class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1875{
1876public:
1877 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1878 CommandObjectMultiword (interpreter,
1879 "command script",
1880 "A set of commands for managing or customizing script commands.",
1881 "command script <subcommand> [<subcommand-options>]")
1882 {
1883 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1884 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1885 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1886 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Enrico Granata59df36f2011-10-17 21:45:27 +00001887 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001888 }
1889
1890 ~CommandObjectMultiwordCommandsScript ()
1891 {
1892 }
1893
1894};
1895
1896
Jim Ingham767af882010-07-07 03:36:20 +00001897#pragma mark CommandObjectMultiwordCommands
1898
1899//-------------------------------------------------------------------------
1900// CommandObjectMultiwordCommands
1901//-------------------------------------------------------------------------
1902
1903CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001904 CommandObjectMultiword (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +00001905 "command",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001906 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton40e48242011-04-20 22:55:21 +00001907 "command <subcommand> [<subcommand-options>]")
Jim Ingham767af882010-07-07 03:36:20 +00001908{
Greg Clayton238c0a12010-09-18 01:14:36 +00001909 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1910 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1911 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytond12aeab2011-04-20 16:37:46 +00001912 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Ingham6247dbe2011-07-12 03:12:18 +00001913 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001914 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Ingham767af882010-07-07 03:36:20 +00001915}
1916
1917CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1918{
1919}
1920