blob: 737a449dbc3f57bff8a6feba91da47c40c8e8ee4 [file] [log] [blame]
Jim Inghamebc09c32010-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 Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Jim Inghamebc09c32010-07-07 03:36:20 +000012#include "CommandObjectCommands.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
Greg Clayton0e5e5a72011-04-20 22:55:21 +000017#include "llvm/ADT/StringRef.h"
18
Jim Inghamebc09c32010-07-07 03:36:20 +000019// Project includes
Jim Inghamebc09c32010-07-07 03:36:20 +000020#include "lldb/Core/Debugger.h"
Greg Claytonde164aa2011-04-20 16:37:46 +000021#include "lldb/Core/InputReader.h"
Enrico Granatabe93a352011-08-16 16:49:25 +000022#include "lldb/Core/InputReaderEZ.h"
23#include "lldb/Core/StringList.h"
Greg Claytonde164aa2011-04-20 16:37:46 +000024#include "lldb/Interpreter/Args.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000025#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytonde164aa2011-04-20 16:37:46 +000026#include "lldb/Interpreter/CommandObjectRegexCommand.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000027#include "lldb/Interpreter/CommandReturnObject.h"
Enrico Granata012d4fc2013-06-11 01:26:35 +000028#include "lldb/Interpreter/OptionValueBoolean.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000029#include "lldb/Interpreter/Options.h"
Enrico Granata99f0b8f2011-08-17 01:30:04 +000030#include "lldb/Interpreter/ScriptInterpreter.h"
31#include "lldb/Interpreter/ScriptInterpreterPython.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000032
33using namespace lldb;
34using namespace lldb_private;
35
Jim Inghamebc09c32010-07-07 03:36:20 +000036//-------------------------------------------------------------------------
37// CommandObjectCommandsSource
38//-------------------------------------------------------------------------
39
Jim Ingham5a988412012-06-08 21:56:10 +000040class CommandObjectCommandsHistory : public CommandObjectParsed
Jim Inghama5a97eb2011-07-12 03:12:18 +000041{
Jim Ingham5a988412012-06-08 21:56:10 +000042public:
43 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
44 CommandObjectParsed (interpreter,
45 "command history",
46 "Dump the history of commands in this session.",
47 NULL),
48 m_options (interpreter)
49 {
50 }
51
52 ~CommandObjectCommandsHistory () {}
53
54 virtual Options *
55 GetOptions ()
56 {
57 return &m_options;
58 }
59
60protected:
Jim Inghama5a97eb2011-07-12 03:12:18 +000061
62 class CommandOptions : public Options
63 {
64 public:
65
66 CommandOptions (CommandInterpreter &interpreter) :
67 Options (interpreter)
68 {
69 }
70
71 virtual
72 ~CommandOptions (){}
73
74 virtual Error
75 SetOptionValue (uint32_t option_idx, const char *option_arg)
76 {
77 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000078 const int short_option = m_getopt_table[option_idx].val;
Jim Inghama5a97eb2011-07-12 03:12:18 +000079 bool success;
80
81 switch (short_option)
82 {
83 case 'c':
84 m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
85 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000086 error.SetErrorStringWithFormat("invalid value for count: %s", option_arg);
Jim Inghama5a97eb2011-07-12 03:12:18 +000087 if (m_end_idx != 0)
88 m_end_idx--;
89 m_start_idx = 0;
90 break;
91 case 'e':
92 m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
93 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000094 error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg);
Jim Inghama5a97eb2011-07-12 03:12:18 +000095 break;
96 case 's':
97 m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
98 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +000099 error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg);
Jim Inghama5a97eb2011-07-12 03:12:18 +0000100 break;
101 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000102 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghama5a97eb2011-07-12 03:12:18 +0000103 break;
104 }
105
106 return error;
107 }
108
109 void
110 OptionParsingStarting ()
111 {
112 m_start_idx = 0;
113 m_end_idx = UINT_MAX;
114 }
115
116 const OptionDefinition*
117 GetDefinitions ()
118 {
119 return g_option_table;
120 }
121
122 // Options table: Required for subclasses of Options.
123
124 static OptionDefinition g_option_table[];
125
126 // Instance variables to hold the values for command options.
127
128 uint32_t m_start_idx;
129 uint32_t m_end_idx;
130 };
131
Jim Inghama5a97eb2011-07-12 03:12:18 +0000132 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000133 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghama5a97eb2011-07-12 03:12:18 +0000134 {
135
136 m_interpreter.DumpHistory (result.GetOutputStream(),
137 m_options.m_start_idx,
138 m_options.m_end_idx);
139 return result.Succeeded();
140
141 }
Jim Ingham5a988412012-06-08 21:56:10 +0000142
143 CommandOptions m_options;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000144};
145
146OptionDefinition
147CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
148{
149{ LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
150{ LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands."},
151{ LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
152{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
153};
154
155
156//-------------------------------------------------------------------------
157// CommandObjectCommandsSource
158//-------------------------------------------------------------------------
159
Jim Ingham5a988412012-06-08 21:56:10 +0000160class CommandObjectCommandsSource : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000161{
Jim Ingham5a988412012-06-08 21:56:10 +0000162public:
163 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
164 CommandObjectParsed (interpreter,
165 "command source",
166 "Read in debugger commands from the file <filename> and execute them.",
167 NULL),
168 m_options (interpreter)
169 {
170 CommandArgumentEntry arg;
171 CommandArgumentData file_arg;
172
173 // Define the first (and only) variant of this arg.
174 file_arg.arg_type = eArgTypeFilename;
175 file_arg.arg_repetition = eArgRepeatPlain;
176
177 // There is only one variant this argument could be; put it into the argument entry.
178 arg.push_back (file_arg);
179
180 // Push the data for the first argument into the m_arguments vector.
181 m_arguments.push_back (arg);
182 }
183
184 ~CommandObjectCommandsSource () {}
185
186 virtual const char*
187 GetRepeatCommand (Args &current_command_args, uint32_t index)
188 {
189 return "";
190 }
191
Greg Claytonc7bece562013-01-25 18:06:21 +0000192 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +0000193 HandleArgumentCompletion (Args &input,
194 int &cursor_index,
195 int &cursor_char_position,
196 OptionElementVector &opt_element_vector,
197 int match_start_point,
198 int max_return_elements,
199 bool &word_complete,
200 StringList &matches)
201 {
202 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
203 completion_str.erase (cursor_char_position);
204
205 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
206 CommandCompletions::eDiskFileCompletion,
207 completion_str.c_str(),
208 match_start_point,
209 max_return_elements,
210 NULL,
211 word_complete,
212 matches);
213 return matches.GetSize();
214 }
215
216 virtual Options *
217 GetOptions ()
218 {
219 return &m_options;
220 }
221
222protected:
Jim Inghame16c50a2011-02-18 00:54:25 +0000223
224 class CommandOptions : public Options
225 {
226 public:
227
Greg Claytoneb0103f2011-04-07 22:46:35 +0000228 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata012d4fc2013-06-11 01:26:35 +0000229 Options (interpreter),
230 m_stop_on_error (true)
Greg Claytoneb0103f2011-04-07 22:46:35 +0000231 {
232 }
Jim Inghame16c50a2011-02-18 00:54:25 +0000233
234 virtual
235 ~CommandOptions (){}
236
237 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000238 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame16c50a2011-02-18 00:54:25 +0000239 {
240 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000241 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame16c50a2011-02-18 00:54:25 +0000242 bool success;
243
244 switch (short_option)
245 {
246 case 'e':
Enrico Granata012d4fc2013-06-11 01:26:35 +0000247 m_stop_on_error.SetCurrentValue(Args::StringToBoolean(option_arg, true, &success));
Jim Inghame16c50a2011-02-18 00:54:25 +0000248 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000249 error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000250 break;
251 case 'c':
252 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
253 if (!success)
Greg Clayton86edbf42011-10-26 00:56:27 +0000254 error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000255 break;
256 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000257 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghame16c50a2011-02-18 00:54:25 +0000258 break;
259 }
260
261 return error;
262 }
263
264 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000265 OptionParsingStarting ()
Jim Inghame16c50a2011-02-18 00:54:25 +0000266 {
Enrico Granata012d4fc2013-06-11 01:26:35 +0000267 m_stop_on_error.Clear();
Jim Inghame16c50a2011-02-18 00:54:25 +0000268 m_stop_on_continue = true;
269 }
270
Greg Claytone0d378b2011-03-24 21:19:54 +0000271 const OptionDefinition*
Jim Inghame16c50a2011-02-18 00:54:25 +0000272 GetDefinitions ()
273 {
274 return g_option_table;
275 }
276
277 // Options table: Required for subclasses of Options.
278
Greg Claytone0d378b2011-03-24 21:19:54 +0000279 static OptionDefinition g_option_table[];
Jim Inghame16c50a2011-02-18 00:54:25 +0000280
281 // Instance variables to hold the values for command options.
282
Enrico Granata012d4fc2013-06-11 01:26:35 +0000283 OptionValueBoolean m_stop_on_error;
Jim Inghame16c50a2011-02-18 00:54:25 +0000284 bool m_stop_on_continue;
285 };
286
Jim Inghamebc09c32010-07-07 03:36:20 +0000287 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000288 DoExecute(Args& command, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000289 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000290 const size_t argc = command.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000291 if (argc == 1)
292 {
Jim Ingham5a988412012-06-08 21:56:10 +0000293 const char *filename = command.GetArgumentAtIndex(0);
Jim Inghamebc09c32010-07-07 03:36:20 +0000294
295 result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
296
Johnny Chen1ee38532010-10-20 21:40:50 +0000297 FileSpec cmd_file (filename, true);
Jim Inghame16c50a2011-02-18 00:54:25 +0000298 ExecutionContext *exe_ctx = NULL; // Just use the default context.
299 bool echo_commands = true;
300 bool print_results = true;
Enrico Granata012d4fc2013-06-11 01:26:35 +0000301 bool stop_on_error = m_options.m_stop_on_error.OptionWasSet() ? (bool)m_options.m_stop_on_error : m_interpreter.GetStopCmdSourceOnError();
Jim Inghamebc09c32010-07-07 03:36:20 +0000302
Enrico Granata012d4fc2013-06-11 01:26:35 +0000303 m_interpreter.HandleCommandsFromFile (cmd_file,
Jim Inghame16c50a2011-02-18 00:54:25 +0000304 exe_ctx,
305 m_options.m_stop_on_continue,
Enrico Granata012d4fc2013-06-11 01:26:35 +0000306 stop_on_error,
Jim Inghame16c50a2011-02-18 00:54:25 +0000307 echo_commands,
Enrico Granata5f5ab602012-05-31 01:09:06 +0000308 print_results,
309 eLazyBoolCalculate,
Jim Inghame16c50a2011-02-18 00:54:25 +0000310 result);
Jim Inghamebc09c32010-07-07 03:36:20 +0000311 }
312 else
313 {
314 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
315 result.SetStatus (eReturnStatusFailed);
316 }
317 return result.Succeeded();
318
319 }
Jim Ingham5a988412012-06-08 21:56:10 +0000320 CommandOptions m_options;
Jim Inghamebc09c32010-07-07 03:36:20 +0000321};
322
Greg Claytone0d378b2011-03-24 21:19:54 +0000323OptionDefinition
Jim Inghame16c50a2011-02-18 00:54:25 +0000324CommandObjectCommandsSource::CommandOptions::g_option_table[] =
325{
326{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
327{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
328{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
329};
330
Jim Inghamebc09c32010-07-07 03:36:20 +0000331#pragma mark CommandObjectCommandsAlias
332//-------------------------------------------------------------------------
333// CommandObjectCommandsAlias
334//-------------------------------------------------------------------------
335
Enrico Granatabe93a352011-08-16 16:49:25 +0000336static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
337 "You must define a Python function with this signature:\n"
Enrico Granata40d55712012-08-08 02:06:30 +0000338 "def my_command_impl(debugger, args, result, internal_dict):";
Enrico Granatabe93a352011-08-16 16:49:25 +0000339
340
Jim Ingham5a988412012-06-08 21:56:10 +0000341class CommandObjectCommandsAlias : public CommandObjectRaw
Jim Inghamebc09c32010-07-07 03:36:20 +0000342{
Enrico Granatabe93a352011-08-16 16:49:25 +0000343
Enrico Granatabe93a352011-08-16 16:49:25 +0000344
Jim Inghamebc09c32010-07-07 03:36:20 +0000345public:
Greg Claytona7015092010-09-18 01:14:36 +0000346 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000347 CommandObjectRaw (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000348 "command alias",
Caroline Ticee3d26312010-09-08 21:06:11 +0000349 "Allow users to define their own debugger command abbreviations.",
Caroline Tice405fe672010-10-04 22:28:36 +0000350 NULL)
Jim Inghamebc09c32010-07-07 03:36:20 +0000351 {
352 SetHelpLong(
353 "'alias' allows the user to create a short-cut or abbreviation for long \n\
354 commands, multi-word commands, and commands that take particular options. \n\
355 Below are some simple examples of how one might use the 'alias' command: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000356 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000357 // command. \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000358 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000359 // command. Since breakpoint commands are two-word \n\
360 // commands, the user will still need to enter the \n\
361 // second word after 'bp', e.g. 'bp enable' or \n\
362 // 'bp delete'. \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000363 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000364 // two-word command 'breakpoint list'. \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000365 \nAn alias can include some options for the command, with the values either \n\
366 filled in at the time the alias is created, or specified as positional \n\
367 arguments, to be filled in when the alias is invoked. The following example \n\
368 shows how to create aliases with options: \n\
369 \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000370 'command alias bfl breakpoint set -f %1 -l %2' \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000371 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
372 options already part of the alias. So if the user wants to set a breakpoint \n\
373 by file and line without explicitly having to use the -f and -l options, the \n\
374 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
375 for the actual arguments that will be passed when the alias command is used. \n\
376 The number in the placeholder refers to the position/order the actual value \n\
Jim Ingham81ded932011-08-18 02:29:05 +0000377 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000378 will be replaced with the first argument, all the occurrences of '%2' in the \n\
379 alias will be replaced with the second argument, and so on. This also allows \n\
380 actual arguments to be used multiple times within an alias (see 'process \n\
Jim Ingham81ded932011-08-18 02:29:05 +0000381 launch' example below). \n\
382 Note: the positional arguments must substitute as whole words in the resultant\n\
383 command, so you can't at present do something like:\n\
384 \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000385 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
Jim Ingham81ded932011-08-18 02:29:05 +0000386 \n\
387 to get the file extension \".cpp\" automatically appended. For more complex\n\
388 aliasing, use the \"command regex\" command instead.\n\
389 \nSo in the 'bfl' case, the actual file value will be \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000390 filled in with the first argument following 'bfl' and the actual line number \n\
391 value will be filled in with the second argument. The user would use this \n\
392 alias as follows: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000393 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000394 <... some time later ...> \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000395 (lldb) bfl my-file.c 137 \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000396 \nThis would be the same as if the user had entered \n\
397 'breakpoint set -f my-file.c -l 137'. \n\
398 \nAnother example: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000399 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000400 (lldb) pltty /dev/tty0 \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000401 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000402 \nIf the user always wanted to pass the same value to a particular option, the \n\
403 alias could be defined with that value directly in the alias as a constant, \n\
404 rather than using a positional placeholder: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000405 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000406 // 3 of whatever file is indicated. \n");
Jim Inghamebc09c32010-07-07 03:36:20 +0000407
Caroline Tice405fe672010-10-04 22:28:36 +0000408 CommandArgumentEntry arg1;
409 CommandArgumentEntry arg2;
410 CommandArgumentEntry arg3;
411 CommandArgumentData alias_arg;
412 CommandArgumentData cmd_arg;
413 CommandArgumentData options_arg;
414
415 // Define the first (and only) variant of this arg.
416 alias_arg.arg_type = eArgTypeAliasName;
417 alias_arg.arg_repetition = eArgRepeatPlain;
418
419 // There is only one variant this argument could be; put it into the argument entry.
420 arg1.push_back (alias_arg);
421
422 // Define the first (and only) variant of this arg.
423 cmd_arg.arg_type = eArgTypeCommandName;
424 cmd_arg.arg_repetition = eArgRepeatPlain;
425
426 // There is only one variant this argument could be; put it into the argument entry.
427 arg2.push_back (cmd_arg);
428
429 // Define the first (and only) variant of this arg.
430 options_arg.arg_type = eArgTypeAliasOptions;
431 options_arg.arg_repetition = eArgRepeatOptional;
432
433 // There is only one variant this argument could be; put it into the argument entry.
434 arg3.push_back (options_arg);
435
436 // Push the data for the first argument into the m_arguments vector.
437 m_arguments.push_back (arg1);
438 m_arguments.push_back (arg2);
439 m_arguments.push_back (arg3);
Jim Inghamebc09c32010-07-07 03:36:20 +0000440 }
441
442 ~CommandObjectCommandsAlias ()
443 {
444 }
445
Jim Ingham5a988412012-06-08 21:56:10 +0000446protected:
447 virtual bool
448 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Caroline Tice844d2302010-12-09 22:52:49 +0000449 {
450 Args args (raw_command_line);
451 std::string raw_command_string (raw_command_line);
452
453 size_t argc = args.GetArgumentCount();
454
455 if (argc < 2)
456 {
457 result.AppendError ("'alias' requires at least two arguments");
458 result.SetStatus (eReturnStatusFailed);
459 return false;
460 }
461
462 // Get the alias command.
463
464 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatabe93a352011-08-16 16:49:25 +0000465
Caroline Tice844d2302010-12-09 22:52:49 +0000466 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
467 // does the stripping itself.
468 size_t pos = raw_command_string.find (alias_command);
469 if (pos == 0)
470 {
471 raw_command_string = raw_command_string.substr (alias_command.size());
472 pos = raw_command_string.find_first_not_of (' ');
473 if ((pos != std::string::npos) && (pos > 0))
474 raw_command_string = raw_command_string.substr (pos);
475 }
476 else
477 {
478 result.AppendError ("Error parsing command string. No alias created.");
479 result.SetStatus (eReturnStatusFailed);
480 return false;
481 }
482
483
484 // Verify that the command is alias-able.
485 if (m_interpreter.CommandExists (alias_command.c_str()))
486 {
487 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
488 alias_command.c_str());
489 result.SetStatus (eReturnStatusFailed);
490 return false;
491 }
492
493 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
494 // raw_command_string is returned with the name of the command object stripped off the front.
495 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
496
497 if (!cmd_obj)
498 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000499 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
Caroline Tice844d2302010-12-09 22:52:49 +0000500 " No alias created.", raw_command_string.c_str());
501 result.SetStatus (eReturnStatusFailed);
502 return false;
503 }
504 else if (!cmd_obj->WantsRawCommandString ())
505 {
506 // Note that args was initialized with the original command, and has not been updated to this point.
507 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
Jim Ingham5a988412012-06-08 21:56:10 +0000508 return HandleAliasingNormalCommand (args, result);
Caroline Tice844d2302010-12-09 22:52:49 +0000509 }
510 else
511 {
Jim Ingham5a988412012-06-08 21:56:10 +0000512 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
513 }
514 return result.Succeeded();
515 }
516
517 bool
518 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
519 {
Caroline Tice844d2302010-12-09 22:52:49 +0000520 // Verify & handle any options/arguments passed to the alias command
521
522 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
523 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
524
Jim Ingham5a988412012-06-08 21:56:10 +0000525 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
Caroline Ticeca90c472011-05-06 21:37:15 +0000526
527 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Tice844d2302010-12-09 22:52:49 +0000528 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000529 result.AppendError ("Unable to create requested alias.\n");
530 result.SetStatus (eReturnStatusFailed);
531 return false;
Caroline Tice844d2302010-12-09 22:52:49 +0000532 }
533
534 // Create the alias
535 if (m_interpreter.AliasExists (alias_command.c_str())
536 || m_interpreter.UserCommandExists (alias_command.c_str()))
537 {
538 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
539 if (temp_option_arg_sp.get())
540 {
541 if (option_arg_vector->size() == 0)
542 m_interpreter.RemoveAliasOptions (alias_command.c_str());
543 }
544 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
545 alias_command.c_str());
546 }
547
Caroline Tice472362e2010-12-14 18:51:39 +0000548 if (cmd_obj_sp)
549 {
550 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
551 if (option_arg_vector->size() > 0)
552 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
553 result.SetStatus (eReturnStatusSuccessFinishNoResult);
554 }
555 else
556 {
557 result.AppendError ("Unable to create requested alias.\n");
558 result.SetStatus (eReturnStatusFailed);
559 }
Jim Ingham5a988412012-06-08 21:56:10 +0000560 return result.Succeeded ();
Caroline Tice844d2302010-12-09 22:52:49 +0000561 }
Jim Ingham5a988412012-06-08 21:56:10 +0000562
Jim Inghamebc09c32010-07-07 03:36:20 +0000563 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000564 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000565 {
Caroline Tice867b185d2010-09-21 23:25:40 +0000566 size_t argc = args.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000567
568 if (argc < 2)
Greg Claytonc982c762010-07-09 20:39:50 +0000569 {
Jim Inghamebc09c32010-07-07 03:36:20 +0000570 result.AppendError ("'alias' requires at least two arguments");
571 result.SetStatus (eReturnStatusFailed);
572 return false;
Greg Claytonc982c762010-07-09 20:39:50 +0000573 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000574
575 const std::string alias_command = args.GetArgumentAtIndex(0);
576 const std::string actual_command = args.GetArgumentAtIndex(1);
577
578 args.Shift(); // Shift the alias command word off the argument vector.
579 args.Shift(); // Shift the old command word off the argument vector.
580
581 // Verify that the command is alias'able, and get the appropriate command object.
582
Greg Claytona7015092010-09-18 01:14:36 +0000583 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000584 {
585 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
586 alias_command.c_str());
587 result.SetStatus (eReturnStatusFailed);
588 }
589 else
590 {
Greg Claytona7015092010-09-18 01:14:36 +0000591 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Inghamebc09c32010-07-07 03:36:20 +0000592 CommandObjectSP subcommand_obj_sp;
593 bool use_subcommand = false;
594 if (command_obj_sp.get())
595 {
596 CommandObject *cmd_obj = command_obj_sp.get();
Greg Claytonc982c762010-07-09 20:39:50 +0000597 CommandObject *sub_cmd_obj = NULL;
Jim Inghamebc09c32010-07-07 03:36:20 +0000598 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
599 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
600
Caroline Tice844d2302010-12-09 22:52:49 +0000601 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Inghamebc09c32010-07-07 03:36:20 +0000602 {
603 if (argc >= 3)
604 {
605 const std::string sub_command = args.GetArgumentAtIndex(0);
606 assert (sub_command.length() != 0);
Greg Clayton998255b2012-10-13 02:07:45 +0000607 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000608 if (subcommand_obj_sp.get())
609 {
610 sub_cmd_obj = subcommand_obj_sp.get();
611 use_subcommand = true;
612 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Tice844d2302010-12-09 22:52:49 +0000613 cmd_obj = sub_cmd_obj;
Jim Inghamebc09c32010-07-07 03:36:20 +0000614 }
615 else
616 {
Caroline Ticef415eeb2010-11-02 19:00:04 +0000617 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
618 "Unable to create alias.\n",
619 sub_command.c_str(), actual_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000620 result.SetStatus (eReturnStatusFailed);
621 return false;
622 }
623 }
624 }
625
626 // Verify & handle any options/arguments passed to the alias command
627
628 if (args.GetArgumentCount () > 0)
629 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000630 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
631 if (use_subcommand)
632 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
633
634 std::string args_string;
635 args.GetCommandString (args_string);
636
637 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
638 {
639 result.AppendError ("Unable to create requested alias.\n");
640 result.SetStatus (eReturnStatusFailed);
641 return false;
642 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000643 }
644
645 // Create the alias.
646
Greg Claytona7015092010-09-18 01:14:36 +0000647 if (m_interpreter.AliasExists (alias_command.c_str())
648 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000649 {
Greg Claytona7015092010-09-18 01:14:36 +0000650 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Inghamebc09c32010-07-07 03:36:20 +0000651 if (tmp_option_arg_sp.get())
652 {
653 if (option_arg_vector->size() == 0)
Greg Claytona7015092010-09-18 01:14:36 +0000654 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000655 }
656 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
657 alias_command.c_str());
658 }
659
660 if (use_subcommand)
Greg Claytona7015092010-09-18 01:14:36 +0000661 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000662 else
Greg Claytona7015092010-09-18 01:14:36 +0000663 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000664 if (option_arg_vector->size() > 0)
Greg Claytona7015092010-09-18 01:14:36 +0000665 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000666 result.SetStatus (eReturnStatusSuccessFinishNoResult);
667 }
668 else
669 {
670 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
671 result.SetStatus (eReturnStatusFailed);
Caroline Ticee7941792010-10-28 23:17:48 +0000672 return false;
Jim Inghamebc09c32010-07-07 03:36:20 +0000673 }
674 }
675
676 return result.Succeeded();
677 }
Jim Ingham5a988412012-06-08 21:56:10 +0000678
Jim Inghamebc09c32010-07-07 03:36:20 +0000679};
680
681#pragma mark CommandObjectCommandsUnalias
682//-------------------------------------------------------------------------
683// CommandObjectCommandsUnalias
684//-------------------------------------------------------------------------
685
Jim Ingham5a988412012-06-08 21:56:10 +0000686class CommandObjectCommandsUnalias : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000687{
688public:
Greg Claytona7015092010-09-18 01:14:36 +0000689 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000690 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000691 "command unalias",
Caroline Tice86ddae52010-09-12 04:56:10 +0000692 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice405fe672010-10-04 22:28:36 +0000693 NULL)
Jim Inghamebc09c32010-07-07 03:36:20 +0000694 {
Caroline Tice405fe672010-10-04 22:28:36 +0000695 CommandArgumentEntry arg;
696 CommandArgumentData alias_arg;
697
698 // Define the first (and only) variant of this arg.
699 alias_arg.arg_type = eArgTypeAliasName;
700 alias_arg.arg_repetition = eArgRepeatPlain;
701
702 // There is only one variant this argument could be; put it into the argument entry.
703 arg.push_back (alias_arg);
704
705 // Push the data for the first argument into the m_arguments vector.
706 m_arguments.push_back (arg);
Jim Inghamebc09c32010-07-07 03:36:20 +0000707 }
708
709 ~CommandObjectCommandsUnalias()
710 {
711 }
712
Jim Ingham5a988412012-06-08 21:56:10 +0000713protected:
Jim Inghamebc09c32010-07-07 03:36:20 +0000714 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000715 DoExecute (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000716 {
717 CommandObject::CommandMap::iterator pos;
718 CommandObject *cmd_obj;
719
720 if (args.GetArgumentCount() != 0)
721 {
722 const char *command_name = args.GetArgumentAtIndex(0);
Greg Claytona7015092010-09-18 01:14:36 +0000723 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Inghamebc09c32010-07-07 03:36:20 +0000724 if (cmd_obj)
725 {
Greg Claytona7015092010-09-18 01:14:36 +0000726 if (m_interpreter.CommandExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000727 {
728 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
729 command_name);
730 result.SetStatus (eReturnStatusFailed);
731 }
732 else
733 {
734
Greg Claytona7015092010-09-18 01:14:36 +0000735 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Inghamebc09c32010-07-07 03:36:20 +0000736 {
Greg Claytona7015092010-09-18 01:14:36 +0000737 if (m_interpreter.AliasExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000738 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
739 command_name);
740 else
741 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
742 result.SetStatus (eReturnStatusFailed);
743 }
744 else
745 result.SetStatus (eReturnStatusSuccessFinishNoResult);
746 }
747 }
748 else
749 {
750 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
751 "current list of commands.\n",
752 command_name);
753 result.SetStatus (eReturnStatusFailed);
754 }
755 }
756 else
757 {
758 result.AppendError ("must call 'unalias' with a valid alias");
759 result.SetStatus (eReturnStatusFailed);
760 }
761
762 return result.Succeeded();
763 }
764};
765
Greg Claytonde164aa2011-04-20 16:37:46 +0000766//-------------------------------------------------------------------------
767// CommandObjectCommandsAddRegex
768//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000769#pragma mark CommandObjectCommandsAddRegex
Greg Claytonde164aa2011-04-20 16:37:46 +0000770
Jim Ingham5a988412012-06-08 21:56:10 +0000771class CommandObjectCommandsAddRegex : public CommandObjectParsed
Greg Claytonde164aa2011-04-20 16:37:46 +0000772{
773public:
774 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000775 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000776 "command regex",
Greg Claytonde164aa2011-04-20 16:37:46 +0000777 "Allow the user to create a regular expression command.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000778 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Claytonde164aa2011-04-20 16:37:46 +0000779 m_options (interpreter)
780 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000781 SetHelpLong(
782"This command allows the user to create powerful regular expression commands\n"
783"with substitutions. The regular expressions and substitutions are specified\n"
784"using the regular exression substitution format of:\n"
785"\n"
786" s/<regex>/<subst>/\n"
787"\n"
788"<regex> is a regular expression that can use parenthesis to capture regular\n"
789"expression input and substitute the captured matches in the output using %1\n"
790"for the first match, %2 for the second, and so on.\n"
791"\n"
792"The regular expressions can all be specified on the command line if more than\n"
793"one argument is provided. If just the command name is provided on the command\n"
794"line, then the regular expressions and substitutions can be entered on separate\n"
795" lines, followed by an empty line to terminate the command definition.\n"
796"\n"
797"EXAMPLES\n"
798"\n"
Sean Callananadc43c92012-08-16 21:46:58 +0000799"The following example will define a regular expression command named 'f' that\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000800"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
801"a number follows 'f':\n"
Sean Callananadc43c92012-08-16 21:46:58 +0000802"\n"
803" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
804"\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000805 );
Greg Claytonde164aa2011-04-20 16:37:46 +0000806 }
807
808 ~CommandObjectCommandsAddRegex()
809 {
810 }
811
812
Jim Ingham5a988412012-06-08 21:56:10 +0000813protected:
Greg Claytonde164aa2011-04-20 16:37:46 +0000814 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000815 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytonde164aa2011-04-20 16:37:46 +0000816 {
Jim Ingham5a988412012-06-08 21:56:10 +0000817 const size_t argc = command.GetArgumentCount();
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000818 if (argc == 0)
Greg Claytonde164aa2011-04-20 16:37:46 +0000819 {
Jason Molenda69c12cc2011-11-10 22:43:35 +0000820 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000821 result.SetStatus (eReturnStatusFailed);
822 }
823 else
824 {
825 Error error;
Jim Ingham5a988412012-06-08 21:56:10 +0000826 const char *name = command.GetArgumentAtIndex(0);
Greg Claytonde164aa2011-04-20 16:37:46 +0000827 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
828 name,
829 m_options.GetHelp (),
830 m_options.GetSyntax (),
831 10));
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000832
833 if (argc == 1)
Greg Claytonde164aa2011-04-20 16:37:46 +0000834 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000835 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
836 if (reader_sp)
837 {
838 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
Greg Claytonde164aa2011-04-20 16:37:46 +0000839 this, // baton
840 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000841 NULL, // end token
Greg Claytonde164aa2011-04-20 16:37:46 +0000842 "> ", // prompt
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000843 true); // echo input
844 if (error.Success())
845 {
846 m_interpreter.GetDebugger().PushInputReader (reader_sp);
847 result.SetStatus (eReturnStatusSuccessFinishNoResult);
848 return true;
849 }
Greg Claytonde164aa2011-04-20 16:37:46 +0000850 }
851 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000852 else
853 {
854 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
855 {
Jim Ingham5a988412012-06-08 21:56:10 +0000856 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000857 error = AppendRegexSubstitution (arg_strref);
858 if (error.Fail())
859 break;
860 }
861
862 if (error.Success())
863 {
864 AddRegexCommandToInterpreter();
865 }
866 }
867 if (error.Fail())
868 {
869 result.AppendError (error.AsCString());
870 result.SetStatus (eReturnStatusFailed);
871 }
Greg Claytonde164aa2011-04-20 16:37:46 +0000872 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000873
Greg Claytonde164aa2011-04-20 16:37:46 +0000874 return result.Succeeded();
875 }
876
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000877 Error
878 AppendRegexSubstitution (const llvm::StringRef &regex_sed)
Greg Claytonde164aa2011-04-20 16:37:46 +0000879 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000880 Error error;
881
882 if (m_regex_cmd_ap.get() == NULL)
Greg Claytonde164aa2011-04-20 16:37:46 +0000883 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000884 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
885 (int)regex_sed.size(),
886 regex_sed.data());
887 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +0000888 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000889
890 size_t regex_sed_size = regex_sed.size();
891
892 if (regex_sed_size <= 1)
893 {
894 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
895 (int)regex_sed.size(),
896 regex_sed.data());
897 return error;
898 }
899
900 if (regex_sed[0] != 's')
901 {
902 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
903 (int)regex_sed.size(),
904 regex_sed.data());
905 return error;
906 }
907 const size_t first_separator_char_pos = 1;
908 // use the char that follows 's' as the regex separator character
909 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
910 const char separator_char = regex_sed[first_separator_char_pos];
911 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
912
913 if (second_separator_char_pos == std::string::npos)
914 {
915 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
916 separator_char,
917 (int)(regex_sed.size() - first_separator_char_pos - 1),
918 regex_sed.data() + (first_separator_char_pos + 1));
919 return error;
920 }
921
922 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
923
924 if (third_separator_char_pos == std::string::npos)
925 {
926 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
927 separator_char,
928 (int)(regex_sed.size() - second_separator_char_pos - 1),
929 regex_sed.data() + (second_separator_char_pos + 1));
930 return error;
931 }
932
933 if (third_separator_char_pos != regex_sed_size - 1)
934 {
935 // Make sure that everything that follows the last regex
936 // separator char
937 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
938 {
939 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
940 (int)third_separator_char_pos + 1,
941 regex_sed.data(),
942 (int)(regex_sed.size() - third_separator_char_pos - 1),
943 regex_sed.data() + (third_separator_char_pos + 1));
944 return error;
945 }
946
947 }
948 else if (first_separator_char_pos + 1 == second_separator_char_pos)
949 {
950 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
951 separator_char,
952 separator_char,
953 separator_char,
954 (int)regex_sed.size(),
955 regex_sed.data());
956 return error;
957 }
958 else if (second_separator_char_pos + 1 == third_separator_char_pos)
959 {
960 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
961 separator_char,
962 separator_char,
963 separator_char,
964 (int)regex_sed.size(),
965 regex_sed.data());
966 return error;
967 }
968 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
969 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
970 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
971 subst.c_str());
972 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +0000973 }
974
975 void
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000976 AddRegexCommandToInterpreter()
Greg Claytonde164aa2011-04-20 16:37:46 +0000977 {
978 if (m_regex_cmd_ap.get())
979 {
980 if (m_regex_cmd_ap->HasRegexEntries())
981 {
982 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
983 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
984 }
985 }
986 }
987
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000988 void
989 InputReaderDidCancel()
990 {
991 m_regex_cmd_ap.reset();
992 }
993
Greg Claytonde164aa2011-04-20 16:37:46 +0000994 static size_t
995 InputReaderCallback (void *baton,
996 InputReader &reader,
997 lldb::InputReaderAction notification,
998 const char *bytes,
Jim Ingham5a988412012-06-08 21:56:10 +0000999 size_t bytes_len)
1000 {
1001 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
1002 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
1003
1004 switch (notification)
1005 {
1006 case eInputReaderActivate:
1007 if (!batch_mode)
1008 {
1009 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1010 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1011 out_stream->Flush();
1012 }
1013 break;
1014 case eInputReaderReactivate:
1015 break;
1016
1017 case eInputReaderDeactivate:
1018 break;
1019
1020 case eInputReaderAsynchronousOutputWritten:
1021 break;
1022
1023 case eInputReaderGotToken:
1024 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1025 --bytes_len;
1026 if (bytes_len == 0)
1027 reader.SetIsDone(true);
1028 else if (bytes)
1029 {
1030 llvm::StringRef bytes_strref (bytes, bytes_len);
1031 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1032 if (error.Fail())
1033 {
1034 if (!batch_mode)
1035 {
1036 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1037 out_stream->Printf("error: %s\n", error.AsCString());
1038 out_stream->Flush();
1039 }
1040 add_regex_cmd->InputReaderDidCancel ();
1041 reader.SetIsDone (true);
1042 }
1043 }
1044 break;
1045
1046 case eInputReaderInterrupt:
1047 {
1048 reader.SetIsDone (true);
1049 if (!batch_mode)
1050 {
1051 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1052 out_stream->PutCString("Regular expression command creations was cancelled.\n");
1053 out_stream->Flush();
1054 }
1055 add_regex_cmd->InputReaderDidCancel ();
1056 }
1057 break;
1058
1059 case eInputReaderEndOfFile:
1060 reader.SetIsDone (true);
1061 break;
1062
1063 case eInputReaderDone:
1064 add_regex_cmd->AddRegexCommandToInterpreter();
1065 break;
1066 }
1067
1068 return bytes_len;
1069 }
1070
Greg Claytonde164aa2011-04-20 16:37:46 +00001071private:
Greg Clayton7b0992d2013-04-18 22:45:39 +00001072 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
Greg Claytonde164aa2011-04-20 16:37:46 +00001073
1074 class CommandOptions : public Options
1075 {
1076 public:
1077
1078 CommandOptions (CommandInterpreter &interpreter) :
1079 Options (interpreter)
1080 {
1081 }
1082
1083 virtual
1084 ~CommandOptions (){}
1085
1086 virtual Error
1087 SetOptionValue (uint32_t option_idx, const char *option_arg)
1088 {
1089 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001090 const int short_option = m_getopt_table[option_idx].val;
Greg Claytonde164aa2011-04-20 16:37:46 +00001091
1092 switch (short_option)
1093 {
1094 case 'h':
1095 m_help.assign (option_arg);
1096 break;
1097 case 's':
1098 m_syntax.assign (option_arg);
1099 break;
1100
1101 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001102 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytonde164aa2011-04-20 16:37:46 +00001103 break;
1104 }
1105
1106 return error;
1107 }
1108
1109 void
1110 OptionParsingStarting ()
1111 {
1112 m_help.clear();
1113 m_syntax.clear();
1114 }
1115
1116 const OptionDefinition*
1117 GetDefinitions ()
1118 {
1119 return g_option_table;
1120 }
1121
1122 // Options table: Required for subclasses of Options.
1123
1124 static OptionDefinition g_option_table[];
1125
1126 const char *
1127 GetHelp ()
1128 {
1129 if (m_help.empty())
1130 return NULL;
1131 return m_help.c_str();
1132 }
1133 const char *
1134 GetSyntax ()
1135 {
1136 if (m_syntax.empty())
1137 return NULL;
1138 return m_syntax.c_str();
1139 }
1140 // Instance variables to hold the values for command options.
1141 protected:
1142 std::string m_help;
1143 std::string m_syntax;
1144 };
Jim Ingham5a988412012-06-08 21:56:10 +00001145
Greg Claytonde164aa2011-04-20 16:37:46 +00001146 virtual Options *
1147 GetOptions ()
1148 {
1149 return &m_options;
1150 }
Jim Ingham5a988412012-06-08 21:56:10 +00001151
1152 CommandOptions m_options;
Greg Claytonde164aa2011-04-20 16:37:46 +00001153};
1154
Greg Claytonde164aa2011-04-20 16:37:46 +00001155OptionDefinition
1156CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1157{
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001158{ LLDB_OPT_SET_1, false, "help" , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
Greg Claytonde164aa2011-04-20 16:37:46 +00001159{ LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001160{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytonde164aa2011-04-20 16:37:46 +00001161};
1162
1163
Jim Ingham5a988412012-06-08 21:56:10 +00001164class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata223383e2011-08-16 23:24:13 +00001165{
1166private:
1167 std::string m_function_name;
Enrico Granata0a305db2011-11-07 22:57:04 +00001168 ScriptedCommandSynchronicity m_synchro;
Enrico Granatafac939e2012-09-18 21:53:02 +00001169 bool m_fetched_help_long;
Enrico Granata223383e2011-08-16 23:24:13 +00001170
1171public:
1172
1173 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1174 std::string name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001175 std::string funct,
1176 ScriptedCommandSynchronicity synch) :
Jim Ingham5a988412012-06-08 21:56:10 +00001177 CommandObjectRaw (interpreter,
1178 name.c_str(),
1179 (std::string("Run Python function ") + funct).c_str(),
1180 NULL),
1181 m_function_name(funct),
Enrico Granatafac939e2012-09-18 21:53:02 +00001182 m_synchro(synch),
1183 m_fetched_help_long(false)
Enrico Granata223383e2011-08-16 23:24:13 +00001184 {
1185 }
1186
1187 virtual
1188 ~CommandObjectPythonFunction ()
1189 {
1190 }
1191
1192 virtual bool
Greg Clayton3a18e312012-10-08 22:41:53 +00001193 IsRemovable () const
Jim Ingham5a988412012-06-08 21:56:10 +00001194 {
1195 return true;
1196 }
1197
1198 const std::string&
1199 GetFunctionName ()
1200 {
1201 return m_function_name;
1202 }
1203
1204 ScriptedCommandSynchronicity
1205 GetSynchronicity ()
1206 {
1207 return m_synchro;
1208 }
1209
Enrico Granatafac939e2012-09-18 21:53:02 +00001210 virtual const char *
1211 GetHelpLong ()
1212 {
1213 if (!m_fetched_help_long)
1214 {
1215 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1216 if (scripter)
1217 {
1218 std::string docstring;
1219 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1220 if (!docstring.empty())
1221 SetHelpLong(docstring);
1222 }
1223 }
1224 return CommandObjectRaw::GetHelpLong();
1225 }
1226
Jim Ingham5a988412012-06-08 21:56:10 +00001227protected:
1228 virtual bool
1229 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001230 {
1231 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1232
1233 Error error;
1234
Jim Ingham70f11f82012-06-27 17:25:36 +00001235 result.SetStatus(eReturnStatusInvalid);
1236
Enrico Granata223383e2011-08-16 23:24:13 +00001237 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1238 raw_command_line,
Enrico Granata0a305db2011-11-07 22:57:04 +00001239 m_synchro,
Enrico Granata223383e2011-08-16 23:24:13 +00001240 result,
1241 error) == false)
1242 {
1243 result.AppendError(error.AsCString());
1244 result.SetStatus(eReturnStatusFailed);
1245 }
1246 else
Jim Ingham70f11f82012-06-27 17:25:36 +00001247 {
1248 // Don't change the status if the command already set it...
1249 if (result.GetStatus() == eReturnStatusInvalid)
1250 {
1251 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1252 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1253 else
1254 result.SetStatus(eReturnStatusSuccessFinishResult);
1255 }
1256 }
Enrico Granata223383e2011-08-16 23:24:13 +00001257
1258 return result.Succeeded();
1259 }
1260
Enrico Granata223383e2011-08-16 23:24:13 +00001261};
1262
Enrico Granataa9dbf432011-10-17 21:45:27 +00001263//-------------------------------------------------------------------------
1264// CommandObjectCommandsScriptImport
1265//-------------------------------------------------------------------------
1266
Jim Ingham5a988412012-06-08 21:56:10 +00001267class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granataa9dbf432011-10-17 21:45:27 +00001268{
Jim Ingham5a988412012-06-08 21:56:10 +00001269public:
1270 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1271 CommandObjectParsed (interpreter,
1272 "command script import",
1273 "Import a scripting module in LLDB.",
1274 NULL),
1275 m_options(interpreter)
1276 {
1277 CommandArgumentEntry arg1;
1278 CommandArgumentData cmd_arg;
1279
1280 // Define the first (and only) variant of this arg.
1281 cmd_arg.arg_type = eArgTypeFilename;
1282 cmd_arg.arg_repetition = eArgRepeatPlain;
1283
1284 // There is only one variant this argument could be; put it into the argument entry.
1285 arg1.push_back (cmd_arg);
1286
1287 // Push the data for the first argument into the m_arguments vector.
1288 m_arguments.push_back (arg1);
1289 }
1290
1291 ~CommandObjectCommandsScriptImport ()
1292 {
1293 }
1294
Greg Claytonc7bece562013-01-25 18:06:21 +00001295 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +00001296 HandleArgumentCompletion (Args &input,
1297 int &cursor_index,
1298 int &cursor_char_position,
1299 OptionElementVector &opt_element_vector,
1300 int match_start_point,
1301 int max_return_elements,
1302 bool &word_complete,
1303 StringList &matches)
1304 {
1305 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1306 completion_str.erase (cursor_char_position);
1307
1308 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1309 CommandCompletions::eDiskFileCompletion,
1310 completion_str.c_str(),
1311 match_start_point,
1312 max_return_elements,
1313 NULL,
1314 word_complete,
1315 matches);
1316 return matches.GetSize();
1317 }
1318
1319 virtual Options *
1320 GetOptions ()
1321 {
1322 return &m_options;
1323 }
1324
1325protected:
Enrico Granata0a305db2011-11-07 22:57:04 +00001326
1327 class CommandOptions : public Options
1328 {
1329 public:
1330
1331 CommandOptions (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001332 Options (interpreter)
Enrico Granata0a305db2011-11-07 22:57:04 +00001333 {
1334 }
1335
1336 virtual
1337 ~CommandOptions (){}
1338
1339 virtual Error
1340 SetOptionValue (uint32_t option_idx, const char *option_arg)
1341 {
1342 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001343 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata0a305db2011-11-07 22:57:04 +00001344
1345 switch (short_option)
1346 {
1347 case 'r':
1348 m_allow_reload = true;
1349 break;
1350 default:
1351 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1352 break;
1353 }
1354
1355 return error;
1356 }
1357
1358 void
1359 OptionParsingStarting ()
1360 {
Enrico Granatae0c70f12013-05-31 01:03:09 +00001361 m_allow_reload = true;
Enrico Granata0a305db2011-11-07 22:57:04 +00001362 }
1363
1364 const OptionDefinition*
1365 GetDefinitions ()
1366 {
1367 return g_option_table;
1368 }
1369
1370 // Options table: Required for subclasses of Options.
1371
1372 static OptionDefinition g_option_table[];
1373
1374 // Instance variables to hold the values for command options.
1375
1376 bool m_allow_reload;
1377 };
Enrico Granata0a305db2011-11-07 22:57:04 +00001378
Enrico Granataa9dbf432011-10-17 21:45:27 +00001379 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001380 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001381 {
1382
1383 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1384 {
1385 result.AppendError ("only scripting language supported for module importing is currently Python");
1386 result.SetStatus (eReturnStatusFailed);
1387 return false;
1388 }
1389
Jim Ingham5a988412012-06-08 21:56:10 +00001390 size_t argc = command.GetArgumentCount();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001391
1392 if (argc != 1)
1393 {
1394 result.AppendError ("'command script import' requires one argument");
1395 result.SetStatus (eReturnStatusFailed);
1396 return false;
1397 }
1398
Jim Ingham5a988412012-06-08 21:56:10 +00001399 std::string path = command.GetArgumentAtIndex(0);
Enrico Granataa9dbf432011-10-17 21:45:27 +00001400 Error error;
1401
Greg Claytonc9d645d2012-10-18 22:40:37 +00001402 const bool init_session = true;
Enrico Granata078551c2013-05-09 19:33:49 +00001403 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1404 // commands won't ever be recursively invoked, but it's actually possible to craft
1405 // a Python script that does other "command script imports" in __lldb_init_module
1406 // the real fix is to have recursive commands possible with a CommandInvocation object
1407 // separate from the CommandObject itself, so that recursive command invocations
1408 // won't stomp on each other (wrt to execution contents, options, and more)
1409 m_exe_ctx.Clear();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001410 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata0a305db2011-11-07 22:57:04 +00001411 m_options.m_allow_reload,
Greg Claytonc9d645d2012-10-18 22:40:37 +00001412 init_session,
Enrico Granataa9dbf432011-10-17 21:45:27 +00001413 error))
1414 {
1415 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1416 }
1417 else
1418 {
1419 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1420 result.SetStatus (eReturnStatusFailed);
1421 }
1422
1423 return result.Succeeded();
1424 }
Enrico Granata0a305db2011-11-07 22:57:04 +00001425
Jim Ingham5a988412012-06-08 21:56:10 +00001426 CommandOptions m_options;
Enrico Granataa9dbf432011-10-17 21:45:27 +00001427};
Enrico Granata223383e2011-08-16 23:24:13 +00001428
Enrico Granata0a305db2011-11-07 22:57:04 +00001429OptionDefinition
1430CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1431{
Enrico Granatae0c70f12013-05-31 01:03:09 +00001432 { 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. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."},
Enrico Granata0a305db2011-11-07 22:57:04 +00001433 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1434};
1435
1436
Enrico Granata223383e2011-08-16 23:24:13 +00001437//-------------------------------------------------------------------------
1438// CommandObjectCommandsScriptAdd
1439//-------------------------------------------------------------------------
1440
Jim Ingham5a988412012-06-08 21:56:10 +00001441class CommandObjectCommandsScriptAdd : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001442{
Jim Ingham5a988412012-06-08 21:56:10 +00001443public:
1444 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1445 CommandObjectParsed (interpreter,
1446 "command script add",
1447 "Add a scripted function as an LLDB command.",
1448 NULL),
1449 m_options (interpreter)
1450 {
1451 CommandArgumentEntry arg1;
1452 CommandArgumentData cmd_arg;
1453
1454 // Define the first (and only) variant of this arg.
1455 cmd_arg.arg_type = eArgTypeCommandName;
1456 cmd_arg.arg_repetition = eArgRepeatPlain;
1457
1458 // There is only one variant this argument could be; put it into the argument entry.
1459 arg1.push_back (cmd_arg);
1460
1461 // Push the data for the first argument into the m_arguments vector.
1462 m_arguments.push_back (arg1);
1463 }
1464
1465 ~CommandObjectCommandsScriptAdd ()
1466 {
1467 }
1468
1469 virtual Options *
1470 GetOptions ()
1471 {
1472 return &m_options;
1473 }
1474
1475protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001476
1477 class CommandOptions : public Options
1478 {
1479 public:
1480
1481 CommandOptions (CommandInterpreter &interpreter) :
1482 Options (interpreter)
1483 {
1484 }
1485
1486 virtual
1487 ~CommandOptions (){}
1488
1489 virtual Error
1490 SetOptionValue (uint32_t option_idx, const char *option_arg)
1491 {
1492 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001493 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata223383e2011-08-16 23:24:13 +00001494
1495 switch (short_option)
1496 {
1497 case 'f':
1498 m_funct_name = std::string(option_arg);
1499 break;
Enrico Granata0a305db2011-11-07 22:57:04 +00001500 case 's':
1501 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1502 if (!error.Success())
1503 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1504 break;
Enrico Granata223383e2011-08-16 23:24:13 +00001505 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001506 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata223383e2011-08-16 23:24:13 +00001507 break;
1508 }
1509
1510 return error;
1511 }
1512
1513 void
1514 OptionParsingStarting ()
1515 {
1516 m_funct_name = "";
Enrico Granata0a305db2011-11-07 22:57:04 +00001517 m_synchronous = eScriptedCommandSynchronicitySynchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001518 }
1519
1520 const OptionDefinition*
1521 GetDefinitions ()
1522 {
1523 return g_option_table;
1524 }
1525
1526 // Options table: Required for subclasses of Options.
1527
1528 static OptionDefinition g_option_table[];
1529
1530 // Instance variables to hold the values for command options.
1531
1532 std::string m_funct_name;
Enrico Granata0a305db2011-11-07 22:57:04 +00001533 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001534 };
Jim Ingham5a988412012-06-08 21:56:10 +00001535
1536private:
Enrico Granata223383e2011-08-16 23:24:13 +00001537 class PythonAliasReader : public InputReaderEZ
1538 {
1539 private:
1540 CommandInterpreter& m_interpreter;
1541 std::string m_cmd_name;
Enrico Granata0a305db2011-11-07 22:57:04 +00001542 ScriptedCommandSynchronicity m_synchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001543 StringList m_user_input;
1544 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1545 public:
1546 PythonAliasReader(Debugger& debugger,
1547 CommandInterpreter& interpreter,
Enrico Granata0a305db2011-11-07 22:57:04 +00001548 std::string cmd_name,
1549 ScriptedCommandSynchronicity synch) :
Enrico Granata223383e2011-08-16 23:24:13 +00001550 InputReaderEZ(debugger),
1551 m_interpreter(interpreter),
1552 m_cmd_name(cmd_name),
Enrico Granata0a305db2011-11-07 22:57:04 +00001553 m_synchronous(synch),
Enrico Granata223383e2011-08-16 23:24:13 +00001554 m_user_input()
1555 {}
1556
1557 virtual
1558 ~PythonAliasReader()
1559 {
1560 }
1561
1562 virtual void ActivateHandler(HandlerData& data)
1563 {
1564 StreamSP out_stream = data.GetOutStream();
1565 bool batch_mode = data.GetBatchMode();
1566 if (!batch_mode)
1567 {
1568 out_stream->Printf ("%s\n", g_python_command_instructions);
1569 if (data.reader.GetPrompt())
1570 out_stream->Printf ("%s", data.reader.GetPrompt());
1571 out_stream->Flush();
1572 }
1573 }
1574
1575 virtual void ReactivateHandler(HandlerData& data)
1576 {
1577 StreamSP out_stream = data.GetOutStream();
1578 bool batch_mode = data.GetBatchMode();
1579 if (data.reader.GetPrompt() && !batch_mode)
1580 {
1581 out_stream->Printf ("%s", data.reader.GetPrompt());
1582 out_stream->Flush();
1583 }
1584 }
1585 virtual void GotTokenHandler(HandlerData& data)
1586 {
1587 StreamSP out_stream = data.GetOutStream();
1588 bool batch_mode = data.GetBatchMode();
1589 if (data.bytes && data.bytes_len)
1590 {
1591 m_user_input.AppendString(data.bytes, data.bytes_len);
1592 }
1593 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1594 {
1595 out_stream->Printf ("%s", data.reader.GetPrompt());
1596 out_stream->Flush();
1597 }
1598 }
1599 virtual void InterruptHandler(HandlerData& data)
1600 {
1601 StreamSP out_stream = data.GetOutStream();
1602 bool batch_mode = data.GetBatchMode();
1603 data.reader.SetIsDone (true);
1604 if (!batch_mode)
1605 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001606 out_stream->Printf ("Warning: No script attached.\n");
Enrico Granata223383e2011-08-16 23:24:13 +00001607 out_stream->Flush();
1608 }
1609 }
1610 virtual void EOFHandler(HandlerData& data)
1611 {
1612 data.reader.SetIsDone (true);
1613 }
1614 virtual void DoneHandler(HandlerData& data)
1615 {
1616 StreamSP out_stream = data.GetOutStream();
1617
1618 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1619 if (!interpreter)
1620 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001621 out_stream->Printf ("Script interpreter missing: no script attached.\n");
Enrico Granata223383e2011-08-16 23:24:13 +00001622 out_stream->Flush();
1623 return;
1624 }
Enrico Granataa73b7df2012-03-06 23:42:15 +00001625 std::string funct_name_str;
Enrico Granata223383e2011-08-16 23:24:13 +00001626 if (!interpreter->GenerateScriptAliasFunction (m_user_input,
Enrico Granataa73b7df2012-03-06 23:42:15 +00001627 funct_name_str))
Enrico Granata223383e2011-08-16 23:24:13 +00001628 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001629 out_stream->Printf ("Unable to create function: no script attached.\n");
Enrico Granata223383e2011-08-16 23:24:13 +00001630 out_stream->Flush();
1631 return;
1632 }
Enrico Granataa73b7df2012-03-06 23:42:15 +00001633 if (funct_name_str.empty())
Enrico Granata223383e2011-08-16 23:24:13 +00001634 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001635 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
Enrico Granata223383e2011-08-16 23:24:13 +00001636 out_stream->Flush();
1637 return;
1638 }
Enrico Granata223383e2011-08-16 23:24:13 +00001639 // everything should be fine now, let's add this alias
1640
1641 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1642 m_cmd_name,
Enrico Granataa73b7df2012-03-06 23:42:15 +00001643 funct_name_str.c_str(),
Enrico Granata0a305db2011-11-07 22:57:04 +00001644 m_synchronous));
Enrico Granata223383e2011-08-16 23:24:13 +00001645
Enrico Granata0a305db2011-11-07 22:57:04 +00001646 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
Enrico Granata223383e2011-08-16 23:24:13 +00001647 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001648 out_stream->Printf ("Unable to add selected command: no script attached.\n");
Enrico Granata223383e2011-08-16 23:24:13 +00001649 out_stream->Flush();
1650 return;
1651 }
1652 }
1653 };
1654
Jim Ingham5a988412012-06-08 21:56:10 +00001655protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001656 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001657 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001658 {
Enrico Granata99f0b8f2011-08-17 01:30:04 +00001659
1660 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1661 {
1662 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1663 result.SetStatus (eReturnStatusFailed);
1664 return false;
1665 }
1666
Jim Ingham5a988412012-06-08 21:56:10 +00001667 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001668
1669 if (argc != 1)
1670 {
1671 result.AppendError ("'command script add' requires one argument");
1672 result.SetStatus (eReturnStatusFailed);
1673 return false;
1674 }
1675
Jim Ingham5a988412012-06-08 21:56:10 +00001676 std::string cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00001677
1678 if (m_options.m_funct_name.empty())
1679 {
1680 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1681 m_interpreter,
Enrico Granata0a305db2011-11-07 22:57:04 +00001682 cmd_name,
1683 m_options.m_synchronous));
Enrico Granata223383e2011-08-16 23:24:13 +00001684
1685 if (reader_sp)
1686 {
1687
1688 InputReaderEZ::InitializationParameters ipr;
1689
1690 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
1691 if (err.Success())
1692 {
1693 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1694 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1695 }
1696 else
1697 {
1698 result.AppendError (err.AsCString());
1699 result.SetStatus (eReturnStatusFailed);
1700 }
1701 }
1702 else
1703 {
1704 result.AppendError("out of memory");
1705 result.SetStatus (eReturnStatusFailed);
1706 }
1707 }
1708 else
1709 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001710 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1711 cmd_name,
1712 m_options.m_funct_name,
1713 m_options.m_synchronous));
1714 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
Enrico Granata223383e2011-08-16 23:24:13 +00001715 {
1716 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1717 }
1718 else
1719 {
1720 result.AppendError("cannot add command");
1721 result.SetStatus (eReturnStatusFailed);
1722 }
1723 }
1724
1725 return result.Succeeded();
1726
1727 }
Jim Ingham5a988412012-06-08 21:56:10 +00001728
1729 CommandOptions m_options;
Enrico Granata223383e2011-08-16 23:24:13 +00001730};
1731
Enrico Granata0a305db2011-11-07 22:57:04 +00001732static OptionEnumValueElement g_script_synchro_type[] =
1733{
1734 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1735 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1736 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1737 { 0, NULL, NULL }
1738};
1739
Enrico Granata223383e2011-08-16 23:24:13 +00001740OptionDefinition
1741CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1742{
Enrico Granata9128ee22011-09-06 19:20:51 +00001743 { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
Enrico Granata0a305db2011-11-07 22:57:04 +00001744 { 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 Granata223383e2011-08-16 23:24:13 +00001745 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1746};
1747
1748//-------------------------------------------------------------------------
1749// CommandObjectCommandsScriptList
1750//-------------------------------------------------------------------------
1751
Jim Ingham5a988412012-06-08 21:56:10 +00001752class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001753{
1754private:
Enrico Granata0a305db2011-11-07 22:57:04 +00001755
Enrico Granata223383e2011-08-16 23:24:13 +00001756public:
1757 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001758 CommandObjectParsed (interpreter,
Enrico Granata223383e2011-08-16 23:24:13 +00001759 "command script list",
1760 "List defined scripted commands.",
1761 NULL)
1762 {
1763 }
1764
1765 ~CommandObjectCommandsScriptList ()
1766 {
1767 }
1768
1769 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001770 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001771 {
1772
1773 m_interpreter.GetHelp(result,
1774 CommandInterpreter::eCommandTypesUserDef);
1775
1776 result.SetStatus (eReturnStatusSuccessFinishResult);
1777
1778 return true;
1779
1780
1781 }
1782};
1783
1784//-------------------------------------------------------------------------
1785// CommandObjectCommandsScriptClear
1786//-------------------------------------------------------------------------
1787
Jim Ingham5a988412012-06-08 21:56:10 +00001788class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001789{
1790private:
1791
1792public:
1793 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001794 CommandObjectParsed (interpreter,
1795 "command script clear",
1796 "Delete all scripted commands.",
1797 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00001798 {
1799 }
1800
1801 ~CommandObjectCommandsScriptClear ()
1802 {
1803 }
1804
Jim Ingham5a988412012-06-08 21:56:10 +00001805protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001806 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001807 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001808 {
1809
1810 m_interpreter.RemoveAllUser();
1811
1812 result.SetStatus (eReturnStatusSuccessFinishResult);
1813
1814 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00001815 }
1816};
1817
1818//-------------------------------------------------------------------------
1819// CommandObjectCommandsScriptDelete
1820//-------------------------------------------------------------------------
1821
Jim Ingham5a988412012-06-08 21:56:10 +00001822class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001823{
Enrico Granata223383e2011-08-16 23:24:13 +00001824public:
1825 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001826 CommandObjectParsed (interpreter,
1827 "command script delete",
1828 "Delete a scripted command.",
1829 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00001830 {
1831 CommandArgumentEntry arg1;
1832 CommandArgumentData cmd_arg;
1833
1834 // Define the first (and only) variant of this arg.
1835 cmd_arg.arg_type = eArgTypeCommandName;
1836 cmd_arg.arg_repetition = eArgRepeatPlain;
1837
1838 // There is only one variant this argument could be; put it into the argument entry.
1839 arg1.push_back (cmd_arg);
1840
1841 // Push the data for the first argument into the m_arguments vector.
1842 m_arguments.push_back (arg1);
1843 }
1844
1845 ~CommandObjectCommandsScriptDelete ()
1846 {
1847 }
1848
Jim Ingham5a988412012-06-08 21:56:10 +00001849protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001850 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001851 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001852 {
1853
Jim Ingham5a988412012-06-08 21:56:10 +00001854 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001855
1856 if (argc != 1)
1857 {
1858 result.AppendError ("'command script delete' requires one argument");
1859 result.SetStatus (eReturnStatusFailed);
1860 return false;
1861 }
1862
Jim Ingham5a988412012-06-08 21:56:10 +00001863 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00001864
1865 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1866 {
1867 m_interpreter.RemoveUser(cmd_name);
1868 result.SetStatus (eReturnStatusSuccessFinishResult);
1869 }
1870 else
1871 {
1872 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1873 result.SetStatus (eReturnStatusFailed);
1874 }
1875
1876 return result.Succeeded();
1877
1878 }
1879};
1880
1881#pragma mark CommandObjectMultiwordCommandsScript
1882
1883//-------------------------------------------------------------------------
1884// CommandObjectMultiwordCommandsScript
1885//-------------------------------------------------------------------------
1886
1887class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1888{
1889public:
1890 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1891 CommandObjectMultiword (interpreter,
1892 "command script",
1893 "A set of commands for managing or customizing script commands.",
1894 "command script <subcommand> [<subcommand-options>]")
1895 {
1896 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1897 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1898 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1899 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Enrico Granataa9dbf432011-10-17 21:45:27 +00001900 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00001901 }
1902
1903 ~CommandObjectMultiwordCommandsScript ()
1904 {
1905 }
1906
1907};
1908
1909
Jim Inghamebc09c32010-07-07 03:36:20 +00001910#pragma mark CommandObjectMultiwordCommands
1911
1912//-------------------------------------------------------------------------
1913// CommandObjectMultiwordCommands
1914//-------------------------------------------------------------------------
1915
1916CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001917 CommandObjectMultiword (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001918 "command",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001919 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001920 "command <subcommand> [<subcommand-options>]")
Jim Inghamebc09c32010-07-07 03:36:20 +00001921{
Greg Claytona7015092010-09-18 01:14:36 +00001922 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1923 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1924 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytonde164aa2011-04-20 16:37:46 +00001925 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Inghama5a97eb2011-07-12 03:12:18 +00001926 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00001927 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Inghamebc09c32010-07-07 03:36:20 +00001928}
1929
1930CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1931{
1932}
1933