blob: e3e113aac23bc46b4e46b462535a1c38cfd0a388 [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,
Greg Claytonf6913cd2014-03-07 00:53:24 +00001037 "lldb", // Name of input reader for history
1038 "\033[K> ", // Prompt and clear line
Greg Clayton44d93782014-01-27 23:43:24 +00001039 multiple_lines,
Greg Claytonf6913cd2014-03-07 00:53:24 +00001040 0, // Don't show line numbers
Greg Clayton44d93782014-01-27 23:43:24 +00001041 *this));
1042
1043 if (io_handler_sp)
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001044 {
Greg Clayton44d93782014-01-27 23:43:24 +00001045 debugger.PushIOHandler(io_handler_sp);
1046 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Greg Claytonde164aa2011-04-20 16:37:46 +00001047 }
1048 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001049 else
1050 {
1051 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
1052 {
Jim Ingham5a988412012-06-08 21:56:10 +00001053 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
Greg Clayton44d93782014-01-27 23:43:24 +00001054 bool check_only = false;
1055 error = AppendRegexSubstitution (arg_strref, check_only);
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001056 if (error.Fail())
1057 break;
1058 }
1059
1060 if (error.Success())
1061 {
1062 AddRegexCommandToInterpreter();
1063 }
1064 }
1065 if (error.Fail())
1066 {
1067 result.AppendError (error.AsCString());
1068 result.SetStatus (eReturnStatusFailed);
1069 }
Greg Claytonde164aa2011-04-20 16:37:46 +00001070 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001071
Greg Claytonde164aa2011-04-20 16:37:46 +00001072 return result.Succeeded();
1073 }
1074
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001075 Error
Greg Clayton44d93782014-01-27 23:43:24 +00001076 AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
Greg Claytonde164aa2011-04-20 16:37:46 +00001077 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001078 Error error;
1079
1080 if (m_regex_cmd_ap.get() == NULL)
Greg Claytonde164aa2011-04-20 16:37:46 +00001081 {
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001082 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
1083 (int)regex_sed.size(),
1084 regex_sed.data());
1085 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001086 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001087
1088 size_t regex_sed_size = regex_sed.size();
1089
1090 if (regex_sed_size <= 1)
1091 {
1092 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
1093 (int)regex_sed.size(),
1094 regex_sed.data());
1095 return error;
1096 }
1097
1098 if (regex_sed[0] != 's')
1099 {
1100 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
1101 (int)regex_sed.size(),
1102 regex_sed.data());
1103 return error;
1104 }
1105 const size_t first_separator_char_pos = 1;
1106 // use the char that follows 's' as the regex separator character
1107 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1108 const char separator_char = regex_sed[first_separator_char_pos];
1109 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1110
1111 if (second_separator_char_pos == std::string::npos)
1112 {
1113 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
1114 separator_char,
1115 (int)(regex_sed.size() - first_separator_char_pos - 1),
1116 regex_sed.data() + (first_separator_char_pos + 1));
1117 return error;
1118 }
1119
1120 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1121
1122 if (third_separator_char_pos == std::string::npos)
1123 {
1124 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
1125 separator_char,
1126 (int)(regex_sed.size() - second_separator_char_pos - 1),
1127 regex_sed.data() + (second_separator_char_pos + 1));
1128 return error;
1129 }
1130
1131 if (third_separator_char_pos != regex_sed_size - 1)
1132 {
1133 // Make sure that everything that follows the last regex
1134 // separator char
1135 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1136 {
1137 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1138 (int)third_separator_char_pos + 1,
1139 regex_sed.data(),
1140 (int)(regex_sed.size() - third_separator_char_pos - 1),
1141 regex_sed.data() + (third_separator_char_pos + 1));
1142 return error;
1143 }
1144
1145 }
1146 else if (first_separator_char_pos + 1 == second_separator_char_pos)
1147 {
1148 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1149 separator_char,
1150 separator_char,
1151 separator_char,
1152 (int)regex_sed.size(),
1153 regex_sed.data());
1154 return error;
1155 }
1156 else if (second_separator_char_pos + 1 == third_separator_char_pos)
1157 {
1158 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1159 separator_char,
1160 separator_char,
1161 separator_char,
1162 (int)regex_sed.size(),
1163 regex_sed.data());
1164 return error;
1165 }
Greg Clayton44d93782014-01-27 23:43:24 +00001166
1167 if (check_only == false)
1168 {
1169 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1170 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1171 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1172 subst.c_str());
1173 }
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001174 return error;
Greg Claytonde164aa2011-04-20 16:37:46 +00001175 }
1176
1177 void
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001178 AddRegexCommandToInterpreter()
Greg Claytonde164aa2011-04-20 16:37:46 +00001179 {
1180 if (m_regex_cmd_ap.get())
1181 {
1182 if (m_regex_cmd_ap->HasRegexEntries())
1183 {
1184 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1185 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1186 }
1187 }
1188 }
1189
Greg Claytonde164aa2011-04-20 16:37:46 +00001190private:
Greg Clayton7b0992d2013-04-18 22:45:39 +00001191 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
Greg Claytonde164aa2011-04-20 16:37:46 +00001192
1193 class CommandOptions : public Options
1194 {
1195 public:
1196
1197 CommandOptions (CommandInterpreter &interpreter) :
1198 Options (interpreter)
1199 {
1200 }
1201
1202 virtual
1203 ~CommandOptions (){}
1204
1205 virtual Error
1206 SetOptionValue (uint32_t option_idx, const char *option_arg)
1207 {
1208 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001209 const int short_option = m_getopt_table[option_idx].val;
Greg Claytonde164aa2011-04-20 16:37:46 +00001210
1211 switch (short_option)
1212 {
1213 case 'h':
1214 m_help.assign (option_arg);
1215 break;
1216 case 's':
1217 m_syntax.assign (option_arg);
1218 break;
1219
1220 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001221 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Greg Claytonde164aa2011-04-20 16:37:46 +00001222 break;
1223 }
1224
1225 return error;
1226 }
1227
1228 void
1229 OptionParsingStarting ()
1230 {
1231 m_help.clear();
1232 m_syntax.clear();
1233 }
1234
1235 const OptionDefinition*
1236 GetDefinitions ()
1237 {
1238 return g_option_table;
1239 }
1240
1241 // Options table: Required for subclasses of Options.
1242
1243 static OptionDefinition g_option_table[];
1244
1245 const char *
1246 GetHelp ()
1247 {
1248 if (m_help.empty())
1249 return NULL;
1250 return m_help.c_str();
1251 }
1252 const char *
1253 GetSyntax ()
1254 {
1255 if (m_syntax.empty())
1256 return NULL;
1257 return m_syntax.c_str();
1258 }
1259 // Instance variables to hold the values for command options.
1260 protected:
1261 std::string m_help;
1262 std::string m_syntax;
1263 };
Jim Ingham5a988412012-06-08 21:56:10 +00001264
Greg Claytonde164aa2011-04-20 16:37:46 +00001265 virtual Options *
1266 GetOptions ()
1267 {
1268 return &m_options;
1269 }
Jim Ingham5a988412012-06-08 21:56:10 +00001270
1271 CommandOptions m_options;
Greg Claytonde164aa2011-04-20 16:37:46 +00001272};
1273
Greg Claytonde164aa2011-04-20 16:37:46 +00001274OptionDefinition
1275CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1276{
Virgile Belloe2607b52013-09-05 16:42:23 +00001277{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1278{ 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 +00001279{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
Greg Claytonde164aa2011-04-20 16:37:46 +00001280};
1281
1282
Jim Ingham5a988412012-06-08 21:56:10 +00001283class CommandObjectPythonFunction : public CommandObjectRaw
Enrico Granata223383e2011-08-16 23:24:13 +00001284{
1285private:
1286 std::string m_function_name;
Enrico Granata0a305db2011-11-07 22:57:04 +00001287 ScriptedCommandSynchronicity m_synchro;
Enrico Granatafac939e2012-09-18 21:53:02 +00001288 bool m_fetched_help_long;
Enrico Granata223383e2011-08-16 23:24:13 +00001289
1290public:
1291
1292 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1293 std::string name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001294 std::string funct,
1295 ScriptedCommandSynchronicity synch) :
Jim Ingham5a988412012-06-08 21:56:10 +00001296 CommandObjectRaw (interpreter,
1297 name.c_str(),
1298 (std::string("Run Python function ") + funct).c_str(),
1299 NULL),
1300 m_function_name(funct),
Enrico Granatafac939e2012-09-18 21:53:02 +00001301 m_synchro(synch),
1302 m_fetched_help_long(false)
Enrico Granata223383e2011-08-16 23:24:13 +00001303 {
1304 }
1305
1306 virtual
1307 ~CommandObjectPythonFunction ()
1308 {
1309 }
1310
1311 virtual bool
Greg Clayton3a18e312012-10-08 22:41:53 +00001312 IsRemovable () const
Jim Ingham5a988412012-06-08 21:56:10 +00001313 {
1314 return true;
1315 }
1316
1317 const std::string&
1318 GetFunctionName ()
1319 {
1320 return m_function_name;
1321 }
1322
1323 ScriptedCommandSynchronicity
1324 GetSynchronicity ()
1325 {
1326 return m_synchro;
1327 }
1328
Enrico Granatafac939e2012-09-18 21:53:02 +00001329 virtual const char *
1330 GetHelpLong ()
1331 {
1332 if (!m_fetched_help_long)
1333 {
1334 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1335 if (scripter)
1336 {
1337 std::string docstring;
1338 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1339 if (!docstring.empty())
1340 SetHelpLong(docstring);
1341 }
1342 }
1343 return CommandObjectRaw::GetHelpLong();
1344 }
1345
Jim Ingham5a988412012-06-08 21:56:10 +00001346protected:
1347 virtual bool
1348 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001349 {
1350 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1351
1352 Error error;
1353
Jim Ingham70f11f82012-06-27 17:25:36 +00001354 result.SetStatus(eReturnStatusInvalid);
1355
Enrico Granata223383e2011-08-16 23:24:13 +00001356 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1357 raw_command_line,
Enrico Granata0a305db2011-11-07 22:57:04 +00001358 m_synchro,
Enrico Granata223383e2011-08-16 23:24:13 +00001359 result,
1360 error) == false)
1361 {
1362 result.AppendError(error.AsCString());
1363 result.SetStatus(eReturnStatusFailed);
1364 }
1365 else
Jim Ingham70f11f82012-06-27 17:25:36 +00001366 {
1367 // Don't change the status if the command already set it...
1368 if (result.GetStatus() == eReturnStatusInvalid)
1369 {
Daniel Malea9a71a7d2013-07-03 17:58:31 +00001370 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
Jim Ingham70f11f82012-06-27 17:25:36 +00001371 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1372 else
1373 result.SetStatus(eReturnStatusSuccessFinishResult);
1374 }
1375 }
Enrico Granata223383e2011-08-16 23:24:13 +00001376
1377 return result.Succeeded();
1378 }
1379
Enrico Granata223383e2011-08-16 23:24:13 +00001380};
1381
Enrico Granataa9dbf432011-10-17 21:45:27 +00001382//-------------------------------------------------------------------------
1383// CommandObjectCommandsScriptImport
1384//-------------------------------------------------------------------------
1385
Jim Ingham5a988412012-06-08 21:56:10 +00001386class CommandObjectCommandsScriptImport : public CommandObjectParsed
Enrico Granataa9dbf432011-10-17 21:45:27 +00001387{
Jim Ingham5a988412012-06-08 21:56:10 +00001388public:
1389 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1390 CommandObjectParsed (interpreter,
1391 "command script import",
1392 "Import a scripting module in LLDB.",
1393 NULL),
1394 m_options(interpreter)
1395 {
1396 CommandArgumentEntry arg1;
1397 CommandArgumentData cmd_arg;
1398
1399 // Define the first (and only) variant of this arg.
1400 cmd_arg.arg_type = eArgTypeFilename;
1401 cmd_arg.arg_repetition = eArgRepeatPlain;
1402
1403 // There is only one variant this argument could be; put it into the argument entry.
1404 arg1.push_back (cmd_arg);
1405
1406 // Push the data for the first argument into the m_arguments vector.
1407 m_arguments.push_back (arg1);
1408 }
1409
1410 ~CommandObjectCommandsScriptImport ()
1411 {
1412 }
1413
Greg Claytonc7bece562013-01-25 18:06:21 +00001414 virtual int
Jim Ingham5a988412012-06-08 21:56:10 +00001415 HandleArgumentCompletion (Args &input,
1416 int &cursor_index,
1417 int &cursor_char_position,
1418 OptionElementVector &opt_element_vector,
1419 int match_start_point,
1420 int max_return_elements,
1421 bool &word_complete,
1422 StringList &matches)
1423 {
1424 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1425 completion_str.erase (cursor_char_position);
1426
1427 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1428 CommandCompletions::eDiskFileCompletion,
1429 completion_str.c_str(),
1430 match_start_point,
1431 max_return_elements,
1432 NULL,
1433 word_complete,
1434 matches);
1435 return matches.GetSize();
1436 }
1437
1438 virtual Options *
1439 GetOptions ()
1440 {
1441 return &m_options;
1442 }
1443
1444protected:
Enrico Granata0a305db2011-11-07 22:57:04 +00001445
1446 class CommandOptions : public Options
1447 {
1448 public:
1449
1450 CommandOptions (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001451 Options (interpreter)
Enrico Granata0a305db2011-11-07 22:57:04 +00001452 {
1453 }
1454
1455 virtual
1456 ~CommandOptions (){}
1457
1458 virtual Error
1459 SetOptionValue (uint32_t option_idx, const char *option_arg)
1460 {
1461 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001462 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata0a305db2011-11-07 22:57:04 +00001463
1464 switch (short_option)
1465 {
1466 case 'r':
1467 m_allow_reload = true;
1468 break;
1469 default:
1470 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1471 break;
1472 }
1473
1474 return error;
1475 }
1476
1477 void
1478 OptionParsingStarting ()
1479 {
Enrico Granatae0c70f12013-05-31 01:03:09 +00001480 m_allow_reload = true;
Enrico Granata0a305db2011-11-07 22:57:04 +00001481 }
1482
1483 const OptionDefinition*
1484 GetDefinitions ()
1485 {
1486 return g_option_table;
1487 }
1488
1489 // Options table: Required for subclasses of Options.
1490
1491 static OptionDefinition g_option_table[];
1492
1493 // Instance variables to hold the values for command options.
1494
1495 bool m_allow_reload;
1496 };
Enrico Granata0a305db2011-11-07 22:57:04 +00001497
Enrico Granataa9dbf432011-10-17 21:45:27 +00001498 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001499 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granataa9dbf432011-10-17 21:45:27 +00001500 {
1501
1502 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1503 {
1504 result.AppendError ("only scripting language supported for module importing is currently Python");
1505 result.SetStatus (eReturnStatusFailed);
1506 return false;
1507 }
1508
Jim Ingham5a988412012-06-08 21:56:10 +00001509 size_t argc = command.GetArgumentCount();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001510
1511 if (argc != 1)
1512 {
1513 result.AppendError ("'command script import' requires one argument");
1514 result.SetStatus (eReturnStatusFailed);
1515 return false;
1516 }
1517
Jim Ingham5a988412012-06-08 21:56:10 +00001518 std::string path = command.GetArgumentAtIndex(0);
Enrico Granataa9dbf432011-10-17 21:45:27 +00001519 Error error;
1520
Greg Claytonc9d645d2012-10-18 22:40:37 +00001521 const bool init_session = true;
Enrico Granata078551c2013-05-09 19:33:49 +00001522 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1523 // commands won't ever be recursively invoked, but it's actually possible to craft
1524 // a Python script that does other "command script imports" in __lldb_init_module
1525 // the real fix is to have recursive commands possible with a CommandInvocation object
1526 // separate from the CommandObject itself, so that recursive command invocations
1527 // won't stomp on each other (wrt to execution contents, options, and more)
1528 m_exe_ctx.Clear();
Enrico Granataa9dbf432011-10-17 21:45:27 +00001529 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
Enrico Granata0a305db2011-11-07 22:57:04 +00001530 m_options.m_allow_reload,
Greg Claytonc9d645d2012-10-18 22:40:37 +00001531 init_session,
Enrico Granataa9dbf432011-10-17 21:45:27 +00001532 error))
1533 {
1534 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1535 }
1536 else
1537 {
1538 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1539 result.SetStatus (eReturnStatusFailed);
1540 }
1541
1542 return result.Succeeded();
1543 }
Enrico Granata0a305db2011-11-07 22:57:04 +00001544
Jim Ingham5a988412012-06-08 21:56:10 +00001545 CommandOptions m_options;
Enrico Granataa9dbf432011-10-17 21:45:27 +00001546};
Enrico Granata223383e2011-08-16 23:24:13 +00001547
Enrico Granata0a305db2011-11-07 22:57:04 +00001548OptionDefinition
1549CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1550{
Virgile Belloe2607b52013-09-05 16:42:23 +00001551 { 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 +00001552 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1553};
1554
1555
Enrico Granata223383e2011-08-16 23:24:13 +00001556//-------------------------------------------------------------------------
1557// CommandObjectCommandsScriptAdd
1558//-------------------------------------------------------------------------
1559
Greg Clayton44d93782014-01-27 23:43:24 +00001560class CommandObjectCommandsScriptAdd :
1561 public CommandObjectParsed,
1562 public IOHandlerDelegateMultiline
Enrico Granata223383e2011-08-16 23:24:13 +00001563{
Jim Ingham5a988412012-06-08 21:56:10 +00001564public:
1565 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1566 CommandObjectParsed (interpreter,
1567 "command script add",
1568 "Add a scripted function as an LLDB command.",
1569 NULL),
Greg Clayton44d93782014-01-27 23:43:24 +00001570 IOHandlerDelegateMultiline ("DONE"),
Jim Ingham5a988412012-06-08 21:56:10 +00001571 m_options (interpreter)
1572 {
1573 CommandArgumentEntry arg1;
1574 CommandArgumentData cmd_arg;
1575
1576 // Define the first (and only) variant of this arg.
1577 cmd_arg.arg_type = eArgTypeCommandName;
1578 cmd_arg.arg_repetition = eArgRepeatPlain;
1579
1580 // There is only one variant this argument could be; put it into the argument entry.
1581 arg1.push_back (cmd_arg);
1582
1583 // Push the data for the first argument into the m_arguments vector.
1584 m_arguments.push_back (arg1);
1585 }
1586
1587 ~CommandObjectCommandsScriptAdd ()
1588 {
1589 }
1590
1591 virtual Options *
1592 GetOptions ()
1593 {
1594 return &m_options;
1595 }
1596
1597protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001598
1599 class CommandOptions : public Options
1600 {
1601 public:
1602
1603 CommandOptions (CommandInterpreter &interpreter) :
Greg Clayton44d93782014-01-27 23:43:24 +00001604 Options (interpreter)
Enrico Granata223383e2011-08-16 23:24:13 +00001605 {
1606 }
1607
1608 virtual
1609 ~CommandOptions (){}
1610
1611 virtual Error
1612 SetOptionValue (uint32_t option_idx, const char *option_arg)
1613 {
1614 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001615 const int short_option = m_getopt_table[option_idx].val;
Enrico Granata223383e2011-08-16 23:24:13 +00001616
1617 switch (short_option)
1618 {
1619 case 'f':
1620 m_funct_name = std::string(option_arg);
1621 break;
Enrico Granata0a305db2011-11-07 22:57:04 +00001622 case 's':
Greg Clayton44d93782014-01-27 23:43:24 +00001623 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
Enrico Granata0a305db2011-11-07 22:57:04 +00001624 if (!error.Success())
1625 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1626 break;
Enrico Granata223383e2011-08-16 23:24:13 +00001627 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001628 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Enrico Granata223383e2011-08-16 23:24:13 +00001629 break;
1630 }
1631
1632 return error;
1633 }
1634
1635 void
1636 OptionParsingStarting ()
1637 {
1638 m_funct_name = "";
Greg Clayton44d93782014-01-27 23:43:24 +00001639 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
Enrico Granata223383e2011-08-16 23:24:13 +00001640 }
1641
1642 const OptionDefinition*
1643 GetDefinitions ()
1644 {
1645 return g_option_table;
1646 }
1647
1648 // Options table: Required for subclasses of Options.
1649
1650 static OptionDefinition g_option_table[];
1651
1652 // Instance variables to hold the values for command options.
1653
1654 std::string m_funct_name;
Greg Clayton44d93782014-01-27 23:43:24 +00001655 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001656 };
Jim Ingham5a988412012-06-08 21:56:10 +00001657
Greg Clayton44d93782014-01-27 23:43:24 +00001658 virtual void
1659 IOHandlerActivated (IOHandler &io_handler)
Enrico Granata223383e2011-08-16 23:24:13 +00001660 {
Greg Clayton44d93782014-01-27 23:43:24 +00001661 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1662 if (output_sp)
Enrico Granata223383e2011-08-16 23:24:13 +00001663 {
Greg Clayton44d93782014-01-27 23:43:24 +00001664 output_sp->PutCString(g_python_command_instructions);
1665 output_sp->Flush();
Enrico Granata223383e2011-08-16 23:24:13 +00001666 }
Greg Clayton44d93782014-01-27 23:43:24 +00001667 }
Enrico Granata223383e2011-08-16 23:24:13 +00001668
Greg Clayton44d93782014-01-27 23:43:24 +00001669
1670 virtual void
1671 IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1672 {
1673 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1674
1675 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1676 if (interpreter)
1677 {
1678
1679 StringList lines;
1680 lines.SplitIntoLines(data);
1681 if (lines.GetSize() > 0)
1682 {
1683 std::string funct_name_str;
1684 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1685 {
1686 if (funct_name_str.empty())
1687 {
1688 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1689 error_sp->Flush();
1690 }
1691 else
1692 {
1693 // everything should be fine now, let's add this alias
1694
1695 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1696 m_cmd_name,
1697 funct_name_str.c_str(),
1698 m_synchronicity));
1699
1700 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1701 {
1702 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
1703 error_sp->Flush();
1704 }
1705 }
1706 }
1707 else
1708 {
1709 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
1710 error_sp->Flush();
1711 }
1712 }
1713 else
1714 {
1715 error_sp->Printf ("error: empty function, didn't add python command.\n");
1716 error_sp->Flush();
1717 }
1718 }
1719 else
1720 {
1721 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
1722 error_sp->Flush();
1723 }
1724
1725 io_handler.SetIsDone(true);
1726
1727
1728 }
1729
Jim Ingham5a988412012-06-08 21:56:10 +00001730protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001731 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001732 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001733 {
Enrico Granata99f0b8f2011-08-17 01:30:04 +00001734
1735 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1736 {
1737 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1738 result.SetStatus (eReturnStatusFailed);
1739 return false;
1740 }
1741
Jim Ingham5a988412012-06-08 21:56:10 +00001742 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001743
1744 if (argc != 1)
1745 {
1746 result.AppendError ("'command script add' requires one argument");
1747 result.SetStatus (eReturnStatusFailed);
1748 return false;
1749 }
1750
Greg Clayton44d93782014-01-27 23:43:24 +00001751 // Store the command name and synchronicity in case we get multi-line input
1752 m_cmd_name = command.GetArgumentAtIndex(0);
1753 m_synchronicity = m_options.m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001754
1755 if (m_options.m_funct_name.empty())
1756 {
Greg Clayton44d93782014-01-27 23:43:24 +00001757 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
1758 *this, // IOHandlerDelegate
1759 true, // Run IOHandler in async mode
1760 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
Enrico Granata223383e2011-08-16 23:24:13 +00001761 }
1762 else
1763 {
Enrico Granata0a305db2011-11-07 22:57:04 +00001764 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
Greg Clayton44d93782014-01-27 23:43:24 +00001765 m_cmd_name,
Enrico Granata0a305db2011-11-07 22:57:04 +00001766 m_options.m_funct_name,
Greg Clayton44d93782014-01-27 23:43:24 +00001767 m_synchronicity));
1768 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
Enrico Granata223383e2011-08-16 23:24:13 +00001769 {
1770 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1771 }
1772 else
1773 {
1774 result.AppendError("cannot add command");
1775 result.SetStatus (eReturnStatusFailed);
1776 }
1777 }
1778
1779 return result.Succeeded();
1780
1781 }
Jim Ingham5a988412012-06-08 21:56:10 +00001782
1783 CommandOptions m_options;
Greg Clayton44d93782014-01-27 23:43:24 +00001784 std::string m_cmd_name;
1785 ScriptedCommandSynchronicity m_synchronicity;
Enrico Granata223383e2011-08-16 23:24:13 +00001786};
1787
Enrico Granata0a305db2011-11-07 22:57:04 +00001788static OptionEnumValueElement g_script_synchro_type[] =
1789{
1790 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1791 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1792 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1793 { 0, NULL, NULL }
1794};
1795
Enrico Granata223383e2011-08-16 23:24:13 +00001796OptionDefinition
1797CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1798{
Virgile Belloe2607b52013-09-05 16:42:23 +00001799 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
1800 { 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 +00001801 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1802};
1803
1804//-------------------------------------------------------------------------
1805// CommandObjectCommandsScriptList
1806//-------------------------------------------------------------------------
1807
Jim Ingham5a988412012-06-08 21:56:10 +00001808class CommandObjectCommandsScriptList : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001809{
1810private:
Enrico Granata0a305db2011-11-07 22:57:04 +00001811
Enrico Granata223383e2011-08-16 23:24:13 +00001812public:
1813 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001814 CommandObjectParsed (interpreter,
Enrico Granata223383e2011-08-16 23:24:13 +00001815 "command script list",
1816 "List defined scripted commands.",
1817 NULL)
1818 {
1819 }
1820
1821 ~CommandObjectCommandsScriptList ()
1822 {
1823 }
1824
1825 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001826 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001827 {
1828
1829 m_interpreter.GetHelp(result,
1830 CommandInterpreter::eCommandTypesUserDef);
1831
1832 result.SetStatus (eReturnStatusSuccessFinishResult);
1833
1834 return true;
1835
1836
1837 }
1838};
1839
1840//-------------------------------------------------------------------------
1841// CommandObjectCommandsScriptClear
1842//-------------------------------------------------------------------------
1843
Jim Ingham5a988412012-06-08 21:56:10 +00001844class CommandObjectCommandsScriptClear : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001845{
1846private:
1847
1848public:
1849 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001850 CommandObjectParsed (interpreter,
1851 "command script clear",
1852 "Delete all scripted commands.",
1853 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00001854 {
1855 }
1856
1857 ~CommandObjectCommandsScriptClear ()
1858 {
1859 }
1860
Jim Ingham5a988412012-06-08 21:56:10 +00001861protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001862 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001863 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001864 {
1865
1866 m_interpreter.RemoveAllUser();
1867
1868 result.SetStatus (eReturnStatusSuccessFinishResult);
1869
1870 return true;
Enrico Granata223383e2011-08-16 23:24:13 +00001871 }
1872};
1873
1874//-------------------------------------------------------------------------
1875// CommandObjectCommandsScriptDelete
1876//-------------------------------------------------------------------------
1877
Jim Ingham5a988412012-06-08 21:56:10 +00001878class CommandObjectCommandsScriptDelete : public CommandObjectParsed
Enrico Granata223383e2011-08-16 23:24:13 +00001879{
Enrico Granata223383e2011-08-16 23:24:13 +00001880public:
1881 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001882 CommandObjectParsed (interpreter,
1883 "command script delete",
1884 "Delete a scripted command.",
1885 NULL)
Enrico Granata223383e2011-08-16 23:24:13 +00001886 {
1887 CommandArgumentEntry arg1;
1888 CommandArgumentData cmd_arg;
1889
1890 // Define the first (and only) variant of this arg.
1891 cmd_arg.arg_type = eArgTypeCommandName;
1892 cmd_arg.arg_repetition = eArgRepeatPlain;
1893
1894 // There is only one variant this argument could be; put it into the argument entry.
1895 arg1.push_back (cmd_arg);
1896
1897 // Push the data for the first argument into the m_arguments vector.
1898 m_arguments.push_back (arg1);
1899 }
1900
1901 ~CommandObjectCommandsScriptDelete ()
1902 {
1903 }
1904
Jim Ingham5a988412012-06-08 21:56:10 +00001905protected:
Enrico Granata223383e2011-08-16 23:24:13 +00001906 bool
Jim Ingham5a988412012-06-08 21:56:10 +00001907 DoExecute (Args& command, CommandReturnObject &result)
Enrico Granata223383e2011-08-16 23:24:13 +00001908 {
1909
Jim Ingham5a988412012-06-08 21:56:10 +00001910 size_t argc = command.GetArgumentCount();
Enrico Granata223383e2011-08-16 23:24:13 +00001911
1912 if (argc != 1)
1913 {
1914 result.AppendError ("'command script delete' requires one argument");
1915 result.SetStatus (eReturnStatusFailed);
1916 return false;
1917 }
1918
Jim Ingham5a988412012-06-08 21:56:10 +00001919 const char* cmd_name = command.GetArgumentAtIndex(0);
Enrico Granata223383e2011-08-16 23:24:13 +00001920
1921 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1922 {
1923 m_interpreter.RemoveUser(cmd_name);
1924 result.SetStatus (eReturnStatusSuccessFinishResult);
1925 }
1926 else
1927 {
1928 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1929 result.SetStatus (eReturnStatusFailed);
1930 }
1931
1932 return result.Succeeded();
1933
1934 }
1935};
1936
1937#pragma mark CommandObjectMultiwordCommandsScript
1938
1939//-------------------------------------------------------------------------
1940// CommandObjectMultiwordCommandsScript
1941//-------------------------------------------------------------------------
1942
1943class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1944{
1945public:
1946 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1947 CommandObjectMultiword (interpreter,
1948 "command script",
1949 "A set of commands for managing or customizing script commands.",
1950 "command script <subcommand> [<subcommand-options>]")
1951 {
1952 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1953 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1954 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1955 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
Enrico Granataa9dbf432011-10-17 21:45:27 +00001956 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00001957 }
1958
1959 ~CommandObjectMultiwordCommandsScript ()
1960 {
1961 }
1962
1963};
1964
1965
Jim Inghamebc09c32010-07-07 03:36:20 +00001966#pragma mark CommandObjectMultiwordCommands
1967
1968//-------------------------------------------------------------------------
1969// CommandObjectMultiwordCommands
1970//-------------------------------------------------------------------------
1971
1972CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001973 CommandObjectMultiword (interpreter,
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001974 "command",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001975 "A set of commands for managing or customizing the debugger commands.",
Greg Clayton0e5e5a72011-04-20 22:55:21 +00001976 "command <subcommand> [<subcommand-options>]")
Jim Inghamebc09c32010-07-07 03:36:20 +00001977{
Greg Claytona7015092010-09-18 01:14:36 +00001978 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1979 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1980 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
Greg Claytonde164aa2011-04-20 16:37:46 +00001981 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
Jim Inghama5a97eb2011-07-12 03:12:18 +00001982 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
Enrico Granata223383e2011-08-16 23:24:13 +00001983 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
Jim Inghamebc09c32010-07-07 03:36:20 +00001984}
1985
1986CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1987{
1988}
1989