blob: 7bfdec094d6cedbcdc8a4e14e52965ed7c395f4b [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 Clayton44d93782014-01-27 23:43:24 +000021#include "lldb/Core/IOHandler.h"
Enrico Granatabe93a352011-08-16 16:49:25 +000022#include "lldb/Core/StringList.h"
Greg Claytonde164aa2011-04-20 16:37:46 +000023#include "lldb/Interpreter/Args.h"
Enrico Granata7594f142013-06-17 22:51:50 +000024#include "lldb/Interpreter/CommandHistory.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"
Enrico Granata7594f142013-06-17 22:51:50 +000029#include "lldb/Interpreter/OptionValueUInt64.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000030#include "lldb/Interpreter/Options.h"
Enrico Granata99f0b8f2011-08-17 01:30:04 +000031#include "lldb/Interpreter/ScriptInterpreter.h"
32#include "lldb/Interpreter/ScriptInterpreterPython.h"
Jim Inghamebc09c32010-07-07 03:36:20 +000033
34using namespace lldb;
35using namespace lldb_private;
36
Jim Inghamebc09c32010-07-07 03:36:20 +000037//-------------------------------------------------------------------------
38// CommandObjectCommandsSource
39//-------------------------------------------------------------------------
40
Jim Ingham5a988412012-06-08 21:56:10 +000041class CommandObjectCommandsHistory : public CommandObjectParsed
Jim Inghama5a97eb2011-07-12 03:12:18 +000042{
Jim Ingham5a988412012-06-08 21:56:10 +000043public:
44 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
45 CommandObjectParsed (interpreter,
46 "command history",
47 "Dump the history of commands in this session.",
48 NULL),
49 m_options (interpreter)
50 {
51 }
52
53 ~CommandObjectCommandsHistory () {}
54
55 virtual Options *
56 GetOptions ()
57 {
58 return &m_options;
59 }
60
61protected:
Jim Inghama5a97eb2011-07-12 03:12:18 +000062
63 class CommandOptions : public Options
64 {
65 public:
66
67 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata7594f142013-06-17 22:51:50 +000068 Options (interpreter),
69 m_start_idx(0),
70 m_stop_idx(0),
71 m_count(0),
Enrico Granata63123b62013-06-17 23:28:27 +000072 m_clear(false)
Jim Inghama5a97eb2011-07-12 03:12:18 +000073 {
74 }
75
76 virtual
77 ~CommandOptions (){}
78
79 virtual Error
80 SetOptionValue (uint32_t option_idx, const char *option_arg)
81 {
82 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000083 const int short_option = m_getopt_table[option_idx].val;
Jim Inghama5a97eb2011-07-12 03:12:18 +000084
85 switch (short_option)
86 {
87 case 'c':
Enrico Granata7594f142013-06-17 22:51:50 +000088 error = m_count.SetValueFromCString(option_arg,eVarSetOperationAssign);
Jim Inghama5a97eb2011-07-12 03:12:18 +000089 break;
90 case 's':
Enrico Granata7594f142013-06-17 22:51:50 +000091 if (option_arg && strcmp("end", option_arg) == 0)
92 {
93 m_start_idx.SetCurrentValue(UINT64_MAX);
94 m_start_idx.SetOptionWasSet();
95 }
96 else
97 error = m_start_idx.SetValueFromCString(option_arg,eVarSetOperationAssign);
98 break;
99 case 'e':
100 error = m_stop_idx.SetValueFromCString(option_arg,eVarSetOperationAssign);
101 break;
Enrico Granata63123b62013-06-17 23:28:27 +0000102 case 'C':
103 m_clear.SetCurrentValue(true);
104 m_clear.SetOptionWasSet();
Jim Inghama5a97eb2011-07-12 03:12:18 +0000105 break;
106 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000107 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghama5a97eb2011-07-12 03:12:18 +0000108 break;
109 }
110
111 return error;
112 }
113
114 void
115 OptionParsingStarting ()
116 {
Enrico Granata7594f142013-06-17 22:51:50 +0000117 m_start_idx.Clear();
118 m_stop_idx.Clear();
119 m_count.Clear();
Enrico Granata63123b62013-06-17 23:28:27 +0000120 m_clear.Clear();
Jim Inghama5a97eb2011-07-12 03:12:18 +0000121 }
122
123 const OptionDefinition*
124 GetDefinitions ()
125 {
126 return g_option_table;
127 }
128
129 // Options table: Required for subclasses of Options.
130
131 static OptionDefinition g_option_table[];
132
133 // Instance variables to hold the values for command options.
134
Enrico Granata7594f142013-06-17 22:51:50 +0000135 OptionValueUInt64 m_start_idx;
136 OptionValueUInt64 m_stop_idx;
137 OptionValueUInt64 m_count;
Enrico Granata63123b62013-06-17 23:28:27 +0000138 OptionValueBoolean m_clear;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000139 };
140
Jim Inghama5a97eb2011-07-12 03:12:18 +0000141 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000142 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghama5a97eb2011-07-12 03:12:18 +0000143 {
Enrico Granata63123b62013-06-17 23:28:27 +0000144 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
Enrico Granata7594f142013-06-17 22:51:50 +0000145 {
146 m_interpreter.GetCommandHistory().Clear();
147 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
148 }
149 else
150 {
151 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
152 {
153 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
154 result.SetStatus(lldb::eReturnStatusFailed);
155 }
156 else
157 {
Virgile Bello84400ec2013-08-27 16:22:29 +0000158 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
159 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
160 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
Enrico Granata7594f142013-06-17 22:51:50 +0000161
162 const CommandHistory& history(m_interpreter.GetCommandHistory());
163
164 if (start_idx.first && start_idx.second == UINT64_MAX)
165 {
166 if (count.first)
167 {
168 start_idx.second = history.GetSize() - count.second;
169 stop_idx.second = history.GetSize() - 1;
170 }
171 else if (stop_idx.first)
172 {
173 start_idx.second = stop_idx.second;
174 stop_idx.second = history.GetSize() - 1;
175 }
176 else
177 {
178 start_idx.second = 0;
179 stop_idx.second = history.GetSize() - 1;
180 }
181 }
182 else
183 {
184 if (!start_idx.first && !stop_idx.first && !count.first)
185 {
186 start_idx.second = 0;
187 stop_idx.second = history.GetSize() - 1;
188 }
189 else if (start_idx.first)
190 {
191 if (count.first)
192 {
193 stop_idx.second = start_idx.second + count.second - 1;
194 }
195 else if (!stop_idx.first)
196 {
197 stop_idx.second = history.GetSize() - 1;
198 }
199 }
200 else if (stop_idx.first)
201 {
202 if (count.first)
203 {
204 if (stop_idx.second >= count.second)
205 start_idx.second = stop_idx.second - count.second + 1;
206 else
207 start_idx.second = 0;
208 }
209 }
210 else /* if (count.first) */
211 {
212 start_idx.second = 0;
213 stop_idx.second = count.second - 1;
214 }
215 }
216 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
217 }
218 }
Jim Inghama5a97eb2011-07-12 03:12:18 +0000219 return result.Succeeded();
220
221 }
Jim Ingham5a988412012-06-08 21:56:10 +0000222
223 CommandOptions m_options;
Jim Inghama5a97eb2011-07-12 03:12:18 +0000224};
225
226OptionDefinition
227CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
228{
Virgile Belloe2607b52013-09-05 16:42:23 +0000229{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
230{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
231{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
232{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, 0, eArgTypeBoolean, "Clears the current command history."},
Jim Inghama5a97eb2011-07-12 03:12:18 +0000233{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
234};
235
236
237//-------------------------------------------------------------------------
238// CommandObjectCommandsSource
239//-------------------------------------------------------------------------
240
Jim Ingham5a988412012-06-08 21:56:10 +0000241class CommandObjectCommandsSource : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000242{
Jim Ingham5a988412012-06-08 21:56:10 +0000243public:
244 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
245 CommandObjectParsed (interpreter,
246 "command source",
247 "Read in debugger commands from the file <filename> and execute them.",
248 NULL),
249 m_options (interpreter)
250 {
251 CommandArgumentEntry arg;
252 CommandArgumentData file_arg;
253
254 // Define the first (and only) variant of this arg.
255 file_arg.arg_type = eArgTypeFilename;
256 file_arg.arg_repetition = eArgRepeatPlain;
257
258 // There is only one variant this argument could be; put it into the argument entry.
259 arg.push_back (file_arg);
260
261 // Push the data for the first argument into the m_arguments vector.
262 m_arguments.push_back (arg);
263 }
264
265 ~CommandObjectCommandsSource () {}
266
267 virtual const char*
268 GetRepeatCommand (Args &current_command_args, uint32_t index)
269 {
270 return "";
271 }
272
Greg Claytonc7bece562013-01-25 18:06:21 +0000273 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +0000274 HandleArgumentCompletion (Args &input,
275 int &cursor_index,
276 int &cursor_char_position,
277 OptionElementVector &opt_element_vector,
278 int match_start_point,
279 int max_return_elements,
280 bool &word_complete,
281 StringList &matches)
282 {
283 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
284 completion_str.erase (cursor_char_position);
285
286 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
287 CommandCompletions::eDiskFileCompletion,
288 completion_str.c_str(),
289 match_start_point,
290 max_return_elements,
291 NULL,
292 word_complete,
293 matches);
294 return matches.GetSize();
295 }
296
297 virtual Options *
298 GetOptions ()
299 {
300 return &m_options;
301 }
302
303protected:
Jim Inghame16c50a2011-02-18 00:54:25 +0000304
305 class CommandOptions : public Options
306 {
307 public:
308
Greg Claytoneb0103f2011-04-07 22:46:35 +0000309 CommandOptions (CommandInterpreter &interpreter) :
Enrico Granata012d4fc2013-06-11 01:26:35 +0000310 Options (interpreter),
Greg Clayton340b0302014-02-05 17:57:57 +0000311 m_stop_on_error (true),
312 m_silent_run (false),
313 m_stop_on_continue (true)
Greg Claytoneb0103f2011-04-07 22:46:35 +0000314 {
315 }
Jim Inghame16c50a2011-02-18 00:54:25 +0000316
317 virtual
318 ~CommandOptions (){}
319
320 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +0000321 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghame16c50a2011-02-18 00:54:25 +0000322 {
323 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000324 const int short_option = m_getopt_table[option_idx].val;
Jim Inghame16c50a2011-02-18 00:54:25 +0000325
326 switch (short_option)
327 {
328 case 'e':
Enrico Granata15571f12013-06-26 00:36:27 +0000329 error = m_stop_on_error.SetValueFromCString(option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000330 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000331
Jim Inghame16c50a2011-02-18 00:54:25 +0000332 case 'c':
Greg Clayton340b0302014-02-05 17:57:57 +0000333 error = m_stop_on_continue.SetValueFromCString(option_arg);
Jim Inghame16c50a2011-02-18 00:54:25 +0000334 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000335
Michael Sartain60986172013-07-09 23:22:53 +0000336 case 's':
Greg Clayton340b0302014-02-05 17:57:57 +0000337 error = m_silent_run.SetValueFromCString(option_arg);
Michael Sartain60986172013-07-09 23:22:53 +0000338 break;
Greg Clayton340b0302014-02-05 17:57:57 +0000339
Jim Inghame16c50a2011-02-18 00:54:25 +0000340 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000341 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Jim Inghame16c50a2011-02-18 00:54:25 +0000342 break;
343 }
344
345 return error;
346 }
347
348 void
Greg Claytonf6b8b582011-04-13 00:18:08 +0000349 OptionParsingStarting ()
Jim Inghame16c50a2011-02-18 00:54:25 +0000350 {
Enrico Granata012d4fc2013-06-11 01:26:35 +0000351 m_stop_on_error.Clear();
Greg Clayton340b0302014-02-05 17:57:57 +0000352 m_silent_run.Clear();
353 m_stop_on_continue.Clear();
Jim Inghame16c50a2011-02-18 00:54:25 +0000354 }
355
Greg Claytone0d378b2011-03-24 21:19:54 +0000356 const OptionDefinition*
Jim Inghame16c50a2011-02-18 00:54:25 +0000357 GetDefinitions ()
358 {
359 return g_option_table;
360 }
361
362 // Options table: Required for subclasses of Options.
363
Greg Claytone0d378b2011-03-24 21:19:54 +0000364 static OptionDefinition g_option_table[];
Jim Inghame16c50a2011-02-18 00:54:25 +0000365
366 // Instance variables to hold the values for command options.
367
Enrico Granata012d4fc2013-06-11 01:26:35 +0000368 OptionValueBoolean m_stop_on_error;
Greg Clayton340b0302014-02-05 17:57:57 +0000369 OptionValueBoolean m_silent_run;
370 OptionValueBoolean m_stop_on_continue;
Jim Inghame16c50a2011-02-18 00:54:25 +0000371 };
372
Jim Inghamebc09c32010-07-07 03:36:20 +0000373 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000374 DoExecute(Args& command, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000375 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000376 const size_t argc = command.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000377 if (argc == 1)
378 {
Jim Ingham5a988412012-06-08 21:56:10 +0000379 const char *filename = command.GetArgumentAtIndex(0);
Jim Inghamebc09c32010-07-07 03:36:20 +0000380
Johnny Chen1ee38532010-10-20 21:40:50 +0000381 FileSpec cmd_file (filename, true);
Jim Inghame16c50a2011-02-18 00:54:25 +0000382 ExecutionContext *exe_ctx = NULL; // Just use the default context.
Greg Clayton340b0302014-02-05 17:57:57 +0000383
384 // If any options were set, then use them
385 if (m_options.m_stop_on_error.OptionWasSet() ||
386 m_options.m_silent_run.OptionWasSet() ||
387 m_options.m_stop_on_continue.OptionWasSet())
388 {
389 // Use user set settings
390 LazyBool print_command = m_options.m_silent_run.GetCurrentValue() ? eLazyBoolNo : eLazyBoolYes;
391 m_interpreter.HandleCommandsFromFile (cmd_file,
392 exe_ctx,
393 m_options.m_stop_on_continue.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on continue
394 m_options.m_stop_on_error.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on error
395 print_command, // Echo command
396 print_command, // Print command output
397 eLazyBoolCalculate, // Add to history
398 result);
399
400 }
401 else
402 {
403 // No options were set, inherit any settings from nested "command source" commands,
404 // or set to sane default settings...
405 m_interpreter.HandleCommandsFromFile (cmd_file,
406 exe_ctx,
407 eLazyBoolCalculate, // Stop on continue
408 eLazyBoolCalculate, // Stop on error
409 eLazyBoolCalculate, // Echo command
410 eLazyBoolCalculate, // Print command output
411 eLazyBoolCalculate, // Add to history
412 result);
413
414 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000415 }
416 else
417 {
418 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
419 result.SetStatus (eReturnStatusFailed);
420 }
421 return result.Succeeded();
422
423 }
Jim Ingham5a988412012-06-08 21:56:10 +0000424 CommandOptions m_options;
Jim Inghamebc09c32010-07-07 03:36:20 +0000425};
426
Greg Claytone0d378b2011-03-24 21:19:54 +0000427OptionDefinition
Jim Inghame16c50a2011-02-18 00:54:25 +0000428CommandObjectCommandsSource::CommandOptions::g_option_table[] =
429{
Virgile Belloe2607b52013-09-05 16:42:23 +0000430{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
431{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
432{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
Jim Inghame16c50a2011-02-18 00:54:25 +0000433{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
434};
435
Jim Inghamebc09c32010-07-07 03:36:20 +0000436#pragma mark CommandObjectCommandsAlias
437//-------------------------------------------------------------------------
438// CommandObjectCommandsAlias
439//-------------------------------------------------------------------------
440
Enrico Granatabe93a352011-08-16 16:49:25 +0000441static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
442 "You must define a Python function with this signature:\n"
Greg Clayton44d93782014-01-27 23:43:24 +0000443 "def my_command_impl(debugger, args, result, internal_dict):\n";
Enrico Granatabe93a352011-08-16 16:49:25 +0000444
445
Jim Ingham5a988412012-06-08 21:56:10 +0000446class CommandObjectCommandsAlias : public CommandObjectRaw
Jim Inghamebc09c32010-07-07 03:36:20 +0000447{
Enrico Granatabe93a352011-08-16 16:49:25 +0000448
Enrico Granatabe93a352011-08-16 16:49:25 +0000449
Jim Inghamebc09c32010-07-07 03:36:20 +0000450public:
Greg Claytona7015092010-09-18 01:14:36 +0000451 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000452 CommandObjectRaw (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000453 "command alias",
Caroline Ticee3d26312010-09-08 21:06:11 +0000454 "Allow users to define their own debugger command abbreviations.",
Caroline Tice405fe672010-10-04 22:28:36 +0000455 NULL)
Jim Inghamebc09c32010-07-07 03:36:20 +0000456 {
457 SetHelpLong(
458 "'alias' allows the user to create a short-cut or abbreviation for long \n\
459 commands, multi-word commands, and commands that take particular options. \n\
460 Below are some simple examples of how one might use the 'alias' command: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000461 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000462 // command. \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000463 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000464 // command. Since breakpoint commands are two-word \n\
465 // commands, the user will still need to enter the \n\
466 // second word after 'bp', e.g. 'bp enable' or \n\
467 // 'bp delete'. \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000468 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000469 // two-word command 'breakpoint list'. \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000470 \nAn alias can include some options for the command, with the values either \n\
471 filled in at the time the alias is created, or specified as positional \n\
472 arguments, to be filled in when the alias is invoked. The following example \n\
473 shows how to create aliases with options: \n\
474 \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000475 'command alias bfl breakpoint set -f %1 -l %2' \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000476 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
477 options already part of the alias. So if the user wants to set a breakpoint \n\
478 by file and line without explicitly having to use the -f and -l options, the \n\
479 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
480 for the actual arguments that will be passed when the alias command is used. \n\
481 The number in the placeholder refers to the position/order the actual value \n\
Jim Ingham81ded932011-08-18 02:29:05 +0000482 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000483 will be replaced with the first argument, all the occurrences of '%2' in the \n\
484 alias will be replaced with the second argument, and so on. This also allows \n\
485 actual arguments to be used multiple times within an alias (see 'process \n\
Jim Ingham81ded932011-08-18 02:29:05 +0000486 launch' example below). \n\
487 Note: the positional arguments must substitute as whole words in the resultant\n\
488 command, so you can't at present do something like:\n\
489 \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000490 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
Jim Ingham81ded932011-08-18 02:29:05 +0000491 \n\
492 to get the file extension \".cpp\" automatically appended. For more complex\n\
493 aliasing, use the \"command regex\" command instead.\n\
494 \nSo in the 'bfl' case, the actual file value will be \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000495 filled in with the first argument following 'bfl' and the actual line number \n\
496 value will be filled in with the second argument. The user would use this \n\
497 alias as follows: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000498 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000499 <... some time later ...> \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000500 (lldb) bfl my-file.c 137 \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000501 \nThis would be the same as if the user had entered \n\
502 'breakpoint set -f my-file.c -l 137'. \n\
503 \nAnother example: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000504 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
Caroline Tice09799af2010-09-08 22:08:58 +0000505 (lldb) pltty /dev/tty0 \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000506 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
Jim Inghamebc09c32010-07-07 03:36:20 +0000507 \nIf the user always wanted to pass the same value to a particular option, the \n\
508 alias could be defined with that value directly in the alias as a constant, \n\
509 rather than using a positional placeholder: \n\
Jason Molenda69c12cc2011-11-10 22:43:35 +0000510 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
Sean Callanan0708e2c2010-08-09 18:50:15 +0000511 // 3 of whatever file is indicated. \n");
Jim Inghamebc09c32010-07-07 03:36:20 +0000512
Caroline Tice405fe672010-10-04 22:28:36 +0000513 CommandArgumentEntry arg1;
514 CommandArgumentEntry arg2;
515 CommandArgumentEntry arg3;
516 CommandArgumentData alias_arg;
517 CommandArgumentData cmd_arg;
518 CommandArgumentData options_arg;
519
520 // Define the first (and only) variant of this arg.
521 alias_arg.arg_type = eArgTypeAliasName;
522 alias_arg.arg_repetition = eArgRepeatPlain;
523
524 // There is only one variant this argument could be; put it into the argument entry.
525 arg1.push_back (alias_arg);
526
527 // Define the first (and only) variant of this arg.
528 cmd_arg.arg_type = eArgTypeCommandName;
529 cmd_arg.arg_repetition = eArgRepeatPlain;
530
531 // There is only one variant this argument could be; put it into the argument entry.
532 arg2.push_back (cmd_arg);
533
534 // Define the first (and only) variant of this arg.
535 options_arg.arg_type = eArgTypeAliasOptions;
536 options_arg.arg_repetition = eArgRepeatOptional;
537
538 // There is only one variant this argument could be; put it into the argument entry.
539 arg3.push_back (options_arg);
540
541 // Push the data for the first argument into the m_arguments vector.
542 m_arguments.push_back (arg1);
543 m_arguments.push_back (arg2);
544 m_arguments.push_back (arg3);
Jim Inghamebc09c32010-07-07 03:36:20 +0000545 }
546
547 ~CommandObjectCommandsAlias ()
548 {
549 }
550
Jim Ingham5a988412012-06-08 21:56:10 +0000551protected:
552 virtual bool
553 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Caroline Tice844d2302010-12-09 22:52:49 +0000554 {
555 Args args (raw_command_line);
556 std::string raw_command_string (raw_command_line);
557
558 size_t argc = args.GetArgumentCount();
559
560 if (argc < 2)
561 {
562 result.AppendError ("'alias' requires at least two arguments");
563 result.SetStatus (eReturnStatusFailed);
564 return false;
565 }
566
567 // Get the alias command.
568
569 const std::string alias_command = args.GetArgumentAtIndex (0);
Enrico Granatabe93a352011-08-16 16:49:25 +0000570
Caroline Tice844d2302010-12-09 22:52:49 +0000571 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
572 // does the stripping itself.
573 size_t pos = raw_command_string.find (alias_command);
574 if (pos == 0)
575 {
576 raw_command_string = raw_command_string.substr (alias_command.size());
577 pos = raw_command_string.find_first_not_of (' ');
578 if ((pos != std::string::npos) && (pos > 0))
579 raw_command_string = raw_command_string.substr (pos);
580 }
581 else
582 {
583 result.AppendError ("Error parsing command string. No alias created.");
584 result.SetStatus (eReturnStatusFailed);
585 return false;
586 }
587
588
589 // Verify that the command is alias-able.
590 if (m_interpreter.CommandExists (alias_command.c_str()))
591 {
592 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
593 alias_command.c_str());
594 result.SetStatus (eReturnStatusFailed);
595 return false;
596 }
597
598 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
599 // raw_command_string is returned with the name of the command object stripped off the front.
600 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
601
602 if (!cmd_obj)
603 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000604 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
Caroline Tice844d2302010-12-09 22:52:49 +0000605 " No alias created.", raw_command_string.c_str());
606 result.SetStatus (eReturnStatusFailed);
607 return false;
608 }
609 else if (!cmd_obj->WantsRawCommandString ())
610 {
611 // Note that args was initialized with the original command, and has not been updated to this point.
612 // 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 +0000613 return HandleAliasingNormalCommand (args, result);
Caroline Tice844d2302010-12-09 22:52:49 +0000614 }
615 else
616 {
Jim Ingham5a988412012-06-08 21:56:10 +0000617 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
618 }
619 return result.Succeeded();
620 }
621
622 bool
623 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
624 {
Caroline Tice844d2302010-12-09 22:52:49 +0000625 // Verify & handle any options/arguments passed to the alias command
626
627 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
628 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
629
Jim Ingham5a988412012-06-08 21:56:10 +0000630 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
Caroline Ticeca90c472011-05-06 21:37:15 +0000631
632 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
Caroline Tice844d2302010-12-09 22:52:49 +0000633 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000634 result.AppendError ("Unable to create requested alias.\n");
635 result.SetStatus (eReturnStatusFailed);
636 return false;
Caroline Tice844d2302010-12-09 22:52:49 +0000637 }
638
639 // Create the alias
640 if (m_interpreter.AliasExists (alias_command.c_str())
641 || m_interpreter.UserCommandExists (alias_command.c_str()))
642 {
643 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
644 if (temp_option_arg_sp.get())
645 {
646 if (option_arg_vector->size() == 0)
647 m_interpreter.RemoveAliasOptions (alias_command.c_str());
648 }
649 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
650 alias_command.c_str());
651 }
652
Caroline Tice472362e2010-12-14 18:51:39 +0000653 if (cmd_obj_sp)
654 {
655 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
656 if (option_arg_vector->size() > 0)
657 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
658 result.SetStatus (eReturnStatusSuccessFinishNoResult);
659 }
660 else
661 {
662 result.AppendError ("Unable to create requested alias.\n");
663 result.SetStatus (eReturnStatusFailed);
664 }
Jim Ingham5a988412012-06-08 21:56:10 +0000665 return result.Succeeded ();
Caroline Tice844d2302010-12-09 22:52:49 +0000666 }
Jim Ingham5a988412012-06-08 21:56:10 +0000667
Jim Inghamebc09c32010-07-07 03:36:20 +0000668 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000669 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000670 {
Caroline Tice867b185d2010-09-21 23:25:40 +0000671 size_t argc = args.GetArgumentCount();
Jim Inghamebc09c32010-07-07 03:36:20 +0000672
673 if (argc < 2)
Greg Claytonc982c762010-07-09 20:39:50 +0000674 {
Jim Inghamebc09c32010-07-07 03:36:20 +0000675 result.AppendError ("'alias' requires at least two arguments");
676 result.SetStatus (eReturnStatusFailed);
677 return false;
Greg Claytonc982c762010-07-09 20:39:50 +0000678 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000679
680 const std::string alias_command = args.GetArgumentAtIndex(0);
681 const std::string actual_command = args.GetArgumentAtIndex(1);
682
683 args.Shift(); // Shift the alias command word off the argument vector.
684 args.Shift(); // Shift the old command word off the argument vector.
685
686 // Verify that the command is alias'able, and get the appropriate command object.
687
Greg Claytona7015092010-09-18 01:14:36 +0000688 if (m_interpreter.CommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000689 {
690 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
691 alias_command.c_str());
692 result.SetStatus (eReturnStatusFailed);
693 }
694 else
695 {
Greg Claytona7015092010-09-18 01:14:36 +0000696 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
Jim Inghamebc09c32010-07-07 03:36:20 +0000697 CommandObjectSP subcommand_obj_sp;
698 bool use_subcommand = false;
699 if (command_obj_sp.get())
700 {
701 CommandObject *cmd_obj = command_obj_sp.get();
Greg Claytonc982c762010-07-09 20:39:50 +0000702 CommandObject *sub_cmd_obj = NULL;
Jim Inghamebc09c32010-07-07 03:36:20 +0000703 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
704 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
705
Caroline Tice844d2302010-12-09 22:52:49 +0000706 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
Jim Inghamebc09c32010-07-07 03:36:20 +0000707 {
708 if (argc >= 3)
709 {
710 const std::string sub_command = args.GetArgumentAtIndex(0);
711 assert (sub_command.length() != 0);
Greg Clayton998255b2012-10-13 02:07:45 +0000712 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000713 if (subcommand_obj_sp.get())
714 {
715 sub_cmd_obj = subcommand_obj_sp.get();
716 use_subcommand = true;
717 args.Shift(); // Shift the sub_command word off the argument vector.
Caroline Tice844d2302010-12-09 22:52:49 +0000718 cmd_obj = sub_cmd_obj;
Jim Inghamebc09c32010-07-07 03:36:20 +0000719 }
720 else
721 {
Caroline Ticef415eeb2010-11-02 19:00:04 +0000722 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
723 "Unable to create alias.\n",
724 sub_command.c_str(), actual_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000725 result.SetStatus (eReturnStatusFailed);
726 return false;
727 }
728 }
729 }
730
731 // Verify & handle any options/arguments passed to the alias command
732
733 if (args.GetArgumentCount () > 0)
734 {
Caroline Ticeca90c472011-05-06 21:37:15 +0000735 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
736 if (use_subcommand)
737 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
738
739 std::string args_string;
740 args.GetCommandString (args_string);
741
742 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
743 {
744 result.AppendError ("Unable to create requested alias.\n");
745 result.SetStatus (eReturnStatusFailed);
746 return false;
747 }
Jim Inghamebc09c32010-07-07 03:36:20 +0000748 }
749
750 // Create the alias.
751
Greg Claytona7015092010-09-18 01:14:36 +0000752 if (m_interpreter.AliasExists (alias_command.c_str())
753 || m_interpreter.UserCommandExists (alias_command.c_str()))
Jim Inghamebc09c32010-07-07 03:36:20 +0000754 {
Greg Claytona7015092010-09-18 01:14:36 +0000755 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
Jim Inghamebc09c32010-07-07 03:36:20 +0000756 if (tmp_option_arg_sp.get())
757 {
758 if (option_arg_vector->size() == 0)
Greg Claytona7015092010-09-18 01:14:36 +0000759 m_interpreter.RemoveAliasOptions (alias_command.c_str());
Jim Inghamebc09c32010-07-07 03:36:20 +0000760 }
761 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
762 alias_command.c_str());
763 }
764
765 if (use_subcommand)
Greg Claytona7015092010-09-18 01:14:36 +0000766 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000767 else
Greg Claytona7015092010-09-18 01:14:36 +0000768 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000769 if (option_arg_vector->size() > 0)
Greg Claytona7015092010-09-18 01:14:36 +0000770 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
Jim Inghamebc09c32010-07-07 03:36:20 +0000771 result.SetStatus (eReturnStatusSuccessFinishNoResult);
772 }
773 else
774 {
775 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
776 result.SetStatus (eReturnStatusFailed);
Caroline Ticee7941792010-10-28 23:17:48 +0000777 return false;
Jim Inghamebc09c32010-07-07 03:36:20 +0000778 }
779 }
780
781 return result.Succeeded();
782 }
Jim Ingham5a988412012-06-08 21:56:10 +0000783
Jim Inghamebc09c32010-07-07 03:36:20 +0000784};
785
786#pragma mark CommandObjectCommandsUnalias
787//-------------------------------------------------------------------------
788// CommandObjectCommandsUnalias
789//-------------------------------------------------------------------------
790
Jim Ingham5a988412012-06-08 21:56:10 +0000791class CommandObjectCommandsUnalias : public CommandObjectParsed
Jim Inghamebc09c32010-07-07 03:36:20 +0000792{
793public:
Greg Claytona7015092010-09-18 01:14:36 +0000794 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000795 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000796 "command unalias",
Caroline Tice86ddae52010-09-12 04:56:10 +0000797 "Allow the user to remove/delete a user-defined command abbreviation.",
Caroline Tice405fe672010-10-04 22:28:36 +0000798 NULL)
Jim Inghamebc09c32010-07-07 03:36:20 +0000799 {
Caroline Tice405fe672010-10-04 22:28:36 +0000800 CommandArgumentEntry arg;
801 CommandArgumentData alias_arg;
802
803 // Define the first (and only) variant of this arg.
804 alias_arg.arg_type = eArgTypeAliasName;
805 alias_arg.arg_repetition = eArgRepeatPlain;
806
807 // There is only one variant this argument could be; put it into the argument entry.
808 arg.push_back (alias_arg);
809
810 // Push the data for the first argument into the m_arguments vector.
811 m_arguments.push_back (arg);
Jim Inghamebc09c32010-07-07 03:36:20 +0000812 }
813
814 ~CommandObjectCommandsUnalias()
815 {
816 }
817
Jim Ingham5a988412012-06-08 21:56:10 +0000818protected:
Jim Inghamebc09c32010-07-07 03:36:20 +0000819 bool
Jim Ingham5a988412012-06-08 21:56:10 +0000820 DoExecute (Args& args, CommandReturnObject &result)
Jim Inghamebc09c32010-07-07 03:36:20 +0000821 {
822 CommandObject::CommandMap::iterator pos;
823 CommandObject *cmd_obj;
824
825 if (args.GetArgumentCount() != 0)
826 {
827 const char *command_name = args.GetArgumentAtIndex(0);
Greg Claytona7015092010-09-18 01:14:36 +0000828 cmd_obj = m_interpreter.GetCommandObject(command_name);
Jim Inghamebc09c32010-07-07 03:36:20 +0000829 if (cmd_obj)
830 {
Greg Claytona7015092010-09-18 01:14:36 +0000831 if (m_interpreter.CommandExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000832 {
833 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
834 command_name);
835 result.SetStatus (eReturnStatusFailed);
836 }
837 else
838 {
839
Greg Claytona7015092010-09-18 01:14:36 +0000840 if (m_interpreter.RemoveAlias (command_name) == false)
Jim Inghamebc09c32010-07-07 03:36:20 +0000841 {
Greg Claytona7015092010-09-18 01:14:36 +0000842 if (m_interpreter.AliasExists (command_name))
Jim Inghamebc09c32010-07-07 03:36:20 +0000843 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
844 command_name);
845 else
846 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
847 result.SetStatus (eReturnStatusFailed);
848 }
849 else
850 result.SetStatus (eReturnStatusSuccessFinishNoResult);
851 }
852 }
853 else
854 {
855 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
856 "current list of commands.\n",
857 command_name);
858 result.SetStatus (eReturnStatusFailed);
859 }
860 }
861 else
862 {
863 result.AppendError ("must call 'unalias' with a valid alias");
864 result.SetStatus (eReturnStatusFailed);
865 }
866
867 return result.Succeeded();
868 }
869};
870
Greg Claytonde164aa2011-04-20 16:37:46 +0000871//-------------------------------------------------------------------------
872// CommandObjectCommandsAddRegex
873//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000874#pragma mark CommandObjectCommandsAddRegex
Greg Claytonde164aa2011-04-20 16:37:46 +0000875
Greg Clayton44d93782014-01-27 23:43:24 +0000876class CommandObjectCommandsAddRegex :
877 public CommandObjectParsed,
878 public IOHandlerDelegate
Greg Claytonde164aa2011-04-20 16:37:46 +0000879{
880public:
881 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000882 CommandObjectParsed (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000883 "command regex",
Greg Claytonde164aa2011-04-20 16:37:46 +0000884 "Allow the user to create a regular expression command.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000885 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
Greg Clayton44d93782014-01-27 23:43:24 +0000886 IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
Greg Claytonde164aa2011-04-20 16:37:46 +0000887 m_options (interpreter)
888 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000889 SetHelpLong(
890"This command allows the user to create powerful regular expression commands\n"
891"with substitutions. The regular expressions and substitutions are specified\n"
892"using the regular exression substitution format of:\n"
893"\n"
894" s/<regex>/<subst>/\n"
895"\n"
896"<regex> is a regular expression that can use parenthesis to capture regular\n"
897"expression input and substitute the captured matches in the output using %1\n"
898"for the first match, %2 for the second, and so on.\n"
899"\n"
900"The regular expressions can all be specified on the command line if more than\n"
901"one argument is provided. If just the command name is provided on the command\n"
902"line, then the regular expressions and substitutions can be entered on separate\n"
903" lines, followed by an empty line to terminate the command definition.\n"
904"\n"
905"EXAMPLES\n"
906"\n"
Sean Callananadc43c92012-08-16 21:46:58 +0000907"The following example will define a regular expression command named 'f' that\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000908"will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
909"a number follows 'f':\n"
Sean Callananadc43c92012-08-16 21:46:58 +0000910"\n"
911" (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
912"\n"
Greg Clayton0e5e5a72011-04-20 22:55:21 +0000913 );
Greg Claytonde164aa2011-04-20 16:37:46 +0000914 }
915
916 ~CommandObjectCommandsAddRegex()
917 {
918 }
919
920
Jim Ingham5a988412012-06-08 21:56:10 +0000921protected:
Greg Clayton44d93782014-01-27 23:43:24 +0000922
923 virtual void
924 IOHandlerActivated (IOHandler &io_handler)
925 {
926 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
927 if (output_sp)
928 {
929 output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n");
930 output_sp->Flush();
931 }
932 }
933
934 virtual void
935 IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
936 {
937 io_handler.SetIsDone(true);
938 if (m_regex_cmd_ap.get())
939 {
940 StringList lines;
941 if (lines.SplitIntoLines (data))
942 {
943 const size_t num_lines = lines.GetSize();
944 bool check_only = false;
945 for (size_t i=0; i<num_lines; ++i)
946 {
947 printf ("regex[%zu] = %s\n", i, lines[i].c_str());
948 llvm::StringRef bytes_strref (lines[i]);
949 Error error = AppendRegexSubstitution (bytes_strref, check_only);
950 if (error.Fail())
951 {
952 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
953 {
954 StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
955 out_stream->Printf("error: %s\n", error.AsCString());
956 }
957 }
958 }
959 }
960 if (m_regex_cmd_ap->HasRegexEntries())
961 {
962 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
963 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
964 }
965 }
966 }
967
968 virtual LineStatus
969 IOHandlerLinesUpdated (IOHandler &io_handler,
970 StringList &lines,
971 uint32_t line_idx,
972 Error &error)
973 {
974 if (line_idx == UINT32_MAX)
975 {
976 // Return true to indicate we are done getting lines (this
977 // is a "fake" line - the real terminating blank line was
978 // removed during a previous call with the code below)
979 error.Clear();
980 return LineStatus::Done;
981 }
982 else
983 {
984 const size_t num_lines = lines.GetSize();
985 if (line_idx + 1 == num_lines)
986 {
987 // The last line was edited, if this line is empty, then we are done
988 // getting our multiple lines.
989 if (lines[line_idx].empty())
990 {
991 // Remove the last empty line from "lines" so it doesn't appear
992 // in our final expression and return true to indicate we are done
993 // getting lines
994 lines.PopBack();
995 return LineStatus::Done;
996 }
997 }
998 // Check the current line to make sure it is formatted correctly
999 bool check_only = true;
1000 llvm::StringRef regex_sed(lines[line_idx]);
1001 error = AppendRegexSubstitution (regex_sed, check_only);
1002 if (error.Fail())
1003 {
1004 return LineStatus::Error;
1005 }
1006 else
1007 {
1008 return LineStatus::Success;
1009 }
1010 }
1011 }
1012
Greg Claytonde164aa2011-04-20 16:37:46 +00001013 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001014 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytonde164aa2011-04-20 16:37:46 +00001015 {
Jim Ingham5a988412012-06-08 21:56:10 +00001016 const size_t argc = command.GetArgumentCount();
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001017 if (argc == 0)
Greg Claytonde164aa2011-04-20 16:37:46 +00001018 {
Jason Molenda69c12cc2011-11-10 22:43:35 +00001019 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001020 result.SetStatus (eReturnStatusFailed);
1021 }
1022 else
1023 {
1024 Error error;
Jim Ingham5a988412012-06-08 21:56:10 +00001025 const char *name = command.GetArgumentAtIndex(0);
Greg Claytonde164aa2011-04-20 16:37:46 +00001026 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1027 name,
1028 m_options.GetHelp (),
1029 m_options.GetSyntax (),
1030 10));
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001031
1032 if (argc == 1)
Greg Claytonde164aa2011-04-20 16:37:46 +00001033 {
Greg Clayton44d93782014-01-27 23:43:24 +00001034 Debugger &debugger = m_interpreter.GetDebugger();
1035 const bool multiple_lines = true; // Get multiple lines
1036 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
1037 "lldb", // Name of input reader for history
1038 "\033[K> ", // Prompt and clear line
1039 multiple_lines,
1040 *this));
1041
1042 if (io_handler_sp)
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001043 {
Greg Clayton44d93782014-01-27 23:43:24 +00001044 debugger.PushIOHandler(io_handler_sp);
1045 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonde164aa2011-04-20 16:37:46 +00001046 }
1047 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001048 else
1049 {
1050 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
1051 {
Jim Ingham5a988412012-06-08 21:56:10 +00001052 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton44d93782014-01-27 23:43:24 +00001053 bool check_only = false;
1054 error = AppendRegexSubstitution (arg_strref, check_only);
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001055 if (error.Fail())
1056 break;
1057 }
1058
1059 if (error.Success())
1060 {
1061 AddRegexCommandToInterpreter();
1062 }
1063 }
1064 if (error.Fail())
1065 {
1066 result.AppendError (error.AsCString());
1067 result.SetStatus (eReturnStatusFailed);
1068 }
Greg Claytonde164aa2011-04-20 16:37:46 +00001069 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001070
Greg Claytonde164aa2011-04-20 16:37:46 +00001071 return result.Succeeded();
1072 }
1073
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001074 Error
Greg Clayton44d93782014-01-27 23:43:24 +00001075 AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
Greg Claytonde164aa2011-04-20 16:37:46 +00001076 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001077 Error error;
1078
1079 if (m_regex_cmd_ap.get() == NULL)
Greg Claytonde164aa2011-04-20 16:37:46 +00001080 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001081 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
1082 (int)regex_sed.size(),
1083 regex_sed.data());
1084 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001085 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001086
1087 size_t regex_sed_size = regex_sed.size();
1088
1089 if (regex_sed_size <= 1)
1090 {
1091 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
1092 (int)regex_sed.size(),
1093 regex_sed.data());
1094 return error;
1095 }
1096
1097 if (regex_sed[0] != 's')
1098 {
1099 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
1100 (int)regex_sed.size(),
1101 regex_sed.data());
1102 return error;
1103 }
1104 const size_t first_separator_char_pos = 1;
1105 // use the char that follows 's' as the regex separator character
1106 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1107 const char separator_char = regex_sed[first_separator_char_pos];
1108 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1109
1110 if (second_separator_char_pos == std::string::npos)
1111 {
1112 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
1113 separator_char,
1114 (int)(regex_sed.size() - first_separator_char_pos - 1),
1115 regex_sed.data() + (first_separator_char_pos + 1));
1116 return error;
1117 }
1118
1119 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1120
1121 if (third_separator_char_pos == std::string::npos)
1122 {
1123 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
1124 separator_char,
1125 (int)(regex_sed.size() - second_separator_char_pos - 1),
1126 regex_sed.data() + (second_separator_char_pos + 1));
1127 return error;
1128 }
1129
1130 if (third_separator_char_pos != regex_sed_size - 1)
1131 {
1132 // Make sure that everything that follows the last regex
1133 // separator char
1134 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1135 {
1136 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1137 (int)third_separator_char_pos + 1,
1138 regex_sed.data(),
1139 (int)(regex_sed.size() - third_separator_char_pos - 1),
1140 regex_sed.data() + (third_separator_char_pos + 1));
1141 return error;
1142 }
1143
1144 }
1145 else if (first_separator_char_pos + 1 == second_separator_char_pos)
1146 {
1147 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1148 separator_char,
1149 separator_char,
1150 separator_char,
1151 (int)regex_sed.size(),
1152 regex_sed.data());
1153 return error;
1154 }
1155 else if (second_separator_char_pos + 1 == third_separator_char_pos)
1156 {
1157 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1158 separator_char,
1159 separator_char,
1160 separator_char,
1161 (int)regex_sed.size(),
1162 regex_sed.data());
1163 return error;
1164 }
Greg Clayton44d93782014-01-27 23:43:24 +00001165
1166 if (check_only == false)
1167 {
1168 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1169 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1170 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1171 subst.c_str());
1172 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001173 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001174 }
1175
1176 void
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001177 AddRegexCommandToInterpreter()
Greg Claytonde164aa2011-04-20 16:37:46 +00001178 {
1179 if (m_regex_cmd_ap.get())
1180 {
1181 if (m_regex_cmd_ap->HasRegexEntries())
1182 {
1183 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1184 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1185 }
1186 }
1187 }
1188
Greg Claytonde164aa2011-04-20 16:37:46 +00001189private:
Greg Clayton7b0992d2013-04-18 22:45:39 +00001190 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
Greg Claytonde164aa2011-04-20 16:37:46 +00001191
1192 class CommandOptions : public Options
1193 {
1194 public:
1195
1196 CommandOptions (CommandInterpreter &interpreter) :
1197 Options (interpreter)
1198 {
1199 }
1200
1201 virtual
1202 ~CommandOptions (){}
1203
1204 virtual Error
1205 SetOptionValue (uint32_t option_idx, const char *option_arg)
1206 {
1207 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001208 const int short_option = m_getopt_table[option_idx].val;
Greg Claytonde164aa2011-04-20 16:37:46 +00001209
1210 switch (short_option)
1211 {
1212 case 'h':
1213 m_help.assign (option_arg);
1214 break;
1215 case 's':
1216 m_syntax.assign (option_arg);
1217 break;
1218
1219 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001220 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytonde164aa2011-04-20 16:37:46 +00001221 break;
1222 }
1223
1224 return error;
1225 }
1226
1227 void
1228 OptionParsingStarting ()
1229 {
1230 m_help.clear();
1231 m_syntax.clear();
1232 }
1233
1234 const OptionDefinition*
1235 GetDefinitions ()
1236 {
1237 return g_option_table;
1238 }
1239
1240 // Options table: Required for subclasses of Options.
1241
1242 static OptionDefinition g_option_table[];
1243
1244 const char *
1245 GetHelp ()
1246 {
1247 if (m_help.empty())
1248 return NULL;
1249 return m_help.c_str();
1250 }
1251 const char *
1252 GetSyntax ()
1253 {
1254 if (m_syntax.empty())
1255 return NULL;
1256 return m_syntax.c_str();
1257 }
1258 // Instance variables to hold the values for command options.
1259 protected:
1260 std::string m_help;
1261 std::string m_syntax;
1262 };
Jim Ingham5a988412012-06-08 21:56:10 +00001263
Greg Claytonde164aa2011-04-20 16:37:46 +00001264 virtual Options *
1265 GetOptions ()
1266 {
1267 return &m_options;
1268 }
Jim Ingham5a988412012-06-08 21:56:10 +00001269
1270 CommandOptions m_options;
Greg Claytonde164aa2011-04-20 16:37:46 +00001271};
1272
Greg Claytonde164aa2011-04-20 16:37:46 +00001273OptionDefinition
1274CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1275{
Virgile Belloe2607b52013-09-05 16:42:23 +00001276{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1277{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001278{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytonde164aa2011-04-20 16:37:46 +00001279};
1280
1281
Jim Ingham5a988412012-06-08 21:56:10 +00001282class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata223383e2011-08-16 23:24:13 +00001283{
1284private:
1285 std::string m_function_name;
Enrico Granata0a305db2011-11-07 22:57:04 +00001286 ScriptedCommandSynchronicity m_synchro;
Enrico Granatafac939e2012-09-18 21:53:02 +00001287 bool m_fetched_help_long;
Enrico Granata223383e2011-08-16 23:24:13 +00001288
1289public:
1290
1291 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1292 std::string name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001293 std::string funct,
1294 ScriptedCommandSynchronicity synch) :
Jim Ingham5a988412012-06-08 21:56:10 +00001295 CommandObjectRaw (interpreter,
1296 name.c_str(),
1297 (std::string("Run Python function ") + funct).c_str(),
1298 NULL),
1299 m_function_name(funct),
Enrico Granatafac939e2012-09-18 21:53:02 +00001300 m_synchro(synch),
1301 m_fetched_help_long(false)
Enrico Granata223383e2011-08-16 23:24:13 +00001302 {
1303 }
1304
1305 virtual
1306 ~CommandObjectPythonFunction ()
1307 {
1308 }
1309
1310 virtual bool
Greg Clayton3a18e312012-10-08 22:41:53 +00001311 IsRemovable () const
Jim Ingham5a988412012-06-08 21:56:10 +00001312 {
1313 return true;
1314 }
1315
1316 const std::string&
1317 GetFunctionName ()
1318 {
1319 return m_function_name;
1320 }
1321
1322 ScriptedCommandSynchronicity
1323 GetSynchronicity ()
1324 {
1325 return m_synchro;
1326 }
1327
Enrico Granatafac939e2012-09-18 21:53:02 +00001328 virtual const char *
1329 GetHelpLong ()
1330 {
1331 if (!m_fetched_help_long)
1332 {
1333 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1334 if (scripter)
1335 {
1336 std::string docstring;
1337 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1338 if (!docstring.empty())
1339 SetHelpLong(docstring);
1340 }
1341 }
1342 return CommandObjectRaw::GetHelpLong();
1343 }
1344
Jim Ingham5a988412012-06-08 21:56:10 +00001345protected:
1346 virtual bool
1347 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001348 {
1349 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1350
1351 Error error;
1352
Jim Ingham70f11f82012-06-27 17:25:36 +00001353 result.SetStatus(eReturnStatusInvalid);
1354
Enrico Granata223383e2011-08-16 23:24:13 +00001355 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1356 raw_command_line,
Enrico Granata0a305db2011-11-07 22:57:04 +00001357 m_synchro,
Enrico Granata223383e2011-08-16 23:24:13 +00001358 result,
1359 error) == false)
1360 {
1361 result.AppendError(error.AsCString());
1362 result.SetStatus(eReturnStatusFailed);
1363 }
1364 else
Jim Ingham70f11f82012-06-27 17:25:36 +00001365 {
1366 // Don't change the status if the command already set it...
1367 if (result.GetStatus() == eReturnStatusInvalid)
1368 {
Daniel Malea9a71a7d2013-07-03 17:58:31 +00001369 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
Jim Ingham70f11f82012-06-27 17:25:36 +00001370 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1371 else
1372 result.SetStatus(eReturnStatusSuccessFinishResult);
1373 }
1374 }
Enrico Granata223383e2011-08-16 23:24:13 +00001375
1376 return result.Succeeded();
1377 }
1378
Enrico Granata223383e2011-08-16 23:24:13 +00001379};
1380
Enrico Granataa9dbf432011-10-17 21:45:27 +00001381//-------------------------------------------------------------------------
1382// CommandObjectCommandsScriptImport
1383//-------------------------------------------------------------------------
1384
Jim Ingham5a988412012-06-08 21:56:10 +00001385class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granataa9dbf432011-10-17 21:45:27 +00001386{
Jim Ingham5a988412012-06-08 21:56:10 +00001387public:
1388 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1389 CommandObjectParsed (interpreter,
1390 "command script import",
1391 "Import a scripting module in LLDB.",
1392 NULL),
1393 m_options(interpreter)
1394 {
1395 CommandArgumentEntry arg1;
1396 CommandArgumentData cmd_arg;
1397
1398 // Define the first (and only) variant of this arg.
1399 cmd_arg.arg_type = eArgTypeFilename;
1400 cmd_arg.arg_repetition = eArgRepeatPlain;
1401
1402 // There is only one variant this argument could be; put it into the argument entry.
1403 arg1.push_back (cmd_arg);
1404
1405 // Push the data for the first argument into the m_arguments vector.
1406 m_arguments.push_back (arg1);
1407 }
1408
1409 ~CommandObjectCommandsScriptImport ()
1410 {
1411 }
1412
Greg Claytonc7bece562013-01-25 18:06:21 +00001413 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +00001414 HandleArgumentCompletion (Args &input,
1415 int &cursor_index,
1416 int &cursor_char_position,
1417 OptionElementVector &opt_element_vector,
1418 int match_start_point,
1419 int max_return_elements,
1420 bool &word_complete,
1421 StringList &matches)
1422 {
1423 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1424 completion_str.erase (cursor_char_position);
1425
1426 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1427 CommandCompletions::eDiskFileCompletion,
1428 completion_str.c_str(),
1429 match_start_point,
1430 max_return_elements,
1431 NULL,
1432 word_complete,
1433 matches);
1434 return matches.GetSize();
1435 }
1436
1437 virtual Options *
1438 GetOptions ()
1439 {
1440 return &m_options;
1441 }
1442
1443protected:
Enrico Granata0a305db2011-11-07 22:57:04 +00001444
1445 class CommandOptions : public Options
1446 {
1447 public:
1448
1449 CommandOptions (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001450 Options (interpreter)
Enrico Granata0a305db2011-11-07 22:57:04 +00001451 {
1452 }
1453
1454 virtual
1455 ~CommandOptions (){}
1456
1457 virtual Error
1458 SetOptionValue (uint32_t option_idx, const char *option_arg)
1459 {
1460 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001461 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata0a305db2011-11-07 22:57:04 +00001462
1463 switch (short_option)
1464 {
1465 case 'r':
1466 m_allow_reload = true;
1467 break;
1468 default:
1469 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1470 break;
1471 }
1472
1473 return error;
1474 }
1475
1476 void
1477 OptionParsingStarting ()
1478 {
Enrico Granatae0c70f12013-05-31 01:03:09 +00001479 m_allow_reload = true;
Enrico Granata0a305db2011-11-07 22:57:04 +00001480 }
1481
1482 const OptionDefinition*
1483 GetDefinitions ()
1484 {
1485 return g_option_table;
1486 }
1487
1488 // Options table: Required for subclasses of Options.
1489
1490 static OptionDefinition g_option_table[];
1491
1492 // Instance variables to hold the values for command options.
1493
1494 bool m_allow_reload;
1495 };
Enrico Granata0a305db2011-11-07 22:57:04 +00001496
Enrico Granataa9dbf432011-10-17 21:45:27 +00001497 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001498 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001499 {
1500
1501 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1502 {
1503 result.AppendError ("only scripting language supported for module importing is currently Python");
1504 result.SetStatus (eReturnStatusFailed);
1505 return false;
1506 }
1507
Jim Ingham5a988412012-06-08 21:56:10 +00001508 size_t argc = command.GetArgumentCount();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001509
1510 if (argc != 1)
1511 {
1512 result.AppendError ("'command script import' requires one argument");
1513 result.SetStatus (eReturnStatusFailed);
1514 return false;
1515 }
1516
Jim Ingham5a988412012-06-08 21:56:10 +00001517 std::string path = command.GetArgumentAtIndex(0);
Enrico Granataa9dbf432011-10-17 21:45:27 +00001518 Error error;
1519
Greg Claytonc9d645d2012-10-18 22:40:37 +00001520 const bool init_session = true;
Enrico Granata078551c2013-05-09 19:33:49 +00001521 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1522 // commands won't ever be recursively invoked, but it's actually possible to craft
1523 // a Python script that does other "command script imports" in __lldb_init_module
1524 // the real fix is to have recursive commands possible with a CommandInvocation object
1525 // separate from the CommandObject itself, so that recursive command invocations
1526 // won't stomp on each other (wrt to execution contents, options, and more)
1527 m_exe_ctx.Clear();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001528 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata0a305db2011-11-07 22:57:04 +00001529 m_options.m_allow_reload,
Greg Claytonc9d645d2012-10-18 22:40:37 +00001530 init_session,
Enrico Granataa9dbf432011-10-17 21:45:27 +00001531 error))
1532 {
1533 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1534 }
1535 else
1536 {
1537 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1538 result.SetStatus (eReturnStatusFailed);
1539 }
1540
1541 return result.Succeeded();
1542 }
Enrico Granata0a305db2011-11-07 22:57:04 +00001543
Jim Ingham5a988412012-06-08 21:56:10 +00001544 CommandOptions m_options;
Enrico Granataa9dbf432011-10-17 21:45:27 +00001545};
Enrico Granata223383e2011-08-16 23:24:13 +00001546
Enrico Granata0a305db2011-11-07 22:57:04 +00001547OptionDefinition
1548CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1549{
Virgile Belloe2607b52013-09-05 16:42:23 +00001550 { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, 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 +00001551 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1552};
1553
1554
Enrico Granata223383e2011-08-16 23:24:13 +00001555//-------------------------------------------------------------------------
1556// CommandObjectCommandsScriptAdd
1557//-------------------------------------------------------------------------
1558
Greg Clayton44d93782014-01-27 23:43:24 +00001559class CommandObjectCommandsScriptAdd :
1560 public CommandObjectParsed,
1561 public IOHandlerDelegateMultiline
Enrico Granata223383e2011-08-16 23:24:13 +00001562{
Jim Ingham5a988412012-06-08 21:56:10 +00001563public:
1564 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1565 CommandObjectParsed (interpreter,
1566 "command script add",
1567 "Add a scripted function as an LLDB command.",
1568 NULL),
Greg Clayton44d93782014-01-27 23:43:24 +00001569 IOHandlerDelegateMultiline ("DONE"),
Jim Ingham5a988412012-06-08 21:56:10 +00001570 m_options (interpreter)
1571 {
1572 CommandArgumentEntry arg1;
1573 CommandArgumentData cmd_arg;
1574
1575 // Define the first (and only) variant of this arg.
1576 cmd_arg.arg_type = eArgTypeCommandName;
1577 cmd_arg.arg_repetition = eArgRepeatPlain;
1578
1579 // There is only one variant this argument could be; put it into the argument entry.
1580 arg1.push_back (cmd_arg);
1581
1582 // Push the data for the first argument into the m_arguments vector.
1583 m_arguments.push_back (arg1);
1584 }
1585
1586 ~CommandObjectCommandsScriptAdd ()
1587 {
1588 }
1589
1590 virtual Options *
1591 GetOptions ()
1592 {
1593 return &m_options;
1594 }
1595
1596protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001597
1598 class CommandOptions : public Options
1599 {
1600 public:
1601
1602 CommandOptions (CommandInterpreter &interpreter) :
Greg Clayton44d93782014-01-27 23:43:24 +00001603 Options (interpreter)
Enrico Granata223383e2011-08-16 23:24:13 +00001604 {
1605 }
1606
1607 virtual
1608 ~CommandOptions (){}
1609
1610 virtual Error
1611 SetOptionValue (uint32_t option_idx, const char *option_arg)
1612 {
1613 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001614 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata223383e2011-08-16 23:24:13 +00001615
1616 switch (short_option)
1617 {
1618 case 'f':
1619 m_funct_name = std::string(option_arg);
1620 break;
Enrico Granata0a305db2011-11-07 22:57:04 +00001621 case 's':
Greg Clayton44d93782014-01-27 23:43:24 +00001622 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
Enrico Granata0a305db2011-11-07 22:57:04 +00001623 if (!error.Success())
1624 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1625 break;
Enrico Granata223383e2011-08-16 23:24:13 +00001626 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001627 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata223383e2011-08-16 23:24:13 +00001628 break;
1629 }
1630
1631 return error;
1632 }
1633
1634 void
1635 OptionParsingStarting ()
1636 {
1637 m_funct_name = "";
Greg Clayton44d93782014-01-27 23:43:24 +00001638 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001639 }
1640
1641 const OptionDefinition*
1642 GetDefinitions ()
1643 {
1644 return g_option_table;
1645 }
1646
1647 // Options table: Required for subclasses of Options.
1648
1649 static OptionDefinition g_option_table[];
1650
1651 // Instance variables to hold the values for command options.
1652
1653 std::string m_funct_name;
Greg Clayton44d93782014-01-27 23:43:24 +00001654 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001655 };
Jim Ingham5a988412012-06-08 21:56:10 +00001656
Greg Clayton44d93782014-01-27 23:43:24 +00001657 virtual void
1658 IOHandlerActivated (IOHandler &io_handler)
Enrico Granata223383e2011-08-16 23:24:13 +00001659 {
Greg Clayton44d93782014-01-27 23:43:24 +00001660 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1661 if (output_sp)
Enrico Granata223383e2011-08-16 23:24:13 +00001662 {
Greg Clayton44d93782014-01-27 23:43:24 +00001663 output_sp->PutCString(g_python_command_instructions);
1664 output_sp->Flush();
Enrico Granata223383e2011-08-16 23:24:13 +00001665 }
Greg Clayton44d93782014-01-27 23:43:24 +00001666 }
Enrico Granata223383e2011-08-16 23:24:13 +00001667
Greg Clayton44d93782014-01-27 23:43:24 +00001668
1669 virtual void
1670 IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1671 {
1672 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1673
1674 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1675 if (interpreter)
1676 {
1677
1678 StringList lines;
1679 lines.SplitIntoLines(data);
1680 if (lines.GetSize() > 0)
1681 {
1682 std::string funct_name_str;
1683 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1684 {
1685 if (funct_name_str.empty())
1686 {
1687 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1688 error_sp->Flush();
1689 }
1690 else
1691 {
1692 // everything should be fine now, let's add this alias
1693
1694 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1695 m_cmd_name,
1696 funct_name_str.c_str(),
1697 m_synchronicity));
1698
1699 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1700 {
1701 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
1702 error_sp->Flush();
1703 }
1704 }
1705 }
1706 else
1707 {
1708 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
1709 error_sp->Flush();
1710 }
1711 }
1712 else
1713 {
1714 error_sp->Printf ("error: empty function, didn't add python command.\n");
1715 error_sp->Flush();
1716 }
1717 }
1718 else
1719 {
1720 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
1721 error_sp->Flush();
1722 }
1723
1724 io_handler.SetIsDone(true);
1725
1726
1727 }
1728
Jim Ingham5a988412012-06-08 21:56:10 +00001729protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001730 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001731 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001732 {
Enrico Granata99f0b8f2011-08-17 01:30:04 +00001733
1734 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1735 {
1736 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1737 result.SetStatus (eReturnStatusFailed);
1738 return false;
1739 }
1740
Jim Ingham5a988412012-06-08 21:56:10 +00001741 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001742
1743 if (argc != 1)
1744 {
1745 result.AppendError ("'command script add' requires one argument");
1746 result.SetStatus (eReturnStatusFailed);
1747 return false;
1748 }
1749
Greg Clayton44d93782014-01-27 23:43:24 +00001750 // Store the command name and synchronicity in case we get multi-line input
1751 m_cmd_name = command.GetArgumentAtIndex(0);
1752 m_synchronicity = m_options.m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001753
1754 if (m_options.m_funct_name.empty())
1755 {
Greg Clayton44d93782014-01-27 23:43:24 +00001756 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
1757 *this, // IOHandlerDelegate
1758 true, // Run IOHandler in async mode
1759 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
Enrico Granata223383e2011-08-16 23:24:13 +00001760 }
1761 else
1762 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001763 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
Greg Clayton44d93782014-01-27 23:43:24 +00001764 m_cmd_name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001765 m_options.m_funct_name,
Greg Clayton44d93782014-01-27 23:43:24 +00001766 m_synchronicity));
1767 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
Enrico Granata223383e2011-08-16 23:24:13 +00001768 {
1769 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1770 }
1771 else
1772 {
1773 result.AppendError("cannot add command");
1774 result.SetStatus (eReturnStatusFailed);
1775 }
1776 }
1777
1778 return result.Succeeded();
1779
1780 }
Jim Ingham5a988412012-06-08 21:56:10 +00001781
1782 CommandOptions m_options;
Greg Clayton44d93782014-01-27 23:43:24 +00001783 std::string m_cmd_name;
1784 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001785};
1786
Enrico Granata0a305db2011-11-07 22:57:04 +00001787static OptionEnumValueElement g_script_synchro_type[] =
1788{
1789 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1790 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1791 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1792 { 0, NULL, NULL }
1793};
1794
Enrico Granata223383e2011-08-16 23:24:13 +00001795OptionDefinition
1796CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1797{
Virgile Belloe2607b52013-09-05 16:42:23 +00001798 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
1799 { LLDB_OPT_SET_1, false, "synchronicity", 's', OptionParser::eRequiredArgument, 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 +00001800 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1801};
1802
1803//-------------------------------------------------------------------------
1804// CommandObjectCommandsScriptList
1805//-------------------------------------------------------------------------
1806
Jim Ingham5a988412012-06-08 21:56:10 +00001807class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001808{
1809private:
Enrico Granata0a305db2011-11-07 22:57:04 +00001810
Enrico Granata223383e2011-08-16 23:24:13 +00001811public:
1812 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001813 CommandObjectParsed (interpreter,
Enrico Granata223383e2011-08-16 23:24:13 +00001814 "command script list",
1815 "List defined scripted commands.",
1816 NULL)
1817 {
1818 }
1819
1820 ~CommandObjectCommandsScriptList ()
1821 {
1822 }
1823
1824 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001825 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001826 {
1827
1828 m_interpreter.GetHelp(result,
1829 CommandInterpreter::eCommandTypesUserDef);
1830
1831 result.SetStatus (eReturnStatusSuccessFinishResult);
1832
1833 return true;
1834
1835
1836 }
1837};
1838
1839//-------------------------------------------------------------------------
1840// CommandObjectCommandsScriptClear
1841//-------------------------------------------------------------------------
1842
Jim Ingham5a988412012-06-08 21:56:10 +00001843class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001844{
1845private:
1846
1847public:
1848 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001849 CommandObjectParsed (interpreter,
1850 "command script clear",
1851 "Delete all scripted commands.",
1852 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00001853 {
1854 }
1855
1856 ~CommandObjectCommandsScriptClear ()
1857 {
1858 }
1859
Jim Ingham5a988412012-06-08 21:56:10 +00001860protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001861 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001862 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001863 {
1864
1865 m_interpreter.RemoveAllUser();
1866
1867 result.SetStatus (eReturnStatusSuccessFinishResult);
1868
1869 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00001870 }
1871};
1872
1873//-------------------------------------------------------------------------
1874// CommandObjectCommandsScriptDelete
1875//-------------------------------------------------------------------------
1876
Jim Ingham5a988412012-06-08 21:56:10 +00001877class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001878{
Enrico Granata223383e2011-08-16 23:24:13 +00001879public:
1880 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001881 CommandObjectParsed (interpreter,
1882 "command script delete",
1883 "Delete a scripted command.",
1884 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00001885 {
1886 CommandArgumentEntry arg1;
1887 CommandArgumentData cmd_arg;
1888
1889 // Define the first (and only) variant of this arg.
1890 cmd_arg.arg_type = eArgTypeCommandName;
1891 cmd_arg.arg_repetition = eArgRepeatPlain;
1892
1893 // There is only one variant this argument could be; put it into the argument entry.
1894 arg1.push_back (cmd_arg);
1895
1896 // Push the data for the first argument into the m_arguments vector.
1897 m_arguments.push_back (arg1);
1898 }
1899
1900 ~CommandObjectCommandsScriptDelete ()
1901 {
1902 }
1903
Jim Ingham5a988412012-06-08 21:56:10 +00001904protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001905 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001906 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001907 {
1908
Jim Ingham5a988412012-06-08 21:56:10 +00001909 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001910
1911 if (argc != 1)
1912 {
1913 result.AppendError ("'command script delete' requires one argument");
1914 result.SetStatus (eReturnStatusFailed);
1915 return false;
1916 }
1917
Jim Ingham5a988412012-06-08 21:56:10 +00001918 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00001919
1920 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1921 {
1922 m_interpreter.RemoveUser(cmd_name);
1923 result.SetStatus (eReturnStatusSuccessFinishResult);
1924 }
1925 else
1926 {
1927 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1928 result.SetStatus (eReturnStatusFailed);
1929 }
1930
1931 return result.Succeeded();
1932
1933 }
1934};
1935
1936#pragma mark CommandObjectMultiwordCommandsScript
1937
1938//-------------------------------------------------------------------------
1939// CommandObjectMultiwordCommandsScript
1940//-------------------------------------------------------------------------
1941
1942class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1943{
1944public:
1945 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1946 CommandObjectMultiword (interpreter,
1947 "command script",
1948 "A set of commands for managing or customizing script commands.",
1949 "command script <subcommand> [<subcommand-options>]")
1950 {
1951 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1952 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1953 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1954 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Enrico Granataa9dbf432011-10-17 21:45:27 +00001955 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00001956 }
1957
1958 ~CommandObjectMultiwordCommandsScript ()
1959 {
1960 }
1961
1962};
1963
1964
Jim Inghamebc09c32010-07-07 03:36:20 +00001965#pragma mark CommandObjectMultiwordCommands
1966
1967//-------------------------------------------------------------------------
1968// CommandObjectMultiwordCommands
1969//-------------------------------------------------------------------------
1970
1971CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001972 CommandObjectMultiword (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001973 "command",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001974 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001975 "command <subcommand> [<subcommand-options>]")
Jim Inghamebc09c32010-07-07 03:36:20 +00001976{
Greg Claytona7015092010-09-18 01:14:36 +00001977 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1978 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1979 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytonde164aa2011-04-20 16:37:46 +00001980 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Inghama5a97eb2011-07-12 03:12:18 +00001981 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00001982 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Inghamebc09c32010-07-07 03:36:20 +00001983}
1984
1985CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1986{
1987}
1988