blob: e8937eaaba52cf69de61fcbe0ef950e1c0f9001b [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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Jim Ingham767af882010-07-07 03:36:20 +000012#include "CommandObjectCommands.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
Greg Clayton40e48242011-04-20 22:55:21 +000017#include "llvm/ADT/StringRef.h"
18
Jim Ingham767af882010-07-07 03:36:20 +000019// Project includes
Jim Ingham767af882010-07-07 03:36:20 +000020#include "lldb/Core/Debugger.h"
Greg Claytond12aeab2011-04-20 16:37:46 +000021#include "lldb/Core/InputReader.h"
Enrico Granatac2a28252011-08-16 16:49:25 +000022#include "lldb/Core/InputReaderEZ.h"
23#include "lldb/Core/StringList.h"
Greg Claytond12aeab2011-04-20 16:37:46 +000024#include "lldb/Interpreter/Args.h"
Jim Ingham767af882010-07-07 03:36:20 +000025#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytond12aeab2011-04-20 16:37:46 +000026#include "lldb/Interpreter/CommandObjectRegexCommand.h"
Jim Ingham767af882010-07-07 03:36:20 +000027#include "lldb/Interpreter/CommandReturnObject.h"
28#include "lldb/Interpreter/Options.h"
Enrico Granatae5e34cb2011-08-17 01:30:04 +000029#include "lldb/Interpreter/ScriptInterpreter.h"
30#include "lldb/Interpreter/ScriptInterpreterPython.h"
Jim Ingham767af882010-07-07 03:36:20 +000031
32using namespace lldb;
33using namespace lldb_private;
34
Jim Ingham767af882010-07-07 03:36:20 +000035//-------------------------------------------------------------------------
36// CommandObjectCommandsSource
37//-------------------------------------------------------------------------
38
Jim Inghamda26bd22012-06-08 21:56:10 +000039class CommandObjectCommandsHistory : public CommandObjectParsed
Jim Ingham6247dbe2011-07-12 03:12:18 +000040{
Jim Inghamda26bd22012-06-08 21:56:10 +000041public:
42 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
43 CommandObjectParsed (interpreter,
44 "command history",
45 "Dump the history of commands in this session.",
46 NULL),
47 m_options (interpreter)
48 {
49 }
50
51 ~CommandObjectCommandsHistory () {}
52
53 virtual Options *
54 GetOptions ()
55 {
56 return &m_options;
57 }
58
59protected:
Jim Ingham6247dbe2011-07-12 03:12:18 +000060
61 class CommandOptions : public Options
62 {
63 public:
64
65 CommandOptions (CommandInterpreter &interpreter) :
66 Options (interpreter)
67 {
68 }
69
70 virtual
71 ~CommandOptions (){}
72
73 virtual Error
74 SetOptionValue (uint32_t option_idx, const char *option_arg)
75 {
76 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +000077 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham6247dbe2011-07-12 03:12:18 +000078 bool success;
79
80 switch (short_option)
81 {
82 case 'c':
83 m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
84 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000085 error.SetErrorStringWithFormat("invalid value for count: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000086 if (m_end_idx != 0)
87 m_end_idx--;
88 m_start_idx = 0;
89 break;
90 case 'e':
91 m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
92 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000093 error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000094 break;
95 case 's':
96 m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
97 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000098 error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg);
Jim Ingham6247dbe2011-07-12 03:12:18 +000099 break;
100 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000101 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Ingham6247dbe2011-07-12 03:12:18 +0000102 break;
103 }
104
105 return error;
106 }
107
108 void
109 OptionParsingStarting ()
110 {
111 m_start_idx = 0;
112 m_end_idx = UINT_MAX;
113 }
114
115 const OptionDefinition*
116 GetDefinitions ()
117 {
118 return g_option_table;
119 }
120
121 // Options table: Required for subclasses of Options.
122
123 static OptionDefinition g_option_table[];
124
125 // Instance variables to hold the values for command options.
126
127 uint32_t m_start_idx;
128 uint32_t m_end_idx;
129 };
130
Jim Ingham6247dbe2011-07-12 03:12:18 +0000131 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000132 DoExecute (Args& command, CommandReturnObject &result)
Jim Ingham6247dbe2011-07-12 03:12:18 +0000133 {
134
135 m_interpreter.DumpHistory (result.GetOutputStream(),
136 m_options.m_start_idx,
137 m_options.m_end_idx);
138 return result.Succeeded();
139
140 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000141
142 CommandOptions m_options;
Jim Ingham6247dbe2011-07-12 03:12:18 +0000143};
144
145OptionDefinition
146CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
147{
148{ LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
149{ LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands."},
150{ LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
151{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
152};
153
154
155//-------------------------------------------------------------------------
156// CommandObjectCommandsSource
157//-------------------------------------------------------------------------
158
Jim Inghamda26bd22012-06-08 21:56:10 +0000159class CommandObjectCommandsSource : public CommandObjectParsed
Jim Ingham767af882010-07-07 03:36:20 +0000160{
Jim Inghamda26bd22012-06-08 21:56:10 +0000161public:
162 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
163 CommandObjectParsed (interpreter,
164 "command source",
165 "Read in debugger commands from the file <filename> and execute them.",
166 NULL),
167 m_options (interpreter)
168 {
169 CommandArgumentEntry arg;
170 CommandArgumentData file_arg;
171
172 // Define the first (and only) variant of this arg.
173 file_arg.arg_type = eArgTypeFilename;
174 file_arg.arg_repetition = eArgRepeatPlain;
175
176 // There is only one variant this argument could be; put it into the argument entry.
177 arg.push_back (file_arg);
178
179 // Push the data for the first argument into the m_arguments vector.
180 m_arguments.push_back (arg);
181 }
182
183 ~CommandObjectCommandsSource () {}
184
185 virtual const char*
186 GetRepeatCommand (Args &current_command_args, uint32_t index)
187 {
188 return "";
189 }
190
191 int
192 HandleArgumentCompletion (Args &input,
193 int &cursor_index,
194 int &cursor_char_position,
195 OptionElementVector &opt_element_vector,
196 int match_start_point,
197 int max_return_elements,
198 bool &word_complete,
199 StringList &matches)
200 {
201 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
202 completion_str.erase (cursor_char_position);
203
204 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
205 CommandCompletions::eDiskFileCompletion,
206 completion_str.c_str(),
207 match_start_point,
208 max_return_elements,
209 NULL,
210 word_complete,
211 matches);
212 return matches.GetSize();
213 }
214
215 virtual Options *
216 GetOptions ()
217 {
218 return &m_options;
219 }
220
221protected:
Jim Ingham949d5ac2011-02-18 00:54:25 +0000222
223 class CommandOptions : public Options
224 {
225 public:
226
Greg Claytonf15996e2011-04-07 22:46:35 +0000227 CommandOptions (CommandInterpreter &interpreter) :
228 Options (interpreter)
229 {
230 }
Jim Ingham949d5ac2011-02-18 00:54:25 +0000231
232 virtual
233 ~CommandOptions (){}
234
235 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000236 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham949d5ac2011-02-18 00:54:25 +0000237 {
238 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000239 const int short_option = m_getopt_table[option_idx].val;
Jim Ingham949d5ac2011-02-18 00:54:25 +0000240 bool success;
241
242 switch (short_option)
243 {
244 case 'e':
245 m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
246 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000247 error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000248 break;
249 case 'c':
250 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
251 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000252 error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000253 break;
254 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000255 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000256 break;
257 }
258
259 return error;
260 }
261
262 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000263 OptionParsingStarting ()
Jim Ingham949d5ac2011-02-18 00:54:25 +0000264 {
Jim Ingham949d5ac2011-02-18 00:54:25 +0000265 m_stop_on_error = true;
266 m_stop_on_continue = true;
267 }
268
Greg Claytonb3448432011-03-24 21:19:54 +0000269 const OptionDefinition*
Jim Ingham949d5ac2011-02-18 00:54:25 +0000270 GetDefinitions ()
271 {
272 return g_option_table;
273 }
274
275 // Options table: Required for subclasses of Options.
276
Greg Claytonb3448432011-03-24 21:19:54 +0000277 static OptionDefinition g_option_table[];
Jim Ingham949d5ac2011-02-18 00:54:25 +0000278
279 // Instance variables to hold the values for command options.
280
281 bool m_stop_on_error;
282 bool m_stop_on_continue;
283 };
284
Jim Ingham767af882010-07-07 03:36:20 +0000285 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000286 DoExecute(Args& command, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000287 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000288 const int argc = command.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000289 if (argc == 1)
290 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000291 const char *filename = command.GetArgumentAtIndex(0);
Jim Ingham767af882010-07-07 03:36:20 +0000292
293 result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
294
Johnny Chena83ea882010-10-20 21:40:50 +0000295 FileSpec cmd_file (filename, true);
Jim Ingham949d5ac2011-02-18 00:54:25 +0000296 ExecutionContext *exe_ctx = NULL; // Just use the default context.
297 bool echo_commands = true;
298 bool print_results = true;
Jim Ingham767af882010-07-07 03:36:20 +0000299
Jim Ingham949d5ac2011-02-18 00:54:25 +0000300 m_interpreter.HandleCommandsFromFile (cmd_file,
301 exe_ctx,
302 m_options.m_stop_on_continue,
303 m_options.m_stop_on_error,
304 echo_commands,
Enrico Granata01bc2d42012-05-31 01:09:06 +0000305 print_results,
306 eLazyBoolCalculate,
Jim Ingham949d5ac2011-02-18 00:54:25 +0000307 result);
Jim Ingham767af882010-07-07 03:36:20 +0000308 }
309 else
310 {
311 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
312 result.SetStatus (eReturnStatusFailed);
313 }
314 return result.Succeeded();
315
316 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000317 CommandOptions m_options;
Jim Ingham767af882010-07-07 03:36:20 +0000318};
319
Greg Claytonb3448432011-03-24 21:19:54 +0000320OptionDefinition
Jim Ingham949d5ac2011-02-18 00:54:25 +0000321CommandObjectCommandsSource::CommandOptions::g_option_table[] =
322{
323{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
324{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
325{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
326};
327
Jim Ingham767af882010-07-07 03:36:20 +0000328#pragma mark CommandObjectCommandsAlias
329//-------------------------------------------------------------------------
330// CommandObjectCommandsAlias
331//-------------------------------------------------------------------------
332
Enrico Granatac2a28252011-08-16 16:49:25 +0000333static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
334 "You must define a Python function with this signature:\n"
Enrico Granatac1ca9dc2012-08-08 02:06:30 +0000335 "def my_command_impl(debugger, args, result, internal_dict):";
Enrico Granatac2a28252011-08-16 16:49:25 +0000336
337
Jim Inghamda26bd22012-06-08 21:56:10 +0000338class CommandObjectCommandsAlias : public CommandObjectRaw
Jim Ingham767af882010-07-07 03:36:20 +0000339{
Enrico Granatac2a28252011-08-16 16:49:25 +0000340
Enrico Granatac2a28252011-08-16 16:49:25 +0000341
Jim Ingham767af882010-07-07 03:36:20 +0000342public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000343 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000344 CommandObjectRaw (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000345 "command alias",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000346 "Allow users to define their own debugger command abbreviations.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000347 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000348 {
349 SetHelpLong(
350 "'alias' allows the user to create a short-cut or abbreviation for long \n\
351 commands, multi-word commands, and commands that take particular options. \n\
352 Below are some simple examples of how one might use the 'alias' command: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000353 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000354 // command. \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000355 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000356 // command. Since breakpoint commands are two-word \n\
357 // commands, the user will still need to enter the \n\
358 // second word after 'bp', e.g. 'bp enable' or \n\
359 // 'bp delete'. \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000360 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000361 // two-word command 'breakpoint list'. \n\
Jim Ingham767af882010-07-07 03:36:20 +0000362 \nAn alias can include some options for the command, with the values either \n\
363 filled in at the time the alias is created, or specified as positional \n\
364 arguments, to be filled in when the alias is invoked. The following example \n\
365 shows how to create aliases with options: \n\
366 \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000367 'command alias bfl breakpoint set -f %1 -l %2' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000368 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
369 options already part of the alias. So if the user wants to set a breakpoint \n\
370 by file and line without explicitly having to use the -f and -l options, the \n\
371 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
372 for the actual arguments that will be passed when the alias command is used. \n\
373 The number in the placeholder refers to the position/order the actual value \n\
Jim Ingham536f6332011-08-18 02:29:05 +0000374 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
Jim Ingham767af882010-07-07 03:36:20 +0000375 will be replaced with the first argument, all the occurrences of '%2' in the \n\
376 alias will be replaced with the second argument, and so on. This also allows \n\
377 actual arguments to be used multiple times within an alias (see 'process \n\
Jim Ingham536f6332011-08-18 02:29:05 +0000378 launch' example below). \n\
379 Note: the positional arguments must substitute as whole words in the resultant\n\
380 command, so you can't at present do something like:\n\
381 \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000382 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
Jim Ingham536f6332011-08-18 02:29:05 +0000383 \n\
384 to get the file extension \".cpp\" automatically appended. For more complex\n\
385 aliasing, use the \"command regex\" command instead.\n\
386 \nSo in the 'bfl' case, the actual file value will be \n\
Jim Ingham767af882010-07-07 03:36:20 +0000387 filled in with the first argument following 'bfl' and the actual line number \n\
388 value will be filled in with the second argument. The user would use this \n\
389 alias as follows: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000390 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000391 <... some time later ...> \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000392 (lldb) bfl my-file.c 137 \n\
Jim Ingham767af882010-07-07 03:36:20 +0000393 \nThis would be the same as if the user had entered \n\
394 'breakpoint set -f my-file.c -l 137'. \n\
395 \nAnother example: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000396 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
Caroline Tice31fbb642010-09-08 22:08:58 +0000397 (lldb) pltty /dev/tty0 \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000398 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Ingham767af882010-07-07 03:36:20 +0000399 \nIf the user always wanted to pass the same value to a particular option, the \n\
400 alias could be defined with that value directly in the alias as a constant, \n\
401 rather than using a positional placeholder: \n\
Jason Molenda4049bc32011-11-10 22:43:35 +0000402 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
Sean Callanana3aff732010-08-09 18:50:15 +0000403 // 3 of whatever file is indicated. \n");
Jim Ingham767af882010-07-07 03:36:20 +0000404
Caroline Tice43b014a2010-10-04 22:28:36 +0000405 CommandArgumentEntry arg1;
406 CommandArgumentEntry arg2;
407 CommandArgumentEntry arg3;
408 CommandArgumentData alias_arg;
409 CommandArgumentData cmd_arg;
410 CommandArgumentData options_arg;
411
412 // Define the first (and only) variant of this arg.
413 alias_arg.arg_type = eArgTypeAliasName;
414 alias_arg.arg_repetition = eArgRepeatPlain;
415
416 // There is only one variant this argument could be; put it into the argument entry.
417 arg1.push_back (alias_arg);
418
419 // Define the first (and only) variant of this arg.
420 cmd_arg.arg_type = eArgTypeCommandName;
421 cmd_arg.arg_repetition = eArgRepeatPlain;
422
423 // There is only one variant this argument could be; put it into the argument entry.
424 arg2.push_back (cmd_arg);
425
426 // Define the first (and only) variant of this arg.
427 options_arg.arg_type = eArgTypeAliasOptions;
428 options_arg.arg_repetition = eArgRepeatOptional;
429
430 // There is only one variant this argument could be; put it into the argument entry.
431 arg3.push_back (options_arg);
432
433 // Push the data for the first argument into the m_arguments vector.
434 m_arguments.push_back (arg1);
435 m_arguments.push_back (arg2);
436 m_arguments.push_back (arg3);
Jim Ingham767af882010-07-07 03:36:20 +0000437 }
438
439 ~CommandObjectCommandsAlias ()
440 {
441 }
442
Jim Inghamda26bd22012-06-08 21:56:10 +0000443protected:
444 virtual bool
445 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Caroline Ticee0da7a52010-12-09 22:52:49 +0000446 {
447 Args args (raw_command_line);
448 std::string raw_command_string (raw_command_line);
449
450 size_t argc = args.GetArgumentCount();
451
452 if (argc < 2)
453 {
454 result.AppendError ("'alias' requires at least two arguments");
455 result.SetStatus (eReturnStatusFailed);
456 return false;
457 }
458
459 // Get the alias command.
460
461 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatac2a28252011-08-16 16:49:25 +0000462
Caroline Ticee0da7a52010-12-09 22:52:49 +0000463 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
464 // does the stripping itself.
465 size_t pos = raw_command_string.find (alias_command);
466 if (pos == 0)
467 {
468 raw_command_string = raw_command_string.substr (alias_command.size());
469 pos = raw_command_string.find_first_not_of (' ');
470 if ((pos != std::string::npos) && (pos > 0))
471 raw_command_string = raw_command_string.substr (pos);
472 }
473 else
474 {
475 result.AppendError ("Error parsing command string. No alias created.");
476 result.SetStatus (eReturnStatusFailed);
477 return false;
478 }
479
480
481 // Verify that the command is alias-able.
482 if (m_interpreter.CommandExists (alias_command.c_str()))
483 {
484 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
485 alias_command.c_str());
486 result.SetStatus (eReturnStatusFailed);
487 return false;
488 }
489
490 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
491 // raw_command_string is returned with the name of the command object stripped off the front.
492 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
493
494 if (!cmd_obj)
495 {
Greg Clayton9c236732011-10-26 00:56:27 +0000496 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
Caroline Ticee0da7a52010-12-09 22:52:49 +0000497 " No alias created.", raw_command_string.c_str());
498 result.SetStatus (eReturnStatusFailed);
499 return false;
500 }
501 else if (!cmd_obj->WantsRawCommandString ())
502 {
503 // Note that args was initialized with the original command, and has not been updated to this point.
504 // 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 +0000505 return HandleAliasingNormalCommand (args, result);
Caroline Ticee0da7a52010-12-09 22:52:49 +0000506 }
507 else
508 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000509 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
510 }
511 return result.Succeeded();
512 }
513
514 bool
515 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
516 {
Caroline Ticee0da7a52010-12-09 22:52:49 +0000517 // Verify & handle any options/arguments passed to the alias command
518
519 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
520 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
521
Jim Inghamda26bd22012-06-08 21:56:10 +0000522 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
Caroline Tice5ddbe212011-05-06 21:37:15 +0000523
524 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Ticee0da7a52010-12-09 22:52:49 +0000525 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000526 result.AppendError ("Unable to create requested alias.\n");
527 result.SetStatus (eReturnStatusFailed);
528 return false;
Caroline Ticee0da7a52010-12-09 22:52:49 +0000529 }
530
531 // Create the alias
532 if (m_interpreter.AliasExists (alias_command.c_str())
533 || m_interpreter.UserCommandExists (alias_command.c_str()))
534 {
535 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
536 if (temp_option_arg_sp.get())
537 {
538 if (option_arg_vector->size() == 0)
539 m_interpreter.RemoveAliasOptions (alias_command.c_str());
540 }
541 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
542 alias_command.c_str());
543 }
544
Caroline Tice56d2fc42010-12-14 18:51:39 +0000545 if (cmd_obj_sp)
546 {
547 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
548 if (option_arg_vector->size() > 0)
549 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
550 result.SetStatus (eReturnStatusSuccessFinishNoResult);
551 }
552 else
553 {
554 result.AppendError ("Unable to create requested alias.\n");
555 result.SetStatus (eReturnStatusFailed);
556 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000557 return result.Succeeded ();
Caroline Ticee0da7a52010-12-09 22:52:49 +0000558 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000559
Jim Ingham767af882010-07-07 03:36:20 +0000560 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000561 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000562 {
Caroline Tice8bb61f02010-09-21 23:25:40 +0000563 size_t argc = args.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000564
565 if (argc < 2)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000566 {
Jim Ingham767af882010-07-07 03:36:20 +0000567 result.AppendError ("'alias' requires at least two arguments");
568 result.SetStatus (eReturnStatusFailed);
569 return false;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000570 }
Jim Ingham767af882010-07-07 03:36:20 +0000571
572 const std::string alias_command = args.GetArgumentAtIndex(0);
573 const std::string actual_command = args.GetArgumentAtIndex(1);
574
575 args.Shift(); // Shift the alias command word off the argument vector.
576 args.Shift(); // Shift the old command word off the argument vector.
577
578 // Verify that the command is alias'able, and get the appropriate command object.
579
Greg Clayton238c0a12010-09-18 01:14:36 +0000580 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000581 {
582 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
583 alias_command.c_str());
584 result.SetStatus (eReturnStatusFailed);
585 }
586 else
587 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000588 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Ingham767af882010-07-07 03:36:20 +0000589 CommandObjectSP subcommand_obj_sp;
590 bool use_subcommand = false;
591 if (command_obj_sp.get())
592 {
593 CommandObject *cmd_obj = command_obj_sp.get();
Greg Clayton54e7afa2010-07-09 20:39:50 +0000594 CommandObject *sub_cmd_obj = NULL;
Jim Ingham767af882010-07-07 03:36:20 +0000595 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
596 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
597
Caroline Ticee0da7a52010-12-09 22:52:49 +0000598 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Ingham767af882010-07-07 03:36:20 +0000599 {
600 if (argc >= 3)
601 {
602 const std::string sub_command = args.GetArgumentAtIndex(0);
603 assert (sub_command.length() != 0);
Greg Clayton13193d52012-10-13 02:07:45 +0000604 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000605 if (subcommand_obj_sp.get())
606 {
607 sub_cmd_obj = subcommand_obj_sp.get();
608 use_subcommand = true;
609 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Ticee0da7a52010-12-09 22:52:49 +0000610 cmd_obj = sub_cmd_obj;
Jim Ingham767af882010-07-07 03:36:20 +0000611 }
612 else
613 {
Caroline Tice5d53b622010-11-02 19:00:04 +0000614 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
615 "Unable to create alias.\n",
616 sub_command.c_str(), actual_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000617 result.SetStatus (eReturnStatusFailed);
618 return false;
619 }
620 }
621 }
622
623 // Verify & handle any options/arguments passed to the alias command
624
625 if (args.GetArgumentCount () > 0)
626 {
Caroline Tice5ddbe212011-05-06 21:37:15 +0000627 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
628 if (use_subcommand)
629 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
630
631 std::string args_string;
632 args.GetCommandString (args_string);
633
634 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
635 {
636 result.AppendError ("Unable to create requested alias.\n");
637 result.SetStatus (eReturnStatusFailed);
638 return false;
639 }
Jim Ingham767af882010-07-07 03:36:20 +0000640 }
641
642 // Create the alias.
643
Greg Clayton238c0a12010-09-18 01:14:36 +0000644 if (m_interpreter.AliasExists (alias_command.c_str())
645 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Ingham767af882010-07-07 03:36:20 +0000646 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000647 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Ingham767af882010-07-07 03:36:20 +0000648 if (tmp_option_arg_sp.get())
649 {
650 if (option_arg_vector->size() == 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000651 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Ingham767af882010-07-07 03:36:20 +0000652 }
653 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
654 alias_command.c_str());
655 }
656
657 if (use_subcommand)
Greg Clayton238c0a12010-09-18 01:14:36 +0000658 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000659 else
Greg Clayton238c0a12010-09-18 01:14:36 +0000660 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000661 if (option_arg_vector->size() > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +0000662 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Ingham767af882010-07-07 03:36:20 +0000663 result.SetStatus (eReturnStatusSuccessFinishNoResult);
664 }
665 else
666 {
667 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
668 result.SetStatus (eReturnStatusFailed);
Caroline Ticee6866a32010-10-28 23:17:48 +0000669 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000670 }
671 }
672
673 return result.Succeeded();
674 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000675
Jim Ingham767af882010-07-07 03:36:20 +0000676};
677
678#pragma mark CommandObjectCommandsUnalias
679//-------------------------------------------------------------------------
680// CommandObjectCommandsUnalias
681//-------------------------------------------------------------------------
682
Jim Inghamda26bd22012-06-08 21:56:10 +0000683class CommandObjectCommandsUnalias : public CommandObjectParsed
Jim Ingham767af882010-07-07 03:36:20 +0000684{
685public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000686 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000687 CommandObjectParsed (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000688 "command unalias",
Caroline Tice146292c2010-09-12 04:56:10 +0000689 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000690 NULL)
Jim Ingham767af882010-07-07 03:36:20 +0000691 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000692 CommandArgumentEntry arg;
693 CommandArgumentData alias_arg;
694
695 // Define the first (and only) variant of this arg.
696 alias_arg.arg_type = eArgTypeAliasName;
697 alias_arg.arg_repetition = eArgRepeatPlain;
698
699 // There is only one variant this argument could be; put it into the argument entry.
700 arg.push_back (alias_arg);
701
702 // Push the data for the first argument into the m_arguments vector.
703 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000704 }
705
706 ~CommandObjectCommandsUnalias()
707 {
708 }
709
Jim Inghamda26bd22012-06-08 21:56:10 +0000710protected:
Jim Ingham767af882010-07-07 03:36:20 +0000711 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000712 DoExecute (Args& args, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000713 {
714 CommandObject::CommandMap::iterator pos;
715 CommandObject *cmd_obj;
716
717 if (args.GetArgumentCount() != 0)
718 {
719 const char *command_name = args.GetArgumentAtIndex(0);
Greg Clayton238c0a12010-09-18 01:14:36 +0000720 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Ingham767af882010-07-07 03:36:20 +0000721 if (cmd_obj)
722 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000723 if (m_interpreter.CommandExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000724 {
725 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
726 command_name);
727 result.SetStatus (eReturnStatusFailed);
728 }
729 else
730 {
731
Greg Clayton238c0a12010-09-18 01:14:36 +0000732 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Ingham767af882010-07-07 03:36:20 +0000733 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000734 if (m_interpreter.AliasExists (command_name))
Jim Ingham767af882010-07-07 03:36:20 +0000735 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
736 command_name);
737 else
738 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
739 result.SetStatus (eReturnStatusFailed);
740 }
741 else
742 result.SetStatus (eReturnStatusSuccessFinishNoResult);
743 }
744 }
745 else
746 {
747 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
748 "current list of commands.\n",
749 command_name);
750 result.SetStatus (eReturnStatusFailed);
751 }
752 }
753 else
754 {
755 result.AppendError ("must call 'unalias' with a valid alias");
756 result.SetStatus (eReturnStatusFailed);
757 }
758
759 return result.Succeeded();
760 }
761};
762
Greg Claytond12aeab2011-04-20 16:37:46 +0000763//-------------------------------------------------------------------------
764// CommandObjectCommandsAddRegex
765//-------------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000766#pragma mark CommandObjectCommandsAddRegex
Greg Claytond12aeab2011-04-20 16:37:46 +0000767
Jim Inghamda26bd22012-06-08 21:56:10 +0000768class CommandObjectCommandsAddRegex : public CommandObjectParsed
Greg Claytond12aeab2011-04-20 16:37:46 +0000769{
770public:
771 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000772 CommandObjectParsed (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +0000773 "command regex",
Greg Claytond12aeab2011-04-20 16:37:46 +0000774 "Allow the user to create a regular expression command.",
Greg Clayton40e48242011-04-20 22:55:21 +0000775 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytond12aeab2011-04-20 16:37:46 +0000776 m_options (interpreter)
777 {
Greg Clayton40e48242011-04-20 22:55:21 +0000778 SetHelpLong(
779"This command allows the user to create powerful regular expression commands\n"
780"with substitutions. The regular expressions and substitutions are specified\n"
781"using the regular exression substitution format of:\n"
782"\n"
783" s/<regex>/<subst>/\n"
784"\n"
785"<regex> is a regular expression that can use parenthesis to capture regular\n"
786"expression input and substitute the captured matches in the output using %1\n"
787"for the first match, %2 for the second, and so on.\n"
788"\n"
789"The regular expressions can all be specified on the command line if more than\n"
790"one argument is provided. If just the command name is provided on the command\n"
791"line, then the regular expressions and substitutions can be entered on separate\n"
792" lines, followed by an empty line to terminate the command definition.\n"
793"\n"
794"EXAMPLES\n"
795"\n"
Sean Callanan7acd60a2012-08-16 21:46:58 +0000796"The following example will define a regular expression command named 'f' that\n"
Greg Clayton40e48242011-04-20 22:55:21 +0000797"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
798"a number follows 'f':\n"
Sean Callanan7acd60a2012-08-16 21:46:58 +0000799"\n"
800" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
801"\n"
Greg Clayton40e48242011-04-20 22:55:21 +0000802 );
Greg Claytond12aeab2011-04-20 16:37:46 +0000803 }
804
805 ~CommandObjectCommandsAddRegex()
806 {
807 }
808
809
Jim Inghamda26bd22012-06-08 21:56:10 +0000810protected:
Greg Claytond12aeab2011-04-20 16:37:46 +0000811 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000812 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytond12aeab2011-04-20 16:37:46 +0000813 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000814 const size_t argc = command.GetArgumentCount();
Greg Clayton40e48242011-04-20 22:55:21 +0000815 if (argc == 0)
Greg Claytond12aeab2011-04-20 16:37:46 +0000816 {
Jason Molenda4049bc32011-11-10 22:43:35 +0000817 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton40e48242011-04-20 22:55:21 +0000818 result.SetStatus (eReturnStatusFailed);
819 }
820 else
821 {
822 Error error;
Jim Inghamda26bd22012-06-08 21:56:10 +0000823 const char *name = command.GetArgumentAtIndex(0);
Greg Claytond12aeab2011-04-20 16:37:46 +0000824 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
825 name,
826 m_options.GetHelp (),
827 m_options.GetSyntax (),
828 10));
Greg Clayton40e48242011-04-20 22:55:21 +0000829
830 if (argc == 1)
Greg Claytond12aeab2011-04-20 16:37:46 +0000831 {
Greg Clayton40e48242011-04-20 22:55:21 +0000832 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
833 if (reader_sp)
834 {
835 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
Greg Claytond12aeab2011-04-20 16:37:46 +0000836 this, // baton
837 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton40e48242011-04-20 22:55:21 +0000838 NULL, // end token
Greg Claytond12aeab2011-04-20 16:37:46 +0000839 "> ", // prompt
Greg Clayton40e48242011-04-20 22:55:21 +0000840 true); // echo input
841 if (error.Success())
842 {
843 m_interpreter.GetDebugger().PushInputReader (reader_sp);
844 result.SetStatus (eReturnStatusSuccessFinishNoResult);
845 return true;
846 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000847 }
848 }
Greg Clayton40e48242011-04-20 22:55:21 +0000849 else
850 {
851 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
852 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000853 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton40e48242011-04-20 22:55:21 +0000854 error = AppendRegexSubstitution (arg_strref);
855 if (error.Fail())
856 break;
857 }
858
859 if (error.Success())
860 {
861 AddRegexCommandToInterpreter();
862 }
863 }
864 if (error.Fail())
865 {
866 result.AppendError (error.AsCString());
867 result.SetStatus (eReturnStatusFailed);
868 }
Greg Claytond12aeab2011-04-20 16:37:46 +0000869 }
Greg Clayton40e48242011-04-20 22:55:21 +0000870
Greg Claytond12aeab2011-04-20 16:37:46 +0000871 return result.Succeeded();
872 }
873
Greg Clayton40e48242011-04-20 22:55:21 +0000874 Error
875 AppendRegexSubstitution (const llvm::StringRef &regex_sed)
Greg Claytond12aeab2011-04-20 16:37:46 +0000876 {
Greg Clayton40e48242011-04-20 22:55:21 +0000877 Error error;
878
879 if (m_regex_cmd_ap.get() == NULL)
Greg Claytond12aeab2011-04-20 16:37:46 +0000880 {
Greg Clayton40e48242011-04-20 22:55:21 +0000881 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
882 (int)regex_sed.size(),
883 regex_sed.data());
884 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000885 }
Greg Clayton40e48242011-04-20 22:55:21 +0000886
887 size_t regex_sed_size = regex_sed.size();
888
889 if (regex_sed_size <= 1)
890 {
891 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
892 (int)regex_sed.size(),
893 regex_sed.data());
894 return error;
895 }
896
897 if (regex_sed[0] != 's')
898 {
899 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
900 (int)regex_sed.size(),
901 regex_sed.data());
902 return error;
903 }
904 const size_t first_separator_char_pos = 1;
905 // use the char that follows 's' as the regex separator character
906 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
907 const char separator_char = regex_sed[first_separator_char_pos];
908 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
909
910 if (second_separator_char_pos == std::string::npos)
911 {
912 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
913 separator_char,
914 (int)(regex_sed.size() - first_separator_char_pos - 1),
915 regex_sed.data() + (first_separator_char_pos + 1));
916 return error;
917 }
918
919 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
920
921 if (third_separator_char_pos == std::string::npos)
922 {
923 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
924 separator_char,
925 (int)(regex_sed.size() - second_separator_char_pos - 1),
926 regex_sed.data() + (second_separator_char_pos + 1));
927 return error;
928 }
929
930 if (third_separator_char_pos != regex_sed_size - 1)
931 {
932 // Make sure that everything that follows the last regex
933 // separator char
934 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
935 {
936 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
937 (int)third_separator_char_pos + 1,
938 regex_sed.data(),
939 (int)(regex_sed.size() - third_separator_char_pos - 1),
940 regex_sed.data() + (third_separator_char_pos + 1));
941 return error;
942 }
943
944 }
945 else if (first_separator_char_pos + 1 == second_separator_char_pos)
946 {
947 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
948 separator_char,
949 separator_char,
950 separator_char,
951 (int)regex_sed.size(),
952 regex_sed.data());
953 return error;
954 }
955 else if (second_separator_char_pos + 1 == third_separator_char_pos)
956 {
957 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
958 separator_char,
959 separator_char,
960 separator_char,
961 (int)regex_sed.size(),
962 regex_sed.data());
963 return error;
964 }
965 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
966 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
967 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
968 subst.c_str());
969 return error;
Greg Claytond12aeab2011-04-20 16:37:46 +0000970 }
971
972 void
Greg Clayton40e48242011-04-20 22:55:21 +0000973 AddRegexCommandToInterpreter()
Greg Claytond12aeab2011-04-20 16:37:46 +0000974 {
975 if (m_regex_cmd_ap.get())
976 {
977 if (m_regex_cmd_ap->HasRegexEntries())
978 {
979 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
980 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
981 }
982 }
983 }
984
Greg Clayton40e48242011-04-20 22:55:21 +0000985 void
986 InputReaderDidCancel()
987 {
988 m_regex_cmd_ap.reset();
989 }
990
Greg Claytond12aeab2011-04-20 16:37:46 +0000991 static size_t
992 InputReaderCallback (void *baton,
993 InputReader &reader,
994 lldb::InputReaderAction notification,
995 const char *bytes,
Jim Inghamda26bd22012-06-08 21:56:10 +0000996 size_t bytes_len)
997 {
998 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
999 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
1000
1001 switch (notification)
1002 {
1003 case eInputReaderActivate:
1004 if (!batch_mode)
1005 {
1006 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1007 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1008 out_stream->Flush();
1009 }
1010 break;
1011 case eInputReaderReactivate:
1012 break;
1013
1014 case eInputReaderDeactivate:
1015 break;
1016
1017 case eInputReaderAsynchronousOutputWritten:
1018 break;
1019
1020 case eInputReaderGotToken:
1021 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1022 --bytes_len;
1023 if (bytes_len == 0)
1024 reader.SetIsDone(true);
1025 else if (bytes)
1026 {
1027 llvm::StringRef bytes_strref (bytes, bytes_len);
1028 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1029 if (error.Fail())
1030 {
1031 if (!batch_mode)
1032 {
1033 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1034 out_stream->Printf("error: %s\n", error.AsCString());
1035 out_stream->Flush();
1036 }
1037 add_regex_cmd->InputReaderDidCancel ();
1038 reader.SetIsDone (true);
1039 }
1040 }
1041 break;
1042
1043 case eInputReaderInterrupt:
1044 {
1045 reader.SetIsDone (true);
1046 if (!batch_mode)
1047 {
1048 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1049 out_stream->PutCString("Regular expression command creations was cancelled.\n");
1050 out_stream->Flush();
1051 }
1052 add_regex_cmd->InputReaderDidCancel ();
1053 }
1054 break;
1055
1056 case eInputReaderEndOfFile:
1057 reader.SetIsDone (true);
1058 break;
1059
1060 case eInputReaderDone:
1061 add_regex_cmd->AddRegexCommandToInterpreter();
1062 break;
1063 }
1064
1065 return bytes_len;
1066 }
1067
Greg Claytond12aeab2011-04-20 16:37:46 +00001068private:
1069 std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1070
1071 class CommandOptions : public Options
1072 {
1073 public:
1074
1075 CommandOptions (CommandInterpreter &interpreter) :
1076 Options (interpreter)
1077 {
1078 }
1079
1080 virtual
1081 ~CommandOptions (){}
1082
1083 virtual Error
1084 SetOptionValue (uint32_t option_idx, const char *option_arg)
1085 {
1086 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +00001087 const int short_option = m_getopt_table[option_idx].val;
Greg Claytond12aeab2011-04-20 16:37:46 +00001088
1089 switch (short_option)
1090 {
1091 case 'h':
1092 m_help.assign (option_arg);
1093 break;
1094 case 's':
1095 m_syntax.assign (option_arg);
1096 break;
1097
1098 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001099 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytond12aeab2011-04-20 16:37:46 +00001100 break;
1101 }
1102
1103 return error;
1104 }
1105
1106 void
1107 OptionParsingStarting ()
1108 {
1109 m_help.clear();
1110 m_syntax.clear();
1111 }
1112
1113 const OptionDefinition*
1114 GetDefinitions ()
1115 {
1116 return g_option_table;
1117 }
1118
1119 // Options table: Required for subclasses of Options.
1120
1121 static OptionDefinition g_option_table[];
1122
1123 const char *
1124 GetHelp ()
1125 {
1126 if (m_help.empty())
1127 return NULL;
1128 return m_help.c_str();
1129 }
1130 const char *
1131 GetSyntax ()
1132 {
1133 if (m_syntax.empty())
1134 return NULL;
1135 return m_syntax.c_str();
1136 }
1137 // Instance variables to hold the values for command options.
1138 protected:
1139 std::string m_help;
1140 std::string m_syntax;
1141 };
Jim Inghamda26bd22012-06-08 21:56:10 +00001142
Greg Claytond12aeab2011-04-20 16:37:46 +00001143 virtual Options *
1144 GetOptions ()
1145 {
1146 return &m_options;
1147 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001148
1149 CommandOptions m_options;
Greg Claytond12aeab2011-04-20 16:37:46 +00001150};
1151
Greg Claytond12aeab2011-04-20 16:37:46 +00001152OptionDefinition
1153CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1154{
Greg Clayton40e48242011-04-20 22:55:21 +00001155{ 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 +00001156{ 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 +00001157{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytond12aeab2011-04-20 16:37:46 +00001158};
1159
1160
Jim Inghamda26bd22012-06-08 21:56:10 +00001161class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata6b1596d2011-08-16 23:24:13 +00001162{
1163private:
1164 std::string m_function_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001165 ScriptedCommandSynchronicity m_synchro;
Enrico Granata5b9f7772012-09-18 21:53:02 +00001166 bool m_fetched_help_long;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001167
1168public:
1169
1170 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1171 std::string name,
Enrico Granata6010ace2011-11-07 22:57:04 +00001172 std::string funct,
1173 ScriptedCommandSynchronicity synch) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001174 CommandObjectRaw (interpreter,
1175 name.c_str(),
1176 (std::string("Run Python function ") + funct).c_str(),
1177 NULL),
1178 m_function_name(funct),
Enrico Granata5b9f7772012-09-18 21:53:02 +00001179 m_synchro(synch),
1180 m_fetched_help_long(false)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001181 {
1182 }
1183
1184 virtual
1185 ~CommandObjectPythonFunction ()
1186 {
1187 }
1188
1189 virtual bool
Greg Claytonf737d372012-10-08 22:41:53 +00001190 IsRemovable () const
Jim Inghamda26bd22012-06-08 21:56:10 +00001191 {
1192 return true;
1193 }
1194
1195 const std::string&
1196 GetFunctionName ()
1197 {
1198 return m_function_name;
1199 }
1200
1201 ScriptedCommandSynchronicity
1202 GetSynchronicity ()
1203 {
1204 return m_synchro;
1205 }
1206
Enrico Granata5b9f7772012-09-18 21:53:02 +00001207 virtual const char *
1208 GetHelpLong ()
1209 {
1210 if (!m_fetched_help_long)
1211 {
1212 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1213 if (scripter)
1214 {
1215 std::string docstring;
1216 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1217 if (!docstring.empty())
1218 SetHelpLong(docstring);
1219 }
1220 }
1221 return CommandObjectRaw::GetHelpLong();
1222 }
1223
Jim Inghamda26bd22012-06-08 21:56:10 +00001224protected:
1225 virtual bool
1226 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001227 {
1228 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1229
1230 Error error;
1231
Jim Ingham839de392012-06-27 17:25:36 +00001232 result.SetStatus(eReturnStatusInvalid);
1233
Enrico Granata6b1596d2011-08-16 23:24:13 +00001234 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1235 raw_command_line,
Enrico Granata6010ace2011-11-07 22:57:04 +00001236 m_synchro,
Enrico Granata6b1596d2011-08-16 23:24:13 +00001237 result,
1238 error) == false)
1239 {
1240 result.AppendError(error.AsCString());
1241 result.SetStatus(eReturnStatusFailed);
1242 }
1243 else
Jim Ingham839de392012-06-27 17:25:36 +00001244 {
1245 // Don't change the status if the command already set it...
1246 if (result.GetStatus() == eReturnStatusInvalid)
1247 {
1248 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1249 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1250 else
1251 result.SetStatus(eReturnStatusSuccessFinishResult);
1252 }
1253 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001254
1255 return result.Succeeded();
1256 }
1257
Enrico Granata6b1596d2011-08-16 23:24:13 +00001258};
1259
Enrico Granata59df36f2011-10-17 21:45:27 +00001260//-------------------------------------------------------------------------
1261// CommandObjectCommandsScriptImport
1262//-------------------------------------------------------------------------
1263
Jim Inghamda26bd22012-06-08 21:56:10 +00001264class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granata59df36f2011-10-17 21:45:27 +00001265{
Jim Inghamda26bd22012-06-08 21:56:10 +00001266public:
1267 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1268 CommandObjectParsed (interpreter,
1269 "command script import",
1270 "Import a scripting module in LLDB.",
1271 NULL),
1272 m_options(interpreter)
1273 {
1274 CommandArgumentEntry arg1;
1275 CommandArgumentData cmd_arg;
1276
1277 // Define the first (and only) variant of this arg.
1278 cmd_arg.arg_type = eArgTypeFilename;
1279 cmd_arg.arg_repetition = eArgRepeatPlain;
1280
1281 // There is only one variant this argument could be; put it into the argument entry.
1282 arg1.push_back (cmd_arg);
1283
1284 // Push the data for the first argument into the m_arguments vector.
1285 m_arguments.push_back (arg1);
1286 }
1287
1288 ~CommandObjectCommandsScriptImport ()
1289 {
1290 }
1291
1292 int
1293 HandleArgumentCompletion (Args &input,
1294 int &cursor_index,
1295 int &cursor_char_position,
1296 OptionElementVector &opt_element_vector,
1297 int match_start_point,
1298 int max_return_elements,
1299 bool &word_complete,
1300 StringList &matches)
1301 {
1302 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1303 completion_str.erase (cursor_char_position);
1304
1305 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1306 CommandCompletions::eDiskFileCompletion,
1307 completion_str.c_str(),
1308 match_start_point,
1309 max_return_elements,
1310 NULL,
1311 word_complete,
1312 matches);
1313 return matches.GetSize();
1314 }
1315
1316 virtual Options *
1317 GetOptions ()
1318 {
1319 return &m_options;
1320 }
1321
1322protected:
Enrico Granata6010ace2011-11-07 22:57:04 +00001323
1324 class CommandOptions : public Options
1325 {
1326 public:
1327
1328 CommandOptions (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001329 Options (interpreter)
Enrico Granata6010ace2011-11-07 22:57:04 +00001330 {
1331 }
1332
1333 virtual
1334 ~CommandOptions (){}
1335
1336 virtual Error
1337 SetOptionValue (uint32_t option_idx, const char *option_arg)
1338 {
1339 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +00001340 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata6010ace2011-11-07 22:57:04 +00001341
1342 switch (short_option)
1343 {
1344 case 'r':
1345 m_allow_reload = true;
1346 break;
1347 default:
1348 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1349 break;
1350 }
1351
1352 return error;
1353 }
1354
1355 void
1356 OptionParsingStarting ()
1357 {
1358 m_allow_reload = false;
1359 }
1360
1361 const OptionDefinition*
1362 GetDefinitions ()
1363 {
1364 return g_option_table;
1365 }
1366
1367 // Options table: Required for subclasses of Options.
1368
1369 static OptionDefinition g_option_table[];
1370
1371 // Instance variables to hold the values for command options.
1372
1373 bool m_allow_reload;
1374 };
Enrico Granata6010ace2011-11-07 22:57:04 +00001375
Enrico Granata59df36f2011-10-17 21:45:27 +00001376 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001377 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata59df36f2011-10-17 21:45:27 +00001378 {
1379
1380 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1381 {
1382 result.AppendError ("only scripting language supported for module importing is currently Python");
1383 result.SetStatus (eReturnStatusFailed);
1384 return false;
1385 }
1386
Jim Inghamda26bd22012-06-08 21:56:10 +00001387 size_t argc = command.GetArgumentCount();
Enrico Granata59df36f2011-10-17 21:45:27 +00001388
1389 if (argc != 1)
1390 {
1391 result.AppendError ("'command script import' requires one argument");
1392 result.SetStatus (eReturnStatusFailed);
1393 return false;
1394 }
1395
Jim Inghamda26bd22012-06-08 21:56:10 +00001396 std::string path = command.GetArgumentAtIndex(0);
Enrico Granata59df36f2011-10-17 21:45:27 +00001397 Error error;
1398
Greg Clayton2e7f3132012-10-18 22:40:37 +00001399 const bool init_session = true;
Enrico Granata59df36f2011-10-17 21:45:27 +00001400 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001401 m_options.m_allow_reload,
Greg Clayton2e7f3132012-10-18 22:40:37 +00001402 init_session,
Enrico Granata59df36f2011-10-17 21:45:27 +00001403 error))
1404 {
1405 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1406 }
1407 else
1408 {
1409 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1410 result.SetStatus (eReturnStatusFailed);
1411 }
1412
1413 return result.Succeeded();
1414 }
Enrico Granata6010ace2011-11-07 22:57:04 +00001415
Jim Inghamda26bd22012-06-08 21:56:10 +00001416 CommandOptions m_options;
Enrico Granata59df36f2011-10-17 21:45:27 +00001417};
Enrico Granata6b1596d2011-08-16 23:24:13 +00001418
Enrico Granata6010ace2011-11-07 22:57:04 +00001419OptionDefinition
1420CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1421{
1422 { 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)."},
1423 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1424};
1425
1426
Enrico Granata6b1596d2011-08-16 23:24:13 +00001427//-------------------------------------------------------------------------
1428// CommandObjectCommandsScriptAdd
1429//-------------------------------------------------------------------------
1430
Jim Inghamda26bd22012-06-08 21:56:10 +00001431class CommandObjectCommandsScriptAdd : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001432{
Jim Inghamda26bd22012-06-08 21:56:10 +00001433public:
1434 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1435 CommandObjectParsed (interpreter,
1436 "command script add",
1437 "Add a scripted function as an LLDB command.",
1438 NULL),
1439 m_options (interpreter)
1440 {
1441 CommandArgumentEntry arg1;
1442 CommandArgumentData cmd_arg;
1443
1444 // Define the first (and only) variant of this arg.
1445 cmd_arg.arg_type = eArgTypeCommandName;
1446 cmd_arg.arg_repetition = eArgRepeatPlain;
1447
1448 // There is only one variant this argument could be; put it into the argument entry.
1449 arg1.push_back (cmd_arg);
1450
1451 // Push the data for the first argument into the m_arguments vector.
1452 m_arguments.push_back (arg1);
1453 }
1454
1455 ~CommandObjectCommandsScriptAdd ()
1456 {
1457 }
1458
1459 virtual Options *
1460 GetOptions ()
1461 {
1462 return &m_options;
1463 }
1464
1465protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001466
1467 class CommandOptions : public Options
1468 {
1469 public:
1470
1471 CommandOptions (CommandInterpreter &interpreter) :
1472 Options (interpreter)
1473 {
1474 }
1475
1476 virtual
1477 ~CommandOptions (){}
1478
1479 virtual Error
1480 SetOptionValue (uint32_t option_idx, const char *option_arg)
1481 {
1482 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +00001483 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001484
1485 switch (short_option)
1486 {
1487 case 'f':
1488 m_funct_name = std::string(option_arg);
1489 break;
Enrico Granata6010ace2011-11-07 22:57:04 +00001490 case 's':
1491 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1492 if (!error.Success())
1493 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1494 break;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001495 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001496 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001497 break;
1498 }
1499
1500 return error;
1501 }
1502
1503 void
1504 OptionParsingStarting ()
1505 {
1506 m_funct_name = "";
Enrico Granata6010ace2011-11-07 22:57:04 +00001507 m_synchronous = eScriptedCommandSynchronicitySynchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001508 }
1509
1510 const OptionDefinition*
1511 GetDefinitions ()
1512 {
1513 return g_option_table;
1514 }
1515
1516 // Options table: Required for subclasses of Options.
1517
1518 static OptionDefinition g_option_table[];
1519
1520 // Instance variables to hold the values for command options.
1521
1522 std::string m_funct_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001523 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001524 };
Jim Inghamda26bd22012-06-08 21:56:10 +00001525
1526private:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001527 class PythonAliasReader : public InputReaderEZ
1528 {
1529 private:
1530 CommandInterpreter& m_interpreter;
1531 std::string m_cmd_name;
Enrico Granata6010ace2011-11-07 22:57:04 +00001532 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001533 StringList m_user_input;
1534 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1535 public:
1536 PythonAliasReader(Debugger& debugger,
1537 CommandInterpreter& interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001538 std::string cmd_name,
1539 ScriptedCommandSynchronicity synch) :
Enrico Granata6b1596d2011-08-16 23:24:13 +00001540 InputReaderEZ(debugger),
1541 m_interpreter(interpreter),
1542 m_cmd_name(cmd_name),
Enrico Granata6010ace2011-11-07 22:57:04 +00001543 m_synchronous(synch),
Enrico Granata6b1596d2011-08-16 23:24:13 +00001544 m_user_input()
1545 {}
1546
1547 virtual
1548 ~PythonAliasReader()
1549 {
1550 }
1551
1552 virtual void ActivateHandler(HandlerData& data)
1553 {
1554 StreamSP out_stream = data.GetOutStream();
1555 bool batch_mode = data.GetBatchMode();
1556 if (!batch_mode)
1557 {
1558 out_stream->Printf ("%s\n", g_python_command_instructions);
1559 if (data.reader.GetPrompt())
1560 out_stream->Printf ("%s", data.reader.GetPrompt());
1561 out_stream->Flush();
1562 }
1563 }
1564
1565 virtual void ReactivateHandler(HandlerData& data)
1566 {
1567 StreamSP out_stream = data.GetOutStream();
1568 bool batch_mode = data.GetBatchMode();
1569 if (data.reader.GetPrompt() && !batch_mode)
1570 {
1571 out_stream->Printf ("%s", data.reader.GetPrompt());
1572 out_stream->Flush();
1573 }
1574 }
1575 virtual void GotTokenHandler(HandlerData& data)
1576 {
1577 StreamSP out_stream = data.GetOutStream();
1578 bool batch_mode = data.GetBatchMode();
1579 if (data.bytes && data.bytes_len)
1580 {
1581 m_user_input.AppendString(data.bytes, data.bytes_len);
1582 }
1583 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1584 {
1585 out_stream->Printf ("%s", data.reader.GetPrompt());
1586 out_stream->Flush();
1587 }
1588 }
1589 virtual void InterruptHandler(HandlerData& data)
1590 {
1591 StreamSP out_stream = data.GetOutStream();
1592 bool batch_mode = data.GetBatchMode();
1593 data.reader.SetIsDone (true);
1594 if (!batch_mode)
1595 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001596 out_stream->Printf ("Warning: No script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001597 out_stream->Flush();
1598 }
1599 }
1600 virtual void EOFHandler(HandlerData& data)
1601 {
1602 data.reader.SetIsDone (true);
1603 }
1604 virtual void DoneHandler(HandlerData& data)
1605 {
1606 StreamSP out_stream = data.GetOutStream();
1607
1608 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1609 if (!interpreter)
1610 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001611 out_stream->Printf ("Script interpreter missing: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001612 out_stream->Flush();
1613 return;
1614 }
Enrico Granata400105d2012-03-06 23:42:15 +00001615 std::string funct_name_str;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001616 if (!interpreter->GenerateScriptAliasFunction (m_user_input,
Enrico Granata400105d2012-03-06 23:42:15 +00001617 funct_name_str))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001618 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001619 out_stream->Printf ("Unable to create function: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001620 out_stream->Flush();
1621 return;
1622 }
Enrico Granata400105d2012-03-06 23:42:15 +00001623 if (funct_name_str.empty())
Enrico Granata6b1596d2011-08-16 23:24:13 +00001624 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001625 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001626 out_stream->Flush();
1627 return;
1628 }
Enrico Granata6b1596d2011-08-16 23:24:13 +00001629 // everything should be fine now, let's add this alias
1630
1631 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1632 m_cmd_name,
Enrico Granata400105d2012-03-06 23:42:15 +00001633 funct_name_str.c_str(),
Enrico Granata6010ace2011-11-07 22:57:04 +00001634 m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001635
Enrico Granata6010ace2011-11-07 22:57:04 +00001636 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001637 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001638 out_stream->Printf ("Unable to add selected command: no script attached.\n");
Enrico Granata6b1596d2011-08-16 23:24:13 +00001639 out_stream->Flush();
1640 return;
1641 }
1642 }
1643 };
1644
Jim Inghamda26bd22012-06-08 21:56:10 +00001645protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001646 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001647 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001648 {
Enrico Granatae5e34cb2011-08-17 01:30:04 +00001649
1650 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1651 {
1652 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1653 result.SetStatus (eReturnStatusFailed);
1654 return false;
1655 }
1656
Jim Inghamda26bd22012-06-08 21:56:10 +00001657 size_t argc = command.GetArgumentCount();
Enrico Granata6b1596d2011-08-16 23:24:13 +00001658
1659 if (argc != 1)
1660 {
1661 result.AppendError ("'command script add' requires one argument");
1662 result.SetStatus (eReturnStatusFailed);
1663 return false;
1664 }
1665
Jim Inghamda26bd22012-06-08 21:56:10 +00001666 std::string cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001667
1668 if (m_options.m_funct_name.empty())
1669 {
1670 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1671 m_interpreter,
Enrico Granata6010ace2011-11-07 22:57:04 +00001672 cmd_name,
1673 m_options.m_synchronous));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001674
1675 if (reader_sp)
1676 {
1677
1678 InputReaderEZ::InitializationParameters ipr;
1679
1680 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
1681 if (err.Success())
1682 {
1683 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1684 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1685 }
1686 else
1687 {
1688 result.AppendError (err.AsCString());
1689 result.SetStatus (eReturnStatusFailed);
1690 }
1691 }
1692 else
1693 {
1694 result.AppendError("out of memory");
1695 result.SetStatus (eReturnStatusFailed);
1696 }
1697 }
1698 else
1699 {
Enrico Granata6010ace2011-11-07 22:57:04 +00001700 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1701 cmd_name,
1702 m_options.m_funct_name,
1703 m_options.m_synchronous));
1704 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
Enrico Granata6b1596d2011-08-16 23:24:13 +00001705 {
1706 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1707 }
1708 else
1709 {
1710 result.AppendError("cannot add command");
1711 result.SetStatus (eReturnStatusFailed);
1712 }
1713 }
1714
1715 return result.Succeeded();
1716
1717 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001718
1719 CommandOptions m_options;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001720};
1721
Enrico Granata6010ace2011-11-07 22:57:04 +00001722static OptionEnumValueElement g_script_synchro_type[] =
1723{
1724 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1725 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1726 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1727 { 0, NULL, NULL }
1728};
1729
Enrico Granata6b1596d2011-08-16 23:24:13 +00001730OptionDefinition
1731CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1732{
Enrico Granata91544802011-09-06 19:20:51 +00001733 { 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 +00001734 { 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 +00001735 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1736};
1737
1738//-------------------------------------------------------------------------
1739// CommandObjectCommandsScriptList
1740//-------------------------------------------------------------------------
1741
Jim Inghamda26bd22012-06-08 21:56:10 +00001742class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001743{
1744private:
Enrico Granata6010ace2011-11-07 22:57:04 +00001745
Enrico Granata6b1596d2011-08-16 23:24:13 +00001746public:
1747 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001748 CommandObjectParsed (interpreter,
Enrico Granata6b1596d2011-08-16 23:24:13 +00001749 "command script list",
1750 "List defined scripted commands.",
1751 NULL)
1752 {
1753 }
1754
1755 ~CommandObjectCommandsScriptList ()
1756 {
1757 }
1758
1759 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001760 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001761 {
1762
1763 m_interpreter.GetHelp(result,
1764 CommandInterpreter::eCommandTypesUserDef);
1765
1766 result.SetStatus (eReturnStatusSuccessFinishResult);
1767
1768 return true;
1769
1770
1771 }
1772};
1773
1774//-------------------------------------------------------------------------
1775// CommandObjectCommandsScriptClear
1776//-------------------------------------------------------------------------
1777
Jim Inghamda26bd22012-06-08 21:56:10 +00001778class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001779{
1780private:
1781
1782public:
1783 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001784 CommandObjectParsed (interpreter,
1785 "command script clear",
1786 "Delete all scripted commands.",
1787 NULL)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001788 {
1789 }
1790
1791 ~CommandObjectCommandsScriptClear ()
1792 {
1793 }
1794
Jim Inghamda26bd22012-06-08 21:56:10 +00001795protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001796 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001797 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001798 {
1799
1800 m_interpreter.RemoveAllUser();
1801
1802 result.SetStatus (eReturnStatusSuccessFinishResult);
1803
1804 return true;
Enrico Granata6b1596d2011-08-16 23:24:13 +00001805 }
1806};
1807
1808//-------------------------------------------------------------------------
1809// CommandObjectCommandsScriptDelete
1810//-------------------------------------------------------------------------
1811
Jim Inghamda26bd22012-06-08 21:56:10 +00001812class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata6b1596d2011-08-16 23:24:13 +00001813{
Enrico Granata6b1596d2011-08-16 23:24:13 +00001814public:
1815 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001816 CommandObjectParsed (interpreter,
1817 "command script delete",
1818 "Delete a scripted command.",
1819 NULL)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001820 {
1821 CommandArgumentEntry arg1;
1822 CommandArgumentData cmd_arg;
1823
1824 // Define the first (and only) variant of this arg.
1825 cmd_arg.arg_type = eArgTypeCommandName;
1826 cmd_arg.arg_repetition = eArgRepeatPlain;
1827
1828 // There is only one variant this argument could be; put it into the argument entry.
1829 arg1.push_back (cmd_arg);
1830
1831 // Push the data for the first argument into the m_arguments vector.
1832 m_arguments.push_back (arg1);
1833 }
1834
1835 ~CommandObjectCommandsScriptDelete ()
1836 {
1837 }
1838
Jim Inghamda26bd22012-06-08 21:56:10 +00001839protected:
Enrico Granata6b1596d2011-08-16 23:24:13 +00001840 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001841 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata6b1596d2011-08-16 23:24:13 +00001842 {
1843
Jim Inghamda26bd22012-06-08 21:56:10 +00001844 size_t argc = command.GetArgumentCount();
Enrico Granata6b1596d2011-08-16 23:24:13 +00001845
1846 if (argc != 1)
1847 {
1848 result.AppendError ("'command script delete' requires one argument");
1849 result.SetStatus (eReturnStatusFailed);
1850 return false;
1851 }
1852
Jim Inghamda26bd22012-06-08 21:56:10 +00001853 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata6b1596d2011-08-16 23:24:13 +00001854
1855 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1856 {
1857 m_interpreter.RemoveUser(cmd_name);
1858 result.SetStatus (eReturnStatusSuccessFinishResult);
1859 }
1860 else
1861 {
1862 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1863 result.SetStatus (eReturnStatusFailed);
1864 }
1865
1866 return result.Succeeded();
1867
1868 }
1869};
1870
1871#pragma mark CommandObjectMultiwordCommandsScript
1872
1873//-------------------------------------------------------------------------
1874// CommandObjectMultiwordCommandsScript
1875//-------------------------------------------------------------------------
1876
1877class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1878{
1879public:
1880 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1881 CommandObjectMultiword (interpreter,
1882 "command script",
1883 "A set of commands for managing or customizing script commands.",
1884 "command script <subcommand> [<subcommand-options>]")
1885 {
1886 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1887 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1888 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1889 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Enrico Granata59df36f2011-10-17 21:45:27 +00001890 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001891 }
1892
1893 ~CommandObjectMultiwordCommandsScript ()
1894 {
1895 }
1896
1897};
1898
1899
Jim Ingham767af882010-07-07 03:36:20 +00001900#pragma mark CommandObjectMultiwordCommands
1901
1902//-------------------------------------------------------------------------
1903// CommandObjectMultiwordCommands
1904//-------------------------------------------------------------------------
1905
1906CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001907 CommandObjectMultiword (interpreter,
Greg Clayton40e48242011-04-20 22:55:21 +00001908 "command",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001909 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton40e48242011-04-20 22:55:21 +00001910 "command <subcommand> [<subcommand-options>]")
Jim Ingham767af882010-07-07 03:36:20 +00001911{
Greg Clayton238c0a12010-09-18 01:14:36 +00001912 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1913 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1914 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytond12aeab2011-04-20 16:37:46 +00001915 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Ingham6247dbe2011-07-12 03:12:18 +00001916 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Enrico Granata6b1596d2011-08-16 23:24:13 +00001917 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Ingham767af882010-07-07 03:36:20 +00001918}
1919
1920CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1921{
1922}
1923